mirror of
https://github.com/GSA/notifications-api.git
synced 2026-02-02 17:31:14 -05:00
notify-api-412 use black to enforce python style standards
This commit is contained in:
@@ -2,32 +2,34 @@ from app.clients import Client, ClientException
|
||||
|
||||
|
||||
class EmailClientException(ClientException):
|
||||
'''
|
||||
"""
|
||||
Base Exception for EmailClients
|
||||
'''
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class EmailClientNonRetryableException(ClientException):
|
||||
'''
|
||||
"""
|
||||
Represents an error returned from the email client API with a 4xx response code
|
||||
that should not be retried and should instead be marked as technical failure.
|
||||
An example of this would be an email address that makes it through our
|
||||
validation rules but is rejected by SES. There is no point in retrying this type as
|
||||
it will always fail however many calls to SES. Whereas a throttling error would not
|
||||
use this exception as it may succeed if we retry
|
||||
'''
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class EmailClient(Client):
|
||||
'''
|
||||
"""
|
||||
Base Email client for sending emails.
|
||||
'''
|
||||
"""
|
||||
|
||||
def send_email(self, *args, **kwargs):
|
||||
raise NotImplementedError('TODO Need to implement.')
|
||||
raise NotImplementedError("TODO Need to implement.")
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
raise NotImplementedError('TODO Need to implement.')
|
||||
raise NotImplementedError("TODO Need to implement.")
|
||||
|
||||
@@ -17,30 +17,30 @@ from app.clients.email import (
|
||||
from app.cloudfoundry_config import cloud_config
|
||||
|
||||
ses_response_map = {
|
||||
'Permanent': {
|
||||
"message": 'Hard bounced',
|
||||
"Permanent": {
|
||||
"message": "Hard bounced",
|
||||
"success": False,
|
||||
"notification_status": 'permanent-failure',
|
||||
"notification_statistics_status": STATISTICS_FAILURE
|
||||
"notification_status": "permanent-failure",
|
||||
"notification_statistics_status": STATISTICS_FAILURE,
|
||||
},
|
||||
'Temporary': {
|
||||
"message": 'Soft bounced',
|
||||
"Temporary": {
|
||||
"message": "Soft bounced",
|
||||
"success": False,
|
||||
"notification_status": 'temporary-failure',
|
||||
"notification_statistics_status": STATISTICS_FAILURE
|
||||
"notification_status": "temporary-failure",
|
||||
"notification_statistics_status": STATISTICS_FAILURE,
|
||||
},
|
||||
'Delivery': {
|
||||
"message": 'Delivered',
|
||||
"Delivery": {
|
||||
"message": "Delivered",
|
||||
"success": True,
|
||||
"notification_status": 'delivered',
|
||||
"notification_statistics_status": STATISTICS_DELIVERED
|
||||
"notification_status": "delivered",
|
||||
"notification_statistics_status": STATISTICS_DELIVERED,
|
||||
},
|
||||
'Complaint': {
|
||||
"message": 'Complaint',
|
||||
"Complaint": {
|
||||
"message": "Complaint",
|
||||
"success": True,
|
||||
"notification_status": 'delivered',
|
||||
"notification_statistics_status": STATISTICS_DELIVERED
|
||||
}
|
||||
"notification_status": "delivered",
|
||||
"notification_statistics_status": STATISTICS_DELIVERED,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -57,61 +57,57 @@ class AwsSesClientThrottlingSendRateException(AwsSesClientException):
|
||||
|
||||
|
||||
class AwsSesClient(EmailClient):
|
||||
'''
|
||||
"""
|
||||
Amazon SES email client.
|
||||
'''
|
||||
"""
|
||||
|
||||
def init_app(self, *args, **kwargs):
|
||||
self._client = client(
|
||||
'ses',
|
||||
"ses",
|
||||
region_name=cloud_config.ses_region,
|
||||
aws_access_key_id=cloud_config.ses_access_key,
|
||||
aws_secret_access_key=cloud_config.ses_secret_key,
|
||||
config=AWS_CLIENT_CONFIG
|
||||
config=AWS_CLIENT_CONFIG,
|
||||
)
|
||||
super(AwsSesClient, self).__init__(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return 'ses'
|
||||
return "ses"
|
||||
|
||||
def send_email(self,
|
||||
source,
|
||||
to_addresses,
|
||||
subject,
|
||||
body,
|
||||
html_body='',
|
||||
reply_to_address=None):
|
||||
def send_email(
|
||||
self, source, to_addresses, subject, body, html_body="", reply_to_address=None
|
||||
):
|
||||
try:
|
||||
if isinstance(to_addresses, str):
|
||||
to_addresses = [to_addresses]
|
||||
|
||||
reply_to_addresses = [reply_to_address] if reply_to_address else []
|
||||
|
||||
body = {
|
||||
'Text': {'Data': body}
|
||||
}
|
||||
body = {"Text": {"Data": body}}
|
||||
|
||||
if html_body:
|
||||
body.update({
|
||||
'Html': {'Data': html_body}
|
||||
})
|
||||
body.update({"Html": {"Data": html_body}})
|
||||
|
||||
start_time = monotonic()
|
||||
response = self._client.send_email(
|
||||
Source=source,
|
||||
Destination={
|
||||
'ToAddresses': [punycode_encode_email(addr) for addr in to_addresses],
|
||||
'CcAddresses': [],
|
||||
'BccAddresses': []
|
||||
"ToAddresses": [
|
||||
punycode_encode_email(addr) for addr in to_addresses
|
||||
],
|
||||
"CcAddresses": [],
|
||||
"BccAddresses": [],
|
||||
},
|
||||
Message={
|
||||
'Subject': {
|
||||
'Data': subject,
|
||||
"Subject": {
|
||||
"Data": subject,
|
||||
},
|
||||
'Body': body
|
||||
"Body": body,
|
||||
},
|
||||
ReplyToAddresses=[punycode_encode_email(addr) for addr in reply_to_addresses]
|
||||
ReplyToAddresses=[
|
||||
punycode_encode_email(addr) for addr in reply_to_addresses
|
||||
],
|
||||
)
|
||||
except botocore.exceptions.ClientError as e:
|
||||
_do_fancy_exception_handling(e)
|
||||
@@ -120,23 +116,25 @@ class AwsSesClient(EmailClient):
|
||||
raise AwsSesClientException(str(e))
|
||||
else:
|
||||
elapsed_time = monotonic() - start_time
|
||||
current_app.logger.info("AWS SES request finished in {}".format(elapsed_time))
|
||||
return response['MessageId']
|
||||
current_app.logger.info(
|
||||
"AWS SES request finished in {}".format(elapsed_time)
|
||||
)
|
||||
return response["MessageId"]
|
||||
|
||||
|
||||
def punycode_encode_email(email_address):
|
||||
# only the hostname should ever be punycode encoded.
|
||||
local, hostname = email_address.split('@')
|
||||
return '{}@{}'.format(local, hostname.encode('idna').decode('utf-8'))
|
||||
local, hostname = email_address.split("@")
|
||||
return "{}@{}".format(local, hostname.encode("idna").decode("utf-8"))
|
||||
|
||||
|
||||
def _do_fancy_exception_handling(e):
|
||||
# http://docs.aws.amazon.com/ses/latest/DeveloperGuide/api-error-codes.html
|
||||
if e.response['Error']['Code'] == 'InvalidParameterValue':
|
||||
raise EmailClientNonRetryableException(e.response['Error']['Message'])
|
||||
if e.response["Error"]["Code"] == "InvalidParameterValue":
|
||||
raise EmailClientNonRetryableException(e.response["Error"]["Message"])
|
||||
elif (
|
||||
e.response['Error']['Code'] == 'Throttling'
|
||||
and e.response['Error']['Message'] == 'Maximum sending rate exceeded.'
|
||||
e.response["Error"]["Code"] == "Throttling"
|
||||
and e.response["Error"]["Message"] == "Maximum sending rate exceeded."
|
||||
):
|
||||
raise AwsSesClientThrottlingSendRateException(str(e))
|
||||
else:
|
||||
|
||||
@@ -17,23 +17,14 @@ class AwsSesStubClient(EmailClient):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return 'ses'
|
||||
return "ses"
|
||||
|
||||
def send_email(self,
|
||||
source,
|
||||
to_addresses,
|
||||
subject,
|
||||
body,
|
||||
html_body='',
|
||||
reply_to_address=None):
|
||||
def send_email(
|
||||
self, source, to_addresses, subject, body, html_body="", reply_to_address=None
|
||||
):
|
||||
try:
|
||||
start_time = monotonic()
|
||||
response = request(
|
||||
"POST",
|
||||
self.url,
|
||||
data={"id": "dummy-data"},
|
||||
timeout=60
|
||||
)
|
||||
response = request("POST", self.url, data={"id": "dummy-data"}, timeout=60)
|
||||
response.raise_for_status()
|
||||
response_json = json.loads(response.text)
|
||||
|
||||
@@ -41,5 +32,7 @@ class AwsSesStubClient(EmailClient):
|
||||
raise AwsSesStubClientException(str(e))
|
||||
else:
|
||||
elapsed_time = monotonic() - start_time
|
||||
current_app.logger.info("AWS SES stub request finished in {}".format(elapsed_time))
|
||||
return response_json['MessageId']
|
||||
current_app.logger.info(
|
||||
"AWS SES stub request finished in {}".format(elapsed_time)
|
||||
)
|
||||
return response_json["MessageId"]
|
||||
|
||||
Reference in New Issue
Block a user