From a14afc3241782a91f3293f32ad8fc402b917c0a4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 21 Dec 2025 18:13:20 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=90=20Update=20translations=20for=20ja?= =?UTF-8?q?=20(update-outdated)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../docs/advanced/additional-status-codes.md | 34 +- docs/ja/docs/advanced/custom-response.md | 224 ++++++--- docs/ja/docs/advanced/index.md | 24 +- .../path-operation-advanced-configuration.md | 157 +++++- docs/ja/docs/advanced/response-directly.md | 14 +- docs/ja/docs/advanced/websockets.md | 72 ++- docs/ja/docs/benchmarks.md | 36 +- docs/ja/docs/deployment/concepts.md | 90 ++-- docs/ja/docs/deployment/docker.md | 428 ++++++----------- docs/ja/docs/deployment/https.md | 86 ++-- docs/ja/docs/deployment/index.md | 24 +- docs/ja/docs/deployment/server-workers.md | 182 +++---- docs/ja/docs/deployment/versions.md | 104 ++-- docs/ja/docs/environment-variables.md | 115 +++-- docs/ja/docs/how-to/conditional-openapi.md | 12 +- docs/ja/docs/index.md | 447 +++++++++++------- docs/ja/docs/learn/index.md | 4 +- docs/ja/docs/project-generation.md | 102 +--- docs/ja/docs/python-types.md | 366 +++++++++----- docs/ja/docs/tutorial/background-tasks.md | 46 +- docs/ja/docs/tutorial/body-fields.md | 22 +- docs/ja/docs/tutorial/body-multiple-params.md | 63 +-- docs/ja/docs/tutorial/body-nested-models.md | 108 ++--- docs/ja/docs/tutorial/body-updates.md | 38 +- docs/ja/docs/tutorial/body.md | 138 +++--- docs/ja/docs/tutorial/cookie-param-models.md | 25 +- docs/ja/docs/tutorial/cookie-params.md | 24 +- docs/ja/docs/tutorial/cors.md | 42 +- docs/ja/docs/tutorial/debugging.md | 14 +- .../dependencies/classes-as-dependencies.md | 150 +++++- ...pendencies-in-path-operation-decorators.md | 62 ++- .../dependencies/dependencies-with-yield.md | 185 +++++--- docs/ja/docs/tutorial/dependencies/index.md | 128 +++-- .../tutorial/dependencies/sub-dependencies.md | 49 +- docs/ja/docs/tutorial/encoder.md | 10 +- docs/ja/docs/tutorial/extra-data-types.md | 42 +- docs/ja/docs/tutorial/extra-models.md | 90 ++-- docs/ja/docs/tutorial/first-steps.md | 210 ++++---- docs/ja/docs/tutorial/handling-errors.md | 118 ++--- docs/ja/docs/tutorial/header-params.md | 36 +- docs/ja/docs/tutorial/index.md | 90 ++-- docs/ja/docs/tutorial/metadata.md | 105 ++-- docs/ja/docs/tutorial/middleware.md | 47 +- .../tutorial/path-operation-configuration.md | 58 ++- .../path-params-numeric-validations.md | 111 +++-- docs/ja/docs/tutorial/path-params.md | 123 ++--- docs/ja/docs/tutorial/query-param-models.md | 22 +- .../tutorial/query-params-str-validations.md | 360 ++++++++++---- docs/ja/docs/tutorial/query-params.md | 64 +-- .../docs/tutorial/request-forms-and-files.md | 20 +- docs/ja/docs/tutorial/request-forms.md | 24 +- docs/ja/docs/tutorial/response-model.md | 297 ++++++++---- docs/ja/docs/tutorial/response-status-code.md | 40 +- docs/ja/docs/tutorial/schema-extra-example.md | 201 ++++++-- docs/ja/docs/tutorial/security/first-steps.md | 70 +-- .../tutorial/security/get-current-user.md | 49 +- docs/ja/docs/tutorial/security/oauth2-jwt.md | 88 ++-- docs/ja/docs/tutorial/static-files.md | 18 +- docs/ja/docs/tutorial/testing.md | 99 +++- docs/ja/docs/virtual-environments.md | 98 ++-- 60 files changed, 3642 insertions(+), 2463 deletions(-) diff --git a/docs/ja/docs/advanced/additional-status-codes.md b/docs/ja/docs/advanced/additional-status-codes.md index 33457f591..af8e28de0 100644 --- a/docs/ja/docs/advanced/additional-status-codes.md +++ b/docs/ja/docs/advanced/additional-status-codes.md @@ -1,41 +1,41 @@ -# 追加のステータスコード +# 追加のステータスコード { #additional-status-codes } -デフォルトでは、 **FastAPI** は `JSONResponse` を使ってレスポンスを返します。その `JSONResponse` の中には、 *path operation* が返した内容が入ります。 +デフォルトでは、 **FastAPI** は `JSONResponse` を使ってレスポンスを返し、*path operation* から返した内容をその `JSONResponse` の中に入れます。 -それは、デフォルトのステータスコードか、 *path operation* でセットしたものを利用します。 +デフォルトのステータスコード、または *path operation* で設定したステータスコードが使用されます。 -## 追加のステータスコード +## 追加のステータスコード { #additional-status-codes_1 } -メインのステータスコードとは別に、他のステータスコードを返したい場合は、`Response` (`JSONResponse` など) に追加のステータスコードを設定して直接返します。 +メインのステータスコードとは別に追加のステータスコードを返したい場合は、`JSONResponse` のような `Response` を直接返し、追加のステータスコードを直接設定できます。 -例えば、itemを更新し、成功した場合は200 "OK"のHTTPステータスコードを返す *path operation* を作りたいとします。 +たとえば、item を更新でき、成功時に HTTP ステータスコード 200「OK」を返す *path operation* を作りたいとします。 -しかし、新しいitemも許可したいです。itemが存在しない場合は、それらを作成して201 "Created"を返します。 +しかし、新しい item も受け付けたいとします。そして、item が以前存在しなかった場合には作成し、HTTP ステータスコード 201「Created」を返します。 -これを達成するには、 `JSONResponse` をインポートし、 `status_code` を設定して直接内容を返します。 +これを実現するには、`JSONResponse` をインポートし、望む `status_code` を設定して、そこで内容を直接返します。 -{* ../../docs_src/additional_status_codes/tutorial001.py hl[4,25] *} +{* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *} /// warning | 注意 -上記の例のように `Response` を明示的に返す場合、それは直接返されます。 +上の例のように `Response` を直接返すと、それはそのまま返されます。 -モデルなどはシリアライズされません。 +モデルなどでシリアライズされません。 -必要なデータが含まれていることや、値が有効なJSONであること (`JSONResponse` を使う場合) を確認してください。 +必要なデータが含まれていること、そして(`JSONResponse` を使用している場合)値が有効な JSON であることを確認してください。 /// /// note | 技術詳細 -`from starlette.responses import JSONResponse` を利用することもできます。 +`from starlette.responses import JSONResponse` を使うこともできます。 -**FastAPI** は `fastapi.responses` と同じ `starlette.responses` を、開発者の利便性のために提供しています。しかし有効なレスポンスはほとんどStarletteから来ています。 `status` についても同じです。 +**FastAPI** は開発者の利便性のために、`fastapi.responses` と同じ `starlette.responses` を提供しています。しかし、利用可能なレスポンスのほとんどは Starlette から直接提供されています。`status` も同様です。 /// -## OpenAPIとAPIドキュメント +## OpenAPI と API ドキュメント { #openapi-and-api-docs } -ステータスコードとレスポンスを直接返す場合、それらはOpenAPIスキーマ (APIドキュメント) には含まれません。なぜなら、FastAPIは何が返されるのか事前に知ることができないからです。 +追加のステータスコードとレスポンスを直接返す場合、それらは OpenAPI スキーマ(API ドキュメント)には含まれません。FastAPI には、事前に何が返されるかを知る方法がないからです。 -しかし、 [Additional Responses](additional-responses.md){.internal-link target=_blank} を使ってコードの中にドキュメントを書くことができます。 +しかし、[Additional Responses](additional-responses.md){.internal-link target=_blank} を使ってコード内にドキュメント化できます。 diff --git a/docs/ja/docs/advanced/custom-response.md b/docs/ja/docs/advanced/custom-response.md index 1b2cd914d..002d68bc4 100644 --- a/docs/ja/docs/advanced/custom-response.md +++ b/docs/ja/docs/advanced/custom-response.md @@ -1,34 +1,40 @@ -# カスタムレスポンス - HTML、ストリーム、ファイル、その他のレスポンス +# カスタムレスポンス - HTML、ストリーム、ファイル、その他のレスポンス { #custom-response-html-stream-file-others } デフォルトでは、**FastAPI** は `JSONResponse` を使ってレスポンスを返します。 [レスポンスを直接返す](response-directly.md){.internal-link target=_blank}で見たように、 `Response` を直接返すことでこの挙動をオーバーライドできます。 -しかし、`Response` を直接返すと、データは自動的に変換されず、ドキュメントも自動生成されません (例えば、生成されるOpenAPIの一部としてHTTPヘッダー `Content-Type` に特定の「メディアタイプ」を含めるなど) 。 +しかし、`Response` を直接返すと(または `JSONResponse` のような任意のサブクラスを返すと)、データは自動的に変換されず(`response_model` を宣言していても)、ドキュメントも自動生成されません(例えば、生成されるOpenAPIの一部としてHTTPヘッダー `Content-Type` に特定の「メディアタイプ」を含めるなど)。 -しかし、*path operationデコレータ* に、使いたい `Response` を宣言することもできます。 +しかし、`response_class` パラメータを使用して、*パスオペレーションデコレータ* で使用したい `Response`(例: 任意の `Response` サブクラス)を宣言することもできます。 -*path operation関数* から返されるコンテンツは、その `Response` に含まれます。 +*パスオペレーション関数* から返されるコンテンツは、その `Response` に含まれます。 -そしてもし、`Response` が、`JSONResponse` や `UJSONResponse` の場合のようにJSONメディアタイプ (`application/json`) ならば、データは *path operationデコレータ* に宣言したPydantic `response_model` により自動的に変換 (もしくはフィルタ) されます。 +そしてその `Response` が、`JSONResponse` や `UJSONResponse` の場合のようにJSONメディアタイプ(`application/json`)なら、返すデータは *パスオペレーションデコレータ* に宣言した任意のPydantic `response_model` により自動的に変換(およびフィルタ)されます。 /// note | 備考 -メディアタイプを指定せずにレスポンスクラスを利用すると、FastAPIは何もコンテンツがないことを期待します。そのため、生成されるOpenAPIドキュメントにレスポンスフォーマットが記載されません。 +メディアタイプを指定せずにレスポンスクラスを利用すると、FastAPIはレスポンスにコンテンツがないことを期待します。そのため、生成されるOpenAPIドキュメントにレスポンスフォーマットが記載されません。 /// -## `ORJSONResponse` を使う +## `ORJSONResponse` を使う { #use-orjsonresponse } -例えば、パフォーマンスを出したい場合は、`orjson`をインストールし、`ORJSONResponse`をレスポンスとしてセットすることができます。 +例えば、パフォーマンスを絞り出したい場合は、`orjson`をインストールし、レスポンスとして `ORJSONResponse` をセットできます。 -使いたい `Response` クラス (サブクラス) をインポートし、 *path operationデコレータ* に宣言します。 +使いたい `Response` クラス(サブクラス)をインポートし、*パスオペレーションデコレータ* に宣言します。 -{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *} +大きなレスポンスの場合、`Response` を直接返すほうが、辞書を返すよりもはるかに高速です。 + +これは、デフォルトではFastAPIがチュートリアルで説明した同じ[JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}を使って、内部の各アイテムを検査し、JSONとしてシリアライズ可能であることを確認するためです。これにより、例えばデータベースモデルのような**任意のオブジェクト**を返せます。 + +しかし、返そうとしているコンテンツが **JSONでシリアライズ可能**であることが確実なら、それを直接レスポンスクラスに渡して、FastAPIがレスポンスクラスへ渡す前に返却コンテンツを `jsonable_encoder` に通すことで発生する追加のオーバーヘッドを回避できます。 + +{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *} /// info | 情報 -パラメータ `response_class` は、レスポンスの「メディアタイプ」を定義するために利用することもできます。 +パラメータ `response_class` は、レスポンスの「メディアタイプ」を定義するためにも利用されます。 この場合、HTTPヘッダー `Content-Type` には `application/json` がセットされます。 @@ -38,70 +44,70 @@ /// tip | 豆知識 -`ORJSONResponse` は、現在はFastAPIのみで利用可能で、Starletteでは利用できません。 +`ORJSONResponse` はFastAPIでのみ利用可能で、Starletteでは利用できません。 /// -## HTMLレスポンス +## HTMLレスポンス { #html-response } **FastAPI** からHTMLを直接返す場合は、`HTMLResponse` を使います。 * `HTMLResponse` をインポートする。 -* *path operation* のパラメータ `content_type` に `HTMLResponse` を渡す。 +* *パスオペレーションデコレータ* のパラメータ `response_class` に `HTMLResponse` を渡す。 -{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *} +{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *} /// info | 情報 -パラメータ `response_class` は、レスポンスの「メディアタイプ」を定義するために利用されます。 +パラメータ `response_class` は、レスポンスの「メディアタイプ」を定義するためにも利用されます。 この場合、HTTPヘッダー `Content-Type` には `text/html` がセットされます。 -そして、OpenAPIにはそのようにドキュメント化されます。 +そして、OpenAPIにはそのようにドキュメントされます。 /// -### `Response` を返す +### `Response` を返す { #return-a-response } -[レスポンスを直接返す](response-directly.md){.internal-link target=_blank}で見たように、レスポンスを直接返すことで、*path operation* の中でレスポンスをオーバーライドできます。 +[レスポンスを直接返す](response-directly.md){.internal-link target=_blank}で見たように、レスポンスを返すことで、*パスオペレーション* の中でレスポンスを直接オーバーライドすることもできます。 上記と同じ例において、 `HTMLResponse` を返すと、このようになります: -{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *} +{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *} /// warning | 注意 -*path operation関数* から直接返される `Response` は、OpenAPIにドキュメントされず (例えば、 `Content-Type` がドキュメントされない) 、自動的な対話的ドキュメントからも閲覧できません。 +*パスオペレーション関数* から直接返される `Response` は、OpenAPIにドキュメントされず(例えば、`Content-Type` がドキュメントされない)、自動的な対話的ドキュメントでも表示されません。 /// /// info | 情報 -もちろん、実際の `Content-Type` ヘッダーやステータスコードなどは、返された `Response` オブジェクトに由来しています。 +もちろん、実際の `Content-Type` ヘッダーやステータスコードなどは、返された `Response` オブジェクトに由来します。 /// -### OpenAPIドキュメントと `Response` のオーバーライド +### OpenAPIドキュメントと `Response` のオーバーライド { #document-in-openapi-and-override-response } -関数の中でレスポンスをオーバーライドしつつも、OpenAPI に「メディアタイプ」をドキュメント化したいなら、 `response_class` パラメータを使い、 `Response` オブジェクトを返します。 +関数の中でレスポンスをオーバーライドしつつも、OpenAPI に「メディアタイプ」をドキュメント化したいなら、`response_class` パラメータを使用し、かつ `Response` オブジェクトを返せます。 -`response_class` はOpenAPIの *path operation* ドキュメントにのみ使用されますが、 `Response` はそのまま使用されます。 +`response_class` はOpenAPIの*パスオペレーション*のドキュメント化のためにのみ使用され、`Response` はそのまま使用されます。 -#### `HTMLResponse` を直接返す +#### `HTMLResponse` を直接返す { #return-an-htmlresponse-directly } 例えば、このようになります: -{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *} +{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *} -この例では、関数 `generate_html_response()` は、`str` のHTMLを返すのではなく `Response` を生成して返しています。 +この例では、関数 `generate_html_response()` は、`str` のHTMLを返すのではなく、`Response` を生成して返しています。 -`generate_html_response()` を呼び出した結果を返すことにより、**FastAPI** の振る舞いを上書きする `Response` が既に返されています。 +`generate_html_response()` を呼び出した結果を返すことにより、デフォルトの **FastAPI** の挙動をオーバーライドする `Response` をすでに返しています。 -しかし、一方では `response_class` に `HTMLResponse` を渡しているため、 **FastAPI** はOpenAPIや対話的ドキュメントでHTMLとして `text/html` でドキュメント化する方法を知っています。 +しかし、`response_class` にも `HTMLResponse` を渡しているため、**FastAPI** はOpenAPIと対話的ドキュメントで、`text/html` のHTMLとしてどのようにドキュメント化すればよいかを理解できます: -## 利用可能なレスポンス +## 利用可能なレスポンス { #available-responses } 以下が利用可能なレスポンスの一部です。 @@ -111,11 +117,11 @@ `from starlette.responses import HTMLResponse` も利用できます。 -**FastAPI** は開発者の利便性のために `fastapi.responses` として `starlette.responses` と同じものを提供しています。しかし、利用可能なレスポンスのほとんどはStarletteから直接提供されます。 +**FastAPI** は開発者の利便性のために、`starlette.responses` と同じものを `fastapi.responses` として提供しています。しかし、利用可能なレスポンスのほとんどはStarletteから直接提供されます。 /// -### `Response` +### `Response` { #response } メインの `Response` クラスで、他の全てのレスポンスはこれを継承しています。 @@ -128,41 +134,53 @@ * `headers` - 文字列の `dict` 。 * `media_type` - メディアタイプを示す `str` 。例えば `"text/html"` 。 -FastAPI (実際にはStarlette) は自動的にContent-Lengthヘッダーを含みます。また、media_typeに基づいたContent-Typeヘッダーを含み、テキストタイプのためにcharsetを追加します。 +FastAPI(実際にはStarlette)は自動的にContent-Lengthヘッダーを含みます。また、`media_type` に基づいたContent-Typeヘッダーを含み、テキストタイプのためにcharsetを追加します。 -{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} +{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *} -### `HTMLResponse` +### `HTMLResponse` { #htmlresponse } 上で読んだように、テキストやバイトを受け取り、HTMLレスポンスを返します。 -### `PlainTextResponse` +### `PlainTextResponse` { #plaintextresponse } テキストやバイトを受け取り、プレーンテキストのレスポンスを返します。 -{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *} +{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *} -### `JSONResponse` +### `JSONResponse` { #jsonresponse } -データを受け取り、 `application/json` としてエンコードされたレスポンスを返します。 +データを受け取り、`application/json` としてエンコードされたレスポンスを返します。 上で読んだように、**FastAPI** のデフォルトのレスポンスとして利用されます。 -### `ORJSONResponse` +### `ORJSONResponse` { #orjsonresponse } 上で読んだように、`orjson`を使った、高速な代替のJSONレスポンスです。 -### `UJSONResponse` +/// info | 情報 -`ujson`を使った、代替のJSONレスポンスです。 - -/// warning | 注意 - -`ujson` は、いくつかのエッジケースの取り扱いについて、Pythonにビルトインされた実装よりも作りこまれていません。 +これは、例えば `pip install orjson` で `orjson` をインストールする必要があります。 /// -{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *} +### `UJSONResponse` { #ujsonresponse } + +`ujson`を使った、代替のJSONレスポンスです。 + +/// info | 情報 + +これは、例えば `pip install ujson` で `ujson` をインストールする必要があります。 + +/// + +/// warning | 注意 + +`ujson` は、いくつかのエッジケースの取り扱いについて、Pythonにビルトインされた実装ほど注意深くありません。 + +/// + +{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *} /// tip | 豆知識 @@ -170,33 +188,61 @@ FastAPI (実際にはStarlette) は自動的にContent-Lengthヘッダーを含 /// -### `RedirectResponse` +### `RedirectResponse` { #redirectresponse } -HTTPリダイレクトを返します。デフォルトでは307ステータスコード (Temporary Redirect) となります。 +HTTPリダイレクトを返します。デフォルトでは307ステータスコード(Temporary Redirect)となります。 -{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *} +`RedirectResponse` を直接返せます: -### `StreamingResponse` +{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *} -非同期なジェネレータか通常のジェネレータ・イテレータを受け取り、レスポンスボディをストリームします。 +--- -{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *} +または、`response_class` パラメータで使用できます: -#### `StreamingResponse` をファイルライクなオブジェクトとともに使う +{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *} -ファイルライクなオブジェクト (例えば、 `open()` で返されたオブジェクト) がある場合、 `StreamingResponse` に含めて返すことができます。 +その場合、*パスオペレーション*関数からURLを直接返せます。 -これにはクラウドストレージとの連携や映像処理など、多くのライブラリが含まれています。 +この場合に使用される `status_code` は `RedirectResponse` のデフォルトである `307` になります。 -{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *} +--- + +また、`status_code` パラメータを `response_class` パラメータと組み合わせて使うこともできます: + +{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *} + +### `StreamingResponse` { #streamingresponse } + +非同期ジェネレータ、または通常のジェネレータ/イテレータを受け取り、レスポンスボディをストリームします。 + +{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *} + +#### ファイルライクオブジェクトで `StreamingResponse` を使う { #using-streamingresponse-with-file-like-objects } + +file-like オブジェクト(例: `open()` で返されるオブジェクト)がある場合、そのfile-likeオブジェクトを反復処理するジェネレータ関数を作れます。 + +そうすれば、最初にすべてをメモリへ読み込む必要はなく、そのジェネレータ関数を `StreamingResponse` に渡して返せます。 + +これにはクラウドストレージとの連携、映像処理など、多くのライブラリが含まれます。 + +{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *} + +1. これはジェネレータ関数です。内部に `yield` 文を含むため「ジェネレータ関数」です。 +2. `with` ブロックを使うことで、ジェネレータ関数が終わった後(つまりレスポンスの送信が完了した後)にfile-likeオブジェクトが確実にクローズされるようにします。 +3. この `yield from` は、`file_like` という名前のものを反復処理するように関数へ指示します。そして反復された各パートについて、そのパートをこのジェネレータ関数(`iterfile`)から来たものとして `yield` します。 + + つまり、内部的に「生成」の作業を別のものへ移譲するジェネレータ関数です。 + + このようにすることで `with` ブロックに入れられ、完了後にfile-likeオブジェクトが確実にクローズされます。 /// tip | 豆知識 -ここでは `async` や `await` をサポートしていない標準の `open()` を使っているので、通常の `def` でpath operationを宣言していることに注意してください。 +ここでは `async` と `await` をサポートしていない標準の `open()` を使っているため、通常の `def` でパスオペレーションを宣言している点に注意してください。 /// -### `FileResponse` +### `FileResponse` { #fileresponse } レスポンスとしてファイルを非同期的にストリームします。 @@ -204,29 +250,63 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス * `path` - ストリームするファイルのファイルパス。 * `headers` - 含めたい任意のカスタムヘッダーの辞書。 -* `media_type` - メディアタイプを示す文字列。セットされなかった場合は、ファイル名やパスからメディアタイプが推察されます。 -* `filename` - セットされた場合、レスポンスの `Content-Disposition` に含まれます。 +* `media_type` - メディアタイプを示す文字列。未設定の場合、ファイル名やパスからメディアタイプが推測されます。 +* `filename` - 設定した場合、レスポンスの `Content-Disposition` に含まれます。 -ファイルレスポンスには、適切な `Content-Length` 、 `Last-Modified` 、 `ETag` ヘッダーが含まれます。 +ファイルレスポンスには、適切な `Content-Length`、`Last-Modified`、`ETag` ヘッダーが含まれます。 -{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *} +{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *} -## デフォルトレスポンスクラス +`response_class` パラメータを使うこともできます: -**FastAPI** クラスのインスタンスか `APIRouter` を生成するときに、デフォルトのレスポンスクラスを指定できます。 +{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *} -定義するためのパラメータは、 `default_response_class` です。 +この場合、*パスオペレーション*関数からファイルパスを直接返せます。 -以下の例では、 **FastAPI** は、全ての *path operation* で `JSONResponse` の代わりに `ORJSONResponse` をデフォルトとして利用します。 +## カスタムレスポンスクラス { #custom-response-class } -{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *} +`Response` を継承した独自のカスタムレスポンスクラスを作成して利用できます。 + +例えば、`orjson`を使いたいが、同梱の `ORJSONResponse` クラスで使われていないカスタム設定も使いたいとします。 + +例えば、インデントされ整形されたJSONを返したいので、orjsonオプション `orjson.OPT_INDENT_2` を使いたいとします。 + +`CustomORJSONResponse` を作れます。主に必要なのは、コンテンツを `bytes` として返す `Response.render(content)` メソッドを作ることです: + +{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *} + +これまでは次のように返していたものが: + +```json +{"message": "Hello World"} +``` + +...このレスポンスでは次のように返されます: + +```json +{ + "message": "Hello World" +} +``` + +もちろん、JSONの整形よりも、これを活用するもっと良い方法が見つかるはずです。 😉 + +## デフォルトレスポンスクラス { #default-response-class } + +**FastAPI** クラスのインスタンス、または `APIRouter` を作成する際に、デフォルトで使用するレスポンスクラスを指定できます。 + +これを定義するパラメータは `default_response_class` です。 + +以下の例では、**FastAPI** はすべての*パスオペレーション*で、`JSONResponse` の代わりに `ORJSONResponse` をデフォルトとして使います。 + +{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *} /// tip | 豆知識 -前に見たように、 *path operation* の中で `response_class` をオーバーライドできます。 +これまでと同様に、*パスオペレーション*で `response_class` をオーバーライドできます。 /// -## その他のドキュメント +## その他のドキュメント { #additional-documentation } -また、OpenAPIでは `responses` を使ってメディアタイプやその他の詳細を宣言することもできます: [Additional Responses in OpenAPI](additional-responses.md){.internal-link target=_blank} +OpenAPIでは `responses` を使ってメディアタイプやその他の詳細を宣言することもできます: [Additional Responses in OpenAPI](additional-responses.md){.internal-link target=_blank}。 diff --git a/docs/ja/docs/advanced/index.md b/docs/ja/docs/advanced/index.md index 22eaf6eb8..1d0f7566c 100644 --- a/docs/ja/docs/advanced/index.md +++ b/docs/ja/docs/advanced/index.md @@ -1,27 +1,21 @@ -# 高度なユーザーガイド +# 高度なユーザーガイド { #advanced-user-guide } -## さらなる機能 +## さらなる機能 { #additional-features } -[チュートリアル - ユーザーガイド](../tutorial/index.md){.internal-link target=_blank}により、**FastAPI**の主要な機能は十分に理解できたことでしょう。 +メインの[チュートリアル - ユーザーガイド](../tutorial/index.md){.internal-link target=_blank}だけで、**FastAPI**の主要な機能を一通り把握するには十分なはずです。 -以降のセクションでは、チュートリアルでは説明しきれなかったオプションや設定、および機能について説明します。 +以降のセクションでは、その他のオプション、設定、追加機能を見ていきます。 /// tip | 豆知識 -以降のセクションは、 **必ずしも"応用編"ではありません**。 +以降のセクションは、**必ずしも「高度」ではありません**。 -ユースケースによっては、その中から解決策を見つけられるかもしれません。 +また、あなたのユースケースに対する解決策が、その中のどれかにある可能性もあります。 /// -## 先にチュートリアルを読む +## 先にチュートリアルを読む { #read-the-tutorial-first } -[チュートリアル - ユーザーガイド](../tutorial/index.md){.internal-link target=_blank}の知識があれば、**FastAPI**の主要な機能を利用することができます。 +メインの[チュートリアル - ユーザーガイド](../tutorial/index.md){.internal-link target=_blank}で得た知識があれば、**FastAPI**の機能の多くは引き続き利用できます。 -以降のセクションは、すでにチュートリアルを読んで、その主要なアイデアを理解できていることを前提としています。 - -## テスト駆動開発のコース - -このセクションの内容を補完するために脱初心者用コースを受けたい場合は、**TestDriven.io**による、Test-Driven Development with FastAPI and Dockerを確認するのがよいかもしれません。 - -現在、このコースで得られた利益の10%が**FastAPI**の開発のために寄付されています。🎉 😄 +また、以降のセクションでは、すでにそれを読んでいて、主要な考え方を理解していることを前提としています。 diff --git a/docs/ja/docs/advanced/path-operation-advanced-configuration.md b/docs/ja/docs/advanced/path-operation-advanced-configuration.md index 05188d5b2..a78c3cb02 100644 --- a/docs/ja/docs/advanced/path-operation-advanced-configuration.md +++ b/docs/ja/docs/advanced/path-operation-advanced-configuration.md @@ -1,30 +1,30 @@ -# Path Operationの高度な設定 +# Path Operationの高度な設定 { #path-operation-advanced-configuration } -## OpenAPI operationId +## OpenAPI operationId { #openapi-operationid } /// warning | 注意 -あなたがOpenAPIの「エキスパート」でなければ、これは必要ないかもしれません。 +OpenAPIの「エキスパート」でなければ、これはおそらく必要ありません。 /// *path operation* で `operation_id` パラメータを利用することで、OpenAPIの `operationId` を設定できます。 -`operation_id` は各オペレーションで一意にする必要があります。 +各オペレーションで一意になるようにする必要があります。 -{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *} -### *path operation関数* の名前をoperationIdとして使用する +### *path operation関数* の名前をoperationIdとして使用する { #using-the-path-operation-function-name-as-the-operationid } -APIの関数名を `operationId` として利用したい場合、すべてのAPIの関数をイテレーションし、各 *path operation* の `operationId` を `APIRoute.name` で上書きすれば可能です。 +APIの関数名を `operationId` として利用したい場合、すべてのAPI関数をイテレーションし、各 *path operation* の `operation_id` を `APIRoute.name` で上書きすれば可能です。 -そうする場合は、すべての *path operation* を追加した後に行う必要があります。 +すべての *path operation* を追加した後に行うべきです。 -{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2,12:21,24] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *} /// tip | 豆知識 -`app.openapi()` を手動でコールする場合、その前に`operationId`を更新する必要があります。 +`app.openapi()` を手動で呼び出す場合、その前に `operationId` を更新するべきです。 /// @@ -32,22 +32,141 @@ APIの関数名を `operationId` として利用したい場合、すべてのAP この方法をとる場合、各 *path operation関数* が一意な名前である必要があります。 -それらが異なるモジュール (Pythonファイル) にあるとしてもです。 +異なるモジュール(Pythonファイル)にある場合でも同様です。 /// -## OpenAPIから除外する +## OpenAPIから除外する { #exclude-from-openapi } -生成されるOpenAPIスキーマ (つまり、自動ドキュメント生成の仕組み) から *path operation* を除外するには、 `include_in_schema` パラメータを `False` にします。 +生成されるOpenAPIスキーマ(つまり、自動ドキュメント生成の仕組み)から *path operation* を除外するには、`include_in_schema` パラメータを使用して `False` に設定します。 -{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *} -## docstringによる説明の高度な設定 +## docstringによる説明の高度な設定 { #advanced-description-from-docstring } -*path operation関数* のdocstringからOpenAPIに使用する行を制限することができます。 +*path operation関数* のdocstringからOpenAPIに使用する行を制限できます。 -`\f` (「書式送り (Form Feed)」のエスケープ文字) を付与することで、**FastAPI** はOpenAPIに使用される出力をその箇所までに制限します。 +`\f`(エスケープされた「書式送り(form feed)」文字)を追加すると、**FastAPI** はその地点でOpenAPIに使用される出力を切り詰めます。 -ドキュメントには表示されませんが、他のツール (例えばSphinx) では残りの部分を利用できるでしょう。 +ドキュメントには表示されませんが、他のツール(Sphinxなど)は残りの部分を利用できます。 -{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *} + +## 追加レスポンス { #additional-responses } + +*path operation* に対して `response_model` と `status_code` を宣言する方法はすでに見たことがあるでしょう。 + +それにより、*path operation* のメインのレスポンスに関するメタデータが定義されます。 + +追加のレスポンスについても、モデルやステータスコードなどとともに宣言できます。 + +これについてはドキュメントに章全体があります。 [OpenAPIの追加レスポンス](additional-responses.md){.internal-link target=_blank} で読めます。 + +## OpenAPI Extra { #openapi-extra } + +アプリケーションで *path operation* を宣言すると、**FastAPI** はOpenAPIスキーマに含めるために、その *path operation* に関連するメタデータを自動的に生成します。 + +/// note | 技術詳細 + +OpenAPI仕様では Operation Object と呼ばれています。 + +/// + +これには *path operation* に関するすべての情報が含まれ、自動ドキュメントを生成するために使われます。 + +`tags`、`parameters`、`requestBody`、`responses` などが含まれます。 + +この *path operation* 固有のOpenAPIスキーマは通常 **FastAPI** により自動生成されますが、拡張することもできます。 + +/// tip | 豆知識 + +これは低レベルな拡張ポイントです。 + +追加レスポンスを宣言するだけなら、より便利な方法として [OpenAPIの追加レスポンス](additional-responses.md){.internal-link target=_blank} を使うことができます。 + +/// + +`openapi_extra` パラメータを使って、*path operation* のOpenAPIスキーマを拡張できます。 + +### OpenAPI Extensions { #openapi-extensions } + +この `openapi_extra` は、例えば [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) を宣言するのに役立ちます。 + +{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *} + +自動APIドキュメントを開くと、その拡張は特定の *path operation* の下部に表示されます。 + + + +そして(APIの `/openapi.json` にある)生成されたOpenAPIを見ると、その拡張も特定の *path operation* の一部として確認できます。 + +```JSON hl_lines="22" +{ + "openapi": "3.1.0", + "info": { + "title": "FastAPI", + "version": "0.1.0" + }, + "paths": { + "/items/": { + "get": { + "summary": "Read Items", + "operationId": "read_items_items__get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "x-aperture-labs-portal": "blue" + } + } + } +} +``` + +### カスタムOpenAPI *path operation* スキーマ { #custom-openapi-path-operation-schema } + +`openapi_extra` 内の辞書は、*path operation* 用に自動生成されたOpenAPIスキーマと深くマージされます。 + +そのため、自動生成されたスキーマに追加データを加えることができます。 + +例えば、Pydanticを使ったFastAPIの自動機能を使わずに独自のコードでリクエストを読み取り・検証することを選べますが、それでもOpenAPIスキーマでリクエストを定義したい場合があります。 + +それは `openapi_extra` で行えます。 + +{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *} + +この例では、Pydanticモデルを一切宣言していません。実際、リクエストボディはJSONとして parsed されず、直接 `bytes` として読み取られます。そして `magic_data_reader()` 関数が、何らかの方法でそれをパースする責務を担います。 + +それでも、リクエストボディに期待されるスキーマを宣言できます。 + +### カスタムOpenAPI content type { #custom-openapi-content-type } + +同じトリックを使って、PydanticモデルでJSON Schemaを定義し、それを *path operation* 用のカスタムOpenAPIスキーマセクションに含めることができます。 + +また、リクエスト内のデータ型がJSONでない場合でもこれを行えます。 + +例えばこのアプリケーションでは、PydanticモデルからJSON Schemaを抽出するFastAPIの統合機能や、JSONの自動バリデーションを使っていません。実際、リクエストのcontent typeをJSONではなくYAMLとして宣言しています。 + +{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *} + +それでも、デフォルトの統合機能を使っていないにもかかわらず、YAMLで受け取りたいデータのために、Pydanticモデルを使って手動でJSON Schemaを生成しています。 + +そしてリクエストを直接使い、ボディを `bytes` として抽出します。これは、FastAPIがリクエストペイロードをJSONとしてパースしようとすらしないことを意味します。 + +その後、コード内でそのYAMLコンテンツを直接パースし、さらに同じPydanticモデルを使ってYAMLコンテンツを検証しています。 + +{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *} + +/// tip | 豆知識 + +ここでは同じPydanticモデルを再利用しています。 + +ただし同様に、別の方法で検証することもできます。 + +/// diff --git a/docs/ja/docs/advanced/response-directly.md b/docs/ja/docs/advanced/response-directly.md index 42412d507..7e83b9ffb 100644 --- a/docs/ja/docs/advanced/response-directly.md +++ b/docs/ja/docs/advanced/response-directly.md @@ -1,4 +1,4 @@ -# レスポンスを直接返す +# レスポンスを直接返す { #return-a-response-directly } **FastAPI** の *path operation* では、通常は任意のデータを返すことができます: 例えば、 `dict`、`list`、Pydanticモデル、データベースモデルなどです。 @@ -10,7 +10,7 @@ これは例えば、カスタムヘッダーやcookieを返すときに便利です。 -## `Response` を返す +## `Response` を返す { #return-a-response } 実際は、`Response` やそのサブクラスを返すことができます。 @@ -26,7 +26,7 @@ これは多くの柔軟性を提供します。任意のデータ型を返したり、任意のデータ宣言やバリデーションをオーバーライドできます。 -## `jsonable_encoder` を `Response` の中で使う +## `jsonable_encoder` を `Response` の中で使う { #using-the-jsonable-encoder-in-a-response } **FastAPI** はあなたが返す `Response` に対して何も変更を加えないので、コンテンツが準備できていることを保証しなければなりません。 @@ -34,7 +34,7 @@ このようなケースでは、レスポンスにデータを含める前に `jsonable_encoder` を使ってデータを変換できます。 -{* ../../docs_src/response_directly/tutorial001.py hl[6:7,21:22] *} +{* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *} /// note | 技術詳細 @@ -44,7 +44,7 @@ /// -## カスタム `Response` を返す +## カスタム `Response` を返す { #returning-a-custom-response } 上記の例では必要な部分を全て示していますが、あまり便利ではありません。`item` を直接返すことができるし、**FastAPI** はそれを `dict` に変換して `JSONResponse` に含めてくれるなど。すべて、デフォルトの動作です。 @@ -54,9 +54,9 @@ XMLを文字列にし、`Response` に含め、それを返します。 -{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} +{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *} -## 備考 +## 備考 { #notes } `Response` を直接返す場合、バリデーションや、変換 (シリアライズ) や、自動ドキュメントは行われません。 diff --git a/docs/ja/docs/advanced/websockets.md b/docs/ja/docs/advanced/websockets.md index 2517530ab..6c68c9f0b 100644 --- a/docs/ja/docs/advanced/websockets.md +++ b/docs/ja/docs/advanced/websockets.md @@ -1,10 +1,10 @@ -# WebSocket +# WebSockets { #websockets } -**FastAPI**でWebSocketが使用できます。 +**FastAPI**でWebSocketsが使用できます。 -## `WebSockets`のインストール +## `websockets`のインストール { #install-websockets } -まず `WebSockets`のインストールが必要です。 +[仮想環境](../virtual-environments.md){.internal-link target=_blank}を作成し、それを有効化してから、「WebSocket」プロトコルを簡単に使えるようにするPythonライブラリの`websockets`をインストールしてください。
@@ -16,13 +16,13 @@ $ pip install websockets
-## WebSocket クライアント +## WebSockets クライアント { #websockets-client } -### 本番環境 +### 本番環境 { #in-production } 本番環境では、React、Vue.js、Angularなどの最新のフレームワークで作成されたフロントエンドを使用しているでしょう。 -そして、バックエンドとWebSocketを使用して通信するために、おそらくフロントエンドのユーティリティを使用することになるでしょう。 +そして、バックエンドとWebSocketsを使用して通信するために、おそらくフロントエンドのユーティリティを使用することになるでしょう。 または、ネイティブコードでWebSocketバックエンドと直接通信するネイティブモバイルアプリケーションがあるかもしれません。 @@ -30,21 +30,21 @@ $ pip install websockets --- -ただし、この例では非常にシンプルなHTML文書といくつかのJavaScriptを、すべてソースコードの中に入れて使用することにします。 +ただし、この例では非常にシンプルなHTML文書といくつかのJavaScriptを、すべて長い文字列の中に入れて使用することにします。 もちろん、これは最適な方法ではありませんし、本番環境で使うことはないでしょう。 本番環境では、上記の方法のいずれかの選択肢を採用することになるでしょう。 -しかし、これはWebSocketのサーバーサイドに焦点を当て、実用的な例を示す最も簡単な方法です。 +しかし、これはWebSocketsのサーバーサイドに焦点を当て、動作する例を示す最も簡単な方法です。 -{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *} +{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *} -## `websocket` を作成する +## `websocket` を作成する { #create-a-websocket } **FastAPI** アプリケーションで、`websocket` を作成します。 -{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *} +{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *} /// note | 技術詳細 @@ -54,22 +54,22 @@ $ pip install websockets /// -## メッセージの送受信 +## メッセージを待機して送信する { #await-for-messages-and-send-messages } -WebSocketルートでは、 `await` を使ってメッセージの送受信ができます。 +WebSocketルートでは、メッセージを待機して送信するために `await` を使用できます。 -{* ../../docs_src/websockets/tutorial001.py hl[48:52] *} +{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *} バイナリやテキストデータ、JSONデータを送受信できます。 -## 試してみる +## 試してみる { #try-it } -ファイル名が `main.py` である場合、以下の方法でアプリケーションを実行します。 +ファイル名が `main.py` である場合、以下でアプリケーションを実行します。
```console -$ uvicorn main:app --reload +$ fastapi dev main.py INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` @@ -86,7 +86,7 @@ $ uvicorn main:app --reload -そして、 WebSocketを使用した**FastAPI**アプリケーションが応答します。 +そして、 WebSocketsを使用した**FastAPI**アプリケーションが応答します。 @@ -96,7 +96,7 @@ $ uvicorn main:app --reload そして、これらの通信はすべて同じWebSocket接続を使用します。 -## 依存関係 +## `Depends` などの使用 { #using-depends-and-others } WebSocketエンドポイントでは、`fastapi` から以下をインポートして使用できます。 @@ -107,28 +107,26 @@ WebSocketエンドポイントでは、`fastapi` から以下をインポート * `Path` * `Query` -これらは、他のFastAPI エンドポイント/*path operation* の場合と同じように機能します。 +これらは、他のFastAPI エンドポイント/*path operations* の場合と同じように機能します。 -{* ../../docs_src/websockets/tutorial002.py hl[58:65,68:83] *} +{* ../../docs_src/websockets/tutorial002_an_py310.py hl[68:69,82] *} /// info | 情報 -WebSocket で `HTTPException` を発生させることはあまり意味がありません。したがって、WebSocketの接続を直接閉じる方がよいでしょう。 +これはWebSocketであるため、`HTTPException` を発生させることはあまり意味がありません。代わりに `WebSocketException` を発生させます。 クロージングコードは、仕様で定義された有効なコードの中から使用することができます。 -将来的には、どこからでも `raise` できる `WebSocketException` が用意され、専用の例外ハンドラを追加できるようになる予定です。これは、Starlette の PR #527 に依存するものです。 - /// -### 依存関係を用いてWebSocketsを試してみる +### 依存関係を用いてWebSocketsを試してみる { #try-the-websockets-with-dependencies } -ファイル名が `main.py` である場合、以下の方法でアプリケーションを実行します。 +ファイル名が `main.py` である場合、以下でアプリケーションを実行します。
```console -$ uvicorn main:app --reload +$ fastapi dev main.py INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` @@ -137,14 +135,14 @@ $ uvicorn main:app --reload ブラウザで http://127.0.0.1:8000 を開きます。 -クライアントが設定できる項目は以下の通りです。 +そこで、以下を設定できます。 * パスで使用される「Item ID」 * クエリパラメータとして使用される「Token」 /// tip | 豆知識 -クエリ `token` は依存パッケージによって処理されることに注意してください。 +クエリ `token` は依存関係によって処理されることに注意してください。 /// @@ -152,11 +150,11 @@ $ uvicorn main:app --reload -## 切断や複数クライアントへの対応 +## 切断や複数クライアントの処理 { #handling-disconnections-and-multiple-clients } WebSocket接続が閉じられると、 `await websocket.receive_text()` は例外 `WebSocketDisconnect` を発生させ、この例のようにキャッチして処理することができます。 -{* ../../docs_src/websockets/tutorial003.py hl[81:83] *} +{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *} 試してみるには、 @@ -174,15 +172,15 @@ Client #1596980209979 left the chat 上記のアプリは、複数の WebSocket 接続に対してメッセージを処理し、ブロードキャストする方法を示すための最小限のシンプルな例です。 -しかし、すべての接続がメモリ内の単一のリストで処理されるため、プロセスの実行中にのみ機能し、単一のプロセスでのみ機能することに注意してください。 +しかし、すべてがメモリ内の単一のリストで処理されるため、プロセスの実行中にのみ機能し、単一のプロセスでのみ機能することに注意してください。 -もしFastAPIと簡単に統合できて、RedisやPostgreSQLなどでサポートされている、より堅牢なものが必要なら、encode/broadcaster を確認してください。 +FastAPIと簡単に統合できて、RedisやPostgreSQLなどでサポートされている、より堅牢なものが必要なら、encode/broadcaster を確認してください。 /// -## その他のドキュメント +## 詳細情報 { #more-info } オプションの詳細については、Starletteのドキュメントを確認してください。 -* `WebSocket` クラス -* クラスベースのWebSocket処理 +* `WebSocket` クラス. +* クラスベースのWebSocket処理. diff --git a/docs/ja/docs/benchmarks.md b/docs/ja/docs/benchmarks.md index 966d199c5..fbfba2e63 100644 --- a/docs/ja/docs/benchmarks.md +++ b/docs/ja/docs/benchmarks.md @@ -1,34 +1,34 @@ -# ベンチマーク +# ベンチマーク { #benchmarks } -TechEmpowerの独立したベンチマークでは、Uvicornの下で動作する**FastAPI**アプリケーションは、利用可能な最速のPythonフレームワークの1つであり、下回っているのはStarletteとUvicorn自体 (FastAPIによって内部で使用される) のみだと示されています。 +TechEmpowerの独立したベンチマークでは、Uvicornの下で動作する**FastAPI**アプリケーションは、利用可能な最速のPythonフレームワークの1つであり、下回っているのはStarletteとUvicorn自体(FastAPIによって内部で使用される)のみだと示されています。 ただし、ベンチマークを確認し、比較する際には下記の内容に気を付けてください。 -## ベンチマークと速度 +## ベンチマークと速度 { #benchmarks-and-speed } -ベンチマークを確認する時、異なるツールを同等なものと比較するのが一般的です。 +ベンチマークを確認する時、異なるタイプの複数のツールが同等のものとして比較されているのを目にするのが一般的です。 -具体的には、Uvicorn、Starlette、FastAPIを (他の多くのツールと) 比較しました。 +具体的には、Uvicorn、Starlette、FastAPIを(他の多くのツールの中で)まとめて比較しているのを目にすることがあります。 ツールで解決する問題がシンプルなほど、パフォーマンスが向上します。また、ほとんどのベンチマークは、ツールから提供される追加機能をテストしていません。 階層関係はこのようになります。 * **Uvicorn**: ASGIサーバー - * **Starlette**: (Uvicornを使用) WEBマイクロフレームワーク - * **FastAPI**: (Starletteを使用) データバリデーションなどの、APIを構築する追加機能を備えたAPIマイクロフレームワーク + * **Starlette**: (Uvicornを使用)webマイクロフレームワーク + * **FastAPI**: (Starletteを使用)データバリデーションなど、APIを構築するためのいくつかの追加機能を備えたAPIマイクロフレームワーク * **Uvicorn**: - * サーバー自体に余分なコードが少ないので、最高のパフォーマンスが得られます。 - * Uvicornにアプリケーションを直接書くことはできません。つまり、あなたのコードには、Starlette (または** FastAPI **) が提供するコードを、多かれ少なかれ含める必要があります。そうすると、最終的なアプリケーションは、フレームワークを使用してアプリのコードとバグを最小限に抑えた場合と同じオーバーヘッドになります。 - * もしUvicornを比較する場合は、Daphne、Hypercorn、uWSGIなどのアプリケーションサーバーと比較してください。 + * サーバー自体以外に余分なコードがあまりないため、最高のパフォーマンスになります。 + * Uvicornにアプリケーションを直接書くことはないでしょう。それは、あなたのコードに、Starlette(または**FastAPI**)が提供するコードを、少なくとも多かれ少なかれ含める必要があるということです。そして、もしそうした場合、最終的なアプリケーションは、フレームワークを使用してアプリのコードとバグを最小限に抑えた場合と同じオーバーヘッドになります。 + * Uvicornを比較する場合は、Daphne、Hypercorn、uWSGIなどのアプリケーションサーバーと比較してください。 * **Starlette**: - * Uvicornに次ぐ性能を持つでしょう。実際、StarletteはUvicornを使用しています。だから、より多くのコードを実行する必要があり、Uvicornよりも「遅く」なってしまうだけなのです。 - * しかし、パスベースのルーティングなどのシンプルなWEBアプリケーションを構築する機能を提供します。 - * もしStarletteを比較する場合は、Sanic、Flask、DjangoなどのWEBフレームワーク (もしくはマイクロフレームワーク) と比較してください。 + * Uvicornに次ぐ性能になるでしょう。実際、Starletteは実行にUvicornを使用しています。そのため、おそらく、より多くのコードを実行しなければならない分だけ、Uvicornより「遅く」なるだけです。 + * しかし、パスに基づくルーティングなどを使って、シンプルなwebアプリケーションを構築するためのツールを提供します。 + * Starletteを比較する場合は、Sanic、Flask、Djangoなどのwebフレームワーク(またはマイクロフレームワーク)と比較してください。 * **FastAPI**: - * StarletteがUvicornを使っているのと同じで、**FastAPI**はStarletteを使っており、それより速くできません。 - * FastAPIはStarletteの上にさらに多くの機能を提供します。データの検証やシリアライゼーションなど、APIを構築する際に常に必要な機能です。また、それを使用することで、自動ドキュメント化を無料で取得できます (ドキュメントは実行中のアプリケーションにオーバーヘッドを追加せず、起動時に生成されます) 。 - * FastAPIを使用せず、直接Starlette (またはSanic, Flask, Responderなど) を使用した場合、データの検証とシリアライズをすべて自分で実装する必要があります。そのため、最終的なアプリケーションはFastAPIを使用して構築した場合と同じオーバーヘッドが発生します。そして、多くの場合、このデータ検証とシリアライズは、アプリケーションのコードの中で最大の記述量になります。 - * FastAPIを使用することで、開発時間、バグ、コード行数を節約でき、使用しない場合 (あなたが全ての機能を実装し直した場合) と同じかそれ以上のパフォーマンスを得られます。 - * もしFastAPIを比較する場合は、Flask-apispec、NestJS、Moltenなどのデータ検証や、シリアライズの機能を提供するWEBフレームワーク (や機能のセット) と比較してください。これらはデータの自動検証や、シリアライズ、ドキュメント化が統合されたフレームワークです。 + * StarletteがUvicornを使用しており、それより速くできないのと同じように、**FastAPI**はStarletteを使用しているため、それより速くできません。 + * FastAPIはStarletteの上に、より多くの機能を提供します。データバリデーションやシリアライゼーションのように、APIを構築する際にほとんど常に必要な機能です。また、それを使用することで、自動ドキュメント化を無料で利用できます(自動ドキュメントは実行中のアプリケーションにオーバーヘッドを追加せず、起動時に生成されます)。 + * FastAPIを使用せず、Starletteを直接(またはSanic、Flask、Responderなど別のツールを)使用した場合、データバリデーションとシリアライゼーションをすべて自分で実装する必要があります。そのため、最終的なアプリケーションはFastAPIを使用して構築した場合と同じオーバーヘッドが発生します。そして多くの場合、このデータバリデーションとシリアライゼーションは、アプリケーションで書かれるコードの大部分になります。 + * そのため、FastAPIを使用することで、開発時間、バグ、コード行数を節約でき、使用しない場合(あなたがそれをすべて自分のコードで実装する必要があるため)と比べて、同じパフォーマンス(またはそれ以上)を得られる可能性があります。 + * FastAPIを比較する場合は、Flask-apispec、NestJS、Moltenなど、データバリデーション、シリアライゼーション、ドキュメント化を提供するwebアプリケーションフレームワーク(またはツール群)と比較してください。自動データバリデーション、シリアライゼーション、ドキュメント化が統合されたフレームワークです。 diff --git a/docs/ja/docs/deployment/concepts.md b/docs/ja/docs/deployment/concepts.md index a0d4fb35b..aaecf313a 100644 --- a/docs/ja/docs/deployment/concepts.md +++ b/docs/ja/docs/deployment/concepts.md @@ -1,4 +1,4 @@ -# デプロイメントのコンセプト +# デプロイメントのコンセプト { #deployments-concepts } **FastAPI**を用いたアプリケーションをデプロイするとき、もしくはどのようなタイプのWeb APIであっても、おそらく気になるコンセプトがいくつかあります。 @@ -10,12 +10,12 @@ * 起動時の実行 * 再起動 * レプリケーション(実行中のプロセス数) -* メモリー +* メモリ * 開始前の事前のステップ これらが**デプロイメント**にどのような影響を与えるかを見ていきましょう。 -最終的な目的は、**安全な方法で**APIクライアントに**サービスを提供**し、**中断を回避**するだけでなく、**計算リソース**(例えばリモートサーバー/仮想マシン)を可能な限り効率的に使用することです。🚀 +最終的な目的は、**安全な方法で**APIクライアントに**サービスを提供**し、**中断を回避**するだけでなく、**計算リソース**(例えばリモートサーバー/仮想マシン)を可能な限り効率的に使用することです。 🚀 この章では前述した**コンセプト**についてそれぞれ説明します。 @@ -27,16 +27,16 @@ しかし、今はこれらの重要な**コンセプトに基づくアイデア**を確認しましょう。これらのコンセプトは、他のどのタイプのWeb APIにも当てはまります。💡 -## セキュリティ - HTTPS +## セキュリティ - HTTPS { #security-https } [前チャプターのHTTPSについて](https.md){.internal-link target=_blank}では、HTTPSがどのようにAPIを暗号化するのかについて学びました。 通常、アプリケーションサーバにとって**外部の**コンポーネントである**TLS Termination Proxy**によって提供されることが一般的です。このプロキシは通信の暗号化を担当します。 -さらにセキュアな通信において、HTTPS証明書の定期的な更新を行いますが、これはTLS Termination Proxyと同じコンポーネントが担当することもあれば、別のコンポーネントが担当することもあります。 +さらに、HTTPS証明書の更新を担当するものが必要で、同じコンポーネントが担当することもあれば、別のコンポーネントが担当することもあります。 -### HTTPS 用ツールの例 +### HTTPS 用ツールの例 { #example-tools-for-https } TLS Termination Proxyとして使用できるツールには以下のようなものがあります: * Traefik @@ -59,11 +59,11 @@ TLS Termination Proxyとして使用できるツールには以下のような 次に考慮すべきコンセプトは、実際のAPIを実行するプログラム(例:Uvicorn)に関連するものすべてです。 -## プログラム と プロセス +## プログラム と プロセス { #program-and-process } 私たちは「**プロセス**」という言葉についてたくさん話すので、その意味や「**プログラム**」という言葉との違いを明確にしておくと便利です。 -### プログラムとは何か +### プログラムとは何か { #what-is-a-program } **プログラム**という言葉は、一般的にいろいろなものを表現するのに使われます: @@ -71,7 +71,7 @@ TLS Termination Proxyとして使用できるツールには以下のような * OSによって実行することができるファイル(例: `python`, `python.exe` or `uvicorn`) * OS上で**実行**している間、CPUを使用し、メモリ上に何かを保存する特定のプログラム(**プロセス**とも呼ばれる) -### プロセスとは何か +### プロセスとは何か { #what-is-a-process } **プロセス**という言葉は通常、より具体的な意味で使われ、OSで実行されているものだけを指します(先ほどの最後の説明のように): @@ -92,27 +92,29 @@ OSの「タスク・マネージャー」や「システム・モニター」( さて、**プロセス**と**プログラム**という用語の違いを確認したところで、デプロイメントについて話を続けます。 -## 起動時の実行 +## 起動時の実行 { #running-on-startup } ほとんどの場合、Web APIを作成するときは、クライアントがいつでもアクセスできるように、**常に**中断されることなく**実行される**ことを望みます。もちろん、特定の状況でのみ実行させたい特別な理由がある場合は別ですが、その時間のほとんどは、常に実行され、**利用可能**であることを望みます。 -### リモートサーバー上での実行 +### リモートサーバー上での実行 { #in-a-remote-server } -リモートサーバー(クラウドサーバー、仮想マシンなど)をセットアップするときにできる最も簡単なことは、ローカルで開発するときと同じように、Uvicorn(または同様のもの)を手動で実行することです。 この方法は**開発中**には役に立つと思われます。 +リモートサーバー(クラウドサーバー、仮想マシンなど)をセットアップするときにできる最も簡単なことは、ローカルで開発するときと同じように、`fastapi run`(Uvicornを使用します)や同様のものを手動で実行することです。 + +そしてこれは動作し、**開発中**には役に立つでしょう。 しかし、サーバーへの接続が切れた場合、**実行中のプロセス**はおそらくダウンしてしまうでしょう。 そしてサーバーが再起動された場合(アップデートやクラウドプロバイダーからのマイグレーションの後など)、おそらくあなたはそれに**気づかないでしょう**。そのため、プロセスを手動で再起動しなければならないことすら気づかないでしょう。つまり、APIはダウンしたままなのです。😱 -### 起動時に自動的に実行 +### 起動時に自動的に実行 { #run-automatically-on-startup } 一般的に、サーバープログラム(Uvicornなど)はサーバー起動時に自動的に開始され、**人の介入**を必要とせずに、APIと一緒にプロセスが常に実行されるようにしたいと思われます(UvicornがFastAPIアプリを実行するなど)。 -### 別のプログラムの用意 +### 別のプログラムの用意 { #separate-program } これを実現するために、通常は**別のプログラム**を用意し、起動時にアプリケーションが実行されるようにします。そして多くの場合、他のコンポーネントやアプリケーション、例えばデータベースも実行されるようにします。 -### 起動時に実行するツールの例 +### 起動時に実行するツールの例 { #example-tools-to-run-at-startup } 実行するツールの例をいくつか挙げます: @@ -127,31 +129,33 @@ OSの「タスク・マネージャー」や「システム・モニター」( 次の章で、より具体的な例を挙げていきます。 -## 再起動 +## 再起動 { #restarts } 起動時にアプリケーションが実行されることを確認するのと同様に、失敗後にアプリケーションが**再起動**されることも確認したいと思われます。 -### 我々は間違いを犯す +### 我々は間違いを犯す { #we-make-mistakes } 私たち人間は常に**間違い**を犯します。ソフトウェアには、ほとんど常に**バグ**があらゆる箇所に隠されています。🐛 -### 小さなエラーは自動的に処理される +そして私たち開発者は、それらのバグを見つけたり新しい機能を実装したりしながらコードを改善し続けます(新しいバグも追加してしまうかもしれません😅)。 + +### 小さなエラーは自動的に処理される { #small-errors-automatically-handled } FastAPIでWeb APIを構築する際に、コードにエラーがある場合、FastAPIは通常、エラーを引き起こした単一のリクエストにエラーを含めます。🛡 クライアントはそのリクエストに対して**500 Internal Server Error**を受け取りますが、アプリケーションは完全にクラッシュするのではなく、次のリクエストのために動作を続けます。 -### 重大なエラー - クラッシュ +### 重大なエラー - クラッシュ { #bigger-errors-crashes } しかしながら、**アプリケーション全体をクラッシュさせるようなコードを書いて**UvicornとPythonをクラッシュさせるようなケースもあるかもしれません。💥 それでも、ある箇所でエラーが発生したからといって、アプリケーションを停止させたままにしたくないでしょう。 少なくとも壊れていない*パスオペレーション*については、**実行し続けたい**はずです。 -### クラッシュ後の再起動 +### クラッシュ後の再起動 { #restart-after-crash } しかし、実行中の**プロセス**をクラッシュさせるような本当にひどいエラーの場合、少なくとも2〜3回ほどプロセスを**再起動**させる外部コンポーネントが必要でしょう。 -/// tip +/// tip | 豆知識 ...とはいえ、アプリケーション全体が**すぐにクラッシュする**のであれば、いつまでも再起動し続けるのは意味がないでしょう。しかし、その場合はおそらく開発中か少なくともデプロイ直後に気づくと思われます。 @@ -161,7 +165,7 @@ FastAPIでWeb APIを構築する際に、コードにエラーがある場合、 あなたはおそらく**外部コンポーネント**がアプリケーションの再起動を担当することを望むと考えます。 なぜなら、その時点でUvicornとPythonを使った同じアプリケーションはすでにクラッシュしており、同じアプリケーションの同じコードに対して何もできないためです。 -### 自動的に再起動するツールの例 +### 自動的に再起動するツールの例 { #example-tools-to-restart-automatically } ほとんどの場合、前述した**起動時にプログラムを実行する**ために使用されるツールは、自動で**再起動**することにも利用されます。 @@ -176,19 +180,19 @@ FastAPIでWeb APIを構築する際に、コードにエラーがある場合、 * クラウドプロバイダーがサービスの一部として内部的に処理 * そのほか... -## レプリケーション - プロセスとメモリー +## レプリケーション - プロセスとメモリ { #replication-processes-and-memory } -FastAPI アプリケーションでは、Uvicorn のようなサーバープログラムを使用し、**1つのプロセス**で1度に複数のクライアントに同時に対応できます。 +FastAPI アプリケーションでは、Uvicorn を実行する `fastapi` コマンドのようなサーバープログラムを使用し、**1つのプロセス**で1度に複数のクライアントに同時に対応できます。 しかし、多くの場合、複数のワーカー・プロセスを同時に実行したいと考えるでしょう。 -### 複数のプロセス - Worker +### 複数のプロセス - Worker { #multiple-processes-workers } クライアントの数が単一のプロセスで処理できる数を超えており(たとえば仮想マシンがそれほど大きくない場合)、かつサーバーの CPU に**複数のコア**がある場合、同じアプリケーションで同時に**複数のプロセス**を実行させ、すべてのリクエストを分散させることができます。 同じAPIプログラムの**複数のプロセス**を実行する場合、それらは一般的に**Worker/ワーカー**と呼ばれます。 -### ワーカー・プロセス と ポート +### ワーカー・プロセス と ポート { #worker-processes-and-ports } [HTTPSについて](https.md){.internal-link target=_blank}のドキュメントで、1つのサーバーで1つのポートとIPアドレスの組み合わせでリッスンできるのは1つのプロセスだけであることを覚えていますでしょうか? @@ -197,13 +201,13 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ そのため、**複数のプロセス**を同時に持つには**ポートでリッスンしている単一のプロセス**が必要であり、それが何らかの方法で各ワーカー・プロセスに通信を送信することが求められます。 -### プロセスあたりのメモリー +### プロセスあたりのメモリ { #memory-per-process } さて、プログラムがメモリにロードする際には、例えば機械学習モデルや大きなファイルの内容を変数に入れたりする場合では、**サーバーのメモリ(RAM)**を少し消費します。 そして複数のプロセスは通常、**メモリを共有しません**。これは、実行中の各プロセスがそれぞれ独自の変数やメモリ等を持っていることを意味します。つまり、コード内で大量のメモリを消費している場合、**各プロセス**は同等の量のメモリを消費することになります。 -### サーバーメモリー +### サーバーメモリ { #server-memory } 例えば、あなたのコードが **1GBのサイズの機械学習モデル**をロードする場合、APIで1つのプロセスを実行すると、少なくとも1GBのRAMを消費します。 @@ -211,7 +215,7 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ リモートサーバーや仮想マシンのRAMが3GBしかない場合、4GB以上のRAMをロードしようとすると問題が発生します。🚨 -### 複数プロセス - 例 +### 複数プロセス - 例 { #multiple-processes-an-example } この例では、2つの**ワーカー・プロセス**を起動し制御する**マネージャー・ プロセス**があります。 @@ -227,7 +231,7 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ 毎回同程度の計算を行うAPIがあり、多くのクライアントがいるのであれば、**CPU使用率**もおそらく**安定**するでしょう(常に急激に上下するのではなく)。 -### レプリケーション・ツールと戦略の例 +### レプリケーション・ツールと戦略の例 { #examples-of-replication-tools-and-strategies } これを実現するにはいくつかのアプローチがありますが、具体的な戦略については次の章(Dockerやコンテナの章など)で詳しく説明します。 @@ -237,25 +241,22 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ 考えられる組み合わせと戦略をいくつか紹介します: -* **Gunicorn**が**Uvicornワーカー**を管理 - * Gunicornは**IP**と**ポート**をリッスンする**プロセスマネージャ**で、レプリケーションは**複数のUvicornワーカー・プロセス**を持つことによって行われる。 -* **Uvicorn**が**Uvicornワーカー**を管理 +* `--workers` を指定した **Uvicorn** * 1つのUvicornの**プロセスマネージャー**が**IP**と**ポート**をリッスンし、**複数のUvicornワーカー・プロセス**を起動する。 * **Kubernetes**やその他の分散**コンテナ・システム** * **Kubernetes**レイヤーの何かが**IP**と**ポート**をリッスンする。レプリケーションは、**複数のコンテナ**にそれぞれ**1つのUvicornプロセス**を実行させることで行われる。 * **クラウド・サービス**によるレプリケーション * クラウド・サービスはおそらく**あなたのためにレプリケーションを処理**します。**実行するプロセス**や使用する**コンテナイメージ**を定義できるかもしれませんが、いずれにせよ、それはおそらく**単一のUvicornプロセス**であり、クラウドサービスはそのレプリケーションを担当するでしょう。 -/// tip +/// tip | 豆知識 これらの**コンテナ**やDockerそしてKubernetesに関する項目が、まだあまり意味をなしていなくても心配しないでください。 - -コンテナ・イメージ、Docker、Kubernetesなどについては、次の章で詳しく説明します: [コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}. +コンテナ・イメージ、Docker、Kubernetesなどについては、将来の章で詳しく説明します: [コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}. /// -## 開始前の事前のステップ +## 開始前の事前のステップ { #previous-steps-before-starting } アプリケーションを**開始する前**に、いくつかのステップを実行したい場合が多くあります。 @@ -271,7 +272,7 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ もちろん、事前のステップを何度も実行しても問題がない場合もあり、その際は対処がかなり楽になります。 -/// tip +/// tip | 豆知識 また、セットアップによっては、アプリケーションを開始する前の**事前のステップ**が必要ない場合もあることを覚えておいてください。 @@ -279,7 +280,7 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ /// -### 事前ステップの戦略例 +### 事前ステップの戦略例 { #examples-of-previous-steps-strategies } これは**システムを**デプロイする方法に**大きく依存**するだろうし、おそらくプログラムの起動方法や再起動の処理などにも関係してくるでしょう。 @@ -289,14 +290,13 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ * 事前のステップを実行し、アプリケーションを起動するbashスクリプト * 利用するbashスクリプトを起動/再起動したり、エラーを検出したりする方法は以前として必要になるでしょう。 -/// tip +/// tip | 豆知識 - -コンテナを使った具体的な例については、次の章で紹介します: [コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}. +コンテナを使った具体的な例については、将来の章で紹介します: [コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}. /// -## リソースの利用 +## リソースの利用 { #resource-utilization } あなたのサーバーは**リソース**であり、プログラムを実行しCPUの計算時間や利用可能なRAMメモリを消費または**利用**することができます。 @@ -319,7 +319,7 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ `htop`のような単純なツールを使って、サーバーで使用されているCPUやRAM、あるいは各プロセスで使用されている量を見ることができます。あるいは、より複雑な監視ツールを使って、サーバに分散して使用することもできます。 -## まとめ +## まとめ { #recap } アプリケーションのデプロイ方法を決定する際に、考慮すべきであろう主要なコンセプトのいくつかを紹介していきました: @@ -327,7 +327,7 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ * 起動時の実行 * 再起動 * レプリケーション(実行中のプロセス数) -* メモリー +* メモリ * 開始前の事前ステップ これらの考え方とその適用方法を理解することで、デプロイメントを設定したり調整したりする際に必要な直感的な判断ができるようになるはずです。🤓 diff --git a/docs/ja/docs/deployment/docker.md b/docs/ja/docs/deployment/docker.md index 53fc851f1..97d41748c 100644 --- a/docs/ja/docs/deployment/docker.md +++ b/docs/ja/docs/deployment/docker.md @@ -1,20 +1,17 @@ -# コンテナ内のFastAPI - Docker +# コンテナ内のFastAPI - Docker { #fastapi-in-containers-docker } -FastAPIアプリケーションをデプロイする場合、一般的なアプローチは**Linuxコンテナ・イメージ**をビルドすることです。 - -基本的には **Docker**を用いて行われます。生成されたコンテナ・イメージは、いくつかの方法のいずれかでデプロイできます。 +FastAPIアプリケーションをデプロイする場合、一般的なアプローチは**Linuxコンテナ・イメージ**をビルドすることです。基本的には **Docker**を用いて行われます。生成されたコンテナ・イメージは、いくつかの方法のいずれかでデプロイできます。 Linuxコンテナの使用には、**セキュリティ**、**反復可能性(レプリカビリティ)**、**シンプリシティ**など、いくつかの利点があります。 -/// tip +/// tip | 豆知識 -TODO: なぜか遷移できない お急ぎで、すでにこれらの情報をご存じですか? [以下の`Dockerfile`の箇所👇](#build-a-docker-image-for-fastapi)へジャンプしてください。 ///
-Dockerfile プレビュー 👀 +Dockerfile Preview 👀 ```Dockerfile FROM python:3.9 @@ -27,15 +24,15 @@ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt COPY ./app /code/app -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] +CMD ["fastapi", "run", "app/main.py", "--port", "80"] # If running behind a proxy like Nginx or Traefik add --proxy-headers -# CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80", "--proxy-headers"] +# CMD ["fastapi", "run", "app/main.py", "--port", "80", "--proxy-headers"] ```
-## コンテナとは何か +## コンテナとは何か { #what-is-a-container } コンテナ(主にLinuxコンテナ)は、同じシステム内の他のコンテナ(他のアプリケーションやコンポーネント)から隔離された状態を保ちながら、すべての依存関係や必要なファイルを含むアプリケーションをパッケージ化する非常に**軽量**な方法です。 @@ -45,7 +42,7 @@ Linuxコンテナは、ホスト(マシン、仮想マシン、クラウドサ コンテナはまた、独自の**分離された**実行プロセス(通常は1つのプロセスのみ)や、ファイルシステム、ネットワークを持ちます。 このことはデプロイ、セキュリティ、開発などを簡素化させます。 -## コンテナ・イメージとは何か +## コンテナ・イメージとは何か { #what-is-a-container-image } **コンテナ**は、**コンテナ・イメージ**から実行されます。 @@ -53,23 +50,17 @@ Linuxコンテナは、ホスト(マシン、仮想マシン、クラウドサ 保存された静的コンテンツである「**コンテナイメージ**」とは対照的に、「**コンテナ**」は通常、実行中のインスタンス、つまり**実行**されているものを指します。 -**コンテナ**が起動され実行されるとき(**コンテナイメージ**から起動されるとき)、ファイルや環境変数などが作成されたり変更されたりする可能性があります。 - -これらの変更はそのコンテナ内にのみ存在しますが、基盤となるコンテナ・イメージには残りません(ディスクに保存されません)。 +**コンテナ**が起動され実行されるとき(**コンテナイメージ**から起動されるとき)、ファイルや環境変数などが作成されたり変更されたりする可能性があります。これらの変更はそのコンテナ内にのみ存在しますが、基盤となるコンテナ・イメージには残りません(ディスクに保存されません)。 コンテナイメージは **プログラム** ファイルやその内容、例えば `python` と `main.py` ファイルに匹敵します。 -そして、**コンテナ**自体は(**コンテナイメージ**とは対照的に)イメージをもとにした実際の実行中のインスタンスであり、**プロセス**に匹敵します。 +そして、**コンテナ**自体は(**コンテナイメージ**とは対照的に)イメージをもとにした実際の実行中のインスタンスであり、**プロセス**に匹敵します。実際、コンテナが実行されているのは、**プロセスが実行されている**ときだけです(通常は単一のプロセスだけです)。 コンテナ内で実行中のプロセスがない場合、コンテナは停止します。 -実際、コンテナが実行されているのは、**プロセスが実行されている**ときだけです(通常は単一のプロセスだけです)。 コンテナ内で実行中のプロセスがない場合、コンテナは停止します。 - -## コンテナ・イメージ +## コンテナ・イメージ { #container-images } Dockerは、**コンテナ・イメージ**と**コンテナ**を作成・管理するための主要なツールの1つです。 -そして、DockerにはDockerイメージ(コンテナ)を共有するDocker Hubというものがあります。 - -Docker Hubは 多くのツールや環境、データベース、アプリケーションに対応している予め作成された**公式のコンテナ・イメージ**をパブリックに提供しています。 +そして、多くのツールや環境、データベース、アプリケーションに対応している予め作成された**公式のコンテナ・イメージ**をパブリックに提供しているDocker Hubというものがあります。 例えば、公式イメージの1つにPython Imageがあります。 @@ -88,7 +79,7 @@ Docker Hubは 多くのツールや環境、データベース、アプリケー すべてのコンテナ管理システム(DockerやKubernetesなど)には、こうしたネットワーキング機能が統合されています。 -## コンテナとプロセス +## コンテナとプロセス { #containers-and-processes } 通常、**コンテナ・イメージ**はそのメタデータに**コンテナ**の起動時に実行されるデフォルトのプログラムまたはコマンドと、そのプログラムに渡されるパラメータを含みます。コマンドラインでの操作とよく似ています。 @@ -100,7 +91,7 @@ Docker Hubは 多くのツールや環境、データベース、アプリケー しかし、**少なくとも1つの実行中のプロセス**がなければ、実行中のコンテナを持つことはできないです。メイン・プロセスが停止すれば、コンテナも停止します。 -## Build a Docker Image for FastAPI +## FastAPI用のDockerイメージをビルドする { #build-a-docker-image-for-fastapi } ということで、何か作りましょう!🚀 @@ -112,7 +103,7 @@ FastAPI用の**Dockerイメージ**を、**公式Python**イメージに基づ * **Raspberry Pi**で実行する場合 * コンテナ・イメージを実行してくれるクラウド・サービスなどを利用する場合 -### パッケージ要件(package requirements) +### パッケージ要件 { #package-requirements } アプリケーションの**パッケージ要件**は通常、何らかのファイルに記述されているはずです。 @@ -125,9 +116,8 @@ FastAPI用の**Dockerイメージ**を、**公式Python**イメージに基づ 例えば、`requirements.txt` は次のようになります: ``` -fastapi>=0.68.0,<0.69.0 -pydantic>=1.8.0,<2.0.0 -uvicorn>=0.15.0,<0.16.0 +fastapi[standard]>=0.113.0,<0.114.0 +pydantic>=2.7.0,<3.0.0 ``` そして通常、例えば `pip` を使ってこれらのパッケージの依存関係をインストールします: @@ -137,20 +127,18 @@ uvicorn>=0.15.0,<0.16.0 ```console $ pip install -r requirements.txt ---> 100% -Successfully installed fastapi pydantic uvicorn +Successfully installed fastapi pydantic ```
-/// info +/// info | 情報 パッケージの依存関係を定義しインストールするためのフォーマットやツールは他にもあります。 -Poetryを使った例は、後述するセクションでご紹介します。👇 - /// -### **FastAPI**コードを作成する +### **FastAPI**コードを作成する { #create-the-fastapi-code } * `app` ディレクトリを作成し、その中に入ります * 空のファイル `__init__.py` を作成します @@ -174,28 +162,28 @@ def read_item(item_id: int, q: Union[str, None] = None): return {"item_id": item_id, "q": q} ``` -### Dockerfile +### Dockerfile { #dockerfile } 同じプロジェクト・ディレクトリに`Dockerfile`というファイルを作成します: ```{ .dockerfile .annotate } -# (1) +# (1)! FROM python:3.9 -# (2) +# (2)! WORKDIR /code -# (3) +# (3)! COPY ./requirements.txt /code/requirements.txt -# (4) +# (4)! RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt -# (5) +# (5)! COPY ./app /code/app -# (6) -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] +# (6)! +CMD ["fastapi", "run", "app/main.py", "--port", "80"] ``` 1. 公式のPythonベースイメージから始めます @@ -211,9 +199,10 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] このファイルは**頻繁には変更されない**ので、Dockerはこのステップではそれを検知し**キャッシュ**を使用し、次のステップでもキャッシュを有効にします。 4. 要件ファイルにあるパッケージの依存関係をインストールします + `--no-cache-dir` オプションはダウンロードしたパッケージをローカルに保存しないように `pip` に指示します。これは、同じパッケージをインストールするために `pip` を再度実行する場合にのみ有効ですが、コンテナで作業する場合はそうではないです。 - /// note + /// note | 備考 `--no-cache-dir`は`pip`に関連しているだけで、Dockerやコンテナとは何の関係もないです。 @@ -225,26 +214,56 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] このステップでキャッシュを使用すると、開発中にイメージを何度もビルドする際に、**毎回**すべての依存関係を**ダウンロードしてインストールする**代わりに多くの**時間**を**節約**できます。 -5. ./app` ディレクトリを `/code` ディレクトリの中にコピーする。 +5. `./app` ディレクトリを `/code` ディレクトリの中にコピーする。 これには**最も頻繁に変更される**すべてのコードが含まれているため、Dockerの**キャッシュ**は**これ以降のステップ**に簡単に使用されることはありません。 そのため、コンテナイメージのビルド時間を最適化するために、`Dockerfile`の **最後** にこれを置くことが重要です。 -6. `uvicorn`サーバーを実行するための**コマンド**を設定します +6. 内部でUvicornを使用する `fastapi run` を使うための**コマンド**を設定します `CMD` は文字列のリストを取り、それぞれの文字列はスペースで区切られたコマンドラインに入力するものです。 このコマンドは **現在の作業ディレクトリ**から実行され、上記の `WORKDIR /code` にて設定した `/code` ディレクトリと同じです。 - そのためプログラムは `/code` で開始しその中にあなたのコードがある `./app` ディレクトリがあるので、**Uvicorn** は `app.main` から `app` を参照し、**インポート** することができます。 +/// tip | 豆知識 -/// tip - -コード内の"+"の吹き出しをクリックして、各行が何をするのかをレビューしてください。👆 +コード内の各番号バブルをクリックして、各行が何をするのかをレビューしてください。👆 /// +/// warning | 注意 + +以下で説明する通り、`CMD` 命令は**常に** **exec形式**を使用してください。 + +/// + +#### `CMD` を使う - Exec形式 { #use-cmd-exec-form } + +Docker命令 `CMD` は2つの形式で書けます: + +✅ **Exec** 形式: + +```Dockerfile +# ✅ Do this +CMD ["fastapi", "run", "app/main.py", "--port", "80"] +``` + +⛔️ **Shell** 形式: + +```Dockerfile +# ⛔️ Don't do this +CMD fastapi run app/main.py --port 80 +``` + +FastAPIが正常にシャットダウンでき、[lifespan events](../advanced/events.md){.internal-link target=_blank}がトリガーされるように、常に **exec** 形式を使用してください。 + +詳しくは、shell形式とexec形式に関するDockerドキュメントをご覧ください。 + +これは `docker compose` を使用する場合にかなり目立つことがあります。より技術的な詳細は、このDocker ComposeのFAQセクションをご覧ください:Why do my services take 10 seconds to recreate or stop?。 + +#### ディレクトリ構造 { #directory-structure } + これで、次のようなディレクトリ構造になるはずです: ``` @@ -256,17 +275,15 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] └── requirements.txt ``` -#### TLS Termination Proxyの裏側 +#### TLS Termination Proxyの裏側 { #behind-a-tls-termination-proxy } -Nginx や Traefik のような TLS Termination Proxy (ロードバランサ) の後ろでコンテナを動かしている場合は、`--proxy-headers`オプションを追加します。 - -このオプションは、Uvicornにプロキシ経由でHTTPSで動作しているアプリケーションに対して、送信されるヘッダを信頼するよう指示します。 +Nginx や Traefik のような TLS Termination Proxy (ロードバランサ) の後ろでコンテナを動かしている場合は、`--proxy-headers`オプションを追加します。これにより、(FastAPI CLI経由で)Uvicornに対して、そのプロキシから送信されるヘッダを信頼し、アプリケーションがHTTPSの裏で実行されていることなどを示すよう指示します。 ```Dockerfile -CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"] +CMD ["fastapi", "run", "app/main.py", "--proxy-headers", "--port", "80"] ``` -#### Dockerキャッシュ +#### Dockerキャッシュ { #docker-cache } この`Dockerfile`には重要なトリックがあり、まず**依存関係だけのファイル**をコピーします。その理由を説明します。 @@ -300,7 +317,7 @@ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt COPY ./app /code/app ``` -### Dockerイメージをビルドする +### Dockerイメージをビルドする { #build-the-docker-image } すべてのファイルが揃ったので、コンテナ・イメージをビルドしましょう。 @@ -317,7 +334,7 @@ $ docker build -t myimage .
-/// tip +/// tip | 豆知識 末尾の `.` に注目してほしいです。これは `./` と同じ意味です。 これはDockerにコンテナイメージのビルドに使用するディレクトリを指示します。 @@ -325,7 +342,7 @@ $ docker build -t myimage . /// -### Dockerコンテナの起動する +### Dockerコンテナの起動する { #start-the-docker-container } * イメージに基づいてコンテナを実行します: @@ -337,7 +354,7 @@ $ docker run -d --name mycontainer -p 80:80 myimage -## 確認する +## 確認する { #check-it } Dockerコンテナのhttp://192.168.99.100/items/5?q=somequeryhttp://127.0.0.1/items/5?q=somequery (またはそれに相当するDockerホストを使用したもの)といったURLで確認できるはずです。 @@ -347,7 +364,7 @@ Dockerコンテナのhttp://192.168.99.100/docshttp://127.0.0.1/docs (またはそれに相当するDockerホストを使用したもの) @@ -355,7 +372,7 @@ Dockerコンテナのhttp://192.168.99.100/redochttp://127.0.0.1/redoc (またはそれに相当するDockerホストを使用したもの)にもアクセスできます。 @@ -363,9 +380,10 @@ DockerコンテナのTraefikのように、**HTTPS**と**証明書**の**自動**取得を扱う別のコンテナである可能性もあります。 -/// tip +/// tip | 豆知識 TraefikはDockerやKubernetesなどと統合されているので、コンテナ用のHTTPSの設定や構成はとても簡単です。 @@ -428,7 +446,7 @@ TraefikはDockerやKubernetesなどと統合されているので、コンテナ あるいは、(コンテナ内でアプリケーションを実行しながら)クラウド・プロバイダーがサービスの1つとしてHTTPSを処理することもできます。 -## 起動時および再起動時の実行 +## 起動時および再起動時の実行 { #running-on-startup-and-restarts } 通常、コンテナの**起動と実行**を担当する別のツールがあります。 @@ -438,21 +456,21 @@ TraefikはDockerやKubernetesなどと統合されているので、コンテナ コンテナを使わなければ、アプリケーションを起動時や再起動時に実行させるのは面倒で難しいかもしれません。しかし、**コンテナ**で作業する場合、ほとんどのケースでその機能はデフォルトで含まれています。✨ -## レプリケーション - プロセス数 +## レプリケーション - プロセス数 { #replication-number-of-processes } -**Kubernetes** や Docker Swarm モード、Nomad、あるいは複数のマシン上で分散コンテナを管理するための同様の複雑なシステムを使ってマシンのクラスターを構成している場合、 各コンテナで(Workerを持つGunicornのような)**プロセスマネージャ**を使用する代わりに、**クラスター・レベル**で**レプリケーション**を処理したいと思うでしょう。 +**Kubernetes** や Docker Swarm モード、Nomad、あるいは複数のマシン上で分散コンテナを管理するための同様の複雑なシステムを使ってマシンのclusterを構成している場合、 各コンテナで(Workerを持つUvicornのような)**プロセスマネージャ**を使用する代わりに、**クラスター・レベル**で**レプリケーション**を処理したいと思うでしょう。 Kubernetesのような分散コンテナ管理システムの1つは通常、入ってくるリクエストの**ロードバランシング**をサポートしながら、**コンテナのレプリケーション**を処理する統合された方法を持っています。このことはすべて**クラスタレベル**にてです。 -そのような場合、UvicornワーカーでGunicornのようなものを実行するのではなく、[上記の説明](#dockerfile)のように**Dockerイメージをゼロから**ビルドし、依存関係をインストールして、**単一のUvicornプロセス**を実行したいでしょう。 +そのような場合、[上記の説明](#dockerfile)のように**Dockerイメージをゼロから**ビルドし、依存関係をインストールして、**単一のUvicornプロセス**を実行したいでしょう。複数のUvicornワーカーを使う代わりにです。 -### ロードバランサー +### ロードバランサー { #load-balancer } コンテナを使用する場合、通常はメイン・ポート**でリスニング**しているコンポーネントがあるはずです。それはおそらく、**HTTPS**を処理するための**TLS Termination Proxy**でもある別のコンテナであったり、同様のツールであったりするでしょう。 このコンポーネントはリクエストの **負荷** を受け、 (うまくいけば) その負荷を**バランスよく** ワーカーに分配するので、一般に **ロードバランサ** とも呼ばれます。 -/// tip +/// tip | 豆知識 HTTPSに使われるものと同じ**TLS Termination Proxy**コンポーネントは、おそらく**ロードバランサー**にもなるでしょう。 @@ -460,7 +478,7 @@ HTTPSに使われるものと同じ**TLS Termination Proxy**コンポーネン そしてコンテナで作業する場合、コンテナの起動と管理に使用する同じシステムには、**ロードバランサー**(**TLS Termination Proxy**の可能性もある)から**ネットワーク通信**(HTTPリクエストなど)をアプリのあるコンテナ(複数可)に送信するための内部ツールが既にあるはずです。 -### 1つのロードバランサー - 複数のワーカーコンテナー +### 1つのロードバランサー - 複数のワーカーコンテナー { #one-load-balancer-multiple-worker-containers } **Kubernetes**や同様の分散コンテナ管理システムで作業する場合、その内部のネットワーキングのメカニズムを使用することで、メインの**ポート**でリッスンしている単一の**ロードバランサー**が、アプリを実行している可能性のある**複数のコンテナ**に通信(リクエスト)を送信できるようになります。 @@ -470,56 +488,61 @@ HTTPSに使われるものと同じ**TLS Termination Proxy**コンポーネン そして通常、この**ロードバランサー**は、クラスタ内の*他の*アプリケーション(例えば、異なるドメインや異なるURLパスのプレフィックスの配下)へのリクエストを処理することができ、その通信をクラスタ内で実行されている*他の*アプリケーションのための適切なコンテナに送信します。 -### 1コンテナにつき1プロセス +### 1コンテナにつき1プロセス { #one-process-per-container } この種のシナリオでは、すでにクラスタ・レベルでレプリケーションを処理しているため、おそらくコンテナごとに**単一の(Uvicorn)プロセス**を持ちたいでしょう。 -この場合、Uvicornワーカーを持つGunicornのようなプロセスマネージャーや、Uvicornワーカーを使うUvicornは**避けたい**でしょう。**コンテナごとにUvicornのプロセスは1つだけ**にしたいでしょう(おそらく複数のコンテナが必要でしょう)。 +この場合、例えばコマンドラインオプションの `--workers` で、コンテナ内に複数のワーカーを持つことは**避けたい**でしょう。**コンテナごとにUvicornのプロセスは1つだけ**にしたいでしょう(おそらく複数のコンテナが必要でしょう)。 -(GunicornやUvicornがUvicornワーカーを管理するように)コンテナ内に別のプロセスマネージャーを持つことは、クラスターシステムですでに対処しているであろう**不要な複雑さ**を追加するだけです。 +(複数のワーカーの場合のように)コンテナ内に別のプロセスマネージャーを持つことは、クラスターシステムですでに対処しているであろう**不要な複雑さ**を追加するだけです。 -### Containers with Multiple Processes and Special Cases +### 複数プロセスのコンテナと特殊なケース { #containers-with-multiple-processes-and-special-cases } -もちろん、**特殊なケース**として、**Gunicornプロセスマネージャ**を持つ**コンテナ**内で複数の**Uvicornワーカープロセス**を起動させたい場合があります。 +もちろん、**特殊なケース**として、**コンテナ**内で複数の**Uvicornワーカープロセス**を起動させたい場合があります。 -このような場合、**公式のDockerイメージ**を使用することができます。このイメージには、複数の**Uvicornワーカープロセス**を実行するプロセスマネージャとして**Gunicorn**が含まれており、現在のCPUコアに基づいてワーカーの数を自動的に調整するためのデフォルト設定がいくつか含まれています。詳しくは後述の[Gunicornによる公式Dockerイメージ - Uvicorn](#gunicorndocker-uvicorn)で説明します。 +そのような場合、`--workers` コマンドラインオプションを使って、実行したいワーカー数を設定できます: + +```{ .dockerfile .annotate } +FROM python:3.9 + +WORKDIR /code + +COPY ./requirements.txt /code/requirements.txt + +RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt + +COPY ./app /code/app + +# (1)! +CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"] +``` + +1. ここでは `--workers` コマンドラインオプションを使って、ワーカー数を4に設定しています。 以下は、それが理にかなっている場合の例です: -#### シンプルなアプリケーション +#### シンプルなアプリ { #a-simple-app } -アプリケーションを**シンプル**な形で実行する場合、プロセス数の細かい調整が必要ない場合、自動化されたデフォルトを使用するだけで、コンテナ内にプロセスマネージャが必要かもしれません。例えば、公式Dockerイメージでシンプルな設定が可能です。 +アプリケーションが、クラスタではなく**単一サーバ**で実行できるほど**シンプル**である場合、コンテナ内にプロセスマネージャが欲しくなることがあります。 -#### Docker Compose +#### Docker Compose { #docker-compose } -Docker Composeで**シングルサーバ**(クラスタではない)にデプロイすることもできますので、共有ネットワークと**ロードバランシング**を維持しながら(Docker Composeで)コンテナのレプリケーションを管理する簡単な方法はないでしょう。 +Docker Composeで**単一サーバ**(クラスタではない)にデプロイすることもできますので、共有ネットワークと**ロードバランシング**を維持しながら(Docker Composeで)コンテナのレプリケーションを管理する簡単な方法はないでしょう。 その場合、**単一のコンテナ**で、**プロセスマネージャ**が内部で**複数のワーカープロセス**を起動するようにします。 -#### Prometheusとその他の理由 - -また、**1つのコンテナ**に**1つのプロセス**を持たせるのではなく、**1つのコンテナ**に**複数のプロセス**を持たせる方が簡単だという**他の理由**もあるでしょう。 - -例えば、(セットアップにもよりますが)Prometheusエクスポーターのようなツールを同じコンテナ内に持つことができます。 - -この場合、**複数のコンテナ**があると、デフォルトでは、Prometheusが**メトリクスを**読みに来たとき、すべてのレプリケートされたコンテナの**蓄積されたメトリクス**を取得するのではなく、毎回**単一のコンテナ**(その特定のリクエストを処理したコンテナ)のものを取得することになります。 - -その場合、**複数のプロセス**を持つ**1つのコンテナ**を用意し、同じコンテナ上のローカルツール(例えばPrometheusエクスポーター)がすべての内部プロセスのPrometheusメトリクスを収集し、その1つのコンテナ上でそれらのメトリクスを公開する方がシンプルかもしれません。 - --- -重要なのは、盲目的に従わなければならない普遍のルールはないということです。 - -これらのアイデアは、**あなた自身のユースケース**を評価し、あなたのシステムに最適なアプローチを決定するために使用することができます: +重要なのは、これらのどれも、盲目的に従わなければならない「**絶対的なルール**」ではないということです。これらのアイデアは、**あなた自身のユースケース**を評価し、あなたのシステムに最適なアプローチを決定するために使用できます。次の概念をどう管理するかを確認してください: * セキュリティ - HTTPS * 起動時の実行 * 再起動 -* **レプリケーション(実行中のプロセス数)** +* レプリケーション(実行中のプロセス数) * メモリ * 開始前の事前ステップ -## メモリー +## メモリ { #memory } コンテナごとに**単一のプロセスを実行する**と、それらのコンテナ(レプリケートされている場合は1つ以上)によって消費される多かれ少なかれ明確に定義された、安定し制限された量のメモリを持つことになります。 @@ -531,109 +554,47 @@ Docker Composeで**シングルサーバ**(クラスタではない)にデ しかし、**多くのメモリを使用**している場合(たとえば**機械学習**モデルなど)、どれだけのメモリを消費しているかを確認し、**各マシンで実行するコンテナの数**を調整する必要があります(そしておそらくクラスタにマシンを追加します)。 -**コンテナごとに複数のプロセス**を実行する場合(たとえば公式のDockerイメージで)、起動するプロセスの数が**利用可能なメモリ以上に消費しない**ようにする必要があります。 +**コンテナごとに複数のプロセス**を実行する場合、起動するプロセスの数が**利用可能なメモリ以上に消費しない**ようにする必要があります。 -## 開始前の事前ステップとコンテナ +## 開始前の事前ステップとコンテナ { #previous-steps-before-starting-and-containers } コンテナ(DockerやKubernetesなど)を使っている場合、主に2つのアプローチがあります。 -### 複数のコンテナ +### 複数のコンテナ { #multiple-containers } -複数の**コンテナ**があり、おそらくそれぞれが**単一のプロセス**を実行している場合(**Kubernetes**クラスタなど)、レプリケートされたワーカーコンテナを実行する**前に**、単一のコンテナで**事前のステップ**の作業を行う**別のコンテナ**を持ちたいと思うでしょう。 +複数の**コンテナ**があり、おそらくそれぞれが**単一のプロセス**を実行している場合(例えば、**Kubernetes**クラスタなど)、レプリケートされたワーカーコンテナを実行する**前に**、単一のコンテナで**事前のステップ**の作業を行う**別のコンテナ**を持ちたいと思うでしょう。 -/// info +/// info | 情報 -もしKubernetesを使用している場合, これはおそらくInit コンテナでしょう。 +もしKubernetesを使用している場合, これはおそらくInit Containerでしょう。 /// -ユースケースが事前のステップを**並列で複数回**実行するのに問題がない場合(例:データベースの準備チェック)、メインプロセスを開始する前に、それらのステップを各コンテナに入れることが可能です。 +ユースケースが事前のステップを**並列で複数回**実行するのに問題がない場合(例:データベースマイグレーションを実行するのではなく、データベースの準備ができたかをチェックするだけの場合)、メインプロセスを開始する直前に、それらのステップを各コンテナに入れることも可能です。 -### 単一コンテナ +### 単一コンテナ { #single-container } -単純なセットアップで、**単一のコンテナ**で複数の**ワーカー・プロセス**(または1つのプロセスのみ)を起動する場合、アプリでプロセスを開始する直前に、同じコンテナで事前のステップを実行できます。公式Dockerイメージは、内部的にこれをサポートしています。 +単純なセットアップで、**単一のコンテナ**で複数の**ワーカープロセス**(または1つのプロセスのみ)を起動する場合、アプリでプロセスを開始する直前に、同じコンテナで事前のステップを実行できます。 -## Gunicornによる公式Dockerイメージ - Uvicorn +### ベースDockerイメージ { #base-docker-image } -前の章で詳しく説明したように、Uvicornワーカーで動作するGunicornを含む公式のDockerイメージがあります: [Server Workers - Gunicorn と Uvicorn](server-workers.md){.internal-link target=_blank}で詳しく説明しています。 +以前は、公式のFastAPI Dockerイメージがありました:tiangolo/uvicorn-gunicorn-fastapi。しかし、現在は非推奨です。⛔️ -このイメージは、主に上記で説明した状況で役に立つでしょう: [複数のプロセスと特殊なケースを持つコンテナ(Containers with Multiple Processes and Special Cases)](#containers-with-multiple-processes-and-special-cases) +おそらく、このベースDockerイメージ(またはその他の類似のもの)は**使用しない**方がよいでしょう。 -* tiangolo/uvicorn-gunicorn-fastapi. +すでに**Kubernetes**(または他のもの)を使用していて、複数の**コンテナ**で、クラスタレベルで**レプリケーション**を設定している場合。そのような場合は、上記で説明したように**ゼロから**イメージを構築する方がよいでしょう:[FastAPI用のDockerイメージをビルドする](#build-a-docker-image-for-fastapi)。 -/// warning +また、複数のワーカーが必要な場合は、単純に `--workers` コマンドラインオプションを使用できます。 -このベースイメージや類似のイメージは**必要ない**可能性が高いので、[上記の: FastAPI用のDockerイメージをビルドする(Build a Docker Image for FastAPI)](#build-a-docker-image-for-fastapi)のようにゼロからイメージをビルドする方が良いでしょう。 +/// note | 技術詳細 + +このDockerイメージは、Uvicornが停止したワーカーの管理と再起動をサポートしていなかった頃に作成されたため、Uvicornと一緒にGunicornを使う必要がありました。これは、GunicornにUvicornワーカープロセスの管理と再起動をさせるだけのために、かなりの複雑さを追加していました。 + +しかし現在は、Uvicorn(および `fastapi` コマンド)が `--workers` をサポートしているため、自分でビルドする代わりにベースDockerイメージを使う理由はありません(コード量もだいたい同じです 😅)。 /// -このイメージには、利用可能なCPUコアに基づいて**ワーカー・プロセスの数**を設定する**オートチューニング**メカニズムが含まれています。 - -これは**賢明なデフォルト**を備えていますが、**環境変数**や設定ファイルを使ってすべての設定を変更したり更新したりすることができます。 - -また、スクリプトで**開始前の事前ステップ**を実行することもサポートしている。 - -/// tip - -すべての設定とオプションを見るには、Dockerイメージのページをご覧ください: tiangolo/uvicorn-gunicorn-fastapi - -/// - -### 公式Dockerイメージのプロセス数 - -このイメージの**プロセス数**は、利用可能なCPU**コア**から**自動的に計算**されます。 - -つまり、CPUから可能な限り**パフォーマンス**を**引き出そう**とします。 - -また、**環境変数**などを使った設定で調整することもできます。 - -しかし、プロセスの数はコンテナが実行しているCPUに依存するため、**消費されるメモリの量**もそれに依存することになります。 - -そのため、(機械学習モデルなどで)大量のメモリを消費するアプリケーションで、サーバーのCPUコアが多いが**メモリが少ない**場合、コンテナは利用可能なメモリよりも多くのメモリを使おうとすることになります。 - -その結果、パフォーマンスが大幅に低下する(あるいはクラッシュする)可能性があります。🚨 - -### Dockerfileを作成する - -この画像に基づいて`Dockerfile`を作成する方法を以下に示します: - -```Dockerfile -FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9 - -COPY ./requirements.txt /app/requirements.txt - -RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt - -COPY ./app /app -``` - -### より大きなアプリケーション - -[複数のファイルを持つ大きなアプリケーション](../tutorial/bigger-applications.md){.internal-link target=_blank}を作成するセクションに従った場合、`Dockerfile`は次のようになります: - -```Dockerfile hl_lines="7" -FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9 - -COPY ./requirements.txt /app/requirements.txt - -RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt - -COPY ./app /app/app -``` - -### いつ使うのか - -おそらく、**Kubernetes**(または他のもの)を使用していて、すでにクラスタレベルで複数の**コンテナ**で**レプリケーション**を設定している場合は、この公式ベースイメージ(または他の類似のもの)は**使用すべきではありません**。 - -そのような場合は、上記のように**ゼロから**イメージを構築する方がよいでしょう: [FastAPI用のDockerイメージをビルドする(Build a Docker Image for FastAPI)](#build-a-docker-image-for-fastapi) を参照してください。 - -このイメージは、主に上記の[複数のプロセスと特殊なケースを持つコンテナ(Containers with Multiple Processes and Special Cases)](#containers-with-multiple-processes-and-special-cases)で説明したような特殊なケースで役に立ちます。 - -例えば、アプリケーションが**シンプル**で、CPUに応じたデフォルトのプロセス数を設定すればうまくいく場合や、クラスタレベルでレプリケーションを手動で設定する手間を省きたい場合、アプリで複数のコンテナを実行しない場合などです。 - -または、**Docker Compose**でデプロイし、単一のサーバで実行している場合などです。 - -## コンテナ・イメージのデプロイ +## コンテナ・イメージのデプロイ { #deploy-the-container-image } コンテナ(Docker)イメージを手に入れた後、それをデプロイするにはいくつかの方法があります。 @@ -645,104 +606,21 @@ COPY ./app /app/app * Nomadのような別のツール * コンテナ・イメージをデプロイするクラウド・サービス -## Poetryを利用したDockerイメージ +## `uv` を使ったDockerイメージ { #docker-image-with-uv } -もしプロジェクトの依存関係を管理するためにPoetryを利用する場合、マルチステージビルドを使うと良いでしょう。 +uv を使ってプロジェクトのインストールと管理をしている場合は、uv Docker guideに従ってください。 -```{ .dockerfile .annotate } -# (1) -FROM python:3.9 as requirements-stage - -# (2) -WORKDIR /tmp - -# (3) -RUN pip install poetry - -# (4) -COPY ./pyproject.toml ./poetry.lock* /tmp/ - -# (5) -RUN poetry export -f requirements.txt --output requirements.txt --without-hashes - -# (6) -FROM python:3.9 - -# (7) -WORKDIR /code - -# (8) -COPY --from=requirements-stage /tmp/requirements.txt /code/requirements.txt - -# (9) -RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt - -# (10) -COPY ./app /code/app - -# (11) -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] -``` - -1. これは最初のステージで、`requirements-stage`と名付けられます -2. `/tmp` を現在の作業ディレクトリに設定します - ここで `requirements.txt` というファイルを生成します。 - -3. このDockerステージにPoetryをインストールします - -4. pyproject.toml`と`poetry.lock`ファイルを`/tmp` ディレクトリにコピーします - - `./poetry.lock*`(末尾に`*`)を使用するため、そのファイルがまだ利用できない場合でもクラッシュすることはないです。 -5. requirements.txt`ファイルを生成します - -6. これは最後のステージであり、ここにあるものはすべて最終的なコンテナ・イメージに保存されます -7. 現在の作業ディレクトリを `/code` に設定します -8. `requirements.txt`ファイルを `/code` ディレクトリにコピーします - このファイルは前のDockerステージにしか存在しないため、`--from-requirements-stage`を使ってコピーします。 -9. 生成された `requirements.txt` ファイルにあるパッケージの依存関係をインストールします -10. app` ディレクトリを `/code` ディレクトリにコピーします -11. uvicorn` コマンドを実行して、`app.main` からインポートした `app` オブジェクトを使用するように指示します -/// tip - -"+"の吹き出しをクリックすると、それぞれの行が何をするのかを見ることができます - -/// - -**Dockerステージ**は`Dockerfile`の一部で、**一時的なコンテナイメージ**として動作します。 - -最初のステージは **Poetryのインストール**と Poetry の `pyproject.toml` ファイルからプロジェクトの依存関係を含む**`requirements.txt`を生成**するためだけに使用されます。 - -この `requirements.txt` ファイルは後半の **次のステージ**で `pip` と共に使用されます。 - -最終的なコンテナイメージでは、**最終ステージ**のみが保存されます。前のステージは破棄されます。 - -Poetryを使用する場合、**Dockerマルチステージビルド**を使用することは理にかなっています。 - -なぜなら、最終的なコンテナイメージにPoetryとその依存関係がインストールされている必要はなく、**必要なのは**プロジェクトの依存関係をインストールするために生成された `requirements.txt` ファイルだけだからです。 - -そして次の(そして最終的な)ステージでは、前述とほぼ同じ方法でイメージをビルドします。 - -### TLS Termination Proxyの裏側 - Poetry - -繰り返しになりますが、NginxやTraefikのようなTLS Termination Proxy(ロードバランサー)の後ろでコンテナを動かしている場合は、`--proxy-headers`オプションをコマンドに追加します: - -```Dockerfile -CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"] -``` - -## まとめ +## まとめ { #recap } コンテナ・システム(例えば**Docker**や**Kubernetes**など)を使えば、すべての**デプロイメントのコンセプト**を扱うのがかなり簡単になります: -* セキュリティ - HTTPS +* HTTPS * 起動時の実行 * 再起動 -* **レプリケーション(実行中のプロセス数)** +* レプリケーション(実行中のプロセス数) * メモリ * 開始前の事前ステップ ほとんどの場合、ベースとなるイメージは使用せず、公式のPython Dockerイメージをベースにした**コンテナイメージをゼロからビルド**します。 -`Dockerfile`と**Dockerキャッシュ**内の命令の**順番**に注意することで、**ビルド時間を最小化**することができ、生産性を最大化することができます(そして退屈を避けることができます)。😎 - -特別なケースでは、FastAPI用の公式Dockerイメージを使いたいかもしれません。🤓 +`Dockerfile`と**Dockerキャッシュ**内の命令の**順番**に注意することで、**ビルド時間を最小化**し、生産性を最大化できます(そして退屈を避けることができます)。😎 diff --git a/docs/ja/docs/deployment/https.md b/docs/ja/docs/deployment/https.md index 7b0f567aa..d5a6daf0c 100644 --- a/docs/ja/docs/deployment/https.md +++ b/docs/ja/docs/deployment/https.md @@ -1,10 +1,10 @@ -# HTTPS について +# HTTPS について { #about-https } HTTPSは単に「有効」か「無効」かで決まるものだと思いがちです。 しかし、それよりもはるかに複雑です。 -/// tip +/// tip | 豆知識 もし急いでいたり、HTTPSの仕組みについて気にしないのであれば、次のセクションに進み、さまざまなテクニックを使ってすべてをセットアップするステップ・バイ・ステップの手順をご覧ください。 @@ -22,25 +22,19 @@ HTTPSは単に「有効」か「無効」かで決まるものだと思いがち * 接続の暗号化は**TCPレベル**で行われます。 * それは**HTTPの1つ下**のレイヤーです。 * つまり、**証明書と暗号化**の処理は、**HTTPの前**に行われます。 -* **TCPは "ドメイン "について知りません**。IPアドレスについてのみ知っています。 +* **TCPは「ドメイン」について知りません**。IPアドレスについてのみ知っています。 * 要求された**特定のドメイン**に関する情報は、**HTTPデータ**に入ります。 * **HTTPS証明書**は、**特定のドメイン**を「証明」しますが、プロトコルと暗号化はTCPレベルで行われ、どのドメインが扱われているかを**知る前**に行われます。 * **デフォルトでは**、**IPアドレスごとに1つのHTTPS証明書**しか持てないことになります。 * これは、サーバーの規模やアプリケーションの規模に寄りません。 * しかし、これには**解決策**があります。 -* **TLS**プロトコル(HTTPの前に、TCPレベルで暗号化を処理するもの)には、**SNI**と呼ばれる**拡張**があります。 +* **TLS**プロトコル(HTTPの前に、TCPレベルで暗号化を処理するもの)には、**SNI**と呼ばれる**拡張**があります。 * このSNI拡張機能により、1つのサーバー(**単一のIPアドレス**を持つ)が**複数のHTTPS証明書**を持ち、**複数のHTTPSドメイン/アプリケーション**にサービスを提供できるようになります。 * これが機能するためには、**パブリックIPアドレス**でリッスンしている、サーバー上で動作している**単一の**コンポーネント(プログラム)が、サーバー内の**すべてのHTTPS証明書**を持っている必要があります。 - * セキュアな接続を取得した**後**でも、通信プロトコルは**HTTPのまま**です。 * コンテンツは**HTTPプロトコル**で送信されているにもかかわらず、**暗号化**されています。 - -サーバー(マシン、ホストなど)上で**1つのプログラム/HTTPサーバー**を実行させ、**HTTPSに関する全てのこと**を管理するのが一般的です。 - -**暗号化された HTTPS リクエスト** を受信し、**復号化された HTTP リクエスト** を同じサーバーで実行されている実際の HTTP アプリケーション(この場合は **FastAPI** アプリケーション)に送信し、アプリケーションから **HTTP レスポンス** を受け取り、適切な **HTTPS 証明書** を使用して **暗号化** し、そして**HTTPS** を使用してクライアントに送り返します。 - -このサーバーはしばしば **TLS Termination Proxy**と呼ばれます。 +サーバー(マシン、ホストなど)上で**1つのプログラム/HTTPサーバー**を実行させ、**HTTPSに関する全てのこと**を管理するのが一般的です。**暗号化された HTTPS リクエスト** を受信し、**復号化された HTTP リクエスト** を同じサーバーで実行されている実際の HTTP アプリケーション(この場合は **FastAPI** アプリケーション)に送信し、アプリケーションから **HTTP レスポンス** を受け取り、適切な **HTTPS 証明書** を使用して **暗号化** し、そして**HTTPS** を使用してクライアントに送り返します。このサーバーはしばしば **TLS Termination Proxy**と呼ばれます。 TLS Termination Proxyとして使えるオプションには、以下のようなものがあります: @@ -50,7 +44,7 @@ TLS Termination Proxyとして使えるオプションには、以下のよう * HAProxy -## Let's Encrypt +## Let's Encrypt { #lets-encrypt } Let's Encrypt以前は、これらの**HTTPS証明書**は信頼できる第三者によって販売されていました。 @@ -64,27 +58,27 @@ Let's Encrypt以前は、これらの**HTTPS証明書**は信頼できる第三 このアイデアは、これらの証明書の取得と更新を自動化することで、**安全なHTTPSを、無料で、永遠に**利用できるようにすることです。 -## 開発者のための HTTPS +## 開発者のための HTTPS { #https-for-developers } ここでは、HTTPS APIがどのように見えるかの例を、主に開発者にとって重要なアイデアに注意を払いながら、ステップ・バイ・ステップで説明します。 -### ドメイン名 +### ドメイン名 { #domain-name } ステップの初めは、**ドメイン名**を**取得すること**から始まるでしょう。その後、DNSサーバー(おそらく同じクラウドプロバイダー)に設定します。 -おそらくクラウドサーバー(仮想マシン)かそれに類するものを手に入れ、固定の **パブリックIPアドレス**を持つことになるでしょう。 +おそらくクラウドサーバー(仮想マシン)かそれに類するものを手に入れ、fixed **パブリックIPアドレス**を持つことになるでしょう。 -DNSサーバーでは、**取得したドメイン**をあなたのサーバーのパプリック**IPアドレス**に向けるレコード(「`Aレコード`」)を設定します。 +DNSサーバーでは、**取得したドメイン**をあなたのサーバーのパプリック**IPアドレス**に向けるレコード(「`A record`」)を設定します。 これはおそらく、最初の1回だけあり、すべてをセットアップするときに行うでしょう。 -/// tip +/// tip | 豆知識 ドメイン名の話はHTTPSに関する話のはるか前にありますが、すべてがドメインとIPアドレスに依存するため、ここで言及する価値があります。 /// -### DNS +### DNS { #dns } では、実際のHTTPSの部分に注目してみよう。 @@ -94,7 +88,7 @@ DNSサーバーは、ブラウザに特定の**IPアドレス**を使用する -### TLS Handshake の開始 +### TLS Handshake の開始 { #tls-handshake-start } ブラウザはIPアドレスと**ポート443**(HTTPSポート)で通信します。 @@ -104,7 +98,7 @@ DNSサーバーは、ブラウザに特定の**IPアドレス**を使用する TLS接続を確立するためのクライアントとサーバー間のこのやりとりは、**TLSハンドシェイク**と呼ばれます。 -### SNI拡張機能付きのTLS +### SNI拡張機能付きのTLS { #tls-with-sni-extension } サーバー内の**1つのプロセス**だけが、特定 の**IPアドレス**の特定の**ポート** で待ち受けることができます。 @@ -112,7 +106,7 @@ TLS接続を確立するためのクライアントとサーバー間のこの TLS(HTTPS)はデフォルトで`443`という特定のポートを使用する。つまり、これが必要なポートです。 -このポートをリッスンできるのは1つのプロセスだけなので、これを実行するプロセスは**TLS Termination Proxy**となります。 +このポートをリクエストできるのは1つのプロセスだけなので、これを実行するプロセスは**TLS Termination Proxy**となります。 TLS Termination Proxyは、1つ以上の**TLS証明書**(HTTPS証明書)にアクセスできます。 @@ -130,13 +124,13 @@ TLS Termination Proxyは、1つ以上の**TLS証明書**(HTTPS証明書)に これが**HTTPS**であり、純粋な(暗号化されていない)TCP接続ではなく、**セキュアなTLS接続**の中に**HTTP**があるだけです。 -/// tip +/// tip | 豆知識 通信の暗号化は、HTTPレベルではなく、**TCPレベル**で行われることに注意してください。 /// -### HTTPS リクエスト +### HTTPS リクエスト { #https-request } これでクライアントとサーバー(具体的にはブラウザとTLS Termination Proxy)は**暗号化されたTCP接続**を持つことになり、**HTTP通信**を開始することができます。 @@ -144,19 +138,19 @@ TLS Termination Proxyは、1つ以上の**TLS証明書**(HTTPS証明書)に -### リクエストの復号化 +### リクエストの復号化 { #decrypt-the-request } TLS Termination Proxy は、合意が取れている暗号化を使用して、**リクエストを復号化**し、**プレーン (復号化された) HTTP リクエスト** をアプリケーションを実行しているプロセス (例えば、FastAPI アプリケーションを実行している Uvicorn を持つプロセス) に送信します。 -### HTTP レスポンス +### HTTP レスポンス { #http-response } アプリケーションはリクエストを処理し、**プレーン(暗号化されていない)HTTPレスポンス** をTLS Termination Proxyに送信します。 -### HTTPS レスポンス +### HTTPS レスポンス { #https-response } TLS Termination Proxyは次に、事前に合意が取れている暗号(`someapp.example.com`の証明書から始まる)を使って**レスポンスを暗号化し**、ブラウザに送り返す。 @@ -166,7 +160,7 @@ TLS Termination Proxyは次に、事前に合意が取れている暗号(`someap クライアント(ブラウザ)は、レスポンスが正しいサーバーから来たことを知ることができます。 なぜなら、そのサーバーは、以前に**HTTPS証明書**を使って合意した暗号を使っているからです。 -### 複数のアプリケーション +### 複数のアプリケーション { #multiple-applications } 同じサーバー(または複数のサーバー)に、例えば他のAPIプログラムやデータベースなど、**複数のアプリケーション**が存在する可能性があります。 @@ -176,7 +170,7 @@ TLS Termination Proxyは次に、事前に合意が取れている暗号(`someap そうすれば、TLS Termination Proxy は、**複数のドメイン**や複数のアプリケーションのHTTPSと証明書を処理し、それぞれのケースで適切なアプリケーションにリクエストを送信することができます。 -### 証明書の更新 +### 証明書の更新 { #certificate-renewal } 将来のある時点で、各証明書は(取得後約3ヶ月で)**失効**します。 @@ -200,10 +194,42 @@ TLS Termination Proxyは次に、事前に合意が取れている暗号(`someap アプリを提供しながらこのような更新処理を行うことは、アプリケーション・サーバー(Uvicornなど)でTLS証明書を直接使用するのではなく、TLS Termination Proxyを使用して**HTTPSを処理する別のシステム**を用意したくなる主な理由の1つです。 -## まとめ +## プロキシ転送ヘッダー { #proxy-forwarded-headers } + +プロキシを使ってHTTPSを処理する場合、**アプリケーションサーバー**(たとえばFastAPI CLI経由のUvicorn)はHTTPS処理について何も知らず、**TLS Termination Proxy**とはプレーンなHTTPで通信します。 + +この**プロキシ**は通常、リクエストを**アプリケーションサーバー**に転送する前に、その場でいくつかのHTTPヘッダーを設定し、リクエストがプロキシによって**転送**されていることをアプリケーションサーバーに知らせます。 + +/// note | 技術詳細 + +プロキシヘッダーは次のとおりです: + +* X-Forwarded-For +* X-Forwarded-Proto +* X-Forwarded-Host + +/// + +それでも、**アプリケーションサーバー**は信頼できる**プロキシ**の背後にあることを知らないため、デフォルトではそれらのヘッダーを信頼しません。 + +しかし、**アプリケーションサーバー**が**プロキシ**から送信される*forwarded*ヘッダーを信頼するように設定できます。FastAPI CLIを使用している場合は、*CLI Option* `--forwarded-allow-ips` を使って、どのIPからの*forwarded*ヘッダーを信頼すべきかを指定できます。 + +たとえば、**アプリケーションサーバー**が信頼できる**プロキシ**からの通信のみを受け取っている場合、`--forwarded-allow-ips="*"` に設定して、受信するすべてのIPを信頼するようにできます。受け取るリクエストは、**プロキシ**が使用するIPからのものだけになるためです。 + +こうすることで、アプリケーションは、HTTPSを使用しているかどうか、ドメインなど、自身のパブリックURLが何であるかを把握できるようになります。 + +これは、たとえばリダイレクトを適切に処理するのに便利です。 + +/// tip | 豆知識 + +これについては、[Behind a Proxy - Enable Proxy Forwarded Headers](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank} のドキュメントで詳しく学べます。 + +/// + +## まとめ { #recap } **HTTPS**を持つことは非常に重要であり、ほとんどの場合、かなり**クリティカル**です。開発者として HTTPS に関わる労力のほとんどは、これらの**概念とその仕組みを理解する**ことです。 しかし、ひとたび**開発者向けHTTPS**の基本的な情報を知れば、簡単な方法ですべてを管理するために、さまざまなツールを組み合わせて設定することができます。 -次の章では、**FastAPI** アプリケーションのために **HTTPS** をセットアップする方法について、いくつかの具体例を紹介します。🔒 +次の章のいくつかでは、**FastAPI** アプリケーションのために **HTTPS** をセットアップする方法について、いくつかの具体例を紹介します。🔒 diff --git a/docs/ja/docs/deployment/index.md b/docs/ja/docs/deployment/index.md index 897956e38..eba6eae6e 100644 --- a/docs/ja/docs/deployment/index.md +++ b/docs/ja/docs/deployment/index.md @@ -1,7 +1,23 @@ -# デプロイ +# デプロイ { #deployment } -**FastAPI** 製のアプリケーションは比較的容易にデプロイできます。 +**FastAPI** アプリケーションのデプロイは比較的簡単です。 -ユースケースや使用しているツールによっていくつかの方法に分かれます。 +## デプロイとは { #what-does-deployment-mean } -次のセクションでより詳しくそれらの方法について説明します。 +アプリケーションを**デプロイ**するとは、**ユーザーが利用できるようにする**ために必要な手順を実行することを意味します。 + +**Web API** の場合、通常は **リモートマシン** 上に配置し、優れたパフォーマンス、安定性などを提供する **サーバープログラム** と組み合わせて、**ユーザー** が中断や問題なく効率的にアプリケーションへ**アクセス**できるようにします。 + +これは **開発** 段階とは対照的です。開発では、コードを常に変更し、壊しては直し、開発サーバーを停止したり再起動したりします。 + +## デプロイ戦略 { #deployment-strategies } + +具体的なユースケースや使用するツールによって、いくつかの方法があります。 + +複数のツールを組み合わせて自分で**サーバーをデプロイ**することもできますし、作業の一部を代行してくれる **クラウドサービス** を使うこともできます。ほかにも選択肢があります。 + +たとえば、FastAPI の開発チームである私たちは、クラウドへの FastAPI アプリのデプロイを可能な限り合理化し、FastAPI を使って開発するのと同じ開発者体験を提供するために、**FastAPI Cloud** を構築しました。 + +**FastAPI** アプリケーションをデプロイする際に、おそらく念頭に置くべき主要な概念をいくつか紹介します(ただし、そのほとんどは他の種類の Web アプリケーションにも当てはまります)。 + +次のセクションでは、留意すべき点の詳細や、それを実現するためのいくつかの手法を確認します。 ✨ diff --git a/docs/ja/docs/deployment/server-workers.md b/docs/ja/docs/deployment/server-workers.md index 38ceab017..933b875d7 100644 --- a/docs/ja/docs/deployment/server-workers.md +++ b/docs/ja/docs/deployment/server-workers.md @@ -1,4 +1,4 @@ -# Server Workers - Gunicorn と Uvicorn +# Server Workers - ワーカー付きUvicorn { #server-workers-uvicorn-with-workers } 前回のデプロイメントのコンセプトを振り返ってみましょう: @@ -9,124 +9,79 @@ * メモリ * 開始前の事前ステップ -ここまでのドキュメントのチュートリアルでは、おそらくUvicornのような**サーバープログラム**を**単一のプロセス**で実行しています。 +ここまでのドキュメントのチュートリアルでは、おそらく `fastapi` コマンドなど(Uvicornを実行するもの)を使って、**単一のプロセス**として動作する**サーバープログラム**を実行してきたはずです。 アプリケーションをデプロイする際には、**複数のコア**を利用し、そしてより多くのリクエストを処理できるようにするために、プロセスの**レプリケーション**を持つことを望むでしょう。 前のチャプターである[デプロイメントのコンセプト](concepts.md){.internal-link target=_blank}にて見てきたように、有効な戦略がいくつかあります。 -ここでは**Gunicorn**が**Uvicornのワーカー・プロセス**を管理する場合の使い方について紹介していきます。 +ここでは、`fastapi` コマンド、または `uvicorn` コマンドを直接使って、**ワーカープロセス**付きの **Uvicorn** を使う方法を紹介します。 -/// info +/// info | 情報 - -DockerやKubernetesなどのコンテナを使用している場合は、次の章で詳しく説明します: [コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank} +DockerやKubernetesなどのコンテナを使用している場合は、次の章で詳しく説明します: [コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}。 -特に**Kubernetes**上で実行する場合は、おそらく**Gunicornを使用せず**、**コンテナごとに単一のUvicornプロセス**を実行することになりますが、それについてはこの章の後半で説明します。 +特に**Kubernetes**上で実行する場合は、おそらくワーカーは使わず、代わりに**コンテナごとに単一のUvicornプロセス**を実行したいはずですが、それについてはその章の後半で説明します。 /// -## GunicornによるUvicornのワーカー・プロセスの管理 +## 複数ワーカー { #multiple-workers } -**Gunicorn**は**WSGI標準**のアプリケーションサーバーです。このことは、GunicornはFlaskやDjangoのようなアプリケーションにサービスを提供できることを意味します。Gunicornそれ自体は**FastAPI**と互換性がないですが、というのもFastAPIは最新の**ASGI 標準**を使用しているためです。 +`--workers` コマンドラインオプションで複数のワーカーを起動できます。 -しかし、Gunicornは**プロセスマネージャー**として動作し、ユーザーが特定の**ワーカー・プロセスクラス**を使用するように指示することができます。するとGunicornはそのクラスを使い1つ以上の**ワーカー・プロセス**を開始します。 +//// tab | `fastapi` -そして**Uvicorn**には**Gunicorn互換のワーカークラス**があります。 - -この組み合わせで、Gunicornは**プロセスマネージャー**として動作し、**ポート**と**IP**をリッスンします。そして、**Uvicornクラス**を実行しているワーカー・プロセスに通信を**転送**します。 - -そして、Gunicorn互換の**Uvicornワーカー**クラスが、FastAPIが使えるように、Gunicornから送られてきたデータをASGI標準に変換する役割を担います。 - -## GunicornとUvicornをインストールする +`fastapi` コマンドを使う場合:
```console -$ pip install "uvicorn[standard]" gunicorn +$ fastapi run --workers 4 main.py ----> 100% + FastAPI Starting production server 🚀 + + Searching for package file structure from directories with + __init__.py files + Importing from /home/user/code/awesomeapp + + module 🐍 main.py + + code Importing the FastAPI app object from the module with the + following code: + + from main import app + + app Using import string: main:app + + server Server started at http://0.0.0.0:8000 + server Documentation at http://0.0.0.0:8000/docs + + Logs: + + INFO Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to + quit) + INFO Started parent process [27365] + INFO Started server process [27368] + INFO Started server process [27369] + INFO Started server process [27370] + INFO Started server process [27367] + INFO Waiting for application startup. + INFO Waiting for application startup. + INFO Waiting for application startup. + INFO Waiting for application startup. + INFO Application startup complete. + INFO Application startup complete. + INFO Application startup complete. + INFO Application startup complete. ```
-これによりUvicornと(高性能を得るための)標準(`standard`)の追加パッケージとGunicornの両方がインストールされます。 +//// -## UvicornのワーカーとともにGunicornを実行する +//// tab | `uvicorn` -Gunicornを以下のように起動させることができます: - -
- -```console -$ gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:80 - -[19499] [INFO] Starting gunicorn 20.1.0 -[19499] [INFO] Listening at: http://0.0.0.0:80 (19499) -[19499] [INFO] Using worker: uvicorn.workers.UvicornWorker -[19511] [INFO] Booting worker with pid: 19511 -[19513] [INFO] Booting worker with pid: 19513 -[19514] [INFO] Booting worker with pid: 19514 -[19515] [INFO] Booting worker with pid: 19515 -[19511] [INFO] Started server process [19511] -[19511] [INFO] Waiting for application startup. -[19511] [INFO] Application startup complete. -[19513] [INFO] Started server process [19513] -[19513] [INFO] Waiting for application startup. -[19513] [INFO] Application startup complete. -[19514] [INFO] Started server process [19514] -[19514] [INFO] Waiting for application startup. -[19514] [INFO] Application startup complete. -[19515] [INFO] Started server process [19515] -[19515] [INFO] Waiting for application startup. -[19515] [INFO] Application startup complete. -``` - -
- -それぞれのオプションの意味を見てみましょう: - -* `main:app`: `main`は"`main`"という名前のPythonモジュール、つまりファイル`main.py`を意味します。そして `app` は **FastAPI** アプリケーションの変数名です。 - * main:app`はPythonの`import`文と同じようなものだと想像できます: - - ```Python - from main import app - ``` - - * つまり、`main:app`のコロンは、`from main import app`のPythonの`import`の部分と同じになります。 - -* `--workers`: 使用するワーカー・プロセスの数で、それぞれがUvicornのワーカーを実行します。 - -* `--worker-class`: ワーカー・プロセスで使用するGunicorn互換のワーカークラスです。 - * ここではGunicornがインポートして使用できるクラスを渡します: - - ```Python - import uvicorn.workers.UvicornWorker - ``` - -* `--bind`: GunicornにリッスンするIPとポートを伝えます。コロン(`:`)でIPとポートを区切ります。 - * Uvicornを直接実行している場合は、`--bind 0.0.0.0:80` (Gunicornのオプション)の代わりに、`--host 0.0.0.0`と `--port 80`を使います。 - -出力では、各プロセスの**PID**(プロセスID)が表示されているのがわかります(単なる数字です)。 - -以下の通りです: - -* Gunicornの**プロセス・マネージャー**はPID `19499`(あなたの場合は違う番号でしょう)で始まります。 -* 次に、`Listening at: http://0.0.0.0:80`を開始します。 -* それから `uvicorn.workers.UvicornWorker` でワーカークラスを使用することを検出します。 -* そして、**4つのワーカー**を起動します。それぞれのワーカーのPIDは、`19511`、`19513`、`19514`、`19515`です。 - -Gunicornはまた、ワーカーの数を維持するために必要であれば、**ダウンしたプロセス**を管理し、**新しいプロセスを**再起動**させます。そのため、上記のリストにある**再起動**の概念に一部役立ちます。 - -しかしながら、必要であればGunicornを**再起動**させ、**起動時に実行**させるなど、外部のコンポーネントを持たせることも必要かもしれません。 - -## Uvicornとワーカー - -Uvicornには複数の**ワーカー・プロセス**を起動し実行するオプションもあります。 - -とはいうものの、今のところUvicornのワーカー・プロセスを扱う機能はGunicornよりも制限されています。そのため、このレベル(Pythonレベル)でプロセスマネージャーを持ちたいのであれば、Gunicornをプロセスマネージャーとして使ってみた方が賢明かもしれないです。 - -どんな場合であれ、以下のように実行します: +`uvicorn` コマンドを直接使いたい場合:
@@ -150,36 +105,35 @@ $ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
-ここで唯一の新しいオプションは `--workers` で、Uvicornに4つのワーカー・プロセスを起動するように指示しています。 +//// -各プロセスの **PID** が表示され、親プロセスの `27365` (これは **プロセスマネージャ**) と、各ワーカー・プロセスの **PID** が表示されます: `27368`、`27369`、`27370`、`27367`になります。 +ここで唯一の新しいオプションは `--workers` で、Uvicornに4つのワーカープロセスを起動するように指示しています。 -## デプロイメントのコンセプト +各プロセスの **PID** も表示されていて、親プロセス(これは**プロセスマネージャー**)が `27365`、各ワーカープロセスがそれぞれ `27368`、`27369`、`27370`、`27367` です。 -ここでは、アプリケーションの実行を**並列化**し、CPUの**マルチコア**を活用し、**より多くのリクエスト**に対応できるようにするために、**Gunicorn**(またはUvicorn)を使用して**Uvicornワーカー・プロセス**を管理する方法を見ていきました。 +## デプロイメントのコンセプト { #deployment-concepts } -上記のデプロイのコンセプトのリストから、ワーカーを使うことは主に**レプリケーション**の部分と、**再起動**を少し助けてくれます: +ここでは、複数の **ワーカー** を使ってアプリケーションの実行を**並列化**し、CPUの**複数コア**を活用して、**より多くのリクエスト**を処理できるようにする方法を見てきました。 -* セキュリティ - HTTPS -* 起動時の実行 -* 再起動 +上のデプロイメントのコンセプトのリストから、ワーカーを使うことは主に**レプリケーション**の部分と、**再起動**を少し助けてくれますが、それ以外については引き続き対処が必要です: + +* **セキュリティ - HTTPS** +* **起動時の実行** +* ***再起動*** * レプリケーション(実行中のプロセス数) -* メモリー -* 開始前の事前のステップ +* **メモリ** +* **開始前の事前ステップ** +## コンテナとDocker { #containers-and-docker } -## コンテナとDocker - -次章の[コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}では、その他の**デプロイのコンセプト**を扱うために実施するであろう戦略をいくつか紹介します。 +次章の[コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}では、その他の**デプロイメントのコンセプト**を扱うために使える戦略をいくつか説明します。 -また、**GunicornとUvicornワーカー**を含む**公式Dockerイメージ**と、簡単なケースに役立ついくつかのデフォルト設定も紹介します。 +単一のUvicornプロセスを実行するために、**ゼロから独自のイメージを構築する**方法も紹介します。これは簡単なプロセスで、**Kubernetes**のような分散コンテナ管理システムを使う場合に、おそらくやりたいことでしょう。 -また、(Gunicornを使わずに)Uvicornプロセスを1つだけ実行するために、**ゼロから独自のイメージを**構築する方法も紹介します。これは簡単なプロセスで、おそらく**Kubernetes**のような分散コンテナ管理システムを使うときにやりたいことでしょう。 +## まとめ { #recap } -## まとめ +`fastapi` または `uvicorn` コマンドで `--workers` CLIオプションを使うことで、**マルチコアCPU**を活用し、**複数のプロセスを並列実行**できるように複数のワーカープロセスを利用できます。 -Uvicornワーカーを使ったプロセスマネージャとして**Gunicorn**(またはUvicorn)を使えば、**マルチコアCPU**を活用して**複数のプロセスを並列実行**できます。 +他のデプロイメントのコンセプトを自分で対応しながら、**独自のデプロイシステム**を構築している場合にも、これらのツールやアイデアを使えます。 -これらのツールやアイデアは、**あなた自身のデプロイシステム**をセットアップしながら、他のデプロイコンセプトを自分で行う場合にも使えます。 - -次の章では、コンテナ(DockerやKubernetesなど)を使った**FastAPI**について学んでいきましょう。これらのツールには、他の**デプロイのコンセプト**も解決する簡単な方法があることがわかるでしょう。✨ +次の章で、コンテナ(例:DockerやKubernetes)を使った **FastAPI** について学びましょう。これらのツールにも、他の**デプロイメントのコンセプト**を解決する簡単な方法があることがわかります。✨ diff --git a/docs/ja/docs/deployment/versions.md b/docs/ja/docs/deployment/versions.md index 7575fc4f7..7980b8be2 100644 --- a/docs/ja/docs/deployment/versions.md +++ b/docs/ja/docs/deployment/versions.md @@ -1,93 +1,93 @@ -# FastAPIのバージョンについて +# FastAPIのバージョンについて { #about-fastapi-versions } -**FastAPI** は既に多くのアプリケーションやシステムに本番環境で使われています。また、100%のテストカバレッジを維持しています。しかし、活発な開発が続いています。 +**FastAPI** はすでに多くのアプリケーションやシステムで本番環境にて使われています。また、テストカバレッジは 100% に維持されています。しかし、開発は依然として急速に進んでいます。 -高頻度で新機能が追加され、定期的にバグが修正され、実装は継続的に改善されています。 +新機能が高頻度で追加され、定期的にバグが修正され、コードは継続的に改善されています。 これが現在のバージョンがいまだに `0.x.x` な理由であり、それぞれのバージョンは破壊的な変更がなされる可能性があります。これは、セマンティック バージョニングの規則に則っています。 -**FastAPI** を使用すると本番用アプリケーションをすぐに作成できますが (すでに何度も経験しているかもしれませんが)、残りのコードが正しく動作するバージョンなのか確認しなければいけません。 +**FastAPI** を使用すると本番用アプリケーションを今すぐ作成できます(そして、おそらくあなたはしばらく前からそうしているはずです)。必要なのは、残りのコードと正しく動作するバージョンを使用していることを確認することだけです。 -## `fastapi` のバージョンを固定 +## `fastapi` のバージョンを固定 { #pin-your-fastapi-version } -最初にすべきことは、アプリケーションが正しく動作する **FastAPI** のバージョンを固定することです。 +最初にすべきことは、使用している **FastAPI** のバージョンを、アプリケーションで正しく動作することが分かっている特定の最新バージョンに「固定(pin)」することです。 -例えば、バージョン `0.45.0` を使っているとしましょう。 +例えば、アプリでバージョン `0.112.0` を使っているとしましょう。 -`requirements.txt` を使っているなら、以下の様にバージョンを指定できます: +`requirements.txt` ファイルを使う場合は、以下のようにバージョンを指定できます: ```txt -fastapi==0.45.0 +fastapi[standard]==0.112.0 ``` -これは、厳密にバージョン `0.45.0` だけを使うことを意味します。 +これは、厳密にバージョン `0.112.0` だけを使うことを意味します。 -または、以下の様に固定することもできます: +または、以下のように固定することもできます: + +```txt +fastapi[standard]>=0.112.0,<0.113.0 +``` + +これは `0.112.0` 以上、`0.113.0` 未満のバージョンを使うことを意味します。例えば、バージョン `0.112.2` は使用可能です。 + +`uv`、Poetry、Pipenv など、他のインストール管理ツールを使用している場合でも、いずれもパッケージの特定バージョンを定義する方法があります。 + +## 利用可能なバージョン { #available-versions } + +利用可能なバージョン(例: 現在の最新が何かを確認するため)は、[Release Notes](../release-notes.md){.internal-link target=_blank} で確認できます。 + +## バージョンについて { #about-versions } + +セマンティック バージョニングの規約に従って、`1.0.0` 未満のバージョンは破壊的な変更が加わる可能性があります。 + +FastAPI では「PATCH」バージョンの変更はバグ修正と非破壊的な変更に使う、という規約にも従っています。 + +/// tip | 豆知識 + +「PATCH」は最後の数字です。例えば、`0.2.3` では PATCH バージョンは `3` です。 + +/// + +従って、以下のようなバージョンの固定ができるはずです: ```txt fastapi>=0.45.0,<0.46.0 ``` -これは `0.45.0` 以上、`0.46.0` 未満のバージョンを使うことを意味します。例えば、バージョン `0.45.2` は使用可能です。 - -PoetryやPipenvなど、他のインストール管理ツールを使用している場合でも、それぞれパッケージのバージョンを指定する機能があります。 - -## 利用可能なバージョン - -[Release Notes](../release-notes.md){.internal-link target=_blank}で利用可能なバージョンが確認できます (現在の最新版の確認などのため)。 - -## バージョンについて - -セマンティック バージョニングの規約に従って、`1.0.0` 未満の全てのバージョンは破壊的な変更が加わる可能性があります。 - -FastAPIでは「パッチ」バージョンはバグ修正と非破壊的な変更に留めるという規約に従っています。 +破壊的な変更と新機能は「MINOR」バージョンで追加されます。 /// tip | 豆知識 -「パッチ」は最後の数字を指します。例えば、`0.2.3` ではパッチバージョンは `3` です。 +「MINOR」は真ん中の数字です。例えば、`0.2.3` では MINOR バージョンは `2` です。 /// -従って、以下の様なバージョンの固定が望ましいです: +## FastAPIのバージョンのアップグレード { #upgrading-the-fastapi-versions } -```txt -fastapi>=0.45.0,<0.46.0 -``` +アプリケーションにテストを追加すべきです。 -破壊的な変更と新機能実装は「マイナー」バージョンで加えられます。 +**FastAPI** では非常に簡単に実現できます(Starlette のおかげです)。ドキュメントを確認して下さい: [テスト](../tutorial/testing.md){.internal-link target=_blank} -/// tip | 豆知識 +テストを追加したら、**FastAPI** のバージョンをより新しいものにアップグレードし、テストを実行することで全てのコードが正しく動作するか確認できます。 -「マイナー」は真ん中の数字です。例えば、`0.2.3` ではマイナーバージョンは `2` です。 +全てが動作する、または必要な変更を行った後に全てのテストが通るなら、その新しいバージョンに `fastapi` を固定できます。 -/// +## Starletteについて { #about-starlette } -## FastAPIのバージョンのアップグレード +`starlette` のバージョンは固定すべきではありません。 -アプリケーションにテストを加えるべきです。 +**FastAPI** のバージョンが異なれば、Starlette の特定のより新しいバージョンが使われます。 -**FastAPI** では非常に簡単に実現できます (Starletteのおかげで)。ドキュメントを確認して下さい: [テスト](../tutorial/testing.md){.internal-link target=_blank} +そのため、正しい Starlette バージョンを **FastAPI** に任せればよいです。 -テストを加えた後で、**FastAPI** のバージョンをより最新のものにアップグレードし、テストを実行することで全てのコードが正常に動作するか確認できます。 +## Pydanticについて { #about-pydantic } -全てが動作するか、修正を行った上で全てのテストを通過した場合、使用している`fastapi` のバージョンをより最新のバージョンに固定できます。 +Pydantic は自身のテストに **FastAPI** のテストも含んでいるため、Pydantic の新しいバージョン(`1.0.0` より上)は常に FastAPI と互換性があります。 -## Starletteについて - -`Starlette` のバージョンは固定すべきではありません。 - -**FastAPI** は、バージョン毎にStarletteのより新しいバージョンを使用します。 - -よって、最適なStarletteのバージョン選択を**FastAPI** に任せることができます。 - -## Pydanticについて - -Pydanticは自身のテストだけでなく**FastAPI** のためのテストを含んでいます。なので、Pydanticの新たなバージョン ( `1.0.0` 以降) は全てFastAPIと整合性があります。 - -Pydanticのバージョンを、動作が保証できる`1.0.0`以降のいずれかのバージョンから`2.0.0` 未満の間に固定できます。 +Pydantic は、自分にとって動作する `1.0.0` より上の任意のバージョンに固定できます。 例えば: ```txt -pydantic>=1.2.0,<2.0.0 +pydantic>=2.7.0,<3.0.0 ``` diff --git a/docs/ja/docs/environment-variables.md b/docs/ja/docs/environment-variables.md index 507af3a0c..45dbfc71f 100644 --- a/docs/ja/docs/environment-variables.md +++ b/docs/ja/docs/environment-variables.md @@ -1,18 +1,18 @@ -# 環境変数 +# 環境変数 { #environment-variables } -/// tip +/// tip | 豆知識 もし、「環境変数」とは何か、それをどう使うかを既に知っている場合は、このセクションをスキップして構いません。 /// -環境変数(**env var**とも呼ばれる)はPythonコードの**外側**、つまり**OS**に存在する変数で、Pythonから読み取ることができます。(他のプログラムでも同様に読み取れます。) +環境変数(「**env var**」とも呼ばれます)とは、Pythonコードの**外側**、つまり**オペレーティングシステム**に存在する変数で、Pythonコード(または他のプログラム)から読み取れます。 -環境変数は、アプリケーションの**設定**の管理や、Pythonの**インストール**などに役立ちます。 +環境変数は、アプリケーションの**設定**の扱い、Pythonの**インストール**の一部などで役立ちます。 -## 環境変数の作成と使用 +## 環境変数の作成と使用 { #create-and-use-env-vars } -環境変数は**シェル(ターミナル)**内で**作成**して使用でき、それらにPythonは不要です。 +環境変数は、Pythonを必要とせず、**シェル(ターミナル)**で**作成**して使用できます。 //// tab | Linux, macOS, Windows Bash @@ -36,7 +36,6 @@ Hello Wade Wilson
- ```console // Create an env var MY_NAME $ $Env:MY_NAME = "Wade Wilson" @@ -51,9 +50,9 @@ Hello Wade Wilson //// -## Pythonで環境変数を読み取る +## Pythonで環境変数を読み取る { #read-env-vars-in-python } -環境変数をPythonの**外側**、ターミナル(や他の方法)で作成し、**Python内で読み取る**こともできます。 +環境変数はPythonの**外側**(ターミナル、またはその他の方法)で作成し、その後に**Pythonで読み取る**こともできます。 例えば、以下のような`main.py`ファイルを用意します: @@ -64,11 +63,11 @@ name = os.getenv("MY_NAME", "World") print(f"Hello {name} from Python") ``` -/// tip +/// tip | 豆知識 -`os.getenv()` の第2引数は、デフォルトで返される値を指定します。 +`os.getenv()` の第2引数は、デフォルトで返される値です。 -この引数を省略するとデフォルト値として`None`が返されますが、ここではデフォルト値として`"World"`を指定しています。 +指定しない場合、デフォルトは`None`ですが、ここでは使用するデフォルト値として`"World"`を指定しています。 /// @@ -128,11 +127,11 @@ Hello Wade Wilson from Python //// -環境変数はコードの外側で設定し、内側から読み取ることができるので、他のファイルと一緒に(`git`に)保存する必要がありません。そのため、環境変数をコンフィグレーションや**設定**に使用することが一般的です。 +環境変数はコードの外側で設定でき、コードから読み取れ、他のファイルと一緒に(`git`に)保存(コミット)する必要がないため、設定や**settings**に使うのが一般的です。 -また、**特定のプログラムの呼び出し**のための環境変数を、そのプログラムのみ、その実行中に限定して利用できるよう作成できます。 +また、**特定のプログラムの呼び出し**のためだけに、そのプログラムでのみ、実行中の間だけ利用できる環境変数を作成することもできます。 -そのためには、プログラム起動コマンドと同じコマンドライン上の、起動コマンド直前で環境変数を作成してください。 +そのためには、同じ行で、プログラム自体の直前に作成してください。
@@ -152,25 +151,25 @@ Hello World from Python
-/// tip +/// tip | 豆知識 詳しくは The Twelve-Factor App: Config を参照してください。 /// -## 型とバリデーション +## 型とバリデーション { #types-and-validation } -環境変数は**テキスト文字列**のみを扱うことができます。これは、環境変数がPython外部に存在し、他のプログラムやシステム全体(Linux、Windows、macOS間の互換性を含む)と連携する必要があるためです。 +これらの環境変数が扱えるのは**テキスト文字列**のみです。環境変数はPythonの外部にあり、他のプログラムやシステム全体(Linux、Windows、macOSなど異なるオペレーティングシステム間も)との互換性が必要になるためです。 -つまり、Pythonが環境変数から読み取る**あらゆる値**は **`str`型となり**、他の型への変換やバリデーションはコード内で行う必要があります。 +つまり、環境変数からPythonで読み取る**あらゆる値**は **`str`になり**、他の型への変換やバリデーションはコード内で行う必要があります。 -環境変数を使用して**アプリケーション設定**を管理する方法については、[高度なユーザーガイド - Settings and Environment Variables](./advanced/settings.md){.internal-link target=_blank}で詳しく学べます。 +環境変数を使って**アプリケーション設定**を扱う方法については、[高度なユーザーガイド - Settings and Environment Variables](./advanced/settings.md){.internal-link target=_blank} で詳しく学べます。 -## `PATH`環境変数 +## `PATH`環境変数 { #path-environment-variable } -**`PATH`**という**特別な**環境変数があります。この環境変数は、OS(Linux、macOS、Windows)が実行するプログラムを発見するために使用されます。 +**`PATH`**という**特別な**環境変数があります。これはオペレーティングシステム(Linux、macOS、Windows)が実行するプログラムを見つけるために使用されます。 -`PATH`変数は、複数のディレクトリのパスから成る長い文字列です。このパスはLinuxやMacOSの場合は`:`で、Windowsの場合は`;`で区切られています。 +変数`PATH`の値は長い文字列で、LinuxとmacOSではコロン`:`、Windowsではセミコロン`;`で区切られたディレクトリで構成されます。 例えば、`PATH`環境変数は次のような文字列かもしれません: @@ -180,7 +179,7 @@ Hello World from Python /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin ``` -これは、OSはプログラムを見つけるために以下のディレクトリを探す、ということを意味します: +これは、システムが次のディレクトリでプログラムを探すことを意味します: * `/usr/local/bin` * `/usr/bin` @@ -196,7 +195,7 @@ Hello World from Python C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32 ``` -これは、OSはプログラムを見つけるために以下のディレクトリを探す、ということを意味します: +これは、システムが次のディレクトリでプログラムを探すことを意味します: * `C:\Program Files\Python312\Scripts` * `C:\Program Files\Python312` @@ -204,63 +203,61 @@ C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System3 //// -ターミナル上で**コマンド**を入力すると、 OSはそのプログラムを見つけるために、`PATH`環境変数のリストに記載された**それぞれのディレクトリを探し**ます。 +ターミナル上で**コマンド**を入力すると、オペレーティングシステムは`PATH`環境変数に記載された**それぞれのディレクトリ**の中からプログラムを**探し**ます。 -例えば、ターミナル上で`python`を入力すると、OSは`python`によって呼ばれるプログラムを見つけるために、そのリストの**先頭のディレクトリ**を最初に探します。 +例えば、ターミナルで`python`と入力すると、オペレーティングシステムはそのリストの**最初のディレクトリ**で`python`というプログラムを探します。 -OSは、もしそのプログラムをそこで発見すれば**実行し**ますが、そうでなければリストの**他のディレクトリ**を探していきます。 +見つかればそれを**使用**します。見つからなければ、**他のディレクトリ**を探し続けます。 -### PythonのインストールとPATH環境変数の更新 +### Pythonのインストールと`PATH`の更新 { #installing-python-and-updating-the-path } -Pythonのインストール時に`PATH`環境変数を更新したいか聞かれるかもしれません。 +Pythonのインストール時に、`PATH`環境変数を更新するかどうかを尋ねられるかもしれません。 -/// tab | Linux, macOS +//// tab | Linux, macOS -Pythonをインストールして、そのプログラムが`/opt/custompython/bin`というディレクトリに配置されたとします。 +Pythonをインストールして、その結果`/opt/custompython/bin`というディレクトリに配置されたとします。 -もし、`PATH`環境変数を更新するように答えると、`PATH`環境変数に`/opt/custompython/bin`が追加されます。 +`PATH`環境変数を更新することに同意すると、インストーラーは`PATH`環境変数に`/opt/custompython/bin`を追加します。 -`PATH`環境変数は以下のように更新されるでしょう: +例えば次のようになります: -``` plaintext +```plaintext /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin ``` -このようにして、ターミナルで`python`と入力したときに、OSは`/opt/custompython/bin`(リストの末尾のディレクトリ)にあるPythonプログラムを見つけ、使用します。 +このようにして、ターミナルで`python`と入力すると、システムは`/opt/custompython/bin`(最後のディレクトリ)にあるPythonプログラムを見つけ、それを使用します。 -/// +//// -/// tab | Windows +//// tab | Windows -Pythonをインストールして、そのプログラムが`C:\opt\custompython\bin`というディレクトリに配置されたとします。 +Pythonをインストールして、その結果`C:\opt\custompython\bin`というディレクトリに配置されたとします。 -もし、`PATH`環境変数を更新するように答えると、`PATH`環境変数に`C:\opt\custompython\bin`が追加されます。 - -`PATH`環境変数は以下のように更新されるでしょう: +`PATH`環境変数を更新することに同意すると、インストーラーは`PATH`環境変数に`C:\opt\custompython\bin`を追加します。 ```plaintext C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin ``` -このようにして、ターミナルで`python`と入力したときに、OSは`C:\opt\custompython\bin\python`(リストの末尾のディレクトリ)にあるPythonプログラムを見つけ、使用します。 +このようにして、ターミナルで`python`と入力すると、システムは`C:\opt\custompython\bin`(最後のディレクトリ)にあるPythonプログラムを見つけ、それを使用します。 -/// +//// -つまり、ターミナルで以下のコマンドを入力すると: +つまり、ターミナルで次のように入力すると:
-``` console +```console $ python ```
-/// tab | Linux, macOS +//// tab | Linux, macOS -OSは`/opt/custompython/bin`にある`python`プログラムを**見つけ**て実行します。 +システムは`/opt/custompython/bin`にある`python`プログラムを**見つけ**て実行します。 -これは、次のコマンドを入力した場合とほとんど同等です: +これは、次のように入力するのとおおむね同等です:
@@ -270,13 +267,13 @@ $ /opt/custompython/bin/python
-/// +//// -/// tab | Windows +//// tab | Windows -OSは`C:\opt\custompython\bin\python`にある`python`プログラムを**見つけ**て実行します。 +システムは`C:\opt\custompython\bin\python`にある`python`プログラムを**見つけ**て実行します。 -これは、次のコマンドを入力した場合とほとんど同等です: +これは、次のように入力するのとおおむね同等です:
@@ -286,16 +283,16 @@ $ C:\opt\custompython\bin\python
-/// +//// -この情報は、[Virtual Environments](virtual-environments.md) について学ぶ際にも役立ちます。 +この情報は、[Virtual Environments](virtual-environments.md){.internal-link target=_blank} について学ぶ際にも役立ちます。 -## まとめ +## まとめ { #conclusion } これで、**環境変数**とは何か、Pythonでどのように使用するかについて、基本的な理解が得られたはずです。 -環境変数についての詳細は、Wikipedia: Environment Variable を参照してください。 +環境変数についての詳細は、Wikipedia for Environment Variable も参照してください。 -環境変数の用途や適用方法が最初は直感的ではないかもしれませんが、開発中のさまざまなシナリオで繰り返し登場します。そのため、基本を知っておくことが重要です。 +多くの場合、環境変数がどのように役立ち、すぐに適用できるのかはあまり明確ではありません。しかし、開発中のさまざまなシナリオで何度も登場するため、知っておくとよいでしょう。 -たとえば、この情報は次のセクションで扱う[Virtual Environments](virtual-environments.md)にも関連します。 +例えば、次のセクションの[Virtual Environments](virtual-environments.md)でこの情報が必要になります。 diff --git a/docs/ja/docs/how-to/conditional-openapi.md b/docs/ja/docs/how-to/conditional-openapi.md index bfaa9e6d7..9478f5c03 100644 --- a/docs/ja/docs/how-to/conditional-openapi.md +++ b/docs/ja/docs/how-to/conditional-openapi.md @@ -1,8 +1,8 @@ -# 条件付き OpenAPI +# 条件付き OpenAPI { #conditional-openapi } 必要であれば、設定と環境変数を利用して、環境に応じて条件付きでOpenAPIを構成することが可能です。また、完全にOpenAPIを無効にすることもできます。 -## セキュリティとAPI、およびドキュメントについて +## セキュリティとAPI、およびドキュメントについて { #about-security-apis-and-docs } 本番環境においてドキュメントのUIを非表示にすることによって、APIを保護しようと *すべきではありません*。 @@ -17,19 +17,19 @@ * リクエストボディとレスポンスのためのPydanticモデルの定義を見直す。 * 依存関係に基づきすべての必要なパーミッションとロールを設定する。 * パスワードを絶対に平文で保存しない。パスワードハッシュのみを保存する。 -* PasslibやJWTトークンに代表される、よく知られた暗号化ツールを使って実装する。 +* pwdlibやJWTトークンに代表される、よく知られた暗号化ツールを使って実装する。 * そして必要なところでは、もっと細かいパーミッション制御をOAuth2スコープを使って行う。 -* など +* ...など それでも、例えば本番環境のような特定の環境のみで、あるいは環境変数の設定によってAPIドキュメントをどうしても無効にしたいという、非常に特殊なユースケースがあるかもしれません。 -## 設定と環境変数による条件付き OpenAPI +## 設定と環境変数による条件付き OpenAPI { #conditional-openapi-from-settings-and-env-vars } 生成するOpenAPIとドキュメントUIの構成は、共通のPydanticの設定を使用して簡単に切り替えられます。 例えば、 -{* ../../docs_src/conditional_openapi/tutorial001.py hl[6,11] *} +{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *} ここでは `openapi_url` の設定を、デフォルトの `"/openapi.json"` のまま宣言しています。 diff --git a/docs/ja/docs/index.md b/docs/ja/docs/index.md index 8dee1ee03..271acf6cb 100644 --- a/docs/ja/docs/index.md +++ b/docs/ja/docs/index.md @@ -1,4 +1,4 @@ -# FastAPI +# FastAPI { #fastapi }