Spaces:
Sleeping
Sleeping
| import os | |
| import sys | |
| from pathlib import Path | |
| from fastapi import FastAPI | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import FileResponse, RedirectResponse | |
| from fastapi.staticfiles import StaticFiles | |
| from dotenv import load_dotenv, find_dotenv | |
| # Ensure project root on sys.path for package imports | |
| ROOT_DIR = Path(__file__).resolve().parent | |
| if str(ROOT_DIR) not in sys.path: | |
| sys.path.append(str(ROOT_DIR)) | |
| # Load environment (HF Spaces will inject secrets via env vars) | |
| load_dotenv(find_dotenv(), override=True) | |
| app = FastAPI(title="Flagship AI", version="0.1.0") | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # --- Static assets (shared Suite styles/header) --- | |
| SUITE_STATIC_DIR = (ROOT_DIR / "Suite" / "app" / "static").resolve() | |
| app.mount("/static", StaticFiles(directory=str(SUITE_STATIC_DIR)), name="static") | |
| # --- Include routers from agents that already use prefixed routes --- | |
| # UX Prototyper uses router prefix '/ux' | |
| try: | |
| from AIDesign.app.main import router as ux_router # type: ignore | |
| app.include_router(ux_router) | |
| except Exception: | |
| # Optional: keep the app booting even if module missing | |
| pass | |
| # Slack Knowledge Bot uses router prefix '/slack' | |
| try: | |
| from AIIntegration.app.main import router as slack_router # type: ignore | |
| app.include_router(slack_router) | |
| except Exception: | |
| pass | |
| # AI Readiness Audit uses router prefix '/audit' | |
| try: | |
| print("Attempting to import AIReadiness...") | |
| from AIReadiness.app.main import router as audit_router # type: ignore | |
| print(f"Successfully imported AIReadiness router: {audit_router}") | |
| print(f"Router prefix: {audit_router.prefix}") | |
| app.include_router(audit_router) | |
| print("Successfully included AIReadiness router") | |
| except Exception as e: | |
| print(f"Failed to import AIReadiness router: {e}") | |
| import traceback | |
| traceback.print_exc() | |
| pass | |
| # Additional prefixed routers | |
| for mod_path, name in ( | |
| ("AIAccessibility.app.main", "access_router"), | |
| ("AIAutomation.app.main", "automation_router"), | |
| ("AIStrategy.app.main", "strategy_router"), | |
| ("AIFit.app.main", "fit_router"), | |
| ("AIDual.app.main", "dual_router"), | |
| ("AIQuiz.app.main", "quiz_router"), | |
| ("AIRoute.app.main", "route_router"), | |
| ("AISaas.app.main", "saas_router"), | |
| ): | |
| try: | |
| print(f"Importing {mod_path}...") | |
| module = __import__(mod_path, fromlist=["router"]) # type: ignore | |
| router = getattr(module, "router") | |
| print(f"Successfully imported {name}: {router}") | |
| print(f"Router routes: {[route.path for route in router.routes]}") | |
| app.include_router(router) # type: ignore | |
| print(f"Successfully included {name}") | |
| except Exception as e: | |
| print(f"Failed to import {mod_path}: {e}") | |
| import traceback | |
| traceback.print_exc() | |
| pass | |
| # --- Mount full apps where clean scoping is needed --- | |
| # Opportunity Planner (AISolutions) has unprefixed routes; mount under '/solutions' | |
| try: | |
| from AISolutions.app.main import app as solutions_app # type: ignore | |
| app.mount("/solutions", solutions_app) | |
| except Exception: | |
| pass | |
| # Include routers with proper prefixes | |
| try: | |
| from AIArchitecture.app.main import router as arch_router # type: ignore | |
| app.include_router(arch_router) | |
| except Exception: | |
| pass | |
| try: | |
| from AICommerce.app.main import router as commerce_router # type: ignore | |
| app.include_router(commerce_router) | |
| except Exception: | |
| pass | |
| # AIAutomation is now included in the loop above | |
| try: | |
| from AIHealthcare.app.main import router as healthcare_router # type: ignore | |
| app.include_router(healthcare_router) | |
| except Exception: | |
| pass | |
| # These routers are already included by the loop above | |
| # --- Index routes for top-level and agent landings --- | |
| def suite_index() -> FileResponse: | |
| """Serve the Flagship Suite landing page.""" | |
| return FileResponse((SUITE_STATIC_DIR / "index.html").as_posix()) | |
| def ux_index() -> FileResponse: | |
| base = ROOT_DIR / "AIDesign" / "app" / "static" / "index.html" | |
| return FileResponse(base.as_posix()) | |
| def slack_index() -> FileResponse: | |
| base = ROOT_DIR / "AIIntegration" / "app" / "static" / "index.html" | |
| return FileResponse(base.as_posix()) | |
| # Audit route is now handled by the AIReadiness router | |
| # Static index shortcuts for mounted apps and prefixed routers | |
| def solutions_index_redirect() -> RedirectResponse: | |
| # Mounted app handles this; ensure trailing slash variant resolves | |
| return RedirectResponse(url="/solutions/") | |
| # These routes are now handled by their respective routers | |
| def triage_index() -> FileResponse: | |
| base = ROOT_DIR / "AIHealthcare" / "app" / "static" / "index.html" | |
| return FileResponse(base.as_posix()) | |
| # Invoice route is now handled by the AIAutomation router | |
| # These routes are now handled by their respective routers | |
| # Optional health endpoint for the aggregator | |
| def healthz() -> dict: | |
| return { | |
| "status": "ok", | |
| "openai_key": bool(os.getenv("OPENAI_API_KEY")), | |
| "version": "0.1.0", | |
| } | |