Невозможно получить доступ к данным HTTP-запроса после ожидания в Python3 .5 asyncio - PullRequest
0 голосов
/ 09 июля 2020

Я пытался поиграть с 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 ]

2 голосов
/ 09 июля 2020

Вы правы, вы ждете будущего своего request. Но когда это будущее сделано, и вы получили свой ответ, неясно, доступно ли все содержимое ответа.

Вы можете увидеть это в документации aiohttp.ClientResponse :

сопрограмма json (*, encoding = None, загружает = 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()
0 голосов
/ 09 июля 2020

Не уверен, что правильно понял ваш вопрос, но вы ищете asyncio.run?

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