Comments (14)
I was able to solve this by the link you had shared, below is the way if someone needs it:
REQUEST_CTX_KEY = "request_context"
_request_ctx_var: ContextVar[str] = ContextVar(REQUEST_CTX_KEY, default=None)
@app.middleware("http")
async def request_context_middleware(request: Request, call_next):
try:
request_ctx = _request_ctx_var.set(request)
response = await call_next(request)
_request_ctx_var.reset(request_ctx)
return response
except Exception as e:
raise e
Cheers!! @laurentS
from slowapi.
Hi @sdklab007, you should be able to use a callable to pick the limit, like:
def get_limit_for_user():
return "2/minute"
@limiter.limit(get_limit_for_user):
def some_request(request: Request):
pass
and if you want some users to be exempted from the limit, you should also be able to do:
def is_user_exempt():
pass # return a boolean
@limiter.limit(get_limit_for_user, exempt_when=is_request_exempt):
def some_request():
pass
I hope this helps!
from slowapi.
@laurentS Can we reopen this issue in the meantime? A few seem to be asking for it.
Personally I have a user_jwt = Depends(parse_jwt)
, where user_jwt is a JWT Token that has a user_id and a rate limit. It would be useful if slowapi has the ability to read the rate limit from their JWT Token (i.e. have access to the same parameters as the API request itself). A separate feature on a similar topic is to use their user_id as the key instead of their IP address.
It might be hard to implement, but I'm thinking of a use case like this:
@limiter.limit("4/second")
@limiter.limit("20/minute")
@limiter.limit("500/hour")
@limiter.limit("10000/day")
@limiter.limit(custom=...)
@router.post("/get-some-data")
async def get_some_data(data: dict = Body(...), user_jwt: dict = Depends(guard_login)):
Where, the first 4 use the IP address as key, and the second 4 are by user_id using the user_id as key and the JWT's rate limit. custom
receives a Python function that takes in all of the parameters of the API request (data = Body(...), user_jwt = Depends(parse_jwt), db = Depends(get_db))
, and returns the key and List[rate limit strings]. For @seizoux's PSQL use case, he can use db
as a parameter (And the IP rate limit before it prevents abusing db connections too much).
Perhaps some or all of that is not possible, I'm not really sure what's under the hood or how this is implemented.
from slowapi.
@sdklab007 sorry for the lag. I'm afraid I don't have a good solution for your last question. This is a use case which I don't think has been needed so far. The code was ported from flask-limiter
where it's possible to access the current request object almost like a global variable (see encode/starlette#420 for a bit more on this), and I did not think of this at the time.
If you're in a hurry, you can probably hack something together based on the ticket above, but I'll add it to my todo list to change the code to handle this use case, I think the current status is not acceptable 😓
Obviously, PRs are always welcome if you're faster to it than me! 😉
from slowapi.
any news here? i have an async func that calls my PSQL database and returns a str containing a ratelimit, i want to use this.
from slowapi.
With FastAPI becoming more and more popular, this is a common usecase now. Either request should be made accessible or async dynamic limit Callable must be supported.
Async support would probably be easier and help with most cases?
@laurentS What are your thoughts on this?
from slowapi.
@laurentS Thank you so much.
from slowapi.
@laurentS One more query, how do I get the request object in get_limit_for_user to identify the user.
from slowapi.
@laurentS Thanks for your kind update. I need to hack a bit as per the link you've shared.
Sure, I will see if I can contribute :)
from slowapi.
This post help me a lot! Thanks
from slowapi.
Could someone give an example, of how to use @sdklab007's code in practice?
My endpoint is the following:
@app.post("/v1/chat/completions")
@limiter.limit("2/second")
@limiter.limit("10/minute")
@limiter.limit("100/hour")
@limiter.limit("2000/day")
async def chat_completion(request: Request, data: dict = Body(...)):
model = data.get("model", None)
I want to check if the model equals llama-70b
, if, set rate limits to:
@limiter.limit("1/second")
@limiter.limit("5/minute")
@limiter.limit("50/hour")
@limiter.limit("1000/day")
from slowapi.
You can also use a double-wrapper (a whopper 😃) to get access to the request.
def condition_func(request: Request, func, *args, **kwargs):
if no_limit:
return func.__wrapped__(request=request, *args, **kwargs) # call unlimited func
return func(request=request, *args, **kwargs)
def ratelimit(*decor_args, **decor_kwargs):
def decorate(func):
condition_func = decor_kwargs.pop('condition_func')
func = decor_kwargs.pop('limiter').limit(*decor_args, **decor_kwargs)(func)
@functools.wraps(func)
def wrapper(request: Request, *args, **kwargs):
return condition_func(request, func, *args, **kwargs)
return wrapper
return decorate
Use it like the original:
@ratelimit('10/day', limiter=limiter, condition_func=condition_func)
from slowapi.
@gellnerm Could you show me a complete example in fastapi? Also on discord if you want (username: fredipy)
Thanks
from slowapi.
Like I want to change the rate limit based on the data that gets sent.
data = await request.json()
if data.get("model") == "llama-2-13b":
rate_limit = "5/minute;30/hour"
from slowapi.
Related Issues (20)
- Dependency Dashboard
- Hi @smittysmee this is not my day job, it's 100% volunteer work, so priority may fall behind. The process for publishing an update is a bit manual still. If you want to give a hand with opening a PR to prepare for a release 0.1.8, I think a lot of people will be grateful. Examples from past releases #120 or #108. As a policy (see #58 ), I add any contributor who's had at least one PR merged to the repo, to help reduce bottlenecks. You're welcome to join the team!
- Features
- Feature | Can this support individual limits by IP address or user token? HOT 1
- slowapi uses limits==2.8.0 which contains usage of deprecated pkg_resources
- Bug: slowapi shared limiter does not accept callable for scope parameter HOT 3
- add multiple limiters on a single route. HOT 15
- The limiters of different routes with the same function name are confused, resulting in multiple checks HOT 1
- [Ehancement] Don't require `Request` parameter to be present in endpoint function signature. HOT 4
- Add as package in arch user repository
- Exception: No "request" or "websocket" argument on function HOT 3
- Need Rate Limiting on Basis of Request Body for a POST API HOT 1
- mypy error: type of `_rate_limit_exceeded_handler` is incompatible with latest starlette HOT 1
- Wrong parsing of limit_value when having more than one decorator HOT 1
- `request` parameter unable to be renamed HOT 1
- Consider avoiding BaseHTTPMiddleware as parent of SlowAPIMiddleware HOT 2
- [Feature request] - Limiter global `exempt_when` option
- {Token, User}-dependent rate limit control HOT 9
- dynamic_limit isn't really dynamic HOT 2
- There is 'cp949' encoding error in Windows
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from slowapi.