slowapi

Rate limiting for Starlette and FastAPI endpoints, adapted from Flask-Limiter.

Library
PyPI
v0.1.10
2,051stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
62/100Good
Development Activity64
Maintenance32
Community52
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
69/100Good
Architecture72
Code Quality68
Innovation62
Learning Curve75

slowapi is a rate-limiting library for Starlette and FastAPI, adapted directly from flask-limiter. It wraps the limits package to enforce per-route, per-method, shared-group, or application-wide rate limits, and plugs into Starlette’s exception-handling system to return 429 responses with standard rate-limit headers.

The library is used in production setups handling millions of requests per month. It supports both sync and async endpoints, multiple storage backends (in-memory, Redis, Memcached) with automatic in-memory fallback, and custom key functions for deriving rate-limit identity from IP address, auth tokens, or any request attribute.

What You Get

  • A Limiter class you instantiate once with a key_func and attach to app.state.limiter.
  • A @limiter.limit(...) decorator for applying per-route or per-method limits to sync and async endpoints.
  • Pluggable storage backends (in-memory, Redis, Memcached) via the underlying limits library, with in-memory fallback if the backend goes down.
  • A ready-made RateLimitExceeded exception and Starlette exception handler that returns 429 JSON responses with X-RateLimit-* headers.

Common Use Cases

  • Protecting public FastAPI APIs from scraping and abuse
  • Throttling login and password-reset endpoints against credential stuffing
  • Applying different limits to different route groups via shared limit scopes
  • Setting application-wide default limits while overriding specific hot endpoints

Under The Hood

Architecture The library layers a small set of focused modules: extension.py defines the Limiter class that owns configuration, storage-backend selection, and per-request limit checking; wrappers.py defines Limit and LimitGroup, the abstraction that turns a limit string or callable into concrete Limit objects at request time; middleware.py implements an ASGI/Starlette middleware path for auto-checking limits outside the decorator flow; and errors.py defines RateLimitExceeded, a starlette.exceptions.HTTPException subclass that Starlette’s own exception-handling machinery can route to a 429 JSON response. A decorated endpoint call flows through LimitGroup.__iter__ to produce Limit instances, which Limiter._check_request_limit evaluates against the configured storage strategy from the limits package, raising RateLimitExceeded on breach. Because both the decorator path and the middleware path funnel through the same Limit/LimitGroup abstraction, changing that core representation would ripple through request checking, header injection, and exemption logic alike.

Tech Stack Written for Python 3.7+ and managed with Poetry, the package’s only required runtime dependency is limits (>=2.3), which supplies the actual rate-limiting strategies and storage backends; redis is an optional extra for the Redis-backed storage option. It builds directly on Starlette’s ASGI primitives (Request, Response, BaseHTTPMiddleware) and works transparently with FastAPI since FastAPI is itself built on Starlette. Development tooling includes black, mypy, isort, and flake8 for style and typing, pytest with coverage for testing, and mkdocs with mkautodoc for the docs site published on Read the Docs; CI runs this full chain across Python 3.9-3.11 via GitHub Actions.

Code Quality Test coverage is meaningful rather than superficial: test_fastapi_extension.py and test_starlette_extension.py each exercise the decorator across single/multiple limits, headers, exemptions, and both sync and async handlers, backed by shared fixtures in tests/__init__.py. Type hints are used extensively and checked with mypy in CI, though several # type: ignore markers on the limits import point to gaps in the upstream library’s own typing. CI only enforces the F401 (unused-import) flake8 rule rather than a full lint pass, and there’s no visible coverage-percentage gate, so quality leans on the type checker and the decorator-level test suite more than exhaustive static analysis.

API Design The public surface is deliberately small and mirrors flask-limiter’s API: construct a Limiter with a key_func, decorate endpoints with @limiter.limit(...), and register the provided exception handler. This keeps onboarding low for anyone coming from Flask, but it carries one documented rough edge — the request argument must be explicitly present in the endpoint signature or the decorator cannot hook into it, a constraint the README calls out directly rather than handling transparently. Documentation is present but thin: an api.md and examples.md on Read the Docs cover the essentials without deep guides for advanced backend or key-function customization.

Used by 5 apps in this directory

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search