main.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. """FastAPI application entry point."""
  2. import os
  3. from fastapi import FastAPI, Request, HTTPException
  4. from fastapi.middleware.cors import CORSMiddleware
  5. from .config import APP_NAME, APP_VERSION, APP_DESCRIPTION, CORS_ORIGINS
  6. from .database import init_db
  7. from .routers import projects, plans, experience, generation, analytics, ai, search, ai_plan, analysis, adaptive, tasks, monitor, reports
  8. app = FastAPI(
  9. title=APP_NAME,
  10. version=APP_VERSION,
  11. description=APP_DESCRIPTION,
  12. )
  13. # CORS middleware (allow frontend dev server)
  14. app.add_middleware(
  15. CORSMiddleware,
  16. allow_origins=CORS_ORIGINS,
  17. allow_credentials=True,
  18. allow_methods=["*"],
  19. allow_headers=["*"],
  20. )
  21. # E4 fix: optional API key authentication middleware.
  22. # Enabled only when AFM_API_KEY is set in environment.
  23. _API_KEY = os.environ.get("AFM_API_KEY", "").strip()
  24. _PUBLIC_PATHS = ("/api/health", "/docs", "/openapi.json", "/redoc", "/")
  25. @app.middleware("http")
  26. async def api_key_auth(request: Request, call_next):
  27. """Optional API key authentication (E4 fix)."""
  28. if not _API_KEY:
  29. return await call_next(request)
  30. path = request.url.path
  31. if any(path.startswith(p) for p in _PUBLIC_PATHS):
  32. return await call_next(request)
  33. provided = request.headers.get("X-API-Key", "")
  34. if provided != _API_KEY:
  35. raise HTTPException(status_code=401, detail="Invalid or missing API key")
  36. return await call_next(request)
  37. # Include routers
  38. app.include_router(projects.router)
  39. app.include_router(plans.router)
  40. app.include_router(experience.router)
  41. app.include_router(generation.router)
  42. app.include_router(analytics.router)
  43. app.include_router(ai.router)
  44. app.include_router(search.router)
  45. app.include_router(ai_plan.router)
  46. app.include_router(analysis.router)
  47. app.include_router(adaptive.router)
  48. app.include_router(tasks.router)
  49. app.include_router(monitor.router)
  50. app.include_router(reports.router)
  51. @app.on_event("startup")
  52. def on_startup():
  53. """Initialize database on startup."""
  54. init_db()
  55. @app.get("/api/health")
  56. def health_check():
  57. """Health check endpoint."""
  58. return {"status": "ok", "app": APP_NAME, "version": APP_VERSION}
  59. @app.get("/")
  60. def root():
  61. """Root endpoint - redirect to API docs."""
  62. return {
  63. "message": APP_NAME,
  64. "version": APP_VERSION,
  65. "docs": "/docs",
  66. "api_health": "/api/health",
  67. }