| """Stop the dependencies phoning home, before they get the chance. |
| |
| **What was happening.** Constructing a `gradio.Blocks` reaches |
| `api.gradio.app` and `huggingface.co`. Constructing a `gradio_client.Client` |
| reaches `huggingface.co` twice, once for a registry lookup and once for |
| telemetry carrying the URL of the server the operator typed. Both happen on |
| import or construction, before anything is served and before any pairing |
| succeeds, and the second one is worse than it sounds: on a self-hosted, tunnel |
| or private-network deployment, that URL is the thing the operator was keeping |
| private. |
| |
| `distinct_agent/transport.py` already passed `analytics_enabled=False` to the |
| client. It does nothing. `gradio_client` reads it as:: |
| |
| analytics_enabled or os.getenv("GRADIO_ANALYTICS_ENABLED", "True") == "True" |
| |
| and `False or True` is `True`, so the keyword cannot turn anything off. The |
| environment variable is the only control that works, and the registry lookup |
| inside `huggingface_hub` answers to neither: only `HF_HUB_OFFLINE` stops it. |
| |
| **Why this is set here rather than documented.** A project whose whole claim is |
| that prompts stay on machines their operator chose does not get to ship a |
| default that contacts two third parties on start-up and print a note about it |
| in a README. Deployment advice is not a control. This is a control. |
| |
| **Set, not forced.** Each variable is left alone if the operator has already |
| set it, including to a value that turns telemetry back on. Somebody who |
| deliberately wants the upstream analytics can have them; nobody gets them by |
| default and by accident. |
| |
| `HF_HUB_OFFLINE` does not affect model weights. Nothing in this repository |
| imports `huggingface_hub`: `distinct_agent/weights.py` downloads with |
| `urllib.request` from a pinned URL and verifies a SHA-256 before the file is |
| put into place. The variable only silences the library gradio brings with it. |
| |
| **What this cannot do.** It works because it runs before `gradio` or |
| `gradio_client` is first imported, which is why the calls sit at the top of |
| `distinct_server/__init__.py` and `distinct_agent/__init__.py`: importing |
| either package runs its `__init__` first. Code that imports `gradio` before it |
| imports anything of ours is outside this, and a test in |
| `tests/test_redteam_regressions.py` pins the ordering so that a later import |
| tidy-up cannot quietly undo it. |
| """ |
|
|
| from __future__ import annotations |
|
|
| import os |
| from collections.abc import MutableMapping |
| from typing import Optional |
|
|
| |
| |
| |
| |
| TELEMETRY_DEFAULTS: dict[str, str] = { |
| |
| |
| "GRADIO_ANALYTICS_ENABLED": "False", |
| |
| "HF_HUB_DISABLE_TELEMETRY": "1", |
| |
| |
| "HF_HUB_OFFLINE": "1", |
| } |
|
|
|
|
| def silence_third_party_telemetry( |
| environ: Optional[MutableMapping[str, str]] = None, |
| ) -> tuple[str, ...]: |
| """Default the telemetry variables to off. Returns the names it set. |
| |
| Returning the names rather than nothing so a caller can say what it did, |
| and so a test can tell "already off" from "turned off here" without |
| reading the environment twice. |
| """ |
|
|
| target = os.environ if environ is None else environ |
| changed: list[str] = [] |
| for name, value in TELEMETRY_DEFAULTS.items(): |
| if target.get(name) is None: |
| target[name] = value |
| changed.append(name) |
| return tuple(changed) |
|
|