|
1 | 1 | import asyncio |
| 2 | +import math |
2 | 3 | import signal |
3 | 4 | import sys |
4 | 5 |
|
5 | 6 | import fastapi |
| 7 | +import redis.asyncio as redis |
6 | 8 | import sqlmodel |
7 | 9 | from fastapi.middleware.cors import CORSMiddleware |
| 10 | +from fastapi_limiter import FastAPILimiter |
8 | 11 | from loguru import logger |
9 | 12 | from oasst_inference_server import database, deps, models, plugins |
10 | 13 | from oasst_inference_server.routes import account, admin, auth, chats, configs, workers |
11 | 14 | from oasst_inference_server.settings import settings |
12 | 15 | from oasst_shared.schemas import inference |
13 | 16 | from prometheus_fastapi_instrumentator import Instrumentator |
14 | 17 | from starlette.middleware.sessions import SessionMiddleware |
| 18 | +from starlette.status import HTTP_429_TOO_MANY_REQUESTS |
15 | 19 |
|
16 | 20 | app = fastapi.FastAPI(title=settings.PROJECT_NAME) |
17 | 21 |
|
@@ -81,6 +85,27 @@ async def alembic_upgrade(): |
81 | 85 | signal.signal(signal.SIGINT, signal.SIG_DFL) |
82 | 86 |
|
83 | 87 |
|
| 88 | +@app.on_event("startup") |
| 89 | +async def setup_rate_limiter(): |
| 90 | + if not settings.rate_limit: |
| 91 | + logger.warning("Skipping rate limiter setup on startup (rate_limit is False)") |
| 92 | + return |
| 93 | + |
| 94 | + async def http_callback(request: fastapi.Request, response: fastapi.Response, pexpire: int): |
| 95 | + """Error callback function when too many requests""" |
| 96 | + expire = math.ceil(pexpire / 1000) |
| 97 | + raise fastapi.HTTPException(f"Too Many Requests. Retry After {expire} seconds.", HTTP_429_TOO_MANY_REQUESTS) |
| 98 | + |
| 99 | + try: |
| 100 | + client = redis.Redis( |
| 101 | + host=settings.redis_host, port=settings.redis_port, db=settings.redis_ratelim_db, decode_responses=True |
| 102 | + ) |
| 103 | + logger.info(f"Connected to {client=}") |
| 104 | + await FastAPILimiter.init(client, http_callback=http_callback) |
| 105 | + except Exception: |
| 106 | + logger.exception("Failed to establish Redis connection") |
| 107 | + |
| 108 | + |
84 | 109 | @app.on_event("startup") |
85 | 110 | async def maybe_add_debug_api_keys(): |
86 | 111 | debug_api_keys = settings.debug_api_keys_list |
|
0 commit comments