fiuai-s3 0.4.1__py3-none-any.whl → 0.4.2__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 fiuai-s3 might be problematic. Click here for more details.

fiuai_s3/__init__.py CHANGED
@@ -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.3.9"
11
+ __version__ = "0.4.1"
12
12
  __all__ = ["ObjectStorage", "ObjectStorageFactory", "StorageConfig", "DocFileObject", "DocSourceFrom", "DocFileType"]
@@ -149,4 +149,107 @@ class AliCloudStorage(ObjectStorage):
149
149
  return files
150
150
  except Exception as e:
151
151
  logger.error(f"列出单据文件失败: {str(e)}")
152
- return []
152
+ return []
153
+
154
+ def generate_presigned_url(self, object_key: str, method: str = "GET", expires_in: int = 3600,
155
+ response_headers: Optional[Dict[str, str]] = None,
156
+ auth_tenant_id: Optional[str] = None,
157
+ auth_company_id: Optional[str] = None,
158
+ doc_id: Optional[str] = None) -> Optional[str]:
159
+ """
160
+ 生成预签名URL
161
+
162
+ Args:
163
+ object_key: 对象存储中的key
164
+ method: HTTP方法,支持 GET、PUT、POST、DELETE
165
+ expires_in: 过期时间(秒),默认3600秒(1小时)
166
+ response_headers: 响应头设置
167
+ auth_tenant_id: 租户ID(可选,若不传则用实例属性)
168
+ auth_company_id: 公司ID(可选,若不传则用实例属性)
169
+ doc_id: 单据ID(可选,若不传则用实例属性)
170
+
171
+ Returns:
172
+ Optional[str]: 预签名URL,失败时返回None
173
+ """
174
+ try:
175
+ # 验证参数
176
+ if not object_key:
177
+ raise ValueError("object_key 不能为空")
178
+
179
+ if method.upper() not in ["GET", "PUT", "POST", "DELETE"]:
180
+ raise ValueError(f"不支持的HTTP方法: {method}")
181
+
182
+ if expires_in <= 0 or expires_in > 604800: # 最大7天
183
+ raise ValueError("过期时间必须在1秒到604800秒(7天)之间")
184
+
185
+ # 生成预签名URL
186
+ from datetime import datetime, timedelta
187
+
188
+ if method.upper() == "GET":
189
+ url = self.bucket.sign_url(
190
+ method='GET',
191
+ key=object_key,
192
+ expires=expires_in,
193
+ headers=response_headers
194
+ )
195
+ elif method.upper() == "PUT":
196
+ url = self.bucket.sign_url(
197
+ method='PUT',
198
+ key=object_key,
199
+ expires=expires_in
200
+ )
201
+ elif method.upper() == "POST":
202
+ url = self.bucket.sign_url(
203
+ method='POST',
204
+ key=object_key,
205
+ expires=expires_in
206
+ )
207
+ elif method.upper() == "DELETE":
208
+ url = self.bucket.sign_url(
209
+ method='DELETE',
210
+ key=object_key,
211
+ expires=expires_in
212
+ )
213
+
214
+ logger.info(f"生成预签名URL成功: {object_key}, method: {method}")
215
+ return url
216
+
217
+ except Exception as e:
218
+ logger.error(f"生成预签名URL失败: {str(e)}")
219
+ return None
220
+
221
+ def generate_presigned_doc_url(self, filename: str, method: str = "GET", expires_in: int = 3600,
222
+ response_headers: Optional[Dict[str, str]] = None,
223
+ auth_tenant_id: Optional[str] = None,
224
+ auth_company_id: Optional[str] = None,
225
+ doc_id: Optional[str] = None) -> Optional[str]:
226
+ """
227
+ 生成单据文件的预签名URL
228
+
229
+ Args:
230
+ filename: 文件名
231
+ method: HTTP方法,支持 GET、PUT、POST、DELETE
232
+ expires_in: 过期时间(秒),默认3600秒(1小时)
233
+ response_headers: 响应头设置
234
+ auth_tenant_id: 租户ID(可选,若不传则用实例属性)
235
+ auth_company_id: 公司ID(可选,若不传则用实例属性)
236
+ doc_id: 单据ID(可选,若不传则用实例属性)
237
+
238
+ Returns:
239
+ Optional[str]: 预签名URL,失败时返回None
240
+ """
241
+ try:
242
+ # 构建单据文件路径
243
+ object_key = self._build_doc_path(filename, auth_tenant_id, auth_company_id, doc_id)
244
+
245
+ # 调用通用预签名URL生成方法
246
+ return self.generate_presigned_url(
247
+ object_key=object_key,
248
+ method=method,
249
+ expires_in=expires_in,
250
+ response_headers=response_headers
251
+ )
252
+
253
+ except Exception as e:
254
+ logger.error(f"生成单据文件预签名URL失败: {str(e)}")
255
+ return None
@@ -257,4 +257,110 @@ class MinioStorage(ObjectStorage):
257
257
  return files
258
258
  except S3Error as e:
259
259
  logger.error(f"list doc files failed: {str(e)}")
260
- return []
260
+ return []
261
+
262
+ def generate_presigned_url(self, object_key: str, method: str = "GET", expires_in: int = 3600,
263
+ response_headers: Optional[Dict[str, str]] = None,
264
+ auth_tenant_id: Optional[str] = None,
265
+ auth_company_id: Optional[str] = None,
266
+ doc_id: Optional[str] = None) -> Optional[str]:
267
+ """
268
+ 生成预签名URL
269
+
270
+ Args:
271
+ object_key: 对象存储中的key
272
+ method: HTTP方法,支持 GET、PUT、POST、DELETE
273
+ expires_in: 过期时间(秒),默认3600秒(1小时)
274
+ response_headers: 响应头设置
275
+ auth_tenant_id: 租户ID(可选,若不传则用实例属性)
276
+ auth_company_id: 公司ID(可选,若不传则用实例属性)
277
+ doc_id: 单据ID(可选,若不传则用实例属性)
278
+
279
+ Returns:
280
+ Optional[str]: 预签名URL,失败时返回None
281
+ """
282
+ try:
283
+ # 验证参数
284
+ if not object_key:
285
+ raise ValueError("object_key 不能为空")
286
+
287
+ if method.upper() not in ["GET", "PUT", "POST", "DELETE"]:
288
+ raise ValueError(f"不支持的HTTP方法: {method}")
289
+
290
+ if expires_in <= 0 or expires_in > 604800: # 最大7天
291
+ raise ValueError("过期时间必须在1秒到604800秒(7天)之间")
292
+
293
+ # 生成预签名URL
294
+ from datetime import timedelta
295
+
296
+ if method.upper() == "GET":
297
+ url = self.client.presigned_get_object(
298
+ bucket_name=self.bucket_name,
299
+ object_name=object_key,
300
+ expires=timedelta(seconds=expires_in),
301
+ response_headers=response_headers
302
+ )
303
+ elif method.upper() == "PUT":
304
+ url = self.client.presigned_put_object(
305
+ bucket_name=self.bucket_name,
306
+ object_name=object_key,
307
+ expires=timedelta(seconds=expires_in)
308
+ )
309
+ elif method.upper() == "POST":
310
+ url = self.client.presigned_post_policy(
311
+ bucket_name=self.bucket_name,
312
+ object_name=object_key,
313
+ expires=timedelta(seconds=expires_in)
314
+ )
315
+ elif method.upper() == "DELETE":
316
+ url = self.client.presigned_delete_object(
317
+ bucket_name=self.bucket_name,
318
+ object_name=object_key,
319
+ expires=timedelta(seconds=expires_in)
320
+ )
321
+
322
+ logger.info(f"生成预签名URL成功: {object_key}, method: {method}")
323
+ return url
324
+
325
+ except S3Error as e:
326
+ logger.error(f"生成预签名URL失败: {str(e)}")
327
+ return None
328
+ except Exception as e:
329
+ logger.error(f"生成预签名URL异常: {str(e)}")
330
+ return None
331
+
332
+ def generate_presigned_doc_url(self, filename: str, method: str = "GET", expires_in: int = 3600,
333
+ response_headers: Optional[Dict[str, str]] = None,
334
+ auth_tenant_id: Optional[str] = None,
335
+ auth_company_id: Optional[str] = None,
336
+ doc_id: Optional[str] = None) -> Optional[str]:
337
+ """
338
+ 生成单据文件的预签名URL
339
+
340
+ Args:
341
+ filename: 文件名
342
+ method: HTTP方法,支持 GET、PUT、POST、DELETE
343
+ expires_in: 过期时间(秒),默认3600秒(1小时)
344
+ response_headers: 响应头设置
345
+ auth_tenant_id: 租户ID(可选,若不传则用实例属性)
346
+ auth_company_id: 公司ID(可选,若不传则用实例属性)
347
+ doc_id: 单据ID(可选,若不传则用实例属性)
348
+
349
+ Returns:
350
+ Optional[str]: 预签名URL,失败时返回None
351
+ """
352
+ try:
353
+ # 构建单据文件路径
354
+ object_key = self._build_doc_path(filename, auth_tenant_id, auth_company_id, doc_id)
355
+
356
+ # 调用通用预签名URL生成方法
357
+ return self.generate_presigned_url(
358
+ object_key=object_key,
359
+ method=method,
360
+ expires_in=expires_in,
361
+ response_headers=response_headers
362
+ )
363
+
364
+ except Exception as e:
365
+ logger.error(f"生成单据文件预签名URL失败: {str(e)}")
366
+ return None
@@ -163,6 +163,52 @@ class ObjectStorage(ABC):
163
163
  """
164
164
  pass
165
165
 
166
+ @abstractmethod
167
+ def generate_presigned_url(self, object_key: str, method: str = "GET", expires_in: int = 3600,
168
+ response_headers: Optional[Dict[str, str]] = None,
169
+ auth_tenant_id: Optional[str] = None,
170
+ auth_company_id: Optional[str] = None,
171
+ doc_id: Optional[str] = None) -> Optional[str]:
172
+ """
173
+ 生成预签名URL
174
+
175
+ Args:
176
+ object_key: 对象存储中的key,如果为空则使用单据路径
177
+ method: HTTP方法,支持 GET、PUT、POST、DELETE
178
+ expires_in: 过期时间(秒),默认3600秒(1小时)
179
+ response_headers: 响应头设置
180
+ auth_tenant_id: 租户ID(可选,若不传则用实例属性)
181
+ auth_company_id: 公司ID(可选,若不传则用实例属性)
182
+ doc_id: 单据ID(可选,若不传则用实例属性)
183
+
184
+ Returns:
185
+ Optional[str]: 预签名URL,失败时返回None
186
+ """
187
+ pass
188
+
189
+ @abstractmethod
190
+ def generate_presigned_doc_url(self, filename: str, method: str = "GET", expires_in: int = 3600,
191
+ response_headers: Optional[Dict[str, str]] = None,
192
+ auth_tenant_id: Optional[str] = None,
193
+ auth_company_id: Optional[str] = None,
194
+ doc_id: Optional[str] = None) -> Optional[str]:
195
+ """
196
+ 生成单据文件的预签名URL
197
+
198
+ Args:
199
+ filename: 文件名
200
+ method: HTTP方法,支持 GET、PUT、POST、DELETE
201
+ expires_in: 过期时间(秒),默认3600秒(1小时)
202
+ response_headers: 响应头设置
203
+ auth_tenant_id: 租户ID(可选,若不传则用实例属性)
204
+ auth_company_id: 公司ID(可选,若不传则用实例属性)
205
+ doc_id: 单据ID(可选,若不传则用实例属性)
206
+
207
+ Returns:
208
+ Optional[str]: 预签名URL,失败时返回None
209
+ """
210
+ pass
211
+
166
212
  class ObjectStorageFactory:
167
213
  """对象存储工厂类"""
168
214
 
@@ -253,6 +299,68 @@ class ObjectStorageFactory:
253
299
  return MinioStorage(config, auth_tenant_id, auth_company_id, doc_id)
254
300
  else:
255
301
  raise ValueError(f"不支持的存储提供商: {provider}")
302
+
303
+ @classmethod
304
+ def generate_presigned_url(cls, object_key: str, method: str = "GET", expires_in: int = 3600,
305
+ response_headers: Optional[Dict[str, str]] = None,
306
+ auth_tenant_id: Optional[str] = None,
307
+ auth_company_id: Optional[str] = None,
308
+ doc_id: Optional[str] = None) -> Optional[str]:
309
+ """通过工厂类生成预签名URL
310
+
311
+ Args:
312
+ object_key: 对象存储中的key
313
+ method: HTTP方法,支持 GET、PUT、POST、DELETE
314
+ expires_in: 过期时间(秒),默认3600秒(1小时)
315
+ response_headers: 响应头设置
316
+ auth_tenant_id: 租户ID(可选)
317
+ auth_company_id: 公司ID(可选)
318
+ doc_id: 单据ID(可选)
319
+
320
+ Returns:
321
+ Optional[str]: 预签名URL,失败时返回None
322
+ """
323
+ storage = cls.get_instance()
324
+ return storage.generate_presigned_url(
325
+ object_key=object_key,
326
+ method=method,
327
+ expires_in=expires_in,
328
+ response_headers=response_headers,
329
+ auth_tenant_id=auth_tenant_id,
330
+ auth_company_id=auth_company_id,
331
+ doc_id=doc_id
332
+ )
333
+
334
+ @classmethod
335
+ def generate_presigned_doc_url(cls, 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
+ """通过工厂类生成单据文件的预签名URL
341
+
342
+ Args:
343
+ filename: 文件名
344
+ method: HTTP方法,支持 GET、PUT、POST、DELETE
345
+ expires_in: 过期时间(秒),默认3600秒(1小时)
346
+ response_headers: 响应头设置
347
+ auth_tenant_id: 租户ID(可选)
348
+ auth_company_id: 公司ID(可选)
349
+ doc_id: 单据ID(可选)
350
+
351
+ Returns:
352
+ Optional[str]: 预签名URL,失败时返回None
353
+ """
354
+ storage = cls.get_instance()
355
+ return storage.generate_presigned_doc_url(
356
+ filename=filename,
357
+ method=method,
358
+ expires_in=expires_in,
359
+ response_headers=response_headers,
360
+ auth_tenant_id=auth_tenant_id,
361
+ auth_company_id=auth_company_id,
362
+ doc_id=doc_id
363
+ )
256
364
 
257
365
  # 导出工厂类
258
366
  __all__ = ['ObjectStorage', 'ObjectStorageFactory', 'StorageConfig']
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fiuai-s3
3
- Version: 0.4.1
3
+ Version: 0.4.2
4
4
  Summary: 一个支持阿里云OSS和MinIO的对象存储抽象包
5
5
  Project-URL: Homepage, https://github.com/fiuai-sz/fiuai-s3
6
6
  Project-URL: Repository, https://github.com/fiuai-sz/fiuai-s3.git
@@ -0,0 +1,11 @@
1
+ fiuai_s3/__init__.py,sha256=BZvQEEefO33hqV8ZcT0HSLtW0XKsw8KpoxBinHTIlzo,421
2
+ fiuai_s3/object_storage.py,sha256=1vPiFFK1eb9_tF-fSn2_CBqpWtbm5WsgSvGk3VEOvvo,14169
3
+ fiuai_s3/type.py,sha256=L1h3SQh7_NhWfjWPa1MMgGoxM7g6wQF26qg5WsERt6U,981
4
+ fiuai_s3/alicloud/__init__.py,sha256=mmrCrFp5DzRF5fViJDq7_LpsqCViwTPXOPz4qoaSscI,218
5
+ fiuai_s3/alicloud/alicloud_storage.py,sha256=DieaILMmPXYU8-xbZIZbdkmju3PXEVDWXAQ7qAtuJdg,10417
6
+ fiuai_s3/minio/__init__.py,sha256=hOmpUkTq8TPgYOxfeOMcWq1_YsJ2r8Zf9VTX3w_v1Lk,209
7
+ fiuai_s3/minio/minio_storage.py,sha256=z_LvuL_CGr0bisCF9vYGwHdqJbohYi9qQFevGV4JhyM,14281
8
+ fiuai_s3-0.4.2.dist-info/METADATA,sha256=0KxOv7GE5LS5N0zPxcTvx63oAR2dP0FjhSHpeMNc8XE,18727
9
+ fiuai_s3-0.4.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
10
+ fiuai_s3-0.4.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
11
+ fiuai_s3-0.4.2.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- fiuai_s3/__init__.py,sha256=tLlqnMEl4K7R4jg2GbvGZanRsis1vm7KFKSc5R_wRUE,421
2
- fiuai_s3/object_storage.py,sha256=jbXQJ8SBZNMoLQz4OXs6vWwY1cVON2d_5a3LolzcqD8,9335
3
- fiuai_s3/type.py,sha256=L1h3SQh7_NhWfjWPa1MMgGoxM7g6wQF26qg5WsERt6U,981
4
- fiuai_s3/alicloud/__init__.py,sha256=mmrCrFp5DzRF5fViJDq7_LpsqCViwTPXOPz4qoaSscI,218
5
- fiuai_s3/alicloud/alicloud_storage.py,sha256=d24AFYDs7RsTsfL9IiVOxYlGyLzsaUa_WUYD5VPLP4s,6035
6
- fiuai_s3/minio/__init__.py,sha256=hOmpUkTq8TPgYOxfeOMcWq1_YsJ2r8Zf9VTX3w_v1Lk,209
7
- fiuai_s3/minio/minio_storage.py,sha256=k0IKpifeUP8JwfDCry0yuFTzrnaHA9ZWYQToNhGS99s,9563
8
- fiuai_s3-0.4.1.dist-info/METADATA,sha256=0ye44O-YuXc3ZCwvvUBRDQdr7f-owyyp3FHQLaa5Yf4,18727
9
- fiuai_s3-0.4.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
10
- fiuai_s3-0.4.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
11
- fiuai_s3-0.4.1.dist-info/RECORD,,