From e1190c872ddb3054824df1da03101a5ef681e094 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 18 May 2017 21:37:57 +0200 Subject: [PATCH] Simplify marshalling. --- accountant/fields.py | 44 ------------------------ accountant/views/accounts.py | 22 ++++++------ accountant/views/operations.py | 14 ++++---- accountant/views/scheduled_operations.py | 14 ++++---- accountant/views/users.py | 6 ++-- 5 files changed, 24 insertions(+), 76 deletions(-) delete mode 100644 accountant/fields.py diff --git a/accountant/fields.py b/accountant/fields.py deleted file mode 100644 index e19b6fc..0000000 --- a/accountant/fields.py +++ /dev/null @@ -1,44 +0,0 @@ -# vim: set tw=80 ts=4 sw=4 sts=4: -""" - This file is part of Accountant. - - Accountant is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Accountant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Accountant. If not, see . -""" -from flask_restplus import marshal, fields - - -class Object(fields.Raw): - """ - Field to marshal an object with fields. - - SQLAlchemy rows are viewed as tuples by Restful marshaller, and must be - translated into a dict before marshaling. - """ - def __init__(self, model, **kwargs): - """ - :param model: the target model of the object. - """ - self.model = model - - super(Object, self).__init__(**kwargs) - - def format(self, value): - # First transform object in dict with fields in attribute. - result = {key: getattr(value, key, None) for key in self.model.keys()} - - # Marshal the dict - return marshal(result, self.model) - - def schema(self): - return self.model.__schema__ diff --git a/accountant/views/accounts.py b/accountant/views/accounts.py index c3c2a2e..d774eb2 100644 --- a/accountant/views/accounts.py +++ b/accountant/views/accounts.py @@ -16,14 +16,12 @@ """ import dateutil.parser -from flask_restplus import Namespace, Resource, fields, marshal_with_field +from flask_restplus import Namespace, Resource, fields from ..models import db from ..models.accounts import Account from ..models.operations import Operation -from ..fields import Object - from .users import requires_auth @@ -144,7 +142,7 @@ class AccountListResource(Resource): @requires_auth @ns.response(200, 'OK', [account_model]) - @marshal_with_field(fields.List(Object(account_model))) + @ns.marshal_list_with(account_model) def get(self): """ Returns accounts with their balances.""" @@ -154,7 +152,7 @@ class AccountListResource(Resource): @ns.expect(account_model) @ns.response(201, 'Account created', account_model) @ns.response(406, 'Invalid account data') - @marshal_with_field(Object(account_model)) + @ns.marshal_with(account_model) def post(self): """Create a new account.""" @@ -195,7 +193,7 @@ class AccountResource(Resource): @requires_auth @ns.response(200, 'OK', account_model) - @marshal_with_field(Object(account_model)) + @ns.marshal_with(account_model) def get(self, id): """Get an account.""" @@ -215,7 +213,7 @@ class AccountResource(Resource): @ns.expect(account_model) @ns.response(200, 'OK', account_model) @ns.response(406, 'Invalid account data') - @marshal_with_field(Object(account_model)) + @ns.marshal_with(account_model) def post(self, id): """Update an account.""" @@ -248,7 +246,7 @@ class AccountResource(Resource): @requires_auth @ns.response(204, 'Account deleted', account_model) - @marshal_with_field(Object(account_model)) + @ns.marshal_with(account_model) def delete(self, id): """Delete an account.""" @@ -278,7 +276,7 @@ class SoldsResource(Resource): 401: 'Unauthorized', 404: 'Account not found' }) - @marshal_with_field(Object(solds_model)) + @ns.marshal_with(solds_model) def get(self, id): """Get solds for a specific account and date range.""" @@ -308,7 +306,7 @@ class BalanceResource(Resource): 404: 'Account not found' }) @ns.expect(range_parser) - @marshal_with_field(Object(balance_model)) + @ns.marshal_with(balance_model) def get(self, id): """Get account balance for a specific date range.""" @@ -340,7 +338,7 @@ class CategoryResource(Resource): 404: 'Account not found' }) @ns.expect(range_parser) - @marshal_with_field(fields.List(Object(category_model))) + @ns.marshal_list_with(category_model) def get(self, id): """Get account category balances for a specific date range.""" @@ -362,7 +360,7 @@ class OHLCResource(Resource): 404: 'Account not found' }) @ns.expect(range_parser) - @marshal_with_field(fields.List(Object(ohlc_model))) + @ns.marshal_list_with(ohlc_model) def get(self, id): """Get OHLC data for a specific date range and account.""" diff --git a/accountant/views/operations.py b/accountant/views/operations.py index 52224c7..7fc50fc 100644 --- a/accountant/views/operations.py +++ b/accountant/views/operations.py @@ -16,7 +16,7 @@ """ import dateutil.parser -from flask_restplus import Namespace, Resource, fields, marshal_with_field +from flask_restplus import Namespace, Resource, fields from ..models import db from ..models.accounts import Account @@ -24,8 +24,6 @@ from ..models.operations import Operation from .users import requires_auth -from ..fields import Object - # pylint: disable=invalid-name ns = Namespace('operation', description='Operation management') @@ -115,7 +113,7 @@ class OperationListResource(Resource): @requires_auth @ns.response(200, 'OK', [operation_with_sold_model]) @ns.expect(parser=account_range_parser) - @marshal_with_field(fields.List(Object(operation_with_sold_model))) + @ns.marshal_list_with(operation_with_sold_model) def get(self): """Get operations with solds for a specific account.""" @@ -132,7 +130,7 @@ class OperationListResource(Resource): @ns.response(201, 'Operation created', operation_model) @ns.response(404, 'Account not found') @ns.response(406, 'Invalid operation data') - @marshal_with_field(Object(operation_model)) + @ns.marshal_with(operation_model) def post(self): """Create a new operation.""" @@ -176,7 +174,7 @@ class OperationResource(Resource): @requires_auth @ns.response(200, 'OK', operation_model) - @marshal_with_field(Object(operation_model)) + @ns.marshal_with(operation_model) def get(self, id): """Get operation.""" @@ -194,7 +192,7 @@ class OperationResource(Resource): @ns.expect(operation_model) @ns.response(200, 'OK', operation_model) @ns.response(406, 'Invalid operation data') - @marshal_with_field(Object(operation_model)) + @ns.marshal_with(operation_model) def post(self, id): """Update an operation.""" @@ -227,7 +225,7 @@ class OperationResource(Resource): @requires_auth @ns.response(204, 'Operation deleted', operation_model) - @marshal_with_field(Object(operation_model)) + @ns.marshal_with(operation_model) def delete(self, id): """Delete an operation.""" diff --git a/accountant/views/scheduled_operations.py b/accountant/views/scheduled_operations.py index 4d45a02..0d3e078 100644 --- a/accountant/views/scheduled_operations.py +++ b/accountant/views/scheduled_operations.py @@ -14,7 +14,7 @@ You should have received a copy of the GNU Affero General Public License along with Accountant. If not, see . """ -from flask_restplus import Namespace, Resource, fields, marshal_with_field +from flask_restplus import Namespace, Resource, fields from sqlalchemy import true @@ -25,8 +25,6 @@ from ..models.scheduled_operations import ScheduledOperation from .users import requires_auth -from ..fields import Object - # pylint: disable=invalid-name ns = Namespace( 'scheduled_operation', @@ -92,7 +90,7 @@ class ScheduledOperationListResource(Resource): @requires_auth @ns.expect(account_id_parser) @ns.response(200, 'OK', [scheduled_operation_model]) - @marshal_with_field(fields.List(Object(scheduled_operation_model))) + @ns.marshal_list_with(scheduled_operation_model) def get(self): """Get all scheduled operation for an account.""" @@ -105,7 +103,7 @@ class ScheduledOperationListResource(Resource): @ns.response(200, 'OK', scheduled_operation_model) @ns.response(404, 'Account not found') @ns.response(406, 'Invalid operation data') - @marshal_with_field(Object(scheduled_operation_model)) + @ns.marshal_with(scheduled_operation_model) def post(self): """Add a new scheduled operation.""" @@ -153,7 +151,7 @@ class ScheduledOperationResource(Resource): @requires_auth @ns.response(200, 'OK', scheduled_operation_model) - @marshal_with_field(Object(scheduled_operation_model)) + @ns.marshal_with(scheduled_operation_model) def get(self, id): """Get scheduled operation.""" @@ -171,7 +169,7 @@ class ScheduledOperationResource(Resource): @ns.response(200, 'OK', scheduled_operation_model) @ns.response(406, 'Invalid scheduled operation data') @ns.expect(scheduled_operation_model) - @marshal_with_field(Object(scheduled_operation_model)) + @ns.marshal_with(scheduled_operation_model) def post(self, id): """Update a scheduled operation.""" @@ -209,7 +207,7 @@ class ScheduledOperationResource(Resource): @requires_auth @ns.response(200, 'OK', scheduled_operation_model) @ns.response(409, 'Cannot be deleted') - @marshal_with_field(Object(scheduled_operation_model)) + @ns.marshal_with(scheduled_operation_model) def delete(self, id): """Delete a scheduled operation.""" diff --git a/accountant/views/users.py b/accountant/views/users.py index 1bd80ea..f63c165 100644 --- a/accountant/views/users.py +++ b/accountant/views/users.py @@ -20,9 +20,7 @@ from functools import wraps import arrow from flask import request, g, current_app as app -from flask_restplus import Namespace, Resource, fields, marshal_with_field - -from ..fields import Object +from flask_restplus import Namespace, Resource, fields from ..models.users import User @@ -144,7 +142,7 @@ class LoginResource(Resource): responses={ 200: ('OK', user_model) }) - @marshal_with_field(Object(user_model)) + @ns.marshal_with(user_model) def get(self): """Get authenticated user information."""