Skip to content

fix(deps): raise the opentelemetry and fastapi floors - #187

Merged
lesnik512 merged 1 commit into
mainfrom
fix/otel-fastapi-floors
Sep 20, 2026
Merged

lesnik512 merged 1 commit into
mainfrom
fix/otel-fastapi-floors

Conversation

@lesnik512

Copy link
Copy Markdown
Member

Last two floors from the audit started in #185 and continued in #186. Origin: modern-python/.github#107.

1. opentelemetry

opentelemetry-api>=1.20 / opentelemetry-sdk>=1.20, but the telemetry middleware passes schema_url to get_meter, which 1.21 added:

TypeError: get_meter() got an unexpected keyword argument 'schema_url'

5 failures in tests/test_middleware_opentelemetry.py. 1.20.0 fails; 1.21.0 and every version after it passes. Raised to >=1.21 in both the extra and the dev group.

2. fastapi

fastapi>=0.95 resolves to 0.100.0, and the FastAPI router does not build against it:

TypeError: must be called with a dataclass type or instance

Bisected on 3.11, with an httpx the resolved starlette can actually use (see the note below, the first attempt at this measured the wrong thing):

fastapi starlette tests/test_fastapi.py
0.100.0, 0.110.0, 0.112.0 0.27.0 – 0.37.2 6 failed, 4 passed
0.113.0 0.38.6 10 passed
0.114.0, 0.115.0 0.38.6 10 passed

Raised to >=0.113. Unmarked: no interpreter in the supported range works below it, so there is nothing to mark.

The lower bound is now green, and this time it is the whole suite

uv pip install --resolution lowest-direct ".[all]" plus test tooling, then the complete suite including the Postgres integration tests:

interpreter result
3.11 624 passed
3.12 624 passed
3.13 624 passed
3.14 624 passed
3.14t 624 passed

Resolved floors, for the record:

3.11 / 3.12 3.13 3.14 / 3.14t
asyncpg 0.29.0 0.30.0 0.31.0
sqlalchemy 2.0.0 2.0.31 2.0.31
pydantic 2.0.2 2.8.0 2.12.0
typing-extensions 4.12.2 4.12.2 4.14.1
fastapi 0.113.0 0.113.0 0.113.0
opentelemetry-api 1.21.0 1.21.0 1.21.0
alembic 1.13.0 1.13.0 1.13.0
prometheus-client 0.19.0 0.19.0 0.19.0

At the normal (highest) resolution nothing changes — uv.lock picks fastapi 0.141.1 and opentelemetry 1.44.0 — so this is inert for anyone not installing at the lower bound.

A measurement note worth keeping

My first pass at the fastapi bisect was wrong, and it is the kind of wrong a lower-bound CI job will hit too.

starlette 1.6 switched TestClient to httpx2, falling back to httpx with a deprecation warning, and the dev group correctly declares httpx2>=2.2. But at the fastapi floor the resolved starlette is 0.38, which knows nothing about httpx2 and calls httpx.Client(app=...) — removed in httpx 0.28. Install current httpx and every FastAPI test fails with Client.__init__() got an unexpected keyword argument 'app', which looks exactly like a floor problem and is not one.

So the test tooling a lower-bound job installs cannot simply be "current": it has to be something the resolved stack can use. Here that is httpx>=0.27,<0.28. Worth recording in modern-python/.github#107 — along with the broader point from #186 that a job which only installs would have missed four of the six floors fixed across these three PRs.

No test

Same as #185 and #186: a declared range that does not work is only observable by resolving it on a given interpreter and running the suite. A unit test reading a floor back out of pyproject.toml would restate the string. The tables above are the verification.

Verification

just lint-ci clean (eof-fixer, ruff format, ruff check, ty). Full suite against Postgres 17 at normal resolution: 624 passed, 100% coverage.

opentelemetry 1.21 added the schema_url argument to get_meter, which the
telemetry middleware passes; 1.20 raised TypeError. fastapi 0.113 is the first
release the FastAPI router builds against; 0.112 and below raise "must be
called with a dataclass type or instance".

With these the whole declared lower bound passes the full suite on every
supported interpreter.
@github-actions

Copy link
Copy Markdown

Benchmark gate

✅ gate passed

scenario msg/s delete/msg WALrec/msg WALB/msg fpi upd del dead_tup
consumer/w1/b10 1020 1.000 6.78 914 242 5000 5000 10000
consumer/w1/b100 1040 1.000 6.82 920 243 5000 5000 10000
consumer/w2/b10 1158 1.000 6.79 960 242 5000 5000 10000
consumer/w2/b100 1408 1.000 6.72 956 243 5000 5000 10000
consumer/w4/b10 1044 1.000 6.82 994 261 5000 5000 10000
consumer/w4/b100 1525 1.000 6.86 1036 244 5000 5000 10000
consumer/w1/b100/tfbs100 5407 0.010 6.07 1116 243 5000 5000 10000
producer/w1/b100 2095 0.000 3.04 584 0 0 0 0

Gated (fails the build): delete_calls + tuple counters (upd/del/ins) + the producer's insert_calls, exact; select_calls within +2; wal_records within a 10% band. msg/s, WAL bytes and total calls are informational (timing/FPI noise).

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.

1 participant