discord.ext.tasks¶
Добавлено в версии 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 Pycord 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.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()
Doing something during cancellation:
from discord.ext import tasks, commands
import asyncio
class MyCog(commands.Cog):
def __init__(self, bot):
self.bot= bot
self._batch = []
self.lock = asyncio.Lock()
self.bulker.start()
async def do_bulk(self):
# bulk insert data here
...
@tasks.loop(seconds=10.0)
async def bulker(self):
async with self.lock:
await self.do_bulk()
@bulker.after_loop
async def on_bulker_cancel(self):
if self.bulker.is_being_cancelled() and len(self._batch) != 0:
# if we're cancelled and we have some data left...
# let's insert it to our database
await self.do_bulk()
API Reference¶
- async__call__
- defadd_exception_type
- @after_loop
- @before_loop
- defcancel
- defchange_interval
- defclear_exception_types
- @error
- deffailed
- defget_task
- defis_being_cancelled
- defis_running
- defremove_exception_type
- defrestart
- defstart
- defstop
- class discord.ext.tasks.Loop(coro, seconds, hours, minutes, time, count, reconnect, loop, overlap)[исходный код]¶
A background task helper that abstracts the loop and reconnection logic for you.
The main interface to create this is through
loop().- Параметры:
- @after_loop(coro)[исходный код]¶
A decorator that register a coroutine to be called after the loop finished running.
The coroutine must take no arguments (except
selfin a class context).Примечание
This coroutine is called even during cancellation. If it is desirable to tell apart whether something was cancelled or not, check to see whether
is_being_cancelled()isTrueor not.
- @before_loop(coro)[исходный код]¶
A decorator that registers 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().The coroutine must take no arguments (except
selfin a class context).
- @error(coro)[исходный код]¶
A decorator that registers a coroutine to be called if the task encounters an unhandled exception.
The coroutine must take only one argument the exception raised (except
selfin a class context).By default, this prints to
sys.stderrhowever it could be overridden to have a different implementation.Добавлено в версии 1.4.
- property seconds: float | None¶
Read-only value for the number of seconds between each iteration.
Noneif an explicittimevalue was passed instead.Добавлено в версии 2.0.
- property minutes: float | None¶
Read-only value for the number of minutes between each iteration.
Noneif an explicittimevalue was passed instead.Добавлено в версии 2.0.
- property hours: float | None¶
Read-only value for the number of hours between each iteration.
Noneif an explicittimevalue was passed instead.Добавлено в версии 2.0.
- property time: list[time] | None¶
Read-only list for the exact times this loop runs at.
Noneif relative times were passed instead.Добавлено в версии 2.0.
- property next_iteration: datetime | None¶
When the next iteration of the loop will occur.
Добавлено в версии 1.3.
- await __call__(*args, **kwargs)[исходный код]¶
This function is a coroutine.
Calls the internal callback that the task holds.
Добавлено в версии 1.6.
- start(*args, **kwargs)[исходный код]¶
Starts the internal task in the event loop.
- Параметры:
- Исключение:
RuntimeError – A task has already been launched and is running.
- Результат:
The task that has been created.
- Тип результата:
- stop()[исходный код]¶
Gracefully stops the task from running.
Unlike
cancel(), this allows the task to finish its current iteration before gracefully exiting.Примечание
If the internal function raises an error that can be handled before finishing then it will retry until it succeeds.
If this is undesirable, either remove the error handling before stopping via
clear_exception_types()or usecancel()instead.Добавлено в версии 1.2.
- Тип результата:
- cancel()[исходный код]¶
Cancels the internal task, if it is running.
- Тип результата:
- restart(*args, **kwargs)[исходный код]¶
A convenience method to restart the internal task.
Примечание
Due to the way this function works, the task is not returned like
start().
- add_exception_type(*exceptions)[исходный код]¶
Adds exception types 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.
- Параметры:
*exceptions (
type[BaseException]) – An argument list of exception classes to handle.- Исключение:
TypeError – An exception passed is either not a class or not inherited from
BaseException.- Тип результата:
- clear_exception_types()[исходный код]¶
Removes all exception types that are handled.
Примечание
This operation obviously cannot be undone!
- Тип результата:
- remove_exception_type(*exceptions)[исходный код]¶
Removes exception types from being handled during the reconnect logic.
- Параметры:
*exceptions (
type[BaseException]) – An argument list of exception classes to handle.- Результат:
Whether all exceptions were successfully removed.
- Тип результата:
- get_task()[исходный код]¶
Fetches the internal task or
Noneif there isn’t one running.
- is_being_cancelled()[исходный код]¶
Whether the task is being cancelled.
- Тип результата:
- failed()[исходный код]¶
Whether the internal task has failed.
Добавлено в версии 1.2.
- Тип результата:
- is_running()[исходный код]¶
Check if the task is currently running.
Добавлено в версии 1.4.
- Тип результата:
- change_interval(*, seconds=0, minutes=0, hours=0, time=...)[исходный код]¶
Changes the interval for the sleep time.
Добавлено в версии 1.2.
- Параметры:
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.time (
time|Sequence[time]) –The exact times to run this loop at. Either a non-empty list or a single value of
datetime.timeshould be passed. This cannot be used in conjunction with the relative time parameters.Добавлено в версии 2.0.
Примечание
Duplicate times will be ignored, and only run once.
- Исключение:
ValueError – An invalid value was given.
TypeError – An invalid value for the
timeparameter was passed, or thetimeparameter was passed in conjunction with relative time parameters.
- Тип результата:
- discord.ext.tasks.loop(*, seconds=..., minutes=..., hours=..., time=..., count=None, reconnect=True, loop=..., overlap=False)[исходный код]¶
A decorator that schedules a task in the background for you with optional reconnect logic. The decorator returns a
Loop.- Параметры:
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.time (
time|Sequence[time]) –The exact times to run this loop at. Either a non-empty list or a single value of
datetime.timeshould be passed. Timezones are supported. If no timezone is given for the times, it is assumed to represent UTC time.This cannot be used in conjunction with the relative time parameters.
Примечание
Duplicate times will be ignored, and only run once.
Добавлено в версии 2.0.
count (
int|None) – The number of loops to do,Noneif 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 indiscord.Client.connect().loop (
AbstractEventLoop) – The loop to use to register the task, if not given the default event loop is used viaasyncio.get_event_loop()if it exists or one is created viaasyncio.new_event_loop().Controls whether overlapping executions of the task loop are allowed. Set to False (default) to run iterations one at a time, True for unlimited overlap, or an int to cap the number of concurrent runs.
Добавлено в версии 2.7.
- Исключение:
ValueError – An invalid value was given.
TypeError – The function was not a coroutine, an invalid value for the
timeparameter was passed, ortimeparameter was passed in conjunction with relative time parameters.
- Тип результата:
Callable[[TypeVar(LF, bound=Callable[...,Awaitable[Any]])],Loop[TypeVar(LF, bound=Callable[...,Awaitable[Any]])]]