skip to Main Content

I’m coding a telegram userbot (with telethon) which sends a message,every 60 seconds, to some chats.

I’m using 2 threads but I get the following errors: "RuntimeWarning: coroutine ‘sender’ was never awaited" and "no running event loop".

My code:

....

async def sender():
    for chat in chats :
        try:
            if  chat.megagroup == True:
                await client.send_message(chat, messaggio)
        except:
            await client.send_message(myID, 'error')
schedule.every(60).seconds.do(asyncio.create_task(sender()))

...
class checker1(Thread):
    def run(self):
        while True:
            schedule.run_pending()
            time.sleep(1)
class checker2(Thread):
    def run(self):
        while True:
            client.add_event_handler(handler)
            client.run_until_disconnected()
checker2().start()
checker1().start()

I searched for a solution but I didn’t find anything…

2

Answers


  1. There are a few problems with your code. asyncio is complaining about "no running event loop" because your program never starts the event loop anywhere, and tasks can’t be scheduled without an event loop running. See Asyncio in corroutine RuntimeError: no running event loop. In order to start the event loop, you can use asyncio.run_until_complete() if you have a main coroutine for your program, or you can use asyncio.get_event_loop().run_forever() to run the event loop forever.

    The second problem is the incorrect usage of schedule.every(60).seconds.do(), which is hidden by the first error. schedule expects a function to be passed in, not an awaitable (which is what asyncio.create_task(sender()) returns). This normally would have caused a TypeError, but the create_task() without a running event loop raised an exception first, so this exception was never raised. You’ll need to define a function and then pass it to schedule, like this:

    def start_sender():
        asyncio.create_task(sender())
    schedule.every(60).seconds.do(start_sender)
    

    This should work as long as the event loop is started somewhere else in your program.

    Login or Signup to reply.
  2. You should avoid using threads with asyncio unless you know what you’re doing. The code can be rewritten using asyncio as follows, since most of the time you don’t actually need threads:

    import asyncio
    
    async def sender():
        for chat in chats :
            try:
                if  chat.megagroup == True:
                    await client.send_message(chat, messaggio)
            except:
                await client.send_message(myID, 'error')
    
    async def checker1():
        while True:
            await sender()
            await asyncio.sleep(60)  # every 60s
    
    async def main():
        await asyncio.create_task(checker1())  # background task
        await client.run_until_disconnected() 
    
    client.loop.run_until_complete(main())
    

    This code is not perfect (you should properly cancel and wait checker1 at the end of the program), but it should work.

    As a side note, you don’t need client.run_until_disconnected(). The call simply blocks (runs) until the client is disconnected. If you can keep the program running differently, as long as asyncio runs, the client will work.

    Another thing: bare except: are a very bad idea, and will probably cause issues with exception. At least, replace it with except Exception.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search