EMMAA’s Subscription Service (emmaa.subscription)

Notifications functions (emmaa.subscription.notifications)

class emmaa.subscription.notifications.EmailHtmlBody(template_path)[source]

Bases: object

Parent class for email body.

class emmaa.subscription.notifications.ModelDeltaEmailHtmlBody(template_path='email_unsub/model_email_body.html')[source]

Bases: emmaa.subscription.notifications.EmailHtmlBody

Email body for model updates.

render(msg_dicts, unsub_link)[source]

Provided pregenerated msg_dicts render HTML to put in email body.

Parameters:
  • msg_dicts (list[dict]) – A list of dictionaries containing parts of messages to be added to email. Each dictionary has the following keys: ‘url’, ‘start’, ‘delta_part’, ‘middle’, ‘message’.
  • unsub_link (str) – A link to unsubscribe page.
Returns:

An html string rendered from the associated jinja2 template

Return type:

html

class emmaa.subscription.notifications.QueryEmailHtmlBody(domain='emmaa.indra.bio', template_path='email_unsub/email_body.html')[source]

Bases: emmaa.subscription.notifications.EmailHtmlBody

Email body for query notifications.

render(static_query_deltas, open_query_deltas, dynamic_query_deltas, unsub_link)[source]

Provided the delta json objects, render HTML to put in email body.

Parameters:
  • static_query_deltas (json) – A list of lists that names which queries have updates. Expected structure: [(english_query, detailed_query_link, model, model_type)]
  • dynamic_query_deltas (list[) – A list of lists that names which queries have updates. Expected structure: [(english_query, model, model_type)]
  • unsub_link (str) – A link to unsubscribe page.
Returns:

An html string rendered from the associated jinja2 template

Return type:

html

emmaa.subscription.notifications.get_all_update_messages(deltas, is_tweet=False)[source]

Get all messages for model deltas that can be further used in tweets and email notifications.

Parameters:
  • deltas (dict) – A dictionary containing deltas for a model and its test results returned by get_model_deltas function.
  • is_tweet (bool) – Whether messages are generated for Twitter (used to determine the formatting of model types).
Returns:

msg_dicts – A list of individual message dictionaries that can be used for tweets or email notifications.

Return type:

list[dict]

emmaa.subscription.notifications.get_model_deltas(model_name, test_corpora, date, bucket='emmaa')[source]

Get deltas from model and test stats for further use in tweets and email notifications.

Parameters:
  • model_name (str) – A name of the model to get the updates for.
  • test_corpora (list[str]) – A list of test corpora names to get the test updates for.
  • date (str) – A date for which the updates should be generated.
  • bucket (str) – A name of S3 bucket where the stats files are stored.
Returns:

deltas – A dictionary containing the deltas for the given model and test corpora.

Return type:

dict

emmaa.subscription.notifications.get_user_query_delta(db, user_email, domain='emmaa.indra.bio')[source]

Produce a report for all query results per user in a given format

Parameters:
  • db (emmaa.db.EmmaaDatabaseManager) – An instance of a database manager to use.
  • user_email (str) – The email of the user for which to get the report for
  • domain (str) – The domain name for the unsubscibe link in the html report. Default: “emmaa.indra.bio”.
Returns:

A tuple with (str report, html report)

Return type:

tuple(str, html_str)

emmaa.subscription.notifications.make_html_report_per_user(static_results_delta, open_results_delta, dynamic_results_delta, email, domain='emmaa.indra.bio')[source]

Produce a report for all query results per user in an html file.

Parameters:
  • static_results_delta (list) – A list of tuples of query deltas for static queries. Each tuple has a format (english_query, link, model, mc_type)
  • open_results_delta (list) – A list of tuples of query deltas for open queries. Each tuple has a format (english_query, link, model, mc_type)
  • dynamic_results_delta (list) – A list of tuples of query deltas for dynamic queries. Each tuple has a format (english_query, link, model, mc_type)
  • email (str) – The email of the user to get the results for.
  • domain (str) – The domain name for the unsubscibe link in the report. Default: “emmaa.indra.bio”.
Returns:

A string containing an html document

Return type:

str

emmaa.subscription.notifications.make_model_html_email(msg_dicts, email, domain='emmaa.indra.bio')[source]

Render html file for model notification email.

emmaa.subscription.notifications.make_reports_from_results(new_results, domain='emmaa.indra.bio')[source]

Make a report given latest results and queries the results are for.

Parameters:new_results (list[tuple]) – Latest results as a list of tuples where each tuple has the format (model_name, query, mc_type, result_json, date, delta).
Returns:reports – A list of reports on changes for each of the queries.
Return type:list
emmaa.subscription.notifications.make_str_report_per_user(static_results_delta, open_results_delta, dynamic_results_delta)[source]

Produce a report for all query results per user as a string.

Parameters:
  • static_results_delta (list) – A list of tuples of query deltas for static queries. Each tuple has a format (english_query, link, model, mc_type)
  • open_results_delta (list) – A list of tuples of query deltas for open queries. Each tuple has a format (english_query, link, model, mc_type)
  • dynamic_results_delta (list) – A list of tuples of query deltas for dynamic queries. Each tuple has a format (english_query, link, model, mc_type) (no link in dynamic_results_delta tuples).
Returns:

msg – A message about query deltas.

Return type:

str

emmaa.subscription.notifications.model_update_notify(model_name, test_corpora, date, db, bucket='emmaa')[source]

This function finds delta for a given model and sends updates via Twitter posts and email notifications.

Parameters:
  • model_name (str) – A name of EMMAA model.
  • test_corpora (list[str]) – A list of test corpora names to get test stats.
  • date (str) – A date for which to get stats for.
  • db (emmaa.db.EmmaaDatabaseManager) – An instance of a database manager to use.
  • bucket (str) – A name of S3 bucket where corresponding stats files are stored.
emmaa.subscription.notifications.tweet_deltas(deltas, twitter_cred)[source]

Tweet the model updates.

Parameters:
  • deltas (dict) – A dictionary containing deltas for a model and its test results returned by get_model_deltas function.
  • twitter_cred (dict) – A dictionary containing consumer_token, consumer_secret, access_token, and access_secret for a model Twitter account.

Email Service (emmaa.subscription.email_service)

emmaa.subscription.email_service.close_to_quota_max(used_quota=0.95, region='us-east-1')[source]

Check if the send quota is close to be exceeded

If the total quota for the 24h cycle is Q, the currently used quota is q and ‘used_quota’ is r, return True if q/Q > r, otherwise return False.

Parameters:
  • used_quota (float) – A float between 0 and 1.0. This number specifies the fraction of send quota currently used. Default: 0.95
  • region (str) – A valid AWS region. The region to check the quota in. Default: us-east-1.
Returns:

True if the quota is close to be exceeded with respect to the provided ratio ‘used’.

Return type:

bool

emmaa.subscription.email_service.get_send_statistics(region='us-east-1')[source]

Return the sending statistics, like bounce and complaint rates

See https://boto3.amazonaws.com/v1/documentation/api/latest/ reference/services/ses.html#SES.Client.get_send_statistics for more info

Parameters:region (Optional[str]) – Specify AWS region
Returns:
Response syntax:
{
‘SendDataPoints’: [
{
‘Timestamp’: datetime(2015, 1, 1), ‘DeliveryAttempts’: 123, ‘Bounces’: 123, ‘Complaints’: 123, ‘Rejects’: 123

},

]

}

Return type:dict
emmaa.subscription.email_service.send_email(sender, recipients, subject, body_text, body_html, source_arn=None, return_email=None, return_arn=None, region='us-east-1')[source]

Wrapper function for the send_email method of the boto3 SES client

IMPORTANT: sending is limited to 14 emails per second.

See more at: https://boto3.amazonaws.com/v1/documentation/api/latest/reference + /services/ses.html#SES.Client.send_email https://docs.aws.amazon.com/ses/latest/APIReference/API_SendEmail.html and python example at https://docs.aws.amazon.com/ses/latest/DeveloperGuide/ + sending-authorization-delegate-sender-tasks-email.html

Parameters:
  • sender (str) – A valid email address to use in the Source field
  • recipients (iterable[str] or str) – A valid email address or a list of valid email addresses. This will fill out the Recipients field.
  • subject (str) – The email subject
  • body_text (str) – The text body of the email
  • body_html (str) – The html body of the email. Must be a valid html body (starting with <html>, ending with </html>).
  • source_arn (str) – The source ARN of the sender. Should be of the format “arn:aws:ses:us-east-1:123456789012:identity/user@example.com” or “arn:aws:ses:us-east-1:123456789012:identity/example.com”. Used only for sending authorization. It is the ARN of the identity that is associated with the sending authorization policy that permits the sender to send using the email address specified as the sender. Example: the owner of the domain “example.com” can send an email from any address using @example.com, as long as the associated source_arn is “arn:aws:ses:us-east-1:123456789012:identity/example.com”
  • return_email (str) – The email to which complaints and bounces are sent. Can be the same as the sender.
  • return_arn (str) – The return path ARN for the sender. This is the ARN associated with the return email. Can be the same as the source_arn if return email is the same as the sender.
  • region (str) – AWS region to use for the SES client. Default: us-east-1
Returns:

The API response object in the form of a dict is returned. The structure is:

>>> response = {                'MessageId': 'EXAMPLE78603177f-7a5433e7-8edb-42ae-af10' +                             '-f0181f34d6ee-000000',                'ResponseMetadata': {                    '...': '...',                },            }

Return type:

dict

Email Utilities (emmaa.subscription.email_util)

emmaa.subscription.email_util.generate_signature(email, expire_str, digestmod=<built-in function openssl_sha256>)[source]

Return an HMAC signature based on email and expire_str

From documentation of HMAC in python: key is a bytes or bytearray object giving the secret key. If msg is present, the method call update(msg) is made. digestmod is the digest name, digest constructor or module for the HMAC object to use. It supports any name suitable to hashlib.new().

Parameters:
  • email (str) – A valid email address. Should not be URL encoded.
  • expire_str (str) – A timestamp string in seconds
  • digestmod (str|digest constructor|module) – digest name, digest constructor or module for the HMAC object to use. Default: hashlib.sha256
Returns:

A hexadecimal string representing the signature

Return type:

str

Generate an unsubscribe link for the provided email address

Given an email address, generate an unsubscribe link using that email address. Optionally provide the number of days into the future the link should be valid until and the domain name. The domain name is expeceted to be of the format “some.domain.com”. The appropriate path and prefixes will be added together with the query string. Example:

>>> generate_unsubscribe_link('user@email.com', domain='some.domain.com')
>>> 'https://some.domain.com/query/unsubscribe?email=user%40email.com' +
    '&expiration=1234567890&signature=1234567890abcdef'
Parameters:
  • email (str) – An email address.
  • days (int) – The number of days into the future the link should be valid until. Default: 7.
  • domain (str) – A domain name to prefix the query string with. Expected format is: “some.domain.com”. Default: ‘emmaa.indra.bio’
Returns:

An unsubscribe link for the provided email and (optionally) domain

Return type:

str

emmaa.subscription.email_util.generate_unsubscribe_qs(email, days=7)[source]

Generate an unsubscribe query string for a url

Parameters:
  • email (str) – A valid email address
  • days (int) – The number of days the query string should be valid. Default: 7.
Returns:

A query string of the format ‘email=<urlenc email>&expiration=<timestamp>&signature=<sha256 hex>’

Return type:

str

emmaa.subscription.email_util.get_email_subscriptions(email)[source]

Verifies which email subsciptions exist for the provided email

Parameters:email (str) – The email to the check subscriptions for
Returns:
Return type:list(tuple(str, str, query_hash))
emmaa.subscription.email_util.register_email_unsubscribe(email, queries, models)[source]

Executes an email unsubscribe request

emmaa.subscription.email_util.verify_email_signature(signature, email, expiration, digestmod=<built-in function openssl_sha256>)[source]

Verify HMAC signature