如何(安全地)将Python对象发送到FlaskAPI?

如何(安全地)将Python对象发送到FlaskAPI?,python,json,scikit-learn,pickle,Python,Json,Scikit Learn,Pickle,我目前正在尝试构建一个FlaskWebAPI,它能够在POST请求中接收python对象 我使用Python3.7.1创建请求,使用Python2.7运行API。API已设置为在本地计算机上运行。我试图发送到API的对象是来自sklearn.emble的RandomForestClassifier对象,但这可能是多种对象类型中的任何一种 到目前为止,我已经尝试json.dumps()my对象,但是这个对象不可json序列化。我还尝试了pickle.dumps()my对象,但这在尝试加载API端的

我目前正在尝试构建一个FlaskWebAPI,它能够在POST请求中接收python对象

我使用Python3.7.1创建请求,使用Python2.7运行API。API已设置为在本地计算机上运行。我试图发送到API的对象是来自
sklearn.emble
RandomForestClassifier
对象,但这可能是多种对象类型中的任何一种

到目前为止,我已经尝试
json.dumps()
my对象,但是这个对象不可json序列化。我还尝试了
pickle.dumps()
my对象,但这在尝试加载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对象时,传递protocol关键字并将其设置为2。这将确保它在Python2上工作

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存在重大安全风险

不要发送实际对象,这是一种糟糕的做法,可能会让您陷入无休止的维护消防。看看是否可以发送它们的表示,并在另一侧重建它们。。另请参见:当某人想要支持各种各样的对象时,有没有关于如何进行这项工作的建议?我觉得应该有一种更简单的方法来实现这一点,而不必编写逻辑来重构您想要支持的每一种对象类型。。。你能说得更具体些吗?尝试将您的对象序列化为JSON,这是开始的好地方。您可以看到,我使用
RandomForestClassifier
对象尝试了这一点,但该对象不可序列化。不过,我不需要这个特定对象的解决方案,我正在寻找一种干净的方法来序列化各种对象(特别是ML模型)。@Urban48但并非所有对象都是JSON可序列化的。谢谢,这将暂时解决我的错误。但正如你所说,我仍然会寻找一种更安全的方法来实现这一点。