from __future__ import annotations import os from pathlib import Path from fastapi import FastAPI, Request from fastapi.responses import FileResponse, JSONResponse from crawler_platform.app.api.routes import register_routes from crawler_platform.app.core.database.session import init_db ONTOLOGY_ROOT = Path(__file__).resolve().parents[2] DATABASE_URL = os.getenv( "CRAWLER_DATABASE_URL", f"sqlite:///{(ONTOLOGY_ROOT / 'data' / 'crawler_platform.db').as_posix()}", ) STATIC_DIR = Path(os.getenv("ONTOLOGY_PRODUCT_STATIC_DIR", str(ONTOLOGY_ROOT / "web" / "static"))) app = FastAPI(title="Ontology Crawler Platform", version="0.1.0") init_db(DATABASE_URL) register_routes(app, DATABASE_URL) @app.exception_handler(KeyError) def _handle_key_error(_request: Request, exc: KeyError) -> JSONResponse: return JSONResponse(status_code=404, content={"detail": str(exc.args[0]) if exc.args else "not found"}) @app.get("/static/{asset_path:path}", include_in_schema=False) def static_or_spa(asset_path: str): static_root = STATIC_DIR.resolve() target = (static_root / asset_path).resolve() try: target.relative_to(static_root) except ValueError: return JSONResponse(status_code=404, content={"detail": "not found"}) if target.is_file(): return FileResponse(target) return FileResponse(STATIC_DIR / "index.html") @app.get("/", include_in_schema=False) def admin_ui(): return FileResponse(STATIC_DIR / "index.html")