AdarshDRC's picture
fix: Resolving backend
29bfc1f
Raw
History Blame Contribute Delete
2.62 kB
import asyncio
import os
from contextlib import asynccontextmanager
# CPU thread tuning — must happen BEFORE torch/onnxruntime import.
# HF free tier = 2 vCPU; we want to use both but not oversubscribe.
os.environ.setdefault("OMP_NUM_THREADS", "2")
os.environ.setdefault("MKL_NUM_THREADS", "2")
os.environ.setdefault("TOKENIZERS_PARALLELISM", "false")
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from src.core.config import MAX_CONCURRENT_INFERENCES, USE_ASYNC_UPLOADS
from src.core.logging import log, init_logging_session, close_logging_session
from src.api import danger, explorer, search, system, upload
from src.api import people# Phase 3
from src.api import jobs as jobs_api # explicit alias
@asynccontextmanager
async def lifespan(app: FastAPI):
await init_logging_session()
log("INFO", "server.startup", message="Loading AI models...")
from src.services.ai_manager import AIModelManager
loop = asyncio.get_event_loop()
app.state.ai = await loop.run_in_executor(None, AIModelManager)
# Split semaphores: face detection and object embedding can overlap
# without fighting for the same CPU cores.
app.state.ai_semaphore = asyncio.Semaphore(MAX_CONCURRENT_INFERENCES)
app.state.face_semaphore = asyncio.Semaphore(MAX_CONCURRENT_INFERENCES)
app.state.object_semaphore = asyncio.Semaphore(MAX_CONCURRENT_INFERENCES)
# Phase 3: start background job worker if async uploads are enabled
worker_task = None
if USE_ASYNC_UPLOADS:
from src.services.jobs import run_worker
worker_task = asyncio.create_task(run_worker(app.state))
log("INFO", "server.worker_started", message="Async upload worker running")
log("INFO", "server.ready", message="All models loaded. API ready.")
yield
# Graceful shutdown
if worker_task:
worker_task.cancel()
try:
await worker_task
except asyncio.CancelledError:
pass
log("INFO", "server.shutdown", message="API shutting down.")
await close_logging_session()
app = FastAPI(lifespan=lifespan)
app.add_middleware(
CORSMiddleware,
allow_origins=["https://photofinderv2.vercel.app"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
os.makedirs("temp_uploads", exist_ok=True)
# Existing routers
app.include_router(system.router)
app.include_router(upload.router)
app.include_router(search.router)
app.include_router(explorer.router)
app.include_router(danger.router)
# Phase 3 routers
app.include_router(people.router)
app.include_router(jobs_api.router)