Skip to content

Commit d7e8105

Browse files
authored
Merge pull request #12 from dt3310321/s3
S3
2 parents d3185fc + 45adf4c commit d7e8105

File tree

4 files changed

+138
-32
lines changed

4 files changed

+138
-32
lines changed

README.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ __________
1111

1212
使用pip安装 ::
1313

14-
  pip install -U qcloud_cos_v5  暂不可用
15-
14+
pip install -U cos-python-sdk-v5
1615

1716
手动安装::
1817

qcloud_cos/cos_client.py

Lines changed: 100 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ def xml_to_dict(data):
8282
"""V5使用xml格式,将response中的xml转换为dict"""
8383
root = xml.etree.ElementTree.fromstring(data)
8484
xmldict = Xml2Dict(root)
85+
xmlstr = str(xmldict)
86+
xmlstr = xmlstr.replace("{http://www.qcloud.com/document/product/436/7751}", "")
87+
xmlstr = xmlstr.replace("{http://www.w3.org/2001/XMLSchema-instance}", "")
88+
xmldict = eval(xmlstr)
8589
return xmldict
8690

8791

@@ -147,13 +151,11 @@ def __init__(self, conf, retry=1, session=None):
147151
else:
148152
self._session = session
149153

150-
def get_auth(self, Method, Bucket, Key=None, **kwargs):
154+
def get_auth(self, Method, Bucket, Key=None, Expired=10000, headers={}, params={}):
151155
"""获取签名"""
152-
headers = mapped(kwargs)
153-
# TODO(tiedu) 检查header的参数合法性
154156
url = self._conf.uri(bucket=Bucket, path=Key)
155-
r = Request(Method, url)
156-
auth = CosS3Auth(self._conf._access_id, self._conf._access_key)
157+
r = Request(Method, url, headers=headers, params=params)
158+
auth = CosS3Auth(self._conf._access_id, self._conf._access_key, Expired)
157159
return auth(r).headers['Authorization']
158160

159161
def send_request(self, method, url, timeout=30, **kwargs):
@@ -239,10 +241,10 @@ def get_object(self, Bucket, Key, **kwargs):
239241
response[k] = rt.headers[k]
240242
return response
241243

242-
def get_presigned_download_url(self, Bucket, Key):
244+
def get_presigned_download_url(self, Bucket, Key, Expired=10000):
243245
"""生成预签名的下载url"""
244246
url = self._conf.uri(bucket=Bucket, path=Key)
245-
sign = self.get_auth(Method='GET', Bucket=Bucket, Key=Key)
247+
sign = self.get_auth(Method='GET', Bucket=Bucket, Key=Key, Expired=10000)
246248
url = url + '?sign=' + urllib.quote(sign)
247249
return url
248250

@@ -353,11 +355,8 @@ def complete_multipart_upload(self, Bucket, Key, UploadId, MultipartUpload={}, *
353355
data=dict_to_xml(MultipartUpload),
354356
timeout=1200, # 分片上传大文件的时间比较长,设置为20min
355357
headers=headers)
356-
response = dict()
357358
data = xml_to_dict(rt.text)
358-
for key in data.keys():
359-
response[key[key.find('}')+1:]] = data[key]
360-
return response
359+
return data
361360

362361
def abort_multipart_upload(self, Bucket, Key, UploadId, **kwargs):
363362
"""放弃一个已经存在的分片上传任务,删除所有已经存在的分片"""
@@ -385,18 +384,45 @@ def list_parts(self, Bucket, Key, UploadId, **kwargs):
385384
url=url,
386385
auth=CosS3Auth(self._conf._access_id, self._conf._access_key),
387386
headers=headers)
387+
data = xml_to_dict(rt.text)
388+
if 'Part' in data.keys() and isinstance(data['Part'], dict): # 只有一个part,将dict转为list,保持一致
389+
lst = []
390+
lst.append(data['Part'])
391+
data['Part'] = lst
392+
return data
393+
394+
def put_object_acl(self, Bucket, Key, **kwargs):
395+
"""设置object ACL"""
396+
headers = mapped(kwargs)
397+
url = self._conf.uri(bucket=Bucket, path=Key+"?acl")
398+
logger.info("put object acl, url=:{url} ,headers=:{headers}".format(
399+
url=url,
400+
headers=headers))
401+
rt = self.send_request(
402+
method='PUT',
403+
url=url,
404+
auth=CosS3Auth(self._conf._access_id, self._conf._access_key),
405+
headers=headers)
406+
return None
388407

408+
def get_object_acl(self, Bucket, Key, **kwargs):
409+
"""获取object ACL"""
410+
headers = mapped(kwargs)
411+
url = self._conf.uri(bucket=Bucket, path=Key+"?acl")
412+
logger.info("get object acl, url=:{url} ,headers=:{headers}".format(
413+
url=url,
414+
headers=headers))
415+
rt = self.send_request(
416+
method='GET',
417+
url=url,
418+
auth=CosS3Auth(self._conf._access_id, self._conf._access_key),
419+
headers=headers)
389420
data = xml_to_dict(rt.text)
390-
if 'Part' in data.keys():
391-
if isinstance(data['Part'], list):
392-
return data
393-
else: # 只有一个part,将dict转为list,保持一致
394-
lst = []
395-
lst.append(data['Part'])
396-
data['Part'] = lst
397-
return data
398-
else:
399-
return data
421+
if data['AccessControlList'] is not None and isinstance(data['AccessControlList']['Grant'], dict):
422+
lst = []
423+
lst.append(data['AccessControlList']['Grant'])
424+
data['AccessControlList']['Grant'] = lst
425+
return data
400426

401427
# s3 bucket interface begin
402428
def create_bucket(self, Bucket, **kwargs):
@@ -447,16 +473,58 @@ def list_objects(self, Bucket, Delimiter="", Marker="", MaxKeys=1000, Prefix="",
447473
auth=CosS3Auth(self._conf._access_id, self._conf._access_key))
448474

449475
data = xml_to_dict(rt.text)
450-
if 'Contents' in data.keys():
451-
if isinstance(data['Contents'], list):
452-
return data
453-
else: # 只有一个Contents,将dict转为list,保持一致
476+
if 'Contents' in data.keys() and isinstance(data['Contents'], dict): # 只有一个Contents,将dict转为list,保持一致
454477
lst = []
455478
lst.append(data['Contents'])
456479
data['Contents'] = lst
457-
return data
458-
else:
459-
return data
480+
return data
481+
482+
def head_bucket(self, Bucket, **kwargs):
483+
"""获取bucket信息"""
484+
headers = mapped(kwargs)
485+
url = self._conf.uri(bucket=Bucket)
486+
logger.info("head bucket, url=:{url} ,headers=:{headers}".format(
487+
url=url,
488+
headers=headers))
489+
rt = self.send_request(
490+
method='HEAD',
491+
url=url,
492+
auth=CosS3Auth(self._conf._access_id, self._conf._access_key),
493+
headers=headers)
494+
return None
495+
496+
def put_bucket_acl(self, Bucket, **kwargs):
497+
"""设置bucket ACL"""
498+
headers = mapped(kwargs)
499+
url = self._conf.uri(bucket=Bucket, path="?acl")
500+
logger.info("put bucket acl, url=:{url} ,headers=:{headers}".format(
501+
url=url,
502+
headers=headers))
503+
rt = self.send_request(
504+
method='PUT',
505+
url=url,
506+
auth=CosS3Auth(self._conf._access_id, self._conf._access_key),
507+
headers=headers)
508+
return None
509+
510+
def get_bucket_acl(self, Bucket, **kwargs):
511+
"""获取bucket ACL"""
512+
headers = mapped(kwargs)
513+
url = self._conf.uri(bucket=Bucket, path="?acl")
514+
logger.info("get bucket acl, url=:{url} ,headers=:{headers}".format(
515+
url=url,
516+
headers=headers))
517+
rt = self.send_request(
518+
method='GET',
519+
url=url,
520+
auth=CosS3Auth(self._conf._access_id, self._conf._access_key),
521+
headers=headers)
522+
data = xml_to_dict(rt.text)
523+
if data['AccessControlList'] is not None and isinstance(data['AccessControlList']['Grant'], dict):
524+
lst = []
525+
lst.append(data['AccessControlList']['Grant'])
526+
data['AccessControlList']['Grant'] = lst
527+
return data
460528

461529
# service interface begin
462530
def list_buckets(self, **kwargs):
@@ -470,6 +538,10 @@ def list_buckets(self, **kwargs):
470538
auth=CosS3Auth(self._conf._access_id, self._conf._access_key),
471539
)
472540
data = xml_to_dict(rt.text)
541+
if data['Buckets'] is not None and isinstance(data['Buckets']['Bucket'], dict):
542+
lst = []
543+
lst.append(data['Buckets']['Bucket'])
544+
data['Buckets']['Bucket'] = lst
473545
return data
474546

475547
if __name__ == "__main__":

qcloud_cos/test.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,19 @@ def Test():
147147
except CosServiceError as e:
148148
print_error_msg(e)
149149

150+
print "Test Put Object ACL " + file_name
151+
response = client.put_object_acl(
152+
Bucket=test_bucket,
153+
Key=file_name,
154+
ACL='public-read-write'
155+
)
156+
157+
print "Test Get Object ACL" + file_name
158+
response = client.get_object_acl(
159+
Bucket=test_bucket,
160+
Key=file_name
161+
)
162+
150163
print "Test Delete Object " + file_name
151164
response = client.head_object(
152165
Bucket=test_bucket,
@@ -164,11 +177,33 @@ def Test():
164177
ACL='public-read'
165178
)
166179

180+
print "Test PUT Bucket ACL"
181+
try:
182+
response = client.put_bucket_acl(
183+
Bucket='test'+file_id,
184+
ACL='public-read-writea'
185+
)
186+
except CosServiceError as e:
187+
print_error_msg(e)
188+
189+
print "Test GET Bucket ACL"
190+
response = client.get_bucket_acl(
191+
Bucket='test'+file_id,
192+
)
193+
167194
print "Test Delete Bucket"
168195
response = client.delete_bucket(
169196
Bucket='test'+file_id
170197
)
171198

199+
print "Test Head Bucket"
200+
try:
201+
response = client.head_bucket(
202+
Bucket='test'+file_id
203+
)
204+
except CosServiceError as e:
205+
print_error_msg(e)
206+
172207
print "Test Create MultipartUpload"
173208
response = client.create_multipart_upload(
174209
Bucket=test_bucket,

qcloud_cos/xml2dict.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ def updateDict(self, aDict):
3535

3636
if __name__ == "__main__":
3737
s = """<?xml version="1.0" encoding="utf-8" ?>
38-
<result>
38+
<result xmlns= "wqa.bai.com">
3939
<count n="1">10</count>
4040
<data><id>1</id><name>test1</name></data>
4141
<data><id>2</id><name>test2</name></data>
4242
<data><id>3</id><name>test3</name></data>
4343
</result>"""
4444
root = xml.etree.ElementTree.fromstring(s)
45-
xmldict = XmlDictConfig(root)
45+
xmldict = Xml2Dict(root)
4646
print xmldict

0 commit comments

Comments
 (0)