Как обработать HTTP-ответ со множеством событий?

Делаю post-request на сайт и приходит прям множество responce. Проблема в том,что он приходит не в классическом формате json,а так:

event:conversation.chat.created
data:{"id":"xxxxxxxx","conversation_id":"xxxxxx","bot_id":"Xxxxxxx","created_at":xxxxxxx,"last_error":{"code":0,"msg":""},"status":"created","usage":{"token_count":0,"output_count":0,"input_count":0}}

event:conversation.chat.in_progress
data:{"id":"xxxxxxxxx","conversation_id":"xxxxxxxxxxx","bot_id":"xxxxxxxxxxx","created_at":xxxxxxxx,"last_error":{"code":0,"msg":""},"status":"in_progress","usage":{"token_count":0,"output_count":0,"input_count":0}}
#Заменил значения на 'XXXX'

Ответов сервера более 9-10 и они получаются все в один ответ. Postman нормально их делит, питон нет:

введите сюда описание изображения

При попытке перевести все это в json через responce.json(), начинает выдавать ошибку json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Попытки перевести в текст привели к тому, что я не могу добавить запятых, убрать лишние \n и так далее. Как мне быть?


Ответы (1 шт):

Автор решения: andreymal

Показанный в вопросе формат подозрительно похож на Server-Sent Events.

Если сервер отвечает с правильным Content-Type, для его разбора можно взять готовую библиотеку вроде requests-sse.

Документация там скудная, но в общем-то особо не нужна — это довольно незамысловатая обёртка над библиотекой requests. Главное — иметь в виду три вещи:

  • именованные параметры из **kwargs передаются напрямую в requests.request(), что позволяет напихать какие угодно параметры запроса (или можно даже передать целый Session в параметре session);
  • содержимое события — это строка; если вы хотите обработать его как JSON, то не забудьте запихнуть event.data в какой-нибудь json.loads;
  • библиотека автоматически переподключается при обрыве соединения (и я не вижу штатного способа это отключить, хотя можно попробовать кинуть исключение в on_error); стоит иметь это в виду при написании кода.
#!/usr/bin/env python3

from requests_sse import EventSource

with EventSource(
    "https://sse-demo.netlify.app/sse",
    timeout=60,
    method="POST",
    # Параметры, явно не объявленные в EventSource, попадут в **kwargs
    headers={"User-Agent": "i-am-not-a-python-script/999.99"},
    json={"hello": "world"},
) as event_source:
    try:
        for event in event_source:
            print("Событие:", event.type)
            print("Данные (в виде строки):", event.data)
    except Exception as exc:
        print("Кажется, что-то пошло не так")
        raise exc
→ Ссылка