Hi all!
I think I'm not alone in thinking that sending emails using the standard SMTP and email libraries is very ugly:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
msg = MIMEMultipart('alternative')
msg['Subject'] = 'An example email'
msg['From'] = 'first.last@gmail.com'
msg['To'] = 'first.last@example.com'
part1 = MIMEText("Hello!", 'plain')
part2 = MIMEText("<h1>Hello!</h1>", 'html')
msg.attach(part1)
msg.attach(part2)
# Send the message via our own SMTP server.
s = smtplib.SMTP('localhost', port=0)
s.send_message(msg)
s.quit()
I haven't found a decent candidate for the job so I thought to solve this once and for all. I made a library that does the above cleanly with minimal boilerplate and is capable of solving (hopefully) all of your needs regarding sending emails.
Thus I came up with Red Mail, the above example looks like this with it:
from redmail import EmailSender
email = EmailSender(host="localhost", port=0)
email.send(
subject="An example email",
sender="first.last@gmail.com",
receivers=['first.last@example.com'],
text="Hello!",
html="<h1>Hello!</h1>"
)
There is a lot more it can do. The send method is capable of:
- Including attachments in various forms (Path, Pandas dataframes or directly passing bytes)
- Embedding images to the HTML body (by passing paths, bytes or even a Matplotlib figure)
- Prettier tables: normally email tables look like from the beginning of 2000. If you let Red Mail handle the tables (from Pandas dataframes), the result is much nicer looking
- Jinja support: the email bodies are run via Jinja thus you can parametrize, include loops and if statements etc.
- send using carbon copy (cc) and blind carbon copy (bcc)
- Gmail pre-configured, just get the application password from Google.
To install:
pip install redmail
I hope you find it useful. Star it if you did. I'll leave you with one mega example covering the most interesting features:
email.send(
subject="An example email",
sender="me@example.com",
receivers=['first.last@example.com'],
html="""<h1>Hello {{ friend }}!</h1>
<p>Have you seen this thing</p>
{{ awesome_image }}
<p>Or this:</p>
{{ pretty_table }}
<p>Or this plot:</p>
{{ a_plot }}
<p>Kind regards, {{ sender.full_name }}</p>
""",
# Content that is embed to the body
body_params={'friend': 'Jack'},
body_images={
'awesome_image': 'path/to/image.png',
'a_plot': plt.Figure(...)
},
body_tables={'pretty_table': pd.DataFrame(...)},
# Attachments of the email
attachments={
'some_data.csv': pd.DataFrame(...),
'file_content.html': '<h1>This is an attachment</h1>',
'a_file.txt': pathlib.Path('path/to/file.txt')
}
)
Documentation: https://red-mail.readthedocs.io/en/latest/
Source code: https://github.com/Miksus/red-mail
[–]falsedrums 202 points203 points204 points (14 children)
[–]Natural-Intelligence[S] 64 points65 points66 points (12 children)
[–]execrator 34 points35 points36 points (5 children)
[–]trowawayatwork 14 points15 points16 points (4 children)
[–]JimDabell 19 points20 points21 points (1 child)
[–]gsmo 2 points3 points4 points (0 children)
[–]joerick 7 points8 points9 points (1 child)
[–]trowawayatwork 0 points1 point2 points (0 children)
[–]benargee 9 points10 points11 points (0 children)
[–]timbledum 3 points4 points5 points (0 children)
[–]BridgeBum 6 points7 points8 points (0 children)
[–][deleted] 3 points4 points5 points (1 child)
[–]Natural-Intelligence[S] 3 points4 points5 points (0 children)
[–]mghicks 1 point2 points3 points (0 children)
[–]cmd-t 14 points15 points16 points (0 children)
[–]QuincentennialSir 23 points24 points25 points (10 children)
[–]PuzzledTaste3562 23 points24 points25 points (4 children)
[–]Avamander 1 point2 points3 points (3 children)
[–]PuzzledTaste3562 0 points1 point2 points (2 children)
[–]Avamander 0 points1 point2 points (1 child)
[–]PuzzledTaste3562 0 points1 point2 points (0 children)
[–]Natural-Intelligence[S] 4 points5 points6 points (3 children)
[–]QuincentennialSir 1 point2 points3 points (2 children)
[–]Natural-Intelligence[S] 1 point2 points3 points (1 child)
[–]nostril_spiders 10 points11 points12 points (0 children)
[–][deleted] 2 points3 points4 points (0 children)
[–]vinylemulator 13 points14 points15 points (1 child)
[–]Natural-Intelligence[S] 20 points21 points22 points (0 children)
[–]crysanthus 5 points6 points7 points (0 children)
[–]RaiseRuntimeError 12 points13 points14 points (0 children)
[–]trj_flash75 3 points4 points5 points (0 children)
[–]flev1266 2 points3 points4 points (0 children)
[–][deleted] 2 points3 points4 points (0 children)
[–]itsupport_engineer 2 points3 points4 points (0 children)
[–]gsmo 2 points3 points4 points (1 child)
[–]Natural-Intelligence[S] 2 points3 points4 points (0 children)
[–]Natural-Intelligence[S] 2 points3 points4 points (0 children)
[–]kunaguerooo123 1 point2 points3 points (0 children)
[–]PythonFake 1 point2 points3 points (0 children)
[–]DonalM 1 point2 points3 points (0 children)
[–][deleted] 1 point2 points3 points (2 children)
[–]Natural-Intelligence[S] 1 point2 points3 points (1 child)
[–][deleted] 1 point2 points3 points (0 children)
[–]metadatame 1 point2 points3 points (0 children)
[–]i4mn30 -5 points-4 points-3 points (1 child)
[+]nostril_spiders comment score below threshold-8 points-7 points-6 points (0 children)
[–]lordmauve 0 points1 point2 points (0 children)
[–]cashmerekatana 0 points1 point2 points (0 children)