discord.ext.tasks – asyncio.Task helpers

New in version 1.1.0.

One of the most common operations when making a bot is having a loop run in the background at a specified interval. This pattern is very common but has a lot of things you need to look out for:

  • How do I handle asyncio.CancelledError?

  • What do I do if the internet goes out?

  • What is the maximum number of seconds I can sleep anyway?

The goal of this discord.py extension is to abstract all these worries away from you.

Recipes

A simple background task in a Cog:

from discord.ext import tasks, commands

class MyCog(commands.Cog):
    def __init__(self):
        self.index = 0
        self.printer.start()

    def cog_unload(self):
        self.printer.cancel()

    @tasks.loop(seconds=5.0)
    async def printer(self):
        print(self.index)
        self.index += 1

Adding an exception to handle during reconnect:

import asyncpg
from discord.ext import tasks, commands

class MyCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.data = []
        self.batch_update.add_exception_type(asyncpg.PostgresConnectionError)
        self.batch_update.start()

    def cog_unload(self):
        self.batch_update.cancel()

    @tasks.loop(minutes=5.0)
    async def batch_update(self):
        async with self.bot.pool.acquire() as con:
            # batch update here...
            pass

Looping a certain amount of times before exiting:

from discord.ext import tasks

@tasks.loop(seconds=5.0, count=5)
async def slow_count():
    print(slow_count.current_loop)

@slow_count.after_loop
async def after_slow_count():
    print('done!')

slow_count.start()

Waiting until the bot is ready before the loop starts:

from discord.ext import tasks, commands

class MyCog(commands.Cog):
    def __init__(self, bot):
        self.index = 0
        self.printer.before_loop(bot.wait_until_ready())
        self.printer.start()

    def cog_unload(self):
        self.printer.cancel()

    @tasks.loop(seconds=5.0)
    async def printer(self):
        print(self.index)
        self.index += 1

before_loop() can be used as a decorator as well:

from discord.ext import tasks, commands

class MyCog(commands.Cog):
    def __init__(self, bot):
        self.index = 0
        self.bot = bot
        self.printer.start()

    def cog_unload(self):
        self.printer.cancel()

    @tasks.loop(seconds=5.0)
    async def printer(self):
        print(self.index)
        self.index += 1

    @printer.before_loop
    async def before_printer(self):
        print('waiting...')
        await self.bot.wait_until_ready()

API Reference

class discord.ext.tasks.Loop

A background task helper that abstracts the loop and reconnection logic for you.

The main interface to create this is through loop().

current_loop

int – The current iteration of the loop.

start(*args, **kwargs)

Starts the internal task in the event loop.

Parameters
  • *args – The arguments to to use.

  • **kwargs – The keyword arguments to use.

Raises

RuntimeError – A task has already been launched.

Returns

The task that has been created.

Return type

asyncio.Task

cancel()

Cancels the internal task, if any are running.

add_exception_type(exc)

Adds an exception type to be handled during the reconnect logic.

By default the exception types handled are those handled by discord.Client.connect(), which includes a lot of internet disconnection errors.

This function is useful if you’re interacting with a 3rd party library that raises its own set of exceptions.

Parameters

exc (Type[BaseException]) – The exception class to handle.

Raises

TypeError – The exception passed is either not a class or not inherited from BaseException.

clear_exception_types()

Removes all exception types that are handled.

Note

This operation obviously cannot be undone!

remove_exception_type(exc)

Removes an exception type from being handled during the reconnect logic.

Parameters

exc (Type[BaseException]) – The exception class to handle.

Returns

Whether it was successfully removed.

Return type

bool

get_task()

Optional[asyncio.Task]: Fetches the internal task or None if there isn’t one running.

before_loop(coro)

A function that also acts as a decorator to register a coroutine to be called before the loop starts running. This is useful if you want to wait for some bot state before the loop starts, such as discord.Client.wait_until_ready().

Parameters

coro (awaitable) – The coroutine to register before the loop runs.

Raises

TypeError – The function was not a coroutine.

after_loop(coro)

A function that also acts as a decorator to register a coroutine to be called after the loop finished running.

Parameters

coro (awaitable) – The coroutine to register after the loop finishes.

Raises

TypeError – The function was not a coroutine.

discord.ext.tasks.loop(*, seconds=0, minutes=0, hours=0, count=None, reconnect=True, loop=None)

A decorator that schedules a task in the background for you with optional reconnect logic.

Parameters
  • seconds (float) – The number of seconds between every iteration.

  • minutes (float) – The number of minutes between every iteration.

  • hours (float) – The number of hours between every iteration.

  • count (Optional[int]) – The number of loops to do, None if it should be an infinite loop.

  • reconnect (bool) – Whether to handle errors and restart the task using an exponential back-off algorithm similar to the one used in discord.Client.connect().

  • loop (asyncio.AbstractEventLoop) – The loop to use to register the task, if not given defaults to asyncio.get_event_loop().

Raises
Returns

The loop helper that handles the background task.

Return type

Loop