From d6419c313c28f3834c14d374808e7a8e8e31b48e Mon Sep 17 00:00:00 2001 From: Alessandro DiMarco Date: Wed, 22 Feb 2017 10:00:52 -0500 Subject: [PATCH 1/4] Add ProcTable to building model --- app/controllers/building.py | 29 ++++++++++++-------- app/models/base.py | 11 +++++--- app/models/building.py | 53 +++++++++++++------------------------ app/views/building.py | 7 ++++- 4 files changed, 50 insertions(+), 50 deletions(-) diff --git a/app/controllers/building.py b/app/controllers/building.py index 2474a01..227d078 100644 --- a/app/controllers/building.py +++ b/app/controllers/building.py @@ -2,6 +2,7 @@ from ..models.building import Building from ..forms.building import BuildingForm from .base import RestController +from ..lib.database import proc class BuildingController(RestController): @@ -14,10 +15,12 @@ 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 @@ -30,19 +33,23 @@ class BuildingController(RestController): bid_not_digit = bid and not bid.isdigit() if bbl_not_digit or lid_not_digit or bid_not_digit: - return {'buildings': []} + return {} - buildings = self.Model.run_proc("get_building", **filter_data) - return {'buildings': [i.__dict__ for i in buildings]} + clean_filter_data = {k: v.strip() for k, v in filter_data.to_dict().items() if v} + results = proc(self.Model, self.Model.PROCS['READ'], **clean_filter_data) + + return results 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_]}) + results = proc(self.Model, self.Model.PROCS['READ'], **{'building_id': id_}) - return buildings[0].__dict__ if buildings else {} + return results[0].__dict__ if results else {} diff --git a/app/models/base.py b/app/models/base.py index 46d1457..e7a6d18 100644 --- a/app/models/base.py +++ b/app/models/base.py @@ -20,6 +20,7 @@ import json class BaseModel: """A base mixin for all models.""" + def get_dictionary(self): """Return a dictionary representation of the model. @@ -90,9 +91,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 @@ -140,7 +141,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 7a61716..86cc4c9 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 0ac630d..2f9f630 100644 --- a/app/views/building.py +++ b/app/views/building.py @@ -15,7 +15,12 @@ class BuildingView(UnprotectedRestView): @app_need def index(self): """/ GET - Retrieve a list of resources.""" - return self.json(self.get_controller().index(request.args)) + # return self.json(self.get_controller().index(request.args)) + return self.json({ + 'buildings': [ + self.parse(m) for m in self.get_controller().index(request.args) + ] + }) @app_need def get(self, id_): -- GitLab From d81201b7c195a37c74030e3094abadc6dd60b514 Mon Sep 17 00:00:00 2001 From: Alessandro DiMarco Date: Wed, 22 Feb 2017 12:57:19 -0500 Subject: [PATCH 2/4] Update building views to match existing patterns --- app/controllers/building.py | 9 +++++++-- app/views/building.py | 15 +++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/app/controllers/building.py b/app/controllers/building.py index 227d078..18ddfae 100644 --- a/app/controllers/building.py +++ b/app/controllers/building.py @@ -1,4 +1,5 @@ """Controllers for posting or manipulating a building.""" +from werkzeug.exceptions import NotFound from ..models.building import Building from ..forms.building import BuildingForm from .base import RestController @@ -50,6 +51,10 @@ class BuildingController(RestController): Returns: dict: Building object """ - results = proc(self.Model, self.Model.PROCS['READ'], **{'building_id': id_}) + # results = proc(self.Model, self.Model.PROCS['READ'], **{'building_id': id_}) - return results[0].__dict__ if results else {} + # return results[0].__dict__ if results else {} + model_list = proc(self.Model, self.Model.PROCS['READ'], **{'building_id': id_}) + if not model_list: + raise NotFound + return model_list[0] diff --git a/app/views/building.py b/app/views/building.py index 2f9f630..dae47f2 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,9 +15,10 @@ 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({ - 'buildings': [ + 'data': [ self.parse(m) for m in self.get_controller().index(request.args) ] }) @@ -25,7 +26,13 @@ class BuildingView(UnprotectedRestView): @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() -- GitLab From 6cac600641165c03599eb5ab972f3f5cdce21923 Mon Sep 17 00:00:00 2001 From: Alessandro DiMarco Date: Wed, 22 Feb 2017 12:59:54 -0500 Subject: [PATCH 3/4] Remove commented code --- app/controllers/building.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/controllers/building.py b/app/controllers/building.py index 18ddfae..59f38ee 100644 --- a/app/controllers/building.py +++ b/app/controllers/building.py @@ -51,9 +51,7 @@ class BuildingController(RestController): Returns: dict: Building object """ - # results = proc(self.Model, self.Model.PROCS['READ'], **{'building_id': id_}) - # return results[0].__dict__ if results else {} model_list = proc(self.Model, self.Model.PROCS['READ'], **{'building_id': id_}) if not model_list: raise NotFound -- GitLab From 58d7ed9e8e6c855f64644b7d5231e9b86096be5f Mon Sep 17 00:00:00 2001 From: Alessandro DiMarco Date: Wed, 22 Feb 2017 14:54:50 -0500 Subject: [PATCH 4/4] Add try except for run proc --- app/controllers/building.py | 41 ++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/app/controllers/building.py b/app/controllers/building.py index 59f38ee..df19a02 100644 --- a/app/controllers/building.py +++ b/app/controllers/building.py @@ -1,5 +1,6 @@ """Controllers for posting or manipulating a building.""" -from werkzeug.exceptions import NotFound +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 @@ -23,23 +24,17 @@ class BuildingController(RestController): 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') - - bbl_not_digit = bbl and not bbl.isdigit() - lid_not_digit = lid and not lid.isdigit() - bid_not_digit = bid and not bid.isdigit() - - if bbl_not_digit or lid_not_digit or bid_not_digit: - return {} - clean_filter_data = {k: v.strip() for k, v in filter_data.to_dict().items() if v} - results = proc(self.Model, self.Model.PROCS['READ'], **clean_filter_data) - return results + 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') + ) + + return building_list def get(self, id_, filter_data): """ @@ -52,7 +47,15 @@ class BuildingController(RestController): dict: Building object """ - model_list = proc(self.Model, self.Model.PROCS['READ'], **{'building_id': id_}) - if not model_list: + 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 model_list[0] + + return building_list[0] -- GitLab