167 lines
5.1 KiB
Python
167 lines
5.1 KiB
Python
"""HuggingFace repository management.
|
|
|
|
Handles repository creation, configuration, and management operations.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import subprocess
|
|
import time
|
|
|
|
from helpers.logger import logger
|
|
|
|
|
|
class RepositoryManager:
|
|
"""Manages HuggingFace repository operations.
|
|
|
|
Provides methods for creating repositories, checking existence,
|
|
and managing repository configuration.
|
|
"""
|
|
|
|
@staticmethod
|
|
def create_repository(
|
|
repo_id: str,
|
|
private: bool = False,
|
|
repo_type: str = "model",
|
|
) -> bool:
|
|
"""Create a new HuggingFace repository.
|
|
|
|
Creates a repository with the specified identifier and settings. Repository
|
|
identifiers follow the format "username/repo-name". Supports model, dataset,
|
|
and space repository types with configurable visibility.
|
|
|
|
Returns:
|
|
True if repository was created, False if it already exists.
|
|
"""
|
|
logger.info(f"Creating repository: {repo_id}")
|
|
|
|
cmd = [
|
|
"huggingface-cli",
|
|
"repo",
|
|
"create",
|
|
repo_id,
|
|
"--type",
|
|
repo_type,
|
|
]
|
|
|
|
if private:
|
|
cmd.append("--private")
|
|
|
|
try:
|
|
result = subprocess.run(
|
|
cmd,
|
|
capture_output=True,
|
|
text=True,
|
|
check=False,
|
|
)
|
|
|
|
if result.returncode == 0:
|
|
logger.info(f"Created repository: {repo_id}")
|
|
return True
|
|
if "already exists" in result.stderr.lower():
|
|
logger.info(f"Repository already exists: {repo_id}")
|
|
return False
|
|
logger.error(f"Failed to create repository: {result.stderr}")
|
|
except Exception as e:
|
|
logger.error(f"Error creating repository: {e}")
|
|
|
|
return False
|
|
|
|
@staticmethod
|
|
def ensure_repository_exists(repo_id: str) -> None:
|
|
"""Ensure repository exists, creating if necessary.
|
|
|
|
Attempts to create the repository if it doesn't exist, then waits
|
|
briefly to ensure the repository is ready for operations.
|
|
"""
|
|
# Try to create the repository
|
|
RepositoryManager.create_repository(repo_id)
|
|
|
|
# Small delay to ensure repository is ready
|
|
time.sleep(2)
|
|
|
|
@staticmethod
|
|
def check_repository_exists(repo_id: str) -> bool:
|
|
"""Check if a repository exists.
|
|
|
|
Queries the HuggingFace Hub to determine if a repository with the
|
|
given identifier exists and is accessible.
|
|
|
|
Returns:
|
|
True if repository exists, False otherwise.
|
|
"""
|
|
try:
|
|
result = subprocess.run(
|
|
["huggingface-cli", "repo", "ls-files", repo_id],
|
|
capture_output=True,
|
|
text=True,
|
|
check=False,
|
|
)
|
|
except Exception:
|
|
return False
|
|
else:
|
|
return result.returncode == 0
|
|
|
|
@staticmethod
|
|
def delete_repository(repo_id: str) -> bool:
|
|
"""Delete a HuggingFace repository.
|
|
|
|
Permanently removes a repository from the HuggingFace Hub. This operation
|
|
cannot be undone and requires appropriate permissions.
|
|
|
|
Returns:
|
|
True if deleted successfully, False otherwise.
|
|
"""
|
|
logger.warning(f"Deleting repository: {repo_id}")
|
|
|
|
try:
|
|
result = subprocess.run(
|
|
["huggingface-cli", "repo", "delete", repo_id, "--yes"],
|
|
capture_output=True,
|
|
text=True,
|
|
check=False,
|
|
)
|
|
|
|
if result.returncode == 0:
|
|
logger.info(f"Deleted repository: {repo_id}")
|
|
return True
|
|
logger.error(f"Failed to delete repository: {result.stderr}")
|
|
except Exception as e:
|
|
logger.error(f"Error deleting repository: {e}")
|
|
return False
|
|
else:
|
|
return False
|
|
|
|
@staticmethod
|
|
def get_repository_url(repo_id: str) -> str:
|
|
"""Get the full URL for a repository.
|
|
|
|
Constructs the complete HuggingFace Hub URL for accessing the repository
|
|
through a web browser.
|
|
|
|
Returns:
|
|
Full HuggingFace URL for the repository.
|
|
"""
|
|
return f"https://huggingface.co/{repo_id}"
|
|
|
|
@staticmethod
|
|
def set_repository_visibility(repo_id: str, private: bool) -> bool:
|
|
"""Set repository visibility (public/private).
|
|
|
|
Changes the visibility setting of an existing repository. Private repositories
|
|
require appropriate permissions and may have usage limitations.
|
|
|
|
Returns:
|
|
True if visibility changed successfully.
|
|
"""
|
|
visibility = "private" if private else "public"
|
|
logger.info(f"Setting {repo_id} visibility to {visibility}")
|
|
|
|
try:
|
|
# Note: This would require using the HuggingFace API directly
|
|
# as the CLI doesn't support changing visibility
|
|
logger.warning("Changing repository visibility requires API access")
|
|
except Exception as e:
|
|
logger.error(f"Error changing visibility: {e}")
|
|
|
|
return False
|