PixelPilotAI / scripts /sync_hf_secrets.py
Sbboss's picture
Deploy Docker Streamlit app to HF Space
5d36f24
#!/usr/bin/env python3
"""
Sync selected keys from a local .env file to Hugging Face Space secrets.
Usage:
python scripts/sync_hf_secrets.py --space-id <username/space-name>
Optional:
python scripts/sync_hf_secrets.py --space-id <username/space-name> --env-file .env
python scripts/sync_hf_secrets.py --space-id <username/space-name> --token <hf_token>
python scripts/sync_hf_secrets.py --space-id <username/space-name> --dry-run
"""
from __future__ import annotations
import argparse
import os
import sys
from pathlib import Path
from dotenv import dotenv_values
ALLOWED_KEYS = [
"AZURE_SEARCH_ENDPOINT",
"AZURE_SEARCH_KEY",
"AZURE_SEARCH_INDEX_NAME",
"AZURE_OPENAI_ENDPOINT",
"AZURE_OPENAI_KEY",
"AZURE_OPENAI_DEPLOYMENT",
"AZURE_OPENAI_API_VERSION",
"AZURE_VISION_ENDPOINT",
"AZURE_VISION_KEY",
"AZURE_VISION_MODEL_VERSION",
"EDITING_API_URL",
"FIVEK_SUBSET_SIZE",
]
def _parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Sync selected .env keys to Hugging Face Space secrets."
)
parser.add_argument(
"--space-id",
required=True,
help="Hugging Face Space id, e.g. username/my-space",
)
parser.add_argument(
"--env-file",
default=".env",
help="Path to .env file (default: .env)",
)
parser.add_argument(
"--token",
default=os.getenv("HF_TOKEN"),
help="Hugging Face token (defaults to HF_TOKEN env var)",
)
parser.add_argument(
"--dry-run",
action="store_true",
help="Print what would be synced without updating the Space",
)
return parser.parse_args()
def _load_pairs(env_file: Path) -> dict[str, str]:
if not env_file.exists():
raise FileNotFoundError(f".env file not found: {env_file}")
raw = dotenv_values(env_file)
pairs: dict[str, str] = {}
for key in ALLOWED_KEYS:
value = raw.get(key)
if value is None:
continue
value = str(value).strip()
if not value:
continue
pairs[key] = value
return pairs
def main() -> int:
args = _parse_args()
env_file = Path(args.env_file).resolve()
try:
pairs = _load_pairs(env_file)
except Exception as exc: # pragma: no cover
print(f"ERROR: {exc}")
return 1
if not pairs:
print("No allowed keys with non-empty values found in .env.")
return 1
if args.dry_run:
print(f"[dry-run] Would sync {len(pairs)} secret(s) to {args.space_id}:")
for k in sorted(pairs):
print(f" - {k}")
return 0
if not args.token:
print("ERROR: Missing token. Set HF_TOKEN or pass --token.")
return 1
try:
from huggingface_hub import HfApi
except Exception:
print("ERROR: huggingface_hub is not installed.")
print("Install it with: pip install huggingface_hub")
return 1
api = HfApi(token=args.token)
print(f"Syncing {len(pairs)} secret(s) to {args.space_id}...")
for key, value in pairs.items():
api.add_space_secret(repo_id=args.space_id, key=key, value=value)
print(f" - synced {key}")
print("Done. Your Space will restart to apply updated secrets.")
return 0
if __name__ == "__main__":
raise SystemExit(main())