"""FastAPI application factory.""" from contextlib import asynccontextmanager from fastapi import FastAPI from gps_denied import __version__ from gps_denied.api.routers import flights @asynccontextmanager async def lifespan(app: FastAPI): """Initialise core pipeline components on startup.""" from gps_denied.core.models import ModelManager from gps_denied.core.vo import SequentialVisualOdometry from gps_denied.core.gpr import GlobalPlaceRecognition from gps_denied.core.metric import MetricRefinement from gps_denied.core.graph import FactorGraphOptimizer from gps_denied.core.chunk_manager import RouteChunkManager from gps_denied.core.recovery import FailureRecoveryCoordinator from gps_denied.core.rotation import ImageRotationManager from gps_denied.schemas.graph import FactorGraphConfig mm = ModelManager() vo = SequentialVisualOdometry(mm) gpr = GlobalPlaceRecognition(mm) metric = MetricRefinement(mm) graph = FactorGraphOptimizer(FactorGraphConfig()) chunk_mgr = RouteChunkManager(graph) recovery = FailureRecoveryCoordinator(chunk_mgr, gpr, metric) rotation = ImageRotationManager(mm) # Store on app.state so deps can access them app.state.pipeline_components = { "vo": vo, "gpr": gpr, "metric": metric, "graph": graph, "recovery": recovery, "chunk_mgr": chunk_mgr, "rotation": rotation, } yield # Cleanup app.state.pipeline_components = None def create_app() -> FastAPI: """Factory function to create and configure the FastAPI application.""" app = FastAPI( title="GPS-Denied Onboard API", description="REST API for UAV Flight Processing in GPS-denied environments.", version=__version__, lifespan=lifespan, ) app.include_router(flights.router) @app.get("/health", tags=["Health"]) async def health() -> dict[str, str]: """Simple health check endpoint.""" return {"status": "ok"} return app app = create_app()