Spaces:
Running
Running
Download utils/public_forms.py from Success-dev/venthrive-api: direct link, hf CLI and curl.
- Browser
- Download file 1.71 kB
-
https://huggingface.co/spaces/Success-dev/venthrive-api/resolve/main/utils/public_forms.py
- Command line
-
hf download hf://spaces/Success-dev/venthrive-api/utils/public_forms.py
-
curl -L -o public_forms.py https://huggingface.co/spaces/Success-dev/venthrive-api/resolve/main/utils/public_forms.py
1.71 kB
| """ | |
| Shared checks for the public, no-sign-in forms (/bsa and /bff): a simple rate | |
| limiter and the contact-detail validators. Rate limits are in-memory, per | |
| process (same trade-off as routes/help.py). | |
| """ | |
| import re | |
| import threading | |
| import time | |
| from collections import defaultdict | |
| from fastapi import HTTPException | |
| EMAIL_RE = re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$") | |
| # Digits with an optional leading +, allowing the spaces, dashes, dots and brackets people type. | |
| PHONE_RE = re.compile(r"^\+?[\d\s().-]+$") | |
| class RateLimiter: | |
| """Allows `count` hits per `period` seconds for each key.""" | |
| def __init__(self): | |
| self._lock = threading.Lock() | |
| self._hits: dict[str, list[float]] = defaultdict(list) | |
| def allow(self, key: str, count: int, period: int) -> bool: | |
| now = time.time() | |
| with self._lock: | |
| recent = [t for t in self._hits[key] if now - t < period] | |
| allowed = len(recent) < count | |
| if allowed: | |
| recent.append(now) | |
| self._hits[key] = recent | |
| return allowed | |
| def reset(self): | |
| with self._lock: | |
| self._hits.clear() | |
| def clean_email(raw: str) -> str: | |
| email = raw.strip().lower() | |
| if not EMAIL_RE.match(email): | |
| raise HTTPException(status_code=400, detail="Enter a valid email address.") | |
| return email | |
| def clean_phone(raw: str) -> str: | |
| """Trimmed phone number, kept as typed apart from spacing. 7 to 15 digits.""" | |
| phone = " ".join(raw.split()) | |
| digits = re.sub(r"\D", "", phone) | |
| if not PHONE_RE.match(phone) or not 7 <= len(digits) <= 15: | |
| raise HTTPException(status_code=400, detail="Enter a valid phone number.") | |
| return phone | |