Other Components

Notifications

class Notification(to_email=[], from_email=None, cc_email=[], subject='', html_template='/public/emails/email_admins.html', txt_template=None, attachments=[], reply_to=None, convert_args=False, *args, **kwargs)[source]

Build a new notification object

A notification object is a light wrapper around the Flask-Mail Message object that also handles compiling and building HTML and text templates.

Parameters:
  • to_email – list of valid email addresses
  • from_email – from email address, defaults to the app’s configured MAIL_DEFAULT_SENDER
  • cc_email – list of valid email addresses
  • subject – subject line for the email that will be sent
  • html_template – path to a jinja html template to be compiled
  • txt_template – path to a jinja text template to be compiled
  • attachments – list of FileStorage objects
  • reply_to – valid email that will be used and reply-to
  • convert_args – Flag as to whether to convert all additional **kwargs passed to the Notification as a dictionary to the html/txt templates
  • *args – A list of additional arguments
  • **kwargs – Remaining keywords arguments to be consumed when rendering the html/text templates
build_msg_body(template, convert_args, *args, **kwargs)[source]

Build an HTML or text message body for an email

Parameters:
  • template – Path to an HTML/text template
  • convert_args – Whether to convert the passed kwargs into a single dictionary that can be iterated through by the default admin template.
  • *args – A list of additional arguments
  • **kwargs – Remaining keywords arguments to be consumed when rendering the html/text templates
Returns:

Rendered HTML/text template to be attached to the Notification

convert_models(kwarg_dict)[source]

Convert a list of keyword arguments to a dictionary

Modifies the passed-in dictionary to replace lists in the models with their __unicode__ representations for easier reading.

Parameters:kwarg_dict – A dictionary of kwargs, taken from instantiation of the Notification
Returns:Modified dictionary with list values replaced by more readable representations of their elements
flatten(l)[source]

Coerces the generator from _flatten to a list and return it

Example

>>> flatten([('a',), ('multi',), ['nested', 'thing']])
>>> # ['a', 'multi', 'nested', 'thing']
Parameters:l – A nested iterable of any depth
Returns:A flattened list
handle_recipients(recipient)[source]

Turns string/list/nested list of recipients into a list of recipient emails

Parameters:recipient – All sorts of forms of recipients (string, unicode, list, list of lists)
Returns:List of recipients with depth one
build_msg(recipient)[source]

Builds a Message object with body, attachments

Argument:
recipient: A formatted single-depth list of email addresses
Returns:Message object
send(multi=False, async=True)[source]

Send a single or group of notifications

Keyword Arguments:
 
  • multi – If True, multi will build an individual Notification for each recipient. If False, a single Notification will be created with all of the recipients visible in the to line.
  • async – If True, the sending will be kicked out to a Celery worker process. If False, the sending will occur on the main request thread

Nightly Jobs

class JobBase(time_override=False)[source]

Base model for nightly jobs

Variables:

jobs – jobs is a list of all jobs currently registered against the JobBase.

Parameters:
  • name – the name instance variable is just the class name of the job. This allows us to ensure that we only every have one copy of a job scheduled per day.
  • time_override – Boolean of whether to override the start_time parameter when scheduling jobs (used primarily in testing)
classmethod register(subcl)[source]

decorator to allow for explicit job registration

Example

Register MySubJob as a valid job on JobBase

@JobBase.register
class MySubJob(JobBase):
    def run_job(self, job):
        pass
start_time

The time when the job will be scheduled

Datetime.datetime objects are better to return because time objects must have dates attached to them to do accurate time comparison around the date changeovers.

Returns:datetime.datetime or datetime.date object, defaults to 7AM EST
job_status_model

Returns the job status model to be used for the particular job.

In production, we use the purchasing.jobs.job_base.JobStatus model, but in testing we can overwrite this.

build_datetime_object(time)[source]

Take a datetime.time object and turn it into today’s date

Parameters:time (datetime.date) – time object of when it should start
Returns:Today’s date with the time information from the passed time attached
schedule_job()[source]

Schedule a job.

If the time_override param is set to True, it will override the timing. This allows us to always run jobs from the tests or manually force a job to be scheduled if necessary. In order to schedule a job, one of the following conditions must be met:

  1. start_time is none
  2. The current time is after the start_time
  3. The time_override attribute is set to True
Returns:If all the conditions for scheduling a job are true, a new JobStatus model will be created or selected and returned.
run_job(job)[source]

Run a job. Must be implemented by subclasses

Raises:NotImplementedError
class EmailJobBase(time_override=False)[source]

Base job for email alerting/updating

should_run()[source]

If a job is scheduled, it should always run.

This method can be overwritten in the child classes, but in the base case, it should always run.

Returns:True
run_job(job)[source]

Run the email job.

To run an email job, we do the following things:

  1. Set the job status to “started”
  2. Call the build_notifications() method to get a list of notification batches to send
  3. For each batches of notifications to send, try to send them
  4. If at any point we fail, update the status to ‘failed’, and provide additional information
  5. If all notifications send successfully, update the status to ‘success’
Parameters:jobJobStatus object
Returns:Job object, modified with a new status and any appropriate messages
Return type:JobStatus
build_notifications()[source]

Method to build Notification objects to send

Raises
NotImplementedError

Admin

For more information on how to use the admin, see the Admin user’s guide. The admin is built using Flask Admin.

User Logins

Users are handled using the Flask-Security framework. More on how this works will be made available soon.