Introduction
Zmail makes it easier to send and retrieve emails in python3. There's no need to manually add—server address, port, suitable protocol, and so on—Zmail will do it for you. Besides, use a python dict as a mail is also more intuitive.
WARNING: This project is no longer maintained. The original goal of
zmail
was to provide a simple way to send e-mail in python3. Unfortunately I am no longer have the time to continue to maintain this project. Feel free to fork if you want some features.
Installation
Zmail only running in python3 without third-party modules required. Do not support python2.
$ pip3 install zmail
Features
- Automatic looks for server address and it's port.
- Automatic uses suitable protocol to login.
- Automatic converts a python dictionary to MIME object(with attachments).
- Automatic add mail header and local name to avoid server reject your mail.
- Easily custom your mail header.
- Support HTML as mail content.
- Only require python >= 3.5 , you can embed it in your project without other module required.
Usage
Before using it, please ensure:
- Using python3
- Open SMTP/POP3 functions in your mail (For @163.com and @gmail.com you need to set your app private password)
Then, all you need to do is just import zmail.
QuickStart
import zmail
server = zmail.server('[email protected]', 'yourpassword')
# Send mail
server.send_mail('[email protected]',{'subject':'Hello!','content_text':'By zmail.'})
# Or to a list of friends.
server.send_mail(['[email protected]','[email protected]'],{'subject':'Hello!','content_text':'By zmail.'})
# Retrieve mail
latest_mail = server.get_latest()
zmail.show(latest_mail)
Demos
see zmail_demos
Examples
Verify SMTP and POP function working correctly
import zmail
server = zmail.server('[email protected]’, 'yourpassword')
if server.smtp_able():
pass
# SMTP function.
if server.pop_able():
pass
# POP function.
If SMTP and POP are working correctly, the function will return True, else return Fasle.
Send your mail
import zmail
mail = {
'subject': 'Success!', # Anything you want.
'content_text': 'This message from zmail!', # Anything you want.
'attachments': ['/Users/zyh/Documents/example.zip','/root/1.jpg'], # Absolute path will be better.
}
server = zmail.server('[email protected]‘, 'yourpassword')
server.send_mail('[email protected]', mail)
You can define sender's name by add 'from':'Boss <[email protected]>'
in your mail.
server.send_mail(['[email protected]','[email protected]'], mail)
you can also name them (use tuple, first is its name, next is its address).
server.send_mail([('Boss','[email protected]'),'[email protected]'], mail)
mail = {
'subject': 'Success!', # Anything you want.
'content_html': ['HTML CONTENT'],
'attachments': '/Users/zyh/Documents/example.zip', # Absolute path will be better.
}
server.send_mail('[email protected]',mail)
or
with open('/Users/example.html','r') as f:
content_html = f.read()
mail = {
'subject': 'Success!', # Anything you want.
'content_html': content_html,
'attachments': '/Users/zyh/Documents/example.zip', # Absolute path will be better.
}
server.send_mail('[email protected]',mail)
server.send_mail(['[email protected]','[email protected]'],mail,cc=['[email protected]'])
Again, you can also name them (use tuple, first is its name, next is its address).
server.send_mail(['[email protected]','[email protected]'],mail,cc=[('Boss','[email protected]'),'[email protected]'])
If zmail is not working correctly, you can customize your server config yourself.
server = zmail.server('username','password',smtp_host='smtp.163.com',smtp_port=994,smtp_ssl=True,pop_host='pop.163.com',pop_port=995,pop_tls=True)
Get your mails
import zmail
server = zmail.server('[email protected]‘, 'yourpassword')
mail = server.get_latest()
mail = server.get_mail(2)
mail = server.get_mails(subject='GitHub',start_time='2018-1-1',sender='github')
In this example, if 'GitHub' in mail's subject, it will be matched, as in '[GitHub] Your password has changed'
Sender is the same way.
You can also assign the range of mails.
mail = server.get_mails(subject='GitHub',start_time='2018-1-1',sender='github',start_index=1,end_index=10)
mailbox_info = server.stat()
The result is a tuple of 2 integers: (message count, mailbox size)
.
Parse your mail
In zmail, each mail will be mapped to a python dictionary, you can access your mail by
subject = mail['subject']
Show your mail's base information, use zmail.show()
import zmail
server = zmail.server('[email protected]’, 'yourpassword')
mail = server.get_latest()
zmail.show(mail)
See all contents in mail.
import zmail
server = zmail.server('[email protected]’, 'yourpassword')
mail = server.get_latest()
for k,v in mail.items():
print(k,v)
API Reference
zmail.server(username,password,smtp_host,smtp_port,smtp_ssl,smtp_tls,pop_host,pop_port,pop_ssl,pop_tls,config,timeout=60, debug=False, log=None,auto_add_from=True, auto_add_to=True)
Return MailServer instance, it implements all SMTP and POP functions.
If set any arguments which starts with pop
or smtp
, it will replace inner auto-generate argument (the arguments depend on the username
or config
you provide).
config Shortcut for use enterprise mail,if specified, enterprise mail configs will replace all inner auto-generate configs.
timeout can either be a float or int number of seconds to wait for.
debug If is True, server will open debug model and display debug information.
log The log can be None or instance of logging.logger,if is None, the zmail default logger is used, you can access it by logging.getLogger('zmail')
auto_add_to If set to True, when the key 'to' (case-insensitive) not in mail(For send), the default 'to' will automatically added to mail.
auto_add_from If set to True, when the key ' 'from' (case-insensitive) not in mail(For send), the default 'from' will automatically added to mail.
MailServer.send_mail(recipients, mail, timeout=None,auto_add_from=False, auto_add_to=False)
Return True if success.
recipients can either be str or a list of str.
mail can either be dict or CaseInsensitiveDict(Mail).mail structure see below.
timeout if is not None, it will replace server's timeout.
auto_add_from if is not None, it will replace server's auto_add_from.
auto_add_to if is not None, it will replace server's auto_add_to.
MailServer.stat()
Get mailbox status. The result is a tuple of 2 integers: (message count, mailbox size).
MailServer.get_mail(which)
Return Mail
which is a int number that represent mail's position in mailbox.The which must between 1 and message count(return from MailServer.stat())
Also set mail's seen flag.
MailServer.get_mails(subject=None,start_time=None,end_time=None,sender=None,start_index=None,end_index=None)
Return a list of Mail
subject can either be None or str, if is not None, the subject of every mail must contains subject
start_time can either be None or string or datetime object, if is string,the format is "YYYY-MM-DD HH:MM:SS"(e.g. "2018-1-1 10:10:20").If is not None,the date of every mail must greater than start_time.
end_time is similar to start_time.If is not None,the date of every mail must smaller than end_time.
sender can either be None or str, if is not None, the from(header) of every mail must contains sender.
start_index can either be None or int, if is None or smaller than 1, it is set to 1. if greater than message_count(From MailServer.stat()), it is set to message_count.
end_index similar to start_index.The selected range limited from start_index to end_index.
lso set mail's seen flag.
MailServer.get_latest()
Return Mail
Return latest mail.Equal to MailServer.get_mail(message_count).The message count is return from MailServer.stat()
also set mail's seen flag.
MailServer.get_info()
Return a list of raw_headers
Use MailServer.get_headers() instead.
Removed in version 0.2.0
MailServer.get_headers(start_index=None,end_index=None)
Return a list of headers.(A list of CaseInsensitiveDict)
The range of headers is limited from start_index to end_index.same as that of MailServer.get_mails()
New in version 0.2.0
MailServer.delete(which)
which flag message number which for deletion.
New in version 0.2.0
MailServer.smtp_able()
Return True if SMTP working correctly else False.
MailServer.pop_able()
Return True if POP working correctly else False.
Utils
-
zmail.show(mails)
You can use this function to show one or list of mail.
-
zmail.save_attachment(mail,target_path=None,overwrite=False)
Save mail's attachments to target_path.If not specified, target_path is current directory.If overwrite is True,the write process will overwrite exists file if possible.
-
zmail.save(mail,name=None,target_path=None,overwrite=False)
Save mail.
-
zmail.read(file_path,SEP=b'\r\n')
Read mail.
Mail Structures
Mail (Used for send)
Can either be dict or CaseInsensitiveDict(Usually from get_mail or get_mails)
subject The subject of mail.
from The 'from' header, represent the mail's source.
to (Not used).You can use tuple (name,address) to define the name of recipient.(Used for To and Cc)
content_text The text content.Can either be str or a list of str.
content_html The html content.Can either be str or a list of str.
attachments Include all attachments.It can either be str or a list of str or a list of tuple.(e.g. '/User/apple/1.txt' or ['/User/apple/1.txt','2.txt'] or [('1.txt',b'...'),('2.txt',b'...')] )
headers If you want to add extra headers,you can specified on it.Must be dict.
Mail(From get_mail or get_mails)
subject The subject of mail.
from The 'from' header, represent the mail's source.
to The 'to' header, represent the mail's destination.
content_text A list of text content.
content_html A list of html content.
attachments Include all attachments.(e.g. ['1.txt',b'...'])
raw_headers Include all raw header pairs.
headers Include all parsed headers.(CaseInsensitiveDict)
charsets Include all charsets.
date Mail date.
id Mail id.Used to locate mail position in mail-box.
raw raw mail.As a list of bytes.
Supported mail server
The mail server in this list has been tested and approved.
If your mail server not in it, don't worry, zmail will handle it automatically.If any problems in use, please tell me in the Github.
Server address | Send mail | Retrieve mail | Remarks |
---|---|---|---|
@163.com | ✓ | ✓ | Need app private password |
@qq.com | ✓ | ✓ | POP3 need app private password |
@126.com | ✓ | ✓ | |
@yeah.net | ✓ | ✓ | |
@gmail.com | ✓ | ✓ | Need app private password |
@sina.com | ✓ | ✓ | |
@outlook | ✓ | ✓ | Need app private password |
@hotmail | ✓ | ✓ | Require extra setup |
Supported enterprise mail server
Name | Usage |
---|---|
Tencent enterprise mail | zmail.server('username','psw',config='qq') |
Ali enterprise mail | zmail.server('username','psw',config='ali') |
Netease enterprise mail | zmail.server('username','psw',config='163') |
Google enterprise mail | zmail.server('username','psw',config='google') |
Q&A
- Can not send or retrieve
- Ensure your smtp&pop3 function is open
- Use smtp or pop protocol settings provided by your mail server to config zmail.server, like following
- SMTP:server = zmail.server('user','psw',smtp_host = 'xxx',smtp_port = 'yyyyy',smtp_ssl=True)
- POP3:server = zmail.server('user','psw',pop_host = 'xxx',pop_port = 'yyyyy',pop_ssl=True)