Add per-key OpenAPI document and Swagger UI portal
GET /openapi.json (X-API-Key authenticated) merges the upstream OpenAPI documents into one spec scoped to the calling key: only granted operations, paths rewritten to gateway routes, component schemas namespaced per service. GET /docs serves a Swagger UI portal that loads the key-scoped spec and injects the key into try-it-out requests. Discovery now caches the raw upstream spec documents (same 5-minute TTL), and FastAPI's built-in /docs and /openapi.json are disabled in favor of the portal routes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
77d7a50fa9
commit
d5878f6130
+6
-2
@@ -6,7 +6,7 @@ from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.responses import RedirectResponse
|
||||
from sqlalchemy import text
|
||||
|
||||
from app import config, proxy, retention, security
|
||||
from app import config, portal, proxy, retention, security
|
||||
from app.admin import routes as admin_routes
|
||||
from app.admin import stats as admin_stats
|
||||
from app.admin.deps import LoginRequired, login_redirect_handler
|
||||
@@ -111,7 +111,10 @@ async def lifespan(app: FastAPI):
|
||||
await proxy.close_client()
|
||||
|
||||
|
||||
app = FastAPI(title="API Gateway", version="2.0.0", lifespan=lifespan)
|
||||
# Built-in docs/openapi are disabled: the gateway serves its own consumer-facing
|
||||
# /docs and per-key /openapi.json (app/portal.py) at those paths instead.
|
||||
app = FastAPI(title="API Gateway", version="2.0.0", lifespan=lifespan,
|
||||
docs_url=None, redoc_url=None, openapi_url=None)
|
||||
app.add_exception_handler(LoginRequired, login_redirect_handler)
|
||||
|
||||
|
||||
@@ -127,6 +130,7 @@ def health():
|
||||
|
||||
app.include_router(admin_routes.router)
|
||||
app.include_router(admin_stats.router)
|
||||
app.include_router(portal.router)
|
||||
app.mount("/static", StaticFiles(directory=str(config.BASE_DIR / "app" / "static")), name="static")
|
||||
# The proxy catch-all (/{slug}/...) must come last so it never shadows
|
||||
# /admin, /static, /docs or /health.
|
||||
|
||||
Reference in New Issue
Block a user