mirror of
https://github.com/kennethreitz/responder.git
synced 2026-07-21 18:39:29 +00:00
428181a096
Flagship: JWTAuth (HS256/RS256/ES256, exp/aud/iss, JWKS with off-loop fetch, scope claims -> requires()) and OAuth2Auth flow descriptions that light up Swagger UI's Authorize button, behind a new responder[jwt] extra. Also additive: responder.Problem (raisable RFC 9457) + RFC 9457 abort(); @api.middleware function-style HTTP middleware; Pydantic bodies and Query/Header/Cookie/Path markers on class-based and WebSocket handlers; Form-model binding; write-side preconditions (If-Match/If-Unmodified-Since -> 412); q-ranked content negotiation; get_list for repeated headers; status_code= route option; OpenAPI document caching; rate-limiter key=/ fail-open/X-RateLimit-Reset; configurable metrics buckets + in-flight gauge; RFC 8288 pagination Link headers; Redis session serializer; unified request-ID policy; CLI --host/--port/--server/--reload; optional orjson encode backend; AsyncTestClient + SSE test helpers; fakeredis backend coverage. Five DeprecationWarnings start the 9.0 clock. Every feature was implemented test-first, then the combined diff went through a 64-agent adversarial review that caught 19 issues including two criticals (an auth scope-claim regression that flipped authorization decisions, and a sync-middleware threadpool deadlock) -- all fixed with regression tests before release. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
113 lines
4.3 KiB
ReStructuredText
113 lines
4.3 KiB
ReStructuredText
Deprecations (the road to v9)
|
|
=============================
|
|
|
|
Responder 8.1 starts the deprecation clock for a handful of legacy behaviors
|
|
that will change or be removed in Responder 9.0. Each emits a
|
|
``DeprecationWarning`` (with a migration hint) when the deprecated path runs
|
|
— and *only* then; normal usage stays silent. **Behavior is unchanged until
|
|
9.0**: the warnings exist so you can migrate on your own schedule.
|
|
|
|
Run your test suite with warnings surfaced to find any usages::
|
|
|
|
python -W error::DeprecationWarning -m pytest
|
|
|
|
``api.session()`` — use ``api.requests``
|
|
----------------------------------------
|
|
|
|
The legacy test-client accessor ``api.session()`` is deprecated and will be
|
|
removed in 9.0. Use the :attr:`~responder.API.requests` property instead::
|
|
|
|
# Deprecated
|
|
r = api.session().get("http://;/hello")
|
|
|
|
# Preferred
|
|
r = api.requests.get("http://;/hello")
|
|
|
|
If you relied on ``session(base_url=...)`` for a custom base URL, construct
|
|
the client directly::
|
|
|
|
from starlette.testclient import TestClient
|
|
|
|
client = TestClient(api, base_url="http://testserver")
|
|
|
|
``PORT`` overriding an explicit ``port=``
|
|
-----------------------------------------
|
|
|
|
Today, ``api.run()`` / ``api.serve()`` let the ``PORT`` environment variable
|
|
silently override an explicitly passed ``port=`` argument. Starting with 9.0,
|
|
an explicit ``port=`` will take precedence over the environment. A warning is
|
|
emitted only when both are set *and disagree*; setting just one (or both to
|
|
the same value) stays silent::
|
|
|
|
# PORT=9000 in the environment:
|
|
api.run(port=8000) # DeprecationWarning; binds 9000 today, 8000 in v9
|
|
api.run(port=9000) # no warning
|
|
api.run() # no warning; binds 9000
|
|
|
|
To keep the current behavior explicitly, resolve the environment yourself::
|
|
|
|
api.run(port=int(os.environ.get("PORT", 8000)))
|
|
|
|
Bare ``add_route()`` static fallback
|
|
------------------------------------
|
|
|
|
Calling ``api.add_route(route)`` with no endpoint currently registers an
|
|
implicit *default* route that serves ``static/index.html`` for every
|
|
unmatched request. This implicit behavior will be removed in 9.0. Pass an
|
|
endpoint explicitly instead::
|
|
|
|
# Deprecated: implicit static fallback
|
|
api.add_route("/")
|
|
|
|
# Preferred: an explicit catch-all view
|
|
async def spa(req, resp):
|
|
resp.html = (pathlib.Path("static") / "index.html").read_text()
|
|
|
|
api.add_route("/", spa, default=True)
|
|
|
|
Static *assets* are unaffected — the ``static_dir`` / ``static_route`` mount
|
|
keeps working as-is.
|
|
|
|
Lossy ``Decimal``-to-float JSON serialization
|
|
---------------------------------------------
|
|
|
|
Assigning a bare :class:`decimal.Decimal` to ``resp.media`` currently
|
|
serializes it as a JSON float, silently losing precision. Responder 9.0 will
|
|
serialize ``Decimal`` values as strings instead. A warning is emitted once
|
|
per process the first time a ``Decimal`` reaches the built-in encoder.
|
|
|
|
Choose a representation explicitly to be forward-compatible::
|
|
|
|
resp.media = {"price": str(total)} # exact, matches v9's default
|
|
resp.media = {"price": float(total)} # current behavior, silenced
|
|
|
|
or keep floats everywhere with a custom encoder (a user ``encoder=`` handles
|
|
``Decimal`` before the built-in fallback, so no warning is emitted)::
|
|
|
|
def encoder(obj):
|
|
if isinstance(obj, decimal.Decimal):
|
|
return float(obj)
|
|
raise TypeError # fall back to the built-in conversions
|
|
|
|
api = responder.API(encoder=encoder)
|
|
|
|
GraphQL: ``400`` with partial data
|
|
-----------------------------------
|
|
|
|
The GraphQL extension currently returns HTTP ``400`` whenever the execution
|
|
result contains errors — even when ``data`` is non-null (a *partial* result,
|
|
e.g. one resolver failed while others succeeded). Per the
|
|
`GraphQL-over-HTTP specification
|
|
<https://graphql.github.io/graphql-over-http/>`_, such well-formed responses
|
|
should be served with ``200``; Responder 9.0 will do so. A warning is emitted
|
|
once per process when a partial-data ``400`` is served.
|
|
|
|
Requests that produce *no* data (validation or request errors) keep their
|
|
``400`` in 9.0 as well — only the partial-data case changes. To be
|
|
forward-compatible, inspect the ``errors`` key of the response body instead
|
|
of relying on the status code::
|
|
|
|
result = client.post("/graph", json={"query": query}).json()
|
|
if result.get("errors"):
|
|
... # handle errors, regardless of HTTP status
|