Spaces:
Running
Running
fix making new commits
Browse files- backend_deploy.py +81 -3
backend_deploy.py
CHANGED
|
@@ -413,6 +413,54 @@ CMD ["npm", "start", "--", "-p", "7860"]
|
|
| 413 |
"""
|
| 414 |
|
| 415 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 416 |
def deploy_to_huggingface_space(
|
| 417 |
code: str,
|
| 418 |
language: str,
|
|
@@ -422,7 +470,8 @@ def deploy_to_huggingface_space(
|
|
| 422 |
description: Optional[str] = None,
|
| 423 |
private: bool = False,
|
| 424 |
existing_repo_id: Optional[str] = None,
|
| 425 |
-
commit_message: Optional[str] = None
|
|
|
|
| 426 |
) -> Tuple[bool, str, Optional[str]]:
|
| 427 |
"""
|
| 428 |
Deploy code to HuggingFace Spaces (create new or update existing)
|
|
@@ -437,6 +486,7 @@ def deploy_to_huggingface_space(
|
|
| 437 |
private: Whether to make the space private (only for new spaces)
|
| 438 |
existing_repo_id: If provided (username/space-name), updates this space instead of creating new one
|
| 439 |
commit_message: Custom commit message (defaults to "Deploy from anycoder" or "Update from anycoder")
|
|
|
|
| 440 |
|
| 441 |
Returns:
|
| 442 |
Tuple of (success: bool, message: str, space_url: Optional[str])
|
|
@@ -449,6 +499,21 @@ def deploy_to_huggingface_space(
|
|
| 449 |
try:
|
| 450 |
api = HfApi(token=token)
|
| 451 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 452 |
# Determine if this is an update or new deployment
|
| 453 |
is_update = existing_repo_id is not None
|
| 454 |
|
|
@@ -456,7 +521,15 @@ def deploy_to_huggingface_space(
|
|
| 456 |
# Use existing repo
|
| 457 |
repo_id = existing_repo_id
|
| 458 |
space_name = existing_repo_id.split('/')[-1]
|
| 459 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 460 |
else:
|
| 461 |
# Get username if not provided
|
| 462 |
if not username:
|
|
@@ -882,7 +955,12 @@ def deploy_to_huggingface_space(
|
|
| 882 |
|
| 883 |
space_url = f"https://huggingface.co/spaces/{repo_id}"
|
| 884 |
action = "Updated" if is_update else "Deployed"
|
| 885 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 886 |
|
| 887 |
except Exception as e:
|
| 888 |
print(f"[Deploy] Top-level exception caught: {type(e).__name__}: {str(e)}")
|
|
|
|
| 413 |
"""
|
| 414 |
|
| 415 |
|
| 416 |
+
def extract_space_id_from_history(history: Optional[List[Dict]], username: Optional[str] = None) -> Optional[str]:
|
| 417 |
+
"""
|
| 418 |
+
Extract existing space ID from chat history (for updates after followups/imports)
|
| 419 |
+
|
| 420 |
+
Args:
|
| 421 |
+
history: Chat history (list of dicts with 'role' and 'content')
|
| 422 |
+
username: Current username (to verify ownership of imported spaces)
|
| 423 |
+
|
| 424 |
+
Returns:
|
| 425 |
+
Space ID (username/space-name) if found, None otherwise
|
| 426 |
+
"""
|
| 427 |
+
if not history:
|
| 428 |
+
return None
|
| 429 |
+
|
| 430 |
+
import re
|
| 431 |
+
existing_space = None
|
| 432 |
+
|
| 433 |
+
# Look through history for previous deployments or imports
|
| 434 |
+
for msg in history:
|
| 435 |
+
role = msg.get('role', '')
|
| 436 |
+
content = msg.get('content', '')
|
| 437 |
+
|
| 438 |
+
# Check assistant messages for deployment confirmations
|
| 439 |
+
if role == 'assistant':
|
| 440 |
+
if "β
Deployed!" in content or "β
Updated!" in content:
|
| 441 |
+
# Look for space URL pattern
|
| 442 |
+
match = re.search(r'huggingface\.co/spaces/([^/\s\)]+/[^/\s\)]+)', content)
|
| 443 |
+
if match:
|
| 444 |
+
existing_space = match.group(1)
|
| 445 |
+
break
|
| 446 |
+
|
| 447 |
+
# Check user messages for imports
|
| 448 |
+
elif role == 'user':
|
| 449 |
+
if "import" in content.lower() and "space" in content.lower():
|
| 450 |
+
# Extract space name from import message
|
| 451 |
+
match = re.search(r'huggingface\.co/spaces/([^/\s\)]+/[^/\s\)]+)', content)
|
| 452 |
+
if match:
|
| 453 |
+
imported_space = match.group(1)
|
| 454 |
+
# Only use imported space if user owns it (can update it)
|
| 455 |
+
if username and imported_space.startswith(f"{username}/"):
|
| 456 |
+
existing_space = imported_space
|
| 457 |
+
break
|
| 458 |
+
# If user doesn't own the imported space, we'll create a new one
|
| 459 |
+
# (existing_space remains None, triggering new deployment)
|
| 460 |
+
|
| 461 |
+
return existing_space
|
| 462 |
+
|
| 463 |
+
|
| 464 |
def deploy_to_huggingface_space(
|
| 465 |
code: str,
|
| 466 |
language: str,
|
|
|
|
| 470 |
description: Optional[str] = None,
|
| 471 |
private: bool = False,
|
| 472 |
existing_repo_id: Optional[str] = None,
|
| 473 |
+
commit_message: Optional[str] = None,
|
| 474 |
+
history: Optional[List[Dict]] = None
|
| 475 |
) -> Tuple[bool, str, Optional[str]]:
|
| 476 |
"""
|
| 477 |
Deploy code to HuggingFace Spaces (create new or update existing)
|
|
|
|
| 486 |
private: Whether to make the space private (only for new spaces)
|
| 487 |
existing_repo_id: If provided (username/space-name), updates this space instead of creating new one
|
| 488 |
commit_message: Custom commit message (defaults to "Deploy from anycoder" or "Update from anycoder")
|
| 489 |
+
history: Chat history (list of dicts with 'role' and 'content') - used to detect followups/imports
|
| 490 |
|
| 491 |
Returns:
|
| 492 |
Tuple of (success: bool, message: str, space_url: Optional[str])
|
|
|
|
| 499 |
try:
|
| 500 |
api = HfApi(token=token)
|
| 501 |
|
| 502 |
+
# Get username if not provided (needed for history tracking)
|
| 503 |
+
if not username:
|
| 504 |
+
try:
|
| 505 |
+
user_info = api.whoami()
|
| 506 |
+
username = user_info.get("name") or user_info.get("preferred_username") or "user"
|
| 507 |
+
except Exception as e:
|
| 508 |
+
pass # Will handle later if needed
|
| 509 |
+
|
| 510 |
+
# Check history for existing space if not explicitly provided
|
| 511 |
+
# This enables automatic updates for followup prompts and imported spaces
|
| 512 |
+
if not existing_repo_id and history:
|
| 513 |
+
existing_repo_id = extract_space_id_from_history(history, username)
|
| 514 |
+
if existing_repo_id:
|
| 515 |
+
print(f"[Deploy] Detected existing space from history: {existing_repo_id}")
|
| 516 |
+
|
| 517 |
# Determine if this is an update or new deployment
|
| 518 |
is_update = existing_repo_id is not None
|
| 519 |
|
|
|
|
| 521 |
# Use existing repo
|
| 522 |
repo_id = existing_repo_id
|
| 523 |
space_name = existing_repo_id.split('/')[-1]
|
| 524 |
+
if '/' in existing_repo_id:
|
| 525 |
+
username = existing_repo_id.split('/')[0]
|
| 526 |
+
elif not username:
|
| 527 |
+
# Get username if still not available
|
| 528 |
+
try:
|
| 529 |
+
user_info = api.whoami()
|
| 530 |
+
username = user_info.get("name") or user_info.get("preferred_username") or "user"
|
| 531 |
+
except Exception as e:
|
| 532 |
+
return False, f"Failed to get user info: {str(e)}", None
|
| 533 |
else:
|
| 534 |
# Get username if not provided
|
| 535 |
if not username:
|
|
|
|
| 955 |
|
| 956 |
space_url = f"https://huggingface.co/spaces/{repo_id}"
|
| 957 |
action = "Updated" if is_update else "Deployed"
|
| 958 |
+
|
| 959 |
+
# Include the space URL in the message for history tracking
|
| 960 |
+
# This allows future deployments to detect this as the existing space
|
| 961 |
+
success_msg = f"β
{action}! View your space at: {space_url}"
|
| 962 |
+
|
| 963 |
+
return True, success_msg, space_url
|
| 964 |
|
| 965 |
except Exception as e:
|
| 966 |
print(f"[Deploy] Top-level exception caught: {type(e).__name__}: {str(e)}")
|