Spaces:
Runtime error
Runtime error
| # main.py | |
| import asyncio | |
| import sys | |
| import os | |
| from pathlib import Path | |
| from contextlib import asynccontextmanager | |
| # ✅ MUST be set FIRST before anything async-related imports. | |
| # On Windows, Uvicorn defaults to SelectorEventLoop which does NOT support | |
| # subprocess creation (needed by Playwright to launch the browser). | |
| # ProactorEventLoop supports subprocesses on Windows. | |
| if sys.platform.startswith("win"): | |
| asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) | |
| from fastapi import FastAPI | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.staticfiles import StaticFiles | |
| # Import routers AFTER setting loop policy | |
| from routes.auth_routes import router as auth_router | |
| from routes.reports_routes import router as reports_router | |
| from routes.user_routes import user_router | |
| from routes.contact_routes import contact_router | |
| # Import SSL monitor | |
| from reports.ssl_monitor import start_ssl_monitor, stop_ssl_monitor | |
| # Import Gemini token tracker | |
| from reports.gemini_token_tracker import initialize_token_tracker | |
| # Import Website Down Detector | |
| from reports.website_down_detector import initialize_down_detector, stop_down_detector | |
| async def lifespan(app: FastAPI): | |
| """ | |
| Application lifespan manager. | |
| Starts SSL monitor, token tracker, and website downtime detector on startup. | |
| Stops all services on shutdown. | |
| """ | |
| # Start SSL monitoring service | |
| try: | |
| start_ssl_monitor() | |
| print("✅ SSL Monitor initialized") | |
| except Exception as e: | |
| print(f"⚠️ Warning: Could not start SSL Monitor: {e}") | |
| # Initialize Gemini token tracker | |
| try: | |
| await initialize_token_tracker() | |
| except Exception as e: | |
| print(f"⚠️ Warning: Could not initialize Token Tracker: {e}") | |
| # Initialize Website Down Detector | |
| try: | |
| await initialize_down_detector() | |
| print("✅ Website Down Detector initialized (monitoring every 24h)") | |
| except Exception as e: | |
| print(f"⚠️ Warning: Could not initialize Website Down Detector: {e}") | |
| print("✨ Server is ready!\n") | |
| yield | |
| # Shutdown | |
| print("\n" + "="*60) | |
| print("🛑 Shutting down WebMentAI Backend API...") | |
| print("="*60) | |
| # Stop SSL monitoring service | |
| try: | |
| stop_ssl_monitor() | |
| print("✅ SSL Monitor stopped") | |
| except Exception as e: | |
| print(f"⚠️ Warning: Error stopping SSL Monitor: {e}") | |
| # Stop Website Down Detector | |
| try: | |
| await stop_down_detector() | |
| print("✅ Website Down Detector stopped") | |
| except Exception as e: | |
| print(f"⚠️ Warning: Error stopping Website Down Detector: {e}") | |
| print("="*60 + "\n") | |
| app = FastAPI( | |
| title="WebMentAI Backend API", | |
| lifespan=lifespan | |
| ) | |
| # Mount static files directory to serve assets (like logo) | |
| assets_path = Path(__file__).parent / "assets" | |
| if assets_path.exists(): | |
| app.mount("/assets", StaticFiles(directory=str(assets_path)), name="assets") | |
| app.include_router(reports_router) | |
| app.include_router(auth_router) | |
| app.include_router(user_router) | |
| app.include_router(contact_router) | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["http://localhost:3000"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| async def home(): | |
| return {"message": "Welcome to the WebMentAI!"} | |