Spaces:
Running
Running
| """ | |
| OptiQ API — FastAPI entry point. | |
| Serves the hybrid Quantum-AI-Classical optimization pipeline. | |
| Extended for SaaS platform with authentication, analytics, and reporting. | |
| """ | |
| from __future__ import annotations | |
| import sys | |
| import os | |
| # Ensure project root is on the path so ``from src.*`` and ``from config`` work. | |
| sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |
| # Load .env file if present | |
| try: | |
| from dotenv import load_dotenv | |
| load_dotenv(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), ".env")) | |
| except ImportError: | |
| pass | |
| from pathlib import Path | |
| from fastapi import FastAPI, Request | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.staticfiles import StaticFiles | |
| from fastapi.responses import FileResponse | |
| from config import CFG | |
| # Initialize database on startup | |
| from api.database import init_db | |
| init_db() | |
| # Import routers | |
| from api.routes.baseline import router as baseline_router | |
| from api.routes.optimize import router as optimize_router | |
| from api.routes.compare import router as compare_router | |
| from api.routes.validate import router as validate_router | |
| from api.routes.grid import router as grid_router | |
| from api.routes.simulate import router as simulate_router | |
| from api.routes.digital_twin import router as digital_twin_router | |
| from api.routes.usage import router as usage_router | |
| from api.routes.audit import router as audit_router | |
| from api.routes.roi import router as roi_router | |
| from api.routes.report import router as report_router | |
| from api.routes.auth_routes import router as auth_router | |
| app = FastAPI( | |
| title="OptiQ SaaS API", | |
| description=( | |
| "AI-Powered Distribution Grid Reconfiguration Platform. " | |
| "Hybrid Quantum-AI-Classical optimization for power distribution networks. " | |
| "Reduces grid losses by 30%+ through intelligent network reconfiguration." | |
| ), | |
| version="1.0.0", | |
| ) | |
| # CORS — allow the frontend (and any origin during dev) | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=CFG.api.cors_origins, | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # Register routers | |
| app.include_router(baseline_router, prefix="/api", tags=["Baseline"]) | |
| app.include_router(optimize_router, prefix="/api", tags=["Optimize"]) | |
| app.include_router(compare_router, prefix="/api", tags=["Compare"]) | |
| app.include_router(validate_router, prefix="/api", tags=["Validate"]) | |
| app.include_router(grid_router, prefix="/api", tags=["Grid"]) | |
| app.include_router(simulate_router, prefix="/api", tags=["Simulate"]) | |
| app.include_router(digital_twin_router, prefix="/api", tags=["Digital Twin"]) | |
| app.include_router(usage_router, prefix="/api", tags=["Usage"]) | |
| app.include_router(audit_router, prefix="/api", tags=["Audit"]) | |
| app.include_router(roi_router, prefix="/api", tags=["ROI"]) | |
| app.include_router(report_router, prefix="/api", tags=["Report"]) | |
| app.include_router(auth_router, prefix="/api", tags=["Auth"]) | |
| def health(): | |
| return {"status": "ok", "project": "OptiQ", "version": "1.0.0"} | |
| # ── Serve React frontend from /frontend/dist ───────────────────────────── | |
| _PROJECT_ROOT = Path(__file__).resolve().parent.parent | |
| _FRONTEND_DIST = _PROJECT_ROOT / "frontend" / "dist" | |
| if _FRONTEND_DIST.is_dir(): | |
| # Serve static assets (JS, CSS, images, etc.) | |
| app.mount("/assets", StaticFiles(directory=_FRONTEND_DIST / "assets"), name="assets") | |
| # Catch-all: serve index.html for any non-API route (SPA client-side routing) | |
| async def serve_spa(request: Request, full_path: str): | |
| # If a static file exists at the path, serve it directly | |
| file_path = _FRONTEND_DIST / full_path | |
| if full_path and file_path.is_file(): | |
| return FileResponse(file_path) | |
| # Otherwise serve index.html for client-side routing | |
| return FileResponse(_FRONTEND_DIST / "index.html") | |
| else: | |
| def root_no_frontend(): | |
| return {"message": "OptiQ API running. Build frontend with: cd frontend && npm run build"} | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run( | |
| "api.main:app", | |
| host=CFG.api.host, | |
| port=CFG.api.port, | |
| reload=CFG.api.reload, | |
| ) | |