from fastapi import FastAPI, Request, Response from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse import time import json from app.core.config import settings from app.core.database import engine, Base from app.core.events import init_minio_bucket from app.api.v1 import api_router from app.models import log as log_models # Create tables (dev convenience; use Alembic in production) Base.metadata.create_all(bind=engine) app = FastAPI( title=settings.PROJECT_NAME, version=settings.VERSION, description=settings.DESCRIPTION, ) app.add_middleware( CORSMiddleware, allow_origins=settings.CORS_ORIGINS, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.middleware("http") async def log_requests(request: Request, call_next): start_time = time.time() response = await call_next(request) duration = int((time.time() - start_time) * 1000) # Skip health checks if request.url.path in ["/docs", "/openapi.json", "/redoc"]: return response from app.core.database import SessionLocal db = None try: db = SessionLocal() log_entry = log_models.OperationLog( module=request.url.path.split("/")[2] if len(request.url.path.split("/")) > 2 else "", action=request.url.path, method=request.method, path=str(request.url), ip=request.client.host if request.client else None, status_code=response.status_code, duration_ms=duration, ) db.add(log_entry) db.commit() except Exception: pass finally: if db: db.close() return response @app.on_event("startup") async def startup_event(): init_minio_bucket() from app.core.database import SessionLocal from app.services.user_service import create_initial_data from app.services.classification_service import init_builtin_data db = SessionLocal() try: create_initial_data(db) init_builtin_data(db) finally: db.close() @app.get("/health") def health_check(): return {"status": "ok"} app.include_router(api_router, prefix="/api/v1")