Cleanup pass over the previous commit. No behaviour change except the
cache header noted below.
app/api_docs.py (111 -> 59 lines):
- Cut the rationale comments. The file was ~32% commentary against 2-6%
in neighbouring app/ modules, and most of it argued decisions that
belong in the PR rather than the source, including a TODO explaining
why an SRI hash could not be computed.
- Inline the spec and bundle URLs into the HTML. The __TOKEN__ replace()
machinery existed only to hoist two string literals, and then needed a
comment defending its own existence.
- Drop the hand-rolled <style> block for two inline style attributes.
- Drop the os.path.isfile guard. FileResponse already answers a missing
file with a 404, so the check was a second stat for the same result.
- Serve the spec with Cache-Control: no-cache rather than no-store.
Both mean "never use a stale copy", but no-store also forbids storing
it, so every docs page load re-transferred all 230 KB. no-cache lets
the browser revalidate against the ETag FileResponse already sets; an
unchanged spec now costs a 304 instead of a full download.
tests-unit/server_test/test_api_docs.py (11 tests -> 6, 144 -> 70 lines):
- Drop the local copy of server.py's /api prefix loop and the two tests
that depended on it. They exercised the copy, not the real loop, so
they would have stayed green through a change to the thing they
claimed to protect. What actually makes prefixing work is that the
spec URL is relative, which is now asserted directly.
- Drop the static-catch-all test. It asserted aiohttp's own route
precedence against a synthetic app, and could not fail if the
registration call moved after the catch-all in server.py.
- Drop the tautological SPEC_PATH assertion, already covered by fetching
the spec through the route.
- Loosen the fallback assertions, which pinned the exact quoting and
inline-handler style of the HTML.
Claude-Session: https://claude.ai/code/session_01BvUveU9ofyGrSz3QxYeecB
openapi.yaml has been linted in CI but never reachable over HTTP. Add
--enable-api-docs (off by default) to serve it at /openapi.yaml and render
it at /api-docs.
The viewer is Redoc rather than Swagger UI specifically because it has no
request-execution feature. The local server is unauthenticated by default,
so a docs page with "Try it out" would give one-click access to
/api/interrupt, /api/free and DELETE /api/userdata/{file}.
Notes on the implementation:
- Routes are registered on PromptServer's route table, not on the app, so
they land before the web.static('/') catch-all that would shadow them.
This also means they are served at both /openapi.yaml and
/api/openapi.yaml; the docs page references the spec by a relative URL so
it resolves from either mount point.
- The spec path resolves from __file__, since ComfyUI is routinely launched
from other directories.
- Cache headers are set explicitly: the cache_control middleware only
special-cases js/css/images, so a .yaml response would otherwise be
served stale after an edit.
- /docs is left alone; it already serves embedded node help content.
The Redoc bundle comes from a pinned CDN URL, so the page needs outbound
network access. Offline installs still get the spec itself, and the page
degrades to a notice pointing at it.
Claude-Session: https://claude.ai/code/session_01BvUveU9ofyGrSz3QxYeecB