Как обработать 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 шт):
Показанный в вопросе формат подозрительно похож на 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