Spaces:
Sleeping
Sleeping
File size: 2,815 Bytes
ae4e2a6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
"""
Main FastAPI Application
=========================
Application entry point
"""
import logging
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from app.core.config import settings
from app.core.exceptions import ToxicDetectionException
from app.models.model_loader import model_loader
from app.api.routes import router
# Configure logging
logging.basicConfig(
level=getattr(logging, settings.LOG_LEVEL),
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
@asynccontextmanager
async def lifespan(app: FastAPI):
"""
Lifespan events
Startup: Load model
Shutdown: Cleanup
"""
# Startup
logger.info("Starting up...")
try:
logger.info("Loading model...")
model_loader.load()
logger.info("Model loaded successfully")
except Exception as e:
logger.error(f"Failed to load model: {str(e)}")
# Continue anyway - health endpoint will show model not loaded
yield
# Shutdown
logger.info("Shutting down...")
# Create FastAPI app
app = FastAPI(
title=settings.API_TITLE,
description=settings.API_DESCRIPTION,
version=settings.API_VERSION,
lifespan=lifespan,
docs_url="/docs",
redoc_url="/redoc",
openapi_url="/openapi.json"
)
# CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=settings.ALLOWED_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Exception handlers
@app.exception_handler(ToxicDetectionException)
async def toxic_detection_exception_handler(request, exc: ToxicDetectionException):
"""Handle custom exceptions"""
return JSONResponse(
status_code=exc.status_code,
content={
"success": False,
"error": exc.detail,
"detail": None
}
)
@app.exception_handler(Exception)
async def general_exception_handler(request, exc: Exception):
"""Handle general exceptions"""
logger.error(f"Unhandled exception: {str(exc)}", exc_info=True)
return JSONResponse(
status_code=500,
content={
"success": False,
"error": "Internal server error",
"detail": str(exc) if settings.LOG_LEVEL == "DEBUG" else None
}
)
# Include routers
app.include_router(router, prefix="/api/v1", tags=["v1"])
app.include_router(router, prefix="", tags=["root"])
# For direct run
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"app.main:app",
host=settings.API_HOST,
port=settings.API_PORT,
reload=settings.API_RELOAD,
log_level=settings.LOG_LEVEL.lower()
)
|