Spaces:
Paused
Paused
Download server/credentials.py from Bit-Trading-Company/ASE-GLM: direct link, hf CLI and curl.
- Browser
- Download file 4.19 kB
-
https://huggingface.co/spaces/Bit-Trading-Company/ASE-GLM/resolve/main/server/credentials.py
- Command line
-
hf download hf://spaces/Bit-Trading-Company/ASE-GLM/server/credentials.py
-
curl -L -o credentials.py https://huggingface.co/spaces/Bit-Trading-Company/ASE-GLM/resolve/main/server/credentials.py
4.19 kB
| """Which token pays for a request. | |
| The rule this file exists to enforce: **bill the viewer, not the Space owner, | |
| whenever we possibly can.** A harness that quietly spends the owner's inference | |
| credits on every visitor is one shared link away from an unpleasant invoice. | |
| Precedence, highest first: | |
| 1. the signed-in viewer's Hugging Face OAuth token -> billed to the viewer | |
| 2. a key the viewer pasted into the UI this session -> billed to the viewer | |
| 3. the Space's own ``HF_TOKEN`` secret -> billed to the owner | |
| Step 3 is off unless ``ASE_ALLOW_SPACE_CREDITS`` is set, so the fallback is a | |
| deliberate act rather than a default. Locally it is on, because there is no | |
| OAuth off-Space and a dev loop that cannot make a request is useless. | |
| """ | |
| from __future__ import annotations | |
| import os | |
| from dataclasses import dataclass | |
| from pathlib import Path | |
| class Credential: | |
| token: str | None | |
| mode: str # oauth | user-key | space-secret | none | |
| who: str | None = None | |
| detail: str = "" | |
| def bills_viewer(self) -> bool: | |
| return self.mode in ("oauth", "user-key") | |
| def to_json(self) -> dict: | |
| return { | |
| "mode": self.mode, | |
| "who": self.who, | |
| "billsViewer": self.bills_viewer, | |
| "detail": self.detail, | |
| } | |
| def on_space() -> bool: | |
| return bool(os.environ.get("SPACE_ID")) | |
| def allow_space_credits() -> bool: | |
| """Falling back to the owner's token is opt-in on a Space, on by default off it.""" | |
| flag = os.environ.get("ASE_ALLOW_SPACE_CREDITS") | |
| if flag is not None: | |
| return flag.strip().lower() in ("1", "true", "yes", "on") | |
| return not on_space() | |
| def resolve(oauth_token: str | None = None, | |
| oauth_user: str | None = None, | |
| user_key: str | None = None) -> Credential: | |
| """Pick the credential for one request. Never logs or returns the value.""" | |
| if oauth_token: | |
| return Credential(oauth_token, "oauth", oauth_user, | |
| "Signed in with Hugging Face; inference is billed to you.") | |
| if user_key: | |
| return Credential(user_key, "user-key", None, | |
| "Using the key you supplied; it is held for this session only.") | |
| secret = (os.environ.get("HF_TOKEN") | |
| or os.environ.get("HUGGING_FACE_HUB_TOKEN") | |
| or _dev_key_file()) | |
| if secret and allow_space_credits(): | |
| return Credential( | |
| secret, "space-secret", None, | |
| "Falling back to the Space's own token — this bills the Space owner.", | |
| ) | |
| if secret: | |
| return Credential( | |
| None, "none", None, | |
| "A Space token exists but owner-billed requests are disabled. " | |
| "Sign in, or supply your own key.", | |
| ) | |
| return Credential(None, "none", None, | |
| "No credential available. Supply a Hugging Face token.") | |
| def _dev_key_file() -> str | None: | |
| """The shared ``key.txt`` this workspace keeps for local development. | |
| Only consulted off a Space. On a Space the token arrives as a secret in the | |
| environment and this path does not exist, so the lookup is dead code there | |
| rather than a second way in. | |
| """ | |
| if on_space(): | |
| return None | |
| explicit = os.environ.get("ASE_KEY_FILE") | |
| if explicit: | |
| # Authoritative when set, including when it points at nothing. The | |
| # search below would otherwise reach outside a test's tmp_path and | |
| # find the developer's real key, which is a test that passes for the | |
| # wrong reason and a suite that behaves differently on CI. | |
| candidates = [Path(explicit)] | |
| else: | |
| # The workspace deliberately keeps one gitignored key above the | |
| # projects so several of them can share it. Walk up to find it. | |
| here = Path(__file__).resolve() | |
| candidates = [parent / "key.txt" for parent in here.parents[:5]] | |
| for path in candidates: | |
| try: | |
| if path.is_file(): | |
| token = path.read_text().strip() | |
| if token: | |
| return token | |
| except OSError: | |
| continue | |
| return None | |