我正在尝试为我的 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))
FastAPI.add_middleware()
继承自 Starlette,它接受它自己的中间件类。您需要使用 app.middleware("http")(rate_limiter_middleware)
(FastAPI
的中间件装饰器)才能使其工作