Подтвердить что ты не робот

Вернуть запрос. Объект ответа из Flask

Я пытаюсь создать простой прокси-сервер, используя флажок и запросы. Код выглядит следующим образом:

@app.route('/es/<string:index>/<string:type>/<string:id>',
           methods=['GET', 'POST', 'PUT']):
def es(index, type, id):
    elasticsearch = find_out_where_elasticsearch_lives()
    # also handle some authentication
    url = '%s%s%s%s' % (elasticsearch, index, type, id)

    esreq = requests.Request(method=request.method, url=url,
                             headers=request.headers, data=request.data)
    resp = requests.Session().send(esreq.prepare())
    return resp.text

Это работает, за исключением того, что он теряет код статуса из Elasticsearch. Я попытался вернуть resp (a requests.models.Response) напрямую, но это не удается с помощью

TypeError: 'Response' object is not callable

Есть ли другой, простой способ вернуть requests.models.Response из фляги?

4b9b3361

Ответ 1

Хорошо, нашел:

Если кортеж возвращен, элементы в кортеже могут предоставить дополнительную информацию. Такие кортежи должны быть в форме (ответ, статус, заголовки), где по крайней мере один элемент должен быть в кортеже. Значение статуса переопределит код состояния, а заголовки могут быть списком или словарем дополнительных значений заголовка.

(Документы флажков.)

Итак,

return (resp.text, resp.status_code, resp.headers.items())

похоже, делает трюк.

Ответ 2

Использование свойства text или content объекта Response не будет работать, если сервер возвращает закодированные данные (например, content-encoding: gzip) и вы возвращаете заголовки без изменений. Это происходит из-за того, что text и content были декодированы, поэтому между кодировкой, сообщаемой в заголовке, и фактическим кодированием будет несоответствие.

Согласно документации:

В редком случае, когда вы хотите получить необработанный ответ сокета от сервера, вы можете получить доступ к r.raw. Если вы хотите сделать это, убедитесь, что вы установили stream=True в своем первоначальном запросе.

а также

Response.raw - это необработанный поток байтов - он не преобразует содержимое ответа.

Итак, для gzipped-данных тоже работает следующее:

esreq = requests.Request(method=request.method, url=url,
                         headers=request.headers, data=request.data)
resp = requests.Session().send(esreq.prepare(), stream=True)
return resp.raw.read(), resp.status_code, resp.headers.items()

Если вы используете метод ярлыка, такой как get, он просто:

resp = requests.get(url, stream=True)
return resp.raw.read(), resp.status_code, resp.headers.items()

Ответ 3

Я столкнулся с тем же сценарием, за исключением того, что в моем случае мои запросы .models.Response содержали вложение. Вот как я заработал:

return send_file (BytesIO (result.content), mimetype = result.headers ['Content-Type'], as_attachment = True)