""" FastAPI URL Blink Application Production-grade API for receiving encrypted user data, decrypting it, and storing in SQLite database. """ import os import logging from contextlib import asynccontextmanager from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from core.database import init_db from routers import auth, blink, general, gemini from services.drive_service import DriveService # Configure logging logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" ) logger = logging.getLogger(__name__) # Initialize Drive Service drive_service = DriveService() @asynccontextmanager async def lifespan(app: FastAPI): """ Application lifespan manager. Initializes database on startup. """ logger.info("Starting up - initializing database...") # Check for RESET_DB environment variable if os.getenv("RESET_DB", "").lower() == "true": logger.warning("RESET_DB is set to true. Skipping download and clearing local database.") if os.path.exists("blink_data.db"): os.remove("blink_data.db") logger.info("Local database deleted.") else: # Startup: Download DB from Drive logger.info("Startup: Attempting to download database from Google Drive...") drive_service.download_db() await init_db() logger.info("Database initialized successfully") # Start background job worker from services.job_worker import start_worker, stop_worker await start_worker() logger.info("Background job worker started") yield # Stop background job worker await stop_worker() logger.info("Background job worker stopped") # Shutdown: Upload DB to Drive logger.info("Shutdown: Uploading database to Google Drive...") drive_service.upload_db() logger.info("Shutting down...") # Create FastAPI application app = FastAPI( title="APIGateway", description="API for receiving and processing encrypted user data", version="1.0.0", lifespan=lifespan ) # Configure CORS app.add_middleware( CORSMiddleware, allow_origins=["*"], # Configure appropriately for production allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Include Routers app.include_router(general.router) app.include_router(auth.router) app.include_router(blink.router) app.include_router(gemini.router) @app.exception_handler(Exception) async def global_exception_handler(request: Request, exc: Exception): """ Global exception handler for unhandled errors. """ logger.error(f"Unhandled exception: {exc}") return JSONResponse( status_code=500, content={"detail": "Internal server error"} ) if __name__ == "__main__": import uvicorn uvicorn.run( "app:app", host="0.0.0.0", port=8000, reload=True, log_level="info" )