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

aiohttp client closes files after sending #3654

Closed
Rapptz opened this issue Mar 18, 2019 · 2 comments
Closed

aiohttp client closes files after sending #3654

Rapptz opened this issue Mar 18, 2019 · 2 comments

Comments

@Rapptz
Copy link

Rapptz commented Mar 18, 2019

Long story short

aiohttp seems to close files after the request is over, meaning a file object cannot be reused once a request is sent.

Expected behaviour

The file should not be closed and I can reuse my file objects following a seek call.

Actual behaviour

aiohttp closes the file instead.

Traceback (most recent call last):
  File "test.py", line 31, in <module>
    asyncio.get_event_loop().run_until_complete(run())
  File "...\Python36\lib\asyncio\base_events.py", line 466, in run_until_complete
    return future.result()
  File "test.py", line 27, in run
    b.seek(0)
ValueError: I/O operation on closed file.

Steps to reproduce

import asyncio
import io
import aiohttp

async def run():
    b = io.BytesIO(b'test')
    async with aiohttp.ClientSession() as sess:
        for _ in range(2):
            b.seek(0)
            async with sess.post('https://httpbin.org/post', data=b) as resp:
                print(await resp.text())

asyncio.get_event_loop().run_until_complete(run())

The equivalent requests code does not error:

b = io.BytesIO(b'test')
for _ in range(2):
    b.seek(0)
    r = requests.post('https://httpbin.org/post', data=b)
    print(r.text)

Your environment

aiohttp version: 3.5.4
Python version: 3.6.1
OS: Windows 8.1

@aio-libs-bot
Copy link

GitMate.io thinks the contributor most likely able to help you is @asvetlov.

Possibly related issues are #3296 (aiohttp client session. it doesn't close a connection after keepalive_timeout), #1907 (aiohttp 2.x closing client request data stream), #3628 (Session not closed in aiohttp.request after exception), #2849 (Getting Connection closed with aiohttp client), and #58 (aiohttp.HttpClient).

@Rapptz
Copy link
Author

Rapptz commented Mar 18, 2019

I searched github earlier and didn't see the duplicate discussion in #1907 sorry.

If this is truly by design (and it seems to be) patching the close method to do nothing and then putting it back will work fine, e.g.

async def run():
    b = io.BytesIO(b'test')
    original = b.close
    b.close = lambda: None
    try:
        async with aiohttp.ClientSession() as sess:
            for _ in range(2):
                b.seek(0)
                async with sess.post('https://httpbin.org/post', data=b) as resp:
                    print(await resp.text())
    finally:
        b.close = original

The reason I needed the file to stay open is because I wanted to retry requests if they failed.

@Rapptz Rapptz closed this as completed Mar 18, 2019
@lock lock bot added the outdated label Mar 17, 2020
@lock lock bot locked as resolved and limited conversation to collaborators Mar 17, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants