Giter VIP home page Giter VIP logo

fastapi-request-limiter's Introduction

FastAPI Request Limiter Middleware

This middleware provides request limiting functionality for FastAPI applications, allowing you to control and manage the rate of incoming requests based on client IP addresses.

Cover GIF

Installation

pip install fastapi-request-limiter

Features

  • Request Limiting: Control the rate of incoming requests by applying a waiting penalty to clients who exceed predefined thresholds.
  • Whitelisting: Allow certain IP addresses to bypass rate limiting restrictions.
  • Blacklisting: Disallow certain IP addresses to access the API on web-server level.
  • Flexible Configuration: Customize the middleware behavior by specifying parameters such as waiting time, whether to limit HTTP or WebSocket requests, and whitelisted IP addresses.
  • Backups: Allows to generate and load backups of request histories.

Usage Example

from fastapi import FastAPI
from request_limiter_middleware import RequestLimitMiddleware
from request_limiter_middleware import Backup, BanHammer

app = FastAPI()

# blocking address
BanHammer.block_it(ip="127.0.0.2")

# saving current IP requests history
Backup.save_archive('file.json')

# Enabling request limiting
app.add_middleware(RequestLimitMiddleware, whitelisted_ip_addresses=("127.0.0.1",),
                   limit_http=True, limit_websocket=True, seconds=7)
# loading history backup
Backup.load_archive('file.json')


@app.get(path='/')
async def home():
  return {"message": "Welcome home"}

This example demonstrates how to integrate and use the middleware in your FastAPI application.

It includes blocking a specific IP address, saving the current IP requests history to a file, enabling request limiting with specified configurations, and loading the history backup from the file.

Parameters

  • app: The FastAPI application instance.
  • whitelisted_ip_addresses: Tuple of whitelisted IP addresses that will bypass rate limiting.
  • seconds: Time interval between two requests in seconds (default: 5 seconds).
  • limit_http: Boolean flag to enable/disable request limiting for HTTP requests (default: True).
  • limit_websocket: Boolean flag to enable/disable request limiting for WebSocket connections (default: True).

Detailed


Scheme:

scheme


FastAPI Request Limiter Middleware contains of three parts:

Requests Archive

RequestsArchive is a singleton class containing a history dictionary with history of requests, which are in according to following structure:

{
    'ip': {
        "expiration_time": float | bool
    },
}
  • waiting_time is the number of seconds to wait
  • expiration_time is the remaining seconds time.time() + seconds or False if the IP is blocked.

RequestsArchive has three methods:

  • extend_time : Extends the cooldown of the given ip for N seconds, by default it's 5.
  • get_remaining_time : Converts the remaining cooldown in float (expiration_time's value) to int and returns it.
    • If a bool value found, which means the IP is permanently blocked, it raises HTTPException with 400 status_code and "Goodbye" detail.
  • add_ip :Adds the given ip to history with N seconds of cooldown, by default it's 5. Used for unknown IP addresses requesting the API for the first time.

BanHammer and Backup

BanHammer and Backup, both are derived classes from Requests Archive.

  • BanHammer

BanHammer allows to block the user permanently. It has one method block_it which changes the "expiration_time" for the particular IP from float to False. This allows to raise errors in case of finding bool value instead of float without further proceeding.

BanHammer as well as the entire library doesn't have any unblocking mechanisms, which is an essential nuance in request limiting and managing the security of the API.

As RequestsArchive is a singleton class, you block IP addresses before and during runtime from any part of your code using BanHammer.

BTW: this mechanism perfectly matches with my another original library called input-armor where you can check user input for maliciousness.

  • Backup

Backup provides save_archive and load_archive methods. As well as BanHammer this class can be used any time from any part of the code.


RequestLimitMiddleware

If you want to find an instantiation example of RequestLimitMiddleware as well as with its parameters and their explanations: Look at Usage Example section of this document to find.

First of all, RequestLimitMiddleware checks the incoming request type, whether it's http or websocket and if the request should or should not be request limited, and proceeds the request if it should not. Then it obtains the client IP using Request(scope).client.host. - Addition: If you are using Flask or Django you need to modify the way of invoking the IP address. As that's the only FastAPI-related dependency of this library. However, instead of installing with pip you need to clone this repo. In the next step it checks if the IP is white-listed, and proceeds the request if it is. Then it checks for the active waiting penalty, if yes raises an error with 429 status code.


License

This project is licensed under the terms of the BSD license.


Author


Links:


fastapi-request-limiter's People

Contributors

armen-jean-andreasian avatar

Stargazers

 avatar  avatar

Watchers

 avatar

Forkers

rm-21

fastapi-request-limiter's Issues

KeyError in `RequestsArchive.add_ip()`

Hi

Using fastapi-request-limiter 1.0.1, fastapi 0.110.3, Python 3.12.3.

from request_limiter_middleware import RequestLimitMiddleware
...
app = FastAPI()
...
app.add_middleware(RequestLimitMiddleware, seconds=1, whitelisted_ip_addresses=())
...

An initial request (empty history) to the FastAPI raises the following error:

  File "/home/vscode/.local/lib/python3.12/site-packages/request_limiter_middleware/requests_archive.py", line 31, in add_ip
    if type(self.history[ip]) is not bool:  # if the IP is permanently banned
            │    │       └ '172.22.0.5'
            │    └ {}
            └ <request_limiter_middleware.requests_archive.RequestsArchive object at 0x7f8b9f6ed5b0>

KeyError: '172.22.0.5'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.