Python asyncio IMAP4rev1 client library
The aim is to port the imaplib with asyncio, to benefit from the sleep or treat model.
It runs with python 3.4 and 3.5.
import asyncio from aioimaplib import aioimaplib @asyncio.coroutine def check_mailbox(host, user, password): imap_client = aioimaplib.IMAP4_SSL(host=host) yield from imap_client.wait_hello_from_server() yield from imap_client.login(user, password) res, data = yield from imap_client.select() print('there is %s messages INBOX' % data) yield from imap_client.logout() if __name__ == '__main__': loop = asyncio.get_event_loop() loop.run_until_complete(check_mailbox('my.imap.server', 'user', 'pass'))
Beware that the IMAP4.close() function is an IMAP function that is closing the selected mailbox, thus passing from SELECTED state to AUTH state. It does not close the TCP connection. The way to close TCP connection properly is to logout.
The RFC2177 is implemented, to be able to wait for new mail messages without using CPU. The responses are pushed in an async queue, and it is possible to read them in real time. To leave the IDLE mode, it is necessary to send a “DONE” command to the server.
@asyncio.coroutine def wait_for_new_message(host, user, password): imap_client = aioimaplib.IMAP4_SSL(host=host) yield from imap_client.wait_hello_from_server() yield from imap_client.login(user, password) yield from imap_client.select() asyncio.async(imap_client.idle()) while True: msg = yield from imap_client.wait_server_push() print('--> received from server: %s' % msg) if 'EXISTS' in msg: imap_client.idle_done() break yield from imap_client.logout() if __name__ == '__main__': loop = asyncio.get_event_loop() loop.run_until_complete(wait_for_new_message('my.imap.server', 'user', 'pass'))
It is possible to use threads but each IMAP4ClientProtocol instance should run in the same thread :
Each color rectangle is an IMAP4ClientProtocol instance piece of code executed by the thread asyncio loop until it reaches a yield, waiting on I/O.
For example, it is possible to launch 4 mono-threaded mail-fetcher processes on a 4 cores server with supervisor, and use a distribution function like len(email) % (process_num) or whatever to share equally a mail account list between the 4 processes.
IMAP protocol allows to run some commands in parallel. Four rules are implemented to ensure responses consistency:
As said in the logging howto the logger is defined with
logger = logging.getLogger(__name__)
Where name is ‘aioimaplib.aioimaplib’. You can set the logger parameters, either by python API
aioimaplib_logger = logging.getLogger('aioimaplib.aioimaplib') sh = logging.StreamHandler() sh.setLevel(logging.DEBUG) sh.setFormatter(logging.Formatter("%(asctime)s %(levelname)s [%(module)s:%(lineno)d] %(message)s")) aioimaplib_logger.addHandler(sh)
Or loading config file (for example with logging.config.dictConfig(yaml.load(file))) with this piece of yaml file:
loggers: ... aioimaplib.aioimaplib: level: DEBUG handlers: [syslog] propagate: no ...
Developers are welcome ! If you want to improve it, fix bugs, test it with other IMAP servers, give feedback, thank you for it.
To develop, just run:
virtualenv --python=python3.4 venv source venv/bin/activate python setup.py develop pip install -r dev-requirements.txt nosetests
To add a imaplib or imaplib2 command you can :
Sometimes you break things and you don’t understand what’s going on (I always do). For this library I have two related tools:
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
|File Name & Checksum SHA256 Checksum Help||Version||File Type||Upload Date|
|aioimaplib-0.7.2-py3.5.egg (342.9 kB) Copy SHA256 Checksum SHA256||3.5||Egg||Jun 19, 2017|
|aioimaplib-0.7.2-py3-none-any.whl (348.5 kB) Copy SHA256 Checksum SHA256||3.5||Wheel||Jun 19, 2017|
|aioimaplib-0.7.2.tar.gz (51.3 kB) Copy SHA256 Checksum SHA256||–||Source||Jun 19, 2017|