简体   繁体   中英

Unable to access Http request data after await in Python3.5 asyncio

I've been trying to play with Python3.5 aiohttp and I wrote this simple wrapper function -

 async def perform_async_http(self, url, method, data='', headers={}):
    async with aiohttp.ClientSession() as session:
        if method.lower() == 'get':
            async with session.get(url, headers=headers) as response:
                return response
        async with session.post(url, data=data, headers=headers) as response:
            return response

Then, I have the following code using this function -

http_future = self.perform_async_http(url, "post", data, headers)
res = await http_future
print(res.json())

The problem is that res.json() or res.text() returns a co-routine. Accessing properties like res.status works well, but text() or json() returns a co-routine from which I cannot retrieve the actual response.

I think I probably don't understand something through, but I thought that awaiting on a future should return the actual value when it's ready.

Where am I wrong?

You are right, you are awaiting the future of the request you made. But when this future is done and you got your response, it is unclear that every content of the response is available yet.

Therefore, the access to some of the responses payload itself is a future you have to await.

You can see this in the aiohttp.ClientResponse documentation :

coroutine json(*, encoding=None, loads=json.loads, content_type='application/json')

Read response's body as JSON, return dict using specified encoding and loader. If data is not still available a read call will be done (...)

This should work as you expect it:

 async def perform_async_http(self, url, method, data='', headers={}):
    async with aiohttp.ClientSession() as session:
        if method.lower() == 'get':
            async with session.get(url, headers=headers) as response:
                return await response.json()
        async with session.post(url, data=data, headers=headers) as response:
            return await response.json()

I'm not sure if I understood your question right, but are you looking for asyncio.run ?

>>> async def f():
...     return 1
...
>>> print(f())
<coroutine object f at 0x000002CEE50AC5C0>
>>> print(asyncio.run(f()))
1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM