{"id":982,"library":"flask-limiter","title":"Flask-Limiter","description":"Flask-Limiter is an active Python extension that adds rate limiting capabilities to Flask applications, preventing abuse and ensuring stability. It allows configuration of limits at various levels (application-wide, per Blueprint, per route) and supports multiple storage backends like Redis, Memcached, MongoDB, and Valkey. The current version is 4.1.1, with a regular release cadence.","status":"active","version":"4.1.1","language":"python","source_language":"en","source_url":"https://github.com/alisaifee/flask-limiter","tags":["flask","rate limiting","security","web","api"],"install":[{"cmd":"pip install Flask-Limiter","lang":"bash","label":"Default"},{"cmd":"pip install Flask-Limiter[redis]","lang":"bash","label":"With Redis backend"},{"cmd":"pip install Flask-Limiter[memcached]","lang":"bash","label":"With Memcached backend"},{"cmd":"pip install Flask-Limiter[mongodb]","lang":"bash","label":"With MongoDB backend"},{"cmd":"pip install Flask-Limiter[valkey]","lang":"bash","label":"With Valkey backend"},{"cmd":"pip install Flask-Limiter[cli]","lang":"bash","label":"With CLI tools"}],"dependencies":[{"reason":"Optional backend for rate limit storage","package":"redis","optional":true},{"reason":"Optional backend for rate limit storage","package":"pymemcache","optional":true},{"reason":"Optional backend for rate limit storage","package":"pymongo","optional":true},{"reason":"Optional backend for rate limit storage","package":"valkey-py","optional":true},{"reason":"Required for Flask CLI commands if 'cli' extra is used","package":"click","optional":true}],"imports":[{"symbol":"Limiter","correct":"from flask_limiter import Limiter"},{"symbol":"get_remote_address","correct":"from flask_limiter.util import get_remote_address"},{"note":"As of v4.0.0, internal submodules are prefixed with an underscore, and direct imports from them (e.g., `flask_limiter.limits`) are deprecated. Import from the root `flask_limiter` namespace instead.","wrong":"from flask_limiter.limits import Limit","symbol":"Limit","correct":"from flask_limiter import Limit"}],"quickstart":{"code":"import os\nfrom flask import Flask\nfrom flask_limiter import Limiter\nfrom flask_limiter.util import get_remote_address\n\napp = Flask(__name__)\n\n# Configure storage_uri, using in-memory for example, or from an environment variable\n# In-memory storage is for development/testing only and should not be used in production with multiple workers.\n# For production, use backends like Redis: 'redis://localhost:6379'\nstorage_uri = os.environ.get('FLASK_RATELIMIT_STORAGE_URI', 'memory://')\n\nlimiter = Limiter(\n    key_func=get_remote_address,\n    app=app,\n    default_limits=[\"200 per day\", \"50 per hour\"],\n    storage_uri=storage_uri,\n    strategy=\"fixed-window\" # Or 'moving-window', 'sliding-window-counter'\n)\n\n@app.route(\"/slow\")\n@limiter.limit(\"1 per day\")\ndef slow():\n    return \":(\"\n\n@app.route(\"/medium\")\n@limiter.limit(\"1/second\", override_defaults=False)\ndef medium():\n    return \":|\"\n\n@app.route(\"/fast\")\ndef fast():\n    return \":)\"\n\n@app.route(\"/ping\")\n@limiter.exempt\ndef ping():\n    return \"PONG\"\n\n# Example error handler for rate limit exceeded (HTTP 429)\n@app.errorhandler(429)\ndef ratelimit_handler(e):\n    return f\"Rate limit exceeded: {e.description}\", 429\n\nif __name__ == '__main__':\n    app.run(debug=True)","lang":"python","description":"Initializes a Flask application with global and per-route rate limits. It uses `get_remote_address` as the default key function and specifies a default storage URI. Routes demonstrate application-wide limits, specific route limits, combined limits, and exemptions. An error handler for HTTP 429 is included for custom responses."},"warnings":[{"fix":"Update imports to use `from flask_limiter import ClassName` (e.g., `from flask_limiter import Limit`) and adjust how limits are configured, leveraging the new limit description classes.","message":"Version 4.0.0 introduced significant breaking changes in module structure and limit definition. All internal submodules are now prefixed with an underscore, and direct imports from them (e.g., `from flask_limiter.limits import Limit`) are deprecated. Instead, import classes like `Limit`, `RouteLimit`, `ApplicationLimit`, and `MetaLimit` directly from the root `flask_limiter` namespace.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Ensure `key_func` is the first argument in `Limiter()` and all subsequent arguments are explicitly named (e.g., `Limiter(get_remote_address, app=app, storage_uri='...')`). Replace `RATELIMIT_STORAGE_URL` with `storage_uri` or `RATELIMIT_STORAGE_URI` in Flask config.","message":"Version 3.0.0 changed the `Limiter` constructor arguments. `key_func` is now a mandatory positional argument, and all other arguments must be passed as keyword arguments. The `RATELIMIT_STORAGE_URL` configuration variable was removed, and legacy Flask < 2 compatibility was dropped.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Always configure a persistent storage backend (e.g., Redis, Memcached, MongoDB, Valkey) for production deployments by setting `storage_uri` or the `RATELIMIT_STORAGE_URI` Flask config variable.","message":"Using in-memory storage (`memory://`) in production with multiple worker processes will lead to inaccurate and unreliable rate limiting. Each worker will maintain its own independent limit state, making global rate limits ineffective.","severity":"gotcha","affected_versions":"All"},{"fix":"Avoid using version 3.13. If you are on 3.13, downgrade to a stable 3.x release (e.g., 3.12 or earlier) or upgrade to version 4.0.0 or later.","message":"The 3.13 release was yanked from PyPI due to compatibility issues with Flask-AppBuilder and Airflow. Users who installed this specific version might encounter unexpected behavior or errors.","severity":"deprecated","affected_versions":"3.13"},{"fix":"Always check the `requires_python` metadata (or `py_modules` in the PyPI classifiers) for the specific Flask-Limiter version you intend to use and ensure your Python environment meets the requirements.","message":"Flask-Limiter frequently adjusts its supported Python versions. For example, Python 3.9 support was dropped in v3.12, and Python 3.8 support was dropped in v3.9.0. Currently, Python >=3.10 is required.","severity":"breaking","affected_versions":"Various, depending on minor/major versions"},{"fix":"Properly configure your proxy to forward the client's IP in a header (e.g., `X-Forwarded-For`) and configure Flask-Limiter to use this header, potentially with a custom `key_func` or by configuring `RATELIMIT_HEADERS_ENABLED` and `RATELIMIT_HEADER_ID`.","message":"When deploying behind a proxy (e.g., Nginx, Gunicorn), `get_remote_address` might return the proxy's IP address instead of the client's. This can lead to all requests being limited by the proxy's IP, effectively acting as a single global limit for all users.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"search_vec":"'4.1.1':55 'abus':21 'activ':9 'add':13 'allow':26 'api':66 'applic':19,34 'application-wid':33 'backend':44 'blueprint':37 'cadenc':60 'capabl':16 'configur':27 'current':52 'ensur':23 'extens':11 'flask':2,5,18,61 'flask-limit':1,4 'level':32 'like':45 'limit':3,6,15,29,63 'memcach':47 'mongodb':48 'multipl':42 'per':36,38 'prevent':20 'python':10 'rate':14,62 'redi':46 'regular':58 'releas':59 'rout':39 'secur':64 'stabil':24 'storag':43 'support':41 'valkey':50 'various':31 'version':53 'web':65 'wide':35","created_at":"2026-03-29T08:37:27.364916+00:00","updated_at":"2026-04-16T15:07:16.158890+00:00","problems":[{"fix":"Pass the 'app' instance using the keyword argument `app=app` during Limiter initialization. For example: `limiter = Limiter(key_func=get_remote_address, app=app, default_limits=['200 per day'])`.","cause":"This error occurs when the 'app' instance is passed as a positional argument after 'key_func' during Limiter initialization, causing Python to interpret 'app' as a second value for 'key_func' because 'key_func' is the only positional argument.","error":"TypeError: Limiter.__init__() got multiple values for argument 'key_func'"},{"fix":"Pin your 'flask-limiter' dependency to a version prior to 3.13 (e.g., `flask-limiter==3.12.1`) or update any dependent libraries to versions compatible with newer 'flask-limiter' releases.","cause":"The 'flask_limiter.wrappers' module was removed as a breaking change in Flask-Limiter version 3.13, causing applications that directly import or rely on this module (especially older versions of dependent libraries like Flask-AppBuilder or Apache Superset) to fail.","error":"ModuleNotFoundError: No module named 'flask_limiter.wrappers'"},{"fix":"Ensure the chosen storage backend service is running and accessible, verify the `storage_uri` is correctly formatted (e.g., `redis://localhost:6379`), and install the required extra dependencies for your backend (e.g., `pip install Flask-Limiter[redis]`).","cause":"This issue, or similar 'time out' errors, typically arises when the specified storage backend (like Redis, Memcached, or MongoDB) is not running, is misconfigured (e.g., incorrect `storage_uri`), or the necessary Python client library for that backend has not been installed as an extra dependency.","error":"flask-limiter redis not working"},{"fix":"Upgrade 'flask-limiter' and its 'limits' dependency to versions compatible with Python 3.10+ (typically `flask-limiter>=2.0.0` and `limits>=2.0.0`).","cause":"This error occurs because 'SafeConfigParser' was deprecated and removed in Python 3.10 and later, and an older version of 'flask-limiter' or its underlying 'limits' library attempts to use it.","error":"AttributeError: module 'configparser' has no attribute 'SafeConfigParser'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"4.1.1","cli_name":"","cli_version":null,"type":"library","homepage":"https://flask-limiter.readthedocs.org","github":"https://github.com/alisaifee/flask-limiter","docs":"https://flask-limiter.readthedocs.org","changelog":null,"pypi":"https://pypi.org/project/flask-limiter/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["web-framework","auth-security"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-27","next_check":"2026-07-28","install_tag":"verified"}}