diff --git a/app/fizz/__init__.py b/app/fizz/__init__.py index 1540b52..60ae9d0 100644 --- a/app/fizz/__init__.py +++ b/app/fizz/__init__.py @@ -1,10 +1,9 @@ BASE_ROUTE = 'fizz' -def register_routes(root_api, root='api'): +def register_routes(api, app, root='api'): from .fizzbar.controller import api as fizzbar_api from .fizzbaz.controller import api as fizzbaz_api - root_api.add_namespace(fizzbar_api, path=f'/{root}/{BASE_ROUTE}/fizzbar') - root_api.add_namespace(fizzbaz_api, path=f'/{root}/{BASE_ROUTE}/fizzbaz') - return root_api + api.add_namespace(fizzbar_api, path=f'/{root}/{BASE_ROUTE}/fizzbar') + api.add_namespace(fizzbaz_api, path=f'/{root}/{BASE_ROUTE}/fizzbaz') diff --git a/app/other_api/__init__.py b/app/other_api/__init__.py new file mode 100644 index 0000000..38d0ef0 --- /dev/null +++ b/app/other_api/__init__.py @@ -0,0 +1,16 @@ +BASE_ROUTE = 'other_api' + + +def register_routes(api, app, root='api'): + from flask import Blueprint + from flask_restplus import Api + + bp = Blueprint('other_api', __name__) + api = Api(bp, title='Another API with separate Swagger docs', version='0.1.0') + + from .doodad.controller import api as doodad_api + from .whatsit.controller import api as whatsit_api + + api.add_namespace(doodad_api, path=f'/doodad') + api.add_namespace(whatsit_api, path=f'/whatsit') + app.register_blueprint(bp, url_prefix=f'/{root}/{BASE_ROUTE}') diff --git a/app/other_api/doodad/__init__.py b/app/other_api/doodad/__init__.py new file mode 100644 index 0000000..5e21359 --- /dev/null +++ b/app/other_api/doodad/__init__.py @@ -0,0 +1,2 @@ +from .model import Doodad # noqa +from .schema import DoodadSchema # noqa diff --git a/app/other_api/doodad/controller.py b/app/other_api/doodad/controller.py new file mode 100644 index 0000000..fcf63ef --- /dev/null +++ b/app/other_api/doodad/controller.py @@ -0,0 +1,56 @@ +from flask import request +from flask_accepts import accepts, responds +from flask_restplus import Namespace, Resource +from flask.wrappers import Response +from typing import List + +from .schema import DoodadSchema +from .service import DoodadService +from .model import Doodad +from .interface import DoodadInterface + +api = Namespace('Doodad', description='A modular namespace within Other API') # noqa + + +@api.route('/') +class DoodadResource(Resource): + '''Doodads''' + + @responds(schema=DoodadSchema, many=True) + def get(self) -> List[Doodad]: + '''Get all Doodads''' + + return DoodadService.get_all() + + @accepts(schema=DoodadSchema, api=api) + @responds(schema=DoodadSchema) + def post(self) -> Doodad: + '''Create a Single Doodad''' + + return DoodadService.create(request.parsed_obj) + + +@api.route('/') +@api.param('doodadId', 'Doodad database ID') +class DoodadIdResource(Resource): + @responds(schema=DoodadSchema) + def get(self, doodadId: int) -> Doodad: + '''Get Single Doodad''' + + return DoodadService.get_by_id(doodadId) + + def delete(self, doodadId: int) -> Response: + '''Delete Single Doodad''' + from flask import jsonify + print('doodadId = ', doodadId) + id = DoodadService.delete_by_id(doodadId) + return jsonify(dict(status='Success', id=id)) + + @accepts(schema=DoodadSchema, api=api) + @responds(schema=DoodadSchema) + def put(self, doodadId: int) -> Doodad: + '''Update Single Doodad''' + + changes: DoodadInterface = request.parsed_obj + Doodad = DoodadService.get_by_id(doodadId) + return DoodadService.update(Doodad, changes) diff --git a/app/other_api/doodad/controller_test.py b/app/other_api/doodad/controller_test.py new file mode 100644 index 0000000..af331b9 --- /dev/null +++ b/app/other_api/doodad/controller_test.py @@ -0,0 +1,84 @@ + +from unittest.mock import patch +from flask.testing import FlaskClient + +from app.test.fixtures import client, app # noqa +from .service import DoodadService +from .schema import DoodadSchema +from .model import Doodad +from .interface import DoodadInterface +from .. import BASE_ROUTE + + +def make_doodad(id: int = 123, name: str = 'Test doodad', + purpose: str = 'Test purpose') -> Doodad: + return Doodad( + doodad_id=id, name=name, purpose=purpose + ) + + +class TestDoodadResource: + @patch.object(DoodadService, 'get_all', + lambda: [make_doodad(123, name='Test Doodad 1'), + make_doodad(456, name='Test Doodad 2')]) + def test_get(self, client: FlaskClient): # noqa + with client: + results = client.get(f'/api/{BASE_ROUTE}/doodad', + follow_redirects=True).get_json() + expected = DoodadSchema(many=True).dump( + [make_doodad(123, name='Test Doodad 1'), + make_doodad(456, name='Test Doodad 2')] + ).data + for r in results: + assert r in expected + + @patch.object(DoodadService, 'create', + lambda create_request: Doodad(**create_request)) + def test_post(self, client: FlaskClient): # noqa + with client: + + payload = dict(name='Test doodad', purpose='Test purpose') + result = client.post(f'/api/{BASE_ROUTE}/doodad/', json=payload).get_json() + expected = DoodadSchema().dump(Doodad( + name=payload['name'], + purpose=payload['purpose'], + )).data + assert result == expected + + +def fake_update(doodad: Doodad, changes: DoodadInterface) -> Doodad: + # To fake an update, just return a new object + updated_Doodad = Doodad(doodad_id=doodad.doodad_id, + name=changes['name'], + purpose=changes['purpose']) + return updated_Doodad + + +class TestDoodadIdResource: + @patch.object(DoodadService, 'get_by_id', + lambda id: make_doodad(id=id)) + def test_get(self, client: FlaskClient): # noqa + with client: + result = client.get(f'/api/{BASE_ROUTE}/doodad/123').get_json() + expected = Doodad(doodad_id=123) + assert result['doodadId'] == expected.doodad_id + + @patch.object(DoodadService, 'delete_by_id', + lambda id: [id]) + def test_delete(self, client: FlaskClient): # noqa + with client: + result = client.delete(f'/api/{BASE_ROUTE}/doodad/123').get_json() + expected = dict(status='Success', id=[123]) + assert result == expected + + @patch.object(DoodadService, 'get_by_id', + lambda id: make_doodad(id=id)) + @patch.object(DoodadService, 'update', fake_update) + def test_put(self, client: FlaskClient): # noqa + with client: + result = client.put(f'/api/{BASE_ROUTE}/doodad/123', + json={'name': 'New Doodad', + 'purpose': 'New purpose'}).get_json() + expected = DoodadSchema().dump( + Doodad(doodad_id=123, name='New Doodad', purpose='New purpose')).data + assert result == expected diff --git a/app/other_api/doodad/interface.py b/app/other_api/doodad/interface.py new file mode 100644 index 0000000..7796d2b --- /dev/null +++ b/app/other_api/doodad/interface.py @@ -0,0 +1,7 @@ +from mypy_extensions import TypedDict + + +class DoodadInterface(TypedDict, total=False): + doodad_id: int + name: str + purpose: str diff --git a/app/other_api/doodad/model.py b/app/other_api/doodad/model.py new file mode 100644 index 0000000..b1558cb --- /dev/null +++ b/app/other_api/doodad/model.py @@ -0,0 +1,19 @@ +from sqlalchemy import Integer, Column, String +from app import db # noqa +from .interface import DoodadInterface +from typing import Any + + +class Doodad(db.Model): # type: ignore + '''A snazzy Doodad''' + + __tablename__ = 'doodad' + + doodad_id = Column(Integer(), primary_key=True) + name = Column(String(255)) + purpose = Column(String(255)) + + def update(self, changes: DoodadInterface): + for key, val in changes.items(): + setattr(self, key, val) + return self diff --git a/app/other_api/doodad/model_test.py b/app/other_api/doodad/model_test.py new file mode 100644 index 0000000..a2e410b --- /dev/null +++ b/app/other_api/doodad/model_test.py @@ -0,0 +1,22 @@ +from pytest import fixture +from flask_sqlalchemy import SQLAlchemy +from app.test.fixtures import app, db # noqa +from .model import Doodad + + +@fixture +def doodad() -> Doodad: + return Doodad( + doodad_id=1, name='Test doodad', purpose='Test purpose' + ) + + +def test_Doodad_create(doodad: Doodad): + assert doodad + + +def test_Doodad_retrieve(doodad: Doodad, db: SQLAlchemy): # noqa + db.session.add(doodad) + db.session.commit() + s = Doodad.query.first() + assert s.__dict__ == doodad.__dict__ diff --git a/app/other_api/doodad/schema.py b/app/other_api/doodad/schema.py new file mode 100644 index 0000000..20e895e --- /dev/null +++ b/app/other_api/doodad/schema.py @@ -0,0 +1,9 @@ +from marshmallow import fields, Schema + + +class DoodadSchema(Schema): + '''Doodad schema''' + + doodadId = fields.Number(attribute='doodad_id') + name = fields.String(attribute='name') + purpose = fields.String(attribute='purpose') diff --git a/app/other_api/doodad/schema_test.py b/app/other_api/doodad/schema_test.py new file mode 100644 index 0000000..e69de29 diff --git a/app/other_api/doodad/service.py b/app/other_api/doodad/service.py new file mode 100644 index 0000000..41e12cc --- /dev/null +++ b/app/other_api/doodad/service.py @@ -0,0 +1,41 @@ +from app import db +from typing import List +from .model import Doodad +from .interface import DoodadInterface + + +class DoodadService(): + @staticmethod + def get_all() -> List[Doodad]: + return Doodad.query.all() + + @staticmethod + def get_by_id(doodad_id: int) -> Doodad: + return Doodad.query.get(doodad_id) + + @staticmethod + def update(doodad: Doodad, Doodad_change_updates: DoodadInterface) -> Doodad: + doodad.update(Doodad_change_updates) + db.session.commit() + return doodad + + @staticmethod + def delete_by_id(doodad_id: int) -> List[int]: + doodad = Doodad.query.filter(Doodad.doodad_id == doodad_id).first() + if not doodad: + return [] + db.session.delete(doodad) + db.session.commit() + return [doodad_id] + + @staticmethod + def create(new_attrs: DoodadInterface) -> Doodad: + new_doodad = Doodad( + name=new_attrs['name'], + purpose=new_attrs['purpose'] + ) + + db.session.add(new_doodad) + db.session.commit() + + return new_doodad diff --git a/app/other_api/doodad/service_test.py b/app/other_api/doodad/service_test.py new file mode 100644 index 0000000..8a1e277 --- /dev/null +++ b/app/other_api/doodad/service_test.py @@ -0,0 +1,60 @@ +from flask_sqlalchemy import SQLAlchemy +from typing import List +from app.test.fixtures import app, db # noqa +from .model import Doodad +from .service import DoodadService # noqa +from .interface import DoodadInterface + + +def test_get_all(db: SQLAlchemy): # noqa + yin: Doodad = Doodad(doodad_id=1, name='Yin', purpose='thing 1') + yang: Doodad = Doodad(doodad_id=2, name='Yang', purpose='thing 2') + db.session.add(yin) + db.session.add(yang) + db.session.commit() + + results: List[Doodad] = DoodadService.get_all() + + assert len(results) == 2 + assert yin in results and yang in results + + +def test_update(db: SQLAlchemy): # noqa + yin: Doodad = Doodad(doodad_id=1, name='Yin', purpose='thing 1') + + db.session.add(yin) + db.session.commit() + updates: DoodadInterface = dict(name='New Doodad name') + + DoodadService.update(yin, updates) + + result: Doodad = Doodad.query.get(yin.doodad_id) + assert result.name == 'New Doodad name' + + +def test_delete_by_id(db: SQLAlchemy): # noqa + yin: Doodad = Doodad(doodad_id=1, name='Yin', purpose='thing 1') + yang: Doodad = Doodad(doodad_id=2, name='Yang', purpose='thing 2') + db.session.add(yin) + db.session.add(yang) + db.session.commit() + + DoodadService.delete_by_id(1) + db.session.commit() + + results: List[Doodad] = Doodad.query.all() + + assert len(results) == 1 + assert yin not in results and yang in results + + +def test_create(db: SQLAlchemy): # noqa + + yin: DoodadInterface = dict(name='Fancy new doodad', purpose='Fancy new purpose') + DoodadService.create(yin) + results: List[Doodad] = Doodad.query.all() + + assert len(results) == 1 + + for k in yin.keys(): + assert getattr(results[0], k) == yin[k] diff --git a/app/other_api/whatsit/__init__.py b/app/other_api/whatsit/__init__.py new file mode 100644 index 0000000..ddd4c95 --- /dev/null +++ b/app/other_api/whatsit/__init__.py @@ -0,0 +1,2 @@ +from .model import Whatsit # noqa +from .schema import WhatsitSchema # noqa diff --git a/app/other_api/whatsit/controller.py b/app/other_api/whatsit/controller.py new file mode 100644 index 0000000..dfc8eb8 --- /dev/null +++ b/app/other_api/whatsit/controller.py @@ -0,0 +1,56 @@ +from flask import request +from flask_accepts import accepts, responds +from flask_restplus import Namespace, Resource +from flask.wrappers import Response +from typing import List + +from .schema import WhatsitSchema +from .service import WhatsitService +from .model import Whatsit +from .interface import WhatsitInterface + +api = Namespace('Whatsit', description='A modular namespace within Other API') # noqa + + +@api.route('/') +class WhatsitResource(Resource): + '''Whatsits''' + + @responds(schema=WhatsitSchema, many=True) + def get(self) -> List[Whatsit]: + '''Get all Whatsits''' + + return WhatsitService.get_all() + + @accepts(schema=WhatsitSchema, api=api) + @responds(schema=WhatsitSchema) + def post(self) -> Whatsit: + '''Create a Single Whatsit''' + + return WhatsitService.create(request.parsed_obj) + + +@api.route('/') +@api.param('whatsitId', 'Whatsit database ID') +class WhatsitIdResource(Resource): + @responds(schema=WhatsitSchema) + def get(self, whatsitId: int) -> Whatsit: + '''Get Single Whatsit''' + + return WhatsitService.get_by_id(whatsitId) + + def delete(self, whatsitId: int) -> Response: + '''Delete Single Whatsit''' + from flask import jsonify + + id = WhatsitService.delete_by_id(whatsitId) + return jsonify(dict(status='Success', id=id)) + + @accepts(schema=WhatsitSchema, api=api) + @responds(schema=WhatsitSchema) + def put(self, whatsitId: int) -> Whatsit: + '''Update Single Whatsit''' + + changes: WhatsitInterface = request.parsed_obj + Whatsit = WhatsitService.get_by_id(whatsitId) + return WhatsitService.update(Whatsit, changes) diff --git a/app/other_api/whatsit/controller_test.py b/app/other_api/whatsit/controller_test.py new file mode 100644 index 0000000..0c030cc --- /dev/null +++ b/app/other_api/whatsit/controller_test.py @@ -0,0 +1,84 @@ + +from unittest.mock import patch +from flask.testing import FlaskClient + +from app.test.fixtures import client, app # noqa +from .service import WhatsitService +from .schema import WhatsitSchema +from .model import Whatsit +from .interface import WhatsitInterface +from .. import BASE_ROUTE + + +def make_whatsit(id: int = 123, name: str = 'Test whatsit', + purpose: str = 'Test purpose') -> Whatsit: + return Whatsit( + whatsit_id=id, name=name, purpose=purpose + ) + + +class TestWhatsitResource: + @patch.object(WhatsitService, 'get_all', + lambda: [make_whatsit(123, name='Test Whatsit 1'), + make_whatsit(456, name='Test Whatsit 2')]) + def test_get(self, client: FlaskClient): # noqa + with client: + results = client.get(f'/api/{BASE_ROUTE}/whatsit', + follow_redirects=True).get_json() + expected = WhatsitSchema(many=True).dump( + [make_whatsit(123, name='Test Whatsit 1'), + make_whatsit(456, name='Test Whatsit 2')] + ).data + for r in results: + assert r in expected + + @patch.object(WhatsitService, 'create', + lambda create_request: Whatsit(**create_request)) + def test_post(self, client: FlaskClient): # noqa + with client: + + payload = dict(name='Test whatsit', purpose='Test purpose') + result = client.post(f'/api/{BASE_ROUTE}/whatsit/', json=payload).get_json() + expected = WhatsitSchema().dump(Whatsit( + name=payload['name'], + purpose=payload['purpose'], + )).data + assert result == expected + + +def fake_update(whatsit: Whatsit, changes: WhatsitInterface) -> Whatsit: + # To fake an update, just return a new object + updated_Whatsit = Whatsit(whatsit_id=whatsit.whatsit_id, + name=changes['name'], + purpose=changes['purpose']) + return updated_Whatsit + + +class TestWhatsitIdResource: + @patch.object(WhatsitService, 'get_by_id', + lambda id: make_whatsit(id=id)) + def test_get(self, client: FlaskClient): # noqa + with client: + result = client.get(f'/api/{BASE_ROUTE}/whatsit/123').get_json() + expected = Whatsit(whatsit_id=123) + assert result['whatsitId'] == expected.whatsit_id + + @patch.object(WhatsitService, 'delete_by_id', + lambda id: [id]) + def test_delete(self, client: FlaskClient): # noqa + with client: + result = client.delete(f'/api/{BASE_ROUTE}/whatsit/123').get_json() + expected = dict(status='Success', id=[123]) + assert result == expected + + @patch.object(WhatsitService, 'get_by_id', + lambda id: make_whatsit(id=id)) + @patch.object(WhatsitService, 'update', fake_update) + def test_put(self, client: FlaskClient): # noqa + with client: + result = client.put(f'/api/{BASE_ROUTE}/whatsit/123', + json={'name': 'New Whatsit', + 'purpose': 'New purpose'}).get_json() + expected = WhatsitSchema().dump( + Whatsit(whatsit_id=123, name='New Whatsit', purpose='New purpose')).data + assert result == expected diff --git a/app/other_api/whatsit/interface.py b/app/other_api/whatsit/interface.py new file mode 100644 index 0000000..7ca2ad6 --- /dev/null +++ b/app/other_api/whatsit/interface.py @@ -0,0 +1,7 @@ +from mypy_extensions import TypedDict + + +class WhatsitInterface(TypedDict, total=False): + whatsit_id: int + name: str + purpose: str diff --git a/app/other_api/whatsit/model.py b/app/other_api/whatsit/model.py new file mode 100644 index 0000000..439e514 --- /dev/null +++ b/app/other_api/whatsit/model.py @@ -0,0 +1,19 @@ +from sqlalchemy import Integer, Column, String +from app import db # noqa +from .interface import WhatsitInterface +from typing import Any + + +class Whatsit(db.Model): # type: ignore + '''A snazzy Whatsit''' + + __tablename__ = 'whatsit' + + whatsit_id = Column(Integer(), primary_key=True) + name = Column(String(255)) + purpose = Column(String(255)) + + def update(self, changes: WhatsitInterface): + for key, val in changes.items(): + setattr(self, key, val) + return self diff --git a/app/other_api/whatsit/model_test.py b/app/other_api/whatsit/model_test.py new file mode 100644 index 0000000..2551ccc --- /dev/null +++ b/app/other_api/whatsit/model_test.py @@ -0,0 +1,22 @@ +from pytest import fixture +from flask_sqlalchemy import SQLAlchemy +from app.test.fixtures import app, db # noqa +from .model import Whatsit + + +@fixture +def whatsit() -> Whatsit: + return Whatsit( + whatsit_id=1, name='Test whatsit', purpose='Test purpose' + ) + + +def test_Whatsit_create(whatsit: Whatsit): + assert whatsit + + +def test_Whatsit_retrieve(whatsit: Whatsit, db: SQLAlchemy): # noqa + db.session.add(whatsit) + db.session.commit() + s = Whatsit.query.first() + assert s.__dict__ == whatsit.__dict__ diff --git a/app/other_api/whatsit/schema.py b/app/other_api/whatsit/schema.py new file mode 100644 index 0000000..c637bed --- /dev/null +++ b/app/other_api/whatsit/schema.py @@ -0,0 +1,9 @@ +from marshmallow import fields, Schema + + +class WhatsitSchema(Schema): + '''Whatsit schema''' + + whatsitId = fields.Number(attribute='whatsit_id') + name = fields.String(attribute='name') + purpose = fields.String(attribute='purpose') diff --git a/app/other_api/whatsit/schema_test.py b/app/other_api/whatsit/schema_test.py new file mode 100644 index 0000000..e69de29 diff --git a/app/other_api/whatsit/service.py b/app/other_api/whatsit/service.py new file mode 100644 index 0000000..9a0dfc3 --- /dev/null +++ b/app/other_api/whatsit/service.py @@ -0,0 +1,41 @@ +from app import db +from typing import List +from .model import Whatsit +from .interface import WhatsitInterface + + +class WhatsitService(): + @staticmethod + def get_all() -> List[Whatsit]: + return Whatsit.query.all() + + @staticmethod + def get_by_id(whatsit_id: int) -> Whatsit: + return Whatsit.query.get(whatsit_id) + + @staticmethod + def update(whatsit: Whatsit, Whatsit_change_updates: WhatsitInterface) -> Whatsit: + whatsit.update(Whatsit_change_updates) + db.session.commit() + return whatsit + + @staticmethod + def delete_by_id(whatsit_id: int) -> List[int]: + whatsit = Whatsit.query.filter(Whatsit.whatsit_id == whatsit_id).first() + if not whatsit: + return [] + db.session.delete(whatsit) + db.session.commit() + return [whatsit_id] + + @staticmethod + def create(new_attrs: WhatsitInterface) -> Whatsit: + new_whatsit = Whatsit( + name=new_attrs['name'], + purpose=new_attrs['purpose'] + ) + + db.session.add(new_whatsit) + db.session.commit() + + return new_whatsit diff --git a/app/other_api/whatsit/service_test.py b/app/other_api/whatsit/service_test.py new file mode 100644 index 0000000..f521f3d --- /dev/null +++ b/app/other_api/whatsit/service_test.py @@ -0,0 +1,60 @@ +from flask_sqlalchemy import SQLAlchemy +from typing import List +from app.test.fixtures import app, db # noqa +from .model import Whatsit +from .service import WhatsitService # noqa +from .interface import WhatsitInterface + + +def test_get_all(db: SQLAlchemy): # noqa + yin: Whatsit = Whatsit(whatsit_id=1, name='Yin', purpose='thing 1') + yang: Whatsit = Whatsit(whatsit_id=2, name='Yang', purpose='thing 2') + db.session.add(yin) + db.session.add(yang) + db.session.commit() + + results: List[Whatsit] = WhatsitService.get_all() + + assert len(results) == 2 + assert yin in results and yang in results + + +def test_update(db: SQLAlchemy): # noqa + yin: Whatsit = Whatsit(whatsit_id=1, name='Yin', purpose='thing 1') + + db.session.add(yin) + db.session.commit() + updates: WhatsitInterface = dict(name='New Whatsit name') + + WhatsitService.update(yin, updates) + + result: Whatsit = Whatsit.query.get(yin.whatsit_id) + assert result.name == 'New Whatsit name' + + +def test_delete_by_id(db: SQLAlchemy): # noqa + yin: Whatsit = Whatsit(whatsit_id=1, name='Yin', purpose='thing 1') + yang: Whatsit = Whatsit(whatsit_id=2, name='Yang', purpose='thing 2') + db.session.add(yin) + db.session.add(yang) + db.session.commit() + + WhatsitService.delete_by_id(1) + db.session.commit() + + results: List[Whatsit] = Whatsit.query.all() + + assert len(results) == 1 + assert yin not in results and yang in results + + +def test_create(db: SQLAlchemy): # noqa + + yin: WhatsitInterface = dict(name='Fancy new whatsit', purpose='Fancy new purpose') + WhatsitService.create(yin) + results: List[Whatsit] = Whatsit.query.all() + + assert len(results) == 1 + + for k in yin.keys(): + assert getattr(results[0], k) == yin[k] diff --git a/app/routes.py b/app/routes.py index 847a699..7252ac1 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,7 +1,11 @@ def register_routes(api, app, root='api'): from app.widget import register_routes as attach_widget from app.fizz import register_routes as attach_fizz + from app.other_api import register_routes as attach_other_api + from app.third_party.app import create_bp # Add routes - attach_widget(api) - attach_fizz(api) + attach_widget(api, app) + attach_fizz(api, app) + attach_other_api(api, app) + app.register_blueprint(create_bp(), url_prefix='/third_party') diff --git a/app/third_party/__init__.py b/app/third_party/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/third_party/app/__init__.py b/app/third_party/app/__init__.py new file mode 100644 index 0000000..37ebdc2 --- /dev/null +++ b/app/third_party/app/__init__.py @@ -0,0 +1,14 @@ +def create_bp(env=None): + from flask import Blueprint, jsonify + from flask_sqlalchemy import SQLAlchemy + from flask_restplus import Api, Resource, Namespace + + bp = Blueprint('Example third party API', __name__) + api = Api(bp, title='Flaskerific API', version='0.1.0') + ns = Namespace('Third party hello world API') + @ns.route('/') + class ExampleResource(Resource): + def get(self): + return "I'm a third party API!" + api.add_namespace(ns, path='/hello_world') + return bp diff --git a/app/third_party/app/app-test.db b/app/third_party/app/app-test.db new file mode 100644 index 0000000..90b3c01 Binary files /dev/null and b/app/third_party/app/app-test.db differ diff --git a/app/third_party/app/config.py b/app/third_party/app/config.py new file mode 100644 index 0000000..3217831 --- /dev/null +++ b/app/third_party/app/config.py @@ -0,0 +1,44 @@ +import os +from typing import List, Type + +basedir = os.path.abspath(os.path.dirname(__file__)) + + +class BaseConfig: + CONFIG_NAME = 'base' + USE_MOCK_EQUIVALENCY = False + DEBUG = False + SQLALCHEMY_TRACK_MODIFICATIONS = False + + +class DevelopmentConfig(BaseConfig): + CONFIG_NAME = 'dev' + SECRET_KEY = os.getenv( + "DEV_SECRET_KEY", "You can't see California without Marlon Widgeto's eyes") + DEBUG = True + SQLALCHEMY_TRACK_MODIFICATIONS = False + TESTING = False + SQLALCHEMY_DATABASE_URI = "sqlite:///{0}/app-dev.db".format(basedir) + + +class TestingConfig(BaseConfig): + CONFIG_NAME = 'test' + SECRET_KEY = os.getenv("TEST_SECRET_KEY", "Thanos did nothing wrong") + DEBUG = True + SQLALCHEMY_TRACK_MODIFICATIONS = False + TESTING = True + SQLALCHEMY_DATABASE_URI = "sqlite:///{0}/app-test.db".format(basedir) + + +class ProductionConfig(BaseConfig): + CONFIG_NAME = 'prod' + SECRET_KEY = os.getenv("PROD_SECRET_KEY", "I'm Ron Burgundy?") + DEBUG = False + SQLALCHEMY_TRACK_MODIFICATIONS = False + TESTING = False + SQLALCHEMY_DATABASE_URI = "sqlite:///{0}/app-prod.db".format(basedir) + + +EXPORT_CONFIGS: List[Type[BaseConfig]] = [ + DevelopmentConfig, TestingConfig, ProductionConfig] +config_by_name = {cfg.CONFIG_NAME: cfg for cfg in EXPORT_CONFIGS} diff --git a/app/third_party/app/routes.py b/app/third_party/app/routes.py new file mode 100644 index 0000000..ec82aac --- /dev/null +++ b/app/third_party/app/routes.py @@ -0,0 +1,9 @@ +def register_routes(api, app, root='api'): + from app.widget import register_routes as attach_widget + from app.fizz import register_routes as attach_fizz + from app.other_api import register_routes as attach_other_api + + # Add routes + attach_widget(api, app) + attach_fizz(api, app) + attach_other_api(api, app) diff --git a/app/widget/__init__.py b/app/widget/__init__.py index 69f61bb..ae0b1fa 100644 --- a/app/widget/__init__.py +++ b/app/widget/__init__.py @@ -3,7 +3,7 @@ from .schema import WidgetSchema # noqa BASE_ROUTE = 'widget' -def register_routes(root_api, root='api'): +def register_routes(api, app, root='api'): from .controller import api as widget_api - root_api.add_namespace(widget_api, path=f'/{root}/{BASE_ROUTE}') - return root_api + + api.add_namespace(widget_api, path=f'/{root}/{BASE_ROUTE}') diff --git a/commands/seed_command.py b/commands/seed_command.py index f1be0ed..ec75d22 100644 --- a/commands/seed_command.py +++ b/commands/seed_command.py @@ -5,11 +5,21 @@ from flask_script import Command from app import db +from app.widget import Widget +from app.fizz.fizzbaz import Fizzbaz +from app.fizz.fizzbar import Fizzbar +from app.other_api.doodad import Doodad +from app.other_api.whatsit import Whatsit -def seed_widgets(): - from app.widget import Widget - widgets = [ +def seed_things(): + classes = [Widget, Fizzbaz, Fizzbar, Doodad, Whatsit] + for klass in classes: + seed_thing(klass) + + +def seed_thing(cls): + things = [ { 'name': 'Pizza Slicer', 'purpose': 'Cut delicious pizza', @@ -23,7 +33,24 @@ def seed_widgets(): 'purpose': 'Bake delicious pizza', }, ] - db.session.bulk_insert_mappings(Widget, widgets) + db.session.bulk_insert_mappings(cls, things) +# def seed_widgets(): +# from app.widget import Widget +# widgets = [ +# { +# 'name': 'Pizza Slicer', +# 'purpose': 'Cut delicious pizza', +# }, +# { +# 'name': 'Rolling Pin', +# 'purpose': 'Roll delicious pizza', +# }, +# { +# 'name': 'Pizza Oven', +# 'purpose': 'Bake delicious pizza', +# }, +# ] +# db.session.bulk_insert_mappings(Widget, widgets) class SeedCommand(Command): @@ -35,6 +62,6 @@ class SeedCommand(Command): print('Dropping tables...') db.drop_all() db.create_all() - seed_widgets() + seed_things() db.session.commit() - print('Widgets successfully seeded.') + print('DB successfully seeded.')