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()