From c4458efa210cdf7a8bcf883205d0fd34e43b7281 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Fri, 3 Jul 2020 14:07:40 +0100 Subject: [PATCH] Bump utils to 40.2.1 Brings in: - re-usable `SerialisedModel` - speed improvements to processing CSVs against email templates I chose not to rename `JSONModel` or `ModelList` to keep the diff nice and small. --- app/models/__init__.py | 32 ++++++++--------------------- requirements-app.txt | 2 +- requirements.txt | 6 +++--- tests/app/models/test_base_model.py | 8 ++++++-- 4 files changed, 19 insertions(+), 29 deletions(-) diff --git a/app/models/__init__.py b/app/models/__init__.py index c7770b1e1..f73531f12 100644 --- a/app/models/__init__.py +++ b/app/models/__init__.py @@ -1,12 +1,13 @@ -from abc import ABC, abstractmethod -from collections.abc import Sequence +from abc import abstractmethod from flask import abort +from notifications_utils.serialised_model import ( + SerialisedModel, + SerialisedModelCollection, +) -class JSONModel(): - - ALLOWED_PROPERTIES = set() +class JSONModel(SerialisedModel): def __init__(self, _dict): # in the case of a bad request _dict may be `None` @@ -25,6 +26,8 @@ class JSONModel(): return self.id == other.id def __getattribute__(self, attr): + # Eventually we should remove this custom implementation in + # favour of looping over self.ALLOWED_PROPERTIES in __init__ try: return super().__getattribute__(attr) @@ -54,29 +57,12 @@ class JSONModel(): abort(404) -class ModelList(ABC, Sequence): +class ModelList(SerialisedModelCollection): @property @abstractmethod def client_method(self): pass - @property - @abstractmethod - def model(self): - pass - def __init__(self, *args): self.items = self.client_method(*args) - - def __getitem__(self, index): - return self.model(self.items[index]) - - def __len__(self): - return len(self.items) - - def __add__(self, other): - return list(self) + list(other) - - def __radd__(self, other): - return list(other) + list(self) diff --git a/requirements-app.txt b/requirements-app.txt index 06c4e4edb..5a2afd14c 100644 --- a/requirements-app.txt +++ b/requirements-app.txt @@ -23,7 +23,7 @@ notifications-python-client==5.6.0 awscli-cwlogs>=1.4,<1.5 itsdangerous==1.1.0 -git+https://github.com/alphagov/notifications-utils.git@40.1.0#egg=notifications-utils==40.1.0 +git+https://github.com/alphagov/notifications-utils.git@40.2.1#egg=notifications-utils==40.2.1 git+https://github.com/alphagov/govuk-frontend-jinja.git@v0.5.1-alpha#egg=govuk-frontend-jinja==0.5.1-alpha # gds-metrics requires prometheseus 0.2.0, override that requirement as later versions bring significant performance gains diff --git a/requirements.txt b/requirements.txt index b70f328df..037366b83 100644 --- a/requirements.txt +++ b/requirements.txt @@ -25,7 +25,7 @@ notifications-python-client==5.6.0 awscli-cwlogs>=1.4,<1.5 itsdangerous==1.1.0 -git+https://github.com/alphagov/notifications-utils.git@40.1.0#egg=notifications-utils==40.1.0 +git+https://github.com/alphagov/notifications-utils.git@40.2.1#egg=notifications-utils==40.2.1 git+https://github.com/alphagov/govuk-frontend-jinja.git@v0.5.1-alpha#egg=govuk-frontend-jinja==0.5.1-alpha # gds-metrics requires prometheseus 0.2.0, override that requirement as later versions bring significant performance gains @@ -33,10 +33,10 @@ prometheus-client==0.8.0 gds-metrics==0.2.0 ## The following requirements were added by pip freeze: -awscli==1.18.91 +awscli==1.18.93 bleach==3.1.4 boto3==1.10.38 -botocore==1.17.14 +botocore==1.17.16 cachetools==4.1.0 certifi==2020.6.20 chardet==3.0.4 diff --git a/tests/app/models/test_base_model.py b/tests/app/models/test_base_model.py index 7f5c748ee..2be06759e 100644 --- a/tests/app/models/test_base_model.py +++ b/tests/app/models/test_base_model.py @@ -30,14 +30,17 @@ def test_prefers_property_to_dict(): )) def test_model_raises_for_unknown_attributes(json_response): - model = JSONModel(json_response) + class Custom(JSONModel): + ALLOWED_PROPERTIES = set() + + model = Custom(json_response) assert model.ALLOWED_PROPERTIES == set() with pytest.raises(AttributeError) as e: model.foo assert str(e.value) == ( - "'JSONModel' object has no attribute 'foo' and 'foo' is not a " + "'Custom' object has no attribute 'foo' and 'foo' is not a " "field in the underlying JSON" ) @@ -60,6 +63,7 @@ def test_model_raises_keyerror_if_item_missing_from_dict(): def test_model_doesnt_swallow_attribute_errors(json_response): class Custom(JSONModel): + ALLOWED_PROPERTIES = set() @property def foo(self): raise AttributeError('Something has gone wrong')