Files
notifications-admin/app/notify_client/job_api_client.py

127 lines
4.1 KiB
Python
Raw Normal View History

from app.extensions import redis_client
from app.notify_client import NotifyAdminAPIClient, _attach_current_user, cache
2016-01-29 10:27:23 +00:00
class JobApiClient(NotifyAdminAPIClient):
JOB_STATUSES = {
'scheduled',
'pending',
'in progress',
'finished',
'cancelled',
'sending limits exceeded',
'ready to send',
'sent to dvla'
}
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}
def get_job(self, service_id, job_id):
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, contact_list_id=None, statuses=None, page=1):
params = {'page': page}
if limit_days is not None:
params['limit_days'] = limit_days
if statuses is not None:
params['statuses'] = ','.join(statuses)
if contact_list_id is not None:
params['contact_list_id'] = contact_list_id
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}
if limit_days is not None:
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 (
(
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'
)
def get_page_of_jobs(self, service_id, *, page, statuses=None, contact_list_id=None, limit_days=None):
return self.get_jobs(
service_id,
statuses=statuses or self.NON_SCHEDULED_JOB_STATUSES,
page=page,
contact_list_id=contact_list_id,
limit_days=limit_days,
)
def get_immediate_jobs(self, service_id):
return self.get_jobs(
service_id,
limit_days=7,
statuses=self.NON_SCHEDULED_JOB_STATUSES,
)['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'],
reverse=True,
)
def get_scheduled_job_stats(self, service_id):
return self.get(
url=f'/service/{service_id}/job/scheduled-job-stats'
)
2022-07-19 18:31:01 -07:00
# @cache.set('has_jobs-{service_id}')
def has_jobs(self, service_id):
return bool(self.get_jobs(service_id)['data'])
def create_job(self, job_id, service_id, scheduled_for=None, contact_list_id=None):
data = {"id": job_id}
if scheduled_for:
data.update({'scheduled_for': scheduled_for})
if contact_list_id:
data.update({'contact_list_id': contact_list_id})
data = _attach_current_user(data)
job = self.post(url='/service/{}/job'.format(service_id), data=data)
redis_client.set(
'has_jobs-{}'.format(service_id),
b'true',
Quick fix to redis DEFAULT_TTL type bug In https://github.com/alphagov/notifications-admin/pull/4077/commits/a9617d4df6021c3080bf888c9f0e5cca4b72044d we upgraded the version of utils to 49.1 which brought in a renamed `TTL` as `DEFAULT_TTL`. However, not only did it change the name, it also changed its type from an `int` to a `float`: https://github.com/alphagov/notifications-utils/pull/923/files We thought that would be OK as in the utils, we moved the conversion to an integer to happen in the `set` method but it turns out that caused an issue in the admin app where setting the `has_jobs...` redis keys will error: ``` Redis error performing set on has_jobs-4bd11cb2-cc17-44e1-b241-8547990db245 ... ... redis.exceptions.ResponseError: value is not an integer or out of range ``` It looks like this is because we are passing a float instead of an int to `ex` See a similar post describing the importance of ints rather than floats for other parameters: https://developpaper.com/question/redis-err-value-is-not-an-integer-or-out-of-range/ An interesting note is our test `test_client_creates_job_data_correctly` didn't catch this because `float(604800) == int(604800`. I've gone for the quickest solution which is to wrap `DEFAULT_TTL` in an int. The reason I've done this now is that to do the long term and more durable fix is to add this fix to utils, however there are several breaking changes infront of it that would take me a while to bring in to the admin app first. I've checked the admin and API apps and this is the only place we are directly using `DEFAULT_TTL`.
2021-12-09 14:16:36 +00:00
ex=int(cache.DEFAULT_TTL),
)
return job
2022-07-19 18:31:01 -07:00
# @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={}
)
2022-07-19 18:31:01 -07:00
# @cache.delete('has_jobs-{service_id}')
def cancel_letter_job(self, service_id, job_id):
return self.post(
url='/service/{}/job/{}/cancel-letter-job'.format(service_id, job_id),
data={}
)
job_api_client = JobApiClient()