mgbam commited on
Commit
80bfd4a
·
verified ·
1 Parent(s): b2a87aa

Update deploy.py

Browse files
Files changed (1) hide show
  1. deploy.py +21 -99
deploy.py CHANGED
@@ -14,11 +14,10 @@ from huggingface_hub import HfApi, duplicate_space
14
  # ------------------------------------------------------------------
15
 
16
  def send_to_sandbox(code: str) -> str:
17
- """Wrap HTML code in a sandboxed iframe via a data URI."""
18
  wrapped = f"""
19
  <!DOCTYPE html>
20
  <html>
21
- <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"></head>
22
  <body>{code}</body>
23
  </html>
24
  """
@@ -30,18 +29,9 @@ def send_to_sandbox(code: str) -> str:
30
  )
31
 
32
  def demo_card_click(e: gr.EventData) -> str:
33
- """Return the description of a demo card when clicked."""
34
- try:
35
- idx = (
36
- e._data.get("index")
37
- or e._data.get("component", {}).get("index")
38
- or e._data.get("target", {}).get("index")
39
- )
40
- except Exception:
41
- idx = 0
42
  from constants import DEMO_LIST
43
- if not (0 <= idx < len(DEMO_LIST)):
44
- idx = 0
45
  return DEMO_LIST[idx]["description"]
46
 
47
  # ------------------------------------------------------------------
@@ -49,7 +39,6 @@ def demo_card_click(e: gr.EventData) -> str:
49
  # ------------------------------------------------------------------
50
 
51
  def wrap_html_in_gradio_app(html_code: str) -> str:
52
- """Generate a minimal Gradio app.py that renders given HTML."""
53
  safe = html_code.replace('"""', r'\"\"\"')
54
  return (
55
  "import gradio as gr\n\n"
@@ -61,40 +50,23 @@ def wrap_html_in_gradio_app(html_code: str) -> str:
61
  )
62
 
63
  def deploy_to_spaces(code: str) -> None:
64
- """Open a new tab to create a Hugging Face Space with a Gradio app."""
65
  if not code.strip():
66
  return
67
  app_py = wrap_html_in_gradio_app(code)
68
- params = urllib.parse.urlencode({
69
- "name": "new-space",
70
- "sdk": "gradio"
71
- })
72
- files = {
73
- "files[0][path]": "app.py",
74
- "files[0][content]": app_py
75
- }
76
- files_params = urllib.parse.urlencode(files)
77
  url = f"https://huggingface.co/new-space?{params}&{files_params}"
78
  webbrowser.open_new_tab(url)
79
 
80
  def wrap_html_in_static_app(html_code: str) -> str:
81
- """Return raw HTML for a static Hugging Face Space."""
82
  return html_code
83
 
84
  def deploy_to_spaces_static(code: str) -> None:
85
- """Open a new tab to create a static HTML Space."""
86
  if not code.strip():
87
  return
88
  html = wrap_html_in_static_app(code)
89
- params = urllib.parse.urlencode({
90
- "name": "new-space",
91
- "sdk": "static"
92
- })
93
- files = {
94
- "files[0][path]": "index.html",
95
- "files[0][content]": html
96
- }
97
- files_params = urllib.parse.urlencode(files)
98
  url = f"https://huggingface.co/new-space?{params}&{files_params}"
99
  webbrowser.open_new_tab(url)
100
 
@@ -103,39 +75,21 @@ def deploy_to_spaces_static(code: str) -> None:
103
  # ------------------------------------------------------------------
104
 
105
  def check_hf_space_url(url: str):
106
- """Validate a HF Spaces URL and extract username/project."""
107
  import re
108
- pattern = re.compile(r'^(?:https?://)?(?:huggingface\.co|hf\.co)/spaces/([\w-]+)/([\w-]+)$', re.IGNORECASE)
109
  m = pattern.match(url.strip())
110
- if not m:
111
- return False, None, None
112
- return True, m.group(1), m.group(2)
113
 
114
  def fetch_hf_space_content(username: str, project: str) -> str:
115
- """Download the main file of a Space and return its content."""
116
  api = HfApi()
117
  info = api.space_info(f"{username}/{project}")
118
  sdk = info.sdk
119
- # Choose main file based on SDK
120
- if sdk == "static":
121
- main_file = "index.html"
122
- elif sdk == "gradio":
123
- main_file = "app.py"
124
- else:
125
- # Fallback: try common filenames
126
- for fname in ["app.py", "index.html", "streamlit_app.py", "main.py"]:
127
- try:
128
- _ = api.hf_hub_download(repo_id=f"{username}/{project}", filename=fname, repo_type="space")
129
- main_file = fname
130
- break
131
- except:
132
- continue
133
  path = api.hf_hub_download(repo_id=f"{username}/{project}", filename=main_file, repo_type="space")
134
  with open(path, "r", encoding="utf-8") as f:
135
  return f.read()
136
 
137
  def load_project_from_url(url: str):
138
- """Return (status_message, code_content) for importing a Space URL."""
139
  valid, user, proj = check_hf_space_url(url)
140
  if not valid:
141
  return "Error: Invalid Hugging Face Space URL.", ""
@@ -145,54 +99,22 @@ def load_project_from_url(url: str):
145
  except Exception as e:
146
  return f"Error fetching project: {e}", ""
147
 
148
- def deploy_to_user_space(code, space_name, sdk_choice, profile: gr.OAuthProfile | None = None, token: gr.OAuthToken | None = None):
149
- """Create or update a user's own HF Space with proper authentication."""
150
  if not profile or not token or not token.token or token.token.startswith("hf_"):
151
  return gr.update(value="Please log in with a valid Hugging Face write token.", visible=True)
152
 
153
  api = HfApi(token=token.token)
154
- is_update = "/" in space_name.strip()
155
- if is_update:
156
- repo_id = space_name.strip()
157
- else:
158
- repo_id = f"{profile.username}/{space_name.strip()}"
159
- sdk_map = {
160
- "Gradio (Python)": "gradio",
161
- "Streamlit (Python)": "docker",
162
- "Static (HTML)": "static",
163
- "Transformers.js": "static"
164
- }
165
- sdk = sdk_map.get(sdk_choice, "gradio")
166
-
167
- # Create or update repo
168
- if not is_update and sdk != "docker":
169
  api.create_repo(repo_id=repo_id, repo_type="space", space_sdk=sdk, exist_ok=True)
170
 
171
- # Duplicate and upload logic for docker (Streamlit) or transformers.js
172
- if sdk == "docker":
173
- dup = duplicate_space(from_id="streamlit/streamlit-template-space", to_id=repo_id, token=token.token, exist_ok=True)
174
- with tempfile.NamedTemporaryFile("w", suffix=".py", delete=False) as f:
175
- f.write(code)
176
- path = f.name
177
- api.upload_file(path_or_fileobj=path, path_in_repo="src/streamlit_app.py", repo_id=repo_id, repo_type="space")
178
- os.unlink(path)
179
- elif sdk_choice == "Transformers.js":
180
- dup = duplicate_space(from_id="static-templates/transformers.js", to_id=repo_id, token=token.token, exist_ok=True)
181
- from utils import parse_transformers_js_output # ensure we have that helper
182
- files = parse_transformers_js_output(code)
183
- for name, content in files.items():
184
- with tempfile.NamedTemporaryFile("w", suffix=f".{name.split('.')[-1]}", delete=False) as f:
185
- f.write(content)
186
- path = f.name
187
- api.upload_file(path_or_fileobj=path, path_in_repo=name, repo_id=repo_id, repo_type="space")
188
- os.unlink(path)
189
- else:
190
- # Static or Gradio: upload single file
191
- filename = "index.html" if sdk == "static" else "app.py"
192
- with tempfile.NamedTemporaryFile("w", suffix=f".{filename.split('.')[-1]}", delete=False) as f:
193
- f.write(code)
194
- path = f.name
195
- api.upload_file(path_or_fileobj=path, path_in_repo=filename, repo_id=repo_id, repo_type="space")
196
- os.unlink(path)
197
 
198
  return gr.update(value=f"✅ Deployed to https://huggingface.co/spaces/{repo_id}", visible=True)
 
14
  # ------------------------------------------------------------------
15
 
16
  def send_to_sandbox(code: str) -> str:
 
17
  wrapped = f"""
18
  <!DOCTYPE html>
19
  <html>
20
+ <head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"></head>
21
  <body>{code}</body>
22
  </html>
23
  """
 
29
  )
30
 
31
  def demo_card_click(e: gr.EventData) -> str:
32
+ idx = e.index if hasattr(e, 'index') else 0
 
 
 
 
 
 
 
 
33
  from constants import DEMO_LIST
34
+ idx = idx if 0 <= idx < len(DEMO_LIST) else 0
 
35
  return DEMO_LIST[idx]["description"]
36
 
37
  # ------------------------------------------------------------------
 
39
  # ------------------------------------------------------------------
40
 
41
  def wrap_html_in_gradio_app(html_code: str) -> str:
 
42
  safe = html_code.replace('"""', r'\"\"\"')
43
  return (
44
  "import gradio as gr\n\n"
 
50
  )
51
 
52
  def deploy_to_spaces(code: str) -> None:
 
53
  if not code.strip():
54
  return
55
  app_py = wrap_html_in_gradio_app(code)
56
+ params = urllib.parse.urlencode({"name": "new-space", "sdk": "gradio"})
57
+ files_params = urllib.parse.urlencode({"files[0][path]": "app.py", "files[0][content]": app_py})
 
 
 
 
 
 
 
58
  url = f"https://huggingface.co/new-space?{params}&{files_params}"
59
  webbrowser.open_new_tab(url)
60
 
61
  def wrap_html_in_static_app(html_code: str) -> str:
 
62
  return html_code
63
 
64
  def deploy_to_spaces_static(code: str) -> None:
 
65
  if not code.strip():
66
  return
67
  html = wrap_html_in_static_app(code)
68
+ params = urllib.parse.urlencode({"name": "new-space", "sdk": "static"})
69
+ files_params = urllib.parse.urlencode({"files[0][path]": "index.html", "files[0][content]": html})
 
 
 
 
 
 
 
70
  url = f"https://huggingface.co/new-space?{params}&{files_params}"
71
  webbrowser.open_new_tab(url)
72
 
 
75
  # ------------------------------------------------------------------
76
 
77
  def check_hf_space_url(url: str):
 
78
  import re
79
+ pattern = re.compile(r'^(?:https?://)?(?:huggingface\\.co|hf\\.co)/spaces/([\\w-]+)/([\\w-]+)$', re.IGNORECASE)
80
  m = pattern.match(url.strip())
81
+ return (False, None, None) if not m else (True, m.group(1), m.group(2))
 
 
82
 
83
  def fetch_hf_space_content(username: str, project: str) -> str:
 
84
  api = HfApi()
85
  info = api.space_info(f"{username}/{project}")
86
  sdk = info.sdk
87
+ main_file = "index.html" if sdk == "static" else "app.py"
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  path = api.hf_hub_download(repo_id=f"{username}/{project}", filename=main_file, repo_type="space")
89
  with open(path, "r", encoding="utf-8") as f:
90
  return f.read()
91
 
92
  def load_project_from_url(url: str):
 
93
  valid, user, proj = check_hf_space_url(url)
94
  if not valid:
95
  return "Error: Invalid Hugging Face Space URL.", ""
 
99
  except Exception as e:
100
  return f"Error fetching project: {e}", ""
101
 
102
+ def deploy_to_user_space(code, space_name, sdk_choice, profile: Optional[gr.OAuthProfile] = None, token: Optional[gr.OAuthToken] = None):
 
103
  if not profile or not token or not token.token or token.token.startswith("hf_"):
104
  return gr.update(value="Please log in with a valid Hugging Face write token.", visible=True)
105
 
106
  api = HfApi(token=token.token)
107
+ repo_id = space_name.strip() if "/" in space_name.strip() else f"{profile.username}/{space_name.strip()}"
108
+ sdk = {"Gradio (Python)": "gradio", "Streamlit (Python)": "docker", "Static (HTML)": "static", "Transformers.js": "static"}.get(sdk_choice, "gradio")
109
+
110
+ if "/" not in space_name and sdk != "docker":
 
 
 
 
 
 
 
 
 
 
 
111
  api.create_repo(repo_id=repo_id, repo_type="space", space_sdk=sdk, exist_ok=True)
112
 
113
+ filename = "index.html" if sdk == "static" else "app.py"
114
+ with tempfile.NamedTemporaryFile("w", suffix=f".{filename.split('.')[-1]}", delete=False) as f:
115
+ f.write(code)
116
+ path = f.name
117
+ api.upload_file(path_or_fileobj=path, path_in_repo=filename, repo_id=repo_id, repo_type="space")
118
+ os.unlink(path)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
  return gr.update(value=f"✅ Deployed to https://huggingface.co/spaces/{repo_id}", visible=True)