Linaqruf commited on
Commit
0a5b850
·
verified ·
1 Parent(s): a20e4c3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +139 -57
app.py CHANGED
@@ -14,6 +14,11 @@ import gradio as gr
14
  from huggingface_hub import snapshot_download, HfApi
15
  from modelscope.hub.api import HubApi
16
  from modelscope.hub.constants import Licenses, ModelVisibility
 
 
 
 
 
17
 
18
 
19
  class MigrationTool:
@@ -90,7 +95,7 @@ class MigrationTool:
90
  try:
91
  api.login(token)
92
  except Exception as login_error:
93
- return False, f"✗ ModelScope Login failed: {str(login_error)}\n\n💡 Tip: Ensure you are using an 'SDK Token' (starts with 'ms-') from https://www.modelscope.cn/my/myaccesstoken, NOT a 'Git Token'."
94
 
95
  # Determine visibility
96
  vis = ModelVisibility.PUBLIC if visibility == "public" else ModelVisibility.PRIVATE
@@ -169,63 +174,139 @@ class MigrationTool:
169
  repo_type: str,
170
  visibility: str,
171
  license_type: str,
172
- chinese_name: Optional[str] = None
 
173
  ) -> str:
174
- """Perform the complete migration process.
175
-
176
- Returns:
177
- Status message with migration progress
178
- """
179
- output = []
180
-
181
- # Validate and clean inputs
182
- hf_token = hf_token.strip() if hf_token else ""
183
- ms_token = ms_token.strip() if ms_token else ""
184
- hf_repo_id = hf_repo_id.strip() if hf_repo_id else ""
185
- ms_repo_id = ms_repo_id.strip() if ms_repo_id else ""
186
-
187
- if not hf_token or not ms_token:
188
- return "✗ Error: Both HuggingFace and ModelScope tokens are required"
189
-
190
- if not hf_repo_id or not ms_repo_id:
191
- return "✗ Error: Both source and destination repository IDs are required"
192
-
193
- if "/" not in ms_repo_id:
194
- return "✗ Error: Destination ModelScope Repo ID must be in 'username/repo-name' format"
195
-
196
- # Download from HuggingFace
197
- output.append(f"⬇️ Downloading {repo_type} from HuggingFace: {hf_repo_id}...")
198
- success, msg, local_path = self.download_from_hf(hf_repo_id, repo_type, hf_token)
199
- output.append(msg)
200
- if not success:
201
- self.cleanup()
202
- return "\n".join(output)
203
-
204
- # Upload to ModelScope
205
- output.append(f"\n⬆️ Uploading {repo_type} to ModelScope: {ms_repo_id}...")
206
- success, msg = self.upload_to_ms(
207
- local_path,
208
- ms_repo_id,
209
- ms_token,
210
- repo_type,
211
- visibility,
212
- license_type,
213
- chinese_name
214
- )
215
- output.append(msg)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
 
217
- # Cleanup
218
- output.append("\n🧹 Cleaning up temporary files...")
219
- self.cleanup()
220
- output.append(" Cleanup complete")
 
 
 
 
 
 
 
 
 
221
 
222
- if success:
223
- output.append(f"\n✅ Migration completed successfully!")
224
- output.append(f"Your {repo_type} is now available at: https://www.modelscope.cn/models/{ms_repo_id}")
225
- else:
226
- output.append(f"\n❌ Migration failed")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
 
228
- return "\n".join(output)
 
 
 
229
 
230
 
231
  def create_interface():
@@ -241,7 +322,8 @@ def create_interface():
241
 
242
  ## 📋 Instructions:
243
  1. Get your **HuggingFace token** from: https://huggingface.co/settings/tokens
244
- 2. Get your **ModelScope token** from: https://www.modelscope.cn/my/myaccesstoken
 
245
  3. Fill in the repository details below
246
  4. Click "Start Migration"
247
  """)
@@ -258,8 +340,8 @@ def create_interface():
258
  ms_token = gr.Textbox(
259
  label="ModelScope Token",
260
  type="password",
261
- placeholder="ms-...",
262
- info="Your ModelScope SDK token (must start with 'ms-')"
263
  )
264
 
265
  with gr.Column():
 
14
  from huggingface_hub import snapshot_download, HfApi
15
  from modelscope.hub.api import HubApi
16
  from modelscope.hub.constants import Licenses, ModelVisibility
17
+ import sys
18
+ import io
19
+ import threading
20
+ import queue
21
+ import time
22
 
23
 
24
  class MigrationTool:
 
95
  try:
96
  api.login(token)
97
  except Exception as login_error:
98
+ return False, f"✗ ModelScope Login failed: {str(login_error)}\n\n💡 Tip: Ensure you are using an 'SDK Token' from https://www.modelscope.cn (NOT modelscope.ai). The token usually starts with 'ms-'."
99
 
100
  # Determine visibility
101
  vis = ModelVisibility.PUBLIC if visibility == "public" else ModelVisibility.PRIVATE
 
174
  repo_type: str,
175
  visibility: str,
176
  license_type: str,
177
+ chinese_name: Optional[str] = None,
178
+ progress=gr.Progress(track_tqdm=True)
179
  ) -> str:
180
+ """Perform the complete migration process with real-time console log capture."""
181
+
182
+ log_queue = queue.Queue()
183
+ output_lines = []
184
+
185
+ # Helper to capture console output and send it to the queue
186
+ class StreamToQueue(io.StringIO):
187
+ def __init__(self, original_stream, q):
188
+ super().__init__()
189
+ self.original_stream = original_stream
190
+ self.q = q
191
+ def write(self, s):
192
+ if s:
193
+ # Write to original stream (console) and our queue (Gradio)
194
+ self.original_stream.write(s)
195
+ self.original_stream.flush()
196
+ self.q.put(s)
197
+ def flush(self):
198
+ self.original_stream.flush()
199
+
200
+ def update_output():
201
+ """Gather all pending messages from the queue and return the full status."""
202
+ new_data = False
203
+ while not log_queue.empty():
204
+ try:
205
+ msg = log_queue.get_nowait()
206
+ # Clean up common console control characters for better display
207
+ msg = msg.replace('\r', '\n').strip()
208
+ if msg:
209
+ for line in msg.split('\n'):
210
+ clean_line = line.strip()
211
+ if clean_line:
212
+ output_lines.append(clean_line)
213
+ new_data = True
214
+ except queue.Empty:
215
+ break
216
+ return "\n".join(output_lines), new_data
217
+
218
+ # Thread-safe migration execution storage
219
+ results = {"success": False, "message": "", "finished": False}
220
+
221
+ def run_migration():
222
+ try:
223
+ # Clean inputs
224
+ nonlocal hf_token, ms_token, hf_repo_id, ms_repo_id
225
+ hf_token = hf_token.strip() if hf_token else ""
226
+ ms_token = ms_token.strip() if ms_token else ""
227
+ hf_repo_id = hf_repo_id.strip() if hf_repo_id else ""
228
+ ms_repo_id = ms_repo_id.strip() if ms_repo_id else ""
229
+
230
+ if not hf_token or not ms_token or not hf_repo_id or not ms_repo_id:
231
+ results["message"] = "✗ Error: All tokens and repository IDs are required"
232
+ results["finished"] = True
233
+ return
234
+
235
+ if "/" not in ms_repo_id:
236
+ results["message"] = "✗ Error: ModelScope Repo ID must include your namespace (e.g., 'username/repo-name')"
237
+ results["finished"] = True
238
+ return
239
+
240
+ # 1. Download
241
+ progress(0.1, desc="Downloading from HuggingFace...")
242
+ print(f"⬇️ Starting download from HuggingFace: {hf_repo_id}...")
243
+ success, msg, local_path = self.download_from_hf(hf_repo_id, repo_type, hf_token)
244
+ print(msg)
245
+ if not success:
246
+ results["message"] = msg
247
+ results["finished"] = True
248
+ return
249
+
250
+ # 2. Upload
251
+ progress(0.4, desc="Uploading to ModelScope...")
252
+ print(f"\n⬆️ Starting upload to ModelScope: {ms_repo_id}...")
253
+ success, msg = self.upload_to_ms(
254
+ local_path,
255
+ ms_repo_id,
256
+ ms_token,
257
+ repo_type,
258
+ visibility,
259
+ license_type,
260
+ chinese_name
261
+ )
262
+ print(msg)
263
+ results["success"] = success
264
+ results["message"] = msg
265
 
266
+ except Exception as e:
267
+ results["message"] = f"✗ Unexpected error: {str(e)}"
268
+ finally:
269
+ print("\n🧹 Cleaning up temporary files...")
270
+ self.cleanup()
271
+ print("✓ Cleanup complete")
272
+ results["finished"] = True
273
+
274
+ # Redirect stdout and stderr to our queue
275
+ old_stdout = sys.stdout
276
+ old_stderr = sys.stderr
277
+ sys.stdout = StreamToQueue(sys.stdout, log_queue)
278
+ sys.stderr = StreamToQueue(sys.stderr, log_queue)
279
 
280
+ try:
281
+ # Start the migration in a background thread
282
+ thread = threading.Thread(target=run_migration)
283
+ thread.start()
284
+
285
+ # Continuously yield updates until the migration thread completes
286
+ while not results["finished"]:
287
+ current_status, updated = update_output()
288
+ if updated:
289
+ yield current_status
290
+ time.sleep(0.1)
291
+
292
+ # Final capture of any remaining logs
293
+ final_status, _ = update_output()
294
+
295
+ # Append final results
296
+ if results["success"]:
297
+ progress(1.0, desc="Completed")
298
+ final_status += f"\n\n✅ Migration completed successfully!"
299
+ final_status += f"\nYour {repo_type} is available at: https://www.modelscope.cn/models/{ms_repo_id}"
300
+ else:
301
+ progress(1.0, desc="Failed")
302
+ final_status += f"\n\n❌ Migration failed: {results['message']}"
303
+
304
+ yield final_status
305
 
306
+ finally:
307
+ # CRITICAL: Restore original streams so we don't break the whole app
308
+ sys.stdout = old_stdout
309
+ sys.stderr = old_stderr
310
 
311
 
312
  def create_interface():
 
322
 
323
  ## 📋 Instructions:
324
  1. Get your **HuggingFace token** from: https://huggingface.co/settings/tokens
325
+ 2. Get your **ModelScope SDK token** from: https://www.modelscope.cn/my/myaccesstoken
326
+ * **Note**: Use tokens from **modelscope.cn** (Chinese site). The international site (modelscope.ai) is not currently supported by the SDK.
327
  3. Fill in the repository details below
328
  4. Click "Start Migration"
329
  """)
 
340
  ms_token = gr.Textbox(
341
  label="ModelScope Token",
342
  type="password",
343
+ placeholder="Enter your ModelScope SDK token",
344
+ info="Use your SDK token from modelscope.cn (usually starts with 'ms-')"
345
  )
346
 
347
  with gr.Column():