Spaces:
Sleeping
Sleeping
| # core/auto_deploy.py | |
| """ | |
| Auto-Deploy – Utilise l'API Hugging Face Hub pour uploader des fichiers. | |
| Contourne les problèmes d'authentification Git. | |
| """ | |
| import os | |
| import logging | |
| from pathlib import Path | |
| from typing import Optional | |
| try: | |
| from huggingface_hub import upload_file, upload_folder, HfApi | |
| HF_HUB_AVAILABLE = True | |
| except ImportError: | |
| HF_HUB_AVAILABLE = False | |
| logging.warning("⚠️ huggingface_hub non installé – auto-déploiement désactivé.") | |
| logger = logging.getLogger("lucie.auto_deploy") | |
| class AutoDeploy: | |
| def __init__(self, repo_dir: str = "/app", token_env: str = "HF_TOKEN"): | |
| self.repo_dir = Path(repo_dir) | |
| self.token = os.environ.get(token_env) | |
| self.repo_id = None | |
| self._detect_repo_id() | |
| if not self.token: | |
| logger.warning("⚠️ HF_TOKEN non défini – auto-déploiement désactivé.") | |
| def _detect_repo_id(self): | |
| """Détecte le nom du Space à partir du remote git ou des variables d'env.""" | |
| try: | |
| import subprocess | |
| res = subprocess.run( | |
| ["git", "remote", "get-url", "origin"], | |
| cwd=self.repo_dir, | |
| capture_output=True, | |
| text=True, | |
| check=True | |
| ) | |
| url = res.stdout.strip() | |
| if "spaces/" in url: | |
| parts = url.split("spaces/")[-1].split("/") | |
| if len(parts) >= 2: | |
| self.repo_id = f"{parts[0]}/{parts[1].replace('.git', '')}" | |
| elif "huggingface.co/" in url: | |
| parts = url.split("huggingface.co/")[-1].split("/") | |
| if len(parts) >= 2: | |
| self.repo_id = f"{parts[0]}/{parts[1].replace('.git', '')}" | |
| except Exception as e: | |
| logger.warning(f"⚠️ Impossible de détecter le repo : {e}") | |
| if not self.repo_id: | |
| space = os.environ.get("SPACE_NAME") | |
| user = os.environ.get("HF_USER") | |
| if space and user: | |
| self.repo_id = f"{user}/{space}" | |
| if not self.repo_id: | |
| logger.warning("⚠️ Repo ID non détecté – déploiement désactivé.") | |
| def is_configured(self) -> bool: | |
| return self.token is not None and self.repo_id is not None and HF_HUB_AVAILABLE | |
| def upload_file(self, local_path: Path, remote_path: str, commit_message: str = "Auto-update by LUCIE") -> bool: | |
| if not self.is_configured(): | |
| logger.error("❌ Auto-déploiement non configuré.") | |
| return False | |
| try: | |
| api = HfApi(token=self.token) | |
| api.upload_file( | |
| path_or_fileobj=str(local_path), | |
| path_in_repo=remote_path, | |
| repo_id=self.repo_id, | |
| repo_type="space", | |
| commit_message=commit_message, | |
| ) | |
| logger.info(f"✅ Fichier {remote_path} uploadé avec succès.") | |
| return True | |
| except Exception as e: | |
| logger.error(f"❌ Erreur upload : {e}") | |
| return False | |
| def push_file(self, file_path: str, commit_message: str = "Auto-update by LUCIE") -> bool: | |
| full_path = self.repo_dir / file_path | |
| if not full_path.exists(): | |
| logger.error(f"❌ Fichier {file_path} introuvable.") | |
| return False | |
| return self.upload_file(full_path, file_path, commit_message) | |
| def push_lora(self, lora_dir: str) -> bool: | |
| if not self.is_configured(): | |
| return False | |
| try: | |
| api = HfApi(token=self.token) | |
| api.upload_folder( | |
| folder_path=lora_dir, | |
| path_in_repo="lora", | |
| repo_id=self.repo_id, | |
| repo_type="space", | |
| commit_message="Auto-update LoRA by LUCIE", | |
| ignore_patterns=["*.pt", "*.pth", "*.bin"], | |
| ) | |
| logger.info("✅ Dossier LoRA uploadé avec succès.") | |
| return True | |
| except Exception as e: | |
| logger.error(f"❌ Erreur upload LoRA : {e}") | |
| return False |