Spaces:
Running
Running
new update
Browse files- backend_deploy.py +12 -7
- frontend/src/app/page.tsx +63 -34
backend_deploy.py
CHANGED
|
@@ -570,20 +570,23 @@ def deploy_to_huggingface_space(
|
|
| 570 |
|
| 571 |
for attempt in range(max_attempts):
|
| 572 |
try:
|
|
|
|
| 573 |
api.upload_file(
|
| 574 |
path_or_fileobj=str(file_path),
|
| 575 |
path_in_repo=filename,
|
| 576 |
repo_id=repo_id,
|
| 577 |
-
repo_type="space"
|
| 578 |
-
commit_message
|
| 579 |
)
|
| 580 |
success = True
|
| 581 |
print(f"[Deploy] Successfully uploaded {filename}")
|
| 582 |
break
|
| 583 |
except Exception as e:
|
| 584 |
last_error = e
|
| 585 |
-
|
| 586 |
-
|
|
|
|
|
|
|
| 587 |
if attempt < max_attempts - 1:
|
| 588 |
time.sleep(2) # Wait before retry
|
| 589 |
print(f"[Deploy] Retry {attempt + 1}/{max_attempts} for {filename}")
|
|
@@ -591,12 +594,14 @@ def deploy_to_huggingface_space(
|
|
| 591 |
if not success:
|
| 592 |
return False, f"Failed to upload {filename} after {max_attempts} attempts: {last_error}", None
|
| 593 |
else:
|
| 594 |
-
# For other languages, use upload_folder
|
|
|
|
|
|
|
| 595 |
api.upload_folder(
|
| 596 |
folder_path=str(temp_path),
|
| 597 |
repo_id=repo_id,
|
| 598 |
-
repo_type="space"
|
| 599 |
-
commit_message
|
| 600 |
)
|
| 601 |
except Exception as e:
|
| 602 |
return False, f"Failed to upload files: {str(e)}", None
|
|
|
|
| 570 |
|
| 571 |
for attempt in range(max_attempts):
|
| 572 |
try:
|
| 573 |
+
# MATCH GRADIO: upload_file WITHOUT commit_message for individual files
|
| 574 |
api.upload_file(
|
| 575 |
path_or_fileobj=str(file_path),
|
| 576 |
path_in_repo=filename,
|
| 577 |
repo_id=repo_id,
|
| 578 |
+
repo_type="space"
|
| 579 |
+
# NO commit_message - HF API handles this automatically for spaces
|
| 580 |
)
|
| 581 |
success = True
|
| 582 |
print(f"[Deploy] Successfully uploaded {filename}")
|
| 583 |
break
|
| 584 |
except Exception as e:
|
| 585 |
last_error = e
|
| 586 |
+
error_str = str(e)
|
| 587 |
+
print(f"[Deploy] Upload error for {filename}: {error_str}")
|
| 588 |
+
if "403" in error_str or "Forbidden" in error_str:
|
| 589 |
+
return False, f"Permission denied uploading {filename}. Check your token has write access to {repo_id}.", None
|
| 590 |
if attempt < max_attempts - 1:
|
| 591 |
time.sleep(2) # Wait before retry
|
| 592 |
print(f"[Deploy] Retry {attempt + 1}/{max_attempts} for {filename}")
|
|
|
|
| 594 |
if not success:
|
| 595 |
return False, f"Failed to upload {filename} after {max_attempts} attempts: {last_error}", None
|
| 596 |
else:
|
| 597 |
+
# For other languages, use upload_folder (Gradio uses individual files everywhere)
|
| 598 |
+
# MATCH GRADIO: No commit_message for spaces
|
| 599 |
+
print(f"[Deploy] Uploading folder to {repo_id}")
|
| 600 |
api.upload_folder(
|
| 601 |
folder_path=str(temp_path),
|
| 602 |
repo_id=repo_id,
|
| 603 |
+
repo_type="space"
|
| 604 |
+
# NO commit_message - HF API handles this automatically for spaces
|
| 605 |
)
|
| 606 |
except Exception as e:
|
| 607 |
return False, f"Failed to upload files: {str(e)}", None
|
frontend/src/app/page.tsx
CHANGED
|
@@ -187,6 +187,27 @@ export default function Home() {
|
|
| 187 |
return;
|
| 188 |
}
|
| 189 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 190 |
// SAME LOGIC AS GRADIO VERSION: Parse message history to find existing space
|
| 191 |
let existingSpace: string | null = null;
|
| 192 |
|
|
@@ -194,61 +215,61 @@ export default function Home() {
|
|
| 194 |
console.log('[Deploy] ========== DEBUG START ==========');
|
| 195 |
console.log('[Deploy] Total messages in history:', messages.length);
|
| 196 |
console.log('[Deploy] Current username:', username);
|
|
|
|
| 197 |
console.log('[Deploy] Messages:', JSON.stringify(messages, null, 2));
|
| 198 |
|
| 199 |
if (messages.length > 0 && username) {
|
| 200 |
-
console.log('[Deploy] Scanning message history...');
|
|
|
|
| 201 |
|
| 202 |
-
|
|
|
|
|
|
|
| 203 |
const msg = messages[i];
|
| 204 |
console.log(`[Deploy] Checking message ${i}:`, {
|
| 205 |
role: msg.role,
|
| 206 |
-
contentPreview: msg.content.substring(0, 100)
|
| 207 |
-
startsWithImported: msg.content.startsWith('Imported Space from')
|
| 208 |
});
|
| 209 |
|
| 210 |
-
// Check for deployment
|
| 211 |
-
if (msg.role === 'assistant'
|
| 212 |
-
|
| 213 |
-
if (
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
|
|
|
|
|
|
|
|
|
| 217 |
}
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
break;
|
| 227 |
}
|
| 228 |
}
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
console.log('[Deploy] π― Found "Imported Space from" message!');
|
| 233 |
const match = msg.content.match(/huggingface\.co\/spaces\/([^\/\s\)]+\/[^\/\s\)]+)/);
|
| 234 |
-
console.log('[Deploy] Regex match result:', match);
|
| 235 |
if (match) {
|
| 236 |
const importedSpace = match[1];
|
| 237 |
-
console.log('[Deploy] Extracted space:', importedSpace);
|
| 238 |
-
console.log('[Deploy]
|
| 239 |
-
console.log('[Deploy] Starts with username?', importedSpace.startsWith(`${username}/`));
|
| 240 |
|
| 241 |
-
// Only use
|
| 242 |
if (importedSpace.startsWith(`${username}/`)) {
|
| 243 |
existingSpace = importedSpace;
|
| 244 |
-
console.log('[Deploy] β
β
β
USER OWNS
|
| 245 |
break;
|
| 246 |
} else {
|
| 247 |
-
console.log('[Deploy] β οΈ User does
|
| 248 |
-
|
| 249 |
}
|
| 250 |
-
} else {
|
| 251 |
-
console.log('[Deploy] β Regex did not match URL in message');
|
| 252 |
}
|
| 253 |
}
|
| 254 |
}
|
|
@@ -256,9 +277,17 @@ export default function Home() {
|
|
| 256 |
console.log('[Deploy] Final existingSpace value:', existingSpace);
|
| 257 |
} else {
|
| 258 |
console.log('[Deploy] Skipping scan - no messages or no username');
|
|
|
|
|
|
|
| 259 |
}
|
| 260 |
console.log('[Deploy] ========== DEBUG END ==========');
|
| 261 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 262 |
// Auto-generate space name (never prompt user)
|
| 263 |
let spaceName = undefined; // undefined = backend will auto-generate
|
| 264 |
|
|
|
|
| 187 |
return;
|
| 188 |
}
|
| 189 |
|
| 190 |
+
// CRITICAL: Wait for username to be loaded from auth
|
| 191 |
+
if (!username) {
|
| 192 |
+
console.warn('[Deploy] Username not loaded yet, checking auth...');
|
| 193 |
+
// Try to get username from auth status
|
| 194 |
+
try {
|
| 195 |
+
const authStatus = await apiClient.getAuthStatus();
|
| 196 |
+
if (authStatus.username) {
|
| 197 |
+
setUsername(authStatus.username);
|
| 198 |
+
// Retry deployment after setting username
|
| 199 |
+
setTimeout(() => handleDeploy(), 100);
|
| 200 |
+
return;
|
| 201 |
+
} else {
|
| 202 |
+
alert('Please log in to deploy your app');
|
| 203 |
+
return;
|
| 204 |
+
}
|
| 205 |
+
} catch (e) {
|
| 206 |
+
alert('Please log in to deploy your app');
|
| 207 |
+
return;
|
| 208 |
+
}
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
// SAME LOGIC AS GRADIO VERSION: Parse message history to find existing space
|
| 212 |
let existingSpace: string | null = null;
|
| 213 |
|
|
|
|
| 215 |
console.log('[Deploy] ========== DEBUG START ==========');
|
| 216 |
console.log('[Deploy] Total messages in history:', messages.length);
|
| 217 |
console.log('[Deploy] Current username:', username);
|
| 218 |
+
console.log('[Deploy] Auth status:', isAuthenticated ? 'authenticated' : 'not authenticated');
|
| 219 |
console.log('[Deploy] Messages:', JSON.stringify(messages, null, 2));
|
| 220 |
|
| 221 |
if (messages.length > 0 && username) {
|
| 222 |
+
console.log('[Deploy] Scanning message history FORWARD (oldest first) - MATCHING GRADIO LOGIC...');
|
| 223 |
+
console.log('[Deploy] Total messages to scan:', messages.length);
|
| 224 |
|
| 225 |
+
// EXACT GRADIO LOGIC: Scan forward (oldest first) and stop at first match
|
| 226 |
+
// Gradio: for user_msg, assistant_msg in history:
|
| 227 |
+
for (let i = 0; i < messages.length; i++) {
|
| 228 |
const msg = messages[i];
|
| 229 |
console.log(`[Deploy] Checking message ${i}:`, {
|
| 230 |
role: msg.role,
|
| 231 |
+
contentPreview: msg.content.substring(0, 100)
|
|
|
|
| 232 |
});
|
| 233 |
|
| 234 |
+
// Check assistant messages for deployment confirmations
|
| 235 |
+
if (msg.role === 'assistant') {
|
| 236 |
+
// Check for "β
Deployed!" message
|
| 237 |
+
if (msg.content.includes('β
Deployed!')) {
|
| 238 |
+
const match = msg.content.match(/huggingface\.co\/spaces\/([^\/\s\)]+\/[^\/\s\)]+)/);
|
| 239 |
+
if (match) {
|
| 240 |
+
existingSpace = match[1];
|
| 241 |
+
console.log('[Deploy] β
Found "β
Deployed!" - existing_space:', existingSpace);
|
| 242 |
+
break;
|
| 243 |
+
}
|
| 244 |
}
|
| 245 |
+
// Check for "β
Updated!" message
|
| 246 |
+
else if (msg.content.includes('β
Updated!')) {
|
| 247 |
+
const match = msg.content.match(/huggingface\.co\/spaces\/([^\/\s\)]+\/[^\/\s\)]+)/);
|
| 248 |
+
if (match) {
|
| 249 |
+
existingSpace = match[1];
|
| 250 |
+
console.log('[Deploy] β
Found "β
Updated!" - existing_space:', existingSpace);
|
| 251 |
+
break;
|
| 252 |
+
}
|
|
|
|
| 253 |
}
|
| 254 |
}
|
| 255 |
+
// Check user messages for imports
|
| 256 |
+
else if (msg.role === 'user' && msg.content.startsWith('Imported Space from')) {
|
| 257 |
+
console.log('[Deploy] π― Found "Imported Space from" message');
|
|
|
|
| 258 |
const match = msg.content.match(/huggingface\.co\/spaces\/([^\/\s\)]+\/[^\/\s\)]+)/);
|
|
|
|
| 259 |
if (match) {
|
| 260 |
const importedSpace = match[1];
|
| 261 |
+
console.log('[Deploy] Extracted imported space:', importedSpace);
|
| 262 |
+
console.log('[Deploy] Checking ownership - user:', username, 'space:', importedSpace);
|
|
|
|
| 263 |
|
| 264 |
+
// Only use if user owns it (EXACT GRADIO LOGIC)
|
| 265 |
if (importedSpace.startsWith(`${username}/`)) {
|
| 266 |
existingSpace = importedSpace;
|
| 267 |
+
console.log('[Deploy] β
β
β
USER OWNS - Will update:', existingSpace);
|
| 268 |
break;
|
| 269 |
} else {
|
| 270 |
+
console.log('[Deploy] β οΈ User does NOT own - will create new space');
|
| 271 |
+
// existing_space remains None (create new deployment)
|
| 272 |
}
|
|
|
|
|
|
|
| 273 |
}
|
| 274 |
}
|
| 275 |
}
|
|
|
|
| 277 |
console.log('[Deploy] Final existingSpace value:', existingSpace);
|
| 278 |
} else {
|
| 279 |
console.log('[Deploy] Skipping scan - no messages or no username');
|
| 280 |
+
console.log('[Deploy] Messages length:', messages.length);
|
| 281 |
+
console.log('[Deploy] Username:', username);
|
| 282 |
}
|
| 283 |
console.log('[Deploy] ========== DEBUG END ==========');
|
| 284 |
|
| 285 |
+
// TEMPORARY DEBUG: Show what will be sent
|
| 286 |
+
console.log('[Deploy] π ABOUT TO DEPLOY:');
|
| 287 |
+
console.log('[Deploy] - Language:', selectedLanguage);
|
| 288 |
+
console.log('[Deploy] - existing_repo_id:', existingSpace || 'None (new deployment)');
|
| 289 |
+
console.log('[Deploy] - Username:', username);
|
| 290 |
+
|
| 291 |
// Auto-generate space name (never prompt user)
|
| 292 |
let spaceName = undefined; // undefined = backend will auto-generate
|
| 293 |
|