Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
| import asyncio | |
| from contextlib import asynccontextmanager | |
| import os | |
| import threading | |
| from dotenv import load_dotenv | |
| from fastapi.responses import RedirectResponse | |
| from config import SanatanConfig | |
| from db import SanatanDatabase | |
| from drive_downloader import ZipDownloader | |
| from modules.firebase.listener import start_firestore_listener | |
| import uvicorn | |
| from fastapi import FastAPI | |
| from modules.dropbox.audio import cleanup_audio_url_cache | |
| # from modules.home.app import home_app | |
| from modules.youtube_metadata.app import initialize_youtube_metadata_and_poll, youtube_metadata_app | |
| from server import router as mobile_router | |
| # from app import gradio_app # your Blocks object | |
| import gradio as gr | |
| import logging | |
| from fastapi import Request | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.staticfiles import StaticFiles | |
| from slowapi import Limiter, _rate_limit_exceeded_handler | |
| from slowapi.util import get_remote_address | |
| from slowapi.errors import RateLimitExceeded | |
| from contextlib import asynccontextmanager | |
| logging.basicConfig(level=logging.INFO) | |
| logger = logging.getLogger() | |
| logger.setLevel(logging.INFO) | |
| def init(): | |
| logger.info("Application Initializing ...") | |
| load_dotenv(override=True) | |
| try: | |
| SanatanDatabase().test_sanity() | |
| except Exception as e: | |
| logger.warning("Sanity Test Failed - %s", e) | |
| logger.info("Downloading database ...") | |
| downloader = ZipDownloader( | |
| service_account_json=os.getenv("GOOGLE_SERVICE_ACCOUNT_JSON") | |
| ) | |
| zip_path = downloader.download_zip_from_drive( | |
| file_id=os.getenv("CHROMADB_FILE_ID"), | |
| output_path=SanatanConfig.dbStorePath, | |
| ) | |
| downloader.unzip(zip_path, extract_to="./") | |
| # add global index | |
| # delete taniyan records | |
| logger.info("STARTED: Deleting Taniyans ...") | |
| sanatanDatabase = SanatanDatabase() | |
| sanatanDatabase.delete_taniyans_in_divya_prabandham() | |
| logger.info("STARED: Building Global Index for all scriptures ...") | |
| sanatanDatabase.build_global_index_for_all_scriptures() | |
| logger.info("FINISHED: Building Global Index for all scriptures ...") | |
| # Launch the whole thing in a background thread | |
| logger.info("STARTED: Initializing youtube metadata poller...") | |
| yt_init_thread = threading.Thread(target=initialize_youtube_metadata_and_poll, daemon=True) | |
| yt_init_thread.start() | |
| logger.info("FINISHED: Initializing youtube metadata poller...") | |
| async def fn_lifespan(app: FastAPI): | |
| logging.info("π Starting Lifespan ...") | |
| ###### Initialize the database ###### | |
| init() | |
| ###### Initialize the database ###### | |
| logging.info("π Starting Firestore listener...") | |
| start_firestore_listener() | |
| yield | |
| logging.info("π Firestore listener shutdown (no explicit cleanup needed).") | |
| app = FastAPI(title="Sanatan AI Unified Server",lifespan=fn_lifespan) | |
| limiter = Limiter(key_func=get_remote_address) | |
| app.state.limiter = limiter | |
| app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler) | |
| # Allow all origins (for dev) | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], # or ["https://your-flutter-web-app.com"] | |
| allow_credentials=True, | |
| allow_methods=["*"], # GET, POST, PUT, DELETE, OPTIONS | |
| allow_headers=["*"], # e.g. Authorization, Content-Type | |
| ) | |
| # Mount mobile endpoints | |
| app.include_router(mobile_router, prefix="/api") | |
| # Convert Gradio Blocks to ASGI app | |
| # app = gr.mount_gradio_app(app, gradio_app,"/sanatan_ai_web") | |
| # app = gr.mount_gradio_app(app, youtube_metadata_app,"/yt_web") | |
| ##### Commenting out to bypass GRADIO ISSUES ON 24-Nov-2025 | |
| # app = gr.mount_gradio_app(app, home_app,"/web") | |
| from fastapi.responses import FileResponse | |
| async def firebase_sw(): | |
| return FileResponse("static/firebase-messaging-sw.js") | |
| app.mount("/home", StaticFiles(directory="static", html=True), name="static") | |
| # Redirect root URL to /home/ | |
| async def redirect_to_web(): | |
| return RedirectResponse(url="/home/") | |
| async def log_requests(request: Request, call_next): | |
| logging.info(f"Request: {request.method} {request.url}") | |
| response = await call_next(request) | |
| logging.info(f"Response status: {response.status_code}") | |
| return response | |
| async def lifespan(app: FastAPI): | |
| # Startup code: start cache cleanup | |
| asyncio.create_task(cleanup_audio_url_cache()) | |
| yield | |
| # Shutdown code (optional) can go here | |
| if __name__ == "__main__": | |
| uvicorn.run("main:app", host="0.0.0.0", port=7860, reload=False, access_log=False, log_level=logging.WARNING) | |