added rate-limiting for specific requests
This commit is contained in:
+17
-1
@@ -17,6 +17,7 @@ from fastapi.responses import PlainTextResponse
|
||||
from calendar_feed import build_ics
|
||||
from datasource import EventStore, iter_artist_names, parse_event_date
|
||||
from models import Event, EventList
|
||||
from rate_limit import Cooldown
|
||||
from scrape_schedule import discover_cron_expr, get_schedule_info
|
||||
|
||||
app = FastAPI(
|
||||
@@ -27,6 +28,9 @@ app = FastAPI(
|
||||
|
||||
store = EventStore()
|
||||
|
||||
_RELOAD_MIN_INTERVAL_SECONDS = float(os.environ.get("RELOAD_MIN_INTERVAL_SECONDS", "10"))
|
||||
_reload_cooldown = Cooldown(_RELOAD_MIN_INTERVAL_SECONDS)
|
||||
|
||||
|
||||
def _matches(
|
||||
event: Event,
|
||||
@@ -82,7 +86,19 @@ def health():
|
||||
|
||||
@app.post("/reload")
|
||||
def reload():
|
||||
"""Re-read the data file(s) from disk (e.g. after a fresh scrape)."""
|
||||
"""Re-read the data file(s) from disk (e.g. after a fresh scrape).
|
||||
|
||||
Rate-limited to one call per RELOAD_MIN_INTERVAL_SECONDS (default 10s)
|
||||
to stop it being hammered - a fresh scrape doesn't land any more often
|
||||
than that anyway.
|
||||
"""
|
||||
remaining = _reload_cooldown.try_acquire()
|
||||
if remaining is not None:
|
||||
raise HTTPException(
|
||||
status_code=429,
|
||||
detail=f"Reload rate-limited; try again in {remaining:.1f}s",
|
||||
headers={"Retry-After": str(int(remaining) + 1)},
|
||||
)
|
||||
try:
|
||||
count = store.reload()
|
||||
except FileNotFoundError as exc:
|
||||
|
||||
Reference in New Issue
Block a user