Spaces:
Running
Running
Download backend/core/usage.py from siddhm11/prompt-engine: direct link, hf CLI and curl.
- Browser
- Download file 2.28 kB
-
https://huggingface.co/spaces/siddhm11/prompt-engine/resolve/main/backend/core/usage.py
- Command line
-
hf download hf://spaces/siddhm11/prompt-engine/backend/core/usage.py
-
curl -L -o usage.py https://huggingface.co/spaces/siddhm11/prompt-engine/resolve/main/backend/core/usage.py
2.28 kB
| """ | |
| Daily-usage accounting that survives a database outage. | |
| check_daily_limit() used to initialise `count = 0`, run a Mongo | |
| count_documents(), and swallow any exception. A read failure therefore | |
| returned "0 used" and every caller got an unlimited allowance — and because | |
| the shared Groq key is ~100 enhancements/day for the whole user base, a single | |
| Atlas free-tier pause could drain the org quota in minutes and surface to | |
| everyone as a total outage. | |
| Failing closed instead is not an improvement on its own: it turns a transient | |
| blip into "nobody can use the product". So Mongo stays authoritative when it | |
| answers, and this module keeps a per-process shadow tally to fall back on. | |
| Scope and limits, stated plainly: the tally lives in this process's memory. The | |
| Space runs a single uvicorn worker with no --workers flag, so today that is the | |
| whole picture. It resets on restart, which is why a degraded read also clamps | |
| to DEGRADED_LIMIT rather than trusting a tally that may have just been born. | |
| Move this to an atomic Mongo $inc on a per-day document before running more | |
| than one worker. | |
| """ | |
| import threading | |
| from datetime import date | |
| _lock = threading.Lock() | |
| _counts: dict = {} # user_id -> [iso_date, count] | |
| # Ceiling applied when the datastore is unreachable and the shadow tally cannot | |
| # be trusted to be complete (e.g. the process restarted mid-outage). | |
| DEGRADED_LIMIT = 3 | |
| def _today() -> str: | |
| return date.today().isoformat() | |
| def record(user_id: str) -> None: | |
| """Count one billable enhancement for today.""" | |
| if not user_id: | |
| return | |
| today = _today() | |
| with _lock: | |
| entry = _counts.get(user_id) | |
| if entry is None or entry[0] != today: | |
| _counts[user_id] = [today, 1] | |
| else: | |
| entry[1] += 1 | |
| def get(user_id: str) -> int: | |
| """Enhancements this process has seen from this user today.""" | |
| with _lock: | |
| entry = _counts.get(user_id) | |
| if entry is None or entry[0] != _today(): | |
| return 0 | |
| return entry[1] | |
| def prune() -> None: | |
| """Drop entries from previous days. Cheap; safe to call opportunistically.""" | |
| today = _today() | |
| with _lock: | |
| for uid in [u for u, e in _counts.items() if e[0] != today]: | |
| _counts.pop(uid, None) | |