File size: 5,000 Bytes
3e1c4b9 0cd83f6 3e1c4b9 2d7a058 3e1c4b9 2d7a058 3e1c4b9 2541fb7 3e1c4b9 2d7a058 3e1c4b9 2f92e9e 80bfd4a 3e1c4b9 2f92e9e 3e1c4b9 2f92e9e 3e1c4b9 2541fb7 3e1c4b9 2541fb7 3e1c4b9 2f92e9e 3e1c4b9 2f92e9e 3e1c4b9 2f92e9e 3e1c4b9 2541fb7 3e1c4b9 2f92e9e 3e1c4b9 2f92e9e 3e1c4b9 2541fb7 3e1c4b9 2f92e9e 3e1c4b9 2f92e9e 2541fb7 3e1c4b9 2541fb7 3e1c4b9 2541fb7 3e1c4b9 2f92e9e 3e1c4b9 2f92e9e 3e1c4b9 2f92e9e 3e1c4b9 2541fb7 80bfd4a 3e1c4b9 2541fb7 80bfd4a 2541fb7 3e1c4b9 |
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 |
# deploy.py
import os
import base64
import webbrowser
import urllib.parse
import tempfile
from typing import Optional
import gradio as gr
from huggingface_hub import HfApi, duplicate_space
# ------------------------------------------------------------------
# Utilities for live-preview sandbox in the Gradio UI
# ------------------------------------------------------------------
def send_to_sandbox(code: str) -> str:
wrapped = f"""
<!DOCTYPE html>
<html>
<head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"></head>
<body>{code}</body>
</html>
"""
b64 = base64.b64encode(wrapped.encode("utf-8")).decode("utf-8")
return (
f'<iframe src="data:text/html;base64,{b64}" '
'width="100%" height="920px" sandbox="allow-scripts allow-same-origin '
'allow-forms allow-popups allow-modals allow-presentation" allow="display-capture"></iframe>'
)
def demo_card_click(e: gr.EventData) -> str:
try:
idx = (
e._data.get("index")
or e._data.get("component", {}).get("index")
or e._data.get("target", {}).get("index")
)
except Exception:
idx = 0
from constants import DEMO_LIST
if not (0 <= idx < len(DEMO_LIST)):
idx = 0
return DEMO_LIST[idx]["description"]
# ------------------------------------------------------------------
# Functions for importing existing Hugging Face Spaces projects
# ------------------------------------------------------------------
def wrap_html_in_gradio_app(html_code: str) -> str:
safe = html_code.replace('"""', r'\"\"\"')
return (
"import gradio as gr\n\n"
"def show_html():\n"
f' return """{safe}"""\n\n'
"demo = gr.Interface(fn=show_html, inputs=None, outputs=gr.HTML())\n\n"
"if __name__ == '__main__':\n"
" demo.launch()\n"
)
def deploy_to_spaces(code: str) -> None:
if not code.strip():
return
app_py = wrap_html_in_gradio_app(code)
params = urllib.parse.urlencode({
"name": "new-space",
"sdk": "gradio"
})
files = {
"files[0][path]": "app.py",
"files[0][content]": app_py
}
files_params = urllib.parse.urlencode(files)
url = f"https://huggingface.co/new-space?{params}&{files_params}"
webbrowser.open_new_tab(url)
def wrap_html_in_static_app(html_code: str) -> str:
return html_code
def deploy_to_spaces_static(code: str) -> None:
if not code.strip():
return
html = wrap_html_in_static_app(code)
params = urllib.parse.urlencode({
"name": "new-space",
"sdk": "static"
})
files = {
"files[0][path]": "index.html",
"files[0][content]": html
}
files_params = urllib.parse.urlencode(files)
url = f"https://huggingface.co/new-space?{params}&{files_params}"
webbrowser.open_new_tab(url)
# ------------------------------------------------------------------
# Functions for loading and updating user Spaces
# ------------------------------------------------------------------
def check_hf_space_url(url: str):
import re
pattern = re.compile(r'^(?:https?://)?(?:huggingface\.co|hf\.co)/spaces/([\w-]+)/([\w-]+)$', re.IGNORECASE)
m = pattern.match(url.strip())
if not m:
return False, None, None
return True, m.group(1), m.group(2)
def fetch_hf_space_content(username: str, project: str) -> str:
api = HfApi()
path = api.hf_hub_download(repo_id=f"{username}/{project}", filename="app.py", repo_type="space")
with open(path, "r", encoding="utf-8") as f:
return f.read()
def load_project_from_url(url: str):
valid, user, proj = check_hf_space_url(url)
if not valid:
return "Error: Invalid Hugging Face Space URL.", ""
try:
content = fetch_hf_space_content(user, proj)
return f"✅ Imported {user}/{proj}", content
except Exception as e:
return f"Error fetching project: {e}", ""
def handle_load_project(url: str):
status_message, content = load_project_from_url(url)
return status_message, content, "", url, [], []
def deploy_to_user_space(code, space_name, sdk_choice, profile: Optional[gr.OAuthProfile] = None, token: Optional[gr.OAuthToken] = None):
if not profile or not token or not token.token or token.token.startswith("hf_"):
return gr.update(value="Please log in with a valid Hugging Face write token.", visible=True)
api = HfApi(token=token.token)
repo_id = f"{profile.username}/{space_name.strip()}"
api.create_repo(repo_id=repo_id, repo_type="space", space_sdk=sdk_choice, exist_ok=True)
with tempfile.NamedTemporaryFile("w", delete=False) as f:
f.write(code)
api.upload_file(path_or_fileobj=f.name, path_in_repo="app.py", repo_id=repo_id, repo_type="space")
os.unlink(f.name)
return gr.update(value=f"✅ Deployed to https://huggingface.co/spaces/{repo_id}", visible=True)
|