Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 68 additions & 4 deletions alibabacloud_oss_v2/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from typing import Any, Optional, Dict, Iterable, List, Union, cast, Tuple, Iterator
from urllib.parse import urlparse, ParseResult, urlencode, quote
from xml.etree import ElementTree as ET
import json
from . import retry
from . import transport
from . import exceptions
Expand All @@ -28,6 +29,7 @@
BodyType,
OperationInput,
OperationOutput,
EndpointProvider,
)


Expand Down Expand Up @@ -109,6 +111,7 @@ def __init__(
feature_flags: Optional[int] = None,
additional_headers: Optional[List[str]] = None,
operation_timeout: Optional[Union[int, float]] = None,
endpoint_provider: Optional[EndpointProvider] = None,
) -> None:
self.product = product
self.region = region
Expand All @@ -126,7 +129,7 @@ def __init__(
self.feature_flags = feature_flags or defaults.FF_DEFAULT
self.additional_headers = additional_headers
self.operation_timeout = operation_timeout

self.endpoint_provider = endpoint_provider

class _InnerOptions:
"""client runtime's information."""
Expand All @@ -137,7 +140,6 @@ def __init__(
self.user_agent = user_agent



class _ClientImplMixIn:
"""Client implement"""

Expand Down Expand Up @@ -219,7 +221,10 @@ def build_request_context(self, op_input: OperationInput, options: _Options, inn
"""build request context
"""
# host & path
url = _build_url(op_input, options)
if options.endpoint_provider is not None:
url = options.endpoint_provider.build_url(op_input)
else:
url = _build_url(op_input, options)

# queries
if op_input.parameters is not None:
Expand Down Expand Up @@ -368,7 +373,10 @@ def service_error_response_handler(response: HttpResponse) -> None:
if not response.is_stream_consumed:
_ = response.read()

raise _to_service_error(response)
if response.headers.get('Content-Type', '') == 'application/json':
raise _to_service_error_json(response)
else:
raise _to_service_error(response)

# insert service error responsed handler first
handlers.append(service_error_response_handler)
Expand Down Expand Up @@ -533,6 +541,7 @@ def _resolve_endpoint(config: Config, options: _Options) -> None:
options.endpoint = urlparse(endpoint)



def _resolve_retryer(_: Config, options: _Options) -> None:
"""retryer"""
if options.retryer:
Expand Down Expand Up @@ -677,6 +686,61 @@ def _to_service_error(response: HttpResponse) -> exceptions.ServiceError:
error_fileds=error_fileds
)

def _to_service_error_json(response: HttpResponse) -> exceptions.ServiceError:
timestamp = serde.deserialize_httptime(response.headers.get('Date'))
content = response.content or b''
response.close()

error_fileds = {}
code = 'BadErrorResponse'
message = ''
ec = ''
request_id = ''
err_body = b''
try:
err_body = content
if len(err_body) == 0:
err_body = base64.b64decode(
response.headers.get('x-oss-err', ''))
root = json.loads(err_body)
errElem = root.get('Error', None)
if errElem is not None:
for k, v in errElem.items():
if isinstance(v, str):
error_fileds[k] = v
message = error_fileds.get('Message', '')
code = error_fileds.get('Code', '')
ec = error_fileds.get('EC', '')
request_id = error_fileds.get('RequestId', '')
else:
message = f'Expect root node Error, but get {root.keys()}.'
except json.JSONDecodeError as e:
errstr = err_body.decode()
if '"Error":' in errstr:
m = re.search('"Code":(.*),', errstr)
if m:
code = m.group(1).strip(' "')
m = re.search('<Message>(.*)</Message>', errstr)
if m:
message = m.group(1).strip(' "')
if len(message) == 0:
message = f'Failed to parse json from response body due to: {str(e)}. With part response body {err_body[:256]}.'
except Exception as e:
message = f'The body of the response was not readable, due to : {str(e)}.'

return exceptions.ServiceError(
status_code=response.status_code,
code=code,
message=message,
request_id=request_id or response.headers.get('x-oss-request-id', ''),
ec=ec or response.headers.get('x-oss-ec', ''),
timestamp=timestamp,
request_target=f'{response.request.method} {response.request.url}',
snapshot=content,
headers=response.headers,
error_fileds=error_fileds
)

def _build_user_agent(config: Config) -> str:
if config.user_agent:
return f'{utils.get_default_user_agent()}/{config.user_agent}'
Expand Down
5 changes: 4 additions & 1 deletion alibabacloud_oss_v2/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ def __init__(
additional_headers: Optional[List[str]] = None,
user_agent: Optional[str] = None,
cloud_box_id: Optional[str] = None,
enable_auto_detect_cloud_box_id: Optional[bool] = None
enable_auto_detect_cloud_box_id: Optional[bool] = None,
account_id: Optional[str] = None
) -> None:
"""
Args:
Expand Down Expand Up @@ -73,6 +74,7 @@ def __init__(
user_agent: (str, optional): The optional user specific identifier appended to the User-Agent header.
cloud_box_id: (str, optional): The cloud box id.
enable_auto_detect_cloud_box_id: (bool, optional): The cloud box id is automatically extracted from endpoint.
account_id: (str, optional): The account id, must be required in vectors options.
"""
self.region = region
self.endpoint = endpoint
Expand All @@ -98,6 +100,7 @@ def __init__(
self.user_agent = user_agent
self.cloud_box_id = cloud_box_id
self.enable_auto_detect_cloud_box_id = enable_auto_detect_cloud_box_id
self.account_id = account_id

def load_default() -> Config:
"""Using the SDK's default configuration"""
Expand Down
1 change: 0 additions & 1 deletion alibabacloud_oss_v2/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ def from_region(region:str, disable_ssl:bool, etype:str) -> str:

return endpoint


def is_ip(hostname:str):
"""Check whether the host name is an IP address."""
is_ipv6 = False
Expand Down
6 changes: 5 additions & 1 deletion alibabacloud_oss_v2/models/bucket_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class PutBucketRequest(serde.RequestModel):
"acl": {"tag": "input", "position": "header", "rename": "x-oss-acl"},
"resource_group_id": {"tag": "input", "position": "header", "rename": "x-oss-resource-group-id"},
"create_bucket_configuration": {"tag": "input", "position": "body", "rename": "CreateBucketConfiguration", "type": "xml"},
"bucket_tagging": {"tag": "input", "position": "header", "rename": "x-oss-bucket-tagging"},
}

def __init__(
Expand All @@ -50,6 +51,7 @@ def __init__(
acl: Optional[str] = None,
resource_group_id: Optional[str] = None,
create_bucket_configuration: Optional["CreateBucketConfiguration"] = None,
bucket_tagging: Optional[str] = None,
**kwargs: Any
) -> None:
"""
Expand All @@ -58,13 +60,15 @@ def __init__(
acl (str, optional): The access control list (ACL) of the bucket.
resource_group_id (str, optional): The ID of the resource group.
create_bucket_configuration (CreateBucketConfiguration, optional):
The configuration information for the bucket.
The configuration information for the bucket.
bucket_tagging (str, optional): The tagging information for the bucket.
"""
super().__init__(**kwargs)
self.bucket = bucket
self.acl = acl
self.resource_group_id = resource_group_id
self.create_bucket_configuration = create_bucket_configuration
self.bucket_tagging = bucket_tagging


class PutBucketResult(serde.ResultModel):
Expand Down
4 changes: 4 additions & 0 deletions alibabacloud_oss_v2/models/bucket_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class LoggingEnabled(serde.Model):
_attribute_map = {
'target_bucket': {'tag': 'xml', 'rename': 'TargetBucket', 'type': 'str'},
'target_prefix': {'tag': 'xml', 'rename': 'TargetPrefix', 'type': 'str'},
'logging_role': {'tag': 'xml', 'rename': 'LoggingRole', 'type': 'str'},
}

_xml_map = {
Expand All @@ -72,16 +73,19 @@ def __init__(
self,
target_bucket: Optional[str] = None,
target_prefix: Optional[str] = None,
logging_role: Optional[str] = None,
**kwargs: Any
) -> None:
"""
Args:
target_bucket (str, optional): The bucket that stores access logs.
target_prefix (str, optional): The prefix of the log objects. This parameter can be left empty.
logging_role (str, optional): The role used for logging operations.
"""
super().__init__(**kwargs)
self.target_bucket = target_bucket
self.target_prefix = target_prefix
self.logging_role = logging_role


class UserDefinedLogFieldsConfiguration(serde.Model):
Expand Down
2 changes: 1 addition & 1 deletion alibabacloud_oss_v2/models/bucket_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import Optional, List, Any, Union
from .. import serde
from .object_basic import TagSet, Tag

from dataclasses import dataclass

class Tagging(serde.Model):
"""
Expand Down
2 changes: 1 addition & 1 deletion alibabacloud_oss_v2/models/object_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from .. import serde
from ..types import BodyType, StreamBody, AsyncStreamBody
from .bucket_basic import Owner

from dataclasses import dataclass

class PutObjectRequest(serde.RequestModel):
"""The request for the PutObject operation."""
Expand Down
2 changes: 2 additions & 0 deletions alibabacloud_oss_v2/models/public_access_block.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import datetime
from dataclasses import dataclass
from typing import Optional, List, Any, Union
from .. import serde

Expand Down Expand Up @@ -71,6 +72,7 @@ def __init__(
super().__init__(**kwargs)
self.public_access_block_configuration = public_access_block_configuration

@dataclass
class PutPublicAccessBlockRequest(serde.RequestModel):
"""
The request for the PutPublicAccessBlock operation.
Expand Down
Loading