diff --git a/.buildinfo b/.buildinfo index 0373b38..6252e94 100644 --- a/.buildinfo +++ b/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file records the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 927e170ec6c070fcbd4e14c41825f173 +config: 5ce83980cbbb1ff8c0566b9128c91144 tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.doctrees/changes.doctree b/.doctrees/changes.doctree index 3ed61b7..5bddbeb 100644 Binary files a/.doctrees/changes.doctree and b/.doctrees/changes.doctree differ diff --git a/.doctrees/environment.pickle b/.doctrees/environment.pickle index 19f6ecc..049d6af 100644 Binary files a/.doctrees/environment.pickle and b/.doctrees/environment.pickle differ diff --git a/_modules/index.html b/_modules/index.html index d9eaf4e..b71be51 100644 --- a/_modules/index.html +++ b/_modules/index.html @@ -4,13 +4,13 @@
-
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
"""Simple in-memory rate limiter for Responder."""
+import threading
import time
from collections import defaultdict
@@ -70,6 +71,7 @@
self.max_requests = requests
self.period = period
self._buckets: dict[str, list[float]] = defaultdict(list)
+ self._lock = threading.Lock()
def _client_key(self, req):
client = req.client
@@ -81,22 +83,27 @@
now = time.time()
cutoff = now - self.period
self._buckets[key] = [t for t in self._buckets[key] if t > cutoff]
+ if not self._buckets[key]:
+ del self._buckets[key]
[docs]
def check(self, req, resp):
"""Check rate limit. Sets 429 status if exceeded."""
key = self._client_key(req)
- self._cleanup(key)
- if len(self._buckets[key]) >= self.max_requests:
- resp.status_code = 429
- resp.media = {"error": "rate limit exceeded"}
- resp.headers["Retry-After"] = str(self.period)
- return False
+ with self._lock:
+ self._cleanup(key)
+
+ if len(self._buckets[key]) >= self.max_requests:
+ resp.status_code = 429
+ resp.media = {"error": "rate limit exceeded"}
+ resp.headers["Retry-After"] = str(self.period)
+ return False
+
+ self._buckets[key].append(time.time())
+ remaining = self.max_requests - len(self._buckets[key])
- self._buckets[key].append(time.time())
- remaining = self.max_requests - len(self._buckets[key])
resp.headers["X-RateLimit-Limit"] = str(self.max_requests)
resp.headers["X-RateLimit-Remaining"] = str(remaining)
return True
@@ -127,7 +134,7 @@
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Useful Links
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
+GraphQL error responses now correctly return 400 status instead of always 200
OpenAPI docs UI now respects custom openapi_route instead of hardcoding /schema.yml
before_requests default type mismatch that could crash routes called outside the router
Blocking synchronous file I/O in Response.stream_file() — now uses async I/O via anyio
Memory leak in rate limiter (empty bucket keys never cleaned up)
Race condition in rate limiter check() — added thread-safe locking
WSGI fallback catching all TypeErrors instead of just call-signature mismatches
Pydantic request/response model validation crashing on non-dict bodies
Test assertions that could never fail (or True, < 500 patterns)
CaseInsensitiveDict missing __delitem__, pop, and setdefault overrides
assert used for input validation in OpenAPI extension (stripped by python -O)
Potential XSS in GraphiQL template endpoint injection
Dead or "" in media format detection logic
DELETE requests now participate in Pydantic request body validation
Simplified status code category check to use chained comparison
Unused method parameter from load_target()
Unused Node.js setup step from CI test workflow
Comprehensive documentation improvements across all pages
WebSocket
Backlog updated: removed implemented features, replaced HTTP/2 server push with dependency injection
uv.lock — this is a library, not an application
WebSocket
CI validation for Python 3.14, 3.14 free-threaded, and PyPy 3.11
Marimo notebook mounting docs and example
Type annotations for routes.py
Replaced deprecated asyncio.iscoroutinefunction with inspect.iscoroutinefunction ahead of Python 3.16 removal
Narrowed broad except Exception to specific exceptions in response model serialization and websocket chat example
WebSocket
Dropped Python 3.9 from CI
WSGI mount returning 400 when requesting the exact mount root path
Werkzeug 3.1.7 compatibility for trusted host validation in tests
WebSocket
RST title underline warning breaking docs CI
Read the Docs configuration (docs hosted on GitHub Pages)
WebSocket
Upgraded to Starlette 1.0
Added comprehensive docstrings across the codebase
WebSocket
Full documentation rewrite: tutorials for REST APIs, SQLAlchemy, Flask migration
Auth, WebSocket, middleware, and configuration guides
WebSocket
GitHub Pages deployment for docs
Reworked homepage prose
Rewrote CLI and API reference docs
WebSocket
Pydantic auto-validation: request_model validates input, returns 422 on failure
Pydantic auto-serialization: response_model strips extra fields from responses
WebSocket
Pydantic support for OpenAPI schema generation
Dependencies flattened: pip install responder gets everything
Core deps reduced to starlette + uvicorn
WebSocket
Removed poethepoet task runner
Multipart parser losing headers when parts have multiple headers
url_for() with typed route params ({id:int})
WebSocket
Platform: Added support for Python 3.10 - Python 3.13
CLI: responder run now also accepts a filesystem path on its <target>
@@ -222,8 +257,8 @@ argument, enabling usage on single-file applications.
CLI: responder run now also accepts URLs.
Platform: Minimum Python version is now 3.9 (dropped 3.6, 3.7, 3.8)
Dependencies: Dramatically reduced core dependency count (10 → 5)
@@ -245,8 +280,8 @@ extensions now, found within thePackaging: Migrated from setup.py to declarative pyproject.toml
Platform: Removed support for EOL Python 3.6, 3.7, 3.8
Status codes: Removed deprecated resume_incomplete and resume
@@ -254,8 +289,8 @@ aliases for HTTP 308 (marked for removal in 3.0)
CLI: responder run --build ceased to exist
Routing: Fixed dispatching static_route=None on Windows
uvicorn: --debug now maps to uvicorn’s log_level = "debug"
Update requirements to support python 3.8
Fix static app resolving
Fix template conflicts
Fix template conflicts
Fix template import
Refactor Router and Schema
ASGI 3 support
CI tests for python 3.8-dev
Route params Converters
Add search for documentation pages
Bump dependencies
Versioning issue
Multiple cookies.
Other bugfixes.
Stream support via resp.stream.
Cookie directives via resp.set_cookie.
Refactor _route_for
Resolve startup/shutdwown events
Documentations
Use Starlette’s LifeSpan middleware
Update denpendencies
Fix route.is_class_based
Fix test_500
Minor fixes for Open API
Typos
Run sync views in a threadpoolexecutor.
Support for before_request.
Fix sessions.
Potential bufix for cookies.
Bugfix for redirects.
Improvement for static file hosting.
Improve cors configuration settings.
Move GraphQL support into a built-in plugin.
CORS support
Improved exceptions.
Subtle improvements.
Packaging fix.
Interactive Documentation endpoint.
Minor improvements.
Overall improvements.
Show traceback info when background tasks raise exceptions.
api.requests.
WebSocket support.
500 support.
File upload support
Improvements to sequential media reading.
Stability.
Sessions support.
Cookies support.
Default routes.
Prototype of static application support.
Bugfix for async class-based views.
Bugfix for async class-based views.
GraphiQL Support.
Improvement to route selection.
Immutable Request object.
Ability to mount WSGI apps.
Supply content-type when serving up the schema.
OpenAPI Schema support.
Safe load/dump yaml.
Asynchronous support for data uploads.
Bug fixes.
Bug fixes.
Switch to ASGI/Starlette.
Conception!
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Host
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Useful Links
diff --git a/tour.html b/tour.html
index 0141447..baccc47 100644
--- a/tour.html
+++ b/tour.html
@@ -5,13 +5,13 @@
- Feature Tour — responder 3.6.1 documentation
+ Feature Tour — responder 3.6.2 documentation
-
+
@@ -732,7 +732,7 @@ bodies by passing &
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Useful Links
diff --git a/tutorial-auth.html b/tutorial-auth.html
index 6456af4..2e1c15e 100644
--- a/tutorial-auth.html
+++ b/tutorial-auth.html
@@ -5,13 +5,13 @@
- Authentication — responder 3.6.1 documentation
+ Authentication — responder 3.6.2 documentation
-
+
@@ -289,7 +289,7 @@ sessions for web apps with login pages.
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Useful Links
diff --git a/tutorial-flask.html b/tutorial-flask.html
index 6f20f05..b848725 100644
--- a/tutorial-flask.html
+++ b/tutorial-flask.html
@@ -5,13 +5,13 @@
- Migrating from Flask — responder 3.6.1 documentation
+ Migrating from Flask — responder 3.6.2 documentation
-
+
@@ -253,7 +253,7 @@ Responder. When you’ve moved everything over, remove the mount.
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Useful Links
diff --git a/tutorial-middleware.html b/tutorial-middleware.html
index 7353fdc..259fac8 100644
--- a/tutorial-middleware.html
+++ b/tutorial-middleware.html
@@ -5,13 +5,13 @@
- Writing Middleware — responder 3.6.1 documentation
+ Writing Middleware — responder 3.6.2 documentation
-
+
@@ -210,7 +210,7 @@ middleware when hooks aren’t enough.
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Useful Links
diff --git a/tutorial-rest.html b/tutorial-rest.html
index 18c003f..eb6c48c 100644
--- a/tutorial-rest.html
+++ b/tutorial-rest.html
@@ -5,13 +5,13 @@
- Building a REST API — responder 3.6.1 documentation
+ Building a REST API — responder 3.6.2 documentation
-
+
@@ -255,7 +255,7 @@ with Responder using the lifespan pattern.
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Useful Links
diff --git a/tutorial-sqlalchemy.html b/tutorial-sqlalchemy.html
index a1f2a6c..90ff66e 100644
--- a/tutorial-sqlalchemy.html
+++ b/tutorial-sqlalchemy.html
@@ -5,13 +5,13 @@
- Using SQLAlchemy — responder 3.6.1 documentation
+ Using SQLAlchemy — responder 3.6.2 documentation
-
+
@@ -291,7 +291,7 @@ your database without losing data.
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2
Responder — a familiar HTTP service framework for Python.
- v3.6.1
+ v3.6.2