diff --git a/app/controllers/building.py b/app/controllers/building.py index 2474a019967d7d8935b562ee2bd9a7748308a986..df19a02b841288eb6ce529b478650532a7acd84d 100644 --- a/app/controllers/building.py +++ b/app/controllers/building.py @@ -1,7 +1,10 @@ """Controllers for posting or manipulating a building.""" +from werkzeug.exceptions import NotFound, BadRequest +from flask import current_app from ..models.building import Building from ..forms.building import BuildingForm from .base import RestController +from ..lib.database import proc class BuildingController(RestController): @@ -14,35 +17,45 @@ class BuildingController(RestController): def index(self, filter_data): """ - get_building(in_address:string, in_bbl:int, in_building_id:int) + Retrieve a list of buildings - :param filter_data: Args for stored proc - :return: List of Building dicts + Args: + filter_data (ImmutableMultiDict): Args for stored proc + Returns: + dict: List of Buildings """ - # Make sure that if a bbl, lot_id, or building_id - # are inputted they are all digits - bbl = filter_data.get('bbl') - lid = filter_data.get('lot_id') - bid = filter_data.get('building_id') + clean_filter_data = {k: v.strip() for k, v in filter_data.to_dict().items() if v} - bbl_not_digit = bbl and not bbl.isdigit() - lid_not_digit = lid and not lid.isdigit() - bid_not_digit = bid and not bid.isdigit() + try: + building_list = proc(self.Model, self.Model.PROCS['READ'], **clean_filter_data) + except Exception as err: + raise ( + BadRequest(str(err)) if current_app.config['DEBUG'] else + BadRequest('Error while executing db call') + ) - if bbl_not_digit or lid_not_digit or bid_not_digit: - return {'buildings': []} - - buildings = self.Model.run_proc("get_building", **filter_data) - return {'buildings': [i.__dict__ for i in buildings]} + return building_list def get(self, id_, filter_data): """ Retrieves a building object - :param id_: building_id of building - :param filter_data: Args for stored proc - :return: building object + Args: + id_ (str): building_id of building + filter_data (ImmutableMultiDict): Args for stored proc + Returns: + dict: Building object """ - buildings = self.Model.run_proc("get_building", **{'building_id': [id_]}) - return buildings[0].__dict__ if buildings else {} + try: + building_list = proc(self.Model, self.Model.PROCS['READ'], **{'building_id': id_}) + except Exception as err: + raise ( + BadRequest(str(err)) if current_app.config['DEBUG'] else + BadRequest('Error while executing db call') + ) + + if not building_list: + raise NotFound + + return building_list[0] diff --git a/app/models/base.py b/app/models/base.py index e6a44c446c36b6f03856e21a92aa0f1175084d80..7b5db710f9090d32dbd9986928bc8b830b733e70 100644 --- a/app/models/base.py +++ b/app/models/base.py @@ -89,9 +89,9 @@ class Model(BaseModel): try: results = db.session.execute(query) db.session.commit() - except Exception as e: + except Exception as err: raise BadRequest('Something went wrong' - ' in the database: {}'.format(str(e))) + ' in the database: {}'.format(str(err))) return results @staticmethod @@ -139,7 +139,11 @@ class Model(BaseModel): if response.status_code == 200: document_list = response.json()['data'] else: - raise InternalServerError("Failed to get documents from document service: {} {}".format(response.status_code, response.reason)) + raise InternalServerError('Failed to get documents from document' + 'service: {} {}'.format( + response.status_code, + response.reason) + ) return document_list diff --git a/app/models/building.py b/app/models/building.py index 7a617167ea28bc699231a5e1c7cff631e4e4fe05..86cc4c9197bac60957ff1a731cfecefec1af5086 100644 --- a/app/models/building.py +++ b/app/models/building.py @@ -1,17 +1,26 @@ """Models for dealing with buildings.""" -from ..lib.database import db -from decimal import Decimal -from .base import Model +from ..lib.database import proc, ProcColumn, ProcTable +from .base import BaseModel -class Building(Model): - params = { - 'address': 'string', - 'bbl': 'int', - 'building_id': 'int', - 'lot_id': 'int' +class Building(BaseModel): + __table_args__ = {"schema": "public"} + + PROCS = { + 'READ': 'get_building', } + __table__ = ProcTable( + 'Building', + ProcColumn('address'), + ProcColumn('bbl'), + ProcColumn('borough'), + ProcColumn('zipcode'), + ProcColumn('building_id'), + ProcColumn('lot_id'), + ProcColumn('bin_id'), + ) + def __init__(self, address, bbl, borough, zipcode, building_id, lot_id, bin_id): self.address = address self.bbl = bbl @@ -23,29 +32,3 @@ class Building(Model): def __str__(self): return "Building: {} located at {}".format(self.building_id, self.address) - - @classmethod - def run_proc(cls, method, **kwargs): - """ - Run stored proc and return a list of Buildings - - :param method: Method name for stored procedure - :param kwargs: For stored procedure parameters - :return: List of Building objects from query - """ - param_inputs = {} - item_list = [] - - # Use inputted arguments for the stored proc - param_inputs = {k: v[0].strip() for k, v in kwargs.items() if v[0]} - - results = Model.run_proc(method, 'public', **param_inputs) - - for field in results: - obj = {} - for column, value in field.items(): - obj[column] = value - - item_list.append(eval(cls.__name__)(**obj)) - - return item_list diff --git a/app/views/building.py b/app/views/building.py index 0ac630d267ce367723cd8ccef4f51e86c11f331e..dae47f2ef7af9299a7b1b0ad5e74f9ab6503e5e8 100644 --- a/app/views/building.py +++ b/app/views/building.py @@ -1,9 +1,9 @@ """Views for working with buildings.""" +from flask import request from werkzeug.exceptions import MethodNotAllowed from ..controllers.building import BuildingController from .base import UnprotectedRestView from ..permissions.application import app_need -from flask import request class BuildingView(UnprotectedRestView): @@ -15,12 +15,24 @@ class BuildingView(UnprotectedRestView): @app_need def index(self): """/ GET - Retrieve a list of resources.""" - return self.json(self.get_controller().index(request.args)) + # TODO: Add data key back to self.json + # return super(BuildingView, self).index(request.args) + return self.json({ + 'data': [ + self.parse(m) for m in self.get_controller().index(request.args) + ] + }) @app_need def get(self, id_): """/{id} GET - Retrieve a resource by id.""" - return self.json(self.get_controller().get(id_, None)) + # TODO: Add data key back in self.json + # return super(BuildingView, self).get(id_, request.args) + return self.json({ + 'data': self.parse( + self.get_controller().get(id_, request.args) + ) + }) def post(self): raise MethodNotAllowed()