Spaces:
Sleeping
A newer version of the Gradio SDK is available: 6.26.0
Developer Guide
This documents how local development differs from running on the Hugging Face Space, since a few things (persistent storage, secrets) work differently in each environment.
Provider API tokens (BYOK)
- Every provider is bring-your-own-key: each user pastes their own API
key(s) into the UI. Keys are persisted in the browser's
localStorageand sent to the server only transiently, as part of each generation request - they are never read from the server environment and never written to disk by this app. - Each
ModelProviderin providers.py declares its ownapi_token_env(just a label identifying which key it needs, e.g.FAL_KEYorREPLICATE_API_TOKEN- not an actual env var read at runtime).app.pyderives one key input field per distinctapi_token_envautomatically (TOKEN_ENVSin app.py), so adding a new provider with a newapi_token_envadds its input field with no other UI changes needed. Providers that share anapi_token_env(e.g. the two fal.ai providers both useFAL_KEY) share one input field. .env/load_dotenv()still exist for non-provider local config (e.g.LOG_LEVEL), but no longer carry provider API keys.- Some providers need more than just a key - e.g. Azure resources are
deployed per-user, so Sora-2-on-Azure also needs the user's own resource
endpoint URL. Declare these via
ModelProvider.extra_config_envs(a tuple of label names, analogous toapi_token_env);app.pyderives one plain (non-password) text input per distinct name automatically (EXTRA_CONFIG_ENVS), rendered in the same BYOK section and persisted the same way. Read a value back inside a provider'scallfunction withprovider.extra_config("NAME").
Persistent storage (/data)
- On the Space:
/datais the mounted persistent storage directory (if enabled for the Space). Runs (input image + per-provider output videos +runs.jsonhistory index) are written there and survive restarts. - Locally:
/datais normally not writable/creatable on a developer machine (e.g. macOS blocks writing to/dataat the OS level).runs.ensure_data_dirs()detects this and falls back to a./datadirectory next to the project files instead. This fallback dir is gitignored. - You don't need to do anything to trigger the fallback - it happens
automatically the first time
ensure_data_dirs()fails to create/data.
Running locally
pip install -r requirements.txt
python app.py
Then open the printed local URL (e.g. http://127.0.0.1:7860).
Adding a new model provider
Add a ModelProvider(...) entry to PROVIDERS in providers.py.
Reuse fal_queue_call if the new model is also on fal.ai, replicate_call if
it's on Replicate, veo_call if it's a Veo model on the Gemini API, or write
a new call function matching the signature (provider, image_path) -> bytes
for providers with a different API contract (see generic_sync_call and
polling_call for templates of direct-response vs. job-polling contracts).
No subclassing is needed - the call field is what makes this duck-typed.
Give the provider an api_token_env label (new or reused) - the UI picks up
a BYOK input field for it automatically. If the provider needs more than a
key (e.g. a per-resource endpoint URL), also set extra_config_envs - see
sora-2-azure for an example.