2015-07-27 1 views
1

Мне нужно иметь два логически идентичных представления для ответа на одни и те же данные в разных типах контента. Я использую Flask RESTful.Flask api-представление влияет на все виды

APP = flask.Flask(__name__) 
API = flask_restful.Api(APP) 

@API.representation('text/csv')            
def output_csv(data, code, headers=None):          
    data_is_list = isinstance(data, types.ListType)       
    keys = data[0].keys() if data_is_list else data.keys()      
    output = io.BytesIO()              
    writer = csv.DictWriter(output, keys)          
    writer.writeheader()              
    encode = lambda v: v.encode('utf-8') if isinstance(      
      v, types.UnicodeType) else v          
    if data_is_list:               
     writer.writerows([{k: encode(v) for k, v in i.items()} for i  in data]) 
    else:                  
     writer.writerow({k: encode(v) for k, v in data.items()})    

    resp = flask.make_response(output.getvalue(), code)      
    resp.headers.extend(headers or {})           

    return resp                


class BaseAction(flask_restful.Resource): 
    def get(self, id=None): 
     # ... 
     return actions[0] if id else actions # Dict or list of dicts. 


class ActionAsCSV(BaseAction): 
    def get(self, id=None): 
     data = super(ActionAsCSV, self).get(id, closed) 
     flask.Response(data, mimetype='text/csv')  
     return data          

Есть несколько проблем. После того как я добавил представление представления, все представления возвращают данные text/csv с соответствующим заголовком. Как использовать первый класс представления для возврата данных приложения/json, а второй для возврата данных text/csv? Вторая проблема - это возвращаемое значение метода CSV get, если я возвращаю объект ответа return flask.Response(data, mimetype='text/csv'), данные становятся искаженными - только ключи без значений. Как включить различный тип изображения без повреждения данных?

ответ

3

Во-первых, обратите внимание, что вы не должны использовать один и тот же ресурс для возврата либо одного действия, либо списка действий. Вы должны использовать два различные ресурсы:

class Action(flask_restful.Resource): 
    def get(self, action_id): 
     return actions[action_id] 

class ActionList(flask_restful.Resource): 
    def get(self): 
     return actions 

Тогда самый простой способ вернуть различные типы носителей для того же ресурс использовать согласование содержания. В этом случае вам не нужно объявлять выделенный ресурс ActionAsCSV, чтобы конкретно обрабатывать случай возврата ответа в формате CSV. Например, чтобы использовать согласование содержания с локон:

curl -iH "Accept: text/csv" http://URL_TO_YOUR_VIEW

Кроме того, Колба-RESTful автоматически добавлять контент типа заголовок прямо для Вас в возвращаемый ответ: вам не нужно определите его в методе get вашего ресурса.

Кроме того, API настроен по умолчанию для возврата представлений в JSON. Тем не менее, вы можете изменить, что следующий:

api = flask_restful.Api(app, default_mediatype="text/csv") 

Если вы Absolutly хотите две различных ресурсов для обработки либо приложения/JSON или текста/CSV, withous используя согласование содержания и отсутствие типа запасных варианта СМИ, это возможно:

api = flask_restful.Api(app, default_mediatype=None) 

class ActionListMixin(object): 
    def get(self): 
     return actions 

class JsonActionList(ActionListMixin, flask_restful.Resource): 
    representations = {'application/json': output_json} 

class CsvActionList(ActionListMixin, flask_restful.Resource): 
    representations = {'text/csv': output_csv} 

Anoter аналогичный параметр для определения представительских трансформаторов при добавлении своих ресурсов:

api = flask_restful.Api(app, default_mediatype=None) 

class ActionList(flask_restful.Resource): 
    def __init__(self, representations=None): 
     self.representations = representations 
     super(ActionList, self).__init__() 

    def get(self): 
     return actions 

api.add_resource(ActionList, '/actions_json', resource_class_kwargs={'representations': {'application/json': output_json}}) 
api.add_resource(ActionList, '/actions_csv', resource_class_kwargs={'representations': {'text/csv': output_csv}}) 

 Смежные вопросы

  • Нет связанных вопросов^_^