From 3a6ae5df43a059ab4f604fdb7b3b0dd06f16fccc Mon Sep 17 00:00:00 2001 From: androiddrew Date: Fri, 20 Oct 2017 17:55:01 -0400 Subject: [PATCH] refactored renders, added Datetime to typesystem --- cookie_api/app.py | 4 ++-- cookie_api/models/types.py | 17 +++++++++++++++++ cookie_api/models/util.py | 10 ---------- cookie_api/render.py | 14 -------------- cookie_api/renders.py | 23 +++++++++++++++++++++++ requirements.txt | 1 + tests/test_auth.py | 2 +- tests/test_renders.py | 0 8 files changed, 44 insertions(+), 27 deletions(-) create mode 100644 cookie_api/models/types.py delete mode 100644 cookie_api/models/util.py delete mode 100644 cookie_api/render.py create mode 100644 cookie_api/renders.py create mode 100644 tests/test_renders.py diff --git a/cookie_api/app.py b/cookie_api/app.py index 4ef646c..82dcd01 100644 --- a/cookie_api/app.py +++ b/cookie_api/app.py @@ -8,11 +8,11 @@ from apistar.interfaces import Router, Injector, Auth from apistar_jwt.authentication import JWTAuthentication from apistar_jwt.exceptions import AuthenticationFailed -from cookie_api.render import JSONRenderer +from cookie_api.renders import JSONRenderer from cookie_api.commands import commands from cookie_api.models.schema import Base, Cookie -from .auth import auth_routes, auth_components +from cookie_api.auth import auth_routes, auth_components @annotate(authentication=[JWTAuthentication()]) diff --git a/cookie_api/models/types.py b/cookie_api/models/types.py new file mode 100644 index 0000000..9967254 --- /dev/null +++ b/cookie_api/models/types.py @@ -0,0 +1,17 @@ +import datetime +import dateutil +from apistar.typesystem import TypeSystemError + + +class Datetime(datetime.datetime): + native_type = datetime.datetime + + def __new__(cls, *args, **kwargs) -> datetime: + if args and isinstance(args[0], cls.native_type): + return args[0] + if args and isinstance(args[0], str): + try: + return dateutil.parser.parse(args[0]) + except ValueError: + raise TypeSystemError(cls=cls, code='type') from None + return cls.native_type(*args, **kwargs) diff --git a/cookie_api/models/util.py b/cookie_api/models/util.py deleted file mode 100644 index 1351458..0000000 --- a/cookie_api/models/util.py +++ /dev/null @@ -1,10 +0,0 @@ -import datetime as dt -import decimal - - -def alchemyencoder(obj): - """JSON encoder function with support for ISO 8601 datetime serialization and Decimal to float casting""" - if isinstance(obj, dt.datetime): - return obj.isoformat() - elif isinstance(obj, decimal.Decimal): - return float(obj) diff --git a/cookie_api/render.py b/cookie_api/render.py deleted file mode 100644 index c1a884c..0000000 --- a/cookie_api/render.py +++ /dev/null @@ -1,14 +0,0 @@ -import json - -from cookie_api.models.util import alchemyencoder - -from apistar import http -from apistar.renderers import Renderer - - -class JSONRenderer(Renderer): - media_type = 'application/json' - charset = None - - def render(self, data: http.ResponseData) -> bytes: - return json.dumps(data, default=alchemyencoder).encode('utf-8') diff --git a/cookie_api/renders.py b/cookie_api/renders.py new file mode 100644 index 0000000..7b01f58 --- /dev/null +++ b/cookie_api/renders.py @@ -0,0 +1,23 @@ +import datetime as dt +import decimal +import json + +from apistar import http +from apistar.renderers import Renderer + + +def extended_encoder(obj): + """JSON encoder function with support for ISO 8601 datetime serialization and Decimal to float casting""" + if isinstance(obj, dt.datetime): + return obj.isoformat() + elif isinstance(obj, decimal.Decimal): + return float(obj) + + +class JSONRenderer(Renderer): + """JSON Render with support for ISO 8601 datetime serialization and Decimal to float casting""" + media_type = 'application/json' + charset = None + + def render(self, data: http.ResponseData) -> bytes: + return json.dumps(data, default=extended_encoder).encode('utf-8') diff --git a/requirements.txt b/requirements.txt index 4d650d1..cc94d7c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,6 +16,7 @@ py==1.4.34 pycparser==2.18 PyJWT==1.5.3 pytest==3.2.3 +python-dateutil==2.6.1 requests==2.18.4 six==1.11.0 SQLAlchemy==1.1.14 diff --git a/tests/test_auth.py b/tests/test_auth.py index 9ddd92f..7574faf 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -76,5 +76,5 @@ def test_valid_blacklisted_token_logout(): pass -def test_valid_blacklisted_token_user(self): +def test_valid_blacklisted_token_user(): """ Test for user status with a blacklisted valid token """ diff --git a/tests/test_renders.py b/tests/test_renders.py new file mode 100644 index 0000000..e69de29