notify-api-412 use black to enforce python coding style

This commit is contained in:
Kenneth Kehl
2023-08-25 09:12:23 -07:00
parent c6eb007386
commit 8c9721d8e2
201 changed files with 31660 additions and 28105 deletions

View File

@@ -10,29 +10,25 @@ cache = RequestCache(redis_client)
def _attach_current_user(data):
return dict(
created_by=current_user.id,
**data
)
return dict(created_by=current_user.id, **data)
class NotifyAdminAPIClient(BaseAPIClient):
def __init__(self):
super().__init__("a" * 73, "b")
def init_app(self, app):
self.base_url = app.config['API_HOST_NAME']
self.service_id = app.config['ADMIN_CLIENT_USER_NAME']
self.api_key = app.config['ADMIN_CLIENT_SECRET']
self.route_secret = app.config['ROUTE_SECRET_KEY_1']
self.base_url = app.config["API_HOST_NAME"]
self.service_id = app.config["ADMIN_CLIENT_USER_NAME"]
self.api_key = app.config["ADMIN_CLIENT_SECRET"]
self.route_secret = app.config["ROUTE_SECRET_KEY_1"]
def generate_headers(self, api_token):
headers = {
"Content-type": "application/json",
"Authorization": "Bearer {}".format(api_token),
"X-Custom-Forwarder": self.route_secret,
"User-agent": "NOTIFY-API-PYTHON-CLIENT/{}".format(__version__)
"User-agent": "NOTIFY-API-PYTHON-CLIENT/{}".format(__version__),
}
return self._add_request_id_header(headers)
@@ -40,8 +36,8 @@ class NotifyAdminAPIClient(BaseAPIClient):
def _add_request_id_header(headers):
if not has_request_context():
return headers
headers['X-B3-TraceId'] = request.request_id
headers['X-B3-SpanId'] = request.span_id
headers["X-B3-TraceId"] = request.request_id
headers["X-B3-SpanId"] = request.span_id
return headers
def check_inactive_service(self):
@@ -51,7 +47,11 @@ class NotifyAdminAPIClient(BaseAPIClient):
# if the current service is inactive and the user isn't a platform admin, we should block them from making any
# stateful modifications to that service
if current_service and not current_service.active and not current_user.platform_admin:
if (
current_service
and not current_service.active
and not current_user.platform_admin
):
abort(403)
def post(self, *args, **kwargs):

View File

@@ -1,30 +1,26 @@
from app.notify_client import NotifyAdminAPIClient, _attach_current_user
# must match key types in notifications-api/app/models.py
KEY_TYPE_NORMAL = 'normal'
KEY_TYPE_TEAM = 'team'
KEY_TYPE_TEST = 'test'
KEY_TYPE_NORMAL = "normal"
KEY_TYPE_TEAM = "team"
KEY_TYPE_TEST = "test"
class ApiKeyApiClient(NotifyAdminAPIClient):
def get_api_keys(self, service_id):
return self.get(url='/service/{}/api-keys'.format(service_id))
return self.get(url="/service/{}/api-keys".format(service_id))
def create_api_key(self, service_id, key_name, key_type):
data = {
'name': key_name,
'key_type': key_type
}
data = {"name": key_name, "key_type": key_type}
data = _attach_current_user(data)
key = self.post(url='/service/{}/api-key'.format(service_id), data=data)
return key['data']
key = self.post(url="/service/{}/api-key".format(service_id), data=data)
return key["data"]
def revoke_api_key(self, service_id, key_id):
data = _attach_current_user({})
return self.post(
url='/service/{0}/api-key/revoke/{1}'.format(service_id, key_id),
data=data)
url="/service/{0}/api-key/revoke/{1}".format(service_id, key_id), data=data
)
api_key_api_client = ApiKeyApiClient()

View File

@@ -2,66 +2,73 @@ from app.notify_client import NotifyAdminAPIClient
class BillingAPIClient(NotifyAdminAPIClient):
def get_monthly_usage_for_service(self, service_id, year):
return self.get(
'/service/{0}/billing/monthly-usage'.format(service_id),
params=dict(year=year)
"/service/{0}/billing/monthly-usage".format(service_id),
params=dict(year=year),
)
def get_annual_usage_for_service(self, service_id, year=None):
return self.get(
'/service/{0}/billing/yearly-usage-summary'.format(service_id),
params=dict(year=year)
"/service/{0}/billing/yearly-usage-summary".format(service_id),
params=dict(year=year),
)
def get_free_sms_fragment_limit_for_year(self, service_id, year=None):
result = self.get(
'/service/{0}/billing/free-sms-fragment-limit'.format(service_id),
params=dict(financial_year_start=year)
"/service/{0}/billing/free-sms-fragment-limit".format(service_id),
params=dict(financial_year_start=year),
)
return result['free_sms_fragment_limit']
return result["free_sms_fragment_limit"]
def create_or_update_free_sms_fragment_limit(self, service_id, free_sms_fragment_limit, year=None):
def create_or_update_free_sms_fragment_limit(
self, service_id, free_sms_fragment_limit, year=None
):
# year = None will update current and future year in the API
data = {
"financial_year_start": year,
"free_sms_fragment_limit": free_sms_fragment_limit
"free_sms_fragment_limit": free_sms_fragment_limit,
}
return self.post(
url='/service/{0}/billing/free-sms-fragment-limit'.format(service_id),
data=data
url="/service/{0}/billing/free-sms-fragment-limit".format(service_id),
data=data,
)
def get_data_for_billing_report(self, start_date, end_date):
return self.get(url='/platform-stats/data-for-billing-report',
params={
'start_date': str(start_date),
'end_date': str(end_date),
})
return self.get(
url="/platform-stats/data-for-billing-report",
params={
"start_date": str(start_date),
"end_date": str(end_date),
},
)
def get_data_for_volumes_by_service_report(self, start_date, end_date):
return self.get(url='/platform-stats/volumes-by-service',
params={
'start_date': str(start_date),
'end_date': str(end_date),
})
return self.get(
url="/platform-stats/volumes-by-service",
params={
"start_date": str(start_date),
"end_date": str(end_date),
},
)
def get_data_for_daily_volumes_report(self, start_date, end_date):
return self.get(url='/platform-stats/daily-volumes-report',
params={
'start_date': str(start_date),
'end_date': str(end_date),
})
return self.get(
url="/platform-stats/daily-volumes-report",
params={
"start_date": str(start_date),
"end_date": str(end_date),
},
)
def get_data_for_daily_sms_provider_volumes_report(self, start_date, end_date):
return self.get(
url='/platform-stats/daily-sms-provider-volumes-report',
url="/platform-stats/daily-sms-provider-volumes-report",
params={
'start_date': str(start_date),
'end_date': str(end_date),
}
"start_date": str(start_date),
"end_date": str(end_date),
},
)

View File

@@ -2,13 +2,12 @@ from app.notify_client import NotifyAdminAPIClient
class ComplaintApiClient(NotifyAdminAPIClient):
def get_all_complaints(self, page=1):
params = {'page': page}
return self.get('/complaint', params=params)
params = {"page": page}
return self.get("/complaint", params=params)
def get_complaint_count(self, params_dict=None):
return self.get('/complaint/count-by-date-range', params=params_dict)
return self.get("/complaint/count-by-date-range", params=params_dict)
complaint_api_client = ComplaintApiClient()

View File

@@ -2,38 +2,37 @@ from app.notify_client import NotifyAdminAPIClient, cache
class EmailBrandingClient(NotifyAdminAPIClient):
@cache.set('email_branding-{branding_id}')
@cache.set("email_branding-{branding_id}")
def get_email_branding(self, branding_id):
return self.get(url='/email-branding/{}'.format(branding_id))
return self.get(url="/email-branding/{}".format(branding_id))
@cache.set('email_branding')
@cache.set("email_branding")
def get_all_email_branding(self, sort_key=None):
brandings = self.get(url='/email-branding')['email_branding']
brandings = self.get(url="/email-branding")["email_branding"]
if sort_key and sort_key in brandings[0]:
brandings.sort(key=lambda branding: branding[sort_key].lower())
return brandings
@cache.delete('email_branding')
@cache.delete("email_branding")
def create_email_branding(self, logo, name, text, colour, brand_type):
data = {
"logo": logo,
"name": name,
"text": text,
"colour": colour,
"brand_type": brand_type
"brand_type": brand_type,
}
return self.post(url="/email-branding", data=data)
@cache.delete('email_branding')
@cache.delete('email_branding-{branding_id}')
@cache.delete("email_branding")
@cache.delete("email_branding-{branding_id}")
def update_email_branding(self, branding_id, logo, name, text, colour, brand_type):
data = {
"logo": logo,
"name": name,
"text": text,
"colour": colour,
"brand_type": brand_type
"brand_type": brand_type,
}
return self.post(url="/email-branding/{}".format(branding_id), data=data)

View File

@@ -2,14 +2,10 @@ from app.notify_client import NotifyAdminAPIClient
class EventsApiClient(NotifyAdminAPIClient):
def create_event(self, event_type, event_data):
data = {
'event_type': event_type,
'data': event_data
}
resp = self.post(url='/events', data=data)
return resp['data']
data = {"event_type": event_type, "data": event_data}
resp = self.post(url="/events", data=data)
return resp["data"]
events_api_client = EventsApiClient()

View File

@@ -2,15 +2,14 @@ from app.notify_client import NotifyAdminAPIClient
class InboundNumberClient(NotifyAdminAPIClient):
def get_available_inbound_sms_numbers(self):
return self.get(url='/inbound-number/available')
return self.get(url="/inbound-number/available")
def get_all_inbound_sms_number_service(self):
return self.get('/inbound-number')
return self.get("/inbound-number")
def get_inbound_sms_number_for_service(self, service_id):
return self.get('/inbound-number/service/{}'.format(service_id))
return self.get("/inbound-number/service/{}".format(service_id))
inbound_number_client = InboundNumberClient()

View File

@@ -6,70 +6,72 @@ from app.utils.user_permissions import (
class InviteApiClient(NotifyAdminAPIClient):
def init_app(self, app):
super().init_app(app)
self.admin_url = app.config['ADMIN_BASE_URL']
self.admin_url = app.config["ADMIN_BASE_URL"]
def create_invite(self,
invite_from_id,
service_id,
email_address,
permissions,
auth_type,
folder_permissions):
def create_invite(
self,
invite_from_id,
service_id,
email_address,
permissions,
auth_type,
folder_permissions,
):
data = {
'service': service_id,
'email_address': email_address,
'from_user': invite_from_id,
'permissions': ','.join(sorted(translate_permissions_from_ui_to_db(permissions))),
'auth_type': auth_type,
'invite_link_host': self.admin_url,
'folder_permissions': folder_permissions,
"service": service_id,
"email_address": email_address,
"from_user": invite_from_id,
"permissions": ",".join(
sorted(translate_permissions_from_ui_to_db(permissions))
),
"auth_type": auth_type,
"invite_link_host": self.admin_url,
"folder_permissions": folder_permissions,
}
data = _attach_current_user(data)
resp = self.post(url='/service/{}/invite'.format(service_id), data=data)
return resp['data']
resp = self.post(url="/service/{}/invite".format(service_id), data=data)
return resp["data"]
def get_invites_for_service(self, service_id):
return self.get(
'/service/{}/invite'.format(service_id)
)['data']
return self.get("/service/{}/invite".format(service_id))["data"]
def get_invited_user(self, invited_user_id):
return self.get(
f'/invite/service/{invited_user_id}'
)['data']
return self.get(f"/invite/service/{invited_user_id}")["data"]
def get_invited_user_for_service(self, service_id, invited_user_id):
return self.get(
f'/service/{service_id}/invite/{invited_user_id}'
)['data']
return self.get(f"/service/{service_id}/invite/{invited_user_id}")["data"]
def get_count_of_invites_with_permission(self, service_id, permission):
if permission not in all_ui_permissions:
raise TypeError('{} is not a valid permission'.format(permission))
return len([
invited_user for invited_user in self.get_invites_for_service(service_id)
if invited_user.has_permission_for_service(service_id, permission)
])
raise TypeError("{} is not a valid permission".format(permission))
return len(
[
invited_user
for invited_user in self.get_invites_for_service(service_id)
if invited_user.has_permission_for_service(service_id, permission)
]
)
def check_token(self, token):
return self.get(url='/invite/service/check/{}'.format(token))['data']
return self.get(url="/invite/service/check/{}".format(token))["data"]
def cancel_invited_user(self, service_id, invited_user_id):
data = {'status': 'cancelled'}
data = {"status": "cancelled"}
data = _attach_current_user(data)
self.post(url='/service/{0}/invite/{1}'.format(service_id, invited_user_id),
data=data)
self.post(
url="/service/{0}/invite/{1}".format(service_id, invited_user_id), data=data
)
@cache.delete('service-{service_id}')
@cache.delete('user-{invited_user_id}')
@cache.delete("service-{service_id}")
@cache.delete("user-{invited_user_id}")
def accept_invite(self, service_id, invited_user_id):
data = {'status': 'accepted'}
self.post(url='/service/{0}/invite/{1}'.format(service_id, invited_user_id),
data=data)
data = {"status": "accepted"}
self.post(
url="/service/{0}/invite/{1}".format(service_id, invited_user_id), data=data
)
invite_api_client = InviteApiClient()

View File

@@ -3,52 +3,58 @@ from app.notify_client import NotifyAdminAPIClient, _attach_current_user, cache
class JobApiClient(NotifyAdminAPIClient):
JOB_STATUSES = {
'scheduled',
'pending',
'in progress',
'finished',
'cancelled',
'sending limits exceeded',
'ready to send',
'sent to dvla'
"scheduled",
"pending",
"in progress",
"finished",
"cancelled",
"sending limits exceeded",
"ready to send",
"sent to dvla",
}
SCHEDULED_JOB_STATUS = 'scheduled'
CANCELLED_JOB_STATUS = 'cancelled'
SCHEDULED_JOB_STATUS = "scheduled"
CANCELLED_JOB_STATUS = "cancelled"
NON_CANCELLED_JOB_STATUSES = JOB_STATUSES - {CANCELLED_JOB_STATUS}
NON_SCHEDULED_JOB_STATUSES = JOB_STATUSES - {SCHEDULED_JOB_STATUS, CANCELLED_JOB_STATUS}
NON_SCHEDULED_JOB_STATUSES = JOB_STATUSES - {
SCHEDULED_JOB_STATUS,
CANCELLED_JOB_STATUS,
}
def get_job(self, service_id, job_id):
params = {}
job = self.get(url='/service/{}/job/{}'.format(service_id, job_id), params=params)
job = self.get(
url="/service/{}/job/{}".format(service_id, job_id), params=params
)
return job
def get_jobs(self, service_id, *, limit_days=None, statuses=None, page=1):
params = {'page': page}
params = {"page": page}
if limit_days is not None:
params['limit_days'] = limit_days
params["limit_days"] = limit_days
if statuses is not None:
params['statuses'] = ','.join(statuses)
params["statuses"] = ",".join(statuses)
return self.get(url='/service/{}/job'.format(service_id), params=params)
return self.get(url="/service/{}/job".format(service_id), params=params)
def get_uploads(self, service_id, limit_days=None, page=1):
params = {'page': page}
params = {"page": page}
if limit_days is not None:
params['limit_days'] = limit_days
return self.get(url='/service/{}/upload'.format(service_id), params=params)
params["limit_days"] = limit_days
return self.get(url="/service/{}/upload".format(service_id), params=params)
def has_sent_previously(self, service_id, template_id, template_version, original_file_name):
return (
template_id, template_version, original_file_name
) in (
def has_sent_previously(
self, service_id, template_id, template_version, original_file_name
):
return (template_id, template_version, original_file_name) in (
(
job['template'], job['template_version'], job['original_file_name'],
job["template"],
job["template_version"],
job["original_file_name"],
)
for job in self.get_jobs(service_id, limit_days=0)['data']
if job['job_status'] != 'cancelled'
for job in self.get_jobs(service_id, limit_days=0)["data"]
if job["job_status"] != "cancelled"
)
def get_page_of_jobs(self, service_id, *, page, statuses=None, limit_days=None):
@@ -64,49 +70,43 @@ class JobApiClient(NotifyAdminAPIClient):
service_id,
limit_days=7,
statuses=self.NON_SCHEDULED_JOB_STATUSES,
)['data']
)["data"]
def get_scheduled_jobs(self, service_id):
return sorted(
self.get_jobs(
service_id,
statuses=[self.SCHEDULED_JOB_STATUS]
)['data'],
key=lambda job: job['scheduled_for'],
self.get_jobs(service_id, statuses=[self.SCHEDULED_JOB_STATUS])["data"],
key=lambda job: job["scheduled_for"],
reverse=True,
)
def get_scheduled_job_stats(self, service_id):
return self.get(
url=f'/service/{service_id}/job/scheduled-job-stats'
)
return self.get(url=f"/service/{service_id}/job/scheduled-job-stats")
@cache.set('has_jobs-{service_id}')
@cache.set("has_jobs-{service_id}")
def has_jobs(self, service_id):
return bool(self.get_jobs(service_id)['data'])
return bool(self.get_jobs(service_id)["data"])
def create_job(self, job_id, service_id, scheduled_for=None):
data = {"id": job_id}
if scheduled_for:
data.update({'scheduled_for': scheduled_for})
data.update({"scheduled_for": scheduled_for})
data = _attach_current_user(data)
job = self.post(url='/service/{}/job'.format(service_id), data=data)
job = self.post(url="/service/{}/job".format(service_id), data=data)
redis_client.set(
'has_jobs-{}'.format(service_id),
b'true',
"has_jobs-{}".format(service_id),
b"true",
ex=int(cache.DEFAULT_TTL),
)
return job
@cache.delete('has_jobs-{service_id}')
@cache.delete("has_jobs-{service_id}")
def cancel_job(self, service_id, job_id):
return self.post(
url='/service/{}/job/{}/cancel'.format(service_id, job_id),
data={}
url="/service/{}/job/{}/cancel".format(service_id, job_id), data={}
)

View File

@@ -2,7 +2,6 @@ from app.notify_client import NotifyAdminAPIClient, _attach_current_user
class NotificationApiClient(NotifyAdminAPIClient):
def get_notifications_for_service(
self,
service_id,
@@ -20,16 +19,16 @@ class NotificationApiClient(NotifyAdminAPIClient):
include_one_off=None,
):
params = {
'page': page,
'page_size': page_size,
'template_type': template_type,
'status': status,
'include_jobs': include_jobs,
'include_from_test_key': include_from_test_key,
'format_for_csv': format_for_csv,
'to': to,
'include_one_off': include_one_off,
'count_pages': count_pages,
"page": page,
"page_size": page_size,
"template_type": template_type,
"status": status,
"include_jobs": include_jobs,
"include_from_test_key": include_from_test_key,
"format_for_csv": format_for_csv,
"to": to,
"include_one_off": include_one_off,
"count_pages": count_pages,
}
params = {k: v for k, v in params.items() if v is not None}
@@ -37,34 +36,37 @@ class NotificationApiClient(NotifyAdminAPIClient):
# if `to` is set it is likely PII like an email address or mobile which
# we do not want in our logs, so we do a POST request instead of a GET
method = self.post if to else self.get
kwargs = {'data': params} if to else {'params': params}
kwargs = {"data": params} if to else {"params": params}
if job_id:
return method(
url='/service/{}/job/{}/notifications'.format(service_id, job_id),
url="/service/{}/job/{}/notifications".format(service_id, job_id),
**kwargs
)
else:
if limit_days is not None:
params['limit_days'] = limit_days
return method(
url='/service/{}/notifications'.format(service_id),
**kwargs
)
params["limit_days"] = limit_days
return method(url="/service/{}/notifications".format(service_id), **kwargs)
def send_notification(self, service_id, *, template_id, recipient, personalisation, sender_id):
def send_notification(
self, service_id, *, template_id, recipient, personalisation, sender_id
):
data = {
'template_id': template_id,
'to': recipient,
'personalisation': personalisation,
"template_id": template_id,
"to": recipient,
"personalisation": personalisation,
}
if sender_id:
data['sender_id'] = sender_id
data["sender_id"] = sender_id
data = _attach_current_user(data)
return self.post(url='/service/{}/send-notification'.format(service_id), data=data)
return self.post(
url="/service/{}/send-notification".format(service_id), data=data
)
def get_notification(self, service_id, notification_id):
return self.get(url='/service/{}/notifications/{}'.format(service_id, notification_id))
return self.get(
url="/service/{}/notifications/{}".format(service_id, notification_id)
)
def get_api_notifications_for_service(self, service_id):
ret = self.get_notifications_for_service(
@@ -72,26 +74,31 @@ class NotificationApiClient(NotifyAdminAPIClient):
include_jobs=False,
include_from_test_key=True,
include_one_off=False,
count_pages=False
count_pages=False,
)
return ret
def update_notification_to_cancelled(self, service_id, notification_id):
return self.post(
url='/service/{}/notifications/{}/cancel'.format(service_id, notification_id),
data={})
url="/service/{}/notifications/{}/cancel".format(
service_id, notification_id
),
data={},
)
def get_notification_status_by_service(self, start_date, end_date):
return self.get(
url='service/monthly-data-by-service',
url="service/monthly-data-by-service",
params={
'start_date': str(start_date),
'end_date': str(end_date),
}
"start_date": str(start_date),
"end_date": str(end_date),
},
)
def get_notification_count_for_job_id(self, *, service_id, job_id):
return self.get(url='/service/{}/job/{}/notification_count'.format(service_id, job_id))["count"]
return self.get(
url="/service/{}/job/{}/notification_count".format(service_id, job_id)
)["count"]
notification_api_client = NotificationApiClient()

View File

@@ -2,51 +2,50 @@ from app.notify_client import NotifyAdminAPIClient, _attach_current_user
class OrgInviteApiClient(NotifyAdminAPIClient):
def init_app(self, app):
super().init_app(app)
self.admin_url = app.config['ADMIN_BASE_URL']
self.admin_url = app.config["ADMIN_BASE_URL"]
def create_invite(self, invite_from_id, org_id, email_address):
data = {
'email_address': email_address,
'invited_by': invite_from_id,
'invite_link_host': self.admin_url,
"email_address": email_address,
"invited_by": invite_from_id,
"invite_link_host": self.admin_url,
}
data = _attach_current_user(data)
resp = self.post(url='/organization/{}/invite'.format(org_id), data=data)
return resp['data']
resp = self.post(url="/organization/{}/invite".format(org_id), data=data)
return resp["data"]
def get_invites_for_organization(self, org_id):
endpoint = '/organization/{}/invite'.format(org_id)
endpoint = "/organization/{}/invite".format(org_id)
resp = self.get(endpoint)
return resp['data']
return resp["data"]
def get_invited_user_for_org(self, org_id, invited_org_user_id):
return self.get(
f'/organization/{org_id}/invite/{invited_org_user_id}'
)['data']
return self.get(f"/organization/{org_id}/invite/{invited_org_user_id}")["data"]
def get_invited_user(self, invited_user_id):
return self.get(
f'/invite/organization/{invited_user_id}'
)['data']
return self.get(f"/invite/organization/{invited_user_id}")["data"]
def check_token(self, token):
resp = self.get(url='/invite/organization/check/{}'.format(token))
return resp['data']
resp = self.get(url="/invite/organization/check/{}".format(token))
return resp["data"]
def cancel_invited_user(self, org_id, invited_user_id):
data = {'status': 'cancelled'}
data = {"status": "cancelled"}
data = _attach_current_user(data)
self.post(url='/organization/{0}/invite/{1}'.format(org_id, invited_user_id),
data=data)
self.post(
url="/organization/{0}/invite/{1}".format(org_id, invited_user_id),
data=data,
)
def accept_invite(self, org_id, invited_user_id):
data = {'status': 'accepted'}
self.post(url='/organization/{0}/invite/{1}'.format(org_id, invited_user_id),
data=data)
data = {"status": "accepted"}
self.post(
url="/organization/{0}/invite/{1}".format(org_id, invited_user_id),
data=data,
)
org_invite_api_client = OrgInviteApiClient()

View File

@@ -7,81 +7,76 @@ from app.notify_client import NotifyAdminAPIClient, cache
class OrganizationsClient(NotifyAdminAPIClient):
@cache.set('organizations')
@cache.set("organizations")
def get_organizations(self):
return self.get(url='/organizations')
return self.get(url="/organizations")
@cache.set('domains')
@cache.set("domains")
def get_domains(self):
return list(chain.from_iterable(
organization['domains']
for organization in self.get_organizations()
))
return list(
chain.from_iterable(
organization["domains"] for organization in self.get_organizations()
)
)
def get_organization(self, org_id):
return self.get(url='/organizations/{}'.format(org_id))
return self.get(url="/organizations/{}".format(org_id))
@cache.set('organization-{org_id}-name')
@cache.set("organization-{org_id}-name")
def get_organization_name(self, org_id):
return self.get_organization(org_id)['name']
return self.get_organization(org_id)["name"]
def get_organization_by_domain(self, domain):
try:
return self.get(
url='/organizations/by-domain?domain={}'.format(domain),
url="/organizations/by-domain?domain={}".format(domain),
)
except HTTPError as error:
if error.status_code == 404:
return None
raise error
@cache.delete('organizations')
@cache.delete("organizations")
def create_organization(self, name, organization_type):
return self.post(
url="/organizations",
data={
"name": name,
"organization_type": organization_type,
}
},
)
@cache.delete('domains')
@cache.delete('organizations')
@cache.delete("domains")
@cache.delete("organizations")
def update_organization(self, org_id, cached_service_ids=None, **kwargs):
api_response = self.post(url="/organizations/{}".format(org_id), data=kwargs)
if cached_service_ids:
redis_client.delete(*map('service-{}'.format, cached_service_ids))
redis_client.delete(*map("service-{}".format, cached_service_ids))
if 'name' in kwargs:
redis_client.delete(f'organization-{org_id}-name')
if "name" in kwargs:
redis_client.delete(f"organization-{org_id}-name")
return api_response
@cache.delete('service-{service_id}')
@cache.delete('live-service-and-organization-counts')
@cache.delete('organizations')
@cache.delete("service-{service_id}")
@cache.delete("live-service-and-organization-counts")
@cache.delete("organizations")
def update_service_organization(self, service_id, org_id):
data = {
'service_id': service_id
}
return self.post(
url="/organizations/{}/service".format(org_id),
data=data
)
data = {"service_id": service_id}
return self.post(url="/organizations/{}/service".format(org_id), data=data)
def get_organization_services(self, org_id):
return self.get(url="/organizations/{}/services".format(org_id))
@cache.delete('user-{user_id}')
@cache.delete("user-{user_id}")
def remove_user_from_organization(self, org_id, user_id):
return self.delete(f'/organizations/{org_id}/users/{user_id}')
return self.delete(f"/organizations/{org_id}/users/{user_id}")
def get_services_and_usage(self, org_id, year):
return self.get(
url=f"/organizations/{org_id}/services-with-usage",
params={"year": str(year)}
params={"year": str(year)},
)

View File

@@ -2,8 +2,7 @@ from app.notify_client import NotifyAdminAPIClient, cache
class PerformanceDashboardAPIClient(NotifyAdminAPIClient):
@cache.set('performance-stats-{start_date}-to-{end_date}', ttl_in_seconds=3600)
@cache.set("performance-stats-{start_date}-to-{end_date}", ttl_in_seconds=3600)
def get_performance_dashboard_stats(
self,
*,
@@ -11,11 +10,11 @@ class PerformanceDashboardAPIClient(NotifyAdminAPIClient):
end_date,
):
return self.get(
'/performance-dashboard',
"/performance-dashboard",
params={
'start_date': str(start_date),
'end_date': str(end_date),
}
"start_date": str(start_date),
"end_date": str(end_date),
},
)

View File

@@ -2,7 +2,6 @@ from app.notify_client import NotifyAdminAPIClient
class PlatformStatsAPIClient(NotifyAdminAPIClient):
def get_aggregate_platform_stats(self, params_dict=None):
return self.get("/platform-stats", params=params_dict)

View File

@@ -1,30 +1,20 @@
from app.notify_client import NotifyAdminAPIClient, _attach_current_user
class ProviderClient(NotifyAdminAPIClient):
def get_all_providers(self):
return self.get(
url='/provider-details'
)
return self.get(url="/provider-details")
def get_provider_by_id(self, provider_id):
return self.get(
url='/provider-details/{}'.format(provider_id)
)
return self.get(url="/provider-details/{}".format(provider_id))
def get_provider_versions(self, provider_id):
return self.get(
url='/provider-details/{}/versions'.format(provider_id)
)
return self.get(url="/provider-details/{}/versions".format(provider_id))
def update_provider(self, provider_id, priority):
data = {
"priority": priority
}
data = {"priority": priority}
data = _attach_current_user(data)
return self.post(url='/provider-details/{}'.format(provider_id), data=data)
return self.post(url="/provider-details/{}".format(provider_id), data=data)
provider_client = ProviderClient()

View File

@@ -7,7 +7,7 @@ from app.notify_client import NotifyAdminAPIClient, _attach_current_user, cache
class ServiceAPIClient(NotifyAdminAPIClient):
@cache.delete('user-{user_id}')
@cache.delete("user-{user_id}")
def create_service(
self,
service_name,
@@ -30,97 +30,100 @@ class ServiceAPIClient(NotifyAdminAPIClient):
"email_from": email_from,
}
data = _attach_current_user(data)
return self.post("/service", data)['data']['id']
return self.post("/service", data)["data"]["id"]
@cache.set('service-{service_id}')
@cache.set("service-{service_id}")
def get_service(self, service_id):
"""
Retrieve a service.
"""
return self.get('/service/{0}'.format(service_id))
return self.get("/service/{0}".format(service_id))
def get_service_statistics(self, service_id, limit_days=None):
return self.get('/service/{0}/statistics'.format(service_id), params={'limit_days': limit_days})['data']
return self.get(
"/service/{0}/statistics".format(service_id),
params={"limit_days": limit_days},
)["data"]
def get_services(self, params_dict=None):
"""
Retrieve a list of services.
"""
return self.get('/service', params=params_dict)
return self.get("/service", params=params_dict)
def find_services_by_name(self, service_name):
return self.get('/service/find-services-by-name', params={"service_name": service_name})
return self.get(
"/service/find-services-by-name", params={"service_name": service_name}
)
def get_live_services_data(self, params_dict=None):
"""
Retrieve a list of live services data with contact names and notification counts.
"""
return self.get('/service/live-services-data', params=params_dict)
return self.get("/service/live-services-data", params=params_dict)
def get_active_services(self, params_dict=None):
"""
Retrieve a list of active services.
"""
params_dict['only_active'] = True
params_dict["only_active"] = True
return self.get_services(params_dict)
@cache.delete('service-{service_id}')
def update_service(
self,
service_id,
**kwargs
):
@cache.delete("service-{service_id}")
def update_service(self, service_id, **kwargs):
"""
Update a service.
"""
data = _attach_current_user(kwargs)
disallowed_attributes = set(data.keys()) - {
'active',
'billing_contact_email_addresses',
'billing_contact_names',
'billing_reference',
'consent_to_research',
'contact_link',
'created_by',
'count_as_live',
'email_branding',
'email_from',
'free_sms_fragment_limit',
'go_live_at',
'go_live_user',
'message_limit',
'name',
'notes',
'organization_type',
'permissions',
'prefix_sms',
'purchase_order_number',
'rate_limit',
'reply_to_email_address',
'research_mode',
'restricted',
'sms_sender',
'volume_email',
'volume_sms',
"active",
"billing_contact_email_addresses",
"billing_contact_names",
"billing_reference",
"consent_to_research",
"contact_link",
"created_by",
"count_as_live",
"email_branding",
"email_from",
"free_sms_fragment_limit",
"go_live_at",
"go_live_user",
"message_limit",
"name",
"notes",
"organization_type",
"permissions",
"prefix_sms",
"purchase_order_number",
"rate_limit",
"reply_to_email_address",
"research_mode",
"restricted",
"sms_sender",
"volume_email",
"volume_sms",
}
if disallowed_attributes:
raise TypeError('Not allowed to update service attributes: {}'.format(
", ".join(disallowed_attributes)
))
raise TypeError(
"Not allowed to update service attributes: {}".format(
", ".join(disallowed_attributes)
)
)
endpoint = "/service/{0}".format(service_id)
return self.post(endpoint, data)
@cache.delete('live-service-and-organization-counts')
@cache.delete("live-service-and-organization-counts")
def update_status(self, service_id, live):
return self.update_service(
service_id,
message_limit=250000 if live else 50,
restricted=(not live),
go_live_at=str(datetime.utcnow()) if live else None
go_live_at=str(datetime.utcnow()) if live else None,
)
@cache.delete('live-service-and-organization-counts')
@cache.delete("live-service-and-organization-counts")
def update_count_as_live(self, service_id, count_as_live):
return self.update_service(
service_id,
@@ -131,37 +134,38 @@ class ServiceAPIClient(NotifyAdminAPIClient):
def update_service_with_properties(self, service_id, properties):
return self.update_service(service_id, **properties)
@cache.delete('service-{service_id}')
@cache.delete('service-{service_id}-templates')
@cache.delete_by_pattern('service-{service_id}-template-*')
@cache.delete("service-{service_id}")
@cache.delete("service-{service_id}-templates")
@cache.delete_by_pattern("service-{service_id}-template-*")
def archive_service(self, service_id, cached_service_user_ids):
if cached_service_user_ids:
redis_client.delete(*map('user-{}'.format, cached_service_user_ids))
return self.post('/service/{}/archive'.format(service_id), data=None)
redis_client.delete(*map("user-{}".format, cached_service_user_ids))
return self.post("/service/{}/archive".format(service_id), data=None)
@cache.delete('service-{service_id}')
@cache.delete("service-{service_id}")
def suspend_service(self, service_id):
return self.post('/service/{}/suspend'.format(service_id), data=None)
return self.post("/service/{}/suspend".format(service_id), data=None)
@cache.delete('service-{service_id}')
@cache.delete("service-{service_id}")
def resume_service(self, service_id):
return self.post('/service/{}/resume'.format(service_id), data=None)
return self.post("/service/{}/resume".format(service_id), data=None)
@cache.delete('service-{service_id}')
@cache.delete('user-{user_id}')
@cache.delete("service-{service_id}")
@cache.delete("user-{user_id}")
def remove_user_from_service(self, service_id, user_id):
"""
Remove a user from a service
"""
endpoint = '/service/{service_id}/users/{user_id}'.format(
service_id=service_id,
user_id=user_id)
endpoint = "/service/{service_id}/users/{user_id}".format(
service_id=service_id, user_id=user_id
)
data = _attach_current_user({})
return self.delete(endpoint, data)
@cache.delete('service-{service_id}-templates')
def create_service_template(self, name, type_, content, service_id, subject=None,
parent_folder_id=None):
@cache.delete("service-{service_id}-templates")
def create_service_template(
self, name, type_, content, service_id, subject=None, parent_folder_id=None
):
"""
Create a service template.
"""
@@ -170,22 +174,18 @@ class ServiceAPIClient(NotifyAdminAPIClient):
"template_type": type_,
"content": content,
"service": service_id,
"process_type": 'normal',
"process_type": "normal",
}
if subject:
data.update({
'subject': subject
})
data.update({"subject": subject})
if parent_folder_id:
data.update({
'parent_folder_id': parent_folder_id
})
data.update({"parent_folder_id": parent_folder_id})
data = _attach_current_user(data)
endpoint = "/service/{0}/template".format(service_id)
return self.post(endpoint, data)
@cache.delete('service-{service_id}-templates')
@cache.delete_by_pattern('service-{service_id}-template-*')
@cache.delete("service-{service_id}-templates")
@cache.delete_by_pattern("service-{service_id}-template-*")
def update_service_template(
self, id_, name, type_, content, service_id, subject=None
):
@@ -193,65 +193,57 @@ class ServiceAPIClient(NotifyAdminAPIClient):
Update a service template.
"""
data = {
'id': id_,
'name': name,
'template_type': type_,
'content': content,
'service': service_id
"id": id_,
"name": name,
"template_type": type_,
"content": content,
"service": service_id,
}
if subject:
data.update({
'subject': subject
})
data.update({
'process_type': 'normal'
})
data.update({"subject": subject})
data.update({"process_type": "normal"})
data = _attach_current_user(data)
endpoint = "/service/{0}/template/{1}".format(service_id, id_)
return self.post(endpoint, data)
@cache.delete('service-{service_id}-templates')
@cache.delete_by_pattern('service-{service_id}-template-*')
@cache.delete("service-{service_id}-templates")
@cache.delete_by_pattern("service-{service_id}-template-*")
def redact_service_template(self, service_id, id_):
return self.post(
"/service/{}/template/{}".format(service_id, id_),
_attach_current_user(
{'redact_personalisation': True}
),
_attach_current_user({"redact_personalisation": True}),
)
@cache.delete('service-{service_id}-templates')
@cache.delete_by_pattern('service-{service_id}-template-*')
@cache.delete("service-{service_id}-templates")
@cache.delete_by_pattern("service-{service_id}-template-*")
def update_service_template_sender(self, service_id, template_id, reply_to):
data = {
'reply_to': reply_to,
"reply_to": reply_to,
}
data = _attach_current_user(data)
return self.post(
"/service/{0}/template/{1}".format(service_id, template_id),
data
"/service/{0}/template/{1}".format(service_id, template_id), data
)
@cache.set('service-{service_id}-template-{template_id}-version-{version}')
@cache.set("service-{service_id}-template-{template_id}-version-{version}")
def get_service_template(self, service_id, template_id, version=None):
"""
Retrieve a service template.
"""
endpoint = '/service/{service_id}/template/{template_id}'.format(
service_id=service_id,
template_id=template_id)
endpoint = "/service/{service_id}/template/{template_id}".format(
service_id=service_id, template_id=template_id
)
if version:
endpoint = '{base}/version/{version}'.format(base=endpoint, version=version)
endpoint = "{base}/version/{version}".format(base=endpoint, version=version)
return self.get(endpoint)
@cache.set('service-{service_id}-template-{template_id}-versions')
@cache.set("service-{service_id}-template-{template_id}-versions")
def get_service_template_versions(self, service_id, template_id):
"""
Retrieve a list of versions for a template
"""
endpoint = '/service/{service_id}/template/{template_id}/versions'.format(
service_id=service_id,
template_id=template_id
endpoint = "/service/{service_id}/template/{template_id}/versions".format(
service_id=service_id, template_id=template_id
)
return self.get(endpoint)
@@ -259,268 +251,244 @@ class ServiceAPIClient(NotifyAdminAPIClient):
"""
Returns the precompiled template for a service, creating it if it doesn't already exist
"""
return self.get('/service/{}/template/precompiled'.format(service_id))
return self.get("/service/{}/template/precompiled".format(service_id))
@cache.set('service-{service_id}-templates')
@cache.set("service-{service_id}-templates")
def get_service_templates(self, service_id):
"""
Retrieve all templates for service.
"""
endpoint = '/service/{service_id}/template?detailed=False'.format(
service_id=service_id)
endpoint = "/service/{service_id}/template?detailed=False".format(
service_id=service_id
)
return self.get(endpoint)
# This doesnt need caching because it calls through to a method which is cached
def count_service_templates(self, service_id, template_type=None):
return len([
template for template in
self.get_service_templates(service_id)['data']
if (
not template_type
or template['template_type'] == template_type
)
])
return len(
[
template
for template in self.get_service_templates(service_id)["data"]
if (not template_type or template["template_type"] == template_type)
]
)
@cache.delete('service-{service_id}-templates')
@cache.delete_by_pattern('service-{service_id}-template-*')
@cache.delete("service-{service_id}-templates")
@cache.delete_by_pattern("service-{service_id}-template-*")
def delete_service_template(self, service_id, template_id):
"""
Set a service template's archived flag to True
"""
endpoint = "/service/{0}/template/{1}".format(service_id, template_id)
data = {
'archived': True
}
data = {"archived": True}
data = _attach_current_user(data)
return self.post(endpoint, data=data)
# Temp access of service history data. Includes service and api key history
def get_service_history(self, service_id):
return self.get('/service/{0}/history'.format(service_id))['data']
return self.get("/service/{0}/history".format(service_id))["data"]
def get_service_service_history(self, service_id):
return self.get_service_history(service_id)['service_history']
return self.get_service_history(service_id)["service_history"]
def get_service_api_key_history(self, service_id):
return self.get_service_history(service_id)['api_key_history']
return self.get_service_history(service_id)["api_key_history"]
def get_monthly_notification_stats(self, service_id, year):
return self.get(url='/service/{}/notifications/monthly?year={}'.format(service_id, year))
return self.get(
url="/service/{}/notifications/monthly?year={}".format(service_id, year)
)
def get_guest_list(self, service_id):
return self.get(url='/service/{}/guest-list'.format(service_id))
return self.get(url="/service/{}/guest-list".format(service_id))
@cache.delete('service-{service_id}')
@cache.delete("service-{service_id}")
def update_guest_list(self, service_id, data):
return self.put(url='/service/{}/guest-list'.format(service_id), data=data)
return self.put(url="/service/{}/guest-list".format(service_id), data=data)
def get_inbound_sms(self, service_id, user_number=''):
def get_inbound_sms(self, service_id, user_number=""):
# POST prevents the user phone number leaking into our logs
return self.post(
'/service/{}/inbound-sms'.format(
"/service/{}/inbound-sms".format(
service_id,
),
data={'phone_number': user_number}
data={"phone_number": user_number},
)
def get_most_recent_inbound_sms(self, service_id, page=None):
return self.get(
'/service/{}/inbound-sms/most-recent'.format(
"/service/{}/inbound-sms/most-recent".format(
service_id,
),
params={
'page': page
}
params={"page": page},
)
def get_inbound_sms_by_id(self, service_id, notification_id):
return self.get(
'/service/{}/inbound-sms/{}'.format(
"/service/{}/inbound-sms/{}".format(
service_id,
notification_id,
)
)
def get_inbound_sms_summary(self, service_id):
return self.get(
'/service/{}/inbound-sms/summary'.format(service_id)
)
return self.get("/service/{}/inbound-sms/summary".format(service_id))
@cache.delete('service-{service_id}')
@cache.delete("service-{service_id}")
def create_service_inbound_api(self, service_id, url, bearer_token, user_id):
data = {
"url": url,
"bearer_token": bearer_token,
"updated_by_id": user_id
}
data = {"url": url, "bearer_token": bearer_token, "updated_by_id": user_id}
return self.post("/service/{}/inbound-api".format(service_id), data)
@cache.delete('service-{service_id}')
def update_service_inbound_api(self, service_id, url, bearer_token, user_id, inbound_api_id):
data = {
"url": url,
"updated_by_id": user_id
}
@cache.delete("service-{service_id}")
def update_service_inbound_api(
self, service_id, url, bearer_token, user_id, inbound_api_id
):
data = {"url": url, "updated_by_id": user_id}
if bearer_token:
data['bearer_token'] = bearer_token
return self.post("/service/{}/inbound-api/{}".format(service_id, inbound_api_id), data)
data["bearer_token"] = bearer_token
return self.post(
"/service/{}/inbound-api/{}".format(service_id, inbound_api_id), data
)
def get_service_inbound_api(self, service_id, inbound_sms_api_id):
return self.get(
"/service/{}/inbound-api/{}".format(
service_id, inbound_sms_api_id
)
)['data']
"/service/{}/inbound-api/{}".format(service_id, inbound_sms_api_id)
)["data"]
@cache.delete('service-{service_id}')
@cache.delete("service-{service_id}")
def delete_service_inbound_api(self, service_id, callback_api_id):
return self.delete("/service/{}/inbound-api/{}".format(
service_id, callback_api_id
))
return self.delete(
"/service/{}/inbound-api/{}".format(service_id, callback_api_id)
)
def get_reply_to_email_addresses(self, service_id):
return self.get(
"/service/{}/email-reply-to".format(
service_id
)
)
return self.get("/service/{}/email-reply-to".format(service_id))
def get_reply_to_email_address(self, service_id, reply_to_email_id):
return self.get(
"/service/{}/email-reply-to/{}".format(
service_id,
reply_to_email_id
)
"/service/{}/email-reply-to/{}".format(service_id, reply_to_email_id)
)
def verify_reply_to_email_address(self, service_id, email_address):
return self.post(
"/service/{}/email-reply-to/verify".format(service_id),
data={"email": email_address}
data={"email": email_address},
)
@cache.delete('service-{service_id}')
@cache.delete_by_pattern('service-{service_id}-template-*')
@cache.delete("service-{service_id}")
@cache.delete_by_pattern("service-{service_id}-template-*")
def add_reply_to_email_address(self, service_id, email_address, is_default=False):
return self.post(
"/service/{}/email-reply-to".format(service_id),
data={
"email_address": email_address,
"is_default": is_default
}
data={"email_address": email_address, "is_default": is_default},
)
@cache.delete('service-{service_id}')
@cache.delete_by_pattern('service-{service_id}-template-*')
def update_reply_to_email_address(self, service_id, reply_to_email_id, email_address, is_default=False):
@cache.delete("service-{service_id}")
@cache.delete_by_pattern("service-{service_id}-template-*")
def update_reply_to_email_address(
self, service_id, reply_to_email_id, email_address, is_default=False
):
return self.post(
"/service/{}/email-reply-to/{}".format(
service_id,
reply_to_email_id,
),
data={
"email_address": email_address,
"is_default": is_default
}
data={"email_address": email_address, "is_default": is_default},
)
@cache.delete('service-{service_id}')
@cache.delete_by_pattern('service-{service_id}-template-*')
@cache.delete("service-{service_id}")
@cache.delete_by_pattern("service-{service_id}-template-*")
def delete_reply_to_email_address(self, service_id, reply_to_email_id):
return self.post(
"/service/{}/email-reply-to/{}/archive".format(service_id, reply_to_email_id),
data=None
"/service/{}/email-reply-to/{}/archive".format(
service_id, reply_to_email_id
),
data=None,
)
def get_sms_senders(self, service_id):
return self.get(
"/service/{}/sms-sender".format(service_id)
)
return self.get("/service/{}/sms-sender".format(service_id))
def get_sms_sender(self, service_id, sms_sender_id):
return self.get(
"/service/{}/sms-sender/{}".format(service_id, sms_sender_id)
)
return self.get("/service/{}/sms-sender/{}".format(service_id, sms_sender_id))
@cache.delete('service-{service_id}')
@cache.delete_by_pattern('service-{service_id}-template-*')
def add_sms_sender(self, service_id, sms_sender, is_default=False, inbound_number_id=None):
data = {
"sms_sender": sms_sender,
"is_default": is_default
}
@cache.delete("service-{service_id}")
@cache.delete_by_pattern("service-{service_id}-template-*")
def add_sms_sender(
self, service_id, sms_sender, is_default=False, inbound_number_id=None
):
data = {"sms_sender": sms_sender, "is_default": is_default}
if inbound_number_id:
data["inbound_number_id"] = inbound_number_id
return self.post("/service/{}/sms-sender".format(service_id), data=data)
@cache.delete('service-{service_id}')
@cache.delete_by_pattern('service-{service_id}-template-*')
def update_sms_sender(self, service_id, sms_sender_id, sms_sender, is_default=False):
@cache.delete("service-{service_id}")
@cache.delete_by_pattern("service-{service_id}-template-*")
def update_sms_sender(
self, service_id, sms_sender_id, sms_sender, is_default=False
):
return self.post(
"/service/{}/sms-sender/{}".format(service_id, sms_sender_id),
data={
"sms_sender": sms_sender,
"is_default": is_default
}
data={"sms_sender": sms_sender, "is_default": is_default},
)
@cache.delete('service-{service_id}')
@cache.delete_by_pattern('service-{service_id}-template-*')
@cache.delete("service-{service_id}")
@cache.delete_by_pattern("service-{service_id}-template-*")
def delete_sms_sender(self, service_id, sms_sender_id):
return self.post(
"/service/{}/sms-sender/{}/archive".format(service_id, sms_sender_id),
data=None
data=None,
)
def get_service_callback_api(self, service_id, callback_api_id):
return self.get(
"/service/{}/delivery-receipt-api/{}".format(
service_id, callback_api_id
)
)['data']
"/service/{}/delivery-receipt-api/{}".format(service_id, callback_api_id)
)["data"]
@cache.delete('service-{service_id}')
def update_service_callback_api(self, service_id, url, bearer_token, user_id, callback_api_id):
data = {
"url": url,
"updated_by_id": user_id
}
@cache.delete("service-{service_id}")
def update_service_callback_api(
self, service_id, url, bearer_token, user_id, callback_api_id
):
data = {"url": url, "updated_by_id": user_id}
if bearer_token:
data['bearer_token'] = bearer_token
return self.post("/service/{}/delivery-receipt-api/{}".format(service_id, callback_api_id), data)
data["bearer_token"] = bearer_token
return self.post(
"/service/{}/delivery-receipt-api/{}".format(service_id, callback_api_id),
data,
)
@cache.delete('service-{service_id}')
@cache.delete("service-{service_id}")
def delete_service_callback_api(self, service_id, callback_api_id):
return self.delete("/service/{}/delivery-receipt-api/{}".format(
service_id, callback_api_id
))
return self.delete(
"/service/{}/delivery-receipt-api/{}".format(service_id, callback_api_id)
)
@cache.delete('service-{service_id}')
@cache.delete("service-{service_id}")
def create_service_callback_api(self, service_id, url, bearer_token, user_id):
data = {
"url": url,
"bearer_token": bearer_token,
"updated_by_id": user_id
}
data = {"url": url, "bearer_token": bearer_token, "updated_by_id": user_id}
return self.post("/service/{}/delivery-receipt-api".format(service_id), data)
@cache.delete('service-{service_id}-data-retention')
def create_service_data_retention(self, service_id, notification_type, days_of_retention):
@cache.delete("service-{service_id}-data-retention")
def create_service_data_retention(
self, service_id, notification_type, days_of_retention
):
data = {
"notification_type": notification_type,
"days_of_retention": days_of_retention
"days_of_retention": days_of_retention,
}
return self.post("/service/{}/data-retention".format(service_id), data)
@cache.delete('service-{service_id}-data-retention')
def update_service_data_retention(self, service_id, data_retention_id, days_of_retention):
data = {
"days_of_retention": days_of_retention
}
return self.post("/service/{}/data-retention/{}".format(service_id, data_retention_id), data)
@cache.delete("service-{service_id}-data-retention")
def update_service_data_retention(
self, service_id, data_retention_id, days_of_retention
):
data = {"days_of_retention": days_of_retention}
return self.post(
"/service/{}/data-retention/{}".format(service_id, data_retention_id), data
)
@cache.set('service-{service_id}-data-retention')
@cache.set("service-{service_id}-data-retention")
def get_service_data_retention(self, service_id):
return self.get("/service/{}/data-retention".format(service_id))

View File

@@ -2,17 +2,16 @@ from app.notify_client import NotifyAdminAPIClient, cache
class StatusApiClient(NotifyAdminAPIClient):
def get_status(self, *params):
return self.get(url='/_status', *params)
return self.get(url="/_status", *params)
@cache.set('live-service-and-organization-counts', ttl_in_seconds=3600)
@cache.set("live-service-and-organization-counts", ttl_in_seconds=3600)
def get_count_of_live_services_and_organizations(self):
return self.get(url='/_status/live-service-and-organization-counts')
return self.get(url="/_status/live-service-and-organization-counts")
@cache.set('live-service-and-organization-counts', ttl_in_seconds=3600)
@cache.set("live-service-and-organization-counts", ttl_in_seconds=3600)
def get_count_of_live_services_and_organizations_cached(self):
return self.get(url='/_status/live-service-and-organization-counts')
return self.get(url="/_status/live-service-and-organization-counts")
status_api_client = StatusApiClient()

View File

@@ -3,67 +3,76 @@ from app.notify_client import NotifyAdminAPIClient, cache
class TemplateFolderAPIClient(NotifyAdminAPIClient):
@cache.delete("service-{service_id}-template-folders")
def create_template_folder(self, service_id, name, parent_id=None):
data = {"name": name, "parent_id": parent_id}
return self.post("/service/{}/template-folder".format(service_id), data)[
"data"
]["id"]
@cache.delete('service-{service_id}-template-folders')
def create_template_folder(
self,
service_id,
name,
parent_id=None
):
data = {
'name': name,
'parent_id': parent_id
}
return self.post('/service/{}/template-folder'.format(service_id), data)['data']['id']
@cache.set('service-{service_id}-template-folders')
@cache.set("service-{service_id}-template-folders")
def get_template_folders(self, service_id):
return self.get('/service/{}/template-folder'.format(service_id))['template_folders']
return self.get("/service/{}/template-folder".format(service_id))[
"template_folders"
]
def get_template_folder(self, service_id, folder_id):
if folder_id is None:
return {
'id': None,
'name': 'Templates',
'parent_id': None,
"id": None,
"name": "Templates",
"parent_id": None,
}
else:
return next(
folder for folder in self.get_template_folders(service_id)
if folder['id'] == str(folder_id)
folder
for folder in self.get_template_folders(service_id)
if folder["id"] == str(folder_id)
)
@cache.delete('service-{service_id}-template-folders')
@cache.delete('service-{service_id}-templates')
@cache.delete("service-{service_id}-template-folders")
@cache.delete("service-{service_id}-templates")
def move_to_folder(self, service_id, folder_id, template_ids, folder_ids):
if folder_id:
url = '/service/{}/template-folder/{}/contents'.format(service_id, folder_id)
url = "/service/{}/template-folder/{}/contents".format(
service_id, folder_id
)
else:
url = '/service/{}/template-folder/contents'.format(service_id)
url = "/service/{}/template-folder/contents".format(service_id)
self.post(url, {
'templates': list(template_ids),
'folders': list(folder_ids),
})
self.post(
url,
{
"templates": list(template_ids),
"folders": list(folder_ids),
},
)
if template_ids:
redis_client.delete(*(f'service-{service_id}-template-{id}-version-None' for id in template_ids))
redis_client.delete(
*(
f"service-{service_id}-template-{id}-version-None"
for id in template_ids
)
)
@cache.delete('service-{service_id}-template-folders')
def update_template_folder(self, service_id, template_folder_id, name, users_with_permission=None):
@cache.delete("service-{service_id}-template-folders")
def update_template_folder(
self, service_id, template_folder_id, name, users_with_permission=None
):
data = {"name": name}
if users_with_permission:
data["users_with_permission"] = users_with_permission
self.post(
'/service/{}/template-folder/{}'.format(service_id, template_folder_id),
data
"/service/{}/template-folder/{}".format(service_id, template_folder_id),
data,
)
@cache.delete('service-{service_id}-template-folders')
@cache.delete("service-{service_id}-template-folders")
def delete_template_folder(self, service_id, template_folder_id):
self.delete('/service/{}/template-folder/{}'.format(service_id, template_folder_id), {})
self.delete(
"/service/{}/template-folder/{}".format(service_id, template_folder_id), {}
)
template_folder_api_client = TemplateFolderAPIClient()

View File

@@ -2,27 +2,28 @@ from app.notify_client import NotifyAdminAPIClient
class TemplateStatisticsApiClient(NotifyAdminAPIClient):
def get_template_statistics_for_service(self, service_id, limit_days=None):
params = {}
if limit_days is not None:
params['limit_days'] = limit_days
params["limit_days"] = limit_days
return self.get(
url='/service/{}/template-statistics'.format(service_id),
params=params
)['data']
url="/service/{}/template-statistics".format(service_id), params=params
)["data"]
def get_monthly_template_usage_for_service(self, service_id, year):
return self.get(
url='/service/{}/notifications/templates_usage/monthly?year={}'.format(service_id, year)
)['stats']
url="/service/{}/notifications/templates_usage/monthly?year={}".format(
service_id, year
)
)["stats"]
def get_last_used_date_for_template(self, service_id, template_id):
return self.get(
url='/service/{}/template-statistics/last-used/{}'.format(service_id, template_id)
)['last_date_used']
url="/service/{}/template-statistics/last-used/{}".format(
service_id, template_id
)
)["last_date_used"]
template_statistics_client = TemplateStatisticsApiClient()

View File

@@ -5,21 +5,20 @@ from app.notify_client import NotifyAdminAPIClient, cache
from app.utils.user_permissions import translate_permissions_from_ui_to_db
ALLOWED_ATTRIBUTES = {
'name',
'email_address',
'mobile_number',
'auth_type',
'updated_by',
'current_session_id',
'email_access_validated_at',
"name",
"email_address",
"mobile_number",
"auth_type",
"updated_by",
"current_session_id",
"email_access_validated_at",
}
class UserApiClient(NotifyAdminAPIClient):
def init_app(self, app):
super().init_app(app)
self.admin_url = app.config['ADMIN_BASE_URL']
self.admin_url = app.config["ADMIN_BASE_URL"]
def register_user(self, name, email_address, mobile_number, password, auth_type):
data = {
@@ -27,21 +26,21 @@ class UserApiClient(NotifyAdminAPIClient):
"email_address": email_address,
"mobile_number": mobile_number,
"password": password,
"auth_type": auth_type
"auth_type": auth_type,
}
user_data = self.post("/user", data)
return user_data['data']
return user_data["data"]
def get_user(self, user_id):
return self._get_user(user_id)['data']
return self._get_user(user_id)["data"]
@cache.set('user-{user_id}')
@cache.set("user-{user_id}")
def _get_user(self, user_id):
return self.get("/user/{}".format(user_id))
def get_user_by_email(self, email_address):
user_data = self.post('/user/email', data={'email': email_address})
return user_data['data']
user_data = self.post("/user/email", data={"email": email_address})
return user_data["data"]
def get_user_by_email_or_none(self, email_address):
try:
@@ -51,37 +50,39 @@ class UserApiClient(NotifyAdminAPIClient):
return None
raise e
@cache.delete('user-{user_id}')
@cache.delete("user-{user_id}")
def update_user_attribute(self, user_id, **kwargs):
data = dict(kwargs)
disallowed_attributes = set(data.keys()) - ALLOWED_ATTRIBUTES
if disallowed_attributes:
raise TypeError('Not allowed to update user attributes: {}'.format(
", ".join(disallowed_attributes)
))
raise TypeError(
"Not allowed to update user attributes: {}".format(
", ".join(disallowed_attributes)
)
)
url = "/user/{}".format(user_id)
user_data = self.post(url, data=data)
return user_data['data']
return user_data["data"]
@cache.delete('user-{user_id}')
@cache.delete("user-{user_id}")
def archive_user(self, user_id):
return self.post('/user/{}/archive'.format(user_id), data=None)
return self.post("/user/{}/archive".format(user_id), data=None)
@cache.delete('user-{user_id}')
@cache.delete("user-{user_id}")
def reset_failed_login_count(self, user_id):
url = "/user/{}/reset-failed-login-count".format(user_id)
user_data = self.post(url, data={})
return user_data['data']
return user_data["data"]
@cache.delete('user-{user_id}')
@cache.delete("user-{user_id}")
def update_password(self, user_id, password):
data = {"_password": password}
url = "/user/{}/update-password".format(user_id)
user_data = self.post(url, data=data)
return user_data['data']
return user_data["data"]
@cache.delete('user-{user_id}')
@cache.delete("user-{user_id}")
def verify_password(self, user_id, password):
try:
current_app.logger.warn(f"Checking password for {user_id}")
@@ -96,36 +97,36 @@ class UserApiClient(NotifyAdminAPIClient):
raise
def send_verify_code(self, user_id, code_type, to, next_string=None):
data = {'to': to}
data = {"to": to}
if next_string:
data['next'] = next_string
if code_type == 'email':
data['email_auth_link_host'] = self.admin_url
endpoint = '/user/{0}/{1}-code'.format(user_id, code_type)
data["next"] = next_string
if code_type == "email":
data["email_auth_link_host"] = self.admin_url
endpoint = "/user/{0}/{1}-code".format(user_id, code_type)
current_app.logger.warn(f"Sending verify_code {code_type} to {user_id}")
self.post(endpoint, data=data)
def send_verify_email(self, user_id, to):
data = {
'to': to,
'admin_base_url': self.admin_url,
"to": to,
"admin_base_url": self.admin_url,
}
endpoint = '/user/{0}/email-verification'.format(user_id)
endpoint = "/user/{0}/email-verification".format(user_id)
self.post(endpoint, data=data)
def send_already_registered_email(self, user_id, to):
data = {'email': to}
endpoint = '/user/{0}/email-already-registered'.format(user_id)
data = {"email": to}
endpoint = "/user/{0}/email-already-registered".format(user_id)
self.post(endpoint, data=data)
@cache.delete('user-{user_id}')
@cache.delete("user-{user_id}")
def check_verify_code(self, user_id, code, code_type):
data = {'code_type': code_type, 'code': code}
endpoint = '/user/{}/verify/code'.format(user_id)
data = {"code_type": code_type, "code": code}
endpoint = "/user/{}/verify/code".format(user_id)
try:
current_app.logger.warn(f"Checking verify code for {user_id}")
self.post(endpoint, data=data)
return True, ''
return True, ""
except HTTPError as e:
if e.status_code == 400 or e.status_code == 404:
current_app.logger.error(f"Verify code for {user_id} was invalid")
@@ -133,76 +134,84 @@ class UserApiClient(NotifyAdminAPIClient):
raise
def get_users_for_service(self, service_id):
endpoint = '/service/{}/users'.format(service_id)
return self.get(endpoint)['data']
endpoint = "/service/{}/users".format(service_id)
return self.get(endpoint)["data"]
def get_users_for_organization(self, org_id):
endpoint = '/organizations/{}/users'.format(org_id)
return self.get(endpoint)['data']
endpoint = "/organizations/{}/users".format(org_id)
return self.get(endpoint)["data"]
def get_all_users(self):
endpoint = '/user'
return self.get(endpoint)['data']
endpoint = "/user"
return self.get(endpoint)["data"]
@cache.delete('service-{service_id}')
@cache.delete('service-{service_id}-template-folders')
@cache.delete('user-{user_id}')
@cache.delete("service-{service_id}")
@cache.delete("service-{service_id}-template-folders")
@cache.delete("user-{user_id}")
def add_user_to_service(self, service_id, user_id, permissions, folder_permissions):
# permissions passed in are the combined UI permissions, not DB permissions
endpoint = '/service/{}/users/{}'.format(service_id, user_id)
endpoint = "/service/{}/users/{}".format(service_id, user_id)
data = {
'permissions': [{'permission': x} for x in translate_permissions_from_ui_to_db(permissions)],
'folder_permissions': folder_permissions,
"permissions": [
{"permission": x}
for x in translate_permissions_from_ui_to_db(permissions)
],
"folder_permissions": folder_permissions,
}
self.post(endpoint, data=data)
@cache.delete('user-{user_id}')
@cache.delete("user-{user_id}")
def add_user_to_organization(self, org_id, user_id):
resp = self.post('/organizations/{}/users/{}'.format(org_id, user_id), data={})
return resp['data']
resp = self.post("/organizations/{}/users/{}".format(org_id, user_id), data={})
return resp["data"]
@cache.delete('service-{service_id}-template-folders')
@cache.delete('user-{user_id}')
def set_user_permissions(self, user_id, service_id, permissions, folder_permissions=None):
@cache.delete("service-{service_id}-template-folders")
@cache.delete("user-{user_id}")
def set_user_permissions(
self, user_id, service_id, permissions, folder_permissions=None
):
# permissions passed in are the combined UI permissions, not DB permissions
data = {
'permissions': [{'permission': x} for x in translate_permissions_from_ui_to_db(permissions)],
"permissions": [
{"permission": x}
for x in translate_permissions_from_ui_to_db(permissions)
],
}
if folder_permissions is not None:
data['folder_permissions'] = folder_permissions
data["folder_permissions"] = folder_permissions
endpoint = '/user/{}/service/{}/permission'.format(user_id, service_id)
endpoint = "/user/{}/service/{}/permission".format(user_id, service_id)
self.post(endpoint, data=data)
def send_reset_password_url(self, email_address, next_string=None):
endpoint = '/user/reset-password'
endpoint = "/user/reset-password"
data = {
'email': email_address,
'admin_base_url': self.admin_url,
"email": email_address,
"admin_base_url": self.admin_url,
}
if next_string:
data['next'] = next_string
data["next"] = next_string
self.post(endpoint, data=data)
def find_users_by_full_or_partial_email(self, email_address):
endpoint = '/user/find-users-by-email'
data = {'email': email_address}
endpoint = "/user/find-users-by-email"
data = {"email": email_address}
users = self.post(endpoint, data=data)
return users
@cache.delete('user-{user_id}')
@cache.delete("user-{user_id}")
def activate_user(self, user_id):
return self.post("/user/{}/activate".format(user_id), data=None)
def send_change_email_verification(self, user_id, new_email):
endpoint = '/user/{}/change-email-verification'.format(user_id)
data = {'email': new_email}
endpoint = "/user/{}/change-email-verification".format(user_id)
data = {"email": new_email}
self.post(endpoint, data)
def get_organizations_and_services_for_user(self, user_id):
endpoint = '/user/{}/organizations-and-services'.format(user_id)
endpoint = "/user/{}/organizations-and-services".format(user_id)
return self.get(endpoint)