Spaces:
Running
Running
File size: 4,678 Bytes
6fe13ea | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | """
Stage and deploy Workflow1111 to a Hugging Face Space.
python apps/05_workflow1111/deploy_space.py --stage # build staging dir only
python apps/05_workflow1111/deploy_space.py --push # create + upload
The Space must be **public**: the reference-node sample images are referenced by
their public `.../resolve/main/samples/...` URL, which is the only default shape
the canvas renders *and* a remote inference provider can fetch. A private Space
would serve 401s for those URLs and the defaults would come up blank.
OAuth is enabled in the README frontmatter, so each visitor signs in and their
own token pays for their own inference — the Space ships no token of its own.
"""
import argparse
import os
import shutil
import sys
HERE = os.path.dirname(os.path.abspath(__file__))
ROOT = os.path.abspath(os.path.join(HERE, "..", ".."))
STAGE = os.path.join(HERE, "_space")
SPACE_ID = os.environ.get("WORKFLOW1111_SPACE", "ysharma/Workflow1111")
SHIP = [
"test_api.py",
"deploy_space.py",
"app.py",
"nodes.py",
"workflow.json",
"requirements.txt",
"build_workflow.py",
"layout.json",
"make_samples.py",
"test_nodes.py",
"test_pipelines.py",
]
FRONTMATTER = """---
title: Workflow1111 Diffusion Studio
emoji: 🎨
colorFrom: indigo
colorTo: purple
sdk: gradio
sdk_version: 6.22.0
app_file: app.py
pinned: false
license: mit
hf_oauth: true
hf_oauth_scopes:
- inference-api
short_description: Automatic1111-style studio on one gr.Workflow canvas
---
> **Sign in with Hugging Face** (button at the top right) before running
> anything. This Space carries no token of its own — every `model`, `space` and
> inference-calling `fn` node runs on *your* token and your own inference quota.
"""
def read_token():
for path in (os.path.join(ROOT, "hf-write-token.txt"),):
if os.path.exists(path):
with open(path, encoding="utf-8") as f:
tok = f.read().strip()
if tok:
return tok
tok = os.environ.get("HF_TOKEN")
if tok:
return tok
raise SystemExit("No write token found (hf-write-token.txt or HF_TOKEN).")
def stage():
if os.path.exists(STAGE):
shutil.rmtree(STAGE)
os.makedirs(STAGE)
for name in SHIP:
src = os.path.join(HERE, name)
if not os.path.exists(src):
raise SystemExit(f"missing file to ship: {name}")
shutil.copy2(src, os.path.join(STAGE, name))
samples_src = os.path.join(HERE, "samples")
samples_dst = os.path.join(STAGE, "samples")
os.makedirs(samples_dst)
for name in sorted(os.listdir(samples_src)):
if name.startswith("_"):
continue
shutil.copy2(os.path.join(samples_src, name), os.path.join(samples_dst, name))
with open(os.path.join(HERE, "README.md"), encoding="utf-8") as f:
body = f.read()
with open(os.path.join(STAGE, "README.md"), "w", encoding="utf-8") as f:
f.write(FRONTMATTER + body)
# Nothing secret may ever reach the Space.
for dirpath, _dirs, files in os.walk(STAGE):
for name in files:
low = name.lower()
if "token" in low and low.endswith(".txt"):
raise SystemExit(f"refusing to ship {name}")
total = sum(os.path.getsize(os.path.join(d, f))
for d, _s, fs in os.walk(STAGE) for f in fs)
files = [os.path.relpath(os.path.join(d, f), STAGE)
for d, _s, fs in os.walk(STAGE) for f in fs]
print(f"staged {len(files)} files ({total // 1024} KB) in {os.path.relpath(STAGE, os.getcwd())}")
for f in sorted(files):
size = os.path.getsize(os.path.join(STAGE, f)) // 1024
print(f" {f:34} {size:>5} KB")
return files
def push():
from huggingface_hub import HfApi
api = HfApi(token=read_token())
who = api.whoami()
print(f"authenticated as: {who.get('name')}")
url = api.create_repo(repo_id=SPACE_ID, repo_type="space", space_sdk="gradio",
exist_ok=True, private=False)
print(f"space repo ready: {url}")
api.upload_folder(
folder_path=STAGE,
repo_id=SPACE_ID,
repo_type="space",
commit_message="Workflow1111 — Automatic1111-style diffusion studio on gr.Workflow",
)
print(f"uploaded → https://huggingface.co/spaces/{SPACE_ID}")
if __name__ == "__main__":
ap = argparse.ArgumentParser()
ap.add_argument("--stage", action="store_true")
ap.add_argument("--push", action="store_true")
args = ap.parse_args()
if not (args.stage or args.push):
ap.error("pass --stage or --push")
stage()
if args.push:
push()
|