[英]How to get the data out of `requests.Response` object in Python?
[英]Return a requests.Response object from Flask
我正在尝试使用 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
还有另一种简单的方法从 Flask 返回requests.models.Response
吗?
好的,找到了:
如果返回元组,则元组中的项目可以提供额外信息。 这样的元组必须采用(响应、状态、标题)的形式。 状态值将覆盖状态代码,并且标头可以是附加标头值的列表或字典。
(烧瓶文档。)
所以
return (resp.text, resp.status_code, resp.headers.items())
似乎可以解决问题。
如果服务器返回编码数据(例如content-encoding: gzip
)并且您返回未更改的标头,则使用Response
对象的text
或content
属性将不起作用。 发生这种情况是因为text
和content
已被解码,因此标头报告的编码与实际编码之间存在不匹配。
根据文档:
在极少数情况下,您希望从服务器获取原始套接字响应,您可以访问
r.raw
。 如果您想这样做,请确保在您的初始请求中设置stream=True
。
和
Response.raw
是一个原始的字节流——它不会转换响应内容。
因此,以下内容也适用于压缩数据:
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()
Flask 可以返回一个flask.wrappers.Response
类型的对象。
您可以像这样从您的requests.models.Response
对象r
创建其中之一:
from flask import Response
return Response(
response=r.reason,
status=r.status_code,
headers=dict(r.headers)
)
我遇到了同样的情况,除了在我的情况下,我的 requests.models.Response 包含一个附件。 这就是我让它工作的方式:
return send_file(BytesIO(result.content), mimetype=result.headers['Content-Type'], as_attachment=True)
我的用例是在我自己的 Flask API 中调用另一个 API。 我只是通过我的 Flask 响应传播不成功的requests.get
调用。 这是我成功的方法:
headers = {
'Authorization': 'Bearer Muh Token'
}
try:
response = requests.get(
'{domain}/users/{id}'\
.format(domain=USERS_API_URL, id=hit['id']),
headers=headers)
response.raise_for_status()
except HTTPError as err:
logging.error(err)
flask.abort(flask.Response(response=response.content, status=response.status_code, headers=response.headers.items()))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.