Files
feedmill-auto-label/backend/main.py
T
asus 5c7c122105 feat: add counting bench, triage, and dataset modules
This commit includes major additions and updates to the frontend and backend architectures, introducing new dataset management, live counting features, batch processing, and triage logic. Includes new UI pages, components, and API routes.
2026-08-14 16:28:52 +07:00

86 lines
2.6 KiB
Python

"""FastAPI server for the dataset enrichment platform.
Run it with: .venv/bin/uvicorn backend.main:app --port 8000
or: docker compose up
Routes live in `backend/api/`, one module per domain; this file only wires them
together and owns startup.
"""
import os
import shutil
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from backend import archive_index, config, db, jobs
from backend.api import (batches, counting_bench as counting_bench_routes,
datasets as dataset_routes, jobs as job_routes,
live_count as live_count_routes, models, projects, review, triage)
@asynccontextmanager
async def lifespan(_app: FastAPI):
config.ensure_dirs()
db.migrate()
from backend import datasets as dataset_store
adopted = dataset_store.adopt_legacy_tree()
if adopted:
print(f"[startup] moved {adopted} legacy dataset tree(s) under datasets/<id>/")
from backend import projects as project_store
project_store.ensure_seed_project()
interrupted = jobs.recover()
if interrupted:
print(f"[startup] closed {interrupted} job(s) interrupted by the last restart")
yield
app = FastAPI(title="Dataset Enrichment", lifespan=lifespan)
app.add_middleware(
CORSMiddleware,
allow_origins=config.CORS_ORIGINS,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(projects.router)
app.include_router(batches.router)
app.include_router(review.router)
app.include_router(models.router)
app.include_router(job_routes.router)
app.include_router(triage.router)
app.include_router(dataset_routes.router)
app.include_router(live_count_routes.router)
app.include_router(counting_bench_routes.router)
@app.get("/api/health")
def health() -> dict:
import torch
from backend import hardware
free_vram = hardware.free_vram_gb()
needed = hardware.SAM3_RESIDENT_GB + hardware.SAM3_HEADROOM_GB
return {
"device": "cuda" if torch.cuda.is_available() else "cpu",
"gpu": torch.cuda.get_device_name(0) if torch.cuda.is_available() else None,
"vram_free_gb": free_vram,
"sam3_ready": free_vram >= needed or _engine_loaded(),
"ffmpeg": shutil.which("ffmpeg") is not None,
"ffprobe": shutil.which("ffprobe") is not None,
"hf_token": bool(os.environ.get("HUGGING_FACE_HUB_TOKEN")),
"db": db.healthy(),
"data_dir": config.DATA_DIR,
"video_root": config.VIDEO_ROOT,
"model_loaded": _engine_loaded(),
}
def _engine_loaded() -> bool:
from backend.sam3_engine import engine_is_loaded
return engine_is_loaded()