rajtheman's picture
Upload folder using huggingface_hub
3183f20 verified
Raw
History Blame Contribute Delete
5.21 kB
"""
Phase 8 β€” automated deployment.
--github : create + push the GitHub repo (TheDeveloperAAA, Contents+Admin token)
--hf : create + push the HuggingFace Space (rajtheman, write token) -> live URL
Tokens are read from ~/.sia_gh_token / ~/.sia_hf_token, never written into the repo.
GitHub auth uses git's http.extraheader so the token is not persisted in .git/config.
"""
from __future__ import annotations
import os, sys, json, subprocess, argparse, tempfile
from pathlib import Path
ROOT = Path(__file__).resolve().parent
sys.path.insert(0, str(ROOT))
from src import config as C
GH_USER = "TheDeveloperAAA"
def _tok(p: Path) -> str:
return p.read_text().strip()
# --------------------------------------------------------------------------- #
def deploy_github():
gh = _tok(C.GH_TOKEN_FILE)
repo = C.GH_REPO_NAME
# 1) create repo (idempotent) via curl (system certs; urllib SSL is flaky on macOS)
body = json.dumps({"name": repo, "private": False,
"description": "Support Integrity Auditor (SIA) β€” self-supervised priority-mismatch auditor"})
r = subprocess.run(["curl", "-s", "-o", "/dev/null", "-w", "%{http_code}",
"-X", "POST", "-H", f"Authorization: Bearer {gh}",
"-H", "Accept: application/vnd.github+json",
"https://api.github.com/user/repos", "-d", body],
capture_output=True, text=True)
print(f"[github] create repo -> HTTP {r.stdout} (201=created, 422=already exists)")
def git(*args, check=True):
return subprocess.run(["git", "-c", "user.email=sia@local",
"-c", "user.name=SIA Bot", *args],
cwd=ROOT, check=check, capture_output=True, text=True)
git("add", "-A")
git("commit", "-m", "Support Integrity Auditor β€” full pipeline, app, artifacts", check=False)
git("branch", "-M", "main")
# GitHub git-over-HTTPS uses Basic auth (token in URL), not a Bearer header.
auth_url = f"https://x-access-token:{gh}@github.com/{GH_USER}/{repo}.git"
push = subprocess.run(["git", "push", "--force", auth_url, "main"],
cwd=ROOT, capture_output=True, text=True)
if push.returncode == 0:
print(f"[github] pushed -> https://github.com/{GH_USER}/{repo}")
else:
print("[github] push failed:\n", push.stderr[-800:])
# --------------------------------------------------------------------------- #
SPACE_README = """---
title: Support Integrity Auditor
emoji: πŸ›‘οΈ
colorFrom: indigo
colorTo: red
sdk: docker
app_port: 7860
pinned: false
license: mit
---
# Support Integrity Auditor (SIA)
Self-supervised auditor that detects **Priority Mismatch** in CRM support tickets β€”
tickets whose human-assigned priority conflicts with their true severity β€” and emits
a hallucination-free **Evidence Dossier** for every flagged case.
- **Audit a Ticket** β€” single-ticket form β†’ binary judgment + dossier
- **Batch Audit** β€” CSV upload β†’ predictions + downloadable dossiers
- **Mismatch Dashboard** β€” flagged distribution, mismatch types, severity-delta heatmap, agent-bias view
"""
def deploy_hf():
from huggingface_hub import HfApi
hf = _tok(C.HF_TOKEN_FILE)
api = HfApi(token=hf)
user = api.whoami()["name"]
repo_id = f"{user}/{C.HF_SPACE_NAME}"
# HF runs Streamlit Spaces via the Docker SDK (a Dockerfile runs streamlit).
api.create_repo(repo_id, repo_type="space", space_sdk="docker", exist_ok=True)
# Space README with front-matter (separate from the repo's methodology README)
sp = ROOT / ".hf_space_README.md"
sp.write_text(SPACE_README)
api.upload_file(path_or_fileobj=str(sp), path_in_repo="README.md",
repo_id=repo_id, repo_type="space")
sp.unlink()
api.upload_folder(
folder_path=str(ROOT), repo_id=repo_id, repo_type="space",
ignore_patterns=[
".git*", ".claude/**", "**/__pycache__/**", "*.pyc", ".sia_*", "*_token",
"*.hf_token", "*.gh_token", "README.md", ".hf_space_README.md",
# raw PII dataset (names/emails) β€” never publish
"data/SIA.pdf", "data/customer_support_tickets.csv",
"data/enhanced_customer_support_data.csv",
# PII-bearing intermediate parquets β€” keep only the slim dashboard.parquet
"artifacts/data/pseudo_labeled.parquet", "artifacts/data/processed.parquet",
"artifacts/data/test_predictions.parquet", "artifacts/predictions/**",
# training checkpoints / optimizer state β€” not needed for inference
"**/checkpoint-*/**", "**/optimizer.pt", "**/training_args.bin",
],
)
print(f"[hf] Space live -> https://huggingface.co/spaces/{repo_id}")
# --------------------------------------------------------------------------- #
if __name__ == "__main__":
ap = argparse.ArgumentParser()
ap.add_argument("--github", action="store_true")
ap.add_argument("--hf", action="store_true")
a = ap.parse_args()
if not (a.github or a.hf):
a.github = a.hf = True
if a.github: deploy_github()
if a.hf: deploy_hf()