feat: bump FastAPI to 0.136.3 and Starlette to 1.2.1#379
Conversation
Move fastapi from >=0.119.1,<0.120 to >=0.136.3,<0.137 in both the PyPI and pixi dependency blocks. Newer fastapi dropped its starlette <0.49 upper bound (fastapi-core 0.136.3 requires starlette >=0.46.0), which unblocks starlette; pixi update pulled starlette 0.48.0 -> 1.2.1. Reviewed fastapi 0.120->0.136 breaking changes; the only ones touching this codebase are 0.132 strict_content_type (JSON body endpoints) and the starlette 1.0 major bump under the middleware/StaticFiles stack. NOTE: test suite still needs to be re-run against starlette 1.2.1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a regression test asserting that a JSON body sent without an application/json Content-Type is rejected (mapped to 400 by the app's validation_exception_handler) rather than silently parsed as it was pre-fastapi-0.132. Guards the strict_content_type default introduced by the fastapi 0.136.3 bump. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Starlette 1.x deprecates using httpx with its TestClient and prefers httpx2. fileglancer has no direct httpx usage (only the test client consumes it), so add httpx2 >=2.2.0,<3 as a test dependency in both the pixi test feature and the PyPI test extra. This silences the StarletteDeprecationWarning; the runtime httpx dependency is left as-is. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fileglancer's code never imports httpx directly; it is only consumed by starlette's TestClient at test time. httpx is also guaranteed by the fastapi (standard) meta-package, which depends on httpx as part of its standard bundle, so removing the explicit pin does not drop httpx from the environment. Remove the redundant declaration from both the PyPI and pixi runtime dependency blocks. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
How this compares to #377Both this PR and #377 land at the same resolved versions in the dev env ( 1. Capping vs. uncapping. #377 reaches 0.136.3 implicitly: it removes the upper caps from 2. httpx2 as runtime vs. test dep. #377 swaps 3. Verification of the behavioral changes. Jumping 0.119 → 0.136 crosses two changes that touch this codebase — FastAPI 0.132's 4. Reviewability. #377 bundles cap-loosening + the httpx→httpx2 swap + the implicit fastapi/starlette jump into one PR with a ~9k-line lock diff. The #378 → #379 split separates the behavior-free bounds sync (#378) from the isolated, reviewed FastAPI/Starlette upgrade (this PR), so each can be evaluated on its own. In short: same destination, but this PR makes the upgrade explicit and pinned, keeps |
_file_info_from_direntry and _file_info computed rel_path via
os.path.realpath(full_path), which follows the final component. For a
broken symlink with an absolute target (e.g. "/nonexistent/path"), this
resolves to the nonexistent target. On Windows that target lands on a
different drive than the chroot, so os.path.relpath raised
ValueError ("path is on mount 'D:', start on mount 'C:'"), failing four
symlink tests on windows-latest.
Resolve only the parent directory and append the entry name, so a
symlink reports its own location relative to root rather than its
(possibly broken or cross-drive) target. name is unaffected since it
derives from basename(absolute_path).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bump FastAPI to 0.136.3 and Starlette to 1.2.1
Follow-up to #378 (stacked on
sync-dep-bounds; this PR will retarget tomainonce #378 merges). #378 deferred the FastAPI/Starlette upgrade to keep the bounds-sync change behavior-free — this PR is that upgrade.Why
FastAPI was pinned
>=0.119.1,<0.120, andfastapi-core 0.119.1capped Starlette at<0.49.0, so Starlette was stuck at 0.48.0 even though conda-forge has it through 1.2.1. Newer FastAPI (fastapi-core 0.136.3) drops that cap (starlette >=0.46.0, no upper bound), which unblocks Starlette 1.x.Changes
fastapi:>=0.119.1,<0.120→>=0.136.3,<0.137in both the PyPI and pixi blocks.starlette:0.48.0→1.2.1(viapixi update starlette; pulled in transitively, not declared directly).httpx2 >=2.2.0,<3as a test dependency (see httpx note below).httpxruntime dependency (unused by our code; still provided transitively by thefastapistandard meta-package).pixi.lockregenerated.FastAPI 0.120 → 0.136 breaking-change review
Reviewed every flagged breaking change in the range against this codebase:
fastapi.securityusagepydantic.v1ORJSONResponse/UJSONResponsestrict_content_type(default on)HeaderparamsThe two that touch us —
strict_content_typeand the Starlette 1.0 major bump — are both validated by the full suite (318 passing). Forstrict_content_typespecifically, added a regression test (test_set_preference_requires_json_content_type) asserting that a JSON body sent withoutapplication/jsonis now rejected (mapped to 400 by the app'svalidation_exception_handler) rather than silently parsed.httpx → httpx2 note
Starlette 1.x deprecates using
httpxwith itsTestClientand prefershttpx2. fileglancer has no direct httpx usage — it's consumed only by the TestClient at test time — so this is not a code migration. Addinghttpx2as a test dependency makes the TestClient prefer it and silences theStarletteDeprecationWarning. The runtimehttpxpin was redundant (FastAPI's standard meta-package guarantees httpx anyway), so it was removed.Verification
pixi run -e test pytest→ 318 passed, no warnings withfastapi 0.136.3+starlette 1.2.1+httpx2 2.3.0on Python 3.14.🤖 Generated with Claude Code