Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash with aiohttp 3.1.x related to use of StreamReader #551

Closed
adamrothman opened this issue Mar 22, 2018 · 19 comments
Closed

Crash with aiohttp 3.1.x related to use of StreamReader #551

adamrothman opened this issue Mar 22, 2018 · 19 comments

Comments

@adamrothman
Copy link
Contributor

I'm getting a crash using aiobotocore 0.6.0 with aiohttp 3.1.0 (released yesterday 2018-03-21). It appears to be related to botocore's response checking:

Traceback (most recent call last):
  File "test.py", line 20, in <module>
    loop.run_until_complete(main())
  File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 467, in run_until_complete
    return future.result()
  File "test.py", line 12, in main
    response = await client.describe_table(TableName='orbit-prod-identities')
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/aiobotocore/client.py", line 94, in _make_api_call
    operation_model, request_dict)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/aiobotocore/endpoint.py", line 290, in _send_request
    exception)):
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/aiobotocore/endpoint.py", line 322, in _needs_retry
    caught_exception=caught_exception, request_dict=request_dict)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/hooks.py", line 227, in emit
    return self._emit(event_name, kwargs)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/hooks.py", line 210, in _emit
    response = handler(**kwargs)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/retryhandler.py", line 183, in __call__
    if self._checker(attempts, response, caught_exception):
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/retryhandler.py", line 251, in __call__
    caught_exception)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/retryhandler.py", line 269, in _should_retry
    return self._checker(attempt_number, response, caught_exception)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/retryhandler.py", line 317, in __call__
    caught_exception)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/retryhandler.py", line 220, in __call__
    return self._check_response(attempt_number, response)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/retryhandler.py", line 335, in _check_response
    actual_crc32 = crc32(response[0].content) & 0xffffffff
TypeError: a bytes-like object is required, not 'StreamReader'

Here's a minimal reproducer:

# -*- coding: utf-8 -*-
import asyncio
from pprint import pprint

import aiobotocore


async def main():
    session = aiobotocore.get_session()
    client = session.create_client('dynamodb')

    response = await client.list_tables()
    pprint(response)

    await client.close()


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

I've also tried client.describe_table, which results in the same error. It seems like the semantics for StreamReader have changed such that it can no longer be treated like data.

The crash does not occur with aiohttp 3.0.9.

Environment:

  • Python 3.6.4
  • aiobotocore 0.6.0
  • aiohttp 3.1.0
  • botocore 1.8.21
@thehesiod
Copy link
Collaborator

thehesiod commented Mar 22, 2018

ya, we should have caught in #536 that aiohttp needs to be upper-bound version locked. We need to add a comment so people don't do this again.

@asvetlov
Copy link
Member

Sorry, guys. My personal fault.
Support for sending StreamReader was dropped. I wanted to replace it with support for any async iterator by aio-libs/aiohttp/issues/2802

But I did run too fast.
Now I think the lost functionality is a critical bug, it will be fixed by pushing async iterator feature into next 3.1 bugfix release (coming soon).

Sorry again.
@thehesiod could you postpone the locking aiohttp upper version?

As alternative I see the commitment on publishing a new aiobotocore version with the lock raised up to the latest aiohttp after every aiohttp release if tests are passed. It looks too complex burden.

On my side I wish to use the latest aiobotocore with the latest aiohttp (my company uses both libraries).
I know about aiobotocore pain related to timeouts but I see a big progress on aio-libs/aiohttp/issues/2768
The first PR aio-libs/aiohttp/pull/2842 is not perfect from my perspective but personally I've got a vision how user interface would look like.
I'm expecting to land new timeouts on aiohttp 3.2 1-2 months from now.

@thehesiod
Copy link
Collaborator

@asvetlov no worries! will do

@adamrothman
Copy link
Contributor Author

Thanks guys, libraries these and maintainers like you are why I love Python. 🤗

@asvetlov
Copy link
Member

Fixed by aiohttp 3.1.1 release

@adamrothman adamrothman changed the title Crash with aiohttp 3.1.0 related to use of StreamReader Crash with aiohttp 3.1.x related to use of StreamReader Mar 28, 2018
@adamrothman
Copy link
Contributor Author

@asvetlov I'm still getting the same crash after updating to aiohttp 3.1.1:

Traceback (most recent call last):
  File "test.py", line 21, in <module>
    loop.run_until_complete(main())
  File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 467, in run_until_complete
    return future.result()
  File "test.py", line 13, in main
    response = await client.list_tables()
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/aiobotocore/client.py", line 94, in _make_api_call
    operation_model, request_dict)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/aiobotocore/endpoint.py", line 290, in _send_request
    exception)):
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/aiobotocore/endpoint.py", line 322, in _needs_retry
    caught_exception=caught_exception, request_dict=request_dict)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/hooks.py", line 227, in emit
    return self._emit(event_name, kwargs)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/hooks.py", line 210, in _emit
    response = handler(**kwargs)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/retryhandler.py", line 183, in __call__
    if self._checker(attempts, response, caught_exception):
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/retryhandler.py", line 251, in __call__
    caught_exception)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/retryhandler.py", line 269, in _should_retry
    return self._checker(attempt_number, response, caught_exception)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/retryhandler.py", line 317, in __call__
    caught_exception)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/retryhandler.py", line 220, in __call__
    return self._check_response(attempt_number, response)
  File "/Users/adam/Desktop/aiobotocore-test/venv/lib/python3.6/site-packages/botocore/retryhandler.py", line 335, in _check_response
    actual_crc32 = crc32(response[0].content) & 0xffffffff
TypeError: a bytes-like object is required, not 'StreamReader'

@thehesiod
Copy link
Collaborator

ya, seems like ClientResponse.content is StreamReader and not string/bytes anymore

@asvetlov asvetlov reopened this Mar 29, 2018
@asvetlov
Copy link
Member

But ClientResponse.content was a StreamReader from time of birth.
3.3.1 restored a broken/removed functionality for passing a content as a body: await client.post(url, data=resp.content), nothing more.

@thehesiod
Copy link
Collaborator

@asvetlov @adamrothman figured it out, looks like ClientResponse._content was renamed to ClientResponse._body. Fix will be in: #564

@thehesiod
Copy link
Collaborator

fixed with #569

@nitrocode
Copy link

Thank you for fixing this issue. I just tripped over it on the 0.6.0 version. I tried upgrading and it looks like 0.6.1 has not been published to pypi. Do you mind publishing it @thehesiod ?

@jettify
Copy link
Member

jettify commented May 1, 2018

Probably due to typo 0.6.1a0 was published https://pypi.org/project/aiobotocore/0.6.1a0/

@thehesiod
Copy link
Collaborator

very weird, I don't remember putting a0

@jettify
Copy link
Member

jettify commented May 1, 2018

https://pypi.org/project/aiobotocore/0.7.0/ released new version

@jettify
Copy link
Member

jettify commented May 1, 2018

sigh, this time RST formatting is broken on PyPI

@thehesiod
Copy link
Collaborator

weird, how did that happen?

@jettify
Copy link
Member

jettify commented May 1, 2018

I edited changes.rst and broke formatting #571 , anyway added command to test RST correctness.

@French-Noodles
Copy link

So is there any fix for this now? im kinda confused on how to do it

async def requestingresponse():
  async with aiohttp.ClientSession() as cs:
    async with cs.get(url) as res:
      response = res
      bytes = BytesIO(response._body)
      img = Image.open(bytes)
      img.show()  

asyncio.run(requestingresponse())

this is my code but now im getting this error after i changed .content to ._body

PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x00000272F288E6D0>

@thehesiod
Copy link
Collaborator

you can't directly pass response['Body'] to BytesIO as it's an async stream

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants