我如何(安全地)将 Python 对象发送到我的 Flask API?

How do I (safely) send a Python object to my Flask API?

我目前正在尝试构建一个能够在 POST-请求中接收 python 对象的 Flask Web API。

我正在使用 Python 3.7.1 创建请求,Python 2.7 用于 运行 创建 API。 API 在我的本地机器上设置为 运行。我试图发送到我的 API 的对象是来自 sklearn.ensembleRandomForestClassifier 对象,但这可能是多种对象类型中的任何一种。

到目前为止我已经尝试 json.dumps() 我的对象,但是这个对象不是 JSON 可序列化的。我也尝试过 pickle.dumps() 我的对象,但是当试图在 API 侧加载对象时这会导致错误。此外,由于 API 将接收来自匿名用户的请求,我担心对可能的恶意对象执行 pickle.loads()

这是有根据的担忧吗?如果是这样,在 POST 请求中发送任何 python 对象的最佳方式是什么?

执行POST请求的脚本:

import requests
import pickle

url = "http://localhost:5000/flask-api-function"

# the object I want to send is the 'model' object
data = pickle.dumps(model)

r = requests.post(url,data=data)

烧瓶API:

@app.route('/flask-api-function', methods=['POST'])
def flask_api_function():

  model = pickle.loads(request.get_data())

在尝试使用 pickle 解码数据时,此设置实际上会导致错误:

Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/flask/app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/larssuanet/Documents/enjins/dscs/flask_api.py", line 39, in store_model
model = pickle.loads(request.get_data())
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1382, in loads
return Unpickler(file).load()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 858, in load
dispatch[key](self)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 886, in load_proto
raise ValueError, "unsupported pickle protocol: %d" % proto
ValueError: unsupported pickle protocol: 3

有什么好的又安全的方法吗?

当你在 python 3 中 pickle 对象时,传递协议关键字并将其设置为 2。这将确保它可以在 python 2.

上工作
import requests
import pickle

url = "http://localhost:5000/flask-api-function"

# the object I want to send is the 'model' object
data = pickle.dumps(model,protocol=2)

r = requests.post(url,data=data)

通常我会尝试找到一种方法将对象序列化为 JSON,因为 pickle 存在重大安全风险