|
| 1 | +# バックグラウンドタスク |
| 2 | + |
| 3 | +レスポンスを返した *後に* 実行されるバックグラウンドタスクを定義できます。 |
| 4 | + |
| 5 | +これは、リクエスト後に処理を開始する必要があるが、クライアントがレスポンスを受け取る前に処理を終える必要のない操作に役立ちます。 |
| 6 | + |
| 7 | +これには、たとえば次のものが含まれます。 |
| 8 | + |
| 9 | +* 作業実行後のメール通知: |
| 10 | + * メールサーバーへの接続とメールの送信は「遅い」(数秒) 傾向があるため、すぐにレスポンスを返し、バックグラウンドでメール通知ができます。 |
| 11 | +* データ処理: |
| 12 | + * たとえば、時間のかかる処理を必要とするファイル受信時には、「受信済み」(HTTP 202) のレスポンスを返し、バックグラウンドで処理できます。 |
| 13 | + |
| 14 | +## `BackgroundTasks` の使用 |
| 15 | + |
| 16 | +まず初めに、`BackgroundTasks` をインポートし、` BackgroundTasks` の型宣言と共に、*path operation 関数* のパラメーターを定義します: |
| 17 | + |
| 18 | +```Python hl_lines="1 13" |
| 19 | +{!../../../docs_src/background_tasks/tutorial001.py!} |
| 20 | +``` |
| 21 | + |
| 22 | +**FastAPI** は、`BackgroundTasks` 型のオブジェクトを作成し、そのパラメーターに渡します。 |
| 23 | + |
| 24 | +## タスク関数の作成 |
| 25 | + |
| 26 | +バックグラウンドタスクとして実行される関数を作成します。 |
| 27 | + |
| 28 | +これは、パラメーターを受け取ることができる単なる標準的な関数です。 |
| 29 | + |
| 30 | +これは `async def` または通常の `def` 関数であり、**FastAPI** はこれを正しく処理します。 |
| 31 | + |
| 32 | +ここで、タスク関数はファイル書き込みを実行します (メール送信のシミュレーション)。 |
| 33 | + |
| 34 | +また、書き込み操作では `async` と `await` を使用しないため、通常の `def` で関数を定義します。 |
| 35 | + |
| 36 | +```Python hl_lines="6-9" |
| 37 | +{!../../../docs_src/background_tasks/tutorial001.py!} |
| 38 | +``` |
| 39 | + |
| 40 | +## バックグラウンドタスクの追加 |
| 41 | + |
| 42 | +*path operations 関数* 内で、`.add_task()` メソッドを使用してタスク関数を *background tasks* オブジェクトに渡します。 |
| 43 | + |
| 44 | +```Python hl_lines="14" |
| 45 | +{!../../../docs_src/background_tasks/tutorial001.py!} |
| 46 | +``` |
| 47 | + |
| 48 | +`.add_task()` は以下の引数を受け取ります: |
| 49 | + |
| 50 | +* バックグラウンドで実行されるタスク関数 (`write_notification`)。 |
| 51 | +* タスク関数に順番に渡す必要のある引数の列 (`email`)。 |
| 52 | +* タスク関数に渡す必要のあるキーワード引数 (`message="some notification"`)。 |
| 53 | + |
| 54 | +## 依存性注入 |
| 55 | + |
| 56 | +`BackgroundTasks` の使用は依存性注入システムでも機能し、様々な階層 (*path operations 関数*、依存性 (依存可能性)、サブ依存性など) で `BackgroundTasks` 型のパラメーターを宣言できます。 |
| 57 | + |
| 58 | +**FastAPI** は、それぞれの場合の処理方法と同じオブジェクトの再利用方法を知っているため、すべてのバックグラウンドタスクがマージされ、バックグラウンドで後で実行されます。 |
| 59 | + |
| 60 | +```Python hl_lines="13 15 22 25" |
| 61 | +{!../../../docs_src/background_tasks/tutorial002.py!} |
| 62 | +``` |
| 63 | + |
| 64 | +この例では、レスポンスが送信された *後* にメッセージが `log.txt` ファイルに書き込まれます。 |
| 65 | + |
| 66 | +リクエストにクエリがあった場合、バックグラウンドタスクでログに書き込まれます。 |
| 67 | + |
| 68 | +そして、*path operations 関数* で生成された別のバックグラウンドタスクは、`email` パスパラメータを使用してメッセージを書き込みます。 |
| 69 | + |
| 70 | +## 技術的な詳細 |
| 71 | + |
| 72 | +`BackgroundTasks` クラスは、<a href="https://www.starlette.io/background/" class="external-link" target="_blank">`starlette.background`</a>から直接取得されます。 |
| 73 | + |
| 74 | +これは、FastAPI に直接インポート/インクルードされるため、`fastapi` からインポートできる上に、`starlette.background`から別の `BackgroundTask` (末尾に `s` がない) を誤ってインポートすることを回避できます。 |
| 75 | + |
| 76 | +`BackgroundTasks`のみを使用することで (`BackgroundTask` ではなく)、`Request` オブジェクトを直接使用する場合と同様に、それを *path operations 関数* パラメーターとして使用し、**FastAPI** に残りの処理を任せることができます。 |
| 77 | + |
| 78 | +それでも、FastAPI で `BackgroundTask` を単独で使用することは可能ですが、コード内でオブジェクトを作成し、それを含むStarlette `Response` を返す必要があります。 |
| 79 | + |
| 80 | +詳細については、<a href="https://www.starlette.io/background/" class="external-link" target="_blank">バックグラウンドタスクに関する Starlette の公式ドキュメント</a>を参照して下さい。 |
| 81 | + |
| 82 | +## 警告 |
| 83 | + |
| 84 | +大量のバックグラウンド計算が必要であり、必ずしも同じプロセスで実行する必要がない場合 (たとえば、メモリや変数などを共有する必要がない場合)、<a href="https://www.celeryproject.org/" class="external-link" target="_blank">Celery</a> のようなより大きな他のツールを使用するとメリットがあるかもしれません。 |
| 85 | + |
| 86 | +これらは、より複雑な構成、RabbitMQ や Redis などのメッセージ/ジョブキューマネージャーを必要とする傾向がありますが、複数のプロセス、特に複数のサーバーでバックグラウンドタスクを実行できます。 |
| 87 | + |
| 88 | +例を確認するには、[Project Generators](../project-generation.md){.internal-link target=_blank} を参照してください。これらにはすべて、Celery が構築済みです。 |
| 89 | + |
| 90 | +ただし、同じ **FastAPI** アプリから変数とオブジェクトにアクセスする必要がある場合、または小さなバックグラウンドタスク (電子メール通知の送信など) を実行する必要がある場合は、単に `BackgroundTasks` を使用できます。 |
| 91 | + |
| 92 | +## まとめ |
| 93 | + |
| 94 | +`BackgroundTasks` をインポートして、*path operations 関数* や依存関係のパラメータに `BackgroundTasks`を使用し、バックグラウンドタスクを追加して下さい。 |
0 commit comments