Spaces:
Build error
Build error
Update huggingface_storage.py
Browse files- huggingface_storage.py +88 -1
huggingface_storage.py
CHANGED
|
@@ -132,4 +132,91 @@ def delete_project_folder_from_hf(
|
|
| 132 |
# Si le dossier est déjà supprimé, HfHubHTTPError 404 est levée par delete_folder
|
| 133 |
if "404" in str(e):
|
| 134 |
return True, "Dossier non trouvé sur Hugging Face (déjà supprimé ou ID invalide)."
|
| 135 |
-
return False, f"Échec de la suppression Hugging Face: {str(e)}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
# Si le dossier est déjà supprimé, HfHubHTTPError 404 est levée par delete_folder
|
| 133 |
if "404" in str(e):
|
| 134 |
return True, "Dossier non trouvé sur Hugging Face (déjà supprimé ou ID invalide)."
|
| 135 |
+
return False, f"Échec de la suppression Hugging Face: {str(e)}"
|
| 136 |
+
|
| 137 |
+
def create_empty_repo_folder_on_hf(
|
| 138 |
+
repo_slug: str,
|
| 139 |
+
user_id: str,
|
| 140 |
+
repo_id: Optional[str] = None
|
| 141 |
+
) -> tuple[bool, str]:
|
| 142 |
+
"""
|
| 143 |
+
Crée une structure de dossier vide (représentant le dépôt) sur le Dataset Hugging Face.
|
| 144 |
+
Ceci est souvent implémenté en créant un fichier .gitkeep ou README.md initial.
|
| 145 |
+
Nous allons créer un fichier README.md minimal.
|
| 146 |
+
"""
|
| 147 |
+
repo_id = repo_id if repo_id else HF_DATASET_REPO_ID
|
| 148 |
+
if not repo_id:
|
| 149 |
+
return False, "Erreur de configuration: Repository Hugging Face non défini."
|
| 150 |
+
|
| 151 |
+
readme_content = f"# Dépôt {repo_slug}\n\nBienvenue sur votre dépôt GitForge, hébergé sur Mailix.\n\nCommencez par ajouter ou créer des fichiers."
|
| 152 |
+
path_in_repo = f"{user_id}/{repo_slug}/README.md"
|
| 153 |
+
|
| 154 |
+
try:
|
| 155 |
+
# Utilisation de HfApi.upload_file pour créer un fichier unique, ce qui crée le dossier
|
| 156 |
+
commit_url = api.upload_file(
|
| 157 |
+
path_or_fileobj=readme_content.encode('utf-8'),
|
| 158 |
+
path_in_repo=path_in_repo,
|
| 159 |
+
repo_id=repo_id,
|
| 160 |
+
repo_type="dataset",
|
| 161 |
+
commit_message=f"Initialisation du dépôt {repo_slug}"
|
| 162 |
+
)
|
| 163 |
+
|
| 164 |
+
logger.info(f"Dépôt vide créé sur HF pour {repo_slug}. Commit: {commit_url}")
|
| 165 |
+
return True, "Dépôt initialisé avec succès sur Hugging Face."
|
| 166 |
+
|
| 167 |
+
except Exception as e:
|
| 168 |
+
logger.error(f"Échec de l'initialisation du dépôt HF pour {repo_slug}: {e}")
|
| 169 |
+
return False, f"Échec de l'initialisation Hugging Face: {str(e)}"
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
def list_repo_files_from_hf(
|
| 173 |
+
repo_slug: str,
|
| 174 |
+
user_id: str,
|
| 175 |
+
repo_id: Optional[str] = None
|
| 176 |
+
) -> tuple[list[Dict], str]:
|
| 177 |
+
"""
|
| 178 |
+
Liste tous les fichiers et dossiers dans le chemin spécifique (user_id/repo_slug)
|
| 179 |
+
du Dataset Hugging Face.
|
| 180 |
+
"""
|
| 181 |
+
repo_id = repo_id if repo_id else HF_DATASET_REPO_ID
|
| 182 |
+
if not repo_id:
|
| 183 |
+
return [], "Erreur de configuration: Repository Hugging Face non défini."
|
| 184 |
+
|
| 185 |
+
# Le chemin dans le repo est 'user_id/repo_slug'
|
| 186 |
+
path_to_repo = f"{user_id}/{repo_slug}"
|
| 187 |
+
|
| 188 |
+
try:
|
| 189 |
+
# Utiliser HfFileSystem pour lister le contenu du dossier
|
| 190 |
+
items = fs.ls(f"datasets/{repo_id}/{path_to_repo}", detail=True)
|
| 191 |
+
|
| 192 |
+
file_list = []
|
| 193 |
+
for item in items:
|
| 194 |
+
# item est un dictionnaire avec 'name', 'type', 'size', 'last_modified', etc.
|
| 195 |
+
# On ignore le nom du dossier racine pour l'affichage utilisateur
|
| 196 |
+
file_name = item['name'].split('/')[-1]
|
| 197 |
+
|
| 198 |
+
# Ignorer les dossiers et les fichiers système cachés (.DS_Store, .gitattributes, etc.)
|
| 199 |
+
if item['type'] == 'directory' or file_name.startswith('.'):
|
| 200 |
+
# Pour une future étape, on pourrait inclure les dossiers
|
| 201 |
+
continue
|
| 202 |
+
|
| 203 |
+
file_list.append({
|
| 204 |
+
"name": file_name,
|
| 205 |
+
"path": item['name'], # Chemin complet pour référence interne
|
| 206 |
+
"size": item.get('size', 0),
|
| 207 |
+
"type": "file", # Dans cette version, nous listons seulement les fichiers
|
| 208 |
+
"last_modified": item.get('last_modified', 'N/A')
|
| 209 |
+
})
|
| 210 |
+
|
| 211 |
+
logger.info(f"Liste des fichiers récupérée pour {path_to_repo} ({len(file_list)} fichiers).")
|
| 212 |
+
return file_list, "Liste des fichiers récupérée avec succès."
|
| 213 |
+
|
| 214 |
+
except HfHubHTTPError as e:
|
| 215 |
+
if "404" in str(e):
|
| 216 |
+
# Le dossier n'existe pas encore (dépôt vide sans initialisation)
|
| 217 |
+
return [], f"Le dépôt '{repo_slug}' n'a pas encore de fichiers sur Hugging Face (404)."
|
| 218 |
+
logger.error(f"Erreur HTTP HF lors de la liste des fichiers pour {path_to_repo}: {e}")
|
| 219 |
+
return [], f"Erreur Hugging Face: {str(e)}"
|
| 220 |
+
except Exception as e:
|
| 221 |
+
logger.error(f"Erreur inconnue lors de la liste des fichiers HF pour {path_to_repo}: {e}")
|
| 222 |
+
return [], f"Erreur inconnue lors de l'accès à Hugging Face: {str(e)}"
|