v3.11.0
Highlights
HTTP range requests. resp.file() and resp.stream_file() now answer Range: bytes=... with 206 Partial Content — video seeking and resumable downloads work out of the box. Suffix ranges (bytes=-500), open-ended ranges (bytes=100-), 416 for unsatisfiable ranges, and Accept-Ranges advertised automatically. stream_file seeks instead of reading the whole file, so partial reads of huge files stay cheap.
Download helper. Serve attachments in one call — streamed, resumable, with RFC 5987-encoded filenames:
@api.route("/export")
def export(req, resp):
resp.download("reports/annual.pdf", filename="Annual Report.pdf")Request timeouts. The third leg of resource protection (after size limits and rate limiting):
api = responder.API(request_timeout=30) # overruns get a 504Content-negotiated error bodies, and dependency teardowns still run on timeout.
Performance
- Route resolution is now cached per
(method, path)with invalidation on registration — ~10% faster dispatch at 81 routes, and the gain grows with route count.
Full changelog: https://github.com/kennethreitz/responder/blob/main/CHANGELOG.md