atomgit 1.0.8__tar.gz → 1.0.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {atomgit-1.0.8 → atomgit-1.0.9}/PKG-INFO +1 -1
- {atomgit-1.0.8 → atomgit-1.0.9}/__init__.py +3 -3
- {atomgit-1.0.8 → atomgit-1.0.9}/api.py +5 -1
- {atomgit-1.0.8 → atomgit-1.0.9}/atomgit.egg-info/PKG-INFO +1 -1
- {atomgit-1.0.8 → atomgit-1.0.9}/atomgit.egg-info/SOURCES.txt +0 -2
- {atomgit-1.0.8 → atomgit-1.0.9}/atomgit_hub.py +68 -0
- {atomgit-1.0.8 → atomgit-1.0.9}/cli.py +2 -2
- {atomgit-1.0.8 → atomgit-1.0.9}/setup.py +2 -2
- atomgit-1.0.8/test.py +0 -154
- {atomgit-1.0.8 → atomgit-1.0.9}/MANIFEST.in +0 -0
- {atomgit-1.0.8 → atomgit-1.0.9}/README.md +0 -0
- {atomgit-1.0.8 → atomgit-1.0.9}/__main__.py +0 -0
- {atomgit-1.0.8 → atomgit-1.0.9}/atomgit.egg-info/dependency_links.txt +0 -0
- {atomgit-1.0.8 → atomgit-1.0.9}/atomgit.egg-info/entry_points.txt +0 -0
- {atomgit-1.0.8 → atomgit-1.0.9}/atomgit.egg-info/requires.txt +0 -0
- {atomgit-1.0.8 → atomgit-1.0.9}/atomgit.egg-info/top_level.txt +0 -0
- {atomgit-1.0.8 → atomgit-1.0.9}/config.py +0 -0
- {atomgit-1.0.8 → atomgit-1.0.9}/rate_limiter.py +0 -0
- {atomgit-1.0.8 → atomgit-1.0.9}/requirements.txt +0 -0
- {atomgit-1.0.8 → atomgit-1.0.9}/setup.cfg +0 -0
- {atomgit-1.0.8 → atomgit-1.0.9}/tests/test_rate_limiter.py +0 -0
- {atomgit-1.0.8 → atomgit-1.0.9}/utils.py +0 -0
|
@@ -8,7 +8,7 @@ AtomGit CLI - 基于Transformers和Hugging Face Hub的模型文件上传下载
|
|
|
8
8
|
支持模型和数据集的上传、下载等操作。
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
__version__ = '1.0.
|
|
11
|
+
__version__ = '1.0.9'
|
|
12
12
|
__author__ = 'AtomGit CLI Team'
|
|
13
13
|
__description__ = 'AtomGit模型文件上传下载CLI工具'
|
|
14
14
|
|
|
@@ -31,6 +31,6 @@ except ImportError:
|
|
|
31
31
|
|
|
32
32
|
__all__ = [
|
|
33
33
|
'config', 'api', 'cli',
|
|
34
|
-
'snapshot_download', 'hub_download_url', 'download_file',
|
|
34
|
+
'snapshot_download', 'hub_download_url', 'download_file',
|
|
35
35
|
'upload_folder', 'create_repository'
|
|
36
|
-
]
|
|
36
|
+
]
|
|
@@ -16,6 +16,10 @@ os.environ["HF_HOME"] = cache_dir
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
from huggingface_hub import hf_hub_download, upload_folder, create_repo, snapshot_download, constants as hf_constants
|
|
19
|
+
try:
|
|
20
|
+
from .atomgit_hub import snapshot_download as atomgit_snapshot_download
|
|
21
|
+
except ImportError:
|
|
22
|
+
from atomgit_hub import snapshot_download as atomgit_snapshot_download
|
|
19
23
|
try:
|
|
20
24
|
from .rate_limiter import install_hf_rate_limiter
|
|
21
25
|
except ImportError:
|
|
@@ -223,7 +227,7 @@ class HuggingFaceAPI:
|
|
|
223
227
|
# 首先尝试不使用token下载(适用于公开仓库)
|
|
224
228
|
credentials = config.get_credentials()
|
|
225
229
|
try:
|
|
226
|
-
|
|
230
|
+
atomgit_snapshot_download(
|
|
227
231
|
repo_id=normalized_repo_id,
|
|
228
232
|
local_dir=str(local_path),
|
|
229
233
|
force_download=force_download, # 根据用户选择决定是否强制下载
|
|
@@ -9,7 +9,6 @@ config.py
|
|
|
9
9
|
rate_limiter.py
|
|
10
10
|
requirements.txt
|
|
11
11
|
setup.py
|
|
12
|
-
test.py
|
|
13
12
|
utils.py
|
|
14
13
|
./__init__.py
|
|
15
14
|
./__main__.py
|
|
@@ -18,7 +17,6 @@ utils.py
|
|
|
18
17
|
./cli.py
|
|
19
18
|
./config.py
|
|
20
19
|
./rate_limiter.py
|
|
21
|
-
./test.py
|
|
22
20
|
./utils.py
|
|
23
21
|
atomgit.egg-info/PKG-INFO
|
|
24
22
|
atomgit.egg-info/SOURCES.txt
|
|
@@ -23,6 +23,8 @@ os.environ["HF_HOME"] = cache_dir
|
|
|
23
23
|
|
|
24
24
|
from huggingface_hub import snapshot_download as hf_snapshot_download
|
|
25
25
|
from huggingface_hub import hf_hub_download, upload_file as hf_upload_file, upload_folder as hf_upload_folder, create_repo
|
|
26
|
+
from huggingface_hub import HfApi
|
|
27
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
26
28
|
try:
|
|
27
29
|
from .rate_limiter import install_hf_rate_limiter
|
|
28
30
|
except ImportError:
|
|
@@ -86,6 +88,54 @@ def _get_token() -> Optional[str]:
|
|
|
86
88
|
return None
|
|
87
89
|
|
|
88
90
|
|
|
91
|
+
def _snapshot_download_from_tree(
|
|
92
|
+
repo_id: str,
|
|
93
|
+
local_dir: Union[str, Path],
|
|
94
|
+
revision: Optional[str],
|
|
95
|
+
token: Optional[Union[str, bool]],
|
|
96
|
+
force_download: bool,
|
|
97
|
+
allow_patterns: Optional[Union[List[str], str]],
|
|
98
|
+
ignore_patterns: Optional[Union[List[str], str]],
|
|
99
|
+
max_workers: int,
|
|
100
|
+
) -> str:
|
|
101
|
+
"""Download through list_repo_tree when repo_info.siblings is unavailable."""
|
|
102
|
+
from huggingface_hub.utils import filter_repo_objects
|
|
103
|
+
from huggingface_hub.hf_api import RepoFile
|
|
104
|
+
|
|
105
|
+
api = HfApi()
|
|
106
|
+
files = [
|
|
107
|
+
item.path
|
|
108
|
+
for item in api.list_repo_tree(
|
|
109
|
+
repo_id=repo_id, recursive=True, revision=revision, token=token
|
|
110
|
+
)
|
|
111
|
+
if isinstance(item, RepoFile)
|
|
112
|
+
]
|
|
113
|
+
files = list(filter_repo_objects(
|
|
114
|
+
items=files,
|
|
115
|
+
allow_patterns=allow_patterns,
|
|
116
|
+
ignore_patterns=ignore_patterns,
|
|
117
|
+
))
|
|
118
|
+
if not files:
|
|
119
|
+
raise FileNotFoundError(f"仓库没有可下载的文件: {repo_id}")
|
|
120
|
+
|
|
121
|
+
destination = Path(local_dir)
|
|
122
|
+
destination.mkdir(parents=True, exist_ok=True)
|
|
123
|
+
|
|
124
|
+
def download_one(filename: str) -> None:
|
|
125
|
+
hf_hub_download(
|
|
126
|
+
repo_id=repo_id,
|
|
127
|
+
filename=filename,
|
|
128
|
+
revision=revision,
|
|
129
|
+
token=token,
|
|
130
|
+
local_dir=str(destination),
|
|
131
|
+
force_download=force_download,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
with ThreadPoolExecutor(max_workers=max(1, max_workers)) as executor:
|
|
135
|
+
list(executor.map(download_one, files))
|
|
136
|
+
return str(destination.resolve())
|
|
137
|
+
|
|
138
|
+
|
|
89
139
|
def snapshot_download(
|
|
90
140
|
repo_id: str,
|
|
91
141
|
revision: Optional[str] = None,
|
|
@@ -181,6 +231,24 @@ def snapshot_download(
|
|
|
181
231
|
return result
|
|
182
232
|
except Exception as e:
|
|
183
233
|
error_msg = str(e)
|
|
234
|
+
if local_dir is not None and (
|
|
235
|
+
"min() iterable argument is empty" in error_msg
|
|
236
|
+
or "min() arg is an empty sequence" in error_msg
|
|
237
|
+
or "404 Not Found" in error_msg
|
|
238
|
+
):
|
|
239
|
+
try:
|
|
240
|
+
return _snapshot_download_from_tree(
|
|
241
|
+
repo_id=normalized_repo_id,
|
|
242
|
+
local_dir=local_dir,
|
|
243
|
+
revision=revision,
|
|
244
|
+
token=token,
|
|
245
|
+
force_download=force_download,
|
|
246
|
+
allow_patterns=allow_patterns,
|
|
247
|
+
ignore_patterns=ignore_patterns,
|
|
248
|
+
max_workers=max_workers,
|
|
249
|
+
)
|
|
250
|
+
except Exception as fallback_error:
|
|
251
|
+
error_msg = str(fallback_error)
|
|
184
252
|
if "401" in error_msg or "403" in error_msg:
|
|
185
253
|
raise Exception(f"认证失败:{error_msg}。请检查token是否正确,或使用 'atomgit login' 重新登录。")
|
|
186
254
|
elif "404" in error_msg:
|
|
@@ -39,7 +39,7 @@ except ImportError:
|
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
@click.group()
|
|
42
|
-
@click.version_option(version='1.0.
|
|
42
|
+
@click.version_option(version='1.0.9')
|
|
43
43
|
def cli():
|
|
44
44
|
"""AtomGit CLI - 基于Transformers和Hugging Face Hub的AtomGit平台模型文件上传下载工具"""
|
|
45
45
|
pass
|
|
@@ -292,4 +292,4 @@ def config_show():
|
|
|
292
292
|
|
|
293
293
|
|
|
294
294
|
if __name__ == '__main__':
|
|
295
|
-
cli()
|
|
295
|
+
cli()
|
|
@@ -31,7 +31,7 @@ def read_requirements():
|
|
|
31
31
|
|
|
32
32
|
setup(
|
|
33
33
|
name='atomgit',
|
|
34
|
-
version='1.0.
|
|
34
|
+
version='1.0.9',
|
|
35
35
|
author='AtomGit CLI Team',
|
|
36
36
|
author_email='sa@atomgit.com',
|
|
37
37
|
description='AtomGit模型文件上传下载CLI工具',
|
|
@@ -69,4 +69,4 @@ setup(
|
|
|
69
69
|
'Bug Reports': 'https://atomgit.com/gitcode-ai/atomgit_cli/issues',
|
|
70
70
|
'Source': 'https://atomgit.com/gitcode-ai/atomgit_cli',
|
|
71
71
|
},
|
|
72
|
-
)
|
|
72
|
+
)
|
atomgit-1.0.8/test.py
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
"""
|
|
4
|
-
AtomGit Hub 功能测试
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from atomgit_hub import (
|
|
8
|
-
create_repository,
|
|
9
|
-
upload_folder,
|
|
10
|
-
snapshot_download,
|
|
11
|
-
hub_download_url,
|
|
12
|
-
download_file,
|
|
13
|
-
load_dataset
|
|
14
|
-
)
|
|
15
|
-
from pathlib import Path
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def test_create_model(repo_id: str, repo_type: str):
|
|
19
|
-
print("\n=== 测试 create_repository ===")
|
|
20
|
-
try:
|
|
21
|
-
result = create_repository(
|
|
22
|
-
repo_id=repo_id,
|
|
23
|
-
token=None, # 使用保存的token
|
|
24
|
-
private=True,
|
|
25
|
-
repo_type=repo_type,
|
|
26
|
-
exist_ok=True,
|
|
27
|
-
space_sdk=None,
|
|
28
|
-
space_hardware=None,
|
|
29
|
-
space_storage=None,
|
|
30
|
-
space_sleep_time=None,
|
|
31
|
-
space_secrets=None,
|
|
32
|
-
space_variables=None
|
|
33
|
-
)
|
|
34
|
-
print(f"✅ 创建仓库成功: {result}")
|
|
35
|
-
except Exception as e:
|
|
36
|
-
print(f"❌ 创建仓库失败: {e}")
|
|
37
|
-
|
|
38
|
-
def test_upload_folder(repo_id: str, folder_path: str):
|
|
39
|
-
print("\n=== 测试 upload_folder ===")
|
|
40
|
-
|
|
41
|
-
try:
|
|
42
|
-
result = upload_folder(
|
|
43
|
-
folder_path=folder_path,
|
|
44
|
-
repo_id=repo_id,
|
|
45
|
-
token=None, # 使用保存的token
|
|
46
|
-
commit_message="Test upload with all parameters",
|
|
47
|
-
commit_description="Full parameter test for upload_folder function",
|
|
48
|
-
upload_timeout=100
|
|
49
|
-
)
|
|
50
|
-
print(f"✅ 上传文件夹成功: {result}")
|
|
51
|
-
except Exception as e:
|
|
52
|
-
print(f"❌ 上传文件夹失败: {e}")
|
|
53
|
-
|
|
54
|
-
def test_snapshot_download(repo_id: str, local_dir: str):
|
|
55
|
-
print("\n=== 测试 snapshot_download ===")
|
|
56
|
-
try:
|
|
57
|
-
local_path = snapshot_download(
|
|
58
|
-
repo_id=repo_id,
|
|
59
|
-
local_dir=local_dir,
|
|
60
|
-
proxies=None,
|
|
61
|
-
etag_timeout=10,
|
|
62
|
-
resume_download=False,
|
|
63
|
-
force_download=True,
|
|
64
|
-
token=None, # 使用保存的token
|
|
65
|
-
local_files_only=False,
|
|
66
|
-
max_workers=8,
|
|
67
|
-
tqdm_class=None
|
|
68
|
-
)
|
|
69
|
-
print(f"✅ 下载快照成功: {local_path}")
|
|
70
|
-
except Exception as e:
|
|
71
|
-
print(f"❌ 下载快照失败: {e}")
|
|
72
|
-
|
|
73
|
-
def test_download_file(repo_id: str, filename: str, local_dir: str):
|
|
74
|
-
print("\n=== 测试 download_file ===")
|
|
75
|
-
try:
|
|
76
|
-
file_path = download_file(
|
|
77
|
-
repo_id=repo_id,
|
|
78
|
-
filename=filename,
|
|
79
|
-
local_dir=local_dir,
|
|
80
|
-
token=None, # 使用保存的token
|
|
81
|
-
force_download=True
|
|
82
|
-
)
|
|
83
|
-
print(f"✅ 下载文件成功: {file_path}")
|
|
84
|
-
except Exception as e:
|
|
85
|
-
print(f"❌ 下载文件失败: {e}")
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def test_hub_download_url(repo_id: str, filename: str, repo_type: str):
|
|
89
|
-
print("\n=== 测试 hub_download_url ===")
|
|
90
|
-
try:
|
|
91
|
-
url = hub_download_url(
|
|
92
|
-
repo_id=repo_id,
|
|
93
|
-
filename=filename,
|
|
94
|
-
repo_type=repo_type
|
|
95
|
-
)
|
|
96
|
-
print(f"✅ 获取URL成功: {url}")
|
|
97
|
-
except Exception as e:
|
|
98
|
-
print(f"❌ 获取URL失败: {e}")
|
|
99
|
-
|
|
100
|
-
def test_load_dataset(repo_id: str, local_dir: str):
|
|
101
|
-
print("\n=== 测试 load_dataset ===")
|
|
102
|
-
try:
|
|
103
|
-
dataset = load_dataset(
|
|
104
|
-
path=repo_id,
|
|
105
|
-
cache_dir=local_dir,
|
|
106
|
-
token=None
|
|
107
|
-
)
|
|
108
|
-
print(f"✅ 加载数据集成功: {dataset}")
|
|
109
|
-
except Exception as e:
|
|
110
|
-
print(f"❌ 加载数据集失败: {e}")
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def run_all_tests():
|
|
114
|
-
"""运行所有测试"""
|
|
115
|
-
print("=" * 60)
|
|
116
|
-
print("开始运行 AtomGit Hub 完整参数测试")
|
|
117
|
-
print("=" * 60)
|
|
118
|
-
model = "ai-test/atomgit-cli-test-model-full"
|
|
119
|
-
dataset = "ai-test/atomgit-cli-test-dataset-full"
|
|
120
|
-
|
|
121
|
-
model_folder_path="/Users/yanlp/csdn/aipython/gitcode_cli/site/yanlp-model-1"
|
|
122
|
-
dataset_folder_path="/Users/yanlp/csdn/aipython/gitcode_cli/site/yanlp-model-1"
|
|
123
|
-
|
|
124
|
-
test_dataset = "yanlp/glaive_toolcall_zh"
|
|
125
|
-
# 注意:按照依赖顺序执行测试
|
|
126
|
-
# 1. 先创建仓库
|
|
127
|
-
# test_create_model(repo_id=model, repo_type="model")
|
|
128
|
-
# test_create_model(repo_id=dataset, repo_type="dataset")
|
|
129
|
-
|
|
130
|
-
# 2. 测试upload
|
|
131
|
-
# test_upload_folder(repo_id=model, folder_path=model_folder_path)
|
|
132
|
-
# test_upload_folder(repo_id=dataset, folder_path=dataset_folder_path)
|
|
133
|
-
test_upload_folder(repo_id="yanlp/dataset-t2", folder_path="/Users/yanlp/csdn/IdeaProjects/gitcode/gitcode-hf-registry/dataset-t11")
|
|
134
|
-
|
|
135
|
-
# 3. 测试下载
|
|
136
|
-
# test_snapshot_download(repo_id=model, local_dir="./test_downloads/model/snapshot_full")
|
|
137
|
-
# test_snapshot_download(repo_id="hf_mirrors/Qwen/Qwen3-0.6B", local_dir="./test_downloads/dataset/snapshot_full2")
|
|
138
|
-
|
|
139
|
-
# 4. 测试下载文件
|
|
140
|
-
# test_download_file(repo_id=model, filename="README.md", local_dir="./test_downloads/model/single_file")
|
|
141
|
-
|
|
142
|
-
# 5. 测试URL获取
|
|
143
|
-
# test_hub_download_url(repo_id=model, filename="model.safetensors", repo_type="model")
|
|
144
|
-
|
|
145
|
-
# 6. 测试数据集加载
|
|
146
|
-
# test_load_dataset(repo_id=test_dataset, local_dir="./test_downloads/dataset/load_dataset")
|
|
147
|
-
|
|
148
|
-
print("\n" + "=" * 60)
|
|
149
|
-
print("所有测试完成")
|
|
150
|
-
print("=" * 60)
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if __name__ == "__main__":
|
|
154
|
-
run_all_tests()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|