Spaces:
Sleeping
Sleeping
| # app/main.py | |
| # FastAPI application factory β entry point for the Hubble AI Engine | |
| from contextlib import asynccontextmanager | |
| from fastapi import FastAPI | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import JSONResponse | |
| from app.config import get_settings | |
| from app.observability.logging import setup_logging, get_logger | |
| from app.observability.langsmith import setup_langsmith | |
| from app.models.model_registry import model_registry | |
| from app.services.redis_service import redis_service | |
| from app.services.mongo_service import mongo_service | |
| from app.services.gemini_service import gemini_service | |
| from app.pipeline.workflow import get_workflow | |
| from app.api.router import api_router | |
| from app.db.connection import connect_db, close_db | |
| async def lifespan(app: FastAPI): | |
| """ | |
| Application lifespan manager. | |
| Startup: | |
| 1. Configure logging | |
| 2. Setup LangSmith tracing | |
| 3. Connect MongoDB & Redis | |
| 4. Initialize Gemini service | |
| 5. Load all ML models | |
| 6. Compile LangGraph workflow | |
| Shutdown: | |
| 1. Disconnect MongoDB & Redis | |
| """ | |
| logger = get_logger(__name__) | |
| settings = get_settings() | |
| # ββ Startup ββ | |
| logger.info("=" * 60) | |
| logger.info("[STARTUP] HUBBLE AI ENGINE β Starting up...") | |
| logger.info("=" * 60) | |
| # 1. LangSmith | |
| langsmith_ok = setup_langsmith() | |
| logger.info("langsmith", enabled=langsmith_ok) | |
| # 2. MongoDB (legacy motor service + Beanie ODM) | |
| logger.info("connecting_mongodb") | |
| await mongo_service.connect() | |
| await connect_db() # initializes Beanie document models | |
| # 3. Redis | |
| logger.info("connecting_redis") | |
| await redis_service.connect() | |
| # 4. Gemini | |
| logger.info("initializing_gemini") | |
| gemini_service.initialize() | |
| # 5. ML Models | |
| logger.info("loading_models") | |
| model_status = await model_registry.load_all() | |
| logger.info("models_loaded", status=model_status) | |
| # 6. LangGraph Workflow | |
| logger.info("compiling_workflow") | |
| get_workflow() | |
| logger.info("=" * 60) | |
| logger.info("[READY] HUBBLE AI ENGINE β Ready!") | |
| logger.info(f" Environment: {settings.env}") | |
| logger.info(f" Port: {settings.port}") | |
| logger.info(f" Docs: http://localhost:{settings.port}/docs") | |
| logger.info("=" * 60) | |
| yield # ββ Application runs here ββ | |
| # ββ Shutdown ββ | |
| logger.info("[SHUTDOWN] HUBBLE β Shutting down...") | |
| await redis_service.disconnect() | |
| await mongo_service.disconnect() | |
| await close_db() | |
| logger.info("Shutdown complete") | |
| def create_app() -> FastAPI: | |
| """Create and configure the FastAPI application.""" | |
| settings = get_settings() | |
| # Configure logging first | |
| setup_logging() | |
| app = FastAPI( | |
| title="Hubble AI Engine β Cyberbullying Detection API", | |
| description=( | |
| "Production-grade content moderation pipeline with layered AI analysis. " | |
| "Supports text, image, and video inputs with risk-based routing." | |
| ), | |
| version="4.0.0", | |
| docs_url="/docs", | |
| redoc_url="/redoc", | |
| lifespan=lifespan, | |
| ) | |
| # CORS β use origins from config | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=settings.cors_origins_list if settings.is_production else ["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # Mount routes | |
| app.include_router(api_router) | |
| async def root(): | |
| return JSONResponse({ | |
| "name": "Hubble Unified API", | |
| "version": "5.0.0", | |
| "docs": "/docs", | |
| "health": "/health", | |
| "endpoints": { | |
| "auth": "POST /api/v1/auth/{register|login|refresh|logout}", | |
| "users": "GET /api/v1/users/me", | |
| "scan_text": "POST /api/v1/scan/text", | |
| "scan_image": "POST /api/v1/scan/image", | |
| "scan_history": "GET /api/v1/scan/history", | |
| "alerts": "GET /api/v1/alerts", | |
| "analyze_text": "POST /api/v1/analyze/text (raw, no auth)", | |
| "analyze_image": "POST /api/v1/analyze/image (raw, no auth)", | |
| }, | |
| }) | |
| return app | |
| # Create the app instance | |
| app = create_app() | |
| if __name__ == "__main__": | |
| import uvicorn | |
| settings = get_settings() | |
| uvicorn.run( | |
| "app.main:app", | |
| host=settings.host, | |
| port=settings.port, | |
| reload=not settings.is_production, | |
| ) | |