2016-11-11 1 views
2

У меня есть API, полностью документированный и законченный, встроенный в python 3.5/flask с использованием flask-restplus. Я хотел бы добавить один кусок функциональности - возвращение маринованного объекта как часть одного из моих ответов.Как я могу маршалировать маринованный объект через API (желательно, используя колбу-restplus)?

Общие решения, не относящиеся к flask-restplus, приветствуются, но поскольку мой API полностью документирован и закончен (кроме этого немного), я предпочел бы повесить это, вместо того, чтобы кардинально изменить используемую структуру.

Моя модель схема выглядит следующим образом (упрощенно):

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'), 
}) 

И пример класса (мариноваться) и модель, которую я хочу, чтобы сформировать ответ API:

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) 

И метод конечных точек API объявлен как:

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 

В этом примере я дал, используя fields.Raw() в качестве ИАС для маринованного объекта не работает (нет json-представления). Итак, что я должен сделать вместо этого, чтобы свести к минимуму реструктуризацию моей инфраструктуры API?

[EDIT: исправить ошибку синтаксиса в исходной Q]

+0

Было ли доступно найти решение вашей проблемы? Я также сталкиваюсь с этой проблемой. – jarandaf

+0

@jarandaf мы отошли от соленых огурцов, чтобы избежать адского контроля версий, когда мы обновили и изменили наши классы. Вместо этого мы добавили сериализатор и десериализатор для класса, предоставив json из API – thclark

ответ

0

Окончательного ответ:

В конце концов, мы отошли от использования рассолов, чтобы избежать проблем контроля версий, когда мы обновили наши классы затем пытались unpickle формирует старые версии.

В итоге мы использовали предложение в this SO answer, которое должно было использовать библиотеку jsonpickle для сериализации произвольного объекта класса и выплевывания его из API.

+0

@jarandaf, возможно, это то, что вы ищете – thclark

+0

Я проверю это, спасибо! – jarandaf