Skip to content

Commit

Permalink
Add headers parameters to the list bucket interface (#341)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhuxiaolong37 authored and huiguangjun committed May 29, 2023
1 parent 6c3436f commit 91167d8
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 12 deletions.
12 changes: 6 additions & 6 deletions oss2/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,13 +311,14 @@ def __init__(self, auth, endpoint,
app_name=app_name, proxies=proxies,
region=region, cloudbox_id=cloudbox_id)

def list_buckets(self, prefix='', marker='', max_keys=100, params=None):
def list_buckets(self, prefix='', marker='', max_keys=100, params=None, headers=None):
"""根据前缀罗列用户的Bucket。
:param str prefix: 只罗列Bucket名为该前缀的Bucket,空串表示罗列所有的Bucket
:param str marker: 分页标志。首次调用传空串,后续使用返回值中的next_marker
:param int max_keys: 每次调用最多返回的Bucket数目
:param dict params: list操作参数,传入'tag-key','tag-value'对结果进行过滤
:param headers: 用户指定的HTTP头部。可以指定Content-Type、Content-MD5、x-oss-meta-开头的头部等。可以是dict,建议是oss2.CaseInsensitiveDict
:return: 罗列的结果
:rtype: oss2.models.ListBucketsResult
Expand All @@ -329,13 +330,12 @@ def list_buckets(self, prefix='', marker='', max_keys=100, params=None):
listParam['marker'] = marker
listParam['max-keys'] = str(max_keys)

headers = http.CaseInsensitiveDict(headers)

if params is not None:
if 'tag-key' in params:
listParam['tag-key'] = params['tag-key']
if 'tag-value' in params:
listParam['tag-value'] = params['tag-value']
listParam.update(params)

resp = self._do('GET', '', '', params=listParam)
resp = self._do('GET', '', '', params=listParam, headers=headers)
logger.debug("List buckets done, req_id: {0}, status_code: {1}".format(resp.request_id, resp.status))
return self._parse_result(resp, xml_utils.parse_list_buckets, ListBucketsResult)

Expand Down
18 changes: 16 additions & 2 deletions oss2/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ def __init__(self, resp):

class SimplifiedBucketInfo(object):
""":func:`list_buckets <oss2.Service.list_objects>` 结果中的单个元素类型。"""
def __init__(self, name, location, creation_date, extranet_endpoint, intranet_endpoint, storage_class):
def __init__(self, name, location, creation_date, extranet_endpoint, intranet_endpoint, storage_class, region=None, resource_group_id=None):
#: Bucket名
self.name = name

Expand All @@ -524,6 +524,12 @@ def __init__(self, name, location, creation_date, extranet_endpoint, intranet_en
#: Bucket存储类型,支持“Standard”、“IA”、“Archive”、“ColdArchive”
self.storage_class = storage_class

#: Bucket所在地域
self.region = region

#: Bucket所属资源组ID
self.resource_group_id = resource_group_id


class ListBucketsResult(RequestResult):
def __init__(self, resp):
Expand All @@ -538,6 +544,9 @@ def __init__(self, resp):
#: 得到的Bucket列表,类型为 :class:`SimplifiedBucketInfo` 。
self.buckets = []

#: owner信息, 类型为: class:`Owner <oss2.models.Owner>`
self.owner = Owner('', '')


class MultipartUploadInfo(object):
def __init__(self, key, upload_id, initiation_date):
Expand Down Expand Up @@ -698,7 +707,8 @@ def __init__(self, display_name, owner_id):
class BucketInfo(object):
def __init__(self, name=None, owner=None, location=None, storage_class=None, intranet_endpoint=None,
extranet_endpoint=None, creation_date=None, acl=None, data_redundancy_type=None, comment=None,
bucket_encryption_rule=None, versioning_status=None, access_monitor=None):
bucket_encryption_rule=None, versioning_status=None, access_monitor=None,
transfer_acceleration=None, cross_region_replication=None, resource_group_id=None):
self.name = name
self.owner = owner
self.location = location
Expand All @@ -713,6 +723,9 @@ def __init__(self, name=None, owner=None, location=None, storage_class=None, int
self.bucket_encryption_rule = bucket_encryption_rule
self.versioning_status = versioning_status
self.access_monitor = access_monitor
self.transfer_acceleration = transfer_acceleration
self.cross_region_replication = cross_region_replication
self.resource_group_id = resource_group_id


class GetBucketStatResult(RequestResult, BucketStat):
Expand Down Expand Up @@ -2732,3 +2745,4 @@ class CallbackPolicyResult(RequestResult):
def __init__(self, resp):
super(CallbackPolicyResult, self).__init__(resp)
self.callback_policies = []

10 changes: 9 additions & 1 deletion oss2/xml_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,14 +223,19 @@ def parse_list_buckets(result, body):
if result.is_truncated:
result.next_marker = _find_tag(root, 'NextMarker')

if root.find('Owner'):
result.owner = Owner(_find_tag_with_default(root, 'Owner/DisplayName', None), _find_tag_with_default(root, 'Owner/ID', None))

for bucket_node in root.findall('Buckets/Bucket'):
result.buckets.append(SimplifiedBucketInfo(
_find_tag(bucket_node, 'Name'),
_find_tag(bucket_node, 'Location'),
iso8601_to_unixtime(_find_tag(bucket_node, 'CreationDate')),
_find_tag(bucket_node, 'ExtranetEndpoint'),
_find_tag(bucket_node, 'IntranetEndpoint'),
_find_tag(bucket_node, 'StorageClass')
_find_tag(bucket_node, 'StorageClass'),
_find_tag_with_default(bucket_node, 'Region', None),
_find_tag_with_default(bucket_node, 'ResourceGroupId', None),
))

return result
Expand Down Expand Up @@ -380,6 +385,9 @@ def parse_get_bucket_info(result, body):
result.versioning_status = _find_tag_with_default(root, 'Bucket/Versioning', None)
result.data_redundancy_type = _find_tag_with_default(root, 'Bucket/DataRedundancyType', None)
result.access_monitor = _find_tag_with_default(root, 'Bucket/AccessMonitor', None)
result.transfer_acceleration = _find_tag_with_default(root, 'Bucket/TransferAcceleration', None)
result.cross_region_replication = _find_tag_with_default(root, 'Bucket/CrossRegionReplication', None)
result.resource_group_id = _find_tag_with_default(root, 'Bucket/ResourceGroupId', None)

server_side_encryption = root.find("Bucket/ServerSideEncryptionRule")
if server_side_encryption is None:
Expand Down
13 changes: 13 additions & 0 deletions tests/test_bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -1201,5 +1201,18 @@ def test_bucket_header_SM4(self):
self.assertEqual(oss2.BUCKET_STORAGE_CLASS_IA, bucket_info3.storage_class)
self.assertEqual("SM4", bucket_info3.bucket_encryption_rule.sse_algorithm)


def test_bucket_with_group_id(self):
auth = oss2.Auth(OSS_ID, OSS_SECRET)
service = oss2.Service(auth, OSS_ENDPOINT)

# By getting_ bucket_ Information to obtain resource_ group_ id
bucket_info = self.bucket.get_bucket_info()

headers = dict()
headers['x-oss-resource-group-id'] = bucket_info.resource_group_id
result = service.list_buckets(prefix='oss-python-sdk-', max_keys=10, headers=headers)
self.assertEqual(bucket_info.resource_group_id, result.buckets[0].resource_group_id)

if __name__ == '__main__':
unittest.main()
195 changes: 192 additions & 3 deletions unittests/test_bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from mock import patch
from functools import partial

from oss2 import to_string
from oss2 import to_string, iso8601_to_unixtime
from oss2.models import AggregationsRequest, MetaQuery, CallbackPolicyInfo
from unittests.common import *

Expand Down Expand Up @@ -2443,7 +2443,7 @@ def test_describe_regions(self, do_request):
self.assertEqual(result.regions[1].internet_endpoint, 'oss-cn-shanghai.aliyuncs.com')
self.assertEqual(result.regions[1].internal_endpoint, 'oss-cn-shanghai-internal.aliyuncs.com')
self.assertEqual(result.regions[1].accelerate_endpoint, 'oss-accelerate.aliyuncs.com')

@patch('oss2.Session.do_request')
def test_async_process_object(self, do_request):
request_text = '''POST /test-video.mp4?x-oss-async-process HTTP/1.1
Expand Down Expand Up @@ -2474,7 +2474,7 @@ def test_async_process_object(self, do_request):
self.assertEqual(result.event_id, '3D7-1XxFtV2t3VtcOn2CXqI2ldsMN3i')
self.assertEqual(result.task_id, 'MediaConvert-d2280366-cd33-48f7-90c6-a0dab65bed63')


@patch('oss2.Session.do_request')
def test_put_bucket_callback_policy(self, do_request):
request_text = '''PUT /?policy&comp=callback HTTP/1.1
Expand Down Expand Up @@ -2582,5 +2582,194 @@ def test_delete_callback_policy(self, do_request):

self.assertRequest(req_info, request_text)


@patch('oss2.Session.do_request')
def test_list_buckets(self, do_request):
request_text = '''GET /?prefix=my&max-keys=10 HTTP/1.1
Host: oss-cn-hangzhou.aliyuncs.com
Accept-Encoding: identity
Connection: keep-alive
date: Sat, 12 Dec 2015 00:35:38 GMT
User-Agent: aliyun-sdk-python/2.0.2(Windows/7/;3.3.3)
Accept: */*
x-oss-resource-group-id: rg-acfmxmt3***
authorization: OSS ZCDmm7TPZKHtx77j:Pt0DtPQ/FODOGs5y0yTIVctRcok='''

response_text = '''HTTP/1.1 200 OK
Server: AliyunOSS
Date: Sat, 12 Dec 2015 00:35:38 GMT
Content-Type: application/xml
Content-Length: 277
Connection: keep-alive
x-oss-resource-group-id: rg-acfmxmt3***
x-oss-request-id: 566B6BDA010B7A4314D1614A
<?xml version="1.0" encoding="UTF-8"?>
<ListAllMyBucketsResult>
<Owner>
<ID>512**</ID>
<DisplayName>51264</DisplayName>
</Owner>
<Buckets>
<Bucket>
<CreationDate>2014-02-07T18:12:43.000Z</CreationDate>
<ExtranetEndpoint>oss-cn-shanghai.aliyuncs.com</ExtranetEndpoint>
<IntranetEndpoint>oss-cn-shanghai-internal.aliyuncs.com</IntranetEndpoint>
<Location>oss-cn-shanghai</Location>
<Name>test-bucket-1</Name>
<Region>cn-shanghai</Region>
<StorageClass>IA</StorageClass>
<ResourceGroupId>rg-acfmxmt3***</ResourceGroupId>
</Bucket>
<Bucket>
<CreationDate>2014-02-05T11:21:04.000Z</CreationDate>
<ExtranetEndpoint>oss-cn-hangzhou.aliyuncs.com</ExtranetEndpoint>
<IntranetEndpoint>oss-cn-hangzhou-internal.aliyuncs.com</IntranetEndpoint>
<Location>oss-cn-hangzhou</Location>
<Name>test-bucket-2</Name>
<Region>cn-hangzhou</Region>
<StorageClass>Standard</StorageClass>
<ResourceGroupId>rg-***</ResourceGroupId>
</Bucket>
</Buckets>
</ListAllMyBucketsResult>'''

req_info = mock_response(do_request, response_text)

headers = dict()
headers['x-oss-resource-group-id'] = 'rg-acfmxmt3***'
result = service().list_buckets(prefix='my', max_keys=10, headers=headers)

self.assertRequest(req_info, request_text)
self.assertEqual("512**", result.owner.id)
self.assertEqual("51264", result.owner.display_name)
self.assertEqual("test-bucket-1", result.buckets[0].name)
self.assertEqual("cn-shanghai", result.buckets[0].region)
self.assertEqual("IA", result.buckets[0].storage_class)
self.assertEqual("rg-acfmxmt3***", result.buckets[0].resource_group_id)
self.assertEqual("oss-cn-shanghai", result.buckets[0].location)
self.assertEqual(iso8601_to_unixtime("2014-02-07T18:12:43.000Z"), result.buckets[0].creation_date)
self.assertEqual("oss-cn-shanghai.aliyuncs.com", result.buckets[0].extranet_endpoint)
self.assertEqual("oss-cn-shanghai-internal.aliyuncs.com", result.buckets[0].intranet_endpoint)
self.assertEqual("test-bucket-2", result.buckets[1].name)
self.assertEqual("cn-hangzhou", result.buckets[1].region)
self.assertEqual("Standard", result.buckets[1].storage_class)
self.assertEqual("rg-***", result.buckets[1].resource_group_id)
self.assertEqual("oss-cn-hangzhou", result.buckets[1].location)
self.assertEqual(iso8601_to_unixtime("2014-02-05T11:21:04.000Z"), result.buckets[1].creation_date)
self.assertEqual("oss-cn-hangzhou.aliyuncs.com", result.buckets[1].extranet_endpoint)
self.assertEqual("oss-cn-hangzhou-internal.aliyuncs.com", result.buckets[1].intranet_endpoint)


@patch('oss2.Session.do_request')
def test_list_buckets_2(self, do_request):
request_text = '''GET /?prefix=my&max-keys=10 HTTP/1.1
Host: oss-cn-hangzhou.aliyuncs.com
Accept-Encoding: identity
Connection: keep-alive
date: Sat, 12 Dec 2015 00:35:38 GMT
User-Agent: aliyun-sdk-python/2.0.2(Windows/7/;3.3.3)
Accept: */*
x-oss-resource-group-id: rg-acfmxmt3***
authorization: OSS ZCDmm7TPZKHtx77j:Pt0DtPQ/FODOGs5y0yTIVctRcok='''

response_text = '''HTTP/1.1 200 OK
Server: AliyunOSS
Date: Sat, 12 Dec 2015 00:35:38 GMT
Content-Type: application/xml
Content-Length: 277
Connection: keep-alive
x-oss-resource-group-id: rg-acfmxmt3***
x-oss-request-id: 566B6BDA010B7A4314D1614A
<?xml version="1.0" encoding="UTF-8"?>
<ListAllMyBucketsResult>
<Buckets>
<Bucket>
<CreationDate>2014-02-07T18:12:43.000Z</CreationDate>
<ExtranetEndpoint>oss-cn-shanghai.aliyuncs.com</ExtranetEndpoint>
<IntranetEndpoint>oss-cn-shanghai-internal.aliyuncs.com</IntranetEndpoint>
<Location>oss-cn-shanghai</Location>
<Name>test-bucket-1</Name>
<StorageClass>Standard</StorageClass>
</Bucket>
</Buckets>
</ListAllMyBucketsResult>'''

req_info = mock_response(do_request, response_text)

headers = dict()
headers['x-oss-resource-group-id'] = 'rg-acfmxmt3***'
result = service().list_buckets(prefix='my', max_keys=10, headers=headers)

self.assertRequest(req_info, request_text)

self.assertEqual("test-bucket-1", result.buckets[0].name)
self.assertEqual("Standard", result.buckets[0].storage_class)
self.assertEqual("oss-cn-shanghai", result.buckets[0].location)
self.assertEqual(iso8601_to_unixtime("2014-02-07T18:12:43.000Z"), result.buckets[0].creation_date)
self.assertEqual("oss-cn-shanghai.aliyuncs.com", result.buckets[0].extranet_endpoint)
self.assertEqual("oss-cn-shanghai-internal.aliyuncs.com", result.buckets[0].intranet_endpoint)


@patch('oss2.Session.do_request')
def test_get_bucket_info(self, do_request):
request_text = '''GET /?bucketInfo HTTP/1.1
Date: Fri , 30 Apr 2021 13:08:38 GMT
Content-Length:443
Host: ming-oss-share.oss-cn-hangzhou.aliyuncs.com
Authorization: OSS qn6qrrqxo2oawuk53otf****:PYbzsdWAIWAlMW8luk****'''

response_text = '''HTTP/1.1 200 OK
x-oss-request-id: 566B6BD927A4046E9C725578
Date: Fri , 30 Apr 2021 13:08:38 GMT
<?xml version="1.0" encoding="UTF-8"?>
<BucketInfo>
<Bucket>
<AccessMonitor>Enabled</AccessMonitor>
<CreationDate>2013-07-31T10:56:21.000Z</CreationDate>
<ExtranetEndpoint>oss-cn-hangzhou.aliyuncs.com</ExtranetEndpoint>
<IntranetEndpoint>oss-cn-hangzhou-internal.aliyuncs.com</IntranetEndpoint>
<Location>oss-cn-hangzhou</Location>
<StorageClass>IA</StorageClass>
<TransferAcceleration>Disabled</TransferAcceleration>
<CrossRegionReplication>Disabled</CrossRegionReplication>
<Name>oss-example</Name>
<ResourceGroupId>rg-aek27tc********</ResourceGroupId>
<Owner>
<DisplayName>username</DisplayName>
<ID>27183473914****</ID>
</Owner>
<AccessControlList>
<Grant>private</Grant>
</AccessControlList>
<Comment>test</Comment>
</Bucket>
</BucketInfo>'''

req_info = mock_response(do_request, response_text)

result = bucket().get_bucket_info()

self.assertRequest(req_info, request_text)
self.assertEqual(result.request_id, '566B6BD927A4046E9C725578')
self.assertEqual(result.status, 200)
self.assertEqual(result.name, 'oss-example')
self.assertEqual(result.owner.display_name, 'username')
self.assertEqual(result.owner.id, '27183473914****')
self.assertEqual(result.location, 'oss-cn-hangzhou')
self.assertEqual(result.storage_class, 'IA')
self.assertEqual(result.access_monitor, 'Enabled')
self.assertEqual(result.creation_date, '2013-07-31T10:56:21.000Z')
self.assertEqual(result.intranet_endpoint, 'oss-cn-hangzhou-internal.aliyuncs.com')
self.assertEqual(result.extranet_endpoint, 'oss-cn-hangzhou.aliyuncs.com')
self.assertEqual(result.transfer_acceleration, 'Disabled')
self.assertEqual(result.cross_region_replication, 'Disabled')
self.assertEqual(result.resource_group_id, 'rg-aek27tc********')
self.assertEqual(result.acl.grant, 'private')
self.assertEqual(result.comment, 'test')


if __name__ == '__main__':
unittest.main()

0 comments on commit 91167d8

Please sign in to comment.