Невозможно получить доступ к данным HTTP-запроса после ожидания в Python3.5 asyncio
Я пытался поиграть с Python3.5 aiohttp и написал эту простую функцию-оболочку -
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
Затем у меня есть следующий код, использующий эту функцию -
http_future = self.perform_async_http(url, "post", data, headers)
res = await http_future
print(res.json())
Проблема в том, что res.json()
или res.text()
возвращает совместную процедуру. Доступ к таким свойствам, какres.status
работает хорошо, но text()
или json()
возвращает сопрограмму, из которой я не могу получить фактический ответ.
Я думаю, что, вероятно, что-то не понимаю, но я подумал, что ожидание в будущем должно возвращать фактическое значение, когда оно будет готово.
Где я не прав?
2 ответа
Вы правы, вы ждете будущего request
ты сделал. Но когда это будущее сделано и вы получили свой ответ, неясно, все ли содержание ответа еще доступно.
Следовательно, доступ к некоторой полезной нагрузке ответов - это будущее, которого вы должны ждать.
Вы можете увидеть это в документации aiohttp.ClientResponse:
сопрограмма json(*, кодировка = Нет, загружает =json.loads, content_type='application/json')
Прочитать тело ответа как JSON, вернуть dict, используя указанную кодировку и загрузчик. Если данные все еще недоступны, будет выполнен вызов чтения (...)
Это должно работать так, как вы этого ожидаете:
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()
Я не уверен, правильно ли я понял ваш вопрос, но вы ищете asyncio.run
?
>>> async def f():
... return 1
...
>>> print(f())
<coroutine object f at 0x000002CEE50AC5C0>
>>> print(asyncio.run(f()))
1