fiuai-s3 0.4.1__tar.gz → 0.4.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.
Potentially problematic release.
This version of fiuai-s3 might be problematic. Click here for more details.
- {fiuai_s3-0.4.1 → fiuai_s3-0.4.3}/PKG-INFO +1 -1
- {fiuai_s3-0.4.1 → fiuai_s3-0.4.3}/pyproject.toml +1 -1
- {fiuai_s3-0.4.1 → fiuai_s3-0.4.3}/src/fiuai_s3/__init__.py +1 -1
- {fiuai_s3-0.4.1 → fiuai_s3-0.4.3}/src/fiuai_s3/alicloud/alicloud_storage.py +131 -2
- {fiuai_s3-0.4.1 → fiuai_s3-0.4.3}/src/fiuai_s3/minio/minio_storage.py +111 -2
- {fiuai_s3-0.4.1 → fiuai_s3-0.4.3}/src/fiuai_s3/object_storage.py +112 -1
- {fiuai_s3-0.4.1 → fiuai_s3-0.4.3}/.gitignore +0 -0
- {fiuai_s3-0.4.1 → fiuai_s3-0.4.3}/LICENSE +0 -0
- {fiuai_s3-0.4.1 → fiuai_s3-0.4.3}/README.md +0 -0
- {fiuai_s3-0.4.1 → fiuai_s3-0.4.3}/src/fiuai_s3/alicloud/__init__.py +0 -0
- {fiuai_s3-0.4.1 → fiuai_s3-0.4.3}/src/fiuai_s3/minio/__init__.py +0 -0
- {fiuai_s3-0.4.1 → fiuai_s3-0.4.3}/src/fiuai_s3/type.py +0 -0
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
from .object_storage import ObjectStorage, ObjectStorageFactory, StorageConfig
|
|
9
9
|
from .type import DocFileObject, DocSourceFrom, DocFileType
|
|
10
10
|
|
|
11
|
-
__version__ = "0.
|
|
11
|
+
__version__ = "0.4.1"
|
|
12
12
|
__all__ = ["ObjectStorage", "ObjectStorageFactory", "StorageConfig", "DocFileObject", "DocSourceFrom", "DocFileType"]
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import os
|
|
9
9
|
import logging
|
|
10
|
-
from typing import List, Optional
|
|
10
|
+
from typing import List, Optional, Dict
|
|
11
11
|
import oss2
|
|
12
12
|
from ..object_storage import ObjectStorage, StorageConfig
|
|
13
13
|
from oss2.headers import OSS_OBJECT_TAGGING
|
|
@@ -37,6 +37,32 @@ class AliCloudStorage(ObjectStorage):
|
|
|
37
37
|
bucket_name=config.bucket_name
|
|
38
38
|
)
|
|
39
39
|
|
|
40
|
+
def upload_temp_file(self, object_key: str, data: bytes, tmppath: str = None) -> bool:
|
|
41
|
+
"""上传临时文件到阿里云OSS
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
object_key: 对象存储中的key
|
|
45
|
+
data: 文件数据
|
|
46
|
+
tmppath: 临时文件路径, 如果为空,则使用默认临时目录
|
|
47
|
+
Returns:
|
|
48
|
+
bool: 是否上传成功
|
|
49
|
+
"""
|
|
50
|
+
_path = f"{self.config.temp_dir}/{object_key}" if not tmppath else f"{tmppath.rstrip('/')}/{object_key}"
|
|
51
|
+
return self.upload_file(_path, data)
|
|
52
|
+
|
|
53
|
+
def download_temp_file(self, object_key: str, tmppath: str = None) -> bytes:
|
|
54
|
+
"""从阿里云OSS下载临时文件
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
object_key: 对象存储中的key
|
|
58
|
+
tmppath: 临时文件路径, 如果为空,则使用默认临时目录
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
bytes: 文件内容,失败时返回None
|
|
62
|
+
"""
|
|
63
|
+
_path = f"{self.config.temp_dir}/{object_key}" if not tmppath else f"{tmppath.rstrip('/')}/{object_key}"
|
|
64
|
+
return self.download_file(_path)
|
|
65
|
+
|
|
40
66
|
def upload_file(self, object_key: str, data: bytes) -> bool:
|
|
41
67
|
"""上传文件到阿里云OSS
|
|
42
68
|
|
|
@@ -149,4 +175,107 @@ class AliCloudStorage(ObjectStorage):
|
|
|
149
175
|
return files
|
|
150
176
|
except Exception as e:
|
|
151
177
|
logger.error(f"列出单据文件失败: {str(e)}")
|
|
152
|
-
return []
|
|
178
|
+
return []
|
|
179
|
+
|
|
180
|
+
def generate_presigned_url(self, object_key: str, method: str = "GET", expires_in: int = 3600,
|
|
181
|
+
response_headers: Optional[Dict[str, str]] = None,
|
|
182
|
+
auth_tenant_id: Optional[str] = None,
|
|
183
|
+
auth_company_id: Optional[str] = None,
|
|
184
|
+
doc_id: Optional[str] = None) -> Optional[str]:
|
|
185
|
+
"""
|
|
186
|
+
生成预签名URL
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
object_key: 对象存储中的key
|
|
190
|
+
method: HTTP方法,支持 GET、PUT、POST、DELETE
|
|
191
|
+
expires_in: 过期时间(秒),默认3600秒(1小时)
|
|
192
|
+
response_headers: 响应头设置
|
|
193
|
+
auth_tenant_id: 租户ID(可选,若不传则用实例属性)
|
|
194
|
+
auth_company_id: 公司ID(可选,若不传则用实例属性)
|
|
195
|
+
doc_id: 单据ID(可选,若不传则用实例属性)
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
Optional[str]: 预签名URL,失败时返回None
|
|
199
|
+
"""
|
|
200
|
+
try:
|
|
201
|
+
# 验证参数
|
|
202
|
+
if not object_key:
|
|
203
|
+
raise ValueError("object_key 不能为空")
|
|
204
|
+
|
|
205
|
+
if method.upper() not in ["GET", "PUT", "POST", "DELETE"]:
|
|
206
|
+
raise ValueError(f"不支持的HTTP方法: {method}")
|
|
207
|
+
|
|
208
|
+
if expires_in <= 0 or expires_in > 604800: # 最大7天
|
|
209
|
+
raise ValueError("过期时间必须在1秒到604800秒(7天)之间")
|
|
210
|
+
|
|
211
|
+
# 生成预签名URL
|
|
212
|
+
from datetime import datetime, timedelta
|
|
213
|
+
|
|
214
|
+
if method.upper() == "GET":
|
|
215
|
+
url = self.bucket.sign_url(
|
|
216
|
+
method='GET',
|
|
217
|
+
key=object_key,
|
|
218
|
+
expires=expires_in,
|
|
219
|
+
headers=response_headers
|
|
220
|
+
)
|
|
221
|
+
elif method.upper() == "PUT":
|
|
222
|
+
url = self.bucket.sign_url(
|
|
223
|
+
method='PUT',
|
|
224
|
+
key=object_key,
|
|
225
|
+
expires=expires_in
|
|
226
|
+
)
|
|
227
|
+
elif method.upper() == "POST":
|
|
228
|
+
url = self.bucket.sign_url(
|
|
229
|
+
method='POST',
|
|
230
|
+
key=object_key,
|
|
231
|
+
expires=expires_in
|
|
232
|
+
)
|
|
233
|
+
elif method.upper() == "DELETE":
|
|
234
|
+
url = self.bucket.sign_url(
|
|
235
|
+
method='DELETE',
|
|
236
|
+
key=object_key,
|
|
237
|
+
expires=expires_in
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
logger.info(f"生成预签名URL成功: {object_key}, method: {method}")
|
|
241
|
+
return url
|
|
242
|
+
|
|
243
|
+
except Exception as e:
|
|
244
|
+
logger.error(f"生成预签名URL失败: {str(e)}")
|
|
245
|
+
return None
|
|
246
|
+
|
|
247
|
+
def generate_presigned_doc_url(self, filename: str, method: str = "GET", expires_in: int = 3600,
|
|
248
|
+
response_headers: Optional[Dict[str, str]] = None,
|
|
249
|
+
auth_tenant_id: Optional[str] = None,
|
|
250
|
+
auth_company_id: Optional[str] = None,
|
|
251
|
+
doc_id: Optional[str] = None) -> Optional[str]:
|
|
252
|
+
"""
|
|
253
|
+
生成单据文件的预签名URL
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
filename: 文件名
|
|
257
|
+
method: HTTP方法,支持 GET、PUT、POST、DELETE
|
|
258
|
+
expires_in: 过期时间(秒),默认3600秒(1小时)
|
|
259
|
+
response_headers: 响应头设置
|
|
260
|
+
auth_tenant_id: 租户ID(可选,若不传则用实例属性)
|
|
261
|
+
auth_company_id: 公司ID(可选,若不传则用实例属性)
|
|
262
|
+
doc_id: 单据ID(可选,若不传则用实例属性)
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
Optional[str]: 预签名URL,失败时返回None
|
|
266
|
+
"""
|
|
267
|
+
try:
|
|
268
|
+
# 构建单据文件路径
|
|
269
|
+
object_key = self._build_doc_path(filename, auth_tenant_id, auth_company_id, doc_id)
|
|
270
|
+
|
|
271
|
+
# 调用通用预签名URL生成方法
|
|
272
|
+
return self.generate_presigned_url(
|
|
273
|
+
object_key=object_key,
|
|
274
|
+
method=method,
|
|
275
|
+
expires_in=expires_in,
|
|
276
|
+
response_headers=response_headers
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
except Exception as e:
|
|
280
|
+
logger.error(f"生成单据文件预签名URL失败: {str(e)}")
|
|
281
|
+
return None
|
|
@@ -81,12 +81,15 @@ class MinioStorage(ObjectStorage):
|
|
|
81
81
|
_path = f"{self.config.temp_dir}/{object_key}" if not tmppath else f"{tmppath.rstrip('/')}/{object_key}"
|
|
82
82
|
return self.upload_file(_path, data)
|
|
83
83
|
|
|
84
|
-
def download_temp_file(self, object_key: str, tmppath: str = None) ->
|
|
84
|
+
def download_temp_file(self, object_key: str, tmppath: str = None) -> bytes:
|
|
85
85
|
"""下载临时文件
|
|
86
86
|
|
|
87
87
|
Args:
|
|
88
88
|
object_key: 对象存储中的key
|
|
89
89
|
tmppath: 临时文件路径, 如果为空,则使用默认临时目录
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
bytes: 文件内容,失败时返回None
|
|
90
93
|
"""
|
|
91
94
|
_path = f"{self.config.temp_dir}/{object_key}" if not tmppath else f"{tmppath.rstrip('/')}/{object_key}"
|
|
92
95
|
return self.download_file(_path)
|
|
@@ -257,4 +260,110 @@ class MinioStorage(ObjectStorage):
|
|
|
257
260
|
return files
|
|
258
261
|
except S3Error as e:
|
|
259
262
|
logger.error(f"list doc files failed: {str(e)}")
|
|
260
|
-
return []
|
|
263
|
+
return []
|
|
264
|
+
|
|
265
|
+
def generate_presigned_url(self, object_key: str, method: str = "GET", expires_in: int = 3600,
|
|
266
|
+
response_headers: Optional[Dict[str, str]] = None,
|
|
267
|
+
auth_tenant_id: Optional[str] = None,
|
|
268
|
+
auth_company_id: Optional[str] = None,
|
|
269
|
+
doc_id: Optional[str] = None) -> Optional[str]:
|
|
270
|
+
"""
|
|
271
|
+
生成预签名URL
|
|
272
|
+
|
|
273
|
+
Args:
|
|
274
|
+
object_key: 对象存储中的key
|
|
275
|
+
method: HTTP方法,支持 GET、PUT、POST、DELETE
|
|
276
|
+
expires_in: 过期时间(秒),默认3600秒(1小时)
|
|
277
|
+
response_headers: 响应头设置
|
|
278
|
+
auth_tenant_id: 租户ID(可选,若不传则用实例属性)
|
|
279
|
+
auth_company_id: 公司ID(可选,若不传则用实例属性)
|
|
280
|
+
doc_id: 单据ID(可选,若不传则用实例属性)
|
|
281
|
+
|
|
282
|
+
Returns:
|
|
283
|
+
Optional[str]: 预签名URL,失败时返回None
|
|
284
|
+
"""
|
|
285
|
+
try:
|
|
286
|
+
# 验证参数
|
|
287
|
+
if not object_key:
|
|
288
|
+
raise ValueError("object_key 不能为空")
|
|
289
|
+
|
|
290
|
+
if method.upper() not in ["GET", "PUT", "POST", "DELETE"]:
|
|
291
|
+
raise ValueError(f"不支持的HTTP方法: {method}")
|
|
292
|
+
|
|
293
|
+
if expires_in <= 0 or expires_in > 604800: # 最大7天
|
|
294
|
+
raise ValueError("过期时间必须在1秒到604800秒(7天)之间")
|
|
295
|
+
|
|
296
|
+
# 生成预签名URL
|
|
297
|
+
from datetime import timedelta
|
|
298
|
+
|
|
299
|
+
if method.upper() == "GET":
|
|
300
|
+
url = self.client.presigned_get_object(
|
|
301
|
+
bucket_name=self.bucket_name,
|
|
302
|
+
object_name=object_key,
|
|
303
|
+
expires=timedelta(seconds=expires_in),
|
|
304
|
+
response_headers=response_headers
|
|
305
|
+
)
|
|
306
|
+
elif method.upper() == "PUT":
|
|
307
|
+
url = self.client.presigned_put_object(
|
|
308
|
+
bucket_name=self.bucket_name,
|
|
309
|
+
object_name=object_key,
|
|
310
|
+
expires=timedelta(seconds=expires_in)
|
|
311
|
+
)
|
|
312
|
+
elif method.upper() == "POST":
|
|
313
|
+
url = self.client.presigned_post_policy(
|
|
314
|
+
bucket_name=self.bucket_name,
|
|
315
|
+
object_name=object_key,
|
|
316
|
+
expires=timedelta(seconds=expires_in)
|
|
317
|
+
)
|
|
318
|
+
elif method.upper() == "DELETE":
|
|
319
|
+
url = self.client.presigned_delete_object(
|
|
320
|
+
bucket_name=self.bucket_name,
|
|
321
|
+
object_name=object_key,
|
|
322
|
+
expires=timedelta(seconds=expires_in)
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
logger.info(f"生成预签名URL成功: {object_key}, method: {method}")
|
|
326
|
+
return url
|
|
327
|
+
|
|
328
|
+
except S3Error as e:
|
|
329
|
+
logger.error(f"生成预签名URL失败: {str(e)}")
|
|
330
|
+
return None
|
|
331
|
+
except Exception as e:
|
|
332
|
+
logger.error(f"生成预签名URL异常: {str(e)}")
|
|
333
|
+
return None
|
|
334
|
+
|
|
335
|
+
def generate_presigned_doc_url(self, filename: str, method: str = "GET", expires_in: int = 3600,
|
|
336
|
+
response_headers: Optional[Dict[str, str]] = None,
|
|
337
|
+
auth_tenant_id: Optional[str] = None,
|
|
338
|
+
auth_company_id: Optional[str] = None,
|
|
339
|
+
doc_id: Optional[str] = None) -> Optional[str]:
|
|
340
|
+
"""
|
|
341
|
+
生成单据文件的预签名URL
|
|
342
|
+
|
|
343
|
+
Args:
|
|
344
|
+
filename: 文件名
|
|
345
|
+
method: HTTP方法,支持 GET、PUT、POST、DELETE
|
|
346
|
+
expires_in: 过期时间(秒),默认3600秒(1小时)
|
|
347
|
+
response_headers: 响应头设置
|
|
348
|
+
auth_tenant_id: 租户ID(可选,若不传则用实例属性)
|
|
349
|
+
auth_company_id: 公司ID(可选,若不传则用实例属性)
|
|
350
|
+
doc_id: 单据ID(可选,若不传则用实例属性)
|
|
351
|
+
|
|
352
|
+
Returns:
|
|
353
|
+
Optional[str]: 预签名URL,失败时返回None
|
|
354
|
+
"""
|
|
355
|
+
try:
|
|
356
|
+
# 构建单据文件路径
|
|
357
|
+
object_key = self._build_doc_path(filename, auth_tenant_id, auth_company_id, doc_id)
|
|
358
|
+
|
|
359
|
+
# 调用通用预签名URL生成方法
|
|
360
|
+
return self.generate_presigned_url(
|
|
361
|
+
object_key=object_key,
|
|
362
|
+
method=method,
|
|
363
|
+
expires_in=expires_in,
|
|
364
|
+
response_headers=response_headers
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
except Exception as e:
|
|
368
|
+
logger.error(f"生成单据文件预签名URL失败: {str(e)}")
|
|
369
|
+
return None
|
|
@@ -58,12 +58,15 @@ class ObjectStorage(ABC):
|
|
|
58
58
|
pass
|
|
59
59
|
|
|
60
60
|
@abstractmethod
|
|
61
|
-
def download_temp_file(self, object_key: str, tmppath: str = None) ->
|
|
61
|
+
def download_temp_file(self, object_key: str, tmppath: str = None) -> bytes:
|
|
62
62
|
"""下载临时文件
|
|
63
63
|
|
|
64
64
|
Args:
|
|
65
65
|
object_key: 对象存储中的key
|
|
66
66
|
tmppath: 临时文件路径, 如果为空,则使用默认临时目录
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
bytes: 文件内容,失败时返回None
|
|
67
70
|
"""
|
|
68
71
|
pass
|
|
69
72
|
|
|
@@ -163,6 +166,52 @@ class ObjectStorage(ABC):
|
|
|
163
166
|
"""
|
|
164
167
|
pass
|
|
165
168
|
|
|
169
|
+
@abstractmethod
|
|
170
|
+
def generate_presigned_url(self, object_key: str, method: str = "GET", expires_in: int = 3600,
|
|
171
|
+
response_headers: Optional[Dict[str, str]] = None,
|
|
172
|
+
auth_tenant_id: Optional[str] = None,
|
|
173
|
+
auth_company_id: Optional[str] = None,
|
|
174
|
+
doc_id: Optional[str] = None) -> Optional[str]:
|
|
175
|
+
"""
|
|
176
|
+
生成预签名URL
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
object_key: 对象存储中的key,如果为空则使用单据路径
|
|
180
|
+
method: HTTP方法,支持 GET、PUT、POST、DELETE
|
|
181
|
+
expires_in: 过期时间(秒),默认3600秒(1小时)
|
|
182
|
+
response_headers: 响应头设置
|
|
183
|
+
auth_tenant_id: 租户ID(可选,若不传则用实例属性)
|
|
184
|
+
auth_company_id: 公司ID(可选,若不传则用实例属性)
|
|
185
|
+
doc_id: 单据ID(可选,若不传则用实例属性)
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
Optional[str]: 预签名URL,失败时返回None
|
|
189
|
+
"""
|
|
190
|
+
pass
|
|
191
|
+
|
|
192
|
+
@abstractmethod
|
|
193
|
+
def generate_presigned_doc_url(self, filename: str, method: str = "GET", expires_in: int = 3600,
|
|
194
|
+
response_headers: Optional[Dict[str, str]] = None,
|
|
195
|
+
auth_tenant_id: Optional[str] = None,
|
|
196
|
+
auth_company_id: Optional[str] = None,
|
|
197
|
+
doc_id: Optional[str] = None) -> Optional[str]:
|
|
198
|
+
"""
|
|
199
|
+
生成单据文件的预签名URL
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
filename: 文件名
|
|
203
|
+
method: HTTP方法,支持 GET、PUT、POST、DELETE
|
|
204
|
+
expires_in: 过期时间(秒),默认3600秒(1小时)
|
|
205
|
+
response_headers: 响应头设置
|
|
206
|
+
auth_tenant_id: 租户ID(可选,若不传则用实例属性)
|
|
207
|
+
auth_company_id: 公司ID(可选,若不传则用实例属性)
|
|
208
|
+
doc_id: 单据ID(可选,若不传则用实例属性)
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
Optional[str]: 预签名URL,失败时返回None
|
|
212
|
+
"""
|
|
213
|
+
pass
|
|
214
|
+
|
|
166
215
|
class ObjectStorageFactory:
|
|
167
216
|
"""对象存储工厂类"""
|
|
168
217
|
|
|
@@ -253,6 +302,68 @@ class ObjectStorageFactory:
|
|
|
253
302
|
return MinioStorage(config, auth_tenant_id, auth_company_id, doc_id)
|
|
254
303
|
else:
|
|
255
304
|
raise ValueError(f"不支持的存储提供商: {provider}")
|
|
305
|
+
|
|
306
|
+
@classmethod
|
|
307
|
+
def generate_presigned_url(cls, object_key: str, method: str = "GET", expires_in: int = 3600,
|
|
308
|
+
response_headers: Optional[Dict[str, str]] = None,
|
|
309
|
+
auth_tenant_id: Optional[str] = None,
|
|
310
|
+
auth_company_id: Optional[str] = None,
|
|
311
|
+
doc_id: Optional[str] = None) -> Optional[str]:
|
|
312
|
+
"""通过工厂类生成预签名URL
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
object_key: 对象存储中的key
|
|
316
|
+
method: HTTP方法,支持 GET、PUT、POST、DELETE
|
|
317
|
+
expires_in: 过期时间(秒),默认3600秒(1小时)
|
|
318
|
+
response_headers: 响应头设置
|
|
319
|
+
auth_tenant_id: 租户ID(可选)
|
|
320
|
+
auth_company_id: 公司ID(可选)
|
|
321
|
+
doc_id: 单据ID(可选)
|
|
322
|
+
|
|
323
|
+
Returns:
|
|
324
|
+
Optional[str]: 预签名URL,失败时返回None
|
|
325
|
+
"""
|
|
326
|
+
storage = cls.get_instance()
|
|
327
|
+
return storage.generate_presigned_url(
|
|
328
|
+
object_key=object_key,
|
|
329
|
+
method=method,
|
|
330
|
+
expires_in=expires_in,
|
|
331
|
+
response_headers=response_headers,
|
|
332
|
+
auth_tenant_id=auth_tenant_id,
|
|
333
|
+
auth_company_id=auth_company_id,
|
|
334
|
+
doc_id=doc_id
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
@classmethod
|
|
338
|
+
def generate_presigned_doc_url(cls, filename: str, method: str = "GET", expires_in: int = 3600,
|
|
339
|
+
response_headers: Optional[Dict[str, str]] = None,
|
|
340
|
+
auth_tenant_id: Optional[str] = None,
|
|
341
|
+
auth_company_id: Optional[str] = None,
|
|
342
|
+
doc_id: Optional[str] = None) -> Optional[str]:
|
|
343
|
+
"""通过工厂类生成单据文件的预签名URL
|
|
344
|
+
|
|
345
|
+
Args:
|
|
346
|
+
filename: 文件名
|
|
347
|
+
method: HTTP方法,支持 GET、PUT、POST、DELETE
|
|
348
|
+
expires_in: 过期时间(秒),默认3600秒(1小时)
|
|
349
|
+
response_headers: 响应头设置
|
|
350
|
+
auth_tenant_id: 租户ID(可选)
|
|
351
|
+
auth_company_id: 公司ID(可选)
|
|
352
|
+
doc_id: 单据ID(可选)
|
|
353
|
+
|
|
354
|
+
Returns:
|
|
355
|
+
Optional[str]: 预签名URL,失败时返回None
|
|
356
|
+
"""
|
|
357
|
+
storage = cls.get_instance()
|
|
358
|
+
return storage.generate_presigned_doc_url(
|
|
359
|
+
filename=filename,
|
|
360
|
+
method=method,
|
|
361
|
+
expires_in=expires_in,
|
|
362
|
+
response_headers=response_headers,
|
|
363
|
+
auth_tenant_id=auth_tenant_id,
|
|
364
|
+
auth_company_id=auth_company_id,
|
|
365
|
+
doc_id=doc_id
|
|
366
|
+
)
|
|
256
367
|
|
|
257
368
|
# 导出工厂类
|
|
258
369
|
__all__ = ['ObjectStorage', 'ObjectStorageFactory', 'StorageConfig']
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|