Spaces:
Runtime error
Runtime error
import os | |
import sys | |
import time | |
import subprocess | |
from pathlib import Path | |
import logging | |
import requests | |
from requests.adapters import HTTPAdapter | |
from urllib3.util.retry import Retry | |
from typing import Optional | |
from dotenv import load_dotenv | |
from huggingface_hub import HfApi, create_repo | |
# Configure logging | |
logging.basicConfig(level=logging.INFO) | |
logger = logging.getLogger(__name__) | |
def setup_requests_session( | |
retries: int = 5, | |
backoff_factor: float = 1.0, | |
status_forcelist: Optional[list] = None | |
) -> requests.Session: | |
"""Configure requests session with retries.""" | |
if status_forcelist is None: | |
status_forcelist = [408, 429, 500, 502, 503, 504] | |
session = requests.Session() | |
retry = Retry( | |
total=retries, | |
read=retries, | |
connect=retries, | |
backoff_factor=backoff_factor, | |
status_forcelist=status_forcelist, | |
) | |
adapter = HTTPAdapter(max_retries=retry) | |
session.mount('http://', adapter) | |
session.mount('https://', adapter) | |
return session | |
def check_network_connectivity(host: str = "8.8.8.8", timeout: int = 5) -> bool: | |
"""Check if network is accessible.""" | |
try: | |
# Try DNS resolution first | |
subprocess.run( | |
["ping", "-c", "1", "-W", str(timeout), host], | |
stdout=subprocess.PIPE, | |
stderr=subprocess.PIPE, | |
check=True | |
) | |
return True | |
except subprocess.CalledProcessError: | |
return False | |
def check_huggingface_connectivity(timeout: int = 5) -> bool: | |
"""Check if Hugging Face is accessible.""" | |
session = setup_requests_session() | |
try: | |
response = session.get("https://huggingface.co.", timeout=timeout) | |
return response.status_code == 200 | |
except: | |
return False | |
def wait_for_network( | |
max_attempts: int = 5, | |
delay: int = 10, | |
hosts: Optional[list] = None | |
) -> bool: | |
"""Wait for network connectivity.""" | |
if hosts is None: | |
hosts = ["8.8.8.8", "1.1.1.1"] | |
for attempt in range(max_attempts): | |
logger.info(f"Checking network connectivity (attempt {attempt + 1}/{max_attempts})") | |
# Try different DNS servers | |
for host in hosts: | |
if check_network_connectivity(host): | |
logger.info(f"Network connectivity established via {host}") | |
return True | |
# Check Hugging Face specifically | |
if check_huggingface_connectivity(): | |
logger.info("Hugging Face is accessible") | |
return True | |
if attempt < max_attempts - 1: | |
logger.warning(f"Network check failed. Waiting {delay} seconds before retry...") | |
time.sleep(delay) | |
return False | |
def upload_to_huggingface(): | |
"""Upload the project to Hugging Face.""" | |
creds_path = None | |
try: | |
# Load environment variables | |
load_dotenv() | |
token = os.getenv("HUGGINGFACE_TOKEN") | |
if not token: | |
raise ValueError("HUGGINGFACE_TOKEN not found in environment variables") | |
# Check network connectivity with increased timeout | |
if not wait_for_network(max_attempts=10, delay=15): | |
raise ConnectionError("Failed to establish network connectivity") | |
# Initialize Hugging Face API with retry session | |
session = setup_requests_session(retries=7, backoff_factor=2.0) | |
api = HfApi(token=token, endpoint="https://huggingface.co.") | |
# Define Space name (modify as needed) | |
space_name = "agentic-system" | |
space_id = f"nananie143/{space_name}" | |
# Create or get existing Space with retries and force hardware restart | |
max_attempts = 3 | |
for attempt in range(max_attempts): | |
try: | |
space_info = api.create_repo( | |
repo_id=space_id, | |
repo_type="space", | |
space_sdk="gradio", | |
private=False, | |
exist_ok=True, | |
hardware={"accelerator": "t4-medium"}, | |
storage={"hf": {"root": "/data"}}, | |
) | |
logger.info(f"Space ready: {space_info.url}") | |
# Force hardware restart to ensure clean environment | |
try: | |
api.request_space_hardware( | |
repo_id=space_id, | |
hardware="t4-medium", | |
sleep_time=2 | |
) | |
logger.info("Requested hardware restart") | |
except Exception as e: | |
logger.warning(f"Hardware restart request failed: {e}") | |
break | |
except Exception as e: | |
if attempt == max_attempts - 1: | |
logger.error(f"Error creating/accessing Space after {max_attempts} attempts: {e}") | |
raise | |
logger.warning(f"Attempt {attempt + 1} failed, retrying...") | |
time.sleep(5 * (attempt + 1)) | |
# Add .gitattributes to ensure proper file handling | |
gitattributes_content = """ | |
*.py text eol=lf | |
*.sh text eol=lf | |
*.yml text eol=lf | |
*.txt text eol=lf | |
requirements.txt text eol=lf | |
""" | |
with open(".gitattributes", "w") as f: | |
f.write(gitattributes_content.strip()) | |
# Files to exclude from upload | |
exclude_patterns = [ | |
"__pycache__", | |
"*.pyc", | |
".git", | |
".env", | |
".env.example", | |
"models/*", | |
"flagged/*", | |
".pytest_cache", | |
"*.log", | |
"*.gguf", | |
".gitignore", | |
"*.backup", | |
"*.bak*", | |
"*.patch", | |
"*.temp", | |
".DS_Store" | |
] | |
# Important files to ensure are included | |
important_files = [ | |
"app.py", | |
"agentic_system.py", | |
"requirements.txt", | |
"space.yml", | |
"download_models_space.py", | |
"app_space.sh", | |
"orchestrator.py", | |
"team_management.py", | |
"meta_learning.py", | |
"config.py", | |
"upload_to_hub.py", | |
".gitattributes" | |
] | |
# Prepare files for upload with validation | |
files_to_upload = [] | |
root_path = Path(".") | |
# First add important files with validation | |
for file in important_files: | |
file_path = Path(file) | |
if file_path.is_file(): | |
if file_path.stat().st_size > 0: # Check if file is not empty | |
files_to_upload.append(str(file_path)) | |
else: | |
logger.warning(f"Skipping empty file: {file}") | |
else: | |
logger.warning(f"Important file not found: {file}") | |
# Then add other files with validation | |
for path in root_path.rglob("*"): | |
if path.is_file(): | |
relative_path = str(path.relative_to(root_path)) | |
if relative_path not in files_to_upload: # Skip if already added | |
skip = False | |
for pattern in exclude_patterns: | |
if Path(relative_path).match(pattern): | |
skip = True | |
break | |
if not skip and path.stat().st_size > 0: # Check if file is not empty | |
files_to_upload.append(relative_path) | |
# Upload files with retry mechanism | |
logger.info("Starting file upload...") | |
total_files = len(files_to_upload) | |
for idx, file_path in enumerate(files_to_upload, 1): | |
max_retries = 3 | |
retry_count = 0 | |
while retry_count < max_retries: | |
try: | |
logger.info(f"[{idx}/{total_files}] Uploading: {file_path}") | |
api.upload_file( | |
path_or_fileobj=file_path, | |
path_in_repo=file_path, | |
repo_id=space_id, | |
repo_type="space" | |
) | |
logger.info(f"✓ Uploaded: {file_path}") | |
break | |
except Exception as e: | |
retry_count += 1 | |
if retry_count == max_retries: | |
logger.error(f"Failed to upload {file_path} after {max_retries} attempts: {e}") | |
else: | |
logger.warning(f"Retry {retry_count}/{max_retries} for {file_path}: {e}") | |
time.sleep(5 * retry_count) | |
logger.info(f"Space updated successfully! Visit: https://huggingface.co./spaces/{space_id}") | |
except Exception as e: | |
logger.error(f"Error uploading to Hugging Face: {e}") | |
raise | |
finally: | |
if creds_path and os.path.exists(creds_path): | |
os.remove(creds_path) | |
if __name__ == "__main__": | |
upload_to_huggingface() | |