问题
I have an API fully documented and finished, built in python 3.5/flask using flask-restplus. I'd like to add one chunk of functionality - returning a pickled object as part of one of my responses.
General solutions not specific to flask-restplus are welcome, but as my API is fully documented and finished (other than this little bit), I'd rather hang this on rather than fundamentally altering the framework I'm using.
My model schema looks like this (simplified):
get_fields = api.model('get-myresource', {
'id': fields.Integer(description='Id of the resource.'),
'other_field': fields.Integer(description='some other fields too.'),
'pickled_obj': fields.Raw(description='Marshalling fields.Raw fails, as the serialised binary cant be expressed as json'),
})
And an example class (to be pickled) and model that I want to form the api response:
class MyClass(object):
# An instance of this class will be serialised with pickle
a_prop = None
def a_method(self):
return 'some_result'
obj_instance = MyClass()
class MyDataModel(object):
# It's actually a SQLAlchemy model, where one of the columns is PickleType, but for the sake of a canonical example...
id = 1
other_field = 2
pickled_obj = pickle.dumps(obj_instance)
And the api endpoint method declared as:
import pickle
from flask import request
from flask_restplus import Resource, Namespace
from .my_schema_file import get_fields
api = Namespace('myresource', description='Whatever')
@api.route('')
class MyResource(Resource):
@api.response(200, 'Resource(s) returned successfully', get_fields)
@api.response(400, 'Bad Request')
@api.response(404, 'Not Found')
@api.response(500, 'Application Error')
@api.marshal_with(get_fields, code=200, description='Resource(s) returned successfully')
def get(self):
# Argument parsing and fetch from the database
data = MyDataModel()
return data, 200
In this example I've given, using fields.Raw() as a marshaller for a pickled object doesn't work (there's no json representation). So what should I do instead to minimise restructuring of my API framework?
[EDIT: to fix syntax error in original Q]
回答1:
Final answer:
In the end, we moved away from using pickles, to avoid version control problems when we updated our classes then tried to unpickle form old versions.
We ultimately used the suggestion in this SO answer, which was to use the jsonpickle library to serialise the arbitrary class object and spit it out of the API.
来源:https://stackoverflow.com/questions/40551215/how-can-i-marshal-a-pickled-object-through-an-api-preferably-using-flask-restp