| """Prometheus API β FastAPI service backing the React dashboard. |
| |
| Run from the project root: |
| uvicorn api.main:app --reload --port 8000 |
| |
| Design notes: |
| * Detection reuses the existing pipeline (src.detection.detector via |
| api.services.detection_service) β one source of truth for inference. |
| * Heavy deps (torch/ultralytics) are imported lazily inside the detection |
| service, so /api/health, /api/metrics and the catalog endpoints respond |
| instantly even on a machine without a model loaded. |
| """ |
|
|
| from __future__ import annotations |
|
|
| import os |
|
|
| |
| |
| |
| |
| |
| os.environ.setdefault("KMP_DUPLICATE_LIB_OK", "TRUE") |
|
|
| import sys |
| from pathlib import Path |
|
|
| from fastapi import FastAPI |
| from fastapi.middleware.cors import CORSMiddleware |
|
|
| PROJECT_ROOT = Path(__file__).resolve().parent.parent |
| sys.path.insert(0, str(PROJECT_ROOT)) |
|
|
| from api.routes import catalog, detection, population, survey, telemetry |
| from api.schemas import SystemInfo |
| from api.services import detection_service |
|
|
| app = FastAPI( |
| title="Prometheus API", |
| description="Aerial wildlife intelligence for the Malilangwe Trust.", |
| version="0.1.0", |
| ) |
|
|
| |
| |
| |
| |
| _origins_env = os.environ.get("ALLOWED_ORIGINS", "*").strip() |
| _allow_origins = ["*"] if _origins_env in ("", "*") else [ |
| o.strip() for o in _origins_env.split(",") if o.strip() |
| ] |
| app.add_middleware( |
| CORSMiddleware, |
| allow_origins=_allow_origins, |
| allow_credentials=False, |
| allow_methods=["*"], |
| allow_headers=["*"], |
| ) |
|
|
| app.include_router(detection.router) |
| app.include_router(catalog.router) |
| app.include_router(population.router) |
| app.include_router(survey.router) |
| app.include_router(telemetry.router) |
|
|
|
|
| @app.get("/api/health", response_model=SystemInfo, tags=["system"]) |
| def health() -> SystemInfo: |
| cuda = False |
| device = "cpu" |
| try: |
| import torch |
|
|
| cuda = bool(torch.cuda.is_available()) |
| device = "cuda" if cuda else "cpu" |
| except Exception: |
| pass |
|
|
| return SystemInfo( |
| status="ok", |
| version="0.1.0", |
| device=device, |
| torch_cuda=cuda, |
| models_available=len(detection_service.available_models()), |
| project="Prometheus Β· Malilangwe Trust", |
| ) |
|
|
|
|
| |
| |
| |
| |
| |
| _WEB = PROJECT_ROOT / "web" |
| if (_WEB / "index.html").exists(): |
| from fastapi.staticfiles import StaticFiles |
|
|
| app.mount("/", StaticFiles(directory=str(_WEB), html=True), name="web") |
|
|