easy-cos 0.2.3.3__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.
@@ -0,0 +1,174 @@
1
+ Metadata-Version: 2.4
2
+ Name: easy_cos
3
+ Version: 0.2.3.3
4
+ Summary: A simple wrapper for cos
5
+ Author: Jiaqi Wu
6
+ Classifier: Programming Language :: Python :: 3.9
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Requires-Python: >=3.8
9
+ Description-Content-Type: text/markdown
10
+ Requires-Dist: cos-python-sdk-v5
11
+ Requires-Dist: tqdm
12
+ Requires-Dist: pillow
13
+ Requires-Dist: numpy
14
+ Dynamic: author
15
+ Dynamic: classifier
16
+ Dynamic: description
17
+ Dynamic: description-content-type
18
+ Dynamic: requires-dist
19
+ Dynamic: requires-python
20
+ Dynamic: summary
21
+
22
+ # easy_cos
23
+
24
+ 让数据流动变得简单!Make data flow!
25
+ ```bash
26
+ pip install cos-python-sdk-v5
27
+
28
+ pip install easy_cos==0.1.3 --index-url https://pypi.tuna.tsinghua.edu.cn/simple
29
+ # pip install easy_cos==0.1.3 --index-url https://pypi.org/simple #清华等其他镜像源可能同步慢
30
+ ```
31
+
32
+
33
+ 这个库的开发是包含了大部分常用的 cos 脚本操作,避免许多重复代码。以及让很多新入职的同事能够快速用起来我们的数据。、
34
+ <br>
35
+ <br>
36
+ <br>
37
+
38
+ ## 快捷命令行指令
39
+ ```bash
40
+ # 在 ~/.bashrc 中添加:
41
+ export COS_SECRET_ID="YOUR_COS_SECRET_ID"
42
+ export COS_SECRET_KEY="YOUR_COS_SECRET_KEY"
43
+ export COS_REGION="ap-guangzhou"
44
+
45
+ # 之后则可以使用快捷命令行指令:
46
+ cos_list bucket_name/prefix # 列出 bucket_name/prefix 下的所有文件
47
+ cos_download bucket_name/prefix/file.txt local/path/file.txt # 下载 bucket_name/prefix/file.txt 到 local/path/file.txt
48
+ cos_download_r bucket_name/dir local/path # 下载 bucket_name/prefix 到 local/path
49
+ cos_upload local/path bucket_name/prefix/file.txt # 上传 local/path 到 bucket_name/prefix/file.txt
50
+ cos_upload_r local/dir bucket_name/prefix # 上传 local/path 到 bucket_name/prefix
51
+ cos_delete bucket_name/prefix/file.txt # 删除 bucket_name/prefix/file.txt
52
+ ```
53
+
54
+ <br>
55
+ <br>
56
+ <br>
57
+
58
+ # Python API 示例
59
+ ```python
60
+ import os
61
+ COS_CONFIG = {
62
+ 'secret_id': f'{os.environ["COS_SECRET_ID"]}',
63
+ 'secret_key': f'{os.environ["COS_SECRET_KEY"]}',
64
+ 'region': f'{os.environ["COS_REGION"]}',
65
+ }
66
+ ```
67
+
68
+
69
+ ## 场景一(list all files under a cos dir):
70
+
71
+ ```python
72
+ from easy_cos import list_all_files_under_cos_dir
73
+
74
+ list_all_files_under_cos_dir(
75
+ cos_dir="bucket_name/prefix",
76
+ config=COS_CONFIG,
77
+ verbose=True,
78
+ return_path_only=True,
79
+ )
80
+ ```
81
+
82
+ ## 场景二(check if a cos path exists):
83
+
84
+ ```python
85
+ from easy_cos import check_cos_path_exist
86
+
87
+ check_cos_path_exist(
88
+ cos_path="bucket_name/prefix/file.txt",
89
+ config=COS_CONFIG,
90
+ )
91
+ ```
92
+
93
+ ## 场景三(delete a cos file):
94
+
95
+ ```python
96
+ from easy_cos import delete_cos_file
97
+
98
+ delete_cos_file(
99
+ cos_path="bucket_name/prefix/file.txt",
100
+ config=COS_CONFIG,
101
+ )
102
+ ```
103
+
104
+ ## 场景四(delete a cos dir):
105
+
106
+ ```python
107
+ from easy_cos import delete_cos_dir
108
+
109
+ delete_cos_dir(
110
+ cos_dibucket_name/prefix",
111
+ config=COS_CONFIG,
112
+ )
113
+ ```
114
+
115
+ ## 场景五(download a cos file):
116
+
117
+ ```python
118
+ from easy_cos import download_cos_file
119
+
120
+ download_cos_file(
121
+ cos_path="bucket_name/prefix/file.txt",
122
+ local_file_path="local/path/file.txt",
123
+ config=COS_CONFIG,
124
+ )
125
+ ```
126
+
127
+ ## 场景六(download a cos dir):
128
+
129
+ ```python
130
+ from easy_cos import download_cos_dir
131
+
132
+ download_cos_dir(
133
+ cos_dir="bucket_name/prefix",
134
+ local_dir="local/path",
135
+ config=COS_CONFIG,
136
+ )
137
+ ```
138
+
139
+
140
+ ## 场景七(save an image to cos):
141
+
142
+ ```python
143
+ from easy_cos import save_img2cos
144
+
145
+ save_img2cos(
146
+ img=Image.open("image.jpg"),
147
+ cos_save_path="bucket_name/prefix/image.jpg",
148
+ config=COS_CONFIG,
149
+ )
150
+ ```
151
+
152
+ ## 场景八(upload a file to cos):
153
+
154
+ ```python
155
+ from easy_cos import upload_file2cos
156
+
157
+ upload_file2cos(
158
+ local_file_path="local/path/file.txt",
159
+ cos_save_path="bucket_name/prefix/file.txt",
160
+ config=COS_CONFIG,
161
+ )
162
+ ```
163
+
164
+
165
+ ## 场景九(upload a dir to cos):
166
+
167
+ ```python
168
+ from easy_cos import upload_dir2cos
169
+
170
+ upload_dir2cos(
171
+ local_upload_dir="local/path",
172
+ cos_dir="bucket_name/prefix",
173
+ config=COS_CONFIG,
174
+ )
@@ -0,0 +1,153 @@
1
+ # easy_cos
2
+
3
+ 让数据流动变得简单!Make data flow!
4
+ ```bash
5
+ pip install cos-python-sdk-v5
6
+
7
+ pip install easy_cos==0.1.3 --index-url https://pypi.tuna.tsinghua.edu.cn/simple
8
+ # pip install easy_cos==0.1.3 --index-url https://pypi.org/simple #清华等其他镜像源可能同步慢
9
+ ```
10
+
11
+
12
+ 这个库的开发是包含了大部分常用的 cos 脚本操作,避免许多重复代码。以及让很多新入职的同事能够快速用起来我们的数据。、
13
+ <br>
14
+ <br>
15
+ <br>
16
+
17
+ ## 快捷命令行指令
18
+ ```bash
19
+ # 在 ~/.bashrc 中添加:
20
+ export COS_SECRET_ID="YOUR_COS_SECRET_ID"
21
+ export COS_SECRET_KEY="YOUR_COS_SECRET_KEY"
22
+ export COS_REGION="ap-guangzhou"
23
+
24
+ # 之后则可以使用快捷命令行指令:
25
+ cos_list bucket_name/prefix # 列出 bucket_name/prefix 下的所有文件
26
+ cos_download bucket_name/prefix/file.txt local/path/file.txt # 下载 bucket_name/prefix/file.txt 到 local/path/file.txt
27
+ cos_download_r bucket_name/dir local/path # 下载 bucket_name/prefix 到 local/path
28
+ cos_upload local/path bucket_name/prefix/file.txt # 上传 local/path 到 bucket_name/prefix/file.txt
29
+ cos_upload_r local/dir bucket_name/prefix # 上传 local/path 到 bucket_name/prefix
30
+ cos_delete bucket_name/prefix/file.txt # 删除 bucket_name/prefix/file.txt
31
+ ```
32
+
33
+ <br>
34
+ <br>
35
+ <br>
36
+
37
+ # Python API 示例
38
+ ```python
39
+ import os
40
+ COS_CONFIG = {
41
+ 'secret_id': f'{os.environ["COS_SECRET_ID"]}',
42
+ 'secret_key': f'{os.environ["COS_SECRET_KEY"]}',
43
+ 'region': f'{os.environ["COS_REGION"]}',
44
+ }
45
+ ```
46
+
47
+
48
+ ## 场景一(list all files under a cos dir):
49
+
50
+ ```python
51
+ from easy_cos import list_all_files_under_cos_dir
52
+
53
+ list_all_files_under_cos_dir(
54
+ cos_dir="bucket_name/prefix",
55
+ config=COS_CONFIG,
56
+ verbose=True,
57
+ return_path_only=True,
58
+ )
59
+ ```
60
+
61
+ ## 场景二(check if a cos path exists):
62
+
63
+ ```python
64
+ from easy_cos import check_cos_path_exist
65
+
66
+ check_cos_path_exist(
67
+ cos_path="bucket_name/prefix/file.txt",
68
+ config=COS_CONFIG,
69
+ )
70
+ ```
71
+
72
+ ## 场景三(delete a cos file):
73
+
74
+ ```python
75
+ from easy_cos import delete_cos_file
76
+
77
+ delete_cos_file(
78
+ cos_path="bucket_name/prefix/file.txt",
79
+ config=COS_CONFIG,
80
+ )
81
+ ```
82
+
83
+ ## 场景四(delete a cos dir):
84
+
85
+ ```python
86
+ from easy_cos import delete_cos_dir
87
+
88
+ delete_cos_dir(
89
+ cos_dibucket_name/prefix",
90
+ config=COS_CONFIG,
91
+ )
92
+ ```
93
+
94
+ ## 场景五(download a cos file):
95
+
96
+ ```python
97
+ from easy_cos import download_cos_file
98
+
99
+ download_cos_file(
100
+ cos_path="bucket_name/prefix/file.txt",
101
+ local_file_path="local/path/file.txt",
102
+ config=COS_CONFIG,
103
+ )
104
+ ```
105
+
106
+ ## 场景六(download a cos dir):
107
+
108
+ ```python
109
+ from easy_cos import download_cos_dir
110
+
111
+ download_cos_dir(
112
+ cos_dir="bucket_name/prefix",
113
+ local_dir="local/path",
114
+ config=COS_CONFIG,
115
+ )
116
+ ```
117
+
118
+
119
+ ## 场景七(save an image to cos):
120
+
121
+ ```python
122
+ from easy_cos import save_img2cos
123
+
124
+ save_img2cos(
125
+ img=Image.open("image.jpg"),
126
+ cos_save_path="bucket_name/prefix/image.jpg",
127
+ config=COS_CONFIG,
128
+ )
129
+ ```
130
+
131
+ ## 场景八(upload a file to cos):
132
+
133
+ ```python
134
+ from easy_cos import upload_file2cos
135
+
136
+ upload_file2cos(
137
+ local_file_path="local/path/file.txt",
138
+ cos_save_path="bucket_name/prefix/file.txt",
139
+ config=COS_CONFIG,
140
+ )
141
+ ```
142
+
143
+
144
+ ## 场景九(upload a dir to cos):
145
+
146
+ ```python
147
+ from easy_cos import upload_dir2cos
148
+
149
+ upload_dir2cos(
150
+ local_upload_dir="local/path",
151
+ cos_dir="bucket_name/prefix",
152
+ config=COS_CONFIG,
153
+ )
@@ -0,0 +1,5 @@
1
+ from .cos_core_ops import *
2
+ from .img_utils import *
3
+ from .system_util import *
4
+ from .io_utils import *
5
+ from .parallel import *
@@ -0,0 +1,255 @@
1
+ #!/usr/bin/env python3
2
+ import argparse
3
+ import os
4
+ import sys
5
+ from pathlib import Path
6
+ import traceback
7
+
8
+ # Import your existing functions
9
+ from .cos_core_ops import (
10
+ list_all_files_under_cos_dir_cli,
11
+ download_cos_file,
12
+ download_cos_dir_cli,
13
+ delete_cos_file,
14
+ upload_file2cos,
15
+ upload_dir2cos_cli,
16
+ _split_cosdir,
17
+ _split_cospath,
18
+ )
19
+
20
+
21
+ def to_absolute_path(path: str) -> str:
22
+ """
23
+ Convert a given path (which may contain ~, ., or ..)
24
+ into an absolute, normalized path.
25
+
26
+ Examples:
27
+ ~/project → /home/jiaqi/project
28
+ ./data/.. → /current/working/dir
29
+ ../logs → /parent/of/current/working/dir/logs
30
+ """
31
+ # 1. Expand ~ (home directory)
32
+ expanded = os.path.expanduser(path)
33
+ # 2. Convert to absolute path (resolves . and ..)
34
+ absolute = os.path.abspath(expanded)
35
+ # 3. Normalize redundant slashes, etc.
36
+ normalized = os.path.normpath(absolute)
37
+ return normalized
38
+
39
+
40
+ def get_cos_config():
41
+ """Get COS config from environment variables"""
42
+ try:
43
+ return {
44
+ 'secret_id': os.environ["COS_SECRET_ID"],
45
+ 'secret_key': os.environ["COS_SECRET_KEY"],
46
+ 'region': os.environ["COS_REGION"],
47
+ }
48
+ except KeyError as e:
49
+ print(f"Error: Missing environment variable {e}")
50
+ print("Please set COS_SECRET_ID, COS_SECRET_KEY, and COS_REGION")
51
+ sys.exit(1)
52
+
53
+
54
+ def list_files():
55
+ """CLI command to list files in COS directory"""
56
+ parser = argparse.ArgumentParser(description='List files in COS directory')
57
+ parser.add_argument('cos_dir', help='COS directory path (cos://bucket/prefix)')
58
+ parser.add_argument('-f', '--list_result_save_path', help='Path to save list result', default="list_result.txt")
59
+ parser.add_argument('--verbose', action='store_true', help='Verbose output')
60
+
61
+ args = parser.parse_args()
62
+ config = get_cos_config()
63
+
64
+ try:
65
+ list_all_files_under_cos_dir_cli(
66
+ cos_dir=args.cos_dir,
67
+ config=config,
68
+ verbose=args.verbose,
69
+ list_result_save_path=args.list_result_save_path,
70
+ )
71
+ except Exception as e:
72
+ print(f"Error: {e}")
73
+ sys.exit(1)
74
+
75
+
76
+ def download_file():
77
+ """CLI command to download file from COS"""
78
+ parser = argparse.ArgumentParser(description='Download file from COS')
79
+ parser.add_argument('cos_path', help='COS file path (cos://bucket/path/file.txt)')
80
+ parser.add_argument('given_path', help='Local file path to save to')
81
+ parser.add_argument('--part_size', type=int, help='The size of the part to download.(Unit: MB)', default=1)
82
+ parser.add_argument('--max_thread', '-j', type=int, help='The maximum number of threads to use.', default=30)
83
+ parser.add_argument('--enable_crc', action='store_true', help='Whether to enable CRC checksum.', default=False)
84
+ parser.add_argument('--num_retry', '-r', type=int, help='The number of times to retry the download.', default=1)
85
+ args = parser.parse_args()
86
+ config = get_cos_config()
87
+ is_dir = False
88
+ if args.given_path.endswith("/"):
89
+ is_dir = True
90
+ given_path = to_absolute_path(args.given_path)
91
+
92
+ _, _, file_name = _split_cospath(args.cos_path)
93
+ if os.path.isdir(given_path):
94
+ local_file_path = os.path.join(given_path, file_name)
95
+ elif os.path.isfile(given_path):
96
+ local_file_path = given_path
97
+ else:
98
+ if is_dir:
99
+ local_file_path = os.path.join(given_path, file_name)
100
+ os.makedirs(local_file_path, exist_ok=True)
101
+ else:
102
+ local_file_path = given_path
103
+ os.makedirs(os.path.dirname(local_file_path), exist_ok=True)
104
+
105
+ try:
106
+ download_cos_file(
107
+ cos_path=args.cos_path,
108
+ local_file_path=local_file_path,
109
+ config=config,
110
+ part_size=args.part_size,
111
+ max_thread=args.max_thread,
112
+ enable_crc=args.enable_crc,
113
+ num_retry=args.num_retry,
114
+ )
115
+ print(f"Downloaded {args.cos_path} to {local_file_path}")
116
+ except Exception as e:
117
+ print(f"Error: {e}")
118
+ traceback.print_exc()
119
+ sys.exit(1)
120
+
121
+
122
+ def download_dir():
123
+ """CLI command to download file from COS"""
124
+ parser = argparse.ArgumentParser(description='Download file from COS')
125
+ parser.add_argument('cos_dir', help='COS dir path (cos://bucket/path/)')
126
+ parser.add_argument('given_local_dir', help='Local dir to save to')
127
+ parser.add_argument('--max_thread', '-j', help='The maximum number of threads to use.', default=30)
128
+ parser.add_argument('--flat', '-f', action='store_true', help='whether to download the cos dir flatly', default=False)
129
+ args = parser.parse_args()
130
+ config = get_cos_config()
131
+ given_local_dir = to_absolute_path(args.given_local_dir)
132
+ _, prefix = _split_cosdir(args.cos_dir)
133
+ cos_dirname = prefix.split("/")[-1]
134
+ if args.flat:
135
+ given_local_dir = given_local_dir
136
+ else:
137
+ given_local_dir = os.path.join(given_local_dir, cos_dirname)
138
+ os.makedirs(given_local_dir, exist_ok=True)
139
+
140
+ try:
141
+ download_cos_dir_cli(
142
+ cos_dir=args.cos_dir,
143
+ local_dir=given_local_dir,
144
+ config=config,
145
+ max_thread=args.max_thread,
146
+ flat=args.flat,
147
+ )
148
+ print(f"Downloaded {args.cos_dir} to {given_local_dir}")
149
+ except Exception as e:
150
+ print(f"Error: {e}")
151
+ traceback.print_exc()
152
+ sys.exit(1)
153
+
154
+
155
+ def upload_file():
156
+ """CLI command to upload file to COS"""
157
+ parser = argparse.ArgumentParser(description='Upload file to COS')
158
+ parser.add_argument('local_path', help='Local file path to upload')
159
+ parser.add_argument('cos_path', help='COS file path (cos://bucket/path/file.txt)')
160
+ parser.add_argument('--part_size', type=int, help='The size of the part to upload.(Unit: MB)', default=1)
161
+ parser.add_argument('--max_thread', '-j', type=int, help='The maximum number of threads to use.', default=30)
162
+ parser.add_argument('--enable_md5', action='store_true', help='Whether to enable MD5 checksum.', default=False)
163
+ args = parser.parse_args()
164
+ config = get_cos_config()
165
+
166
+ is_dir = False
167
+ if args.cos_path.endswith("/"):
168
+ is_dir = True
169
+
170
+ if not os.path.exists(to_absolute_path(args.local_path)):
171
+ raise FileNotFoundError(f"File {args.local_path} not found")
172
+
173
+ local_filename = os.path.basename(args.local_path)
174
+ if is_dir:
175
+ cos_path = f"{args.cos_path}{local_filename}"
176
+ else:
177
+ cos_path = args.cos_path
178
+
179
+ try:
180
+ upload_file2cos(
181
+ local_file_path=args.local_path,
182
+ cos_save_path=cos_path,
183
+ config=config,
184
+ part_size=args.part_size,
185
+ max_thread=args.max_thread,
186
+ enable_md5=args.enable_md5,
187
+ )
188
+ print(f"Uploaded {args.local_path} to {cos_path}")
189
+ except Exception as e:
190
+ print(f"Error: {e}")
191
+ print(f"cos save path: {cos_path}")
192
+ traceback.print_exc()
193
+ sys.exit(1)
194
+
195
+
196
+ def upload_dir():
197
+ """CLI command to upload dir to COS"""
198
+ parser = argparse.ArgumentParser(description='Upload dir to COS')
199
+ parser.add_argument('local_dir', help='Local dir to upload')
200
+ parser.add_argument('cos_dir', help='COS dir path (cos://bucket/path/)')
201
+ parser.add_argument('--part_size', help='The size of the part to upload.(Unit: MB)', default=1)
202
+ parser.add_argument('--max_thread', '-j', help='The maximum number of threads to use.', default=30)
203
+ parser.add_argument('--enable_md5', help='Whether to enable MD5 checksum.', default=False)
204
+ parser.add_argument('--flat', '-f', help='whether to upload the local dir flatly', default=False)
205
+ parser.add_argument('--verbose', action='store_true', help='Verbose output')
206
+ args = parser.parse_args()
207
+ config = get_cos_config()
208
+
209
+
210
+ local_upload_dir = to_absolute_path(args.local_dir)
211
+ if not os.path.exists(local_upload_dir):
212
+ raise FileNotFoundError(f"Dir {local_upload_dir} not found")
213
+
214
+ try:
215
+ upload_dir2cos_cli(
216
+ local_upload_dir=local_upload_dir,
217
+ cos_dir=args.cos_dir,
218
+ config=config,
219
+ part_size=args.part_size,
220
+ max_thread=args.max_thread,
221
+ enable_md5=args.enable_md5,
222
+ flat=args.flat,
223
+ )
224
+ print(f"Uploaded {args.local_dir} to {args.cos_dir}")
225
+ except Exception as e:
226
+ print(f"Error: {e}")
227
+ sys.exit(1)
228
+
229
+
230
+
231
+
232
+ def delete_file():
233
+ """CLI command to delete file from COS"""
234
+ parser = argparse.ArgumentParser(description='Delete file from COS')
235
+ parser.add_argument('cos_path', help='COS file path (cos://bucket/path/file.txt)')
236
+ parser.add_argument('--confirm', action='store_true', help='Confirm deletion')
237
+
238
+ args = parser.parse_args()
239
+ config = get_cos_config()
240
+
241
+ if not args.confirm:
242
+ response = input(f"Are you sure you want to delete {args.cos_path}? (y/N): ")
243
+ if response.lower() != 'y':
244
+ print("Cancelled")
245
+ return
246
+
247
+ try:
248
+ delete_cos_file(
249
+ cos_path=args.cos_path,
250
+ config=config,
251
+ )
252
+ print(f"Deleted {args.cos_path}")
253
+ except Exception as e:
254
+ print(f"Error: {e}")
255
+ sys.exit(1)