"""Serves openapi.yaml and renders it as browsable API docs.
Uses Redoc, not Swagger UI: the local server is unauthenticated by default, so
the viewer must not be able to execute requests.
"""
import os
from aiohttp import web
SPEC_PATH = os.path.join(
os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "openapi.yaml"
)
# The spec URL is relative so it resolves from both /api-docs and /api/api-docs.
# The viewer is pinned and loaded from a CDN, so the page needs network access;
# if it fails to load, the fallback below points at the locally served spec.
API_DOCS_HTML = """
ComfyUI API Reference
The API docs viewer is loaded from a CDN and could not be reached. The
specification itself is served locally:
openapi.yaml
"""
def add_api_docs_routes(routes: web.RouteTableDef) -> None:
"""Register /openapi.yaml and /api-docs on the given route table."""
@routes.get("/openapi.yaml")
async def get_openapi_spec(request):
# The spec is edited in place during development, so never let the
# browser hold a stale copy. no-cache still allows a 304 via the ETag
# FileResponse sets, which matters for a ~230 KB file.
return web.FileResponse(SPEC_PATH, headers={
"Content-Type": "application/yaml",
"Cache-Control": "no-cache",
})
@routes.get("/api-docs")
async def get_api_docs(request):
return web.Response(
text=API_DOCS_HTML,
content_type="text/html",
headers={"Cache-Control": "no-cache"},
)