SaitejaMothukuri's picture
Deploy text-to-sql-guardrails
981d8b1 verified
Raw
History Blame Contribute Delete
3.26 kB
"""Deploy this app to Hugging Face Spaces (Docker SDK) and print the live URL.
Requires:
* `pip install -r requirements-deploy.txt` (huggingface_hub — deploy-only dep)
* a Hugging Face token (cached via `huggingface-cli login`, or HF_TOKEN env)
* OPENROUTER_API_KEY (read from env or .streamlit/secrets.toml) — set as a
Space secret so the deployed app can call OpenRouter.
python scripts/deploy_hf.py [--space-name text-to-sql-guardrails]
"""
from __future__ import annotations
import argparse
import os
import sys
import tempfile
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
SPACE_README = """---
title: Text-to-SQL with Guardrails
emoji: 🛡️
colorFrom: blue
colorTo: indigo
sdk: docker
app_port: 7860
pinned: false
short_description: NL to SQL with read-only guardrails + execution eval
---
# Text-to-SQL with Guardrails
Ask a question in plain English; an LLM writes SQL, a guardrail layer validates it
(read-only, single-statement, table-allowlist, no file functions) using `sqlglot`,
and only then does it run on a real DuckDB. Includes an execution-accuracy eval.
Source: https://github.com/saiteja007-mv/text-to-sql-guardrails
"""
IGNORE = [
".venv/*",
".git/*",
".github/*",
"__pycache__/*",
"*/__pycache__/*",
"*.pyc",
".streamlit/secrets.toml",
".streamlit/secrets.toml.example",
".env",
"tests/*",
"docs/*",
".boot.log",
"README.md", # replaced by the Space README with YAML front-matter
]
def _load_key() -> str | None:
key = os.environ.get("OPENROUTER_API_KEY")
if key:
return key.strip()
sec = ROOT / ".streamlit" / "secrets.toml"
if sec.exists():
import tomllib
return str(tomllib.load(sec.open("rb")).get("OPENROUTER_API_KEY", "")).strip() or None
return None
def main() -> int:
ap = argparse.ArgumentParser()
ap.add_argument("--space-name", default="text-to-sql-guardrails")
args = ap.parse_args()
from huggingface_hub import HfApi
api = HfApi()
user = api.whoami()["name"]
repo_id = f"{user}/{args.space_name}"
print(f"[deploy] HF user: {user} -> space {repo_id}")
api.create_repo(repo_id=repo_id, repo_type="space", space_sdk="docker", exist_ok=True)
key = _load_key()
if key:
api.add_space_secret(repo_id=repo_id, key="OPENROUTER_API_KEY", value=key)
print("[deploy] set Space secret OPENROUTER_API_KEY")
else:
print("[deploy] WARNING: no OPENROUTER_API_KEY found — set it in Space settings.")
with tempfile.TemporaryDirectory() as td:
readme = Path(td) / "README.md"
readme.write_text(SPACE_README, encoding="utf-8")
api.upload_file(
path_or_fileobj=str(readme),
path_in_repo="README.md",
repo_id=repo_id,
repo_type="space",
)
api.upload_folder(
folder_path=str(ROOT),
repo_id=repo_id,
repo_type="space",
ignore_patterns=IGNORE,
commit_message="Deploy text-to-sql-guardrails",
)
url = f"https://huggingface.co/spaces/{repo_id}"
print(f"\n[deploy] DONE. Live (build takes ~1-2 min):\n {url}")
return 0
if __name__ == "__main__":
sys.exit(main())