import os
from typing import Optional, Dict, Any
from pathlib import Path
os.environ["OPENMIND_HUB_ENDPOINT"] = "https://hub.gitcode.com"
cache_dir = os.path.expanduser("~/.cache/gitcode")
os.makedirs(cache_dir, exist_ok=True)
os.environ["HF_HOME"] = cache_dir
from openmind_hub import om_hub_download, upload_folder, create_repo, snapshot_download, whoami
try:
from .config import config
except ImportError:
from config import config
class OpenMindAPI:
"""GitCode API 客户端,完全基于OpenMind Hub SDK"""
def __init__(self):
pass
def _normalize_repo_id(self, repo_id: str) -> str:
"""标准化仓库ID,处理三层格式转换"""
parts = repo_id.split('/')
if len(parts) >= 3:
first_part = parts[0]
second_part = parts[1]
remaining_parts = parts[2:]
normalized = first_part + '%2F' + second_part
if remaining_parts:
normalized += '/' + '/'.join(remaining_parts)
print(f"三层仓库名称转换: {repo_id} -> {normalized}")
return normalized
return repo_id
def login(self, token: str) -> bool:
"""登录验证"""
if not token or len(token) < 10:
print("❌ Token格式不正确")
return False
config.set_credentials(token)
print("✅ Token已保存")
return True
def create_repo(self, repo_name: str, repo_type: str = "model",
description: str = "", private: bool = False) -> bool:
"""创建仓库 - 使用OpenMind Hub SDK"""
try:
credentials = config.get_credentials()
if not credentials:
print("未找到登录凭证")
return False
create_repo(
repo_id=repo_name,
token=credentials['token'],
repo_type=repo_type,
private=private
)
return True
except Exception as e:
print(f"创建仓库失败: {e}")
return False
def upload_folder(self, file_path: Path, repo_id: str,
remote_path: str = None, message: str = None) -> bool:
"""上传文件 - 使用OpenMind Hub SDK"""
try:
if not file_path.exists():
print(f"文件不存在: {file_path}")
return False
credentials = config.get_credentials()
if not credentials:
print("未找到登录凭证")
return False
temp_dir = Path.cwd() / ".tmp_upload"
temp_dir.mkdir(exist_ok=True)
try:
if remote_path:
target_file = temp_dir / remote_path
target_file.parent.mkdir(parents=True, exist_ok=True)
else:
target_file = temp_dir / file_path.name
import shutil
shutil.copy2(file_path, target_file)
commit_message = message or "Upload folder using gitcode client"
upload_folder(
repo_id=repo_id,
folder_path=str(temp_dir),
token=credentials['token'],
commit_message=commit_message
)
return True
finally:
import shutil
if temp_dir.exists():
shutil.rmtree(temp_dir)
except Exception as e:
print(f"上传文件失败: {e}")
return False
def upload_directory(self, dir_path: Path, repo_id: str,
message: str = None, progress_callback=None) -> bool:
"""上传目录 - 使用OpenMind Hub SDK"""
try:
if not dir_path.exists() or not dir_path.is_dir():
print(f"目录不存在: {dir_path}")
return False
credentials = config.get_credentials()
if not credentials:
print("未找到登录凭证")
return False
commit_message = message or "Upload folder using gitcode client"
upload_folder(
repo_id=repo_id,
folder_path=str(dir_path),
token=credentials['token'],
commit_message=commit_message
)
return True
except Exception as e:
print(f"上传目录失败: {e}")
return False
def download_repo(self, repo_id: str, local_path: Path = None, force_download: bool = False) -> bool:
"""下载仓库 - 使用OpenMind Hub SDK,支持公开仓库无需token和断点续传"""
try:
normalized_repo_id = self._normalize_repo_id(repo_id)
if local_path is None:
local_path = Path.cwd() / repo_id.split('/')[-1]
local_path.mkdir(parents=True, exist_ok=True)
try:
snapshot_download(
repo_id=normalized_repo_id,
local_dir=str(local_path),
force_download=force_download
)
print(f"✅ 仓库下载成功")
return True
except Exception as e:
error_msg = str(e)
if "403" in error_msg or "FORBIDDEN" in error_msg or "no scopes" in error_msg:
print("检测到认证问题,尝试使用token下载...")
credentials = config.get_credentials()
if credentials:
try:
snapshot_download(
repo_id=normalized_repo_id,
token=credentials['token'],
local_dir=str(local_path),
force_download=force_download
)
return True
except Exception as token_e:
print(f"下载失败: {token_e}")
return False
else:
print("未找到登录凭证,无法尝试私有仓库下载")
print("💡 建议:如果这是私有仓库,请先使用 'gitcode login' 登录")
return False
else:
print(f"仓库下载失败: {error_msg}")
return False
except Exception as e:
print(f"下载仓库失败: {e}")
return False
def download_file(self, repo_id: str, filename: str, local_path: Path = None, force_download: bool = False) -> bool:
"""下载单个文件 - 使用OpenMind Hub SDK,支持公开仓库无需token和断点续传"""
try:
normalized_repo_id = self._normalize_repo_id(repo_id)
if local_path is None:
local_path = Path.cwd()
local_path.mkdir(parents=True, exist_ok=True)
try:
om_hub_download(
repo_id=normalized_repo_id,
filename=filename,
local_dir=str(local_path)
)
print(f"✅ 文件下载成功")
return True
except Exception as e:
error_msg = str(e)
print(f"公开下载失败: {error_msg}")
if "403" in error_msg or "FORBIDDEN" in error_msg or "no scopes" in error_msg:
print("检测到认证问题,尝试使用token下载...")
credentials = config.get_credentials()
if credentials:
try:
om_hub_download(
repo_id=normalized_repo_id,
filename=filename,
local_dir=str(local_path),
token=credentials['token']
)
print(f"✅ 下载完成")
return True
except Exception as token_e:
print(f"下载失败: {token_e}")
return False
else:
print("未找到登录凭证,无法尝试私有仓库下载")
print("💡 建议:如果这是私有仓库,请先使用 'gitcode login' 登录")
return False
else:
print(f"文件下载失败: {error_msg}")
return False
except Exception as e:
print(f"下载文件失败: {e}")
return False
def get_repo_info(self, repo_id: str) -> Optional[Dict[str, Any]]:
"""获取仓库信息 - 此功能需要OpenMind Hub SDK支持"""
try:
return {
"repo_id": repo_id,
"status": "需要OpenMind Hub SDK支持"
}
except Exception as e:
print(f"获取仓库信息失败: {e}")
return None
api = OpenMindAPI()