Smomitya's picture
tweak the layout
de9aae0 verified
Raw History Blame Contribute Delete
3.14 kB
"""Push the project to its Hugging Face Space.
uv run python scripts/deploy.py # upload and report status
uv run python scripts/deploy.py -m "tweak layout" # with a commit message
uv run python scripts/deploy.py --watch # also wait for it to come up
`hf upload` is not used here: it calls `create_repo` first, and on a free
account creating a Gradio Space returns 402 Payment Required — so the CLI fails
even though the Space already exists. `upload_folder` talks to the commit
endpoint directly and does not care.
"""
import argparse
import sys
import time
from huggingface_hub import HfApi
from huggingface_hub.errors import HfHubHTTPError
from requests.exceptions import RequestException
SPACE_ID = "Smomitya/flight-booking-agent"
# Everything that must never reach the Space. `.venv` alone is gigabytes, and
# `data/` is local state the Space reseeds for itself on startup.
IGNORE = [
".venv/**",
"**/__pycache__/**",
".ruff_cache/**",
".pytest_cache/**",
"data/**",
".git/**",
"**/.DS_Store",
"uv.lock",
]
SETTLED = {"RUNNING", "RUNTIME_ERROR", "BUILD_ERROR", "CONFIG_ERROR", "PAUSED"}
def watch(api: HfApi, space_id: str, minutes: int = 12) -> str:
"""Follow the Space until it settles, printing each stage change."""
last = None
deadline = time.time() + minutes * 60
while time.time() < deadline:
try:
runtime = api.space_info(space_id).runtime
except (HfHubHTTPError, RequestException) as error:
# The hub drops long polls routinely; a failed read is not a
# failed deploy, so keep watching rather than reporting an error.
print(f" (poll failed: {type(error).__name__}, retrying)")
time.sleep(15)
continue
if runtime.stage != last:
print(f" [{time.strftime('%H:%M:%S')}] {runtime.stage}"
f" hardware={runtime.hardware}")
last = runtime.stage
if runtime.stage in SETTLED:
return runtime.stage
time.sleep(15)
return last or "UNKNOWN"
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("-m", "--message", default="Update from local checkout")
parser.add_argument("--space", default=SPACE_ID)
parser.add_argument("--watch", action="store_true",
help="wait for the Space to finish starting")
args = parser.parse_args()
api = HfApi()
print(f"Uploading to {args.space} …")
api.upload_folder(
repo_id=args.space,
repo_type="space",
folder_path=".",
ignore_patterns=IGNORE,
commit_message=args.message,
)
print(f" https://huggingface.co/spaces/{args.space}")
if not args.watch:
return 0
stage = watch(api, args.space)
print(f"final: {stage}")
# A Space can report RUNNING while the app inside it is broken, so this is
# a floor, not a guarantee — check the logs tab if behaviour looks wrong.
return 0 if stage == "RUNNING" else 1
if __name__ == "__main__":
sys.exit(main())