discord.ext.tasks
-- asyncio.Task ヘルパー¶
バージョン 1.1.0 で追加.
ボットを作成するときの最も一般的な操作の1つは、指定した間隔でバックグラウンドでループを実行させることです。このパターンは非常に一般的ですが、注意すべきことがたくさんあります。
asyncio.CancelledError
はどのように処理するべきですか?インターネット接続が切れた場合はどうするべきですか?
スリープできる最大時間は何秒ですか?
discord.pyの拡張機能の目的は、こういった苦労の種を抽象化することです。
レシピ¶
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
再接続中に処理する例外を追加します:
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
特定の回数ループさせる:
from discord.ext import tasks
import discord
@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!')
class MyClient(discord.Client):
async def setup_hook(self):
slow_count.start()
ループが始まる前に、Botの準備が整うまで待機する:
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()
キャンセルする場合、その間に何らかの処理を行う:
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 cog_unload(self):
self.bulker.cancel()
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()
毎日特定の時間に何かを行う:
import datetime
from discord.ext import commands, tasks
utc = datetime.timezone.utc
# If no tzinfo is given then UTC is assumed.
time = datetime.time(hour=8, minute=30, tzinfo=utc)
class MyCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.my_task.start()
def cog_unload(self):
self.my_task.cancel()
@tasks.loop(time=time)
async def my_task(self):
print("My task is running!")
毎日複数の特定の時間に何かを行う:
import datetime
from discord.ext import commands, tasks
utc = datetime.timezone.utc
# If no tzinfo is given then UTC is assumed.
times = [
datetime.time(hour=8, tzinfo=utc),
datetime.time(hour=12, minute=30, tzinfo=utc),
datetime.time(hour=16, minute=40, second=30, tzinfo=utc)
]
class MyCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.my_task.start()
def cog_unload(self):
self.my_task.cancel()
@tasks.loop(time=times)
async def my_task(self):
print("My task is running!")
APIリファレンス¶
- 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¶
ループと再接続処理を抽象化するバックグラウンドタスクのヘルパー。
loop()
はこれを作成するための主要なインタフェースです。- @after_loop¶
ループが終了した後に呼び出されるようにコルーチンを登録するデコレータ。
コルーチンは、引数をとりません。(クラス内での
self
は除く)注釈
このコルーチンはキャンセル中も呼び出されます。キャンセルされたかを判断したい場合は、
is_being_cancelled()
がTrue
か確認してください。
- @before_loop¶
ループが始まる前に呼び出されるようにコルーチンを登録するデコレータ。
discord.Client.wait_until_ready()
などを用いて、ループ開始前にボットの状態が整うまで待つのに便利です。コルーチンは、引数をとりません。(クラス内での
self
は除く)バージョン 2.0 で変更: このコルーチンで
stop()
を呼び出すと、最初のループの実行前にループが停止します。
- @error¶
タスクが未処理の例外に遭遇した場合に呼び出されるコルーチンを登録するデコレータ。
コルーチンは、送出された例外を引数としてとります。(クラス内での
self
は除く)デフォルトではライブラリロガーに出力しますが、他の実装をするために上書きすることもできます。
バージョン 1.4 で追加.
バージョン 2.0 で変更:
sys.stderr
に出力する代わりに、ライブラリロガーを使用するようになりました。
- property seconds¶
各ループ間の秒数を示す読み取り専用の値です。代わりに、明示的な
time
が渡された場合はNone
となります。バージョン 2.0 で追加.
- 型
Optional[
float
]
- property minutes¶
各ループ間の分数を示す読み取り専用の値です。代わりに、明示的な
time
が渡された場合はNone
となります。バージョン 2.0 で追加.
- 型
Optional[
float
]
- property hours¶
各ループ間の時間数を示す読み取り専用の値です。代わりに、明示的な
time
が渡された場合はNone
となります。バージョン 2.0 で追加.
- 型
Optional[
float
]
- property time¶
このループが実行する正確な時刻の読み取り専用のリスト。 相対的な時間が代わりに渡された場合は
None
。バージョン 2.0 で追加.
- 型
Optional[List[
datetime.time
]]
- property next_iteration¶
次のループがいつ発火するか。
バージョン 1.3 で追加.
- 型
Optional[
datetime.datetime
]
- await __call__(*args, **kwargs)¶
This function is a coroutine.
タスク内のコールバックを呼び出します。
バージョン 1.6 で追加.
- パラメータ
*args -- 使用する引数。
**kwargs -- 使用するキーワード引数。
- start(*args, **kwargs)¶
イベントループでタスクを開始します。
- パラメータ
*args -- 使用する引数。
**kwargs -- 使用するキーワード引数。
- 例外
RuntimeError -- タスクはすでに実行されていて実行中である。
- 戻り値
作成されたタスク。
- 戻り値の型
- stop()¶
タスクを正常に停止させます。
cancel()
とは違い、現在のループが終了してからタスクを終了します。注釈
もし終了前に内部の関数が処理可能な例外を送出した場合は成功するまで再試行します。
この動作が望ましくない場合は、停止前に
clear_exception_types()
を用いてエラー処理を除去するか、代わりにcancel()
を使用してください。バージョン 2.0 で変更:
before_loop()
にてこのメソッドを呼び出すと、最初のループの実行前にループが停止します。バージョン 1.2 で追加.
- cancel()¶
実行中の場合、内部のタスクをキャンセルします。
- restart(*args, **kwargs)¶
内部タスクを再起動する便利なメソッド。
注釈
この関数の動作により、
start()
とは異なりタスクは返されません。- パラメータ
*args -- 使用する引数。
**kwargs -- 使用するキーワード引数。
- add_exception_type(*exceptions)¶
再接続中に処理する例外を追加します。
デフォルトでは、
discord.Client.connect()
によって処理される例外は、多くのインターネット切断エラーを含んでいます。独自の例外を送出するサードパーティー・ライブラリーを使用している場合に便利です。
- パラメータ
*exceptions (Type[
BaseException
]) -- 処理するべき例外のクラスの引数リスト。- 例外
TypeError -- 渡された例外はクラスでないか、
BaseException
を継承していません。
- clear_exception_types()¶
処理すべき例外タイプをすべて除去します。
注釈
この動作は当然ながら元に戻せません!
- remove_exception_type(*exceptions)¶
再接続中に処理する例外を除去します:
- パラメータ
*exceptions (Type[
BaseException
]) -- 処理するべき例外のクラスの引数リスト。- 戻り値
すべての例外が正常に除去されたかどうか。
- 戻り値の型
- get_task()¶
Optional[
asyncio.Task
]: 内部タスクを取得します。実行中のものがない場合はNone
を返します。
- is_being_cancelled()¶
タスクがキャンセルされているかどうか。
- change_interval(*, seconds=0, minutes=0, hours=0, time=...)¶
ループ間の間隔を変更します。
バージョン 1.2 で追加.
- パラメータ
seconds (
float
) -- 各繰り返しの間の秒数。minutes (
float
) -- 各繰り返しの間の 分数。hours (
float
) -- 各繰り返しの間の時間数。time (Union[
datetime.time
, Sequence[datetime.time
]]) --ループを実行する正確な時刻。空でないリストか、
datetime.time
が単独で渡されるべきです。これは、相対的な時間を指定するパラメーターと同時に使用できません。バージョン 2.0 で追加.
注釈
重複された時刻は無視され、一回だけ実行されます。
- 例外
ValueError -- 無効な値が渡された場合。
TypeError --
time
パラメーターに無効な値が渡され、またはtime
パラメーターと相対的な時間を指定するパラメーターが同時に使用された場合。
- @discord.ext.tasks.loop(*, seconds=..., minutes=..., hours=..., time=..., count=None, reconnect=True)¶
バックグラウンドでタスクをスケジュールし、オプションで再接続ロジックを扱うデコレータ。デコレータは
Loop
を返します。- パラメータ
seconds (
float
) -- 各繰り返しの間の秒数。minutes (
float
) -- 各繰り返しの間の 分数。hours (
float
) -- 各繰り返しの間の時間数。time (Union[
datetime.time
, Sequence[datetime.time
]]) --ループを実行する正確な時刻。空でないリストか、
datetime.time
が単独で渡されるべきです。タイムゾーンが使用できます。タイムゾーンが設定されてない場合はUTCと推定されます。これは、相対的な時間を指定するパラメーターと同時に使用できません。
注釈
重複された時刻は無視され、一回だけ実行されます。
バージョン 2.0 で追加.
count (Optional[
int
]) -- 実行するループの回数、無限ループの場合はNone
です。reconnect (
bool
) -- エラーを処理し、discord.Client.connect()
で使用されたものと同様のエクスポネンシャルバックオフ アルゴリズムを用いてタスクを再起動するべきか。
- 例外
ValueError -- 無効な値が渡された場合。
TypeError -- 関数がコルーチンではない場合、
time
パラメーターに無効な値が渡された場合、またはtime
パラメーターと相対的な時間を指定するパラメーターが同時に使用された場合。