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

This commit is contained in:
Kenneth Kehl
2023-08-23 10:35:43 -07:00
parent a7898118d7
commit 026dc14021
586 changed files with 33990 additions and 23461 deletions

View File

@@ -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.")

View File

@@ -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:

View File

@@ -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"]