gaurv007 commited on
Commit
376db46
Β·
verified Β·
1 Parent(s): 15e2d6a

v4.2: Update api/main.py

Browse files
Files changed (1) hide show
  1. api/main.py +18 -11
api/main.py CHANGED
@@ -58,8 +58,9 @@ HF_API_TOKEN = os.environ.get("HF_API_TOKEN", "")
58
  SAULLM_ENDPOINT = os.environ.get("SAULLM_ENDPOINT", "")
59
  MAX_TEXT_LENGTH = int(os.environ.get("MAX_TEXT_LENGTH", "200000"))
60
 
61
- # ─── FIX v4.1: Sliding window rate limiter with proper IP extraction ───
62
  _rate_limits: dict[str, list[float]] = {}
 
63
  RATE_LIMIT_REQUESTS = 30
64
  RATE_LIMIT_WINDOW = 60 # seconds
65
 
@@ -71,8 +72,17 @@ def _get_client_ip(request: Request) -> str:
71
  return request.client.host if request.client else "unknown"
72
 
73
  def _check_rate_limit(client_ip: str) -> bool:
74
- """Sliding window rate limiter."""
 
75
  now = time.time()
 
 
 
 
 
 
 
 
76
  if client_ip not in _rate_limits:
77
  _rate_limits[client_ip] = []
78
 
@@ -85,13 +95,6 @@ def _check_rate_limit(client_ip: str) -> bool:
85
  return False
86
 
87
  _rate_limits[client_ip].append(now)
88
-
89
- # Periodic cleanup of stale IPs (every 100 requests)
90
- if len(_rate_limits) > 1000:
91
- stale = [ip for ip, ts in _rate_limits.items() if not ts or now - ts[-1] > RATE_LIMIT_WINDOW * 2]
92
- for ip in stale:
93
- del _rate_limits[ip]
94
-
95
  return True
96
 
97
  # ─── Supabase helper ───
@@ -193,11 +196,15 @@ async def lifespan(app: FastAPI):
193
 
194
  app = FastAPI(title="ClauseGuard API", version="4.1.0", lifespan=lifespan)
195
 
 
 
196
  ALLOWED_ORIGINS = [
197
  "https://clauseguardweb.netlify.app",
198
- "http://localhost:3000",
199
- "http://localhost:3001",
200
  ]
 
 
 
 
201
  app.add_middleware(
202
  CORSMiddleware,
203
  allow_origins=ALLOWED_ORIGINS,
 
58
  SAULLM_ENDPOINT = os.environ.get("SAULLM_ENDPOINT", "")
59
  MAX_TEXT_LENGTH = int(os.environ.get("MAX_TEXT_LENGTH", "200000"))
60
 
61
+ # ─── FIX v4.2: Improved sliding window rate limiter with periodic cleanup ───
62
  _rate_limits: dict[str, list[float]] = {}
63
+ _rate_limits_last_cleanup: float = 0.0
64
  RATE_LIMIT_REQUESTS = 30
65
  RATE_LIMIT_WINDOW = 60 # seconds
66
 
 
72
  return request.client.host if request.client else "unknown"
73
 
74
  def _check_rate_limit(client_ip: str) -> bool:
75
+ """Sliding window rate limiter with periodic stale-IP cleanup."""
76
+ global _rate_limits_last_cleanup
77
  now = time.time()
78
+
79
+ # FIX v4.2: Periodic cleanup every 60s regardless of dict size
80
+ if now - _rate_limits_last_cleanup > 60:
81
+ stale = [ip for ip, ts in _rate_limits.items() if not ts or now - ts[-1] > RATE_LIMIT_WINDOW * 2]
82
+ for ip in stale:
83
+ del _rate_limits[ip]
84
+ _rate_limits_last_cleanup = now
85
+
86
  if client_ip not in _rate_limits:
87
  _rate_limits[client_ip] = []
88
 
 
95
  return False
96
 
97
  _rate_limits[client_ip].append(now)
 
 
 
 
 
 
 
98
  return True
99
 
100
  # ─── Supabase helper ───
 
196
 
197
  app = FastAPI(title="ClauseGuard API", version="4.1.0", lifespan=lifespan)
198
 
199
+ # FIX v4.2: CORS origins configurable via env var; localhost only in dev
200
+ _extra_origins = os.environ.get("CORS_EXTRA_ORIGINS", "").split(",")
201
  ALLOWED_ORIGINS = [
202
  "https://clauseguardweb.netlify.app",
 
 
203
  ]
204
+ # Only add localhost origins if explicitly enabled via env
205
+ if os.environ.get("CORS_ALLOW_LOCALHOST", "").lower() == "true":
206
+ ALLOWED_ORIGINS.extend(["http://localhost:3000", "http://localhost:3001"])
207
+ ALLOWED_ORIGINS.extend([o.strip() for o in _extra_origins if o.strip()])
208
  app.add_middleware(
209
  CORSMiddleware,
210
  allow_origins=ALLOWED_ORIGINS,