Odyssey
Classes | Functions | Variables
sendSESEmail Namespace Reference

Classes

class  CustomArgumentParser
 

Functions

def getParser ()
 
def main (argv)
 
def run ()
 

Variables

tuple format
 
 LOGGER = logging.getLogger(__name__)
 
 logging_handler = logging.StreamHandler()
 
tuple USAGE_HELP
 
 AWS_REGION = os.getenv('AWS_REGION', 'us-west-2')
 

Detailed Description

Send emails through AWS SES.

Uses the AWS SES call send-mail.
Has the following parameters:

Body contents: (at least one of the following has to be specified.)
- text -- the plain text version of the email.
- html -- the HTML-formatted version of the email.

- subject -- the subject of the email.  This is required.
- efrom -- the from email.  This is required.
The efrom requires verification by AWS SES (either by email address or by domain.)
- replyto -- the reply to email.  (submitform.pl & submitsecure.pl)

Email destinations: (at least one of the following has to be specified.)
Destinations are space-separated like a@comp.dom b@comp.dom ...
- to -- a list of to recipients.  (Who the email is actually addressed to.)
- bcc -- a list of bcc recipients. (List isn't visible in email.)
- cc -- the cc for the email.  (Visible list in email.)

Amazon requires the from email to be verified or the domain verified.

Function Documentation

◆ getParser()

def sendSESEmail.getParser ( )
Prepare argument parser.

Returns:
    parser -- ArgumentParser object

Definition at line 76 of file sendSESEmail.py.

76 def getParser():
77  """Prepare argument parser.
78 
79  Returns:
80  parser -- ArgumentParser object
81  """
82  parser = CustomArgumentParser (
83  description = "Send emails through AWS SES.",
84  formatter_class = argparse.RawDescriptionHelpFormatter,
85  epilog = textwrap.dedent('''\
86  additional information:
87  One of --to, --bcc, or --cc has to be defined.
88  One of --plaintext or --htmltext has to be defined.
89  --efrom and --subject are required.
90  '''))
91 
92  parser.add_argument ("--to", nargs = "+",
93  help = "Space-separated list of to email addresses",
94  required = False)
95 
96  parser.add_argument ("--bcc", nargs = "+",
97  help = "Space-separated list of bcc email addresses",
98  required = False)
99 
100  parser.add_argument ("--cc", nargs = "+",
101  help = "Space-separated list of cc email addresses",
102  required = False)
103 
104  parser.add_argument ("--efrom",
105  help = "From email address",
106  required = True)
107 
108  parser.add_argument ("--replyto", nargs = "+",
109  help = "Reply to email address",
110  required = False)
111 
112  parser.add_argument ("--subject",
113  help = "Subject of the email",
114  required = True)
115 
116  parser.add_argument ("--plaintext",
117  help = "Email body in plaintext",
118  required = False)
119 
120  parser.add_argument ("--htmltext",
121  help = "Html body in HTML",
122  required = False)
123 
124  parser.add_argument("--quiet", action = "store_true",
125  help = "Suppress success message",
126  required = False)
127 
128  parser.add_argument("--context",
129  help = ("Json string for logging application"
130  "context for the email messages being sent."),
131  required = False)
132 
133 
134  return parser
135 
136 

◆ main()

def sendSESEmail.main (   argv)
Main method to execute operations on email verification.

Arguments:
    argv {list} -- list of script arguments

Raises:
    SystemExit
    BaseException

Definition at line 137 of file sendSESEmail.py.

137 def main(argv):
138  """Main method to execute operations on email verification.
139 
140  Arguments:
141  argv {list} -- list of script arguments
142 
143  Raises:
144  SystemExit
145  BaseException
146  """
147  return_code = 0
148  response = {}
149  mainReturn = {
150  'status': '000',
151  'error': [],
152  'response': response,
153  'context': {}
154  }
155 
156  # Get argument parser
157  parser = getParser()
158 
159  try:
160  args = parser.parse_args(argv)
161  mainReturn["context"] = args.context
162 
163  # Validation
164  if (args.to == None and args.bcc == None and args.cc == None):
165  raise BaseException ("Destination has to be specified. One of"
166  " the --to, --bcc or --cc options need"
167  " to be provided.")
168 
169  if (args.plaintext == None and args.htmltext == None):
170  raise BaseException ("Email body has to be specified")
171 
172  except (BaseException) as e:
173  return_code = 102
174  evalue = str(e)
175  if (evalue != "0"): # If it is empty, it is a help message
176  mainReturn["status"] = return_code
177  mainReturn["error"].append(USAGE_HELP)
178  mainReturn["error"].append(evalue)
179  LOGGER.error(json.dumps(mainReturn))
180 
181  except (Exception) as e:
182  return_code = 103
183  mainReturn["status"] = return_code
184  mainReturn["error"] = e
185  LOGGER.error(json.dumps(mainReturn))
186 
187  # exit if validation error
188  if return_code > 0:
189  return return_code
190 
191  try:
192  # Create boto3 client object
193  client = boto3.client('ses', region_name=AWS_REGION)
194 
195  # Construct destination
196  destination = {}
197  if (args.to != None):
198  destination["ToAddresses"] = args.to
199  if (args.bcc != None):
200  destination["BccAddresses"] = args.bcc
201  if (args.cc != None):
202  destination["CcAddresses"] = args.cc
203 
204  # Construct message
205  charset = "UTF-8"
206  message = {}
207  message["Subject"] = {}
208  message["Subject"]["Data"] = args.subject
209  message["Subject"]["Charset"] = charset
210  if (args.plaintext != None):
211  message["Body"] = {}
212  message["Body"]["Text"] = {}
213  message["Body"]["Text"]["Data"] = args.plaintext
214  message["Body"]["Text"]["Charset"] = charset
215 
216  if (args.htmltext != None):
217  if "Body" not in message:
218  message["Body"] = {}
219 
220  message["Body"]["Html"] = {}
221  message["Body"]["Html"]["Data"] = args.htmltext
222  message["Body"]["Html"]["Charset"] = charset
223 
224  if (args.replyto != None):
225  # Call AWS SES
226  response = client.send_email (
227  Source = args.efrom,
228  Destination = destination,
229  Message = message,
230  ReplyToAddresses = args.replyto,
231  ConfigurationSetName='ses-detail-logging',
232  )
233  else:
234  # Call AWS SES
235  response = client.send_email (
236  Source = args.efrom,
237  Destination = destination,
238  Message = message,
239  ConfigurationSetName='ses-detail-logging',
240  )
241 
242  except ClientError as e:
243  return_code = 902
244  mainReturn["status"] = return_code
245  mainReturn["error"] = str(e)
246 
247  except Exception as e:
248  return_code = 903
249  mainReturn["status"] = return_code
250  mainReturn['error'] = str(e)
251 
252  mainReturn['response'] = response
253 
254  if return_code > 0:
255  LOGGER.error(json.dumps(mainReturn))
256  else:
257  LOGGER.info(json.dumps(mainReturn))
258 
259  return return_code
260 
261 

◆ run()

def sendSESEmail.run ( )
Script entrypoint

Definition at line 262 of file sendSESEmail.py.

262 def run():
263  """Script entrypoint"""
264  sys.exit(main(sys.argv[1:]))
265 
266 

Variable Documentation

◆ format

tuple sendSESEmail.format
Initial value:
1 = ("[%(levelname)-5s] %(asctime)-15s ({}|%(funcName)s|%(lineno)d) "
2  ":: %(message)s").format(__file__)

Definition at line 35 of file sendSESEmail.py.

◆ USAGE_HELP

tuple sendSESEmail.USAGE_HELP
Initial value:
1 = ("Usage: sendSESEmail.py [-h] [--to TO [TO ...]]"
2  "[--bcc BCC [BCC ...]] [--cc CC [CC ...]] --efrom EFROM"
3  "[--replyto REPLYTO [REPLYTO ...]] --subject SUBJECT"
4  "[--plaintext PLAINTEXT] [--htmltext HTMLTEXT]"
5  "[--quiet] [--context CONTEXT]")

Definition at line 44 of file sendSESEmail.py.