tamar-file-hub-client 0.2.1__py3-none-any.whl → 0.2.3__py3-none-any.whl

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.

Potentially problematic release.


This version of tamar-file-hub-client might be problematic. Click here for more details.

@@ -9,11 +9,61 @@ import asyncio
9
9
  import aiohttp
10
10
  import requests
11
11
  from pathlib import Path
12
- from typing import Union, BinaryIO, Optional, Callable, Dict, Any, AsyncGenerator
12
+ from typing import Union, BinaryIO, Optional, Callable, Dict, Any, AsyncGenerator, Tuple
13
13
  from dataclasses import dataclass
14
14
  import hashlib
15
15
 
16
16
 
17
+ def detect_storage_type(url: str) -> str:
18
+ """
19
+ 根据URL检测存储类型
20
+
21
+ Args:
22
+ url: 上传URL
23
+
24
+ Returns:
25
+ 存储类型: 'gcs'、'oss' 或 'unknown'
26
+ """
27
+ if 'storage.googleapis.com' in url or 'storage.cloud.google.com' in url:
28
+ return 'gcs'
29
+ elif 'aliyuncs.com' in url:
30
+ return 'oss'
31
+ else:
32
+ return 'gcs'
33
+
34
+
35
+ def get_forbid_overwrite_headers(url: str, forbid_overwrite: bool = False) -> Dict[str, str]:
36
+ """
37
+ 获取防止覆盖的headers
38
+
39
+ Args:
40
+ url: 上传URL
41
+ forbid_overwrite: 是否防止覆盖
42
+
43
+ Returns:
44
+ 包含防止覆盖header的字典
45
+
46
+ Note:
47
+ - GCS: 需要在HTTP header中添加 x-goog-if-generation-match: 0
48
+ - OSS: 需要在HTTP header中添加 x-oss-forbid-overwrite: true
49
+ """
50
+ if not forbid_overwrite:
51
+ return {}
52
+
53
+ storage_type = detect_storage_type(url)
54
+
55
+ if storage_type == 'gcs':
56
+ return {
57
+ 'x-goog-if-generation-match': '0'
58
+ }
59
+ elif storage_type == 'oss':
60
+ return {
61
+ 'x-oss-forbid-overwrite': 'true'
62
+ }
63
+ else:
64
+ return {}
65
+
66
+
17
67
  @dataclass
18
68
  class UploadProgress:
19
69
  """上传进度信息"""
@@ -127,10 +177,11 @@ class HttpUploader:
127
177
  progress_callback: Optional[Callable[[UploadProgress], None]] = None,
128
178
  total_size: Optional[int] = None,
129
179
  is_resume: bool = False,
180
+ forbid_overwrite: bool = False,
130
181
  ) -> requests.Response:
131
182
  """
132
183
  上传文件到指定URL
133
-
184
+
134
185
  Args:
135
186
  url: 上传URL
136
187
  content: 文件内容
@@ -138,9 +189,15 @@ class HttpUploader:
138
189
  headers: 请求头
139
190
  progress_callback: 进度回调函数
140
191
  is_resume: 是否断点续传
192
+ forbid_overwrite: 是否防止覆盖(添加相应的header)
141
193
  """
142
194
  headers = headers or {}
143
195
 
196
+ # 添加防止覆盖的headers
197
+ if forbid_overwrite:
198
+ forbid_headers = get_forbid_overwrite_headers(url, forbid_overwrite)
199
+ headers.update(forbid_headers)
200
+
144
201
  # 获取文件大小(不生成 chunk,避免提前读取)
145
202
  final_total_size = self._calculate_total_size(content) if total_size is None else total_size
146
203
 
@@ -360,19 +417,26 @@ class AsyncHttpUploader:
360
417
  progress_callback: Optional[Callable[[UploadProgress], None]] = None,
361
418
  total_size: Optional[int] = None,
362
419
  is_resume: bool = False,
420
+ forbid_overwrite: bool = False,
363
421
  ) -> aiohttp.ClientResponse:
364
422
  """
365
423
  异步上传文件到指定URL
366
-
424
+
367
425
  Args:
368
426
  url: 上传URL
369
427
  content: 文件内容
370
428
  headers: 请求头
371
429
  progress_callback: 进度回调函数
372
430
  is_resume: 是否断点续传
431
+ forbid_overwrite: 是否防止覆盖(添加相应的header)
373
432
  """
374
433
  headers = headers or {}
375
434
 
435
+ # 添加防止覆盖的headers
436
+ if forbid_overwrite:
437
+ forbid_headers = get_forbid_overwrite_headers(url, forbid_overwrite)
438
+ headers.update(forbid_headers)
439
+
376
440
  # 获取文件大小(避免读取内容)
377
441
  final_total_size = total_size or await self._calculate_total_size(content)
378
442