@@ -44,7 +44,7 @@ def __init__(self, Appid=None, Region=None, SecretId=None, SecretKey=None, Token
4444 Access_id = None , Access_key = None , Secret_id = None , Secret_key = None , Endpoint = None , IP = None , Port = None ,
4545 Anonymous = None , UA = None , Proxies = None , Domain = None , ServiceDomain = None , KeepAlive = True , PoolConnections = 10 ,
4646 PoolMaxSize = 10 , AllowRedirects = False , SignHost = True , EndpointCi = None , EndpointPic = None , EnableOldDomain = True , EnableInternalDomain = True , SignParams = True ,
47- AutoSwitchDomainOnRetry = True ):
47+ AutoSwitchDomainOnRetry = False ):
4848 """初始化,保存用户的信息
4949
5050 :param Appid(string): 用户APPID.
@@ -359,6 +359,7 @@ def send_request(self, method, url, bucket, timeout=30, cos_request=True, ci_req
359359 kwargs ['verify' ] = False
360360 if self ._conf ._allow_redirects is not None :
361361 kwargs ['allow_redirects' ] = self ._conf ._allow_redirects
362+ exception_logbuf = list () # 记录每次重试的错误日志
362363 for j in range (self ._retry + 1 ):
363364 try :
364365 if j != 0 :
@@ -397,13 +398,16 @@ def send_request(self, method, url, bucket, timeout=30, cos_request=True, ci_req
397398 else :
398399 break
399400 except Exception as e : # 捕获requests抛出的如timeout等客户端错误,转化为客户端错误
400- logger .exception ('url:%s, retry_time:%d exception:%s' % (url , j , str (e )))
401+ # 记录每次请求的exception
402+ exception_log = 'url:%s, retry_time:%d exception:%s' % (url , j , str (e ))
403+ exception_logbuf .append (exception_log )
401404 if j < self ._retry and (isinstance (e , ConnectionError ) or isinstance (e , Timeout )): # 只重试网络错误
402405 if client_can_retry (file_position , ** kwargs ):
403406 if not domain_switched and self ._conf ._auto_switch_domain_on_retry and self ._conf ._ip is None :
404407 url = switch_hostname_for_url (url )
405408 domain_switched = True
406409 continue
410+ logger .exception (exception_logbuf ) # 最终重试失败, 输出前几次重试失败的exception
407411 raise CosClientError (str (e ))
408412
409413 if not cos_request :
@@ -419,12 +423,16 @@ def send_request(self, method, url, bucket, timeout=30, cos_request=True, ci_req
419423 if 'x-cos-trace-id' in res .headers :
420424 info ['traceid' ] = res .headers ['x-cos-trace-id' ]
421425 logger .warn (info )
426+ if len (exception_logbuf ) > 0 :
427+ logger .exception (exception_logbuf ) # 最终重试失败, 输出前几次重试失败的exception
422428 raise CosServiceError (method , info , res .status_code )
423429 else :
424430 msg = res .text
425431 if msg == u'' : # 服务器没有返回Error Body时 给出头部的信息
426432 msg = res .headers
427433 logger .error (msg )
434+ if len (exception_logbuf ) > 0 :
435+ logger .exception (exception_logbuf ) # 最终重试失败, 输出前几次重试失败的exception
428436 raise CosServiceError (method , msg , res .status_code )
429437
430438 return None
@@ -1613,7 +1621,7 @@ def head_bucket(self, Bucket, **kwargs):
16131621
16141622 :param Bucket(string): 存储桶名称.
16151623 :param kwargs(dict): 设置请求headers.
1616- :return: None .
1624+ :return: HEAD Bucket响应头域 .
16171625
16181626 .. code-block:: python
16191627
@@ -1635,7 +1643,7 @@ def head_bucket(self, Bucket, **kwargs):
16351643 bucket = Bucket ,
16361644 auth = CosS3Auth (self ._conf ),
16371645 headers = headers )
1638- return None
1646+ return rt . headers
16391647
16401648 def put_bucket_acl (self , Bucket , AccessControlPolicy = {}, ** kwargs ):
16411649 """设置bucket ACL
@@ -2926,7 +2934,7 @@ def get_bucket_inventory(self, Bucket, Id, **kwargs):
29262934 return data
29272935
29282936 def delete_bucket_inventory (self , Bucket , Id , ** kwargs ):
2929- """删除bucket 回源配置
2937+ """删除bucket清单规则
29302938
29312939 :param Bucket(string): 存储桶名称.
29322940 :param Id(string): 清单规则名称.
@@ -2957,6 +2965,52 @@ def delete_bucket_inventory(self, Bucket, Id, **kwargs):
29572965 params = params )
29582966 return None
29592967
2968+ def list_bucket_inventory_configurations (self , Bucket , ContinuationToken = None , ** kwargs ):
2969+ """列举存储桶清单规则
2970+
2971+ :param Bucket(string): 存储桶名称
2972+ :param ContinuationToken(string): 分页参数, 用以获取下一页信息
2973+ :param kwargs(dict): 设置请求headers.
2974+ :return(dict): 存储桶清单规则列表
2975+
2976+ .. code-block:: python
2977+
2978+ config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token) # 获取配置对象
2979+ client = CosS3Client(config)
2980+ # 分页列举bucket清单规则
2981+ continuation_token = ''
2982+ while True:
2983+ resp = client.list_bucket_inventory_configurations(
2984+ Bucket=bucket,
2985+ ContinuationToken=continuation_token,
2986+ )
2987+ if 'InventoryConfiguration' in resp:
2988+ for conf in resp['InventoryConfiguration']:
2989+ print(conf)
2990+ if resp['IsTruncated'] == 'true':
2991+ continuation_token = resp['NextContinuationToken']
2992+ else:
2993+ break
2994+ """
2995+ headers = mapped (kwargs )
2996+ params = {'inventory' : '' }
2997+ if ContinuationToken is not None :
2998+ params ['continuation-token' ] = ContinuationToken
2999+ url = self ._conf .uri (bucket = Bucket )
3000+ logger .info ("list bucket inventory configurations, url={url}, headers={headers}" .format (
3001+ url = url ,
3002+ headers = headers ,
3003+ ))
3004+ rt = self .send_request (
3005+ method = 'GET' ,
3006+ url = url ,
3007+ bucket = Bucket ,
3008+ auth = CosS3Auth (self ._conf , params = params ),
3009+ headers = headers ,
3010+ params = params )
3011+ data = xml_to_dict (rt .content )
3012+ return data
3013+
29603014 def put_object_tagging (self , Bucket , Key , Tagging = {}, ** kwargs ):
29613015 """设置object的标签
29623016
@@ -3560,7 +3614,7 @@ def _check_all_upload_parts(self, bucket, key, uploadid, local_path, parts_num,
35603614 already_exist_parts [part_num ] = part ['ETag' ]
35613615 return True
35623616
3563- def download_file (self , Bucket , Key , DestFilePath , PartSize = 20 , MAXThread = 5 , EnableCRC = False , progress_callback = None , ** Kwargs ):
3617+ def download_file (self , Bucket , Key , DestFilePath , PartSize = 20 , MAXThread = 5 , EnableCRC = False , progress_callback = None , DumpRecordDir = None , ** Kwargs ):
35643618 """小于等于20MB的文件简单下载,大于20MB的文件使用续传下载
35653619
35663620 :param Bucket(string): 存储桶名称.
@@ -3596,7 +3650,7 @@ def download_file(self, Bucket, Key, DestFilePath, PartSize=20, MAXThread=5, Ena
35963650 callback = ProgressCallback (file_size , progress_callback )
35973651
35983652 downloader = ResumableDownLoader (self , Bucket , Key , DestFilePath , object_info , PartSize , MAXThread , EnableCRC ,
3599- callback , ** Kwargs )
3653+ callback , DumpRecordDir , ** Kwargs )
36003654 downloader .start ()
36013655
36023656 def upload_file (self , Bucket , Key , LocalFilePath , PartSize = 1 , MAXThread = 5 , EnableMD5 = False , progress_callback = None ,
0 commit comments