Skip to main content

example workflow codecov Documentation Status License

Falcon-Limiter

This library provides advanced rate limiting support for the Falcon web framework.

Rate limiting is provided with the help of the popular Limits library.

This library aims to be compatible with CPython 3.6+ and PyPy 3.5+.

Documentation

You can find the documentation of this library on Read the Docs.

Quickstart

WSGI

Quick example - using fixed-window strategy and storing the hits against limits in the memory:

import falcon
from falcon_limiter import Limiter
from falcon_limiter.utils import get_remote_addr

limiter = Limiter(
    key_func=get_remote_addr,
    default_limits="5 per minute,2 per second"
)

# use the default limit for all methods of this class
@limiter.limit()
class ThingsResource:
    def on_get(self, req, resp):
        resp.body = 'Hello world!'

# add the limiter middleware to the Falcon app
app = falcon.API(middleware=limiter.middleware)

things = ThingsResource()
app.add_route('/things', things)

ASGI (Async)

Quick example - using fixed-window strategy and storing the hits against limits in the memory:

import falcon.asgi
from falcon_limiter import AsyncLimiter
from falcon_limiter.utils import get_remote_addr

limiter = AsyncLimiter(
    key_func=get_remote_addr,
    default_limits="5 per minute,2 per second"
)

# use the default limit for all methods of this class
@limiter.limit()
class ThingsResource:
    async def on_get(self, req, resp):
        resp.body = 'Hello world!'

# add the limiter middleware to the Falcon app
app = falcon.asgi.App(middleware=limiter.middleware)

things = ThingsResource()
app.add_route('/things', things)

See documentation for more about Async.

A more complicated example

When making calls against this app, above >5 calls per minute or >2 per seconds you will receive an HTTP 429 error response with message: "Reached allowed limit 5 hits per 1 minute!"

A second, more complicated example - using the moving-window strategy with a shared Redis backend and running the application behind a reverse proxy behind a reverse proxy:

import falcon
from falcon_limiter import Limiter

# a custom key function
def get_access_route_addr(req, resp, resource, params) -> str:
    """ Get the requestor's IP by discounting 1 reverse proxy
    """
    return req.access_route[-2]

limiter = Limiter(
    key_func=get_access_route_addr,
    default_limits="5 per minute,2 per second",
    # only count HTTP 200 responses against the limit:
    default_deduct_when=lambda req, resp, resource, req_succeeded:
        resp.status == falcon.HTTP_200,
    config={
        'RATELIMIT_KEY_PREFIX': 'myapp',  # to allow multiple apps in the same Redis db
        'RATELIMIT_STORAGE_URL': f'redis://:{REDIS_PSW}@{REDIS_HOST}:{REDIS_PORT}',
        'RATELIMIT_STRATEGY': 'moving-window'
    }
)

class ThingsResource:
    # no rate limit on this method
    def on_get(self, req, resp):
        resp.body = 'Hello world!'

    # a more strict rate limit applied to this method
    # with a custom key function serving up the user_id
    # from the request context as key
    @limiter.limit(limits="3 per minute,1 per second",
        key_func=lambda req, resp, resource, params: req.context.user_id)
    def on_post(self, req, resp):
        resp.body = 'Hello world!'

class SpecialResource:
    # dynamic_limits allowing the 'admin' user a higher limit than others
    @limiter.limit(dynamic_limits=lambda req, resp, resource, params:
        '999/minute,9999/second' if req.context.user == 'admin'
        else '5 per minute,2/second')
    def on_get(self, req, resp):
        resp.body = 'Hello world!'

# add the limiter middleware to the Falcon app
app = falcon.API(middleware=limiter.middleware)

things = ThingsResource()
special = SpecialResource()
app.add_route('/things', things)
app.add_route('/special', special)

For more details please read the documentation at Read the Docs

Development

For the development environment we use Pipenv and for packaging we use Flit.

Documentation

The documentation is built via Sphinx following the Google docstring style and hosted on Read the Docs.

To review the documentation locally before committing:

$ make docs
$ cd docs
$ python -m http.server 8088

Now you can access the documentation locally under http://127.0.0.1:8088/_build/html/

Development environment

You will need Python 3.6-3.9 and PyPy3 and its source package installed to run tox in all environments.

We do use type hinting and run MyPy on those, but unfortunately MyPy currently breaks the PyPy tests due to the typed-ast package's "bug" (see https://github.com/python/typed_ast/issues/97). Also with Pipenv you can't have a second Pipfile. This is why for now we don't have mypy listed as a dev package in the Pipfile.

Credits

Our library uses the popular Limits library for most of the backend operations.

Metadata

Release files for falcon-limiter 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for falcon-limiter 1.0.1
File Size Uploaded Provenance
falcon-limiter-1.0.1.tar.gz 32.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for falcon-limiter 1.0.1
File Interpreter ABI Platform
falcon_limiter-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 49.3 kB

Release files / falcon-limiter-1.0.1.tar.gz

Download URL falcon-limiter-1.0.1.tar.gz
Size 32.7 kB
Tags Source
SHA-256 checksum
How to use checksums
d7475b720fd00ee4ecbbeefdec7c299b5b4809b9631c3126239d63ed09eab408
BLAKE2b-256 checksum
How to use checksums
05cc4cabd97a63774e5486f159a822ee3e294af7567ddb7e6994dbf7057a55c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-requests/2.27.1

Release files / falcon_limiter-1.0.1-py3-none-any.whl

Download URL falcon_limiter-1.0.1-py3-none-any.whl
Size 16.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2bbf0f6913289b7f68d89205ad92744d915f7701fa6bb4162f96c71f512a7226
BLAKE2b-256 checksum
How to use checksums
ffe1a67a5fb170526feb4879172fda36aea41488bed9d2f59ba15cc2d4d9d25b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-requests/2.27.1

Security for falcon-limiter 1.0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page