Search code examples
pythonpython-asynciotelethonaiopg

Run two asynco loop in a python script (telethon, aiopg)


I would like to use Telethon (Telegram bot) and aiopg (PostgreSQL) library.

Telethon example:

from telethon import TelegramClient
api_id = 12345
api_hash = '0123456789abcdef0123456789abcdef'
client = TelegramClient('anon', api_id, api_hash)
async def main():
    # Getting information about yourself
    me = await client.get_me()
    print(me.stringify())

@client.on(events.NewMessage)
async def my_event_handler(event):
    if 'hello' in event.raw_text:
        await event.reply('hi!')

client.start()
client.run_until_disconnected()

aiopg example:

import aiopg

dsn = 'dbname=aiopg user=aiopg password=passwd host=127.0.0.1'


async def notify(conn):
    async with conn.cursor() as cur:
        for i in range(5):
            msg = "message {}".format(i)
            print('Send ->', msg)
            await cur.execute("NOTIFY channel, %s", (msg,))

        await cur.execute("NOTIFY channel, 'finish'")


async def listen(conn):
    async with conn.cursor() as cur:
        await cur.execute("LISTEN channel")
        while True:
            msg = await conn.notifies.get()
            if msg.payload == 'finish':
                return
            else:
                print('Receive <-', msg.payload)


async def main():
    async with aiopg.create_pool(dsn) as pool:
        async with pool.acquire() as conn1:
            listener = listen(conn1)
            async with pool.acquire() as conn2:
                notifier = notify(conn2)
                await asyncio.gather(listener, notifier)
    print("ALL DONE")


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

I would like to use both in a same python script. I tried to find the solution and it is maybe the asyncio.gather(...), but I don't know how can I combine these two library, how to start both loop. Can you please help me?


Solution

  • create a new async function which creates a new client instance and add all the handlers you need, for the sake of this example I showed some example handlers of mine.

    async def init_bot() -> TelegramClient:
        client = TelegramClient(
                     session="trade-bot",
                     api_hash=Config.API_HASH,
                     api_id=Config.API_ID,
                 )
        await client.start(bot_token=Config.BOT_TOKEN)
    
        client.add_event_handler(
            register_handler,
            events.NewMessage(incoming=True, pattern=r"^[\/?!]register$"),
        )
        client.add_event_handler(
            get_webhook_handler,
            events.NewMessage(incoming=True, pattern=r"^[\/?!]webhook$"),
        )
        client.add_event_handler(
            status_handler,
            events.NewMessage(incoming=True, pattern=r"^[\/?!]status$"),
        )
        _LOG.info("Bot client started")
        return client
    

    then later on you main function

    client = await init_bot()
    await client.connect()
    # the below code is non-blocking
    asyncio.create_task(client.run_until_disconnected())