Package: fastapi-simple-rate-limiter
FastAPI Simple RateLimiterThis package contains the API Rate limit decorator for use in FastAPI.It is easy to use, can only be specified in a specific API URL Path, and can be used without special storage (in memory).Additionally, you can use redis to properly share and control the API rate limit value even in multi-instance situations.When the rate limit reaches the set limit, a specified exception or user-specified exception class can be generated.The format of the user-specified exception class is fixed, but the response format can be set somewhat freely.DependenciesPython >= 3.10 or higher environmentredis-pyFastAPI (with Asynchronous Code): Code written with async defInstallationpip$pipinstallfastapi-simple-rate-limiterpoetry$poetryaddfastapi-simple-rate-limiterGithubInstalling the latest version from Github:$gitclonehttps://github.com/jintaekimmm/fastapi-simple-rate-limiter
$cdfastapi-simple-rate-limiter
$pythonsetup.pyinstallUsageTo use this package, please add rate_limiter decorator to the FastAPI api route function.You must set the Request argument in the FastAPI API function to properly check the Client IP address and API URL Path.fromfastapiimportFastAPIfromfastapi.requestsimportRequestapp=FastAPI()@app.get("/test")@rate_limiter(limit=3,seconds=60)asyncdeftest_list_api(request:Request):...This API route can only be called 3 times per 60 seconds.Limit and seconds must be set to Decorator, and you can enter the number of calls and limit time.If the set limit is reached, a FastAPI HTTPException is thrown. If the call is made in an environment where FastAPI is not installed, fastapi_rate_limiter.RateLimitException will occur.When using redis, you can create a redis session and pass it as an argument as shown below.fromfastapiimportFastAPIfromfastapi.requestsimportRequestfromfastapi_simple_rate_limiter.databaseimportcreate_redis_sessionapp=FastAPI()redis_session=create_redis_session()@app.get("/test")@rate_limiter(limit=3,seconds=30,redis=redis_session)asyncdeftest_list_api(request:Request):...You can pass basic connection information tocreate_redis_sessionredis_session=create_redis_session(host='localhost',port=6379,db=0,password='')rate limit exceed responseIf the rate limit excced is reached, the result will be returned asHTTPException.HTTP:429{"detail":"Rate Limit Exceed}If you want to change the HTTP Status or details, you can do so through theexception_statusandexception_messagearguments.@app.get("/test")@rate_limiter(limit=3,seconds=30,exception_status=400,exception_message="Oh..! Too many Request!")asyncdeftest_list_api(request:Request):...custom exception and response formatIf you want to return a limit exceed result in a user-defined response format rather than an HTTPException, you can create and use a custom exception class as follows.fromfastapiimportFastAPIfromfastapi.requestsimportRequestapp=FastAPI()classCustomException(Exception):def__init__(self,status_code:int,message:Any):self.status_code=status_codeself.message=message@app.exception_handler(CustomException)asyncdefcustom_exception_handler(request:Request,exc:CustomException):content={"success":False,"error":{"message":exc.message}}returnJSONResponse(status_code=exc.status_code,content=content,)@app.get("/test")@rate_limiter(limit=3,seconds=30,exception=CustomException)asyncdeftest_list_api(request:Request):...You can return results as a JSONResponse in the desired format via a custom exception.However, when creating a custom exception, there is a limitation that onlystatus_codeandmessagecan be used. Since the limits of the structure are not checked withinmessage, it seems that it can have a free form.Get client real IP AddressWhen checking the API rate limit, use a key combining the client's IP address and API url path.If all client IP addresses are the same, the rate limit will be shared by all users rather than individual users.Here we introduce a method to check the actual IP address of the client when using uvicorn and gunicorn.uvicornuvicorn uses--proxy-headersand--forwarded-allow-ipsDetailed information about options can be found in theuvicorndocument.uvicornapp.main:app--reload--host0.0.0.0--port8000--proxy-headers--forwarded-allow-ips"*"gunicorngunicorn uses the--forwarded-allow-ipsoptionDetailed information about the option can be found in thegunicorndocument.gunicornapp.main:app--bind0.0.0.0:8000-kuvicorn.workers.UvicornWorker--forwarded-allow-ips"*"LicenseThis project is licensed under the terms of the MIT license.