0

I was looking for an asynchronous library for imap and I found this library called imap_tools and find it very easy to use and really want to stick with it but its not asynchronous. The reason I want it to be asynchronous is because I want to use it inside discord.py and non-async network operations would block the event loop and especially because sometimes the response takes longer or gets stuck or anything like that and affects the performance of my bot.

Is there anything I can do to use this library in asynchronous manner like I just need to connect with imap server and fetch an email and that's it. Is it possible that I can just wrap that functionality in an async function?

from imap_tools import MailBox, AND
import asyncio

async def fetch_emails():
    
    with MailBox('imap.gmail.com').login('username@gmail.com', 'pwd') as mailbox:
        for msg in mailbox.fetch():
            print(msg.subject)

asyncio.run(fetch_emails())
not_speshal
  • 22,093
  • 2
  • 15
  • 30
  • You can wrap it in an async function but it will still block the event loop. No idea if this is good, but there is: https://pypi.org/project/aioimaplib/ – Anentropic Aug 08 '23 at 16:09

1 Answers1

-1

This is from another question, but maybe it could help you. Because the main async loop runs in a single thread, non asynchronous tasks will block the entire loop and therefore must be run in a separate thread.

See here for more information (this code below is from this answer here): https://stackoverflow.com/a/28492261/238849

import asyncio
import time
from concurrent.futures import ProcessPoolExecutor

def cpu_bound_operation(x):
    time.sleep(x) # This is some operation that is CPU-bound

@asyncio.coroutine
def main():
    # Run cpu_bound_operation in the ProcessPoolExecutor
    # This will make your coroutine block, but won't block
    # the event loop; other coroutines can run in meantime.
    yield from loop.run_in_executor(p, cpu_bound_operation, 5)


loop = asyncio.get_event_loop()
p = ProcessPoolExecutor(2) # Create a ProcessPool with 2 processes
loop.run_until_complete(main())
synic
  • 26,359
  • 20
  • 111
  • 149
  • The `asyncio.coroutine` decorator was only introduced in python 3.5 when the async/await syntax wasn't introduced yet. The decorator was deprecated in python 3.8 and removed in python 3.10. – Łukasz Kwieciński Aug 08 '23 at 16:14
  • @ŁukaszKwieciński sure, but this comment is unrelated to the question or the answer. The point is the thread – synic Aug 08 '23 at 16:27