Initial commit: CI Agent competitive-intelligence monitoring app
FastAPI + Celery + Next.js + Postgres/Redis app with company monitoring, source collection, LLM-based change analysis, enrichment, and account security (Turnstile, escalating lockout, email verification).
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
"""Shared rate limiter (slowapi / limits, in-memory by default).
|
||||
|
||||
Applied per-route via `@limiter.limit(...)`. Auth endpoints get the
|
||||
tightest limits since they're the classic credential-stuffing target.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import Request
|
||||
from slowapi import Limiter
|
||||
|
||||
from app.core.config import get_settings
|
||||
from app.core.security import get_client_ip
|
||||
|
||||
|
||||
def _client_ip_key(request: Request) -> str:
|
||||
"""Same IP resolution as everything else in the app (is_localhost, the
|
||||
ban/throttle engine) - slowapi's own get_remote_address reads
|
||||
request.client.host directly, which would be Nginx/Cloudflare's own
|
||||
address for every visitor once deployed behind a reverse proxy,
|
||||
collapsing all rate limits into one shared bucket. See
|
||||
app.core.security.get_client_ip / Settings.trusted_proxy_ip_header."""
|
||||
return get_client_ip(request, get_settings())
|
||||
|
||||
|
||||
# Disabled under APP_ENV=test so the many auth calls a test suite makes don't
|
||||
# trip real limits (real limiter behavior is covered by its own test).
|
||||
limiter = Limiter(key_func=_client_ip_key, enabled=get_settings().app_env != "test")
|
||||
Reference in New Issue
Block a user