我正在尝试使用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
(requests.models.Response
),但是
TypeError: 'Response' object is not callable
还有另一种简单的方法可以从Flask返回requests.models.Response
吗?
答案 0 :(得分:54)
好的,找到了:
如果返回元组,则元组中的项可以提供额外信息。这样的元组必须采用(响应,状态,标题)形式,其中至少有一个项目必须在元组中。状态值将覆盖状态代码,标题可以是其他标题值的列表或字典。
(Flask docs。)
所以
return (resp.text, resp.status_code, resp.headers.items())
似乎可以解决问题。
答案 1 :(得分:4)
如果服务器返回编码后的数据(例如text
)并且您返回的标头保持不变,则无法使用Response
对象的content
或content-encoding: gzip
属性。发生这种情况是因为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()
答案 2 :(得分:2)
Flask可以返回d = {'Ernst & Young Nederland LLP': ['Mar 5 06:49:10 2021 GMT', '2048']}
for v in d.values(): print(v[0])
类型的对象。
您可以像这样从flask.wrappers.Response
对象requests.models.Response
创建其中之一:
r
答案 3 :(得分:0)
我遇到了同样的情况,除了在我的情况下我的requests.models.Response包含一个附件。这就是我开始工作的方式:
return send_file(BytesIO(result.content),mimetype = result.headers ['Content-Type'],as_attachment = True)
答案 4 :(得分:0)
我的用例是在我自己的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()))