Как читать строки потокового API с aiohttp в Python? - PullRequest
0 голосов
/ 10 января 2020

Я пытаюсь преобразовать Python HTTP-клиент с requests в aiohttp. Логика c предназначена для отправки вызова GET на конечную точку REST, которая периодически передает данные и печатает возвращаемые строки.

У меня есть код с использованием запросов с параметром stream=True и iter_lines, работает довольно хорошо:

import json
import requests

def main():
    with requests.get('https://my-streaming-url.com', stream=True) as r:
        if r.encoding is None:
            r.encoding = 'utf-8'
        for line in r.iter_lines(decode_unicode=True):
            if line:
                # Print each line emitted by the streaming api
                print(json.loads(line))

if __name__ == '__main__':
    main()

Теперь я хочу преобразовать этот лог c в aiohttp streaming api и попробовал:

import asyncio
import aiohttp
import json

loop = asyncio.get_event_loop()

async def main():
    r = aiohttp.request('get', 'https://my-streaming-url.com')
    async for line in r.content:
        print(json.loads(line))

if __name__ == '__main__':
    loop.run_until_complete(connect_and_listen())
    loop.close()

Я получаю сообщение об ошибке:

... в connect_and_listen

asyn c для строки в r.content:

AttributeError: объект _SessionRequestContextManager ' не имеет атрибута 'content'

sys: 1: RuntimeWarning: сопрограмма ClientSession._request 'никогда не ожидалась

незакрытый сеанс клиента

client_session: aiohttp.client.ClientSession объект в 0x7fac6ec24310

Я пробовал несколько способов, таких как удаление loop.close() из main, удаление async из for l oop, но ни один не помог.

Что мне здесь не хватает? Как я могу напечатать линии потокового API с aiohttp?

PS: Моя Python версия 3.7.5

Ответы [ 2 ]

1 голос
/ 10 января 2020

Поскольку во всей документации рекомендуется использовать класс ClientSession, этот код также инкапсулировал сеанс, как показано ниже, и он работал:

async def main():
    async with aiohttp.ClientSession(raise_for_status=True) as session:
        async with session.get(cashcog_stream_url) as r:
            async for line in r.content:

Еще один момент - loop.close() явно не влияет на работу приложения и может быть удалено.

1 голос
/ 10 января 2020

Вы пропустили ключевое слово await. aiohttp.request - менеджер контекста asyn c. Вы должны использовать его с asyn c с оператором

async def main():
    async with aiohttp.request('get', 'http://localhost:5000') as r:
        async for line in r.content:
            print(json.loads(line))
...