Skip to content

[REF] ui: migrate TemplateResponse to Starlette 1.x, unpin starlette - #191

Merged
beorngb merged 2 commits into
mainfrom
feat/starlette-1x
Aug 27, 2026
Merged

[REF] ui: migrate TemplateResponse to Starlette 1.x, unpin starlette#191
beorngb merged 2 commits into
mainfrom
feat/starlette-1x

Conversation

@beorngb

@beorngb beorngb commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

Closes #181. Supersedes #189.

Starlette 1.x removed TemplateResponse(name, context) in favour of
(request, name, context); on 1.x the old shape raises
TypeError: unhashable type: 'dict' because the context is taken for the
template name. All 110 call sites used the old form, which is what has kept
the dependency pinned since July.

Migration

Every call had the identical shape (two positional args, no kwargs) and every
enclosing handler already took a request parameter, so the transform is one
inserted argument at each site — 35 files, 110 lines, nothing else. Located via
the AST rather than a text match, and the result re-parsed per file before
writing.

The new form is also accepted by 0.x, so that commit stands on its own.

Dependencies

  • starlette>=1.0.0,<2.0.0
  • fastapi>=0.135.0 — 0.131 caps starlette<1.0.0, so leaving the old floor
    would let the resolver fall back to the pinned line without saying so.
  • The Dockerfile carried a second, independent pin (uv pip install --system "starlette<1.0.0" after the project install). Left in place it would
    have kept the container on 0.x while CI validated 1.x, with nothing to reveal
    the divergence.
  • The ten starlette advisories waived in pip-audit under a reachability audit
    are gone from ci.yml; the two unrelated waivers remain.

Verified

  • 705 unit tests pass under starlette 1.6.0.
  • The anyio monkeypatch in ui/app.py (CancelScope._deliver_cancellation, the
    CPU-leak throttle) still matches: the target survives on anyio 4.14.2 with the
    same signature. This was the main unknown flagged on Migrate TemplateResponse to Starlette 1.x signature (unpin starlette, clear CVEs) #181.
  • Container rebuilt on starlette 1.6.0 / fastapi 0.139.0: boots clean, login and
    forgot-password render (HTTP 200, full HTML), protected routes still redirect,
    all 10 stdio MCP servers connect with no failures.
  • OSV reports 10 advisories for starlette 0.50.0 and none for 1.6.0.

Starlette 1.x removed the positional `(name, context)` form in favour of
`(request, name, context)`; on 1.x the old shape raises TypeError because the
context dict is taken for the template name. All 110 call sites carried the
old form, which is what held the dependency back.

Every call had the same shape and every enclosing handler already took a
`request` parameter, so the change is one inserted argument throughout. The
new form is accepted by 0.x as well, so this stands on its own.
Now that no call site depends on the pre-1.0 signature, starlette moves to
>=1.0.0,<2.0.0. The fastapi floor rises to 0.135.0 because 0.131 caps
starlette below 1.0, which would silently resolve back to the old line.

The Dockerfile carried a second, independent pin that reinstalled
starlette<1.0.0 after the project install. Left in place it would have kept
the container on the old line while CI validated the new one — the two
environments disagreeing with nothing to reveal it.

Starlette 0.50.0 carries ten advisories, all fixed on 1.x, which were waived
in pip-audit under a reachability audit. The waivers are removed; only the two
unrelated ones remain.
@beorngb
beorngb merged commit b193c40 into main Aug 27, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate TemplateResponse to Starlette 1.x signature (unpin starlette, clear CVEs)

1 participant