Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
404 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from flaskerize import register_custom_function | ||
|
||
|
||
@register_custom_function | ||
def capitalize(val: str) -> str: | ||
return val.capitalize() | ||
|
||
|
||
@register_custom_function | ||
def lower(val: str) -> str: | ||
return val.lower() |
9 changes: 9 additions & 0 deletions
9
flaskerize/schematics/entity/files/{{ name }}.template/__init__.py.template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from .model import {{ capitalize(name) }} # noqa | ||
from .schema import {{ capitalize(name) }}Schema # noqa | ||
|
||
|
||
def register_routes(root_api, root="/api"): | ||
from .controller import api as {{ lower(name) }}_api | ||
|
||
root_api.add_namespace({{ lower(name) }}_api, path=f"{root}/{{ lower(name) }}") | ||
return root_api |
57 changes: 57 additions & 0 deletions
57
flaskerize/schematics/entity/files/{{ name }}.template/controller.py.template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
from flask_restplus import Resource | ||
from flask import request | ||
from flask_restplus import Namespace | ||
from flask_accepts import accepts, responds | ||
from flask.wrappers import Response | ||
from typing import List | ||
|
||
from .schema import {{ capitalize(name) }}Schema | ||
from .model import {{ capitalize(name) }} | ||
from .service import {{ capitalize(name) }}Service | ||
|
||
api = Namespace("{{ capitalize(name) }}", description="{{ capitalize(name) }} information") | ||
|
||
|
||
@api.route("/") | ||
class {{ capitalize(name) }}Resource(Resource): | ||
"""{{ capitalize(name) }}s""" | ||
|
||
@responds(schema={{ capitalize(name) }}Schema, many=True) | ||
def get(self) -> List[{{ capitalize(name) }}]: | ||
"""Get all {{ capitalize(name) }}s""" | ||
|
||
return {{ capitalize(name) }}Service.get_all() | ||
|
||
@accepts(schema={{ capitalize(name) }}Schema, api=api) | ||
@responds(schema={{ capitalize(name) }}Schema) | ||
def post(self): | ||
"""Create a Single {{ capitalize(name) }}""" | ||
|
||
return {{ capitalize(name) }}Service.create(request.parsed_obj) | ||
|
||
|
||
@api.route("/<int:{{ lower(name) }}Id>") | ||
@api.param("{{ lower(name) }}Id", "{{ capitalize(name) }} database ID") | ||
class {{ capitalize(name) }}IdResource(Resource): | ||
@responds(schema={{ capitalize(name) }}Schema) | ||
def get(self, {{ lower(name) }}Id: int) -> {{ capitalize(name) }}: | ||
"""Get Single {{ capitalize(name) }}""" | ||
|
||
return {{ capitalize(name) }}Service.get_by_id({{ lower(name) }}Id) | ||
|
||
def delete(self, {{ lower(name) }}Id: int) -> Response: | ||
"""Delete Single {{ capitalize(name) }}""" | ||
|
||
from flask import jsonify | ||
|
||
id = {{ capitalize(name) }}Service.delete_by_id({{ lower(name) }}Id) | ||
return jsonify(dict(status="Success", id=id)) | ||
|
||
@accepts(schema={{ capitalize(name) }}Schema, api=api) | ||
@responds(schema={{ capitalize(name) }}Schema) | ||
def put(self, {{ lower(name) }}Id: int) -> {{ capitalize(name) }}: | ||
"""Update Single {{ capitalize(name) }}""" | ||
|
||
changes = request.parsed_obj | ||
{{ lower(name) }} = {{ capitalize(name) }}Service.get_by_id({{ lower(name) }}Id) | ||
return {{ capitalize(name) }}Service.update({{ lower(name) }}, changes) |
96 changes: 96 additions & 0 deletions
96
flaskerize/schematics/entity/files/{{ name }}.template/controller_test.py.template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
from unittest.mock import patch | ||
from flask.testing import FlaskClient | ||
from flask.wrappers import Response | ||
|
||
from app.test.fixtures import client, app # noqa | ||
from .model import {{ capitalize(name) }} | ||
from .schema import {{ capitalize(name) }}Schema | ||
from .service import {{ capitalize(name) }}Service | ||
from .interface import {{ capitalize(name) }}Interface | ||
|
||
|
||
def {{ lower(name) }}(id: int = 123, name: str = "Test name") -> {{ capitalize(name) }}: | ||
return {{ capitalize(name) }}({{ lower(name) }}_id=id, name="Test name", description="Test description") | ||
|
||
|
||
class Test{{ capitalize(name) }}Resource: | ||
@patch.object({{ capitalize(name) }}Service, "get_all", lambda: [{{ lower(name) }}(123), {{ lower(name) }}(456)]) | ||
def test_get(self, client: FlaskClient): # noqa | ||
with client: | ||
results = client.get("/api/{{ lower(name) }}", follow_redirects=True).get_json() | ||
expected = {{ capitalize(name) }}Schema(many=True).dump([{{ lower(name) }}(456), {{ lower(name) }}(123)]).data | ||
for r in results: | ||
assert r in expected | ||
|
||
|
||
class Test{{ capitalize(name) }}{{ capitalize(name) }}Resource: | ||
@patch.object( | ||
{{ capitalize(name) }}Service, | ||
"get_all", | ||
lambda: [{{ lower(name) }}(123, name="Test name 1"), {{ lower(name) }}(456, name="Test name 2")], | ||
) | ||
def test_get(self, client: FlaskClient): # noqa | ||
with client: | ||
results: dict = client.get("/api/{{ lower(name) }}", follow_redirects=True).get_json() | ||
expected = ( | ||
{{ capitalize(name) }}Schema(many=True) | ||
.dump([{{ lower(name) }}(123, name="Test name 1"), {{ lower(name) }}(456, name="Test name 2")]) | ||
.data | ||
) | ||
for r in results: | ||
assert r in expected | ||
|
||
@patch.object( | ||
{{ capitalize(name) }}Service, | ||
"create", | ||
lambda create_request: {{ capitalize(name) }}( | ||
{{ lower(name) }}_id=create_request["{{ lower(name) }}_id"], | ||
name=create_request["name"], | ||
description=create_request["description"], | ||
), | ||
) | ||
def test_post(self, client: FlaskClient): # noqa | ||
with client: | ||
|
||
payload = dict(name="Test name", description="Test description") | ||
result: dict = client.post("/api/{{ lower(name) }}/", json=payload).get_json() | ||
expected = ( | ||
{{ capitalize(name) }}Schema() | ||
.dump({{ capitalize(name) }}(name=payload["name"], description=payload["description"])) | ||
.data | ||
) | ||
assert result == expected | ||
|
||
|
||
def fake_update({{ lower(name) }}: {{ capitalize(name) }}, changes: {{ capitalize(name) }}Interface) -> {{ capitalize(name) }}: | ||
# To fake an update, just return a new object | ||
updated_{{ lower(name) }} = {{ capitalize(name) }}({{ lower(name) }}_id={{ lower(name) }}.{{ lower(name) }}_id, name=changes["name"]) | ||
return updated_{{ lower(name) }} | ||
|
||
|
||
class Test{{ capitalize(name) }}{{ capitalize(name) }}IdResource: | ||
@patch.object({{ capitalize(name) }}Service, "get_by_id", lambda id: {{ capitalize(name) }}({{ lower(name) }}_id=id)) | ||
def test_get(self, client: FlaskClient): # noqa | ||
with client: | ||
result: dict = client.get("/api/{{ lower(name) }}/123").get_json() | ||
expected = {{ capitalize(name) }}({{ lower(name) }}_id=123) | ||
assert result["{{ lower(name) }}Id"] == expected.{{ lower(name) }}_id | ||
|
||
@patch.object({{ capitalize(name) }}Service, "delete_by_id", lambda id: [id]) | ||
def test_delete(self, client: FlaskClient): # noqa | ||
with client: | ||
result: dict = client.delete("/api/{{ lower(name) }}/123").get_json() | ||
expected = dict(status="Success", id=[123]) | ||
assert result == expected | ||
|
||
@patch.object({{ capitalize(name) }}Service, "get_by_id", lambda id: {{ capitalize(name) }}({{ lower(name) }}_id=id)) | ||
@patch.object({{ capitalize(name) }}Service, "update", fake_update) | ||
def test_put(self, client: FlaskClient): # noqa | ||
with client: | ||
result: dict = client.put( | ||
"/api/{{ lower(name) }}/123", json={"name": "New name"} | ||
).get_json() | ||
expected: dict = {{ capitalize(name) }}Schema().dump( | ||
{{ capitalize(name) }}({{ lower(name) }}_id=123, name="New name") | ||
).data | ||
assert result == expected |
9 changes: 9 additions & 0 deletions
9
flaskerize/schematics/entity/files/{{ name }}.template/interface.py.template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from datetime import datetime | ||
from mypy_extensions import TypedDict | ||
|
||
|
||
class {{ capitalize(name) }}Interface(TypedDict, total=False): | ||
{{ lower(name) }}_id: int | ||
name: str | ||
description: str | ||
|
24 changes: 24 additions & 0 deletions
24
flaskerize/schematics/entity/files/{{ name }}.template/interface_test.py.template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from pytest import fixture | ||
|
||
from app.product import Product | ||
from .model import {{ capitalize(name) }} | ||
from .interface import {{ capitalize(name) }}Interface | ||
|
||
|
||
@fixture | ||
def interface() -> {{ capitalize(name) }}Interface: | ||
|
||
params: {{ capitalize(name) }}Interface = { | ||
"{{ lower(name) }}_id": 1, | ||
"name": "Test name", | ||
"description": "Test description", | ||
} | ||
return params | ||
|
||
|
||
def test_{{ capitalize(name) }}Interface_create(interface: {{ capitalize(name) }}Interface): | ||
assert interface | ||
|
||
|
||
def test_{{ capitalize(name) }}Interface_works(interface: {{ capitalize(name) }}Interface): | ||
assert {{ capitalize(name) }}(**interface) |
17 changes: 17 additions & 0 deletions
17
flaskerize/schematics/entity/files/{{ name }}.template/model.py.template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from sqlalchemy import Integer, Column, String | ||
from app import db # noqa | ||
from .interface import {{ capitalize(name) }}Interface | ||
|
||
|
||
class {{ capitalize(name) }}(db.Model): | ||
"""A Flaskerific {{ capitalize(name) }}""" | ||
|
||
__tablename__ = "{{ lower(name) }}" | ||
{{ lower(name) }}_id = Column(Integer(), primary_key=True) | ||
name = Column(String(255)) | ||
description = Column(String(255)) | ||
|
||
def update(self, changes): | ||
for key, val in changes.items(): | ||
setattr(self, key, val) | ||
return |
21 changes: 21 additions & 0 deletions
21
flaskerize/schematics/entity/files/{{ name }}.template/model_test.py.template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from pytest import fixture | ||
from flask_sqlalchemy import SQLAlchemy | ||
|
||
from app.test.fixtures import app, db # noqa | ||
from .model import {{ capitalize(name) }} | ||
|
||
|
||
@fixture | ||
def {{ lower(name) }}() -> {{ capitalize(name) }}: | ||
return {{ capitalize(name) }}({{ lower(name) }}_id=1, name="Test name", description="Test description") | ||
|
||
|
||
def test_{{ capitalize(name) }}_create({{ lower(name) }}: {{ capitalize(name) }}): | ||
assert {{ lower(name) }} | ||
|
||
|
||
def test_{{ capitalize(name) }}_retrieve({{ lower(name) }}: {{ capitalize(name) }}, db: SQLAlchemy): # noqa | ||
db.session.add({{ lower(name) }}) | ||
db.session.commit() | ||
s = {{ capitalize(name) }}.query.first() | ||
assert s.__dict__ == {{ lower(name) }}.__dict__ |
13 changes: 13 additions & 0 deletions
13
flaskerize/schematics/entity/files/{{ name }}.template/schema.py.template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from marshmallow import fields, Schema | ||
|
||
|
||
class {{ capitalize(name) }}Schema(Schema): | ||
"""{{ capitalize(name) }}""" | ||
|
||
class Meta: | ||
ordered = True | ||
|
||
{{ lower(name) }}Id = fields.Number(attribute="{{ lower(name) }}_id") | ||
name = fields.String(attribute="name") | ||
description = fields.String(attribute="description") | ||
|
26 changes: 26 additions & 0 deletions
26
flaskerize/schematics/entity/files/{{ name }}.template/schema_test.py.template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
from pytest import fixture | ||
|
||
from .model import {{ capitalize(name) }} | ||
from .schema import {{ capitalize(name) }}Schema | ||
from .interface import {{ capitalize(name) }}Interface | ||
|
||
|
||
@fixture | ||
def schema() -> {{ capitalize(name) }}Schema: | ||
return {{ capitalize(name) }}Schema() | ||
|
||
|
||
def test_{{ capitalize(name) }}Schema_create(schema: {{ capitalize(name) }}Schema): | ||
assert schema | ||
|
||
|
||
def test_{{ capitalize(name) }}Schema_works(schema: {{ capitalize(name) }}Schema): | ||
params: {{ capitalize(name) }}Interface = schema.load( | ||
{"{{ lower(name) }}Id": 1, "name": "Test name", "description": "Test description"} | ||
).data | ||
{{ lower(name) }} = {{ capitalize(name) }}(**params) | ||
|
||
assert {{ lower(name) }}.{{ lower(name) }}_id == 1 | ||
assert {{ lower(name) }}.name == "Test description" | ||
assert {{ lower(name) }}.description == "Test description" | ||
|
44 changes: 44 additions & 0 deletions
44
flaskerize/schematics/entity/files/{{ name }}.template/service.py.template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
from typing import List | ||
|
||
from app import db # noqa | ||
from .model import {{ capitalize(name) }} | ||
from .interface import {{ capitalize(name) }}Interface | ||
|
||
|
||
class {{ capitalize(name) }}Service: | ||
@staticmethod | ||
def get_all() -> List[{{ capitalize(name) }}]: | ||
return {{ capitalize(name) }}.query.all() | ||
|
||
@staticmethod | ||
def get_by_id({{ lower(name) }}_id: int) -> {{ capitalize(name) }}: | ||
return {{ capitalize(name) }}.query.get({{ lower(name) }}_id) | ||
|
||
@staticmethod | ||
def update({{ lower(name) }}: {{ capitalize(name) }}, {{ lower(name) }}_change_updates: {{ capitalize(name) }}Interface) -> {{ capitalize(name) }}: | ||
{{ lower(name) }}.update({{ lower(name) }}_change_updates) | ||
db.session.commit() | ||
return {{ lower(name) }} | ||
|
||
@staticmethod | ||
def delete_by_id({{ lower(name) }}_id: int) -> List[int]: | ||
{{ lower(name) }} = {{ capitalize(name) }}.query.filter({{ capitalize(name) }}.{{ lower(name) }}_id == {{ lower(name) }}_id).first() | ||
if not {{ lower(name) }}: | ||
return [] | ||
db.session.delete({{ lower(name) }}) | ||
db.session.commit() | ||
return [{{ lower(name) }}_id] | ||
|
||
@staticmethod | ||
def create(new_attrs: {{ capitalize(name) }}Interface) -> {{ capitalize(name) }}: | ||
new_{{ lower(name) }} = {{ capitalize(name) }}( | ||
{{ lower(name) }}_id=new_attrs["{{ lower(name) }}_id"], | ||
name=new_attrs["name"], | ||
description=new_attrs["description"], | ||
) | ||
|
||
db.session.add(new_{{ lower(name) }}) | ||
db.session.commit() | ||
|
||
return new_{{ lower(name) }} | ||
|
61 changes: 61 additions & 0 deletions
61
flaskerize/schematics/entity/files/{{ name }}.template/service_test.py.template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
from app.test.fixtures import app, db # noqa | ||
from flask_sqlalchemy import SQLAlchemy | ||
|
||
from typing import List | ||
from .model import {{ capitalize(name) }} | ||
from .service import {{ capitalize(name) }}Service # noqa | ||
from .interface import {{ capitalize(name) }}Interface | ||
|
||
|
||
def test_get_all(db: SQLAlchemy): # noqa | ||
yin: {{ capitalize(name) }} = {{ capitalize(name) }}({{ lower(name) }}_id=1, name="Yin", description="Test description") | ||
yang: {{ capitalize(name) }} = {{ capitalize(name) }}({{ lower(name) }}_id=2, name="Yaang", description="Test description") | ||
db.session.add(yin) | ||
db.session.add(yang) | ||
db.session.commit() | ||
|
||
results: List[{{ capitalize(name) }}] = {{ capitalize(name) }}Service.get_all() | ||
|
||
assert len(results) == 2 | ||
assert yin in results and yang in results | ||
|
||
|
||
def test_update(db: SQLAlchemy): # noqa | ||
yin: {{ capitalize(name) }} = {{ capitalize(name) }}({{ lower(name) }}_id=1, name="Yin", description="Test description") | ||
|
||
db.session.add(yin) | ||
db.session.commit() | ||
updates = dict({{ lower(name) }}="Yang") | ||
|
||
{{ capitalize(name) }}Service.update(yin, updates) | ||
|
||
result: {{ capitalize(name) }} = {{ capitalize(name) }}.query.get(yin.{{ lower(name) }}_id) | ||
assert result.name == "Yang" | ||
|
||
|
||
def test_delete_by_id(db: SQLAlchemy): # noqa | ||
yin: {{ capitalize(name) }} = {{ capitalize(name) }}({{ lower(name) }}_id=1, name="Yin", description="Test description") | ||
yang: {{ capitalize(name) }} = {{ capitalize(name) }}({{ lower(name) }}_id=2, name="Yang", description="Test description") | ||
db.session.add(yin) | ||
db.session.add(yang) | ||
db.session.commit() | ||
|
||
{{ capitalize(name) }}Service.delete_by_id(1) | ||
results: List[{{ capitalize(name) }}] = {{ capitalize(name) }}.query.all() | ||
|
||
assert len(results) == 1 | ||
assert yin not in results and yang in results | ||
|
||
|
||
def test_create(db: SQLAlchemy): # noqa | ||
|
||
yin: {{ capitalize(name) }}Interface = {{ capitalize(name) }}Interface( | ||
{{ lower(name) }}_id=1, name="Yin", description="Test description" | ||
) | ||
{{ capitalize(name) }}Service.create(yin) | ||
results: List[{{ capitalize(name) }}] = {{ capitalize(name) }}.query.all() | ||
|
||
assert len(results) == 1 | ||
|
||
for k in yin.keys(): | ||
assert getattr(results[0], k) == yin[k] |
Oops, something went wrong.