Skip to content

v3.7.0

Choose a tag to compare

@kennethreitz kennethreitz released this 12 Jun 01:08
· 14 commits to main since this release

Highlights

Dependency injection for route handlers. Register providers with @api.dependency() and declare them as view parameters by name — no marker imports required:

@api.dependency()
async def db():
    session = await create_session()
    yield session          # injected into views
    await session.close()  # teardown after the response

@api.route("/users/{id:int}")
async def get_user(req, resp, *, id, db):
    resp.media = await db.fetch_user(id)

Providers can be sync/async functions or generators (post-yield code runs as teardown). Providers taking a parameter receive the current Request. Each dependency resolves at most once per request, and path parameters take precedence on name collisions.

Per-route rate limiting. Apply @limiter.limit beneath @api.route() to give a single endpoint its own budget.

WebSocket rejection. Closing the socket in a before_request(websocket=True) hook now skips the route handler entirely. Sync WebSocket hooks are also supported.

Fixes

  • {value:float} path convertor matched garbage like 1a5 (unescaped regex dot) and crashed with a 500 — now a 404
  • Literal route characters are regex-escaped, so /file.json no longer matches /fileXjson
  • Unbounded memory growth in BackgroundQueue — completed futures are pruned
  • req.media("form") crashed when the Content-Type header was missing
  • Custom formats registered on api.formats were silently ignored — they now reach request parsing and response negotiation
  • Content negotiation returned an empty body for encode-incapable Accept formats — now falls through to JSON

Plus small per-request performance wins: cached Request.url/Request.params, and format registries are no longer rebuilt twice per request.

Full changelog: https://github.com/kennethreitz/responder/blob/main/CHANGELOG.md

PyPI: https://pypi.org/project/responder/3.7.0/