""" .. module: lemur.common.utils :platform: Unix :copyright: (c) 2015 by Netflix Inc., see AUTHORS for more :license: Apache, see LICENSE for more details. .. moduleauthor:: Kevin Glisson """ from functools import wraps from flask import current_app from flask.ext.restful import marshal from flask.ext.restful.reqparse import RequestParser from flask.ext.sqlalchemy import Pagination class marshal_items(object): def __init__(self, fields, envelope=None): self.fields = fields self.envelop = envelope def __call__(self, f): def _filter_items(items): filtered_items = [] for item in items: filtered_items.append(marshal(item, self.fields)) return filtered_items @wraps(f) def wrapper(*args, **kwargs): try: resp = f(*args, **kwargs) # this is a bit weird way to handle non standard error codes returned from the marshaled function if isinstance(resp, tuple): return resp[0], resp[1] if isinstance(resp, Pagination): return {'items': _filter_items(resp.items), 'total': resp.total} if isinstance(resp, list): return _filter_items(resp) return marshal(resp, self.fields) except Exception as e: # this is a little weird hack to respect flask restful parsing errors on marshaled functions if hasattr(e, 'code'): return {'message': e.data['message']}, 400 else: current_app.logger.exception(e) return {'message': e.message}, 400 return wrapper paginated_parser = RequestParser() paginated_parser.add_argument('count', type=int, default=10, location='args') paginated_parser.add_argument('page', type=int, default=1, location='args') paginated_parser.add_argument('sortDir', type=str, dest='sort_dir', location='args') paginated_parser.add_argument('sortBy', type=str, dest='sort_by', location='args') paginated_parser.add_argument('filter', type=str, location='args')