mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-08 14:12:27 -05:00
This changeset pulls in all of the notification_utils code directly into the API and removes it as an external dependency. We are doing this to cut down on operational maintenance of the project and will begin removing parts of it no longer needed for the API. Signed-off-by: Carlo Costino <carlo.costino@gsa.gov>
135 lines
3.4 KiB
Python
135 lines
3.4 KiB
Python
from collections import defaultdict
|
|
from functools import partial
|
|
from threading import RLock
|
|
|
|
import cachetools
|
|
from flask import current_app
|
|
from werkzeug.utils import cached_property
|
|
|
|
from app import db, redis_store
|
|
from app.dao.api_key_dao import get_model_api_keys
|
|
from app.dao.services_dao import dao_fetch_service_by_id
|
|
from notifications_utils.clients.redis import RequestCache
|
|
from notifications_utils.serialised_model import (
|
|
SerialisedModel,
|
|
SerialisedModelCollection,
|
|
)
|
|
|
|
caches = defaultdict(partial(cachetools.TTLCache, maxsize=1024, ttl=2))
|
|
locks = defaultdict(RLock)
|
|
redis_cache = RequestCache(redis_store)
|
|
|
|
|
|
def memory_cache(func):
|
|
@cachetools.cached(
|
|
cache=caches[func.__qualname__],
|
|
lock=locks[func.__qualname__],
|
|
key=ignore_first_argument_cache_key,
|
|
)
|
|
def wrapper(*args, **kwargs):
|
|
return func(*args, **kwargs)
|
|
|
|
return wrapper
|
|
|
|
|
|
def ignore_first_argument_cache_key(cls, *args, **kwargs):
|
|
return cachetools.keys.hashkey(*args, **kwargs)
|
|
|
|
|
|
class SerialisedTemplate(SerialisedModel):
|
|
ALLOWED_PROPERTIES = {
|
|
"archived",
|
|
"content",
|
|
"id",
|
|
"process_type",
|
|
"reply_to_text",
|
|
"subject",
|
|
"template_type",
|
|
"version",
|
|
}
|
|
|
|
@classmethod
|
|
@memory_cache
|
|
def from_id_and_service_id(cls, template_id, service_id, version=None):
|
|
return cls(cls.get_dict(template_id, service_id, version)["data"])
|
|
|
|
@staticmethod
|
|
@redis_cache.set("service-{service_id}-template-{template_id}-version-{version}")
|
|
def get_dict(template_id, service_id, version):
|
|
from app.dao import templates_dao
|
|
from app.schemas import template_schema
|
|
|
|
fetched_template = templates_dao.dao_get_template_by_id_and_service_id(
|
|
template_id=template_id,
|
|
service_id=service_id,
|
|
version=version,
|
|
)
|
|
|
|
template_dict = template_schema.dump(fetched_template)
|
|
db.session.commit()
|
|
|
|
return {"data": template_dict}
|
|
|
|
|
|
class SerialisedService(SerialisedModel):
|
|
ALLOWED_PROPERTIES = {
|
|
"id",
|
|
"name",
|
|
"active",
|
|
"contact_link",
|
|
"email_from",
|
|
"message_limit",
|
|
"total_message_limit",
|
|
"permissions",
|
|
"rate_limit",
|
|
"restricted",
|
|
"prefix_sms",
|
|
"email_branding",
|
|
}
|
|
|
|
@classmethod
|
|
@memory_cache
|
|
def from_id(cls, service_id):
|
|
return cls(cls.get_dict(service_id)["data"])
|
|
|
|
@staticmethod
|
|
@redis_cache.set("service-{service_id}")
|
|
def get_dict(service_id):
|
|
from app.schemas import service_schema
|
|
|
|
service_dict = service_schema.dump(dao_fetch_service_by_id(service_id))
|
|
db.session.commit()
|
|
|
|
return {"data": service_dict}
|
|
|
|
@cached_property
|
|
def api_keys(self):
|
|
return SerialisedAPIKeyCollection.from_service_id(self.id)
|
|
|
|
@property
|
|
def high_volume(self):
|
|
return self.id in current_app.config["HIGH_VOLUME_SERVICE"]
|
|
|
|
|
|
class SerialisedAPIKey(SerialisedModel):
|
|
ALLOWED_PROPERTIES = {
|
|
"id",
|
|
"secret",
|
|
"expiry_date",
|
|
"key_type",
|
|
}
|
|
|
|
|
|
class SerialisedAPIKeyCollection(SerialisedModelCollection):
|
|
model = SerialisedAPIKey
|
|
|
|
@classmethod
|
|
@memory_cache
|
|
def from_service_id(cls, service_id):
|
|
keys = [
|
|
{k: getattr(key, k) for k in SerialisedAPIKey.ALLOWED_PROPERTIES}
|
|
for key in get_model_api_keys(service_id)
|
|
]
|
|
db.session.commit()
|
|
return cls(keys)
|