### Quick Start Flask App with Rate Limiting Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst A basic Flask application demonstrating Flask-Limiter setup with in-memory storage, default limits, and route-specific overrides. ```python from flask import Flask from flask_limiter import Limiter from flask_limiter.util import get_remote_address app = Flask(__name__) limiter = Limiter( get_remote_address, app=app, default_limits=["200 per day", "50 per hour"], storage_uri="memory://", ) @app.route("/ping") @limiter.exempt def ping(): return "pong" @app.route("/medium") def medium(): return "hello world!" @app.route("/slow") @limiter.limit("1 per day") def slow(): return "slow" ``` -------------------------------- ### Install Flask-Limiter with Valkey Extra Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Install Flask-Limiter with the Valkey storage backend dependencies. ```console $ pip install Flask-Limiter[valkey] ``` -------------------------------- ### Install Flask-Limiter Source: https://github.com/alisaifee/flask-limiter/blob/master/README.rst Install the Flask-Limiter package using pip. ```bash pip install Flask-Limiter ``` -------------------------------- ### Install CLI for Flask-Limiter Source: https://github.com/alisaifee/flask-limiter/blob/master/README.rst Install the command-line interface extension for Flask-Limiter to inspect limits. ```bash pip install Flask-Limiter[cli] ``` -------------------------------- ### Install Flask-Limiter with Memcached Extra Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Install Flask-Limiter with the Memcached storage backend dependencies. ```console $ pip install Flask-Limiter[memcached] ``` -------------------------------- ### Run Flask Application Source: https://github.com/alisaifee/flask-limiter/blob/master/README.rst Start the Flask development server to run the application. Ensure the FLASK_APP environment variable is set correctly. ```bash $ FLASK_APP=app:app flask run ``` -------------------------------- ### Install Flask-Limiter with CLI extras Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/cli.rst Ensure the 'cli' extras are installed for Flask-Limiter to use its command-line interface. ```shell $ pip install Flask-Limiter[cli] ``` -------------------------------- ### Install Flask-Limiter with Redis Extra Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Install Flask-Limiter with the Redis storage backend dependencies. ```console $ pip install Flask-Limiter[redis] ``` -------------------------------- ### Install Flask-Limiter with MongoDB Extra Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Install Flask-Limiter with the MongoDB storage backend dependencies. ```console $ pip install Flask-Limiter[mongodb] ``` -------------------------------- ### Configure Flask-Limiter Logger Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Demonstrates how to get and configure the 'flask-limiter' logger instance for debugging or filtering log messages. ```python import logging limiter_logger = logging.getLogger("flask-limiter") # force DEBUG logging limiter_logger.setLevel(logging.DEBUG) # restrict to only error level limiter_logger.setLevel(logging.ERROR) # Add a filter limiter_logger.addFilter(SomeFilter) # etc .. ``` -------------------------------- ### Run Flask-Limiter Tests Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/development.rst Execute the test suite for Flask-Limiter using `uv run pytest`. Ensure Docker is installed and running if tests require Redis or Memcached instances. ```console $ uv run pytest ``` -------------------------------- ### Rate Limiting All Routes in a Blueprint Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Apply a rate limit to all routes within a blueprint or exempt a blueprint from all rate limits. This example shows a login blueprint with a specific limit and a doc blueprint that is exempt. ```python app = Flask(__name__) login = Blueprint("login", __name__, url_prefix = "/login") regular = Blueprint("regular", __name__, url_prefix = "/regular") doc = Blueprint("doc", __name__, url_prefix = "/doc") @doc.route("/") def doc_index(): return "doc" @regular.route("/") def regular_index(): return "regular" @login.route("/") def login_index(): return "login" limiter = Limiter(get_remote_address, app=app, default_limits = ["1/second"]) limiter.limit("60/hour")(login) limiter.exempt(doc) app.register_blueprint(doc) app.register_blueprint(login) app.register_blueprint(regular) ``` -------------------------------- ### Explicitly Setting Limits/Exemptions on Nested Blueprints Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Illustrates controlling inherited and descendant limits within nested blueprints using `override_defaults` and `flags` parameters. This example sets default and application-wide limits. ```python limiter = Limiter( ..., default_limits = ["100/hour"], application_limits = ["100/minute"] ) parent = Blueprint('parent', __name__, url_prefix='/parent') child = Blueprint('child', __name__, url_prefix='/child') grandchild = Blueprint('grandchild', __name__, url_prefix='/grandchild') health = Blueprint('health', __name__, url_prefix='/health') parent.register_blueprint(child) parent.register_blueprint(health) child.register_blueprint(grandchild) child.register_blueprint(health) grandchild.register_blueprint(health) app.register_blueprint(parent) ``` -------------------------------- ### Initialize Limiter with init_app Method Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Initialize the Limiter extension using the init_app method for deferred application initialization. ```python limiter = Limiter(get_remote_address) limiter.init_app(app) ``` -------------------------------- ### Configure Redis Storage Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Initialize Limiter with Redis storage. Parameters are passed to redis.Redis.from_url. Supports different strategies like 'fixed-window'. ```python from flask_limiter import Limiter from flask_limiter.util import get_remote_address .... limiter = Limiter( get_remote_address, app=app, storage_uri="redis://localhost:6379", storage_options={"socket_connect_timeout": 30}, strategy="fixed-window", # or "moving-window" or "sliding-window-counter" ) ``` -------------------------------- ### Configure MongoDB Storage Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Initialize Limiter with MongoDB storage. Supports different strategies like 'fixed-window'. ```python from flask_limiter import Limiter from flask_limiter.util import get_remote_address .... limiter = Limiter( get_remote_address, app=app, storage_uri="mongodb://localhost:27017", strategy="fixed-window", # or "moving-window" or "sliding-window-counter" ) ``` -------------------------------- ### Configure Redis Storage with Reused Connection Pool Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Initialize Limiter with Redis storage, reusing an existing ConnectionPool instance. Pass the pool in storage_options. ```python import redis from flask_limiter import Limiter from flask_limiter.util import get_remote_address .... pool = redis.connection.BlockingConnectionPool.from_url("redis://.....") limiter = Limiter( get_remote_address, app=app, storage_uri="redis://", storage_options={"connection_pool": pool}, strategy="fixed-window", # or "moving-window" or "sliding-window-counter" ) ``` -------------------------------- ### Basic Flask App with Limiter Configuration Source: https://github.com/alisaifee/flask-limiter/blob/master/README.rst Configure a Flask application with Flask-Limiter, setting default limits, storage URI, and rate limiting strategy. Demonstrates route decorators for specific limits and exemptions. ```python from flask import Flask from flask_limiter import Limiter from flask_limiter.util import get_remote_address app = Flask(__name__) limiter = Limiter( get_remote_address, app=app, default_limits=["2 per minute", "1 per second"], storage_uri="memory://", # Redis # storage_uri="redis://localhost:6379", # Redis cluster # storage_uri="redis+cluster://localhost:7000,localhost:7001,localhost:70002", # Memcached # storage_uri="memcached://localhost:11211", # Memcached Cluster # storage_uri="memcached://localhost:11211,localhost:11212,localhost:11213", # MongoDB # storage_uri="mongodb://localhost:27017", strategy="fixed-window", # or "moving-window", or "sliding-window-counter" ) @app.route("/slow") @limiter.limit("1 per day") def slow(): return "24" @app.route("/fast") def fast(): return "42" @app.route("/ping") @limiter.limiter.exempt def ping(): return 'PONG' ``` -------------------------------- ### Demonstrate Meta Limit Enforcement Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Illustrates how meta limits prevent access to routes even after individual route limits have reset, by enforcing a global hourly or daily limit. ```shell $ curl localhost:5000/fast fast $ curl localhost:5000/slow slow $ curl localhost:5000/slow
1 per 1 minute
$ sleep 60 $ curl localhost:5000/slow slow $ curl localhost:5000/slow1 per 1 minute
$ sleep 60 $ curl localhost:5000/slow2 per 1 hour
$ curl localhost:5000/fast2 per 1 hour
``` -------------------------------- ### Configure Memcached Storage Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Initialize Limiter with Memcached storage. Additional parameters are passed to the memcached client constructor. ```python from flask_limiter import Limiter from flask_limiter.util import get_remote_address .... limiter = Limiter( get_remote_address, app=app, storage_uri="memcached://localhost:11211", storage_options={} ) ``` -------------------------------- ### List all configured Flask-Limiter limits Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/cli.rst Use the 'limits' subcommand to display all configured rate limits in Flask-Limiter. ```shell $ flask limiter limits ``` -------------------------------- ### Initialize Limiter with Flask App Constructor Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Initialize the Limiter extension by passing the Flask application instance directly to the constructor. ```python from flask_limiter import Limiter from flask_limiter.util import get_remote_address .... limiter = Limiter(get_remote_address, app=app) ``` -------------------------------- ### Configure Meta Limits Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Set up meta limits in the Limiter constructor to add an extra layer of protection against excessive requests across all rate limits. ```python app = Limiter( key_func=get_remote_address, meta_limits=["2/hour", "4/day"], default_limits=["10/minute"], ) @app.route("/fast") def fast(): return "fast" @app.route("/slow") @limiter.limit("1/minute") def slow(): return "slow" ``` -------------------------------- ### Display Flask-Limiter configuration Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/cli.rst Use the 'config' subcommand to display the active configuration of Flask-Limiter. ```shell $ flask limiter config ``` -------------------------------- ### Configure Redis Cluster Storage Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Initialize Limiter with Redis Cluster storage. Parameters are passed to redis.cluster.RedisCluster. Supports different strategies. ```python from flask_limiter import Limiter from flask_limiter.util import get_remote_address .... limiter = Limiter( get_remote_address, app=app, storage_uri="redis+cluster://localhost:7000,localhost:7001,localhost:7002", storage_options={"socket_connect_timeout": 30}, strategy="fixed-window", # or "moving-window" or "sliding-window-counter" ) ``` -------------------------------- ### Customizing Rate Limit Header Names Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/configuration.rst Demonstrates how to map default rate limit header names to custom names using the header_name_mapping argument during Limiter initialization. ```python from flask_limiter import Limiter, HEADERS limiter = Limiter(header_name_mapping={ HEADERS.LIMIT : "X-My-Limit", HEADERS.RESET : "X-My-Reset", HEADERS.REMAINING: "X-My-Remaining" } ) ``` -------------------------------- ### Inspect Rate Limits with CLI Source: https://github.com/alisaifee/flask-limiter/blob/master/README.rst Use the Flask CLI to view the configured rate limits for your application. This command helps in understanding how limits are applied to different routes. ```bash $ FLASK_APP=app:app flask limiter limits ``` -------------------------------- ### Inspect Flask-Limiter Limits using CLI Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Use the 'flask limiter limits' command to view the applied rate limits. ```shell $ flask limiter limits ``` ```shell FLASK_APP=../../examples/sample.py:app flask limiter limits ``` -------------------------------- ### Inspect Flask-Limiter Configuration using CLI Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Use the 'flask limiter config' command to view the effective configuration of Flask-Limiter. ```shell $ flask limiter config ``` ```shell FLASK_APP=../../examples/sample.py:app flask limiter config ``` -------------------------------- ### Display Flask-Limiter CLI help Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/cli.rst Access the help message for the Flask-Limiter CLI to see available subcommands and options. ```shell FLASK_APP=../../examples/kitchensink.py:app flask limiter --help ``` -------------------------------- ### Clone Flask-Limiter Repository Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/development.rst Clone the Flask-Limiter project from GitHub and navigate into the project directory. ```console $ git clone git://github.com/alisaifee/flask-limiter.git $ cd flask-limiter $ uv sync --dev ``` -------------------------------- ### Display active Flask-Limiter configuration Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/cli.rst View the currently active configuration settings for Flask-Limiter. ```shell FLASK_APP=../../examples/kitchensink.py:app flask limiter config ``` -------------------------------- ### Display help for Flask-Limiter clear command Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/cli.rst View the help message for the 'clear' subcommand to understand its options for managing limits. ```shell FLASK_APP=../../examples/kitchensink.py:app flask limiter clear --help ``` -------------------------------- ### Check Flask-Limiter limit status by key Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/cli.rst Display the status of limits for a specific key, often an IP address or user identifier. ```shell FLASK_APP=../../examples/kitchensink.py:app flask limiter limits --key=127.0.0.1 ``` -------------------------------- ### Rate Limit by Current User (Flask-Login) Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Customize rate limits to be based on the current user's username using Flask-Login. ```python from flask import Flask, route from flask_login import login_required, current_user from flask_limiter import Limiter app = Flask(__name__) limiter = Limiter(app=app, default_limits=["1 per day"]) @app.route("/test") @login_required @limiter.limit("1 per day", key_func = lambda : current_user.username) def test_route(): return "42" ``` -------------------------------- ### Test Rate Limited Endpoints Source: https://github.com/alisaifee/flask-limiter/blob/master/README.rst Demonstrates making requests to rate-limited and non-limited endpoints using curl. Shows how the 'fast' endpoint respects default limits, 'slow' respects its specific limit, and 'ping' is exempt. ```bash $ curl localhost:5000/fast 42 $ curl localhost:5000/fast 42 $ curl localhost:5000/fast2 per 1 minute
$ curl localhost:5000/slow 24 $ curl localhost:5000/slow1 per 1 day
$ curl localhost:5000/ping PONG $ curl localhost:5000/ping PONG $ curl localhost:5000/ping PONG $ curl localhost:5000/ping PONG ``` -------------------------------- ### List Flask-Limiter limits for a specific path Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/cli.rst Filter the displayed limits to show only those configured for a specific URL path. ```shell FLASK_APP=../../examples/kitchensink.py:app flask limiter limits --path=/health/ ``` -------------------------------- ### Utilities Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/api.rst Provides utility functions for common rate limiting tasks, such as retrieving the client's IP address. ```APIDOC ## Utilities ### Description The `flask_limiter.util` module contains helper functions that are commonly used when configuring rate limits, such as functions for determining the request key. ### Functions - **`get_remote_address(request)`** Returns the remote address of the request. This is the default key function used by `Limiter`. - **`get_ipaddr(request)`** An alias for `get_remote_address`. - **`get_header_ipaddr(header_name='X_FORWARDED_FOR')`** Returns a function that retrieves the IP address from a specified header. Useful when behind a proxy. ```python from flask import Flask from flask_limiter import Limiter from flask_limiter.util import get_header_ipaddr app = Flask(__name__) limiter = Limiter( app=app, key_func=get_header_ipaddr('X-Real-IP') ) ``` - **`moving_window(period, interval)`** A decorator factory for creating moving window rate limiters. - **`fixed_window(period, interval)`** A decorator factory for creating fixed window rate limiters. - **`smooth_window(period, interval)`** A decorator factory for creating smooth window rate limiters. ``` -------------------------------- ### Custom Error Response using Limiter's on_breach Parameter Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Provide a custom error response by passing a callback function to the `on_breach` parameter during Limiter initialization. This response will be embedded in the RateLimitExceeded exception. ```python from flask import make_response, render_template from flask_limiter import Limiter, RequestLimit def default_error_responder(request_limit: RequestLimit): return make_response( render_template("my_ratelimit_template.tmpl", request_limit=request_limit), 429 ) app = Limiter( key_func=..., default_limits=["100/minute"], on_breach=default_error_responder ) ``` -------------------------------- ### Deploy Behind Proxy with ProxyFix Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Configures the Flask application to correctly identify client IP addresses when deployed behind a proxy using Werkzeug's ProxyFix middleware. ```python from flask import Flask from flask_limiter import Limiter from flask_limiter.util import get_remote_address from werkzeug.middleware.proxy_fix import ProxyFix app = Flask(__name__) # for example if the request goes through one proxy # before hitting your application server app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1) limiter = Limiter(get_remote_address, app=app) ``` -------------------------------- ### List Flask-Limiter limits for a specific endpoint Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/cli.rst Filter the displayed limits to show only those configured for a specific endpoint name. ```shell FLASK_APP=../../examples/kitchensink.py:app flask limiter limits --endpoint=root ``` -------------------------------- ### Limit Objects Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/api.rst Dataclasses for defining rate limits with more granularity, including default, application-wide, and meta limits. ```APIDOC ## Limit Objects ### Description These dataclasses provide a structured way to define rate limits with increased granularity, useful for setting default, application-wide, or meta limits. ### Classes - **`Limit`** A base class for defining rate limits. Can be used to specify the limit string, key function, and other options. ```python from flask_limiter.util import get_remote_address from flask_limiter import Limit my_limit = Limit( "100 per hour", key_func=get_remote_address, strategy="fixed-window" ) ``` - **`ApplicationLimit`** A subclass of `Limit` specifically for defining application-wide rate limits. ```python from flask_limiter import ApplicationLimit app_limit = ApplicationLimit( "1000 per day", description="Global application limit" ) ``` - **`MetaLimit`** A subclass of `Limit` for defining meta-limits, which can be used to group or categorize other limits. ```python from flask_limiter import MetaLimit meta_limit = MetaLimit( "50 per minute", description="Meta limit for sensitive operations" ) ``` - **`RouteLimit`** A dataclass used for defining limits specifically for decorating routes or blueprints. It is consistent with the other `Limit` objects. ```python from flask_limiter import RouteLimit route_limit = RouteLimit( "5 per second", error_message="Too many requests on this route." ) ``` ``` -------------------------------- ### Rate Limit by Country using GeoIP Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Rate limit all requests based on the user's country by integrating with GeoIP. Ensure the GeoIP database is accessible. ```python from flask import request, Flask import GeoIP gi = GeoIP.open("GeoLiteCity.dat", GeoIP.GEOIP_INDEX_CACHE | GeoIP.GEOIP_CHECK_CACHE) def get_request_country(): return gi.record_by_name(request.remote_addr)['region_name'] app = Flask(__name__) limiter = Limiter(get_request_country, app=app, default_limits=["10/hour"]) ``` -------------------------------- ### Custom Error Message with String Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Applies a custom static error message to a rate-limited route. ```python app = Flask(__name__) limiter = Limiter(get_remote_address, app=app) def error_handler(): return app.config.get("DEFAULT_ERROR_MESSAGE") @app.route("/") @limiter.limit("1/second", error_message='chill!') def index(): .... ``` -------------------------------- ### Multiple Limit Decorators Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Apply multiple rate limit decorators to a single route. Each decorator specifies a different limit. ```python @app.route("....") @limiter.limit("100/day") @limiter.limit("10/hour") @limiter.limit("1/minute") def my_route(): ... ``` -------------------------------- ### Dynamically Loaded Rate Limit String Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Provide a callable to the limit decorator to dynamically fetch the rate limit string from external sources. The callable is executed for every request and runs within a Flask request context. ```python def rate_limit_from_config(): return current_app.config.get("CUSTOM_LIMIT", "10/s") @app.route("...") @limiter.limit(rate_limit_from_config) def my_route(): ... ``` -------------------------------- ### Custom Keying Function for Rate Limiting Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Implement a custom function to determine the key for rate limiting on a per-route basis. The key function is called within a Flask request context. ```python def my_key_func(): ... @app.route("...") @limiter.limit("100/day", my_key_func) def my_route(): ... ``` -------------------------------- ### Add Custom Rate Limit Headers Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Adds custom rate limit information headers to the response using an after_request hook. ```python app = Flask(__name__) limiter = Limiter(get_remote_address, app=app) @app.route("/") @limiter.limit("1/second") def index(): .... @app.after_request def add_headers(response): if limiter.current_limit: response.headers["RemainingLimit"] = limiter.current_limit.remaining response.headers["ResetAt"] = limiter.current_limit.reset_at response.headers["MaxRequests"] = limiter.current_limit.limit.amount response.headers["WindowSize"] = limiter.current_limit.limit.get_expiry() response.headers["Breached"] = limiter.current_limit.breached return response ``` -------------------------------- ### Limiter Class Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/api.rst The main class for initializing and configuring rate limiting in a Flask application. It provides methods to apply limits to routes and manage rate limiting behavior. ```APIDOC ## class Limiter ### Description The `Limiter` class is the primary interface for integrating rate limiting into a Flask application. It allows for the configuration of global rate limits and the application of specific limits to routes or blueprints. ### Usage ```python from flask import Flask from flask_limiter import Limiter app = Flask(__name__) limiter = Limiter(app=app) @app.route("/slow") @limiter.limit("10 per minute") def slow(): return "This is a slow endpoint." ``` ### Methods - **__init__(self, app=None, storage_uri=None, **options) Initializes the Limiter instance. Can be initialized with a Flask app instance or later using `limiter.init_app(app)`. - **limit(self, limit_value, key_func=None, default_key=None, cost=1, scope=None, exempt_when=None, error_message=None, strategy=None) Decorator to apply a rate limit to a route or function. - **shared_limit(self, limit_value, key_func=None, default_key=None, cost=1, scope=None, exempt_when=None, error_message=None, strategy=None) Decorator to apply a shared rate limit across multiple routes or functions. - **get_limit(self, name) Retrieves the `Limit` object for a given limit name. - **get_window_stats(self, name, key) Retrieves the window statistics for a given limit and key. - **reset(self, name=None, key=None) Resets the rate limit counters. - **exempt(self, func, scope=None, exempt_when=None) Decorator to exempt a function from rate limiting. - **init_app(self, app) Initializes the Limiter with a Flask application instance. ``` -------------------------------- ### Exceptions Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/api.rst Defines the custom exception raised when a rate limit is exceeded. ```APIDOC ## Exceptions ### Description Flask-Limiter raises a `RateLimitExceeded` exception when a request violates a defined rate limit. ### Exception - **`RateLimitExceeded`** This exception is raised when a client exceeds the allowed number of requests within a given time period. It has attributes such as `message`, `limit`, `retry_after`, and `remaining`. ```python from flask import Flask, jsonify from flask_limiter.errors import RateLimitExceeded app = Flask(__name__) @app.errorhandler(RateLimitExceeded) def handle_rate_limit_exceeded(e): return jsonify(error="rate limit exceeded", message=str(e)), 429 ``` ``` -------------------------------- ### Rate Limiting Class-based Views Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Apply a rate limit to all HTTP methods of a class-based view by adding the decorator to the `decorators` attribute. ```python app = Flask(__name__) limiter = Limiter(get_remote_address, app=app) class MyView(flask.views.MethodView): decorators = [limiter.limit("10/second")] def get(self): return "get" def put(self): return "put" ``` -------------------------------- ### Customize Request Cost with a Callable Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Use a callable function with the `cost` parameter in the `limiter.limit` decorator to dynamically determine the penalty for a request. ```python from flask import request, current_app def my_cost_function() -> int: if .....: # Some reason return 2 return 1 @app.route("/") @limiter.limit("100/second", cost=my_cost_function) def root(): ... ``` -------------------------------- ### Request Filter for IP Whitelist Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Implement a request filter to bypass rate limiting for requests originating from a specific IP address, such as localhost ('127.0.0.1'). This is useful for development or trusted sources. ```python @limiter.request_filter def ip_whitelist(): return request.remote_addr == "127.0.0.1" ``` -------------------------------- ### Exempting Routes in Nested Blueprints Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Demonstrates how to exempt a parent blueprint and its nested blueprints from rate limiting. By default, nested blueprints are not automatically exempted. ```python parent = Blueprint('parent', __name__, url_prefix='/parent') child = Blueprint('child', __name__, url_prefix='/child') parent.register_blueprint(child) limiter.exempt(parent) app.register_blueprint(parent) ``` -------------------------------- ### Apply Single Rate Limit Decorator Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Use the Limiter.limit decorator to apply a single rate limit to a route. The limit string can be a single limit or a delimiter-separated string. ```python from flask_limiter import Limiter from flask_limiter.util import get_remote_address .... limiter = Limiter( get_remote_address, app=app, storage_uri="memcached://localhost:11211", storage_options={} ) @limiter.limit("200 per day, 50 per hour") def index(): return "Hello" ``` -------------------------------- ### Careful Rate Limit Handler with Error Response Check Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Implement a custom error handler that checks if an error already has a response, preventing redundant response generation. ```python from flask import jsonify @app.errorhandler(429) def careful_ratelimit_handler(error): return error.get_response() or make_response( jsonify( error=f"ratelimit exceeded {e.description}" ), 429 ) ``` -------------------------------- ### Custom Error Response for Specific Route using on_breach Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Customize rate limit exceeded responses for a specific route by using the `on_breach` parameter in the `@limiter.limit` decorator. ```python from flask import jsonify def index_ratelimit_error_responder(request_limit: RequestLimit): return jsonify({"error": "rate_limit_exceeded"}) @app.route("/") @limiter.limit("10/minute", on_breach=index_ratelimit_error_responder) def index(): ... ``` -------------------------------- ### Request Filter for Header Whitelist Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Implement a request filter to bypass rate limiting for requests with a specific header, such as 'X-Internal: true'. This can be used for internal traffic whitelisting. ```python @limiter.request_filter def header_whitelist(): return request.headers.get("X-Internal", "") == "true" ``` -------------------------------- ### Clear all Flask-Limiter limits Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/cli.rst Use the 'clear' subcommand to remove all rate limit data. This command is interactive by default. ```shell $ flask limiter clear ``` -------------------------------- ### Dynamic Shared Limit with Host Scope Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Create a shared rate limit where the scope is determined dynamically by a callable function, such as the request host. The callable receives the endpoint name as an argument. ```python def host_scope(endpoint_name): return request.host host_limit = limiter.shared_limit("100/hour", scope=host_scope) @app.route("..") @host_limit def r1(): ... @app.route("..") @host_limit def r2(): ... ``` -------------------------------- ### Custom JSON Error Response for Rate Limits Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Register a custom error handler for the 429 status code to return a JSON response when rate limits are exceeded. ```python from flask import make_response, jsonify @app.errorhandler(429) def ratelimit_handler(e): return make_response( jsonify(error=f"ratelimit exceeded {e.description}") , 429 ) ``` -------------------------------- ### Named Shared Limit Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Define a reusable rate limit with a specific scope (e.g., 'mysql') that can be applied to multiple routes. This ensures consistent rate limiting for shared resources. ```python mysql_limit = limiter.shared_limit("100/hour", scope="mysql") @app.route("..") @mysql_limit def r1(): ... @app.route("..") @mysql_limit def r2(): ... ``` -------------------------------- ### Exempt Route Based on Condition Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/index.rst Use the 'exempt_when' argument with a callable to conditionally exempt a route from rate limiting. This is useful for roles like administrators. ```python @app.route("/expensive") @limiter.limit("100/day", exempt_when=lambda: current_user.is_admin) def expensive_route(): ... ``` -------------------------------- ### Clear Flask-Limiter limits for a specific key non-interactively Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/cli.rst Clear rate limit data for a specific key, forcing confirmation with the '-y' flag for use in automations. ```shell FLASK_APP=../../examples/kitchensink.py:app flask limiter clear --key=127.0.0.1 -y ``` -------------------------------- ### Custom Error Message with Callable Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Applies a custom dynamic error message, generated by a callable function, to a rate-limited route. ```python app = Flask(__name__) limiter = Limiter(get_remote_address, app=app) def error_handler(): return app.config.get("DEFAULT_ERROR_MESSAGE") @app.route("/ping") @limiter.limit("10/second", error_message=error_handler) def ping(): .... ``` -------------------------------- ### Conditionally Deduct Rate Limit Based on Response Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Employ the `deduct_when` parameter with a lambda function in the `limiter.limit` decorator to control whether a request counts towards a rate limit after the response is generated. ```python @app.route("..") @limiter.limit( "1/second", deduct_when=lambda response: response.status_code != 200 ) def route(): ... ``` -------------------------------- ### Exempting Nested Blueprints with Descendants Source: https://github.com/alisaifee/flask-limiter/blob/master/doc/source/recipes.rst Exempts a parent blueprint and all its descendants from rate limiting by setting the `DESCENDENTS` flag. This ensures all routes under the parent blueprint are exempt. ```python limiter.exempt( parent, flags=ExemptionScope.DEFAULT | ExemptionScope.APPLICATION | ExemptionScope.DESCENDENTS ) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.