Serialise service, API keys and permissions

By serialising these straight away we can:
- not go back to the database later, potentially closing the connection
  sooner
- potentially cache the serialised data, meaning we don’t touch the
  database at all
This commit is contained in:
Chris Hill-Scott
2020-06-22 11:10:10 +01:00
parent d7b2cc6403
commit 320bca70f7
11 changed files with 113 additions and 24 deletions

View File

@@ -5,9 +5,13 @@ from threading import RLock
import cachetools
from notifications_utils.clients.redis import RequestCache
from werkzeug.utils import cached_property
from app import redis_store
from app.dao import templates_dao
from app.dao.api_key_dao import get_model_api_keys
from app.dao.services_dao import dao_fetch_service_by_id
caches = defaultdict(partial(cachetools.TTLCache, maxsize=1024, ttl=2))
locks = defaultdict(RLock)
@@ -53,6 +57,29 @@ class SerialisedModel(ABC):
return super().__dir__() + list(sorted(self.ALLOWED_PROPERTIES))
class SerialisedModelCollection(ABC):
"""
A SerialisedModelCollection takes a list of dictionaries, typically
created by serialising database objects. When iterated over it
returns a SerialisedModel instance for each of the items in the list.
"""
@property
@abstractmethod
def model(self):
pass
def __init__(self, items):
self.items = items
def __bool__(self):
return bool(self.items)
def __getitem__(self, index):
return self.model(self.items[index])
class SerialisedTemplate(SerialisedModel):
ALLOWED_PROPERTIES = {
'archived',
@@ -84,3 +111,49 @@ class SerialisedTemplate(SerialisedModel):
template_dict = template_schema.dump(fetched_template).data
return {'data': template_dict}
class SerialisedService(SerialisedModel):
ALLOWED_PROPERTIES = {
'id',
'active',
'contact_link',
'email_from',
'permissions',
'research_mode',
'restricted',
}
@classmethod
def from_id(cls, service_id):
return cls(cls.get_dict(service_id))
@staticmethod
def get_dict(service_id):
from app.schemas import service_schema
return service_schema.dump(dao_fetch_service_by_id(service_id)).data
@cached_property
def api_keys(self):
return SerialisedAPIKeyCollection.from_service_id(self.id)
class SerialisedAPIKey(SerialisedModel):
ALLOWED_PROPERTIES = {
'id',
'secret',
'expiry_date',
'key_type',
}
class SerialisedAPIKeyCollection(SerialisedModelCollection):
model = SerialisedAPIKey
@classmethod
def from_service_id(cls, service_id):
return cls([
{k: getattr(key, k) for k in SerialisedAPIKey.ALLOWED_PROPERTIES}
for key in get_model_api_keys(service_id)
])