'Single action script for discord bot with python discord.py

I understand that usually the discord bots are in a listening (blocking) loop, but how can I create a function that connects, send a message or perform any action and disconnect in a non blocking flow?

I'm using discord.py and I'm looking for something like:

import discord

TOKEN = "mYtOkEn"
    
discord.connect(TOKEN)
discord.send("I'm sending this message")
discord.disconnect()

I already tryied playing with the async but have problems with the threading, so was wondering if there is something more simple.

It is for a button that when clicked, perform that action but after that it can continue working on other tasks

Thanks beforehand



Solution 1:[1]

Thank you for your help and support. With the SleepyStew answer I could find the path to solve it and went this way:

import discord
import asyncio

def discord_single_task():

    # Define Coroutine
    async def coroutine_to_run():
        TOKEN = "Secret"

        # Instantiate the Client Class
        client = discord.Client()

        # # Start (We won't use connect because we don't want to open a websocket, it will start a blocking loop and it is what we are avoiding)
        await client.login(TOKEN)
                
        # Do what you have to do
        print("We are doing what we want to do")

        # Close
        await client.close()

    # Create Loop to run coroutine
    loop = asyncio.new_event_loop()
    llll = loop.create_task(coroutine_to_run())
    loop.run_until_complete(llll)

    return 'Action performed successfully without a blocking loop!'

Solution 2:[2]

One way you could accomplish this is by using a custom event loop. Example:

import discord
import asyncio
from threading import Thread

TOKEN = "secret"

client = discord.Client()


def init():
    loop = asyncio.get_event_loop()
    loop.create_task(client.start(TOKEN))
    Thread(target=loop.run_forever).start()


@client.event
async def on_message(message):
    if message.author == client.user:
        return

    await message.channel.send('Hello!')


@client.event
async def on_ready():
    print("Discord bot logged in as: %s, %s" % (client.user.name, client.user.id))

init()
print("Non-blocking")

Take a look at this for more info: C-Python asyncio: running discord.py in a thread

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jfcabreras
Solution 2 SleepyStew