# Mail utility class for use with Flask

from application import app, mail

__all__ = ['send_email', 'send_bulk_email', 'create_email']

def send_async_email(app, msg):
with app.app_context():
mail.send(msg)

def send_bulk_async_email(app, emails):
with app.app_context():
with mail.connect() as conn:
for email in emails:
conn.send(email)

def create_email(subject, recipients, text_body, html_body, sender=('My Company', 'info@mycompany.com.au')):
email = Message(subject, sender=sender, recipients=recipients)
email.body = text_body
email.html = html_body

return email

def send_email(email):
thr.start()

def send_bulk_email(emails):
thr.start()


The first two functions are used internally as the threaded function calls. The create_email function is used to generate Message objects, which are then passed back to the send_email or send_bulk_email function dependent on whether there is a singular or multiple emails, respectively.

I currently think merging the singular and multiple send functions would be overkill, and remove some of the readability, however I am also open to feedback on that opinion.

• What "mail utility class"? All I see is a bunch of related functions. – 200_success Jul 21 '16 at 7:11
• In my application, i have a utils folder separate from my models and views. You're right though, this is not a class. I'm not sure what the appropriate name is for a group of function desgined to provide related functionality is. A package? – Tex Andersen Jul 21 '16 at 7:13

I'd unify both functions and only have the bulk/multiple-emails version because the single case is basically a specialisation of the general case and the slight bit more work is unlikely to be noticeable (unless I missed some other technical reason why this isn't feasible).

Btw. the with can be nested on a single line, i.e.:

def send_bulk_async_email(app, emails):
with app.app_context(), mail.connect() as conn:
for email in emails:
conn.send(email)


The default value for the sender on create_email sounds like it doesn't belong there and should rather be passed in like the rest, perhaps store it in a configuration file anyway.

For spawning the threads also consider making it a bit more flexible by allowing an optional parameter for the thread creation, e.g. to use a thread pool instead of spawning an unlimited number of threads like done here.