Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Supported Python Versions Last commit pypi version Downloads Coverage

"Bote" is German for messenger or courier. The bote library sends plain-text email from localhost or a remote SMTP server. The base functionality is in the standard library, but this package improves upon that in several ways:

  • Enforce that any connection to a SMTP server - except localhost / / ::1 - is encrypted. (Of course this does not influence how the SMTP server sends the message to the recipient.)
  • Good error messages
  • Type-Hints in the code (PEP 484)
  • Extensive testing
  • Automatically wrap messages preserving intentional line-breaks.

How to use it

import os
import bote

mail_settings = {
    'server': '',
    'server_port': 587,
    'encryption': 'starttls',  # or 'ssl', or 'off'
    # Best practice: get secrets from environment variables
    # instead of hardcoded strings =>
    'username': os.environ.get('MAIL_USER'),
    'passphrase': os.environ.get('MAIL_PASSPHRASE'),
    'recipient': '',
    'sender': '',
    'wrap_width': 80}

mailer = bote.Mailer(mail_settings)

mailer.send_mail('Test bote',  # subject
                 'It worked!'  # mail body

# If the setting recipient is a dictionary and contains
# an admin key:
mailer.send_mail_to_admin('Test', 'Message for the admin')

All parameters except recipient and sender are optional as bote has defaults for all others:

Parameter Default Value
server localhost
server_port None
encryption off
username None
passphrase None
wrap_width 80

The parameter recipient can either be an email address as a string or a dictionary. In the later case, this should have a default key with the standard recipient as value. Otherwise the recipient has to be set for every message. If it contains an admin key, the shorthand command send_mail_to_admin can be used.

Keeping Your Credentials Save

You should not store secrets in code that may be shared or saved to source control.

To avoid accidental exposure of secrets it is best practice to use environment variables that can be accessed with os.environ.get(). The python-dotenv could be useful for this too - do not forget to add .env files to .gitignore.


A Python library to send email. Enforces encryption if not sending via localhost.








No packages published