在 POSTMAN 上测试端点时出现 Python FastAPI 错误

问题描述 投票:0回答:1

我正在尝试为我的 API 创建速率限制,我正在使用这种方法。 但是当我在 POSTMAN 上运行端点时,它不起作用。它给了我内部服务器错误

TypeError: RateLimiterMiddleware.__call__() got an unexpected keyword argument 'app' INFO:     127.0.0.1:53544 - "POST /battery HTTP/1.1" 500 Internal Server Error

上面的错误是我收到的,只有当我在 POSTMAN 上测试端点时才会收到此错误

我已经尝试了一切,但还是不行。我有一个 middleware.py,另一个用于 eeping 请求计数的文件和我的 main.py,其中有我的所有端点。

这是我的 middleware.py,我遇到问题的函数是

from fastapi import FastAPI, Request, HTTPException
from typing import Callable, Any
from request_counter import RequestCounter
from starlette.requests import Request
import time


class RateLimiterMiddleware:
    def __init__(self, app: FastAPI, max_requests: int, window_seconds: int, request_counter: RequestCounter):
        self.app = app
        self.request_counter = request_counter
        self.max_requests = max_requests
        self.window_seconds = window_seconds

    async def __call__(self, request: Request, call_next: Callable[[Request], Any]):
        client_ip = request.client.host
        current_time = time.time()

        request_count = self.request_counter.check_rate_limit(
            client_ip, current_time, self.window_seconds, self.max_requests)
        if request_count >= self.max_requests:
            raise HTTPException(status_code=429, detail="Too Many Requests")

        self.request_counter.increase_request_count(
            client_ip, current_time, self.window_seconds)
        return await call_next(request)

下面是我保存请求计数的地方

from fastapi import HTTPException


class RequestCounter:
    def __init__(self):
        self.request_counts = {}

    def increase_request_count(self, client_ip, current_time, window_seconds):
        timestamp = int(current_time - window_seconds)

        if client_ip not in self.request_counts:
            self.request_counts[client_ip] = {}

        if timestamp not in self.request_counts:
            self.request_counts[timestamp] = 0

        self.request_counts[client_ip][timestamp] += 1

    def check_rate_limit(self, client_ip, current_time, window_seconds, max_requests):
        timestamp = int(current_time - window_seconds)

        if client_ip not in self.request_counts or timestamp not in self.request_counts[client_ip]:
            return 0

        request_count = self.request_counts[client_ip][timestamp]
        if request_count >= max_requests:
            raise HTTPException(status_code=429, detail="Too Many Requests")

        return request_count


这是我的main.py


from config import init_firebase
from firebase_admin import firestore
from fastapi import FastAPI, HTTPException
from models import Battery
from typing import List
from middleware import RateLimiterMiddleware
from request_counter import RequestCounter


init_firebase()

app = FastAPI()

db = firestore.client()


request_counter = RequestCounter()
rate_limiter_middleware = RateLimiterMiddleware(
    app, max_requests=10, window_seconds=60, request_counter=request_counter)

app.add_middleware(rate_limiter_middleware)


@app.post("/battery/", response_model=Battery)
async def create_battery(battery: Battery):
    try:
        doc_ref = db.collection("batteries").document()
        doc_ref.set(battery.model_dump())
        return {**battery.model_dump(), "id": doc_ref.id}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@app.get("/batteries/", response_model=List[Battery])
async def get_batteries():
    try:
        ref = db.collection("batteries")
        batteries = ref.stream()

        battery_list = []

        for battery in batteries:
            data = battery.to_dict()
            battery_list.append(data)
        return battery_list
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

python fastapi rate-limiting rate
1个回答
0
投票

FastAPI.add_middleware()
继承自 Starlette,它接受它自己的中间件类。您需要使用
app.middleware("http")(rate_limiter_middleware)
FastAPI
的中间件装饰器)才能使其工作

© www.soinside.com 2019 - 2024. All rights reserved.