Невозможно получить доступ к данным 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
Другие вопросы по тегам