Python Friday #243: Rate Limit in FastAPI

A simple way to protect our API is to limit the number of calls a client can make in a given timespan. For FastAPI, we can use the SlowApi package to prevent our application from being flooded with requests.

This post is part of my journey to learn Python. You find the code for this post in my PythonFriday repository on GitHub.

 

Installation

We can install the SlowApi package with this command:

 

Limit a URL

With this minimalistic FastAPI application we can limit the access to the /max/{id} URL to 3 calls per minute:

We can verify that the behaviour works as expected with this test:

When we call the same id on our /max endpoint for the 4th time in a minute, we get this exception:

{
“error”: “Rate limit exceeded: 3 per 1 minute”
}

Since the default behaviour is per URL, we get a different counter for /max/1 than we get for /max/2. The URL differ and so does our counter for the limit.

 

Limit an endpoint

If we want to have a limit that works for the whole endpoint and not just the specific URL as above, we can add the parameter key_style="endpoint" in our limiter:

With this setting the calls to /max/1 and /max/2 count towards the same limit and as soon we hit the endpoint 3 times, we get the exception no matter what parameter we use.

 

Global limits

If we want to set a global limit for our clients that includes all endpoints, we can use this code:

This adds a middleware to FastAPI that handles the limits and we do not need to add the @limit decorator to our endpoints. Be aware that we must use the application_limits parameter to get a global limit. If you use the default_limits parameter, you get a limit per URL even when you use the middleware.

To check if this really covers all endpoints and parameters, we can use this test:

If we want to exclude an endpoint from the limits, we can add the @limiter.exempt decorator.

 

Limitations and options

There are two main limitations in SlowApi we need to be aware of:

  1. We must pass Request as a parameter to our endpoints.
  2. The @limiter decorator must come below the @app decorator, or else the limit will not work.

Especially the second point is easy to overlook and can lead to a long debugging session.

If we do not specify a storage_uri, SlowApi uses an in-memory cache to track the limits. If we want to use Redis instead, we can point our Limiter to our Redis server:

The documentation for SlowApi explains the necessary details to connect to Redis and how we can use the other options.

 

Next

With SlowApi we get a quick solution to limit the calls of a client. We can choose to limit a specific endpoint, a URL or cover the whole API. Make sure that you adapt the limit to match the usage pattern of your API – otherwise you will lock out too many clients.

Next week we add a login solution to our application to prevent unauthorised people to mess with our tasks.

2 thoughts on “Python Friday #243: Rate Limit in FastAPI”

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.