Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to override the Rate Limter dependency ? #27

Open
Miguelme opened this issue Feb 10, 2023 · 3 comments
Open

Is it possible to override the Rate Limter dependency ? #27

Miguelme opened this issue Feb 10, 2023 · 3 comments

Comments

@Miguelme
Copy link

What is the expected way of overriding the dependency for the rate limiter from the tests? Any example would be appreciated

@WaldemarEnns
Copy link

Also looking forward to a solution ... how are we supposed to test our endpoints when rate-limiting is active?

In my case, I have the following test-file:

from fastapi.testclient import TestClient
from app.misc import normalize_phone_number
from app.database.models.user import User
from app.misc import get_db
from app.services.otp import store_otp_for_user
from app.main import app

client = TestClient(app)

def test_register_new_user(clear_database):
  clear_database()
  phone_number = "+4915202551672"
  response = client.post(
    "/users/register",
    json={
      "name": "Test User",
      "phone_number": phone_number
    }
  )

  assert response.status_code == 201
  assert response.json()["id"] == 1
  assert response.json()["name"] == "Test User"
  assert response.json()["phone_number"] == normalize_phone_number(phone_number)
  assert response.json()["verified"] == False
  
  # get the user from the db
  session = next(get_db())
  user = session.query(User).filter(User.id == 1).first()
  assert len(user.otps) == 1

Using pytest for testing, results in the following error:

FAILED tests/test_user_registration.py::test_register_new_user - Exception: You must call FastAPILimiter.init in startup event of fastapi!

As far as I know, the startup event is not being called by the TestClient?

@JameStitel
Copy link

I have managed to do so by modifying the RateLimiter class:

class CustomRateLimiter(RateLimiter):
    def __hash__(self) -> int:
        return hash(f"limiter-{hash(self.CUSTOM_ID_VALUE)}")

    def __eq__(self, other: object) -> bool:
        if isinstance(other, CustomRateLimiter):
            return self.CUSTOM_ID_VALUE == other.CUSTOM_ID_VALUE
        return False  

Then use app.dependency_overrides[CustomRateLimiter(xxx)] = lambda: True, where xxx is the exact same setting as in the endpoint for which you want to override the RateLimiter dependency (in the case of lambda: True it basically disables the rate limit).

Source: fastapi/fastapi#2795 (comment)

@n0t-4m17h
Copy link

I have managed to do so by modifying the RateLimiter class:

class CustomRateLimiter(RateLimiter):
    def __hash__(self) -> int:
        return hash(f"limiter-{hash(self.CUSTOM_ID_VALUE)}")

    def __eq__(self, other: object) -> bool:
        if isinstance(other, CustomRateLimiter):
            return self.CUSTOM_ID_VALUE == other.CUSTOM_ID_VALUE
        return False  

Then use app.dependency_overrides[CustomRateLimiter(xxx)] = lambda: True, where xxx is the exact same setting as in the endpoint for which you want to override the RateLimiter dependency (in the case of lambda: True it basically disables the rate limit).

Source: fastapi/fastapi#2795 (comment)

FIxes pytest issues, but for my implementation, where I've seperated GET and PUT,etc., rate limit values, my fastapi app applies the GET timer to non-GET endpoints. Some overlap in the hash by redis or something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants