Skip to content

Commit 47244d1

Browse files
committed
🔒 Add global 5rps ratelimit
1 parent 3518703 commit 47244d1

File tree

5 files changed

+100
-5
lines changed

5 files changed

+100
-5
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ ADD ./src /app/
1616
RUN mkdir /app/cache
1717

1818
# ADDING USER
19-
RUN adduser -u 9263 --disabled-password --gecos "" appuser && chown -R appuser /app
19+
RUN adduser -u 9263 --disabled-password --gecos "" appuser && chown -R appuser /app && chown -R appuser /app/cache
2020
USER appuser
2121

2222
HEALTHCHECK CMD curl --fail http://localhost:8000/v1/health || exit 1

app.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
import secrets
44
import logging
55
import os
6+
7+
from slowapi import Limiter, _rate_limit_exceeded_handler
8+
from slowapi.errors import RateLimitExceeded
69
from pydantic import BaseModel
710
from transformers import pipeline
811
from fastapi import FastAPI, HTTPException, status, Depends
12+
from fastapi.requests import Request
913
from fastapi.security import OAuth2PasswordBearer
10-
from concurrent.futures import ThreadPoolExecutor
1114
from dotenv import load_dotenv
1215
from cachier import cachier
1316

@@ -19,6 +22,11 @@
1922
# Create FastAPI instance
2023
app = FastAPI(docs_url=None, redoc_url=None, openapi_url=None)
2124

25+
# Setup rate limiter
26+
limiter = Limiter(key_func=lambda: "global", default_limits=["1000 per day"])
27+
app.state.limiter = limiter # noqa
28+
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler) # noqa
29+
2230
# Setup logging
2331
logging.basicConfig(level=logging.INFO)
2432
logger = logging.getLogger(__name__)
@@ -93,8 +101,12 @@ def classify_sync(message: str, labels: list[str]) -> dict:
93101

94102
# Route to classify message
95103
@app.get("/v1/classify")
104+
@limiter.limit("6/second")
96105
async def classify(
97-
message: str, labels: list[str] = None, token: str = Depends(authenticate_user)
106+
request: Request,
107+
message: str,
108+
labels: list[str] = None,
109+
token: str = Depends(authenticate_user),
98110
) -> Classification:
99111
labels = labels or DEFAULT_LABELS
100112
async with classification_lock: # Ensure only one classification at a time

pdm.lock

Lines changed: 79 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ dependencies = [
1111
"transformers>=4.41.2",
1212
"fastapi>=0.111.0",
1313
"cachier>=3.0.0",
14+
"slowapi>=0.1.9",
1415
]
1516
requires-python = "==3.11.*"
1617
readme = "README.md"

requirements.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ certifi==2024.6.2
88
charset-normalizer==3.3.2
99
click==8.1.7
1010
colorama==0.4.6; sys_platform == "win32" or platform_system == "Windows"
11+
deprecated==1.2.14
1112
dnspython==2.6.1
1213
email-validator==2.2.0
1314
fastapi==0.111.0
@@ -20,8 +21,10 @@ httptools==0.6.1
2021
httpx==0.27.0
2122
huggingface-hub==0.23.4
2223
idna==3.7
24+
importlib-resources==6.4.0
2325
intel-openmp==2021.4.0; platform_system == "Windows"
2426
jinja2==3.1.4
27+
limits==3.12.0
2528
markdown-it-py==3.0.0
2629
markupsafe==2.1.5
2730
mdurl==0.1.2
@@ -57,6 +60,7 @@ rich==13.7.1
5760
safetensors==0.4.3
5861
setuptools==70.1.0
5962
shellingham==1.5.4
63+
slowapi==0.1.9
6064
sniffio==1.3.1
6165
starlette==0.37.2
6266
sympy==1.12.1
@@ -75,5 +79,6 @@ uvloop==0.19.0; (sys_platform != "cygwin" and sys_platform != "win32") and platf
7579
watchdog==4.0.1
7680
watchfiles==0.22.0
7781
websockets==12.0
82+
wrapt==1.16.0
7883
--index-url https://pypi.org/simple
7984
--extra-index-url https://download.pytorch.org/whl/cpu

0 commit comments

Comments
 (0)