Skip to content

Commit 3faf885

Browse files
authored
bump botocore (#844)
1 parent 60a885a commit 3faf885

14 files changed

+81
-33
lines changed

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pip-delete-this-directory.txt
3636
# Unit test / coverage reports
3737
htmlcov/
3838
.tox/
39-
.coverage
39+
.coverage*
4040
.cache
4141
nosetests.xml
4242
coverage.xml
@@ -61,3 +61,5 @@ target/
6161
*.iml
6262
# rope
6363
.ropeproject
64+
65+
Pipfile.lock

CHANGES.rst

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
Changes
22
-------
3+
1.2.0 (2021-01-11)
4+
^^^^^^^^^^^^^^^^^^
5+
* bump botocore to 1.19.52
6+
* use passed in http_session_cls param to create_client (#797)
7+
38
1.1.2 (2020-10-07)
49
^^^^^^^^^^^^^^^^^^
510
* fix AioPageIterator search method #831 (thanks @joseph-jones)

Makefile

+6-2
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,25 @@ cov cover coverage: flake
2222
mototest:
2323
docker pull alpine
2424
docker pull lambci/lambda:python3.8
25-
BOTO_CONFIG=/dev/null pipenv run python3 -Wd -X tracemalloc=5 -X faulthandler -m pytest -vv -m moto -n auto --cov-report term --cov-report html --cov --log-cli-level=DEBUG aiobotocore tests
25+
BOTO_CONFIG=/dev/null pipenv run python3 -Wd -X tracemalloc=5 -X faulthandler -m pytest -vv -m moto -n auto --cov-report term --cov-report html --cov=aiobotocore --cov=tests --log-cli-level=DEBUG aiobotocore tests
2626
@echo "open file://`pwd`/htmlcov/index.html"
2727

2828

2929
clean:
3030
rm -rf `find . -name __pycache__`
31+
rm -rf `find . -name .pytest_cache`
32+
rm -rf `find . -name *.egg-info`
3133
rm -f `find . -type f -name '*.py[co]' `
3234
rm -f `find . -type f -name '*~' `
3335
rm -f `find . -type f -name '.*~' `
3436
rm -f `find . -type f -name '@*' `
3537
rm -f `find . -type f -name '#*#' `
3638
rm -f `find . -type f -name '*.orig' `
3739
rm -f `find . -type f -name '*.rej' `
38-
rm -f .coverage
40+
rm -f .coverage*
3941
rm -rf coverage
42+
rm -rf coverage.xml
43+
rm -rf htmlcov
4044
rm -rf build
4145
rm -rf cover
4246
rm -rf dist

aiobotocore/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
from .session import get_session, AioSession
22

33
__all__ = ['get_session', 'AioSession']
4-
__version__ = '1.1.2'
4+
__version__ = '1.2.0'

aiobotocore/client.py

+3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ async def create_client(self, service_name, region_name, is_secure=True,
3434
verify, credentials, scoped_config, client_config, endpoint_bridge)
3535
service_client = cls(**client_args)
3636
self._register_retries(service_client)
37+
self._register_s3_events(
38+
service_client, endpoint_bridge, endpoint_url, client_config,
39+
scoped_config)
3740
self._register_s3_events(
3841
service_client, endpoint_bridge, endpoint_url, client_config,
3942
scoped_config)

aiobotocore/credentials.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ def create_credential_resolver(session, cache=None, region_name=None):
4646
num_attempts = session.get_config_variable('metadata_service_num_attempts')
4747
disable_env_vars = session.instance_variables().get('profile') is not None
4848

49+
imds_config = {
50+
'ec2_metadata_service_endpoint': session.get_config_variable(
51+
'ec2_metadata_service_endpoint'),
52+
'imds_use_ipv6': session.get_config_variable('imds_use_ipv6')
53+
}
54+
4955
if cache is None:
5056
cache = {}
5157

@@ -55,7 +61,8 @@ def create_credential_resolver(session, cache=None, region_name=None):
5561
iam_role_fetcher=AioInstanceMetadataFetcher(
5662
timeout=metadata_timeout,
5763
num_attempts=num_attempts,
58-
user_agent=session.user_agent())
64+
user_agent=session.user_agent(),
65+
config=imds_config)
5966
)
6067

6168
profile_provider_builder = AioProfileProviderBuilder(
@@ -817,6 +824,8 @@ async def load_credentials(self):
817824

818825

819826
class AioSSOCredentialFetcher(AioCachedCredentialFetcher):
827+
_UTC_DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
828+
820829
def __init__(self, start_url, sso_region, role_name, account_id,
821830
client_creator, token_loader=None, cache=None,
822831
expiry_window_seconds=None):
@@ -826,7 +835,6 @@ def __init__(self, start_url, sso_region, role_name, account_id,
826835
self._account_id = account_id
827836
self._start_url = start_url
828837
self._token_loader = token_loader
829-
830838
super(AioSSOCredentialFetcher, self).__init__(
831839
cache, expiry_window_seconds
832840
)
@@ -846,7 +854,7 @@ def _parse_timestamp(self, timestamp_ms):
846854
# fromtimestamp expects seconds so: milliseconds / 1000 = seconds
847855
timestamp_seconds = timestamp_ms / 1000.0
848856
timestamp = datetime.datetime.fromtimestamp(timestamp_seconds, tzutc())
849-
return _serialize_if_needed(timestamp)
857+
return timestamp.strftime(self._UTC_DATE_FORMAT)
850858

851859
async def _get_credentials(self):
852860
"""Get credentials by calling SSO get role credentials."""

aiobotocore/endpoint.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ def create_endpoint(self, service_model, region_name, endpoint_url,
304304
ssl_context=ssl_context,
305305
**connector_args)
306306

307-
aio_session = aiohttp.ClientSession(
307+
aio_session = http_session_cls(
308308
connector=connector,
309309
timeout=timeout,
310310
skip_auto_headers={'CONTENT-TYPE'},

aiobotocore/response.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ async def __anext__(self):
7575

7676
anext = __anext__
7777

78-
async def iter_lines(self, chunk_size=1024):
78+
async def iter_lines(self, chunk_size=1024, keepends=False):
7979
"""Return an iterator to yield lines from the raw stream.
8080
8181
This is achieved by reading chunk of bytes (of size chunk_size) at a
@@ -85,10 +85,10 @@ async def iter_lines(self, chunk_size=1024):
8585
async for chunk in self.iter_chunks(chunk_size):
8686
lines = (pending + chunk).splitlines(True)
8787
for line in lines[:-1]:
88-
yield line.splitlines()[0]
88+
yield line.splitlines(keepends)[0]
8989
pending = lines[-1]
9090
if pending:
91-
yield pending.splitlines()[0]
91+
yield pending.splitlines(keepends)[0]
9292

9393
async def iter_chunks(self, chunk_size=_DEFAULT_CHUNK_SIZE):
9494
"""Return an iterator to yield chunks of chunk_size bytes from the raw

aiobotocore/signers.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,11 @@ async def sign(self, operation_name, request, region_name=None,
4646
}
4747
if expires_in is not None:
4848
kwargs['expires'] = expires_in
49-
if not explicit_region_name and request.context.get(
50-
'signing', {}).get('region'):
51-
kwargs['region_name'] = request.context['signing']['region']
49+
signing_context = request.context.get('signing', {})
50+
if not explicit_region_name and signing_context.get('region'):
51+
kwargs['region_name'] = signing_context['region']
52+
if signing_context.get('signing_name'):
53+
kwargs['signing_name'] = signing_context['signing_name']
5254
try:
5355
auth = await self.get_auth_instance(**kwargs)
5456
except UnknownSignatureVersionError as e:

aiobotocore/utils.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
from botocore.utils import ContainerMetadataFetcher, InstanceMetadataFetcher, \
88
IMDSFetcher, get_environ_proxies, BadIMDSRequestError, S3RegionRedirector, \
99
ClientError
10-
from botocore.exceptions import MetadataRetrievalError
10+
from botocore.exceptions import (
11+
InvalidIMDSEndpointError, MetadataRetrievalError,
12+
)
1113
import botocore.awsrequest
1214

1315

@@ -58,6 +60,13 @@ async def _fetch_metadata_token(self):
5860
logger.debug(
5961
"Caught retryable HTTP exception while making metadata "
6062
"service request to %s: %s", url, e, exc_info=True)
63+
except aiohttp.client_exceptions.ClientConnectorError as e:
64+
if getattr(e, 'errno', None) == 8 or \
65+
str(getattr(e, 'os_error', None)) == \
66+
'Domain name not found': # threaded vs async resolver
67+
raise InvalidIMDSEndpointError(endpoint=url, error=e)
68+
else:
69+
raise
6170

6271
return None
6372

aiobotocore/waiter.py

+19-5
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ async def wait(self, **kwargs):
2525
config = kwargs.pop('WaiterConfig', {})
2626
sleep_amount = config.get('Delay', self.config.delay)
2727
max_attempts = config.get('MaxAttempts', self.config.max_attempts)
28+
last_matched_acceptor = None
2829
num_attempts = 0
2930

3031
while True:
3132
response = await self._operation_method(**kwargs)
3233
num_attempts += 1
3334
for acceptor in acceptors:
3435
if acceptor.matcher_func(response):
36+
last_matched_acceptor = acceptor
3537
current_state = acceptor.state
3638
break
3739
else:
@@ -43,24 +45,36 @@ async def wait(self, **kwargs):
4345
# can just handle here by raising an exception.
4446
raise WaiterError(
4547
name=self.name,
46-
reason=response['Error'].get('Message', 'Unknown'),
47-
last_response=response
48+
reason='An error occurred (%s): %s' % (
49+
response['Error'].get('Code', 'Unknown'),
50+
response['Error'].get('Message', 'Unknown'),
51+
),
52+
last_response=response,
4853
)
4954
if current_state == 'success':
5055
logger.debug("Waiting complete, waiter matched the "
5156
"success state.")
5257
return
5358
if current_state == 'failure':
59+
reason = 'Waiter encountered a terminal failure state: %s' % (
60+
acceptor.explanation
61+
)
5462
raise WaiterError(
5563
name=self.name,
56-
reason='Waiter encountered a terminal failure state',
64+
reason=reason,
5765
last_response=response,
5866
)
5967
if num_attempts >= max_attempts:
68+
if last_matched_acceptor is None:
69+
reason = 'Max attempts exceeded'
70+
else:
71+
reason = 'Max attempts exceeded. Previously accepted state: %s' % (
72+
acceptor.explanation
73+
)
6074
raise WaiterError(
6175
name=self.name,
62-
reason='Max attempts exceeded',
63-
last_response=response
76+
reason=reason,
77+
last_response=response,
6478
)
6579
await asyncio.sleep(sleep_amount)
6680

setup.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# NOTE: When updating botocore make sure to update awscli/boto3 versions below
88
install_requires = [
99
# pegged to also match items in `extras_require`
10-
'botocore>=1.17.44,<1.17.45',
10+
'botocore>=1.19.52,<1.19.53',
1111
'aiohttp>=3.3.1',
1212
'wrapt>=1.10.10',
1313
'aioitertools>=0.5.1',
@@ -19,8 +19,8 @@ def read(f):
1919

2020

2121
extras_require = {
22-
'awscli': ['awscli==1.18.121'],
23-
'boto3': ['boto3==1.14.44'],
22+
'awscli': ['awscli==1.18.212'],
23+
'boto3': ['boto3==1.16.52'],
2424
}
2525

2626

tests/botocore/test_credentials.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,7 @@ def _f(config_loader: Optional[ConfigValueStore] = None) -> AioSession:
10841084
'config_file': 'c',
10851085
'metadata_service_timeout': 1,
10861086
'metadata_service_num_attempts': 1,
1087+
'imds_use_ipv6': 'false',
10871088
}
10881089

10891090
def fake_get_component(self, key):
@@ -1228,15 +1229,15 @@ async def test_sso_credential_fetcher_can_fetch_credentials(
12281229
self.assertEqual(credentials['access_key'], 'foo')
12291230
self.assertEqual(credentials['secret_key'], 'bar')
12301231
self.assertEqual(credentials['token'], 'baz')
1231-
self.assertEqual(credentials['expiry_time'], '2008-09-23T12:43:20UTC')
1232+
self.assertEqual(credentials['expiry_time'], '2008-09-23T12:43:20Z')
12321233
cache_key = '048db75bbe50955c16af7aba6ff9c41a3131bb7e'
12331234
expected_cached_credentials = {
12341235
'ProviderType': 'sso',
12351236
'Credentials': {
12361237
'AccessKeyId': 'foo',
12371238
'SecretAccessKey': 'bar',
12381239
'SessionToken': 'baz',
1239-
'Expiration': '2008-09-23T12:43:20UTC',
1240+
'Expiration': '2008-09-23T12:43:20Z',
12401241
}
12411242
}
12421243
self.assertEqual(self.cache[cache_key], expected_cached_credentials)

tests/test_patches.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
ClientArgsCreator.get_client_args: {'e3a44e6f50159e8e31c3d76f5e8a1110dda495fa'},
7777

7878
# client.py
79-
ClientCreator.create_client: {'ee63a3d60b5917879cb644c1b0aa3fe34538b915'},
79+
ClientCreator.create_client: {'281fbf7afc4e6282e5c881c7a03717c9e5e4e176'},
8080
ClientCreator._create_client_class: {'5e493d069eedbf314e40e12a7886bbdbcf194335'},
8181
ClientCreator._get_client_args: {'555e1e41f93df7558c8305a60466681e3a267ef3'},
8282
ClientCreator._register_s3_events: {'da3fc62a131d63964c8daa0f52124b092fd8f1b4'},
@@ -116,7 +116,7 @@
116116
RefreshableCredentials.get_frozen_credentials:
117117
{'f661c84a8b759786e011f0b1e8a468a0c6294e36'},
118118
SSOCredentialFetcher:
119-
{'e092b115155a06760af6f3c72ccef120979b1201'},
119+
{'d68353a0d2c291d5742f134d28ae1e1419faa4c6'},
120120
SSOProvider.load:
121121
{'f43d79e1520b2a7b7ef85cd537f41e19d4bce806'},
122122
CachedCredentialFetcher._get_credentials:
@@ -185,7 +185,7 @@
185185
{'c028b9776383cc566be10999745b6082f458d902'},
186186
BotoProvider.load: {'9351b8565c2c969937963fc1d3fbc8b3b6d8ccc1'},
187187
OriginalEC2Provider.load: {'bde9af019f01acf3848a6eda125338b2c588c1ab'},
188-
create_credential_resolver: {'5ff7fe49d7636b795a50202ff5c089611f4e27c1'},
188+
create_credential_resolver: {'c6a08bfc59a4e8f59c8b7a846dbb74db649101fd'},
189189
get_credentials: {'ff0c735a388ac8dd7fe300a32c1e36cdf33c0f56'},
190190

191191
# endpoint.py
@@ -226,7 +226,7 @@
226226
RestJSONParser._create_event_stream: {'0564ba55383a71cc1ba3e5be7110549d7e9992f5'},
227227

228228
# response.py
229-
StreamingBody: {'bb4d872649b0c118c9a3d5e44961e1bea92eb79c'},
229+
StreamingBody: {'b77bd0903f9013bc47c01f91c6d9bfb8a504d106'},
230230

231231
# session.py
232232
Session.__init__: {'ccf156a76beda3425fb54363f3b2718dc0445f6d'},
@@ -242,7 +242,7 @@
242242

243243
# signers.py
244244
RequestSigner.handler: {'371909df136a0964ef7469a63d25149176c2b442'},
245-
RequestSigner.sign: {'7df841d3df3f4015763523c1932652aef754287a'},
245+
RequestSigner.sign: {'a07e4caab222bf9375036b1fafaf021ccb5b2bf3'},
246246
RequestSigner.get_auth: {'4f8099bef30f9a72fa3bcaa1bd3d22c4fbd224a8'},
247247
RequestSigner.get_auth_instance: {'4f8099bef30f9a72fa3bcaa1bd3d22c4fbd224a8'},
248248
RequestSigner._choose_signer: {'d1e0e3196ada449d3ae0ec09b8ae9b5868c50d4e'},
@@ -268,9 +268,9 @@
268268
ContainerMetadataFetcher._get_response:
269269
{'7e5acdd2cf0167a047e3d5ee1439565a2f79f6a6'},
270270
# Overrided session and dealing with proxy support
271-
IMDSFetcher.__init__: {'690e37140ccdcd67c7a85ce5d36331491a79954e'},
271+
IMDSFetcher.__init__: {'a0766a5ba7dde9c26f3c51eb38d73f8e6087d492'},
272272
IMDSFetcher._get_request: {'96a0e580cab5a21deb4d2cd7e904aa17d5e1e504'},
273-
IMDSFetcher._fetch_metadata_token: {'4fdad673b4997b1268c6d9dff09a4b99c1cb5e0d'},
273+
IMDSFetcher._fetch_metadata_token: {'dcb147f6c7a425ba9e30be8ad4818be4b781305c'},
274274

275275
InstanceMetadataFetcher.retrieve_iam_role_credentials:
276276
{'76737f6add82a1b9a0dc590cf10bfac0c7026a2e'},
@@ -285,7 +285,7 @@
285285

286286
# waiter.py
287287
NormalizedOperationMethod.__call__: {'79723632d023739aa19c8a899bc2b814b8ab12ff'},
288-
Waiter.wait: {'5502a89ed740fb5d6238a6f72a3a08efc1a9f43b'},
288+
Waiter.wait: {'3a4ff0fdfc78b7ec42bfd41f3e1ba3b741f2d2b9'},
289289
create_waiter_with_client: {'c3d12c9a4293105cc8c2ecfc7e69a2152ad564de'},
290290
}
291291

0 commit comments

Comments
 (0)