Security News
PyPI’s New Archival Feature Closes a Major Security Gap
PyPI now allows maintainers to archive projects, improving security and helping users make informed decisions about their dependencies.
.. _imaplib2: https://sourceforge.net/projects/imaplib2/ .. _imaplib: https://docs.python.org/3/library/imaplib.html .. _asyncio: https://docs.python.org/3/library/asyncio.html
.. image:: https://github.com/bamthomas/aioimaplib/workflows/tests/badge.svg :alt: Build status :target: https://github.com/bamthomas/aioimaplib/actions/
.. image:: https://coveralls.io/repos/github/bamthomas/aioimaplib/badge.svg :target: https://coveralls.io/github/bamthomas/aioimaplib
This library is inspired by imaplib_ and imaplib2_ from Piers Lauder, Nicolas Sebrecht, Sebastian Spaeth. Some utilities functions are taken from imaplib/imaplib2 thanks to them.
Thank you to all contributors for your time and interest :pray: :point_right:
The aim is to port the imaplib with asyncio_, to benefit from the sleep or treat model. It has no dependencies for runtime (the core library).
It is tested against python 3.9, 3.10, 3.11 matrix. But the library itself could run with other python versions.
.. code-block:: python
import asyncio
from aioimaplib import aioimaplib
async def check_mailbox(host, user, password):
imap_client = aioimaplib.IMAP4_SSL(host=host)
await imap_client.wait_hello_from_server()
await imap_client.login(user, password)
res, data = await imap_client.select()
print('there is %s messages INBOX' % data[0])
await 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.
.. _RFC2177: https://tools.ietf.org/html/rfc2177
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.
.. code-block:: python
async def wait_for_new_message(host, user, password):
imap_client = aioimaplib.IMAP4_SSL(host=host)
await imap_client.wait_hello_from_server()
await imap_client.login(user, password)
await imap_client.select()
idle = await imap_client.idle_start(timeout=10)
while imap_client.has_pending_idle():
msg = await imap_client.wait_server_push()
print(msg)
if msg == STOP_WAIT_SERVER_PUSH:
imap_client.idle_done()
await asyncio.wait_for(idle, 1)
await imap_client.logout()
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(wait_for_new_message('my.imap.server', 'user', 'pass'))
Or in a more event based style (the IDLE command is closed at each message from server):
.. code-block:: python
async def idle_loop(host, user, password): imap_client = aioimaplib.IMAP4_SSL(host=host, timeout=30) await imap_client.wait_hello_from_server()
await imap_client.login(user, password)
await imap_client.select()
while True:
print((await imap_client.uid('fetch', '1:*', 'FLAGS')))
idle = await imap_client.idle_start(timeout=60)
print((await imap_client.wait_server_push()))
imap_client.idle_done()
await asyncio.wait_for(idle, 30)
.. _asyncio.Event: https://docs.python.org/3.4/library/asyncio-sync.html#event .. _asyncio.Condition: https://docs.python.org/3.4/library/asyncio-sync.html#condition .. _supervisor: http://supervisord.org/
The IMAP4ClientProtocol class is not thread safe, it uses asyncio.Event_ and asyncio.Condition_ that are not thread safe, and state change for pending commands is not locked.
It is possible to use threads but each IMAP4ClientProtocol instance should run in the same thread:
.. image:: images/thread_imap_protocol.png
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:
.. _howto: https://docs.python.org/3.4/howto/logging.html#configuring-logging-for-a-library
As said in the logging howto_ the logger is defined with
.. code-block:: python
logger = logging.getLogger(__name__)
Where name is 'aioimaplib.aioimaplib'. You can set the logger parameters, either by python API
.. code-block:: python
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
.. code-block:: yaml
loggers:
...
aioimaplib.aioimaplib:
level: DEBUG
handlers: [syslog]
propagate: no
...
Starting with the 01/01/23 Microsoft Outlook can only be accessed with OAuth2. You need to register you client to be used with oauth. Find more :https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth:`here`.
This might be also used with Google Mail, but it is not tested for it.
.. _poetry: https://python-poetry.org/
Developers are welcome! If you want to improve it, fix bugs, test it with other IMAP servers, give feedback, thank you for it.
We use poetry_ for building the library. Just run
.. code-block:: bash
poetry install
poetry run pytest
# or you can create a poetry shell
poetry install
poetry shell
pytest
To add an imaplib or imaplib2 command you can :
.. _rfc3501: https://tools.ietf.org/html/rfc3501 .. _rfc4978: https://tools.ietf.org/html/rfc4978 .. _rfc4314: https://tools.ietf.org/html/rfc4314 .. _rfc2087: https://tools.ietf.org/html/rfc2087 .. _rfc5256: https://tools.ietf.org/html/rfc5256 .. _rfc2971: https://tools.ietf.org/html/rfc2971 .. _rfc2342: https://tools.ietf.org/html/rfc2342 .. _rfc4469: https://tools.ietf.org/html/rfc4469
Sometimes you break things and you don't understand what's going on (I always do). For this library I have two related tools:
.. role:: bash(code) :language: bash
sudo ngrep -d lo port 12345
FAQs
Python asyncio IMAP4rev1 client library
We found that aioimaplib demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now allows maintainers to archive projects, improving security and helping users make informed decisions about their dependencies.
Research
Security News
Malicious npm package postcss-optimizer delivers BeaverTail malware, targeting developer systems; similarities to past campaigns suggest a North Korean connection.
Security News
CISA's KEV data is now on GitHub, offering easier access, API integration, commit history tracking, and automated updates for security teams and researchers.