Skip to content

Middleware

RateLimitingMiddleware

Bases: BaseHTTPMiddleware

Source code in fastlimits/middleware.py
class RateLimitingMiddleware(BaseHTTPMiddleware):
    def __init__(
        self,
        app: ASGIApp,
        strategy: RateLimiter,
        keys: Optional[
            Union[CallableMiddlewareKey, List[CallableMiddlewareKey]]
        ] = None,
    ) -> None:
        self.strategy = strategy
        self.keys: list[CallableMiddlewareKey] = (
            ensure_list(keys) if keys else ensure_list(get_remote_address)
        )
        super().__init__(app)

    async def dispatch(
        self, request: Request, call_next: Callable[[Request], Awaitable[Response]]
    ) -> Response:
        # just add the limit middleware to the request.state, the dependency on the 'APIRoute' takes care of the rest
        request.state.limiter = self
        response = await call_next(request)
        try:
            limit: "BaseLimiterDependency" = request.state.limit
            limit_keys: list[str] = request.state.limit_keys
        except AttributeError:
            return response
        if (
            limit.no_hit_status_codes
            and response.status_code in limit.no_hit_status_codes
        ):
            return response

        await self.strategy.hit(
            limit.item,
            *limit_keys,
        )
        return response

strategy instance-attribute

strategy = strategy

keys instance-attribute

__init__

__init__(
    app: ASGIApp,
    strategy: RateLimiter,
    keys: Optional[
        Union[
            CallableMiddlewareKey,
            List[CallableMiddlewareKey],
        ]
    ] = None,
) -> None
Source code in fastlimits/middleware.py
def __init__(
    self,
    app: ASGIApp,
    strategy: RateLimiter,
    keys: Optional[
        Union[CallableMiddlewareKey, List[CallableMiddlewareKey]]
    ] = None,
) -> None:
    self.strategy = strategy
    self.keys: list[CallableMiddlewareKey] = (
        ensure_list(keys) if keys else ensure_list(get_remote_address)
    )
    super().__init__(app)

dispatch async

dispatch(
    request: Request,
    call_next: Callable[[Request], Awaitable[Response]],
) -> Response
Source code in fastlimits/middleware.py
async def dispatch(
    self, request: Request, call_next: Callable[[Request], Awaitable[Response]]
) -> Response:
    # just add the limit middleware to the request.state, the dependency on the 'APIRoute' takes care of the rest
    request.state.limiter = self
    response = await call_next(request)
    try:
        limit: "BaseLimiterDependency" = request.state.limit
        limit_keys: list[str] = request.state.limit_keys
    except AttributeError:
        return response
    if (
        limit.no_hit_status_codes
        and response.status_code in limit.no_hit_status_codes
    ):
        return response

    await self.strategy.hit(
        limit.item,
        *limit_keys,
    )
    return response