Python Requests - ChunkedEncodingError(e) - запросы.iter_lines

Я получаю ChunkedEncodingError(e) используя запросы Python. Я использую следующее, чтобы разорвать JSON:

r = requests.get(url, headers=auth, stream=True)

Итерирование по каждой строке с использованием возврата каретки в качестве разделителя, как этот API различает различные события JSON.

for d in r.iter_lines(delimiter="\n"):
    d += "\n"
    sock.send(d)

Я разграничиваю возврат каретки, а затем добавляю его обратно как конечную точку, которую я загружаю в журналы, чтобы фактически ожидать возврата каретки в конце каждого события. Похоже, это работает для примерно 100 тыс. Файлов журнала. Когда я пытаюсь сделать больший звонок, я получаю следующее:

for d in r.iter_lines(delimiter="\n"):
logs_1           |   File "/usr/local/lib/python2.7/dist-packages/requests/models.py", line 783, in iter_lines
logs_1           |     for chunk in self.iter_content(chunk_size=chunk_size, decode_unicode=decode_unicode):
logs_1           |   File "/usr/local/lib/python2.7/dist-packages/requests/models.py", line 742, in generate
logs_1           |     raise ChunkedEncodingError(e)
logs_1           | requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRead(0 bytes read)', IncompleteRead(0 bytes read))

ОБНОВЛЕНИЕ: я обнаружил, что API отправляет обратно NoneType в какой-то момент. Так как же я могу объяснить этот нулевой байт где-то в ответе, не взрывая все? Каждое отдельное событие заканчивается \nи мне нужно уметь проверять каждого даже по отдельности. Должен ли я разделить содержимое на части вместо iter_lines? Тогда убедитесь что нет NoneType в куске? Таким образом, я не пытаюсь iter_lines через NoneType и это взрывается?

3 ответа

Решение

ChunkedEncodingError это вызвано: httplib.IncompletedRead

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

import httplib

def patch_http_response_read(func):
    def inner(*args):
        try:
            return func(*args)
        except httplib.IncompleteRead, e:
            return e.partial
    return inner

httplib.HTTPResponse.read = patch_http_response_read(httplib.HTTPResponse.read)

Я думаю, что это может быть патчем. Это позволяет вам иметь дело с неисправными серверами http.

Большинство серверов передают все данные, но из-за ошибок реализации они неправильно закрывают сеанс, и httplib вызывает ошибку и хоронит ваши драгоценные байты.

Как я написал здесь, упомянутый другим парнем IncompleteRead, вы можете использовать предложение "С", чтобы убедиться, что ваш предыдущий запрос закрыт.

 with requests.request("POST", url_base, json=task, headers=headers) as report:
    print('report: ', report)

Если вы используете объект request.Session совместно с несколькими процессами (многопроцессорность), это может привести к этой ошибке. Вы можете создать отдельный сеанс для каждого процесса (os.getpid()).

Другие вопросы по тегам