Skip to content

Commit

Permalink
bump botocore to 1.29.76 (#999)
Browse files Browse the repository at this point in the history
  • Loading branch information
jakob-keller authored Mar 7, 2023
1 parent 22a1a4a commit 72b8dd5
Show file tree
Hide file tree
Showing 17 changed files with 1,149 additions and 100 deletions.
4 changes: 4 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
Changes
-------
2.5.0 (2023-03-06)
^^^^^^^^^^^^^^^^^^
* bump botocore to 1.29.76 (thanks @jakob-keller #999)

2.4.2 (2022-12-22)
^^^^^^^^^^^^^^^^^^
* fix retries (#988)
Expand Down
2 changes: 1 addition & 1 deletion aiobotocore/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2.4.2'
__version__ = '2.5.0'
83 changes: 83 additions & 0 deletions aiobotocore/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from .config import AioConfig
from .endpoint import AioEndpointCreator
from .regions import AioEndpointRulesetResolver
from .signers import AioRequestSigner


Expand All @@ -23,6 +24,9 @@ def get_client_args(
scoped_config,
client_config,
endpoint_bridge,
auth_token=None,
endpoints_ruleset_data=None,
partition_data=None,
):
final_args = self.compute_client_args(
service_model,
Expand Down Expand Up @@ -54,6 +58,7 @@ def get_client_args(
endpoint_config['signature_version'],
credentials,
event_emitter,
auth_token,
)

config_kwargs['s3'] = s3_config
Expand Down Expand Up @@ -86,6 +91,21 @@ def get_client_args(
protocol, parameter_validation
)
response_parser = botocore.parsers.create_parser(protocol)

ruleset_resolver = self._build_endpoint_resolver(
endpoints_ruleset_data,
partition_data,
client_config,
service_model,
endpoint_region_name,
region_name,
endpoint_url,
endpoint,
is_secure,
endpoint_bridge,
event_emitter,
)

return {
'serializer': serializer,
'endpoint': endpoint,
Expand All @@ -97,4 +117,67 @@ def get_client_args(
'client_config': new_config,
'partition': partition,
'exceptions_factory': self._exceptions_factory,
'endpoint_ruleset_resolver': ruleset_resolver,
}

def _build_endpoint_resolver(
self,
endpoints_ruleset_data,
partition_data,
client_config,
service_model,
endpoint_region_name,
region_name,
endpoint_url,
endpoint,
is_secure,
endpoint_bridge,
event_emitter,
):
if endpoints_ruleset_data is None:
return None

# The legacy EndpointResolver is global to the session, but
# EndpointRulesetResolver is service-specific. Builtins for
# EndpointRulesetResolver must not be derived from the legacy
# endpoint resolver's output, including final_args, s3_config,
# etc.
s3_config_raw = self.compute_s3_config(client_config) or {}
service_name_raw = service_model.endpoint_prefix
# Maintain complex logic for s3 and sts endpoints for backwards
# compatibility.
if service_name_raw in ['s3', 'sts'] or region_name is None:
eprv2_region_name = endpoint_region_name
else:
eprv2_region_name = region_name
resolver_builtins = self.compute_endpoint_resolver_builtin_defaults(
region_name=eprv2_region_name,
service_name=service_name_raw,
s3_config=s3_config_raw,
endpoint_bridge=endpoint_bridge,
client_endpoint_url=endpoint_url,
legacy_endpoint_url=endpoint.host,
)
# botocore does not support client context parameters generically
# for every service. Instead, the s3 config section entries are
# available as client context parameters. In the future, endpoint
# rulesets of services other than s3/s3control may require client
# context parameters.
client_context = (
s3_config_raw if self._is_s3_service(service_name_raw) else {}
)
sig_version = (
client_config.signature_version
if client_config is not None
else None
)
return AioEndpointRulesetResolver(
endpoint_ruleset_data=endpoints_ruleset_data,
partition_data=partition_data,
service_model=service_model,
builtins=resolver_builtins,
client_context=client_context,
event_emitter=event_emitter,
use_ssl=is_secure,
requested_auth_scheme=sig_version,
)
143 changes: 109 additions & 34 deletions aiobotocore/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@
ClientCreator,
ClientEndpointBridge,
PaginatorDocstring,
S3ArnParamHandler,
S3EndpointSetter,
logger,
resolve_checksum_context,
)
from botocore.discovery import block_endpoint_discovery_required_operations
from botocore.exceptions import OperationNotPageableError
from botocore.exceptions import OperationNotPageableError, UnknownServiceError
from botocore.history import get_global_history_recorder
from botocore.hooks import first_non_none_response
from botocore.utils import get_service_module_name
Expand All @@ -22,7 +20,7 @@
from .httpchecksum import apply_request_checksum
from .paginate import AioPaginator
from .retries import adaptive, standard
from .utils import AioS3RegionRedirector
from .utils import AioS3RegionRedirectorv2

history_recorder = get_global_history_recorder()

Expand All @@ -39,12 +37,27 @@ async def create_client(
scoped_config=None,
api_version=None,
client_config=None,
auth_token=None,
):
responses = await self._event_emitter.emit(
'choose-service-name', service_name=service_name
)
service_name = first_non_none_response(responses, default=service_name)
service_model = self._load_service_model(service_name, api_version)
try:
endpoints_ruleset_data = self._load_service_endpoints_ruleset(
service_name, api_version
)
partition_data = self._loader.load_data('partitions')
except UnknownServiceError:
endpoints_ruleset_data = None
partition_data = None
logger.info(
'No endpoints ruleset found for service %s, falling back to '
'legacy endpoint routing.',
service_name,
)

cls = await self._create_client_class(service_name, service_model)
region_name, client_config = self._normalize_fips_region(
region_name, client_config
Expand All @@ -55,6 +68,9 @@ async def create_client(
client_config,
service_signing_name=service_model.metadata.get('signingName'),
config_store=self._config_store,
service_signature_version=service_model.metadata.get(
'signatureVersion'
),
)
client_args = self._get_client_args(
service_model,
Expand All @@ -66,26 +82,20 @@ async def create_client(
scoped_config,
client_config,
endpoint_bridge,
auth_token,
endpoints_ruleset_data,
partition_data,
)
service_client = cls(**client_args)
self._register_retries(service_client)
self._register_eventbridge_events(
service_client, endpoint_bridge, endpoint_url
)
self._register_s3_events(
service_client,
endpoint_bridge,
endpoint_url,
client_config,
scoped_config,
)
self._register_s3_control_events(
service_client,
endpoint_bridge,
endpoint_url,
client_config,
scoped_config,
client=service_client,
endpoint_bridge=None,
endpoint_url=None,
client_config=client_config,
scoped_config=scoped_config,
)
self._register_s3_control_events(client=service_client)
self._register_endpoint_discovery(
service_client, endpoint_url, client_config
)
Expand Down Expand Up @@ -222,17 +232,7 @@ def _register_s3_events(
):
if client.meta.service_model.service_name != 's3':
return
AioS3RegionRedirector(endpoint_bridge, client).register()
S3ArnParamHandler().register(client.meta.events)
use_fips_endpoint = client.meta.config.use_fips_endpoint
S3EndpointSetter(
endpoint_resolver=self._endpoint_resolver,
region=client.meta.region_name,
s3_config=client.meta.config.s3,
endpoint_url=endpoint_url,
partition=client.meta.partition,
use_fips_endpoint=use_fips_endpoint,
).register(client.meta.events)
AioS3RegionRedirectorv2(None, client).register()
self._set_s3_presign_signature_version(
client.meta, client_config, scoped_config
)
Expand All @@ -248,6 +248,9 @@ def _get_client_args(
scoped_config,
client_config,
endpoint_bridge,
auth_token,
endpoints_ruleset_data,
partition_data,
):
# This is a near copy of ClientCreator. What's replaced
# is ClientArgsCreator->AioClientArgsCreator
Expand All @@ -269,6 +272,9 @@ def _get_client_args(
scoped_config,
client_config,
endpoint_bridge,
auth_token,
endpoints_ruleset_data,
partition_data,
)


Expand Down Expand Up @@ -318,8 +324,15 @@ async def _make_api_call(self, operation_name, api_params):
'has_streaming_input': operation_model.has_streaming_input,
'auth_type': operation_model.auth_type,
}
endpoint_url, additional_headers = await self._resolve_endpoint_ruleset( # noqa: BLK100
operation_model, api_params, request_context
)
request_dict = await self._convert_to_request_dict(
api_params, operation_model, context=request_context
api_params=api_params,
operation_model=operation_model,
endpoint_url=endpoint_url,
context=request_context,
headers=additional_headers,
)
resolve_checksum_context(request_dict, operation_model, api_params)

Expand Down Expand Up @@ -378,7 +391,13 @@ async def _make_request(
raise

async def _convert_to_request_dict(
self, api_params, operation_model, context=None
self,
api_params,
operation_model,
endpoint_url,
context=None,
headers=None,
set_user_agent_header=True,
):
api_params = await self._emit_api_params(
api_params, operation_model, context
Expand All @@ -388,10 +407,16 @@ async def _convert_to_request_dict(
)
if not self._client_config.inject_host_prefix:
request_dict.pop('host_prefix', None)
if headers is not None:
request_dict['headers'].update(headers)
if set_user_agent_header:
user_agent = self._client_config.user_agent
else:
user_agent = None
prepare_request_dict(
request_dict,
endpoint_url=self._endpoint.host,
user_agent=self._client_config.user_agent,
endpoint_url=endpoint_url,
user_agent=user_agent,
context=context,
)
return request_dict
Expand Down Expand Up @@ -421,6 +446,56 @@ async def _emit_api_params(self, api_params, operation_model, context):
)
return api_params

async def _resolve_endpoint_ruleset(
self,
operation_model,
params,
request_context,
ignore_signing_region=False,
):
"""Returns endpoint URL and list of additional headers returned from
EndpointRulesetResolver for the given operation and params. If the
ruleset resolver is not available, for example because the service has
no endpoints ruleset file, the legacy endpoint resolver's value is
returned.
Use ignore_signing_region for generating presigned URLs or any other
situtation where the signing region information from the ruleset
resolver should be ignored.
Returns tuple of URL and headers dictionary. Additionally, the
request_context dict is modified in place with any signing information
returned from the ruleset resolver.
"""
if self._ruleset_resolver is None:
endpoint_url = self.meta.endpoint_url
additional_headers = {}
else:
endpoint_info = await self._ruleset_resolver.construct_endpoint(
operation_model=operation_model,
call_args=params,
request_context=request_context,
)
endpoint_url = endpoint_info.url
additional_headers = endpoint_info.headers
# If authSchemes is present, overwrite default auth type and
# signing context derived from service model.
auth_schemes = endpoint_info.properties.get('authSchemes')
if auth_schemes is not None:
auth_info = self._ruleset_resolver.auth_schemes_to_signing_ctx(
auth_schemes
)
auth_type, signing_context = auth_info
request_context['auth_type'] = auth_type
if 'region' in signing_context and ignore_signing_region:
del signing_context['region']
if 'signing' in request_context:
request_context['signing'].update(signing_context)
else:
request_context['signing'] = signing_context

return endpoint_url, additional_headers

def get_paginator(self, operation_name):
"""Create a paginator for an operation.
Expand Down
Loading

0 comments on commit 72b8dd5

Please sign in to comment.