The decorator
In production: Flask-Limiter
Scaffolded apps with authentication ship arate_limits.py that handles this properly.
It limits the Google OAuth login and callback and every admin POST route through
Flask-Limiter, sharing counters across workers via Redis.
.env
config.py as RATELIMIT_DEFAULT, RATELIMIT_LOGIN and RATELIMIT_ADMIN, each
overridable by environment variable. Run flask limiter limits to see which routes are
actually limited.
Two things that fail silently
Both cost real debugging time if you wire this up by hand.Assign the wrapper back
Assign the wrapper back
Flask-Limiter enforces a limit only through the function it returns. Calling
limiter.limit(rule)(app.view_functions[ep]) and discarding the result does nothing,
and drops that endpoint out of the default limit as well.Exempt static endpoints
Exempt static endpoints
A single page load fetches ten or more scripts and fonts from Flask. Without a
limiter.request_filter exempting static and feather_static, a busy user gets a
429 on the app’s own JavaScript while the page is still loading.Exempt health checks
Exempt health checks
A platform probes
/health/ready from one address every few seconds. At every
5 seconds that is 720 requests an hour, over the default 600, so about an hour
after each deploy the app answers its own readiness check with 429 and is taken
out of rotation. The scaffold exempts health.health_check,
health.liveness_check and health.readiness_check in EXEMPT_ENDPOINTS in
rate_limits.py.