]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
🌐 Update translations for ja (update-outdated) (#14588)
authorSebastián Ramírez <tiangolo@gmail.com>
Wed, 4 Feb 2026 16:44:21 +0000 (08:44 -0800)
committerGitHub <noreply@github.com>
Wed, 4 Feb 2026 16:44:21 +0000 (17:44 +0100)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: Maruo.S <raspi-maru2004@outlook.jp>
63 files changed:
docs/en/mkdocs.yml
docs/ja/docs/advanced/additional-status-codes.md
docs/ja/docs/advanced/custom-response.md
docs/ja/docs/advanced/index.md
docs/ja/docs/advanced/path-operation-advanced-configuration.md
docs/ja/docs/advanced/response-directly.md
docs/ja/docs/advanced/websockets.md
docs/ja/docs/benchmarks.md
docs/ja/docs/deployment/concepts.md
docs/ja/docs/deployment/docker.md
docs/ja/docs/deployment/https.md
docs/ja/docs/deployment/index.md
docs/ja/docs/deployment/server-workers.md
docs/ja/docs/deployment/versions.md
docs/ja/docs/environment-variables.md
docs/ja/docs/how-to/conditional-openapi.md
docs/ja/docs/index.md
docs/ja/docs/learn/index.md
docs/ja/docs/project-generation.md
docs/ja/docs/python-types.md
docs/ja/docs/tutorial/background-tasks.md
docs/ja/docs/tutorial/body-fields.md
docs/ja/docs/tutorial/body-multiple-params.md
docs/ja/docs/tutorial/body-nested-models.md
docs/ja/docs/tutorial/body-updates.md
docs/ja/docs/tutorial/body.md
docs/ja/docs/tutorial/cookie-param-models.md
docs/ja/docs/tutorial/cookie-params.md
docs/ja/docs/tutorial/cors.md
docs/ja/docs/tutorial/debugging.md
docs/ja/docs/tutorial/dependencies/classes-as-dependencies.md
docs/ja/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
docs/ja/docs/tutorial/dependencies/dependencies-with-yield.md
docs/ja/docs/tutorial/dependencies/index.md
docs/ja/docs/tutorial/dependencies/sub-dependencies.md
docs/ja/docs/tutorial/encoder.md
docs/ja/docs/tutorial/extra-data-types.md
docs/ja/docs/tutorial/extra-models.md
docs/ja/docs/tutorial/first-steps.md
docs/ja/docs/tutorial/handling-errors.md
docs/ja/docs/tutorial/header-params.md
docs/ja/docs/tutorial/index.md
docs/ja/docs/tutorial/metadata.md
docs/ja/docs/tutorial/middleware.md
docs/ja/docs/tutorial/path-operation-configuration.md
docs/ja/docs/tutorial/path-params-numeric-validations.md
docs/ja/docs/tutorial/path-params.md
docs/ja/docs/tutorial/query-param-models.md
docs/ja/docs/tutorial/query-params-str-validations.md
docs/ja/docs/tutorial/query-params.md
docs/ja/docs/tutorial/request-forms-and-files.md
docs/ja/docs/tutorial/request-forms.md
docs/ja/docs/tutorial/response-model.md
docs/ja/docs/tutorial/response-status-code.md
docs/ja/docs/tutorial/schema-extra-example.md
docs/ja/docs/tutorial/security/first-steps.md
docs/ja/docs/tutorial/security/get-current-user.md
docs/ja/docs/tutorial/security/oauth2-jwt.md
docs/ja/docs/tutorial/static-files.md
docs/ja/docs/tutorial/testing.md
docs/ja/docs/virtual-environments.md
docs/ja/llm-prompt.md
scripts/docs.py

index 1c29546198f0dbff49b0f4c874c3c3fb4cbeb0a2..34d489d92a48356ff6df8f9a29ee06043453c8a8 100644 (file)
@@ -317,6 +317,8 @@ extra:
     name: de - Deutsch
   - link: /es/
     name: es - español
+  - link: /ja/
+    name: ja - 日本語
   - link: /ko/
     name: ko - 한국어
   - link: /pt/
index 33457f591ce961f0100c3d1f051b58490a7161b7..14b7e8ba87cf14d957f50d6315fa29c78d229719 100644 (file)
@@ -1,41 +1,41 @@
-# 追加のステータスコード
+# 追加のステータスコード { #additional-status-codes }
 
\83\87ã\83\95ã\82©ã\83«ã\83\88ã\81§ã\81¯ã\80\81 **FastAPI** ã\81¯ `JSONResponse` ã\82\92使ã\81£ã\81¦ã\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\82\92è¿\94ã\81\97ã\81¾ã\81\99ã\80\82ã\81\9dã\81® `JSONResponse` ã\81®ä¸­ã\81«ã\81¯ã\80\81 *path operation* ã\81\8cè¿\94ã\81\97ã\81\9få\86\85容ã\81\8cå\85¥ã\82\8aます。
\83\87ã\83\95ã\82©ã\83«ã\83\88ã\81§ã\81¯ã\80\81 **FastAPI** ã\81¯ `JSONResponse` ã\82\92使ã\81£ã\81¦ã\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\82\92è¿\94ã\81\97ã\80\81*path operation* ã\81\8bã\82\89è¿\94ã\81\97ã\81\9få\86\85容ã\82\92ã\81\9dã\81® `JSONResponse` ã\81®ä¸­ã\81«å\85¥ã\82\8cます。
 
\81\9dã\82\8cã\81¯ã\80\81ã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\81®ã\82¹ã\83\86ã\83¼ã\82¿ã\82¹ã\82³ã\83¼ã\83\89ã\81\8bã\80\81 *path operation* ã\81§ã\82»ã\83\83ã\83\88ã\81\97ã\81\9fã\82\82ã\81®ã\82\92å\88©ç\94¨ã\81\97ます。
\83\87ã\83\95ã\82©ã\83«ã\83\88ã\81®ã\82¹ã\83\86ã\83¼ã\82¿ã\82¹ã\82³ã\83¼ã\83\89ã\80\81ã\81¾ã\81\9fã\81¯ *path operation* ã\81§è¨­å®\9aã\81\97ã\81\9fã\82¹ã\83\86ã\83¼ã\82¿ã\82¹ã\82³ã\83¼ã\83\89ã\81\8c使ç\94¨ã\81\95ã\82\8cます。
 
-## 追加のステータスコード
+## 追加のステータスコード { #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` を直接返すと、それはそのまま返されます。
 
\83¢ã\83\87ã\83«ã\81ªã\81©ã\81¯シリアライズされません。
\83¢ã\83\87ã\83«ã\81ªã\81©ã\81«ã\82\88ã\81£ã\81¦シリアライズされません。
 
-å¿\85è¦\81ã\81ªã\83\87ã\83¼ã\82¿ã\81\8cå\90«ã\81¾ã\82\8cã\81¦ã\81\84ã\82\8bã\81\93ã\81¨ã\82\84ã\80\81å\80¤ã\81\8cæ\9c\89å\8a¹ã\81ªJSONã\81§ã\81\82ã\82\8bã\81\93ã\81¨ (`JSONResponse` ã\82\92使ã\81\86å ´å\90\88を確認してください。
+å¿\85è¦\81ã\81ªã\83\87ã\83¼ã\82¿ã\81\8cå\90«ã\81¾ã\82\8cã\81¦ã\81\84ã\82\8bã\81\93ã\81¨ã\80\81ã\81\9dã\81\97ã\81¦ï¼\88`JSONResponse` ã\82\92使ç\94¨ã\81\97ã\81¦ã\81\84ã\82\8bå ´å\90\88ï¼\89å\80¤ã\81\8cæ\9c\89å\8a¹ã\81ª JSON ã\81§ã\81\82ã\82\8bã\81\93ã\81¨を確認してください。
 
 ///
 
 /// note | 技術詳細
 
-`from starlette.responses import JSONResponse` を利用することもできます。
+`from starlette.responses import JSONResponse` を使うこともできます。
 
-**FastAPI** は `fastapi.responses` ã\81¨å\90\8cã\81\98 `starlette.responses` ã\82\92ã\80\81é\96\8bç\99ºè\80\85ã\81®å\88©ä¾¿æ\80§ã\81®ã\81\9fã\82\81ã\81«æ\8f\90ä¾\9bã\81\97ã\81¦ã\81\84ã\81¾ã\81\99ã\80\82ã\81\97ã\81\8bã\81\97æ\9c\89å\8a¹ã\81ªã\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\81¯ã\81»ã\81¨ã\82\93ã\81©Starletteã\81\8bã\82\89æ\9d¥ã\81¦ã\81\84ã\81¾ã\81\99ã\80\82 `status` ã\81«ã\81¤ã\81\84ã\81¦ã\82\82å\90\8cã\81\98ã\81§ã\81\99ã\80\82
+**FastAPI** はé\96\8bç\99ºè\80\85ã\81®å\88©ä¾¿æ\80§ã\81®ã\81\9fã\82\81ã\81«ã\80\81`fastapi.responses` ã\81¨å\90\8cã\81\98 `starlette.responses` ã\82\92æ\8f\90ä¾\9bã\81\97ã\81¦ã\81\84ã\81¾ã\81\99ã\80\82ã\81\97ã\81\8bã\81\97ã\80\81å\88©ç\94¨å\8f¯è\83½ã\81ªã\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\81®ã\81»ã\81¨ã\82\93ã\81©ã\81¯ Starlette ã\81\8bã\82\89ç\9b´æ\8e¥æ\8f\90ä¾\9bã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99ã\80\82`status` ã\82\82å\90\8cæ§\98ã\81§ã\81\99ã\80\82
 
 ///
 
-## 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} を使ってコード内にドキュメント化できます。
index 1b2cd914d404c28c23a51a59318451b189f4e505..9d881c013c9e55b364f4eb81d92eaeba44d55934 100644 (file)
@@ -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` パラメータを使用して、*path operation デコレータ* で使用したい `Response`(任意の `Response` サブクラス)を宣言することもできます。
 
-*path operation関数* から返されるコンテンツは、その `Response` に含まれます。
+*path operation 関数* から返されるコンテンツは、その `Response` に含まれます。
 
\81\9dã\81\97ã\81¦ã\82\82ã\81\97ã\80\81`Response` ã\81\8cã\80\81`JSONResponse` ã\82\84 `UJSONResponse` ã\81®å ´å\90\88ã\81®ã\82\88ã\81\86ã\81«JSONã\83¡ã\83\87ã\82£ã\82¢ã\82¿ã\82¤ã\83\97 (`application/json`) ã\81ªã\82\89ã\81°ã\80\81ã\83\87ã\83¼ã\82¿ã\81¯ *path operationã\83\87ã\82³ã\83¬ã\83¼ã\82¿* ã\81«å®£è¨\80ã\81\97ã\81\9fPydantic `response_model` ã\81«ã\82\88ã\82\8aè\87ªå\8b\95ç\9a\84ã\81«å¤\89æ\8f\9b (ã\82\82ã\81\97ã\81\8fã\81¯ã\83\95ã\82£ã\83«ã\82¿) されます。
\81\9dã\81\97ã\81¦ã\81\9dã\81® `Response` ã\81\8cã\80\81`JSONResponse` ã\82\84 `UJSONResponse` ã\81®å ´å\90\88ã\81®ã\82\88ã\81\86ã\81«JSONã\83¡ã\83\87ã\82£ã\82¢ã\82¿ã\82¤ã\83\97ï¼\88`application/json`ï¼\89ã\81ªã\82\89ã\80\81é\96¢æ\95°ã\81®è¿\94ã\82\8aå\80¤ã\81¯ *path operationã\83\87ã\82³ã\83¬ã\83¼ã\82¿* ã\81«å®£è¨\80ã\81\97ã\81\9fä»»æ\84\8fã\81®Pydantic `response_model` ã\81«ã\82\88ã\82\8aè\87ªå\8b\95ç\9a\84ã\81«å¤\89æ\8f\9bï¼\88ã\81\8aã\82\88ã\81³ã\83\95ã\82£ã\83«ã\82¿ï¼\89されます。
 
 /// note | 備考
 
-メディアタイプを指定せずにレスポンスクラスを利用すると、FastAPIは何もコンテンツがないことを期待します。そのため、生成されるOpenAPIドキュメントにレスポンスフォーマットが記載されません。
+メディアタイプを指定せずにレスポンスクラスを利用すると、FastAPIはレスポンスにコンテンツがないことを期待します。そのため、生成されるOpenAPIドキュメントにレスポンスフォーマットが記載されません。
 
 ///
 
-## `ORJSONResponse` を使う
+## `ORJSONResponse` を使う { #use-orjsonresponse }
 
-例えば、パフォーマンスを出したい場合は、<a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>をインストールし、`ORJSONResponse`をレスポンスとしてセットすることができます。
+例えば、パフォーマンスを絞り出したい場合は、<a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>をインストールし、レスポンスとして `ORJSONResponse` をセットできます。
 
-使いたい `Response` クラス (サブクラス) をインポートし、 *path operationデコレータ* に宣言します。
+使いたい `Response` クラス(サブクラス)をインポートし、*path operationデコレータ* に宣言します。
 
-{* ../../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` がセットされます。
 
 
 /// tip | 豆知識
 
-`ORJSONResponse` は、現在はFastAPIのみで利用可能で、Starletteでは利用できません。
+`ORJSONResponse` はFastAPIでのみ利用可能で、Starletteでは利用できません。
 
 ///
 
-## HTMLレスポンス
+## HTMLレスポンス { #html-response }
 
 **FastAPI** からHTMLを直接返す場合は、`HTMLResponse` を使います。
 
 * `HTMLResponse` をインポートする。
-* *path operation* のパラメータ `content_type` に `HTMLResponse` を渡す。
+* *path operation デコレータ* のパラメータ `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}で見たように、レスポンスを返すことで、*path operation* の中でレスポンスを直接オーバーライドすることもできます。
 
 上記と同じ例において、 `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` がドキュメントされない) 、自動的な対話的ドキュメントからも閲覧できません。
+*path operation関数* から直接返される `Response` は、OpenAPIにドキュメントされず(例えば、`Content-Type` がドキュメントされない)、自動的な対話的ドキュメントでも表示されません。
 
 ///
 
 /// info | 情報
 
\82\82ã\81¡ã\82\8dã\82\93ã\80\81å®\9fé\9a\9bã\81® `Content-Type` ã\83\98ã\83\83ã\83\80ã\83¼ã\82\84ã\82¹ã\83\86ã\83¼ã\82¿ã\82¹ã\82³ã\83¼ã\83\89ã\81ªã\81©ã\81¯ã\80\81è¿\94ã\81\95ã\82\8cã\81\9f `Response` ã\82ªã\83\96ã\82¸ã\82§ã\82¯ã\83\88ã\81«ç\94±æ\9d¥ã\81\97ã\81¦ã\81\84ã\81¾ã\81\99ã\80\82
+もちろん、実際の `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の*path operation*のドキュメント化のためにのみ使用され、`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としてどのようにドキュメント化すればよいかを理解できます:
 
 <img src="/img/tutorial/custom-response/image01.png">
 
-## 利用可能なレスポンス
+## 利用可能なレスポンス { #available-responses }
 
 以下が利用可能なレスポンスの一部です。
 
 
 `from starlette.responses import HTMLResponse` も利用できます。
 
-**FastAPI** は開発者の利便性のために `fastapi.responses` として `starlette.responses` と同じものを提供しています。しかし、利用可能なレスポンスのほとんどはStarletteから直接提供されます。
+**FastAPI** は開発者の利便性のために、`starlette.responses` と同じものを `fastapi.responses` として提供しています。しかし、利用可能なレスポンスのほとんどはStarletteから直接提供されます。
 
 ///
 
-### `Response`
+### `Response` { #response }
 
 メインの `Response` クラスで、他の全てのレスポンスはこれを継承しています。
 
 * `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 }
 
 上で読んだように、<a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>を使った、高速な代替のJSONレスポンスです。
 
-### `UJSONResponse`
+/// info | 情報
+
+これは、例えば `pip install orjson` で `orjson` をインストールする必要があります。
+
+///
+
+### `UJSONResponse` { #ujsonresponse }
 
 <a href="https://github.com/ultrajson/ultrajson" class="external-link" target="_blank">`ujson`</a>を使った、代替のJSONレスポンスです。
 
+/// info | 情報
+
+これは、例えば `pip install ujson` で `ujson` をインストールする必要があります。
+
+///
+
 /// warning | 注意
 
-`ujson` ã\81¯ã\80\81ã\81\84ã\81\8fã\81¤ã\81\8bã\81®ã\82¨ã\83\83ã\82¸ã\82±ã\83¼ã\82¹ã\81®å\8f\96ã\82\8aæ\89±ã\81\84ã\81«ã\81¤ã\81\84ã\81¦ã\80\81Pythonã\81«ã\83\93ã\83«ã\83\88ã\82¤ã\83³ã\81\95ã\82\8cã\81\9få®\9fè£\85ã\82\88ã\82\8aã\82\82ä½\9cã\82\8aã\81\93ã\81¾ã\82\8cã\81¦ã\81\84ません。
+`ujson` ã\81¯ã\80\81ã\81\84ã\81\8fã\81¤ã\81\8bã\81®ã\82¨ã\83\83ã\82¸ã\82±ã\83¼ã\82¹ã\81®å\8f\96ã\82\8aæ\89±ã\81\84ã\81«ã\81¤ã\81\84ã\81¦ã\80\81Pythonã\81«ã\83\93ã\83«ã\83\88ã\82¤ã\83³ã\81\95ã\82\8cã\81\9få®\9fè£\85ã\81»ã\81©æ³¨æ\84\8fæ·±ã\81\8fã\81\82ã\82\8aません。
 
 ///
 
-{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *}
+{* ../../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)となります。
+
+`RedirectResponse` を直接返せます:
+
+{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
+
+---
+
+または、`response_class` パラメータで使用できます:
+
+{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
+
+その場合、*path operation*関数からURLを直接返せます。
 
-HTTPリダイレクトを返します。デフォルトでは307ステータスコード (Temporary Redirect) となります。
+この場合に使用される `status_code` は `RedirectResponse` のデフォルトである `307` になります。
 
-{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *}
+---
 
-### `StreamingResponse`
+また、`status_code` パラメータを `response_class` パラメータと組み合わせて使うこともできます:
 
-非同期なジェネレータか通常のジェネレータ・イテレータを受け取り、レスポンスボディをストリームします。
+{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
 
-{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
+### `StreamingResponse` { #streamingresponse }
 
-#### `StreamingResponse` をファイルライクなオブジェクトとともに使う
+非同期ジェネレータ、または通常のジェネレータ/イテレータを受け取り、レスポンスボディをストリームします。
 
-ファイルライクなオブジェクト (例えば、 `open()` で返されたオブジェクト) がある場合、 `StreamingResponse` に含めて返すことができます。
+{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
 
-これにはクラウドストレージとの連携や映像処理など、多くのライブラリが含まれています。
+#### ファイルライクオブジェクトで `StreamingResponse` を使う { #using-streamingresponse-with-file-like-objects }
 
-{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *}
+<a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">file-like</a> オブジェクト(例: `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 | 豆知識
 
\81\93ã\81\93ã\81§ã\81¯ `async` ã\82\84 `await` ã\82\92ã\82µã\83\9dã\83¼ã\83\88ã\81\97ã\81¦ã\81\84ã\81ªã\81\84æ¨\99æº\96ã\81® `open()` ã\82\92使ã\81£ã\81¦ã\81\84ã\82\8bã\81®ã\81§ã\80\81é\80\9a常ã\81® `def` ã\81§path operationã\82\92宣è¨\80ã\81\97ã\81¦ã\81\84ã\82\8bã\81\93ã\81¨に注意してください。
\81\93ã\81\93ã\81§ã\81¯ `async` ã\81¨ `await` ã\82\92ã\82µã\83\9dã\83¼ã\83\88ã\81\97ã\81¦ã\81\84ã\81ªã\81\84æ¨\99æº\96ã\81® `open()` ã\82\92使ã\81£ã\81¦ã\81\84ã\82\8bã\81\9fã\82\81ã\80\81é\80\9a常ã\81® `def` ã\81§path operationã\82\92宣è¨\80ã\81\97ã\81¦ã\81\84ã\82\8bç\82¹に注意してください。
 
 ///
 
-### `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` ヘッダーが含まれます。
+
+{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
+
+`response_class` パラメータを使うこともできます:
+
+{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
+
+この場合、*path operation*関数からファイルパスを直接返せます。
+
+## カスタムレスポンスクラス { #custom-response-class }
+
+`Response` を継承した独自のカスタムレスポンスクラスを作成して利用できます。
+
+例えば、<a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>を使いたいが、同梱の `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"}
+```
+
+...このレスポンスでは次のように返されます:
 
-ファイルレスポンスには、適切な `Content-Length` 、 `Last-Modified` 、 `ETag` ヘッダーが含まれます。
+```json
+{
+  "message": "Hello World"
+}
+```
 
-{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *}
+もちろん、JSONの整形よりも、これを活用するもっと良い方法が見つかるはずです。 😉
 
-## デフォルトレスポンスクラス
+## デフォルトレスポンスクラス { #default-response-class }
 
-**FastAPI** ã\82¯ã\83©ã\82¹ã\81®ã\82¤ã\83³ã\82¹ã\82¿ã\83³ã\82¹ã\81\8b `APIRouter` ã\82\92ç\94\9fæ\88\90ã\81\99ã\82\8bã\81¨ã\81\8dã\81«ã\80\81ã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\81®レスポンスクラスを指定できます。
+**FastAPI** ã\82¯ã\83©ã\82¹ã\81®ã\82¤ã\83³ã\82¹ã\82¿ã\83³ã\82¹ã\80\81ã\81¾ã\81\9fã\81¯ `APIRouter` ã\82\92ä½\9cæ\88\90ã\81\99ã\82\8bé\9a\9bã\81«ã\80\81ã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\81§ä½¿ç\94¨ã\81\99ã\82\8bレスポンスクラスを指定できます。
 
-定義するためのパラメータは、 `default_response_class` です。
+これを定義するパラメータは `default_response_class` です。
 
-以下の例では、 **FastAPI** は、全ての *path operation* で `JSONResponse` の代わりに `ORJSONResponse` をデフォルトとして利用します。
+以下の例では、**FastAPI** はすべての*path operation*で、`JSONResponse` の代わりに `ORJSONResponse` をデフォルトとして使います。
 
-{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *}
+{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
 
 /// tip | 豆知識
 
-前に見たように、 *path operation* の中で `response_class` をオーバーライドできます。
+これまでと同様に、*path operation*で `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}。
index 22eaf6eb80d76f87cfd0d1aa74628fde809beb89..1d0f7566cd54e32cc8a51b462323b730e8c1c366 100644 (file)
@@ -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**の主要な機能を一通り把握するには十分なはずです
 
-以é\99\8dã\81®ã\82»ã\82¯ã\82·ã\83§ã\83³ã\81§ã\81¯ã\80\81ã\83\81ã\83¥ã\83¼ã\83\88ã\83ªã\82¢ã\83«ã\81§ã\81¯èª¬æ\98\8eã\81\97ã\81\8dã\82\8cã\81ªã\81\8bã\81£ã\81\9fã\82ªã\83\97ã\82·ã\83§ã\83³ã\82\84設å®\9aã\80\81ã\81\8aã\82\88ã\81³æ©\9fè\83½ã\81«ã\81¤ã\81\84ã\81¦èª¬æ\98\8eã\81\97ます。
+以é\99\8dã\81®ã\82»ã\82¯ã\82·ã\83§ã\83³ã\81§ã\81¯ã\80\81ã\81\9dã\81®ä»\96ã\81®ã\82ªã\83\97ã\82·ã\83§ã\83³ã\80\81設å®\9aã\80\81追å\8a æ©\9fè\83½ã\82\92è¦\8bã\81¦ã\81\84ã\81\8dます。
 
 /// tip | 豆知識
 
-以降のセクションは、 **必ずしも"応用編"ではありません**。
+以降のセクションは、**必ずしも「高度」ではありません**。
 
\83¦ã\83¼ã\82¹ã\82±ã\83¼ã\82¹ã\81«ã\82\88ã\81£ã\81¦ã\81¯ã\80\81ã\81\9dã\81®ä¸­ã\81\8bã\82\89解決ç­\96ã\82\92è¦\8bã\81¤ã\81\91ã\82\89ã\82\8cã\82\8bã\81\8bã\82\82ã\81\97ã\82\8cã\81¾ã\81\9bã\82\93
\81¾ã\81\9fã\80\81ã\81\82ã\81ªã\81\9fã\81®ã\83¦ã\83¼ã\82¹ã\82±ã\83¼ã\82¹ã\81«å¯¾ã\81\99ã\82\8b解決ç­\96ã\81\8cã\80\81ã\81\9dã\81®ä¸­ã\81®ã\81©ã\82\8cã\81\8bã\81«ã\81\82ã\82\8bå\8f¯è\83½æ\80§ã\82\82ã\81\82ã\82\8aã\81¾ã\81\99
 
 ///
 
-## 先にチュートリアルを読む
+## 先にチュートリアルを読む { #read-the-tutorial-first }
 
-[チュートリアル - ユーザーガイド](../tutorial/index.md){.internal-link target=_blank}の知識があれば、**FastAPI**の主要な機能を利用することができます。
+メインの[チュートリアル - ユーザーガイド](../tutorial/index.md){.internal-link target=_blank}で得た知識があれば、**FastAPI**の機能の多くは引き続き利用できます。
 
-以降のセクションは、すでにチュートリアルを読んで、その主要なアイデアを理解できていることを前提としています。
-
-## テスト駆動開発のコース
-
-このセクションの内容を補完するために脱初心者用コースを受けたい場合は、**TestDriven.io**による、<a href="https://testdriven.io/courses/tdd-fastapi/" class="external-link" target="_blank">Test-Driven Development with FastAPI and Docker</a>を確認するのがよいかもしれません。
-
-現在、このコースで得られた利益の10%が**FastAPI**の開発のために寄付されています。🎉 😄
+また、以降のセクションでは、すでにそれを読んでいて、主要な考え方を理解していることを前提としています。
index 05188d5b25d7e46513d19c188201dee30ed77218..a78c3cb026ae93de38bcd8f1d297ee9293144f16 100644 (file)
@@ -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` で上書きすれば可能です。
 
\81\9dã\81\86ã\81\99ã\82\8bå ´å\90\88ã\81¯ã\80\81ã\81\99ã\81¹ã\81¦ã\81® *path operation* ã\82\92追å\8a ã\81\97ã\81\9få¾\8cã\81«è¡\8cã\81\86å¿\85è¦\81ã\81\8cã\81\82ã\82\8aã\81¾す。
\81\99ã\81¹ã\81¦ã\81® *path operation* ã\82\92追å\8a ã\81\97ã\81\9få¾\8cã\81«è¡\8cã\81\86ã\81¹ã\81\8dã\81§す。
 
-{* ../../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é\96¢æ\95°* ã\81®docstringã\81\8bã\82\89OpenAPIã\81«ä½¿ç\94¨ã\81\99ã\82\8bè¡\8cã\82\92å\88¶é\99\90ã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\81¾ã\81\99ã\80\82
+*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仕様では <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Operation Object</a> と呼ばれています。
+
+///
+
+これには *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* の下部に表示されます。
+
+<img src="/img/tutorial/path-operation-advanced-configuration/image01.png">
+
+そして(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として <abbr title="converted from some plain format, like bytes, into Python objects – bytesなどのプレーンな形式からPythonオブジェクトに変換すること">parsed</abbr> されず、直接 `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モデルを再利用しています。
+
+ただし同様に、別の方法で検証することもできます。
+
+///
index 42412d5070ad77e513931acc77d15e72c35b493e..7e83b9ffb2a33c63e3ddbe60ddd93cdc77f57c44 100644 (file)
@@ -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` を直接返す場合、バリデーションや、変換 (シリアライズ) や、自動ドキュメントは行われません。
 
index 2517530abeafadacdeaa1260ff7c184313e76c7d..6c68c9f0b128944ff9d2cbda94dbcbfddab9ff15 100644 (file)
@@ -1,10 +1,10 @@
-# WebSocket
+# WebSockets { #websockets }
 
-**FastAPI**で<a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank">WebSocket</a>が使用できます。
+**FastAPI**で<a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank">WebSockets</a>が使用できます。
 
-## `WebSockets`のインストール
+## `websockets`のインストール { #install-websockets }
 
-まず `WebSockets`のインストールが必要です
+[仮想環境](../virtual-environments.md){.internal-link target=_blank}を作成し、それを有効化してから、「WebSocket」プロトコルを簡単に使えるようにするPythonライブラリの`websockets`をインストールしてください
 
 <div class="termy">
 
@@ -16,13 +16,13 @@ $ pip install websockets
 
 </div>
 
-## 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
 
 ///
 
-## ã\83¡ã\83\83ã\82»ã\83¼ã\82¸ã\81®é\80\81å\8f\97ä¿¡
+## ã\83¡ã\83\83ã\82»ã\83¼ã\82¸ã\82\92å¾\85æ©\9fã\81\97ã\81¦é\80\81ä¿¡ã\81\99ã\82\8b { #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 }
 
\83\95ã\82¡ã\82¤ã\83«å\90\8dã\81\8c `main.py` ã\81§ã\81\82ã\82\8bå ´å\90\88ã\80\81以ä¸\8bã\81®æ\96¹æ³\95ã\81§ã\82¢ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³ã\82\92å®\9fè¡\8cã\81\97ã\81¾ã\81\99ã\80\82
+ファイル名が `main.py` である場合、以下でアプリケーションを実行します。
 
 <div class="termy">
 
 ```console
-$ uvicorn main:app --reload
+$ fastapi dev main.py
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
@@ -86,7 +86,7 @@ $ uvicorn main:app --reload
 
 <img src="/img/tutorial/websockets/image02.png">
 
-そして、 WebSocketを使用した**FastAPI**アプリケーションが応答します。
+そして、 WebSocketsを使用した**FastAPI**アプリケーションが応答します。
 
 <img src="/img/tutorial/websockets/image03.png">
 
@@ -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` を発生させます
 
 クロージングコードは、<a href="https://tools.ietf.org/html/rfc6455#section-7.4.1" class="external-link" target="_blank">仕様で定義された有効なコード</a>の中から使用することができます。
 
-将来的には、どこからでも `raise` できる `WebSocketException` が用意され、専用の例外ハンドラを追加できるようになる予定です。これは、Starlette の <a href="https://github.com/encode/starlette/pull/527" class="external-link" target="_blank">PR #527</a> に依存するものです。
-
 ///
 
-### 依存関係を用いてWebSocketsを試してみる
+### 依存関係を用いてWebSocketsを試してみる { #try-the-websockets-with-dependencies }
 
\83\95ã\82¡ã\82¤ã\83«å\90\8dã\81\8c `main.py` ã\81§ã\81\82ã\82\8bå ´å\90\88ã\80\81以ä¸\8bã\81®æ\96¹æ³\95ã\81§ã\82¢ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³ã\82\92å®\9fè¡\8cã\81\97ã\81¾ã\81\99ã\80\82
+ファイル名が `main.py` である場合、以下でアプリケーションを実行します。
 
 <div class="termy">
 
 ```console
-$ uvicorn main:app --reload
+$ fastapi dev main.py
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
@@ -137,14 +135,14 @@ $ uvicorn main:app --reload
 
 ブラウザで <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a> を開きます。
 
\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88ã\81\8c設å®\9aã\81§ã\81\8dã\82\8bé \85ç\9b®ã\81¯ä»¥ä¸\8bã\81®é\80\9aã\82\8aã\81§す。
\81\9dã\81\93ã\81§ã\80\81以ä¸\8bã\82\92設å®\9aã\81§ã\81\8dã\81¾す。
 
 * パスで使用される「Item ID」
 * クエリパラメータとして使用される「Token」
 
 /// tip | 豆知識
 
-クエリ `token` は依存パッケージによって処理されることに注意してください。
+クエリ `token` は依存関係によって処理されることに注意してください。
 
 ///
 
@@ -152,11 +150,11 @@ $ uvicorn main:app --reload
 
 <img src="/img/tutorial/websockets/image05.png">
 
-## å\88\87æ\96­ã\82\84è¤\87æ\95°ã\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88ã\81¸ã\81®å¯¾å¿\9c
+## å\88\87æ\96­ã\82\84è¤\87æ\95°ã\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88ã\81®å\87¦ç\90\86 { #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 接続に対してメッセージを処理し、ブロードキャストする方法を示すための最小限のシンプルな例です。
 
\81\97ã\81\8bã\81\97ã\80\81ã\81\99ã\81¹ã\81¦ã\81®æ\8e¥ç¶\9aã\81\8cã\83¡ã\83¢ã\83ªå\86\85ã\81®å\8d\98ä¸\80ã\81®ã\83ªã\82¹ã\83\88ã\81§å\87¦ç\90\86ã\81\95ã\82\8cã\82\8bã\81\9fã\82\81ã\80\81ã\83\97ã\83­ã\82»ã\82¹ã\81®å®\9fè¡\8c中ã\81«ã\81®ã\81¿æ©\9fè\83½ã\81\97ã\80\81å\8d\98ä¸\80ã\81®ã\83\97ã\83­ã\82»ã\82¹ã\81§ã\81®ã\81¿æ©\9fè\83½ã\81\99ã\82\8bã\81\93ã\81¨ã\81«æ³¨æ\84\8fã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82
+しかし、すべてがメモリ内の単一のリストで処理されるため、プロセスの実行中にのみ機能し、単一のプロセスでのみ機能することに注意してください。
 
-もしFastAPIと簡単に統合できて、RedisやPostgreSQLなどでサポートされている、より堅牢なものが必要なら、<a href="https://github.com/encode/broadcaster" class="external-link" target="_blank">encode/broadcaster</a> を確認してください。
+FastAPIと簡単に統合できて、RedisやPostgreSQLなどでサポートされている、より堅牢なものが必要なら、<a href="https://github.com/encode/broadcaster" class="external-link" target="_blank">encode/broadcaster</a> を確認してください。
 
 ///
 
-## その他のドキュメント
+## 詳細情報 { #more-info }
 
 オプションの詳細については、Starletteのドキュメントを確認してください。
 
-* <a href="https://www.starlette.dev/websockets/" class="external-link" target="_blank"> `WebSocket` クラス</a>
-* <a href="https://www.starlette.dev/endpoints/#websocketendpoint" class="external-link" target="_blank">クラスベースのWebSocket処理</a>
+* <a href="https://www.starlette.dev/websockets/" class="external-link" target="_blank">`WebSocket` クラス</a>.
+* <a href="https://www.starlette.dev/endpoints/#websocketendpoint" class="external-link" target="_blank">クラスベースのWebSocket処理</a>.
index 966d199c5ed9029f8d11022f33859d442d989273..fbfba2e637a50b4fd8958ed82e09b9472692e8aa 100644 (file)
@@ -1,34 +1,34 @@
-# ベンチマーク
+# ベンチマーク { #benchmarks }
 
-TechEmpowerの独立したベンチマークでは、Uvicornの下で動作する**FastAPI**アプリケーションは、<a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">利用可能な最速のPythonフレームワークの1つ</a>であり、下回っているのはStarletteとUvicorn自体 (FastAPIによって内部で使用される) のみだと示されています。
+TechEmpowerの独立したベンチマークでは、Uvicornの下で動作する**FastAPI**アプリケーションは、<a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">利用可能な最速のPythonフレームワークの1つ</a>であり、下回っているのはStarletteとUvicorn自体(FastAPIによって内部で使用される)のみだと示されています。
 
 ただし、ベンチマークを確認し、比較する際には下記の内容に気を付けてください。
 
-## ベンチマークと速度
+## ベンチマークと速度 { #benchmarks-and-speed }
 
\83\99ã\83³ã\83\81ã\83\9eã\83¼ã\82¯ã\82\92確èª\8dã\81\99ã\82\8bæ\99\82ã\80\81ç\95°ã\81ªã\82\8bã\83\84ã\83¼ã\83«ã\82\92å\90\8cç­\89ã\81ªã\82\82ã\81®ã\81¨æ¯\94è¼\83するのが一般的です。
\83\99ã\83³ã\83\81ã\83\9eã\83¼ã\82¯ã\82\92確èª\8dã\81\99ã\82\8bæ\99\82ã\80\81ç\95°ã\81ªã\82\8bã\82¿ã\82¤ã\83\97ã\81®è¤\87æ\95°ã\81®ã\83\84ã\83¼ã\83«ã\81\8cå\90\8cç­\89ã\81®ã\82\82ã\81®ã\81¨ã\81\97ã\81¦æ¯\94è¼\83ã\81\95ã\82\8cã\81¦ã\81\84ã\82\8bã\81®ã\82\92ç\9b®ã\81«するのが一般的です。
 
-具体的には、Uvicorn、Starlette、FastAPIを (他の多くのツールと) 比較しました
+具体的には、Uvicorn、Starlette、FastAPIを(他の多くのツールの中で)まとめて比較しているのを目にすることがあります
 
 ツールで解決する問題がシンプルなほど、パフォーマンスが向上します。また、ほとんどのベンチマークは、ツールから提供される追加機能をテストしていません。
 
 階層関係はこのようになります。
 
 * **Uvicorn**: ASGIサーバー
-    * **Starlette**: (Uvicornを使用) WEBマイクロフレームワーク
-        * **FastAPI**: (Starletteを使用) データバリデーションなどの、APIを構築する追加機能を備えたAPIマイクロフレームワーク
+    * **Starlette**: (Uvicornを使用)webマイクロフレームワーク
+        * **FastAPI**: (Starletteを使用)データバリデーションなど、APIを構築するためのいくつかの追加機能を備えたAPIマイクロフレームワーク
 
 * **Uvicorn**:
-    * サーバー自体に余分なコードが少ないので、最高のパフォーマンスが得られます。
-    * Uvicornã\81«ã\82¢ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³ã\82\92ç\9b´æ\8e¥æ\9b¸ã\81\8fã\81\93ã\81¨ã\81¯ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82ã\81¤ã\81¾ã\82\8aã\80\81ã\81\82ã\81ªã\81\9fã\81®ã\82³ã\83¼ã\83\89ã\81«ã\81¯ã\80\81Starlette (ã\81¾ã\81\9fã\81¯** FastAPI **) ã\81\8cæ\8f\90ä¾\9bã\81\99ã\82\8bã\82³ã\83¼ã\83\89ã\82\92ã\80\81å¤\9aã\81\8bã\82\8cå°\91ã\81ªã\81\8bã\82\8cå\90«ã\82\81ã\82\8bå¿\85è¦\81ã\81\8cã\81\82ã\82\8aã\81¾ã\81\99ã\80\82ã\81\9dã\81\86ã\81\99ã\82\8bã\81¨、最終的なアプリケーションは、フレームワークを使用してアプリのコードとバグを最小限に抑えた場合と同じオーバーヘッドになります。
-    * もしUvicornを比較する場合は、Daphne、Hypercorn、uWSGIなどのアプリケーションサーバーと比較してください。
+    * サーバー自体以外に余分なコードがあまりないため、最高のパフォーマンスになります。
+    * Uvicornã\81«ã\82¢ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³ã\82\92ç\9b´æ\8e¥æ\9b¸ã\81\8fã\81\93ã\81¨ã\81¯ã\81ªã\81\84ã\81§ã\81\97ã\82\87ã\81\86ã\80\82ã\81\9dã\82\8cã\81¯ã\80\81ã\81\82ã\81ªã\81\9fã\81®ã\82³ã\83¼ã\83\89ã\81«ã\80\81Starletteï¼\88ã\81¾ã\81\9fã\81¯**FastAPI**ï¼\89ã\81\8cæ\8f\90ä¾\9bã\81\99ã\82\8bã\82³ã\83¼ã\83\89ã\82\92ã\80\81å°\91ã\81ªã\81\8fã\81¨ã\82\82å¤\9aã\81\8bã\82\8cå°\91ã\81ªã\81\8bã\82\8cå\90«ã\82\81ã\82\8bå¿\85è¦\81ã\81\8cã\81\82ã\82\8bã\81¨ã\81\84ã\81\86ã\81\93ã\81¨ã\81§ã\81\99ã\80\82ã\81\9dã\81\97ã\81¦ã\80\81ã\82\82ã\81\97ã\81\9dã\81\86ã\81\97ã\81\9få ´å\90\88、最終的なアプリケーションは、フレームワークを使用してアプリのコードとバグを最小限に抑えた場合と同じオーバーヘッドになります。
+    * Uvicornを比較する場合は、Daphne、Hypercorn、uWSGIなどのアプリケーションサーバーと比較してください。
 * **Starlette**:
-    * Uvicornã\81«æ¬¡ã\81\90æ\80§è\83½ã\82\92æ\8c\81ã\81¤ã\81§ã\81\97ã\82\87ã\81\86ã\80\82å®\9fé\9a\9bã\80\81Starletteã\81¯Uvicornã\82\92使ç\94¨ã\81\97ã\81¦ã\81\84ã\81¾ã\81\99ã\80\82ã\81 ã\81\8bã\82\89ã\80\81ã\82\88ã\82\8aå¤\9aã\81\8fã\81®ã\82³ã\83¼ã\83\89ã\82\92å®\9fè¡\8cã\81\99ã\82\8bå¿\85è¦\81ã\81\8cã\81\82ã\82\8aã\80\81Uvicornã\82\88ã\82\8aã\82\82ã\80\8cé\81\85ã\81\8fã\80\8dã\81ªã\81£ã\81¦ã\81\97ã\81¾ã\81\86ã\81 ã\81\91ã\81ªã\81®です。
-    * ã\81\97ã\81\8bã\81\97ã\80\81ã\83\91ã\82¹ã\83\99ã\83¼ã\82¹ã\81®ã\83«ã\83¼ã\83\86ã\82£ã\83³ã\82°ã\81ªã\81©ã\81®ã\82·ã\83³ã\83\97ã\83«ã\81ªWEBã\82¢ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³ã\82\92æ§\8bç¯\89ã\81\99ã\82\8bæ©\9fè\83½を提供します。
-    * もしStarletteを比較する場合は、Sanic、Flask、DjangoなどのWEBフレームワーク (もしくはマイクロフレームワーク) と比較してください。
+    * Uvicornã\81«æ¬¡ã\81\90æ\80§è\83½ã\81«ã\81ªã\82\8bã\81§ã\81\97ã\82\87ã\81\86ã\80\82å®\9fé\9a\9bã\80\81Starletteã\81¯å®\9fè¡\8cã\81«Uvicornã\82\92使ç\94¨ã\81\97ã\81¦ã\81\84ã\81¾ã\81\99ã\80\82ã\81\9dã\81®ã\81\9fã\82\81ã\80\81ã\81\8aã\81\9dã\82\89ã\81\8fã\80\81ã\82\88ã\82\8aå¤\9aã\81\8fã\81®ã\82³ã\83¼ã\83\89ã\82\92å®\9fè¡\8cã\81\97ã\81ªã\81\91ã\82\8cã\81°ã\81ªã\82\89ã\81ªã\81\84å\88\86ã\81 ã\81\91ã\80\81Uvicornã\82\88ã\82\8aã\80\8cé\81\85ã\81\8fã\80\8dã\81ªã\82\8bã\81 ã\81\91です。
+    * ã\81\97ã\81\8bã\81\97ã\80\81ã\83\91ã\82¹ã\81«å\9fºã\81¥ã\81\8fã\83«ã\83¼ã\83\86ã\82£ã\83³ã\82°ã\81ªã\81©ã\82\92使ã\81£ã\81¦ã\80\81ã\82·ã\83³ã\83\97ã\83«ã\81ªwebã\82¢ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³ã\82\92æ§\8bç¯\89ã\81\99ã\82\8bã\81\9fã\82\81ã\81®ã\83\84ã\83¼ã\83«を提供します。
+    * Starletteを比較する場合は、Sanic、Flask、Djangoなどのwebフレームワーク(またはマイクロフレームワーク)と比較してください。
 * **FastAPI**:
-    * StarletteがUvicornを使っているのと同じで、**FastAPI**はStarletteを使っており、それより速くできません。
-    * FastAPIã\81¯Starletteã\81®ä¸\8aã\81«ã\81\95ã\82\89ã\81«å¤\9aã\81\8fã\81®æ©\9fè\83½ã\82\92æ\8f\90ä¾\9bã\81\97ã\81¾ã\81\99ã\80\82ã\83\87ã\83¼ã\82¿ã\81®æ¤\9c証ã\82\84ã\82·ã\83ªã\82¢ã\83©ã\82¤ã\82¼ã\83¼ã\82·ã\83§ã\83³ã\81ªã\81©ã\80\81APIã\82\92æ§\8bç¯\89ã\81\99ã\82\8bé\9a\9bã\81«å¸¸ã\81«å¿\85è¦\81ã\81ªæ©\9fè\83½ã\81§ã\81\99ã\80\82ã\81¾ã\81\9fã\80\81ã\81\9dã\82\8cã\82\92使ç\94¨ã\81\99ã\82\8bã\81\93ã\81¨ã\81§ã\80\81è\87ªå\8b\95ã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88å\8c\96ã\82\92ç\84¡æ\96\99ã\81§å\8f\96å¾\97ã\81§ã\81\8dã\81¾ã\81\99 (ã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88ã\81¯å®\9fè¡\8c中ã\81®ã\82¢ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³ã\81«ã\82ªã\83¼ã\83\90ã\83¼ã\83\98ã\83\83ã\83\89ã\82\92追å\8a ã\81\9bã\81\9aã\80\81èµ·å\8b\95æ\99\82ã\81«ç\94\9fæ\88\90ã\81\95ã\82\8cã\81¾ã\81\99
-    * FastAPIを使用せず、直接Starlette (またはSanic, Flask, Responderなど) を使用した場合、データの検証とシリアライズをすべて自分で実装する必要があります。そのため、最終的なアプリケーションはFastAPIを使用して構築した場合と同じオーバーヘッドが発生します。そして、多くの場合、このデータ検証とシリアライズは、アプリケーションのコードの中で最大の記述量になります。
-    * FastAPIを使用することで、開発時間、バグ、コード行数を節約でき、使用しない場合 (あなたが全ての機能を実装し直した場合) と同じかそれ以上のパフォーマンスを得られます。
-    * もしFastAPIを比較する場合は、Flask-apispec、NestJS、Moltenなどのデータ検証や、シリアライズの機能を提供するWEBフレームワーク (や機能のセット) と比較してください。これらはデータの自動検証や、シリアライズ、ドキュメント化が統合されたフレームワークです。
+    * StarletteがUvicornを使用しており、それより速くできないのと同じように、**FastAPI**はStarletteを使用しているため、それより速くできません。
+    * FastAPIã\81¯Starletteã\81®ä¸\8aã\81«ã\80\81ã\82\88ã\82\8aå¤\9aã\81\8fã\81®æ©\9fè\83½ã\82\92æ\8f\90ä¾\9bã\81\97ã\81¾ã\81\99ã\80\82ã\83\87ã\83¼ã\82¿ã\83\90ã\83ªã\83\87ã\83¼ã\82·ã\83§ã\83³ã\82\84ã\82·ã\83ªã\82¢ã\83©ã\82¤ã\82¼ã\83¼ã\82·ã\83§ã\83³ã\81®ã\82\88ã\81\86ã\81«ã\80\81APIã\82\92æ§\8bç¯\89ã\81\99ã\82\8bé\9a\9bã\81«ã\81»ã\81¨ã\82\93ã\81©å¸¸ã\81«å¿\85è¦\81ã\81ªæ©\9fè\83½ã\81§ã\81\99ã\80\82ã\81¾ã\81\9fã\80\81ã\81\9dã\82\8cã\82\92使ç\94¨ã\81\99ã\82\8bã\81\93ã\81¨ã\81§ã\80\81è\87ªå\8b\95ã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88å\8c\96ã\82\92ç\84¡æ\96\99ã\81§å\88©ç\94¨ã\81§ã\81\8dã\81¾ã\81\99ï¼\88è\87ªå\8b\95ã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88ã\81¯å®\9fè¡\8c中ã\81®ã\82¢ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³ã\81«ã\82ªã\83¼ã\83\90ã\83¼ã\83\98ã\83\83ã\83\89ã\82\92追å\8a ã\81\9bã\81\9aã\80\81èµ·å\8b\95æ\99\82ã\81«ç\94\9fæ\88\90ã\81\95ã\82\8cã\81¾ã\81\99ï¼\89
+    * FastAPIを使用せず、Starletteを直接(またはSanic、Flask、Responderなど別のツールを)使用した場合、データバリデーションとシリアライゼーションをすべて自分で実装する必要があります。そのため、最終的なアプリケーションはFastAPIを使用して構築した場合と同じオーバーヘッドが発生します。そして多くの場合、このデータバリデーションとシリアライゼーションは、アプリケーションで書かれるコードの大部分になります。
+    * そのため、FastAPIを使用することで、開発時間、バグ、コード行数を節約でき、使用しない場合(あなたがそれをすべて自分のコードで実装する必要があるため)と比べて、同じパフォーマンス(またはそれ以上)を得られる可能性があります。
+    * FastAPIを比較する場合は、Flask-apispec、NestJS、Moltenなど、データバリデーション、シリアライゼーション、ドキュメント化を提供するwebアプリケーションフレームワーク(またはツール群)と比較してください。自動データバリデーション、シリアライゼーション、ドキュメント化が統合されたフレームワークです。
index a0d4fb35b139432a8d3aa08813d69ad3a3b8a54f..787eb2e73f8bbc0f38c0d1fa27deb123b54bf47e 100644 (file)
@@ -1,4 +1,4 @@
-# デプロイメントのコンセプト
+# デプロイメントのコンセプト { #deployments-concepts }
 
 **FastAPI**を用いたアプリケーションをデプロイするとき、もしくはどのようなタイプのWeb APIであっても、おそらく気になるコンセプトがいくつかあります。
 
 * 起動時の実行
 * 再起動
 * レプリケーション(実行中のプロセス数)
-* メモリ
+* メモリ
 * 開始前の事前のステップ
 
 これらが**デプロイメント**にどのような影響を与えるかを見ていきましょう。
 
-最終的な目的は、**安全な方法で**APIクライアントに**サービスを提供**し、**中断を回避**するだけでなく、**計算リソース**(例えばリモートサーバー/仮想マシン)を可能な限り効率的に使用することです。🚀
+最終的な目的は、**安全な方法で**APIクライアントに**サービスを提供**し、**中断を回避**するだけでなく、**計算リソース**(例えばリモートサーバー/仮想マシン)を可能な限り効率的に使用することです。 🚀
 
 この章では前述した**コンセプト**についてそれぞれ説明します。
 
 
 しかし、今はこれらの重要な**コンセプトに基づくアイデア**を確認しましょう。これらのコンセプトは、他のどのタイプのWeb APIにも当てはまります。💡
 
-## セキュリティ - HTTPS
+## セキュリティ - HTTPS { #security-https }
 
 <!-- NOTE: https.md written in Japanese does not exist, so it redirects to English one  -->
 [前チャプターのHTTPSについて](https.md){.internal-link target=_blank}では、HTTPSがどのようにAPIを暗号化するのかについて学びました。
 
 通常、アプリケーションサーバにとって**外部の**コンポーネントである**TLS Termination Proxy**によって提供されることが一般的です。このプロキシは通信の暗号化を担当します。
 
\81\95ã\82\89ã\81«ã\82»ã\82­ã\83¥ã\82¢ã\81ªé\80\9aä¿¡ã\81«ã\81\8aã\81\84ã\81¦ã\80\81HTTPS証æ\98\8eæ\9b¸ã\81®å®\9aæ\9c\9fç\9a\84ã\81ªæ\9b´æ\96°ã\82\92è¡\8cã\81\84ã\81¾ã\81\99ã\81\8cã\80\81ã\81\93ã\82\8cã\81¯TLS Termination Proxyã\81¨同じコンポーネントが担当することもあれば、別のコンポーネントが担当することもあります。
\81\95ã\82\89ã\81«ã\80\81HTTPS証æ\98\8eæ\9b¸ã\81®æ\9b´æ\96°ã\82\92æ\8b\85å½\93ã\81\99ã\82\8bã\82\82ã\81®ã\81\8cå¿\85è¦\81ã\81§ã\80\81同じコンポーネントが担当することもあれば、別のコンポーネントが担当することもあります。
 
-### 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をクラッシュさせるようなケースもあるかもしれません。💥
 
-それでも、ある箇所でエラーが発生したからといって、アプリケーションを停止させたままにしたくないでしょう。 少なくとも壊れていない*パスオペレーション*については、**実行し続けたい**はずです。
+それでも、ある箇所でエラーが発生したからといって、アプリケーションを停止させたままにしたくないでしょう。 少なくとも壊れていない*path operation*については、**実行し続けたい**はずです。
 
-### クラッシュ後の再起動
+### クラッシュ後の再起動 { #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 ã\82¢ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³ã\81§ã\81¯ã\80\81Uvicorn ã\82\92å®\9fè¡\8cã\81\99ã\82\8b `fastapi` ã\82³ã\83\9eã\83³ã\83\89ã\81®ã\82\88ã\81\86ã\81ªã\82µã\83¼ã\83\90ã\83¼ã\83\97ã\83­ã\82°ã\83©ã\83 ã\82\92使ç\94¨ã\81\97ã\80\81**1ã\81¤ã\81®ã\83\97ã\83­ã\82»ã\82¹**ã\81§1度ã\81«è¤\87æ\95°ã\81®ã\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88ã\81«å\90\8cæ\99\82ã\81«å¯¾å¿\9cã\81§ã\81\8dã\81¾ã\81\99ã\80\82
 
 しかし、多くの場合、複数のワーカー・プロセスを同時に実行したいと考えるでしょう。
 
-### 複数のプロセス - Worker
+### 複数のプロセス - Worker { #multiple-processes-workers }
 
 クライアントの数が単一のプロセスで処理できる数を超えており(たとえば仮想マシンがそれほど大きくない場合)、かつサーバーの CPU に**複数のコア**がある場合、同じアプリケーションで同時に**複数のプロセス**を実行させ、すべてのリクエストを分散させることができます。
 
 同じAPIプログラムの**複数のプロセス**を実行する場合、それらは一般的に**Worker/ワーカー**と呼ばれます。
 
-### ワーカー・プロセス と ポート
+### ワーカー・プロセス と ポート { #worker-processes-and-ports }
 <!-- NOTE: https.md written in Japanese does not exist, so it redirects to English one  -->
 
 [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に関する項目が、まだあまり意味をなしていなくても心配しないでください。
-<!-- NOTE: the current version of docker.md is outdated compared to English one. -->
 
-コンテナ・イメージ、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 | 豆知識
 
-<!-- NOTE: the current version of docker.md is outdated compared to English one. -->
-コンテナを使った具体的な例については、次の章で紹介します: [コンテナ内の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 のようなサーバープロ
 * 起動時の実行
 * 再起動
 * レプリケーション(実行中のプロセス数)
-* メモリ
+* メモリ
 * 開始前の事前ステップ
 
 これらの考え方とその適用方法を理解することで、デプロイメントを設定したり調整したりする際に必要な直感的な判断ができるようになるはずです。🤓
index 53fc851f1e9a12e02adba2d1782a9cf9317e7cf8..6c182448c939d3588c1b3e3670568a955d7b12ea 100644 (file)
@@ -1,20 +1,17 @@
-# コンテナ内のFastAPI - Docker
+# コンテナ内のFastAPI - Docker { #fastapi-in-containers-docker }
 
-FastAPIアプリケーションをデプロイする場合、一般的なアプローチは**Linuxコンテナ・イメージ**をビルドすることです。
-
-基本的には <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a>を用いて行われます。生成されたコンテナ・イメージは、いくつかの方法のいずれかでデプロイできます。
+FastAPIアプリケーションをデプロイする場合、一般的なアプローチは**Linuxコンテナ・イメージ**をビルドすることです。基本的には <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a>を用いて行われます。生成されたコンテナ・イメージは、いくつかの方法のいずれかでデプロイできます。
 
 Linuxコンテナの使用には、**セキュリティ**、**反復可能性(レプリカビリティ)**、**シンプリシティ**など、いくつかの利点があります。
 
-/// tip
+/// tip | 豆知識
 
-TODO: なぜか遷移できない
 お急ぎで、すでにこれらの情報をご存じですか? [以下の`Dockerfile`の箇所👇](#build-a-docker-image-for-fastapi)へジャンプしてください。
 
 ///
 
 <details>
-<summary>Dockerfile プレビュー 👀</summary>
+<summary>Dockerfile Preview 👀</summary>
 
 ```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"]
 ```
 
 </details>
 
-## コンテナとは何か
+## コンテナとは何か { #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イメージ(コンテナ)を共有する<a href="https://hub.docker.com/" class="external-link" target="_blank">Docker Hub</a>というものがあります。
-
-Docker Hubは 多くのツールや環境、データベース、アプリケーションに対応している予め作成された**公式のコンテナ・イメージ**をパブリックに提供しています。
+そして、多くのツールや環境、データベース、アプリケーションに対応している予め作成された**公式のコンテナ・イメージ**をパブリックに提供している<a href="https://hub.docker.com/" class="external-link" target="_blank">Docker Hub</a>というものがあります。
 
 例えば、公式イメージの1つに<a href="https://hub.docker.com/_/python" class="external-link" target="_blank">Python Image</a>があります。
 
@@ -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,28 +127,24 @@ uvicorn>=0.15.0,<0.16.0
 ```console
 $ pip install -r requirements.txt
 ---> 100%
-Successfully installed fastapi pydantic uvicorn
+Successfully installed fastapi pydantic
 ```
 
 </div>
 
-/// info
+/// info | 情報
 
 パッケージの依存関係を定義しインストールするためのフォーマットやツールは他にもあります。
 
-Poetryを使った例は、後述するセクションでご紹介します。👇
-
 ///
 
-### **FastAPI**コードを作成する
+### **FastAPI**コードを作成する { #create-the-fastapi-code }
 
-* `app` ディレクトリを作成し、その中に入ります
-* 空のファイル `__init__.py` を作成します
-* `main.py` ファイルを作成します:
+* `app` ディレクトリを作成し、その中に入ります
+* 空のファイル `__init__.py` を作成します
+* 次の内容で `main.py` ファイルを作成します:
 
 ```Python
-from typing import Union
-
 from fastapi import FastAPI
 
 app = FastAPI()
@@ -170,32 +156,32 @@ def read_root():
 
 
 @app.get("/items/{item_id}")
-def read_item(item_id: int, q: Union[str, None] = None):
+def read_item(item_id: int, q: 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 +197,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 +212,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命令 <a href="https://docs.docker.com/reference/dockerfile/#cmd" class="external-link" target="_blank">`CMD`</a> は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** 形式を使用してください。
+
+詳しくは、<a href="https://docs.docker.com/reference/dockerfile/#shell-and-exec-form" class="external-link" target="_blank">shell形式とexec形式に関するDockerドキュメント</a>をご覧ください。
+
+これは `docker compose` を使用する場合にかなり目立つことがあります。より技術的な詳細は、このDocker ComposeのFAQセクションをご覧ください:<a href="https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop" class="external-link" target="_blank">Why do my services take 10 seconds to recreate or stop?</a>。
+
+#### ディレクトリ構造 { #directory-structure }
+
 これで、次のようなディレクトリ構造になるはずです:
 
 ```
@@ -256,17 +273,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,11 +315,11 @@ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
 COPY ./app /code/app
 ```
 
-### Dockerイメージをビルドする
+### Dockerイメージをビルドする { #build-the-docker-image }
 
 すべてのファイルが揃ったので、コンテナ・イメージをビルドしましょう。
 
-* プロジェクトディレクトリに移動します(`Dockerfile`がある場所で、`app`ディレクトリがあります)
+* プロジェクトディレクトリに移動します(`Dockerfile`がある場所で、`app`ディレクトリがあります)
 * FastAPI イメージをビルドします:
 
 <div class="termy">
@@ -317,7 +332,7 @@ $ docker build -t myimage .
 
 </div>
 
-/// tip
+/// tip | 豆知識
 
 末尾の `.` に注目してほしいです。これは `./` と同じ意味です。 これはDockerにコンテナイメージのビルドに使用するディレクトリを指示します。
 
@@ -325,7 +340,7 @@ $ docker build -t myimage .
 
 ///
 
-### Dockerコンテナの起動する
+### Dockerコンテナの起動する { #start-the-docker-container }
 
 * イメージに基づいてコンテナを実行します:
 
@@ -337,7 +352,7 @@ $ docker run -d --name mycontainer -p 80:80 myimage
 
 </div>
 
-## 確認する
+## 確認する { #check-it }
 
 Dockerコンテナの<a href="http://192.168.99.100/items/5?q=somequery" class="external-link" target="_blank">http://192.168.99.100/items/5?q=somequery</a> や <a href="http://127.0.0.1/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1/items/5?q=somequery</a> (またはそれに相当するDockerホストを使用したもの)といったURLで確認できるはずです。
 
@@ -347,7 +362,7 @@ Dockerコンテナの<a href="http://192.168.99.100/items/5?q=somequery" class="
 {"item_id": 5, "q": "somequery"}
 ```
 
-## インタラクティブなAPIドキュメント
+## インタラクティブなAPIドキュメント { #interactive-api-docs }
 
 これらのURLにもアクセスできます:  <a href="http://192.168.99.100/docs" class="external-link" target="_blank">http://192.168.99.100/docs</a> や <a href="http://127.0.0.1/docs" class="external-link" target="_blank">http://127.0.0.1/docs</a> (またはそれに相当するDockerホストを使用したもの)
 
@@ -355,7 +370,7 @@ Dockerコンテナの<a href="http://192.168.99.100/items/5?q=somequery" class="
 
 ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
 
-## 代替のAPIドキュメント
+## 代替のAPIドキュメント { #alternative-api-docs }
 
 また、<a href="http://192.168.99.100/redoc" class="external-link" target="_blank">http://192.168.99.100/redoc</a> や <a href="http://127.0.0.1/redoc" class="external-link" target="_blank">http://127.0.0.1/redoc</a> (またはそれに相当するDockerホストを使用したもの)にもアクセスできます。
 
@@ -363,9 +378,10 @@ Dockerコンテナの<a href="http://192.168.99.100/items/5?q=somequery" class="
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
 
-## 単一ファイルのFastAPIでDockerイメージをビルドする
+## 単一ファイルのFastAPIでDockerイメージをビルドする { #build-a-docker-image-with-a-single-file-fastapi }
 
 FastAPI が単一のファイル、例えば `./app` ディレクトリのない `main.py` の場合、ファイル構造は次のようになります:
+
 ```
 .
 ├── Dockerfile
@@ -384,43 +400,43 @@ COPY ./requirements.txt /code/requirements.txt
 
 RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
 
-# (1)
+# (1)!
 COPY ./main.py /code/
 
-# (2)
-CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
+# (2)!
+CMD ["fastapi", "run", "main.py", "--port", "80"]
 ```
 
-1. main.py`ファイルを `/code` ディレクトリに直接コピーします
+1. `main.py`ファイルを `/code` ディレクトリに直接コピーします(`./app` ディレクトリなし)
 
-2. Uvicornを実行し、`main`から`app`オブジェクトをインポートするように指示します(`app.main`からインポートするのではなく)
+2. 単一ファイル `main.py` 内のアプリケーションを配信するために `fastapi run` を使用します
 
-次にUvicornコマンドを調整して、`app.main` の代わりに新しいモジュール `main` を使用し、FastAPIオブジェクトである `app` をインポートします。
+`fastapi run` にファイルを渡すと、それがパッケージの一部ではなく単一ファイルであることを自動的に検出し、インポートしてFastAPIアプリを配信する方法を判断します。😎
 
-## デプロイメントのコンセプト
+## デプロイメントのコンセプト { #deployment-concepts }
 
 コンテナという観点から、[デプロイのコンセプト](concepts.md){.internal-link target=_blank}に共通するいくつかについて、もう一度説明しましょう。
 
\82³ã\83³ã\83\86ã\83\8aã\81¯ä¸»ã\81«ã\80\81ã\82¢ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³ã\81®**ã\83\93ã\83«ã\83\89ã\81¨ã\83\87ã\83\97ã\83­ã\82¤**ã\81®ã\83\97ã\83­ã\82»ã\82¹ã\82\92ç°¡ç´ å\8c\96ã\81\99ã\82\8bã\81\9fã\82\81ã\81®ã\83\84ã\83¼ã\83«ã\81§ã\81\99ã\81\8cã\80\81ã\81\93ã\82\8cã\82\89ã\81®**ã\83\87ã\83\97ã\83­ã\82¤ã\81®ã\82³ã\83³ã\82»ã\83\97ã\83\88**ã\82\92æ\89±ã\81\86ã\81\9fã\82\81ã\81®ç\89¹å®\9aã\81®ã\82¢ã\83\97ã\83­ã\83¼ã\83\81ã\82\92å¼·å\88¶ã\81\99ã\82\8bã\82\82ã\81®ã\81§ã\81¯ã\81ªã\81\84ã\81§す。
\82³ã\83³ã\83\86ã\83\8aã\81¯ä¸»ã\81«ã\80\81ã\82¢ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³ã\81®**ã\83\93ã\83«ã\83\89ã\81¨ã\83\87ã\83\97ã\83­ã\82¤**ã\81®ã\83\97ã\83­ã\82»ã\82¹ã\82\92ç°¡ç´ å\8c\96ã\81\99ã\82\8bã\81\9fã\82\81ã\81®ã\83\84ã\83¼ã\83«ã\81§ã\81\99ã\81\8cã\80\81ã\81\93ã\82\8cã\82\89ã\81®**ã\83\87ã\83\97ã\83­ã\82¤ã\81®ã\82³ã\83³ã\82»ã\83\97ã\83\88**ã\82\92æ\89±ã\81\86ã\81\9fã\82\81ã\81®ç\89¹å®\9aã\81®ã\82¢ã\83\97ã\83­ã\83¼ã\83\81ã\82\92å¼·å\88¶ã\81\99ã\82\8bã\82\82ã\81®ã\81§ã\81¯ã\81ªã\81\8fã\80\81ã\81\84ã\81\8fã\81¤ã\81\8bã\81®æ\88¦ç\95¥ã\81\8cã\81\82ã\82\8aã\81¾す。
 
 **良いニュース**は、それぞれの異なる戦略には、すべてのデプロイメントのコンセプトをカバーする方法があるということです。🎉
 
 これらの**デプロイメントのコンセプト**をコンテナの観点から見直してみましょう:
 
-* セキュリティ - HTTPS
+* HTTPS
 * 起動時の実行
 * 再起動
-* **レプリケーション(実行中のプロセス数)**
+* レプリケーション(実行中のプロセス数)
 * メモリ
 * 開始前の事前ステップ
 
-## HTTPS
+## HTTPS { #https }
 
 FastAPI アプリケーションの **コンテナ・イメージ**(および後で実行中の **コンテナ**)だけに焦点を当てると、通常、HTTPSは別のツールを用いて**外部で**処理されます。
 
 例えば<a href="https://traefik.io/" class="external-link" target="_blank">Traefik</a>のように、**HTTPS**と**証明書**の**自動**取得を扱う別のコンテナである可能性もあります。
 
-/// tip
+/// tip | 豆知識
 
 TraefikはDockerやKubernetesなどと統合されているので、コンテナ用のHTTPSの設定や構成はとても簡単です。
 
@@ -428,7 +444,7 @@ TraefikはDockerやKubernetesなどと統合されているので、コンテナ
 
 あるいは、(コンテナ内でアプリケーションを実行しながら)クラウド・プロバイダーがサービスの1つとしてHTTPSを処理することもできます。
 
-## 起動時および再起動時の実行
+## 起動時および再起動時の実行 { #running-on-startup-and-restarts }
 
 通常、コンテナの**起動と実行**を担当する別のツールがあります。
 
@@ -438,21 +454,21 @@ TraefikはDockerやKubernetesなどと統合されているので、コンテナ
 
 コンテナを使わなければ、アプリケーションを起動時や再起動時に実行させるのは面倒で難しいかもしれません。しかし、**コンテナ**で作業する場合、ほとんどのケースでその機能はデフォルトで含まれています。✨
 
-## レプリケーション - プロセス数
+## レプリケーション - プロセス数 { #replication-number-of-processes }
 
-**Kubernetes** や Docker Swarm モード、Nomad、あるいは複数のマシン上で分散コンテナを管理するための同様の複雑なシステムを使ってマシンの<abbr title="何らかの方法で接続され、一緒に動作するように構成されたマシンのグループ">クラスター</abbr>を構成している場合、 各コンテナで(Workerを持つGunicornのような)**プロセスマネージャ**を使用する代わりに、**クラスター・レベル**で**レプリケーション**を処理したいと思うでしょう。
+**Kubernetes** や Docker Swarm モード、Nomad、あるいは複数のマシン上で分散コンテナを管理するための同様の複雑なシステムを使ってマシンの<abbr title="A group of machines that are configured to be connected and work together in some way. - ある方法で接続され、連携して動作するように構成されたマシンの集まり">cluster</abbr>を構成している場合、 各コンテナで(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 +476,7 @@ HTTPSに使われるものと同じ**TLS Termination Proxy**コンポーネン
 
 そしてコンテナで作業する場合、コンテナの起動と管理に使用する同じシステムには、**ロードバランサー**(**TLS Termination Proxy**の可能性もある)から**ネットワーク通信**(HTTPリクエストなど)をアプリのあるコンテナ(複数可)に送信するための内部ツールが既にあるはずです。
 
-### 1つのロードバランサー - 複数のワーカーコンテナー
+### 1つのロードバランサー - 複数のワーカーコンテナー { #one-load-balancer-multiple-worker-containers }
 
 **Kubernetes**や同様の分散コンテナ管理システムで作業する場合、その内部のネットワーキングのメカニズムを使用することで、メインの**ポート**でリッスンしている単一の**ロードバランサー**が、アプリを実行している可能性のある**複数のコンテナ**に通信(リクエスト)を送信できるようになります。
 
@@ -470,56 +486,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ワーカープロセス**を起動させたい場合があります。
 
\81\93ã\81®ã\82\88ã\81\86ã\81ªå ´å\90\88ã\80\81**å\85¬å¼\8fã\81®Dockerã\82¤ã\83¡ã\83¼ã\82¸**ã\82\92使ç\94¨ã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\81¾ã\81\99ã\80\82ã\81\93ã\81®ã\82¤ã\83¡ã\83¼ã\82¸ã\81«ã\81¯ã\80\81è¤\87æ\95°ã\81®**Uvicornã\83¯ã\83¼ã\82«ã\83¼ã\83\97ã\83­ã\82»ã\82¹**ã\82\92å®\9fè¡\8cã\81\99ã\82\8bã\83\97ã\83­ã\82»ã\82¹ã\83\9eã\83\8dã\83¼ã\82¸ã\83£ã\81¨ã\81\97ã\81¦**Gunicorn**ã\81\8cå\90«ã\81¾ã\82\8cã\81¦ã\81\8aã\82\8aã\80\81ç\8f¾å\9c¨ã\81®CPUã\82³ã\82¢ã\81«å\9fºã\81¥ã\81\84ã\81¦ã\83¯ã\83¼ã\82«ã\83¼ã\81®æ\95°ã\82\92è\87ªå\8b\95ç\9a\84ã\81«èª¿æ\95´ã\81\99ã\82\8bã\81\9fã\82\81ã\81®ã\83\87ã\83\95ã\82©ã\83«ã\83\88設å®\9aã\81\8cã\81\84ã\81\8fã\81¤ã\81\8bå\90«ã\81¾ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99ã\80\82詳ã\81\97ã\81\8fã\81¯å¾\8cè¿°ã\81®[Gunicornã\81«ã\82\88ã\82\8bå\85¬å¼\8fDockerã\82¤ã\83¡ã\83¼ã\82¸ - Uvicorn](#gunicorndocker-uvicorn)ã\81§èª¬æ\98\8eã\81\97ã\81¾ã\81\99ã\80\82
\81\9dã\81®ã\82\88ã\81\86ã\81ªå ´å\90\88ã\80\81`--workers` ã\82³ã\83\9eã\83³ã\83\89ã\83©ã\82¤ã\83³ã\82ªã\83\97ã\82·ã\83§ã\83³ã\82\92使ã\81£ã\81¦ã\80\81å®\9fè¡\8cã\81\97ã\81\9fã\81\84ã\83¯ã\83¼ã\82«ã\83¼æ\95°ã\82\92設å®\9aã\81§ã\81\8dã\81¾ã\81\99ï¼\9a
 
-以下は、それが理にかなっている場合の例です:
+```{ .dockerfile .annotate }
+FROM python:3.9
 
-#### シンプルなアプリケーション
+WORKDIR /code
 
-アプリケーションを**シンプル**な形で実行する場合、プロセス数の細かい調整が必要ない場合、自動化されたデフォルトを使用するだけで、コンテナ内にプロセスマネージャが必要かもしれません。例えば、公式Dockerイメージでシンプルな設定が可能です。
+COPY ./requirements.txt /code/requirements.txt
 
-#### Docker Compose
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
 
-Docker Composeで**シングルサーバ**(クラスタではない)にデプロイすることもできますので、共有ネットワークと**ロードバランシング**を維持しながら(Docker Composeで)コンテナのレプリケーションを管理する簡単な方法はないでしょう。
+COPY ./app /code/app
 
-その場合、**単一のコンテナ**で、**プロセスマネージャ**が内部で**複数のワーカープロセス**を起動するようにします。
+# (1)!
+CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
+```
 
-#### Prometheusとその他の理由
+1. ここでは `--workers` コマンドラインオプションを使って、ワーカー数を4に設定しています。
 
-また、**1つのコンテナ**に**1つのプロセス**を持たせるのではなく、**1つのコンテナ**に**複数のプロセス**を持たせる方が簡単だという**他の理由**もあるでしょう。
+以下は、それが理にかなっている場合の例です:
 
-例えば、(セットアップにもよりますが)Prometheusエクスポーターのようなツールを同じコンテナ内に持つことができます。
+#### シンプルなアプリ { #a-simple-app }
 
\81\93ã\81®å ´å\90\88ã\80\81**è¤\87æ\95°ã\81®ã\82³ã\83³ã\83\86ã\83\8a**ã\81\8cã\81\82ã\82\8bã\81¨ã\80\81ã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\81§ã\81¯ã\80\81Prometheusã\81\8c**ã\83¡ã\83\88ã\83ªã\82¯ã\82¹ã\82\92**読ã\81¿ã\81«æ\9d¥ã\81\9fã\81¨ã\81\8dã\80\81ã\81\99ã\81¹ã\81¦ã\81®ã\83¬ã\83\97ã\83ªã\82±ã\83¼ã\83\88ã\81\95ã\82\8cã\81\9fã\82³ã\83³ã\83\86ã\83\8aã\81®**è\93\84ç©\8dã\81\95ã\82\8cã\81\9fã\83¡ã\83\88ã\83ªã\82¯ã\82¹**ã\82\92å\8f\96å¾\97ã\81\99ã\82\8bã\81®ã\81§ã\81¯ã\81ªã\81\8fã\80\81æ¯\8eå\9b\9e**å\8d\98ä¸\80ã\81®ã\82³ã\83³ã\83\86ã\83\8a**ï¼\88ã\81\9dã\81®ç\89¹å®\9aã\81®ã\83ªã\82¯ã\82¨ã\82¹ã\83\88ã\82\92å\87¦ç\90\86ã\81\97ã\81\9fã\82³ã\83³ã\83\86ã\83\8aï¼\89ã\81®ã\82\82ã\81®ã\82\92å\8f\96å¾\97ã\81\99ã\82\8bã\81\93ã\81¨ã\81«ã\81ªります。
\82¢ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³ã\81\8cã\80\81ã\82¯ã\83©ã\82¹ã\82¿ã\81§ã\81¯ã\81ªã\81\8f**å\8d\98ä¸\80ã\82µã\83¼ã\83\90**ã\81§å®\9fè¡\8cã\81§ã\81\8dã\82\8bã\81»ã\81©**ã\82·ã\83³ã\83\97ã\83«**ã\81§ã\81\82ã\82\8bå ´å\90\88ã\80\81ã\82³ã\83³ã\83\86ã\83\8aå\86\85ã\81«ã\83\97ã\83­ã\82»ã\82¹ã\83\9eã\83\8dã\83¼ã\82¸ã\83£ã\81\8c欲ã\81\97ã\81\8fã\81ªã\82\8bã\81\93ã\81¨ã\81\8cã\81\82ります。
 
-その場合、**複数のプロセス**を持つ**1つのコンテナ**を用意し、同じコンテナ上のローカルツール(例えばPrometheusエクスポーター)がすべての内部プロセスのPrometheusメトリクスを収集し、その1つのコンテナ上でそれらのメトリクスを公開する方がシンプルかもしれません。
+#### Docker Compose { #docker-compose }
 
----
+Docker Composeで**単一サーバ**(クラスタではない)にデプロイすることもできますので、共有ネットワークと**ロードバランシング**を維持しながら(Docker Composeで)コンテナのレプリケーションを管理する簡単な方法はないでしょう。
 
-重要なのは、盲目的に従わなければならない普遍のルールはないということです。
+その場合、**単一のコンテナ**で、**プロセスマネージャ**が内部で**複数のワーカープロセス**を起動するようにします。
 
-これらのアイデアは、**あなた自身のユースケース**を評価し、あなたのシステムに最適なアプローチを決定するために使用することができます:
+---
+
+重要なのは、これらのどれも、盲目的に従わなければならない「**絶対的なルール**」ではないということです。これらのアイデアは、**あなた自身のユースケース**を評価し、あなたのシステムに最適なアプローチを決定するために使用できます。次の概念をどう管理するかを確認してください:
 
 * セキュリティ - HTTPS
 * 起動時の実行
 * 再起動
-* **レプリケーション(実行中のプロセス数)**
+* レプリケーション(実行中のプロセス数)
 * メモリ
 * 開始前の事前ステップ
 
-## メモリ
+## メモリ { #memory }
 
 コンテナごとに**単一のプロセスを実行する**と、それらのコンテナ(レプリケートされている場合は1つ以上)によって消費される多かれ少なかれ明確に定義された、安定し制限された量のメモリを持つことになります。
 
@@ -531,109 +552,47 @@ Docker Composeで**シングルサーバ**(クラスタではない)にデ
 
 しかし、**多くのメモリを使用**している場合(たとえば**機械学習**モデルなど)、どれだけのメモリを消費しているかを確認し、**各マシンで実行するコンテナの数**を調整する必要があります(そしておそらくクラスタにマシンを追加します)。
 
-**コンテナごとに複数のプロセス**を実行する場合(たとえば公式のDockerイメージで)、起動するプロセスの数が**利用可能なメモリ以上に消費しない**ようにする必要があります。
+**コンテナごとに複数のプロセス**を実行する場合、起動するプロセスの数が**利用可能なメモリ以上に消費しない**ようにする必要があります。
 
-## 開始前の事前ステップとコンテナ
+## 開始前の事前ステップとコンテナ { #previous-steps-before-starting-and-containers }
 
 コンテナ(DockerやKubernetesなど)を使っている場合、主に2つのアプローチがあります。
 
-### 複数のコンテナ
+### 複数のコンテナ { #multiple-containers }
 
-複数の**コンテナ**があり、おそらくそれぞれが**単一のプロセス**を実行している場合(**Kubernetes**クラスタなど)、レプリケートされたワーカーコンテナを実行する**前に**、単一のコンテナで**事前のステップ**の作業を行う**別のコンテナ**を持ちたいと思うでしょう。
+複数の**コンテナ**があり、おそらくそれぞれが**単一のプロセス**を実行している場合(例えば、**Kubernetes**クラスタなど)、レプリケートされたワーカーコンテナを実行する**前に**、単一のコンテナで**事前のステップ**の作業を行う**別のコンテナ**を持ちたいと思うでしょう。
 
-/// info
+/// info | 情報
 
-もしKubernetesを使用している場合, これはおそらく<a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/" class="external-link" target="_blank">Init コンテナ</a>でしょう。
+もしKubernetesを使用している場合, これはおそらく<a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/" class="external-link" target="_blank">Init Container</a>でしょう。
 
 ///
 
-ユースケースが事前のステップを**並列で複数回**実行するのに問題がない場合(例:データベースの準備チェック)、メインプロセスを開始する前に、それらのステップを各コンテナに入れることが可能です。
-
-### 単一コンテナ
-
-単純なセットアップで、**単一のコンテナ**で複数の**ワーカー・プロセス**(または1つのプロセスのみ)を起動する場合、アプリでプロセスを開始する直前に、同じコンテナで事前のステップを実行できます。公式Dockerイメージは、内部的にこれをサポートしています。
+ユースケースが事前のステップを**並列で複数回**実行するのに問題がない場合(例:データベースマイグレーションを実行するのではなく、データベースの準備ができたかをチェックするだけの場合)、メインプロセスを開始する直前に、それらのステップを各コンテナに入れることも可能です。
 
-## Gunicornによる公式Dockerイメージ - Uvicorn
+### 単一コンテナ { #single-container }
 
\89\8dã\81®ç« ã\81§è©³ã\81\97ã\81\8f説æ\98\8eã\81\97ã\81\9fã\82\88ã\81\86ã\81«ã\80\81Uvicornã\83¯ã\83¼ã\82«ã\83¼ã\81§å\8b\95ä½\9cã\81\99ã\82\8bGunicornã\82\92å\90«ã\82\80å\85¬å¼\8fã\81®Dockerã\82¤ã\83¡ã\83¼ã\82¸ã\81\8cã\81\82ã\82\8aã\81¾ã\81\99ï¼\9a [Server Workers - Gunicorn ã\81¨ Uvicorn](server-workers.md){.internal-link target=_blank}ã\81§è©³ã\81\97ã\81\8f説æ\98\8eã\81\97ã\81¦ã\81\84ます。
\8d\98ç´\94ã\81ªã\82»ã\83\83ã\83\88ã\82¢ã\83\83ã\83\97ã\81§ã\80\81**å\8d\98ä¸\80ã\81®ã\82³ã\83³ã\83\86ã\83\8a**ã\81§è¤\87æ\95°ã\81®**ã\83¯ã\83¼ã\82«ã\83¼ã\83\97ã\83­ã\82»ã\82¹**ï¼\88ã\81¾ã\81\9fã\81¯1ã\81¤ã\81®ã\83\97ã\83­ã\82»ã\82¹ã\81®ã\81¿ï¼\89ã\82\92èµ·å\8b\95ã\81\99ã\82\8bå ´å\90\88ã\80\81ã\82¢ã\83\97ã\83ªã\81§ã\83\97ã\83­ã\82»ã\82¹ã\82\92é\96\8bå§\8bã\81\99ã\82\8bç\9b´å\89\8dã\81«ã\80\81å\90\8cã\81\98ã\82³ã\83³ã\83\86ã\83\8aã\81§äº\8bå\89\8dã\81®ã\82¹ã\83\86ã\83\83ã\83\97ã\82\92å®\9fè¡\8cã\81§ã\81\8dます。
 
-このイメージは、主に上記で説明した状況で役に立つでしょう: [複数のプロセスと特殊なケースを持つコンテナ(Containers with Multiple Processes and Special Cases)](#containers-with-multiple-processes-and-special-cases)
+### ベースDockerイメージ { #base-docker-image }
 
-* <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>.
+以前は、公式のFastAPI Dockerイメージがありました:<a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>。しかし、現在は非推奨です。⛔️
 
-/// warning
+おそらく、このベースDockerイメージ(またはその他の類似のもの)は**使用しない**方がよいでしょう。
 
\81\93ã\81®ã\83\99ã\83¼ã\82¹ã\82¤ã\83¡ã\83¼ã\82¸ã\82\84é¡\9eä¼¼ã\81®ã\82¤ã\83¡ã\83¼ã\82¸ã\81¯**å¿\85è¦\81ã\81ªã\81\84**å\8f¯è\83½æ\80§ã\81\8cé«\98ã\81\84ã\81®ã\81§ã\80\81[ä¸\8aè¨\98ã\81®: FastAPIç\94¨ã\81®Dockerã\82¤ã\83¡ã\83¼ã\82¸ã\82\92ã\83\93ã\83«ã\83\89ã\81\99ã\82\8bï¼\88Build a Docker Image for FastAPIï¼\89](#build-a-docker-image-for-fastapi)ã\81®ã\82\88ã\81\86ã\81«ã\82¼ã\83­ã\81\8bã\82\89ã\82¤ã\83¡ã\83¼ã\82¸ã\82\92ã\83\93ã\83«ã\83\89ã\81\99ã\82\8bæ\96¹ã\81\8cè\89¯ã\81\84ã\81§ã\81\97ã\82\87ã\81\86
\81\99ã\81§ã\81«**Kubernetes**ï¼\88ã\81¾ã\81\9fã\81¯ä»\96ã\81®ã\82\82ã\81®ï¼\89ã\82\92使ç\94¨ã\81\97ã\81¦ã\81\84ã\81¦ã\80\81è¤\87æ\95°ã\81®**ã\82³ã\83³ã\83\86ã\83\8a**ã\81§ã\80\81ã\82¯ã\83©ã\82¹ã\82¿ã\83¬ã\83\99ã\83«ã\81§**ã\83¬ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³**ã\82\92設å®\9aã\81\97ã\81¦ã\81\84ã\82\8bå ´å\90\88ã\80\82ã\81\9dã\81®ã\82\88ã\81\86ã\81ªå ´å\90\88ã\81¯ã\80\81ä¸\8aè¨\98ã\81§èª¬æ\98\8eã\81\97ã\81\9fã\82\88ã\81\86ã\81«**ã\82¼ã\83­ã\81\8bã\82\89**ã\82¤ã\83¡ã\83¼ã\82¸ã\82\92æ§\8bç¯\89ã\81\99ã\82\8bæ\96¹ã\81\8cã\82\88ã\81\84ã\81§ã\81\97ã\82\87ã\81\86ï¼\9a[FastAPIç\94¨ã\81®Dockerã\82¤ã\83¡ã\83¼ã\82¸ã\82\92ã\83\93ã\83«ã\83\89ã\81\99ã\82\8b](#build-a-docker-image-for-fastapi)
 
-///
-
-このイメージには、利用可能なCPUコアに基づいて**ワーカー・プロセスの数**を設定する**オートチューニング**メカニズムが含まれています。
+また、複数のワーカーが必要な場合は、単純に `--workers` コマンドラインオプションを使用できます。
 
-これは**賢明なデフォルト**を備えていますが、**環境変数**や設定ファイルを使ってすべての設定を変更したり更新したりすることができます。
+/// note | 技術詳細
 
\81¾ã\81\9fã\80\81ã\82¹ã\82¯ã\83ªã\83\97ã\83\88ã\81§<a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker#pre_start_path" class="external-link" target="_blank">**é\96\8bå§\8bå\89\8dã\81®äº\8bå\89\8dã\82¹ã\83\86ã\83\83ã\83\97**</a>ã\82\92å®\9fè¡\8cã\81\99ã\82\8bã\81\93ã\81¨ã\82\82ã\82µã\83\9dã\83¼ã\83\88ã\81\97ã\81¦ã\81\84ã\82\8b
\81\93ã\81®Dockerã\82¤ã\83¡ã\83¼ã\82¸ã\81¯ã\80\81Uvicornã\81\8cå\81\9cæ­¢ã\81\97ã\81\9fã\83¯ã\83¼ã\82«ã\83¼ã\81®ç®¡ç\90\86ã\81¨å\86\8dèµ·å\8b\95ã\82\92ã\82µã\83\9dã\83¼ã\83\88ã\81\97ã\81¦ã\81\84ã\81ªã\81\8bã\81£ã\81\9fé \83ã\81«ä½\9cæ\88\90ã\81\95ã\82\8cã\81\9fã\81\9fã\82\81ã\80\81Uvicornã\81¨ä¸\80ç·\92ã\81«Gunicornã\82\92使ã\81\86å¿\85è¦\81ã\81\8cã\81\82ã\82\8aã\81¾ã\81\97ã\81\9fã\80\82ã\81\93ã\82\8cã\81¯ã\80\81Gunicornã\81«Uvicornã\83¯ã\83¼ã\82«ã\83¼ã\83\97ã\83­ã\82»ã\82¹ã\81®ç®¡ç\90\86ã\81¨å\86\8dèµ·å\8b\95ã\82\92ã\81\95ã\81\9bã\82\8bã\81 ã\81\91ã\81®ã\81\9fã\82\81ã\81«ã\80\81ã\81\8bã\81ªã\82\8aã\81®è¤\87é\9b\91ã\81\95ã\82\92追å\8a ã\81\97ã\81¦ã\81\84ã\81¾ã\81\97ã\81\9f
 
-/// tip
-
-すべての設定とオプションを見るには、Dockerイメージのページをご覧ください: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>
+しかし現在は、Uvicorn(および `fastapi` コマンド)が `--workers` をサポートしているため、自分でビルドする代わりにベースDockerイメージを使う理由はありません(コード量もだいたい同じです 😅)。
 
 ///
 
-### 公式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 +604,21 @@ COPY ./app /app/app
 * Nomadのような別のツール
 * コンテナ・イメージをデプロイするクラウド・サービス
 
-## Poetryを利用したDockerイメージ
-
-もしプロジェクトの依存関係を管理するために<a href="https://python-poetry.org/" class="external-link" target="_blank">Poetry</a>を利用する場合、マルチステージビルドを使うと良いでしょう。
-
-```{ .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` ファイルだけだからです。
+## `uv` を使ったDockerイメージ { #docker-image-with-uv }
 
-そして次の(そして最終的な)ステージでは、前述とほぼ同じ方法でイメージをビルドします
+<a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a> を使ってプロジェクトのインストールと管理をしている場合は、<a href="https://docs.astral.sh/uv/guides/integration/docker/" class="external-link" target="_blank">uv Docker guide</a>に従ってください
 
-### 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キャッシュ**内の命令の**順番**に注意することで、**ビルド時間を最小化**し、生産性を最大化できます(そして退屈を避けることができます)。😎
index 7b0f567aa50f6d23ef681c4bcaa5b683d80b55fc..d5a6daf0c05a564dadece01c47a13a4bc53efe0b 100644 (file)
@@ -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レベルで暗号化を処理するもの)には、**<a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="サーバー名表示">SNI</abbr></a>**と呼ばれる**拡張**があります。
+* **TLS**プロトコル(HTTPの前に、TCPレベルで暗号化を処理するもの)には、**<a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication">SNI</abbr></a>**と呼ばれる**拡張**があります。
     * このSNI拡張機能により、1つのサーバー(**単一のIPアドレス**を持つ)が**複数のHTTPS証明書**を持ち、**複数のHTTPSドメイン/アプリケーション**にサービスを提供できるようになります。
     * これが機能するためには、**パブリックIPアドレス**でリッスンしている、サーバー上で動作している**単一の**コンポーネント(プログラム)が、サーバー内の**すべてのHTTPS証明書**を持っている必要があります。
-
 * セキュアな接続を取得した**後**でも、通信プロトコルは**HTTPのまま**です。
     * コンテンツは**HTTPプロトコル**で送信されているにもかかわらず、**暗号化**されています。
 
-
-サーバー(マシン、ホストなど)上で**1つのプログラム/HTTPサーバー**を実行させ、**HTTPSに関する全てのこと**を管理するのが一般的です。
-
-**暗号化された HTTPS リクエスト** を受信し、**復号化された HTTP リクエスト** を同じサーバーで実行されている実際の HTTP アプリケーション(この場合は **FastAPI** アプリケーション)に送信し、アプリケーションから **HTTP レスポンス** を受け取り、適切な **HTTPS 証明書** を使用して **暗号化** し、そして**HTTPS** を使用してクライアントに送り返します。
-
-このサーバーはしばしば **<a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">TLS Termination Proxy</a>**と呼ばれます。
+サーバー(マシン、ホストなど)上で**1つのプログラム/HTTPサーバー**を実行させ、**HTTPSに関する全てのこと**を管理するのが一般的です。**暗号化された HTTPS リクエスト** を受信し、**復号化された HTTP リクエスト** を同じサーバーで実行されている実際の HTTP アプリケーション(この場合は **FastAPI** アプリケーション)に送信し、アプリケーションから **HTTP レスポンス** を受け取り、適切な **HTTPS 証明書** を使用して **暗号化** し、そして**HTTPS** を使用してクライアントに送り返します。このサーバーはしばしば **<a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">TLS Termination Proxy</a>**と呼ばれます。
 
 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サーバー(おそらく同じクラウドプロバイダー)に設定します。
 
-おそらくクラウドサーバー(仮想マシン)かそれに類するものを手に入れ、<abbr title="変わらない">固定の</abbr> **パブリックIPアドレス**を持つことになるでしょう。
+おそらくクラウドサーバー(仮想マシン)かそれに類するものを手に入れ、<abbr title="That doesn't change – 変わらない">fixed</abbr> **パブリックIPアドレス**を持つことになるでしょう。
 
-DNSサーバーでは、**取得したドメイン**をあなたのサーバーのパプリック**IPアドレス**に向けるレコード(「`Aレコード`」)を設定します。
+DNSサーバーでは、**取得したドメイン**をあなたのサーバーのパプリック**IPアドレス**に向けるレコード(「`A record`」)を設定します。
 
 これはおそらく、最初の1回だけあり、すべてをセットアップするときに行うでしょう。
 
-/// tip
+/// tip | 豆知識
 
 ドメイン名の話はHTTPSに関する話のはるか前にありますが、すべてがドメインとIPアドレスに依存するため、ここで言及する価値があります。
 
 ///
 
-### DNS
+### DNS { #dns }
 
 では、実際のHTTPSの部分に注目してみよう。
 
@@ -94,7 +88,7 @@ DNSサーバーは、ブラウザに特定の**IPアドレス**を使用する
 
 <img src="/img/deployment/https/https01.drawio.svg">
 
-### 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`という特定のポートを使用する。つまり、これが必要なポートです。
 
\81\93ã\81®ã\83\9dã\83¼ã\83\88ã\82\92ã\83ªã\83\83ã\82¹ã\83³できるのは1つのプロセスだけなので、これを実行するプロセスは**TLS Termination Proxy**となります。
\81\93ã\81®ã\83\9dã\83¼ã\83\88ã\82\92ã\83ªã\82¯ã\82¨ã\82¹ã\83\88できるのは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証明書)に
 
 <img src="/img/deployment/https/https04.drawio.svg">
 
-### リクエストの復号化
+### リクエストの復号化 { #decrypt-the-request }
 
 TLS Termination Proxy は、合意が取れている暗号化を使用して、**リクエストを復号化**し、**プレーン (復号化された) HTTP リクエスト** をアプリケーションを実行しているプロセス (例えば、FastAPI アプリケーションを実行している Uvicorn を持つプロセス) に送信します。
 
 <img src="/img/deployment/https/https05.drawio.svg">
 
-### HTTP レスポンス
+### HTTP レスポンス { #http-response }
 
 アプリケーションはリクエストを処理し、**プレーン(暗号化されていない)HTTPレスポンス** をTLS Termination Proxyに送信します。
 
 <img src="/img/deployment/https/https06.drawio.svg">
 
-### 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 | 技術詳細
+
+プロキシヘッダーは次のとおりです:
+
+* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For" class="external-link" target="_blank">X-Forwarded-For</a>
+* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto" class="external-link" target="_blank">X-Forwarded-Proto</a>
+* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host" class="external-link" target="_blank">X-Forwarded-Host</a>
+
+///
+
+それでも、**アプリケーションサーバー**は信頼できる**プロキシ**の背後にあることを知らないため、デフォルトではそれらのヘッダーを信頼しません。
+
+しかし、**アプリケーションサーバー**が**プロキシ**から送信される*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** をセットアップする方法について、いくつかの具体例を紹介します。🔒
+次ã\81®ç« ã\81®ã\81\84ã\81\8fã\81¤ã\81\8bã\81§ã\81¯ã\80\81**FastAPI** ã\82¢ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³ã\81®ã\81\9fã\82\81ã\81« **HTTPS** ã\82\92ã\82»ã\83\83ã\83\88ã\82¢ã\83\83ã\83\97ã\81\99ã\82\8bæ\96¹æ³\95ã\81«ã\81¤ã\81\84ã\81¦ã\80\81ã\81\84ã\81\8fã\81¤ã\81\8bã\81®å\85·ä½\93ä¾\8bã\82\92ç´¹ä»\8bã\81\97ã\81¾ã\81\99ã\80\82ð\9f\94\92
index 897956e38fb78d689e2658e646111d4864ecb962..eba6eae6eacbec00a9740ab0b6ca31e353913221 100644 (file)
@@ -1,7 +1,23 @@
-# デプロイ
+# デプロイ { #deployment }
 
-**FastAPI** 製のアプリケーションは比較的容易にデプロイできます。
+**FastAPI** アプリケーションのデプロイは比較的簡単です。
 
-ユースケースや使用しているツールによっていくつかの方法に分かれます。
+## デプロイとは { #what-does-deployment-mean }
 
-次のセクションでより詳しくそれらの方法について説明します。
+アプリケーションを**デプロイ**するとは、**ユーザーが利用できるようにする**ために必要な手順を実行することを意味します。
+
+**Web API** の場合、通常は **リモートマシン** 上に配置し、優れたパフォーマンス、安定性などを提供する **サーバープログラム** と組み合わせて、**ユーザー** が中断や問題なく効率的にアプリケーションへ**アクセス**できるようにします。
+
+これは **開発** 段階とは対照的です。開発では、コードを常に変更し、壊しては直し、開発サーバーを停止したり再起動したりします。
+
+## デプロイ戦略 { #deployment-strategies }
+
+具体的なユースケースや使用するツールによって、いくつかの方法があります。
+
+複数のツールを組み合わせて自分で**サーバーをデプロイ**することもできますし、作業の一部を代行してくれる **クラウドサービス** を使うこともできます。ほかにも選択肢があります。
+
+たとえば、FastAPI の開発チームである私たちは、クラウドへの FastAPI アプリのデプロイを可能な限り合理化し、FastAPI を使って開発するのと同じ開発者体験を提供するために、<a href="https://fastapicloud.com" class="external-link" target="_blank">**FastAPI Cloud**</a> を構築しました。
+
+**FastAPI** アプリケーションをデプロイする際に、おそらく念頭に置くべき主要な概念をいくつか紹介します(ただし、そのほとんどは他の種類の Web アプリケーションにも当てはまります)。
+
+次のセクションでは、留意すべき点の詳細や、それを実現するためのいくつかの手法を確認します。 ✨
index 38ceab017280f6ef58701db6664d21995e969a8e..933b875d76a3d17e38abc253c3c36a0add5d4358 100644 (file)
@@ -1,4 +1,4 @@
-# Server Workers - Gunicorn と Uvicorn
+# Server Workers - ワーカー付きUvicorn { #server-workers-uvicorn-with-workers }
 
 前回のデプロイメントのコンセプトを振り返ってみましょう:
 
 * メモリ
 * 開始前の事前ステップ
 
-ここまでのドキュメントのチュートリアルでは、おそらくUvicornのような**サーバープログラム**を**単一のプロセス**で実行しています。
+ここまでのドキュメントのチュートリアルでは、おそらく `fastapi` コマンドなど(Uvicornを実行するもの)を使って、**単一のプロセス**として動作する**サーバープログラム**を実行してきたはずです。
 
 アプリケーションをデプロイする際には、**複数のコア**を利用し、そしてより多くのリクエストを処理できるようにするために、プロセスの**レプリケーション**を持つことを望むでしょう。
 
 前のチャプターである[デプロイメントのコンセプト](concepts.md){.internal-link target=_blank}にて見てきたように、有効な戦略がいくつかあります。
 
-ここでは<a href="https://gunicorn.org/" class="external-link" target="_blank">**Gunicorn**</a>が**Uvicornのワーカー・プロセス**を管理する場合の使い方について紹介していきます。
+ここでは、`fastapi` コマンド、または `uvicorn` コマンドを直接使って、**ワーカープロセス**付きの **Uvicorn** を使う方法を紹介します。
 
-/// info
+/// info | 情報
 
-<!-- NOTE: the current version of docker.md is outdated compared to English one.  -->
-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は最新の**<a href="https://asgi.readthedocs.io/en/latest/" class="external-link" target="_blank">ASGI 標準</a>**を使用しているためです。
+`--workers` コマンドラインオプションで複数のワーカーを起動できます。
 
-しかし、Gunicornは**プロセスマネージャー**として動作し、ユーザーが特定の**ワーカー・プロセスクラス**を使用するように指示することができます。するとGunicornはそのクラスを使い1つ以上の**ワーカー・プロセス**を開始します。
+//// tab | `fastapi`
 
-そして**Uvicorn**には**Gunicorn互換のワーカークラス**があります。
-
-この組み合わせで、Gunicornは**プロセスマネージャー**として動作し、**ポート**と**IP**をリッスンします。そして、**Uvicornクラス**を実行しているワーカー・プロセスに通信を**転送**します。
-
-そして、Gunicorn互換の**Uvicornワーカー**クラスが、FastAPIが使えるように、Gunicornから送られてきたデータをASGI標準に変換する役割を担います。
-
-## GunicornとUvicornをインストールする
-
-<div class="termy">
-
-```console
-$ pip install "uvicorn[standard]" gunicorn
-
----> 100%
-```
-
-</div>
-
-これによりUvicornと(高性能を得るための)標準(`standard`)の追加パッケージとGunicornの両方がインストールされます。
-
-## UvicornのワーカーとともにGunicornを実行する
-
-Gunicornを以下のように起動させることができます:
+`fastapi` コマンドを使う場合:
 
 <div class="termy">
 
 ```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.
-```
-
-</div>
-
-それぞれのオプションの意味を見てみましょう:
-
-* `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`の部分と同じになります。
+$ <font color="#4E9A06">fastapi</font> run --workers 4 <u style="text-decoration-style:solid">main.py</u>
 
-* `--workers`: 使用するワーカー・プロセスの数で、それぞれがUvicornのワーカーを実行します。
+  <span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span>  Starting production server 🚀
 
-* `--worker-class`: ワーカー・プロセスで使用するGunicorn互換のワーカークラスです。
-    * ここではGunicornがインポートして使用できるクラスを渡します:
+             Searching for package file structure from directories with
+             <font color="#3465A4">__init__.py</font> files
+             Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
 
-        ```Python
-        import uvicorn.workers.UvicornWorker
-        ```
+   <span style="background-color:#007166"><font color="#D3D7CF"> module </font></span>  🐍 main.py
 
-* `--bind`: GunicornにリッスンするIPとポートを伝えます。コロン(`:`)でIPとポートを区切ります。
-    * Uvicornを直接実行している場合は、`--bind 0.0.0.0:80` (Gunicornのオプション)の代わりに、`--host 0.0.0.0`と `--port 80`を使います。
+     <span style="background-color:#007166"><font color="#D3D7CF"> code </font></span>  Importing the FastAPI app object from the module with the
+             following code:
 
-出力では、各プロセスの**PID**(プロセスID)が表示されているのがわかります(単なる数字です)。
+             <u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
 
-以下の通りです:
+      <span style="background-color:#007166"><font color="#D3D7CF"> app </font></span>  Using import string: <font color="#3465A4">main:app</font>
 
-* Gunicornの**プロセス・マネージャー**はPID `19499`(あなたの場合は違う番号でしょう)で始まります。
-* 次に、`Listening at: http://0.0.0.0:80`を開始します。
-* それから `uvicorn.workers.UvicornWorker` でワーカークラスを使用することを検出します。
-* そして、**4つのワーカー**を起動します。それぞれのワーカーのPIDは、`19511`、`19513`、`19514`、`19515`です。
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font>
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000/docs</u></font>
 
-Gunicornはまた、ワーカーの数を維持するために必要であれば、**ダウンしたプロセス**を管理し、**新しいプロセスを**再起動**させます。そのため、上記のリストにある**再起動**の概念に一部役立ちます。
+             Logs:
 
-しかしながら、必要であればGunicornを**再起動**させ、**起動時に実行**させるなど、外部のコンポーネントを持たせることも必要かもしれません。
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font> <b>(</b>Press CTRL+C to
+             quit<b>)</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started parent process <b>[</b><font color="#34E2E2"><b>27365</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started server process <b>[</b><font color="#34E2E2"><b>27368</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started server process <b>[</b><font color="#34E2E2"><b>27369</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started server process <b>[</b><font color="#34E2E2"><b>27370</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started server process <b>[</b><font color="#34E2E2"><b>27367</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Waiting for application startup.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Waiting for application startup.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Waiting for application startup.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Waiting for application startup.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Application startup complete.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Application startup complete.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Application startup complete.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Application startup complete.
+```
 
-## Uvicornとワーカー
+</div>
 
-Uvicornには複数の**ワーカー・プロセス**を起動し実行するオプションもあります。
+////
 
-とはいうものの、今のところUvicornのワーカー・プロセスを扱う機能はGunicornよりも制限されています。そのため、このレベル(Pythonレベル)でプロセスマネージャーを持ちたいのであれば、Gunicornをプロセスマネージャーとして使ってみた方が賢明かもしれないです。
+//// tab | `uvicorn`
 
-どんな場合であれ、以下のように実行します
+`uvicorn` コマンドを直接使いたい場合
 
 <div class="termy">
 
@@ -150,36 +105,35 @@ $ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
 
 </div>
 
-ここで唯一の新しいオプションは `--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
-<!-- NOTE: the current version of docker.md is outdated compared to English one.  -->
-次章の[コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}では、その他の**デプロイのコンセプト**を扱うために実施するであろう戦略をいくつか紹介します。
+## コンテナとDocker { #containers-and-docker }
 
-また、**GunicornとUvicornワーカー**を含む**公式Dockerイメージ**と、簡単なケースに役立ついくつかのデフォルト設定も紹介します。
+次章の[コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}では、その他の**デプロイメントのコンセプト**を扱うために使える戦略をいくつか説明します。
 
-また、(Gunicornを使わずに)Uvicornプロセスを1つだけ実行するために、**ゼロから独自のイメージを**構築する方法も紹介します。これは簡単なプロセスで、おそらく**Kubernetes**のような分散コンテナ管理システムを使うときにやりたいことでしょう。
+単一のUvicornプロセスを実行するために、**ゼロから独自のイメージを構築する**方法も紹介します。これは簡単なプロセスで、**Kubernetes**のような分散コンテナ管理システムを使う場合に、おそらくやりたいことでしょう。
 
-## まとめ
+## まとめ { #recap }
 
-Uvicornワーカーを使ったプロセスマネージャとして**Gunicorn**(またはUvicorn)を使えば、**マルチコアCPU**を活用して**複数のプロセスを並列実行**できます。
+`fastapi` または `uvicorn` コマンドで `--workers` CLIオプションを使うことで、**マルチコアCPU**を活用し、**複数のプロセスを並列実行**できるように複数のワーカープロセスを利用できます。
 
-これらのツールやアイデアは、**あなた自身のデプロイシステム**をセットアップしながら、他のデプロイコンセプトを自分で行う場合にも使えます。
+他のデプロイメントのコンセプトを自分で対応しながら、**独自のデプロイシステム**を構築している場合にも、これらのツールやアイデアを使えます。
 
-次ã\81®ç« ã\81§ã\81¯ã\80\81ã\82³ã\83³ã\83\86ã\83\8aï¼\88Dockerã\82\84Kubernetesã\81ªã\81©ï¼\89ã\82\92使ã\81£ã\81\9f**FastAPI**ã\81«ã\81¤ã\81\84ã\81¦å­¦ã\82\93ã\81§ã\81\84ã\81\8dã\81¾ã\81\97ã\82\87ã\81\86ã\80\82ã\81\93ã\82\8cã\82\89ã\81®ã\83\84ã\83¼ã\83«ã\81«ã\81¯ã\80\81ä»\96ã\81®**ã\83\87ã\83\97ã\83­ã\82¤ã\81®ã\82³ã\83³ã\82»ã\83\97ã\83\88**ã\82\82解決ã\81\99ã\82\8bç°¡å\8d\98ã\81ªæ\96¹æ³\95ã\81\8cã\81\82ã\82\8bã\81\93ã\81¨ã\81\8cã\82\8fã\81\8bã\82\8bã\81§ã\81\97ã\82\87ã\81\86。✨
+次ã\81®ç« ã\81§ã\80\81ã\82³ã\83³ã\83\86ã\83\8aï¼\88ä¾\8bï¼\9aDockerã\82\84Kubernetesï¼\89ã\82\92使ã\81£ã\81\9f **FastAPI** ã\81«ã\81¤ã\81\84ã\81¦å­¦ã\81³ã\81¾ã\81\97ã\82\87ã\81\86ã\80\82ã\81\93ã\82\8cã\82\89ã\81®ã\83\84ã\83¼ã\83«ã\81«ã\82\82ã\80\81ä»\96ã\81®**ã\83\87ã\83\97ã\83­ã\82¤ã\83¡ã\83³ã\83\88ã\81®ã\82³ã\83³ã\82»ã\83\97ã\83\88**ã\82\92解決ã\81\99ã\82\8bç°¡å\8d\98ã\81ªæ\96¹æ³\95ã\81\8cã\81\82ã\82\8bã\81\93ã\81¨ã\81\8cã\82\8fã\81\8bã\82\8aã\81¾ã\81\99。✨
index 7575fc4f70c47611df4a13f832373d69f6cf3a81..7980b8be2a6830d370d93be0103fdcaa6dd6cc4b 100644 (file)
@@ -1,93 +1,93 @@
-# FastAPIのバージョンについて
+# FastAPIのバージョンについて { #about-fastapi-versions }
 
-**FastAPI** は既に多くのアプリケーションやシステムに本番環境で使われています。また、100%のテストカバレッジを維持しています。しかし、活発な開発が続いています。
+**FastAPI** はすでに多くのアプリケーションやシステムで本番環境にて使われています。また、テストカバレッジは 100% に維持されています。しかし、開発は依然として急速に進んでいます。
 
-高頻度で新機能が追加され、定期的にバグが修正され、実装は継続的に改善されています。
+新機能が高頻度で追加され、定期的にバグが修正され、コードは継続的に改善されています。
 
 これが現在のバージョンがいまだに `0.x.x` な理由であり、それぞれのバージョンは破壊的な変更がなされる可能性があります。これは、<a href="https://semver.org/" class="external-link" target="_blank">セマンティック バージョニング</a>の規則に則っています。
 
-**FastAPI** を使用すると本番用アプリケーションをすぐに作成できますが (すでに何度も経験しているかもしれませんが)、残りのコードが正しく動作するバージョンなのか確認しなければいけません
+**FastAPI** を使用すると本番用アプリケーションを今すぐ作成できます(そして、おそらくあなたはしばらく前からそうしているはずです)。必要なのは、残りのコードと正しく動作するバージョンを使用していることを確認することだけです
 
-## `fastapi` のバージョンを固定
+## `fastapi` のバージョンを固定 { #pin-your-fastapi-version }
 
-最初にすべきことは、アプリケーションが正しく動作する **FastAPI** のバージョンを固定することです。
+最初にすべきことは、使用している **FastAPI** のバージョンを、アプリケーションで正しく動作することが分かっている特定の最新バージョンに「固定(pin)」することです。
 
-ä¾\8bã\81\88ã\81°ã\80\81ã\83\90ã\83¼ã\82¸ã\83§ã\83³ `0.45.0` を使っているとしましょう。
+ä¾\8bã\81\88ã\81°ã\80\81ã\82¢ã\83\97ã\83ªã\81§ã\83\90ã\83¼ã\82¸ã\83§ã\83³ `0.112.0` を使っているとしましょう。
 
-`requirements.txt` ã\82\92使ã\81£ã\81¦ã\81\84ã\82\8bã\81ªã\82\89ã\80\81以ä¸\8bã\81®æ§\98にバージョンを指定できます:
+`requirements.txt` ã\83\95ã\82¡ã\82¤ã\83«ã\82\92使ã\81\86å ´å\90\88ã\81¯ã\80\81以ä¸\8bã\81®ã\82\88ã\81\86にバージョンを指定できます:
 
 ```txt
-fastapi==0.45.0
+fastapi[standard]==0.112.0
 ```
 
-これは、厳密にバージョン `0.45.0` だけを使うことを意味します。
+これは、厳密にバージョン `0.112.0` だけを使うことを意味します。
 
-または、以下のに固定することもできます:
+または、以下のように固定することもできます:
 
 ```txt
-fastapi>=0.45.0,<0.46.0
+fastapi[standard]>=0.112.0,<0.113.0
 ```
 
-これは `0.45.0` 以上、`0.46.0` 未満のバージョンを使うことを意味します。例えば、バージョン `0.45.2` は使用可能です。
+これは `0.112.0` 以上、`0.113.0` 未満のバージョンを使うことを意味します。例えば、バージョン `0.112.2` は使用可能です。
 
-PoetryやPipenvなど、他のインストール管理ツールを使用している場合でも、それぞれパッケージのバージョンを指定する機能があります。
+`uv`、Poetry、Pipenv など、他のインストール管理ツールを使用している場合でも、いずれもパッケージの特定バージョンを定義する方法があります。
 
-## 利用可能なバージョン
+## 利用可能なバージョン { #available-versions }
 
-[Release Notes](../release-notes.md){.internal-link target=_blank}で利用可能なバージョンが確認できます (現在の最新版の確認などのため)
+利用可能なバージョン(例: 現在の最新が何かを確認するため)は、[Release Notes](../release-notes.md){.internal-link target=_blank} で確認できます
 
-## バージョンについて
+## バージョンについて { #about-versions }
 
-セマンティック バージョニングの規約に従って、`1.0.0` 未満の全てのバージョンは破壊的な変更が加わる可能性があります。
+セマンティック バージョニングの規約に従って、`1.0.0` 未満のバージョンは破壊的な変更が加わる可能性があります。
 
-FastAPIでは「パッチ」バージョンはバグ修正と非破壊的な変更に留めるという規約に従っています。
+FastAPI では「PATCH」バージョンの変更はバグ修正と非破壊的な変更に使う、という規約にも従っています。
 
 /// tip | 豆知識
 
-「パッチ」は最後の数字を指します。例えば、`0.2.3` ではパッチバージョンは `3` です。
+「PATCH」は最後の数字です。例えば、`0.2.3` では PATCH バージョンは `3` です。
 
 ///
 
-従って、以下の様なバージョンの固定が望ましいです:
+従って、以下のようなバージョンの固定ができるはずです:
 
 ```txt
 fastapi>=0.45.0,<0.46.0
 ```
 
-破壊的な変更と新機能実装は「マイナー」バージョンで加えられます。
+破壊的な変更と新機能は「MINOR」バージョンで追加されます。
 
 /// tip | 豆知識
 
-「マイナー」は真ん中の数字です。例えば、`0.2.3` ではマイナーバージョンは `2` です。
+「MINOR」は真ん中の数字です。例えば、`0.2.3` では MINOR バージョンは `2` です。
 
 ///
 
-## FastAPIのバージョンのアップグレード
+## FastAPIのバージョンのアップグレード { #upgrading-the-fastapi-versions }
 
-アプリケーションにテストを加えるべきです。
+アプリケーションにテストを追加すべきです。
 
-**FastAPI** では非常に簡単に実現できます (Starletteのおかげで)。ドキュメントを確認して下さい: [テスト](../tutorial/testing.md){.internal-link target=_blank}
+**FastAPI** では非常に簡単に実現できます(Starlette のおかげです)。ドキュメントを確認して下さい: [テスト](../tutorial/testing.md){.internal-link target=_blank}
 
-テストを加えた後で、**FastAPI** のバージョンをより最新のものにアップグレードし、テストを実行することで全てのコードが正常に動作するか確認できます。
+テストを追加したら、**FastAPI** のバージョンをより新しいものにアップグレードし、テストを実行することで全てのコードが正しく動作するか確認できます。
 
\85¨ã\81¦ã\81\8cå\8b\95ä½\9cã\81\99ã\82\8bã\81\8bã\80\81修正ã\82\92è¡\8cã\81£ã\81\9fä¸\8aã\81§å\85¨ã\81¦ã\81®ã\83\86ã\82¹ã\83\88ã\82\92é\80\9aé\81\8eã\81\97ã\81\9få ´å\90\88ã\80\81使ç\94¨ã\81\97ã\81¦ã\81\84ã\82\8b`fastapi` ã\81®ã\83\90ã\83¼ã\82¸ã\83§ã\83³ã\82\92ã\82\88ã\82\8aæ\9c\80æ\96°ã\81®ã\83\90ã\83¼ã\82¸ã\83§ã\83³ã\81«固定できます。
\85¨ã\81¦ã\81\8cå\8b\95ä½\9cã\81\99ã\82\8bã\80\81ã\81¾ã\81\9fã\81¯å¿\85è¦\81ã\81ªå¤\89æ\9b´ã\82\92è¡\8cã\81£ã\81\9få¾\8cã\81«å\85¨ã\81¦ã\81®ã\83\86ã\82¹ã\83\88ã\81\8cé\80\9aã\82\8bã\81ªã\82\89ã\80\81ã\81\9dã\81®æ\96°ã\81\97ã\81\84ã\83\90ã\83¼ã\82¸ã\83§ã\83³ã\81« `fastapi` ã\82\92固定できます。
 
-## Starletteについて
+## Starletteについて { #about-starlette }
 
-`Starlette` のバージョンは固定すべきではありません。
+`starlette` のバージョンは固定すべきではありません。
 
-**FastAPI** ã\81¯ã\80\81ã\83\90ã\83¼ã\82¸ã\83§ã\83³æ¯\8eã\81«Starletteã\81®ã\82\88ã\82\8aæ\96°ã\81\97ã\81\84ã\83\90ã\83¼ã\82¸ã\83§ã\83³ã\82\92使ç\94¨ã\81\97ます。
+**FastAPI** ã\81®ã\83\90ã\83¼ã\82¸ã\83§ã\83³ã\81\8cç\95°ã\81ªã\82\8cã\81°ã\80\81Starlette ã\81®ç\89¹å®\9aã\81®ã\82\88ã\82\8aæ\96°ã\81\97ã\81\84ã\83\90ã\83¼ã\82¸ã\83§ã\83³ã\81\8c使ã\82\8fã\82\8cます。
 
\82\88ã\81£ã\81¦ã\80\81æ\9c\80é\81©ã\81ªStarletteã\81®ã\83\90ã\83¼ã\82¸ã\83§ã\83³é\81¸æ\8a\9eã\82\92**FastAPI** ã\81«ä»»ã\81\9bã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\81¾す。
\81\9dã\81®ã\81\9fã\82\81ã\80\81æ­£ã\81\97ã\81\84 Starlette ã\83\90ã\83¼ã\82¸ã\83§ã\83³ã\82\92 **FastAPI** ã\81«ä»»ã\81\9bã\82\8cã\81°ã\82\88ã\81\84ã\81§す。
 
-## Pydanticについて
+## Pydanticについて { #about-pydantic }
 
-Pydanticは自身のテストだけでなく**FastAPI** のためのテストを含んでいます。なので、Pydanticの新たなバージョン ( `1.0.0` 以降) は全てFastAPIと整合性があります。
+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
 ```
index 507af3a0ccbb63a831d94e8e4bb119e82f75beab..45dbfc71fdbc532d28c7fc642bcd45285044e37e 100644 (file)
@@ -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
 
 <div class="termy">
 
-
 ```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 }
 
\92°å¢\83å¤\89æ\95°ã\82\92Pythonã\81®**å¤\96å\81´**ã\80\81ã\82¿ã\83¼ã\83\9fã\83\8aã\83«ï¼\88ã\82\84ä»\96ã\81®æ\96¹æ³\95ï¼\89ã\81§ä½\9cæ\88\90ã\81\97ã\80\81**Pythonå\86\85で読み取る**こともできます。
\92°å¢\83å¤\89æ\95°ã\81¯Pythonã\81®**å¤\96å\81´**ï¼\88ã\82¿ã\83¼ã\83\9fã\83\8aã\83«ã\80\81ã\81¾ã\81\9fã\81¯ã\81\9dã\81®ä»\96ã\81®æ\96¹æ³\95ï¼\89ã\81§ä½\9cæ\88\90ã\81\97ã\80\81ã\81\9dã\81®å¾\8cã\81«**Pythonで読み取る**こともできます。
 
 例えば、以下のような`main.py`ファイルを用意します:
 
@@ -64,11 +63,11 @@ name = os.getenv("MY_NAME", "World")
 print(f"Hello {name} from Python")
 ```
 
-/// tip
+/// tip | 豆知識
 
-<a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> ã\81®ç¬¬2å¼\95æ\95°ã\81¯ã\80\81ã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\81§è¿\94ã\81\95ã\82\8cã\82\8bå\80¤ã\82\92æ\8c\87å®\9aã\81\97ã\81¾す。
+<a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> ã\81®ç¬¬2å¼\95æ\95°ã\81¯ã\80\81ã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\81§è¿\94ã\81\95ã\82\8cã\82\8bå\80¤ã\81§す。
 
-この引数を省略するとデフォルト値として`None`が返されますが、ここではデフォルト値として`"World"`を指定しています。
+指定しない場合、デフォルトは`None`ですが、ここでは使用するデフォルト値として`"World"`を指定しています。
 
 ///
 
@@ -128,11 +127,11 @@ Hello Wade Wilson from Python
 
 ////
 
\92°å¢\83å¤\89æ\95°ã\81¯ã\82³ã\83¼ã\83\89ã\81®å¤\96å\81´ã\81§è¨­å®\9aã\81\97ã\80\81å\86\85å\81´ã\81\8bã\82\89読ã\81¿å\8f\96ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\82\8bã\81®ã\81§ã\80\81ä»\96ã\81®ã\83\95ã\82¡ã\82¤ã\83«ã\81¨ä¸\80ç·\92ã\81«ï¼\88`git`ã\81«ï¼\89ä¿\9då­\98ã\81\99ã\82\8bå¿\85è¦\81ã\81\8cã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\80\82ã\81\9dã\81®ã\81\9fã\82\81ã\80\81ç\92°å¢\83å¤\89æ\95°ã\82\92ã\82³ã\83³ã\83\95ã\82£ã\82°ã\83¬ã\83¼ã\82·ã\83§ã\83³ã\82\84**設å®\9a**ã\81«ä½¿ç\94¨ã\81\99ã\82\8bã\81\93ã\81¨が一般的です。
\92°å¢\83å¤\89æ\95°ã\81¯ã\82³ã\83¼ã\83\89ã\81®å¤\96å\81´ã\81§è¨­å®\9aã\81§ã\81\8dã\80\81ã\82³ã\83¼ã\83\89ã\81\8bã\82\89読ã\81¿å\8f\96ã\82\8cã\80\81ä»\96ã\81®ã\83\95ã\82¡ã\82¤ã\83«ã\81¨ä¸\80ç·\92ã\81«ï¼\88`git`ã\81«ï¼\89ä¿\9då­\98ï¼\88ã\82³ã\83\9fã\83\83ã\83\88ï¼\89ã\81\99ã\82\8bå¿\85è¦\81ã\81\8cã\81ªã\81\84ã\81\9fã\82\81ã\80\81設å®\9aã\82\84**settings**ã\81«ä½¿ã\81\86ã\81®が一般的です。
 
\81¾ã\81\9fã\80\81**ç\89¹å®\9aã\81®ã\83\97ã\83­ã\82°ã\83©ã\83 ã\81®å\91¼ã\81³å\87ºã\81\97**ã\81®ã\81\9fã\82\81ã\81®ç\92°å¢\83å¤\89æ\95°ã\82\92ã\80\81ã\81\9dã\81®ã\83\97ã\83­ã\82°ã\83©ã\83 ã\81®ã\81¿ã\80\81ã\81\9dã\81®å®\9fè¡\8c中ã\81«é\99\90å®\9aã\81\97ã\81¦å\88©ç\94¨ã\81§ã\81\8dã\82\8bã\82\88ã\81\86ä½\9cæ\88\90できます。
\81¾ã\81\9fã\80\81**ç\89¹å®\9aã\81®ã\83\97ã\83­ã\82°ã\83©ã\83 ã\81®å\91¼ã\81³å\87ºã\81\97**ã\81®ã\81\9fã\82\81ã\81 ã\81\91ã\81«ã\80\81ã\81\9dã\81®ã\83\97ã\83­ã\82°ã\83©ã\83 ã\81§ã\81®ã\81¿ã\80\81å®\9fè¡\8c中ã\81®é\96\93ã\81 ã\81\91å\88©ç\94¨ã\81§ã\81\8dã\82\8bç\92°å¢\83å¤\89æ\95°ã\82\92ä½\9cæ\88\90ã\81\99ã\82\8bã\81\93ã\81¨ã\82\82できます。
 
-そのためには、プログラム起動コマンドと同じコマンドライン上の、起動コマンド直前で環境変数を作成してください。
+そのためには、同じ行で、プログラム自体の直前に作成してください。
 
 <div class="termy">
 
@@ -152,25 +151,25 @@ Hello World from Python
 
 </div>
 
-/// tip
+/// tip | 豆知識
 
 詳しくは <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a> を参照してください。
 
 ///
 
-## 型とバリデーション
+## 型とバリデーション { #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`**ã\81¨ã\81\84ã\81\86**ç\89¹å\88¥ã\81ª**ç\92°å¢\83å¤\89æ\95°ã\81\8cã\81\82ã\82\8aã\81¾ã\81\99ã\80\82ã\81\93ã\81®ç\92°å¢\83å¤\89æ\95°ã\81¯ã\80\81OSï¼\88Linuxã\80\81macOSã\80\81Windowsï¼\89ã\81\8cå®\9fè¡\8cã\81\99ã\82\8bã\83\97ã\83­ã\82°ã\83©ã\83 ã\82\92ç\99ºè¦\8bã\81\99るために使用されます。
+**`PATH`**ã\81¨ã\81\84ã\81\86**ç\89¹å\88¥ã\81ª**ç\92°å¢\83å¤\89æ\95°ã\81\8cã\81\82ã\82\8aã\81¾ã\81\99ã\80\82ã\81\93ã\82\8cã\81¯ã\82ªã\83\9aã\83¬ã\83¼ã\83\86ã\82£ã\83³ã\82°ã\82·ã\82¹ã\83\86ã\83 ï¼\88Linuxã\80\81macOSã\80\81Windowsï¼\89ã\81\8cå®\9fè¡\8cã\81\99ã\82\8bã\83\97ã\83­ã\82°ã\83©ã\83 ã\82\92è¦\8bã\81¤ã\81\91るために使用されます。
 
-`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
+////
 
-Pythonをインストールして、そのプログラムが`C:\opt\custompython\bin`というディレクトリに配置されたとします。
+//// tab | Windows
 
-もし、`PATH`環境変数を更新するように答えると、`PATH`環境変数に`C:\opt\custompython\bin`が追加されます。
+Pythonをインストールして、その結果`C:\opt\custompython\bin`というディレクトリに配置されたとします。
 
-`PATH`ç\92°å¢\83å¤\89æ\95°ã\81¯ä»¥ä¸\8bã\81®ã\82\88ã\81\86ã\81«æ\9b´æ\96°ã\81\95ã\82\8cã\82\8bã\81§ã\81\97ã\82\87ã\81\86ï¼\9a
+`PATH`ç\92°å¢\83å¤\89æ\95°ã\82\92æ\9b´æ\96°ã\81\99ã\82\8bã\81\93ã\81¨ã\81«å\90\8cæ\84\8fã\81\99ã\82\8bã\81¨ã\80\81ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\81¯`PATH`ç\92°å¢\83å¤\89æ\95°ã\81«`C:\opt\custompython\bin`ã\82\92追å\8a ã\81\97ã\81¾ã\81\99ã\80\82
 
 ```plaintext
 C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin
 ```
 
\81\93ã\81®ã\82\88ã\81\86ã\81«ã\81\97ã\81¦ã\80\81ã\82¿ã\83¼ã\83\9fã\83\8aã\83«ã\81§`python`ã\81¨å\85¥å\8a\9bã\81\97ã\81\9fã\81¨ã\81\8dã\81«ã\80\81OSã\81¯`C:\opt\custompython\bin\python`ï¼\88ã\83ªã\82¹ã\83\88ã\81®æ\9c«å°¾ã\81®ã\83\87ã\82£ã\83¬ã\82¯ã\83\88ã\83ªï¼\89ã\81«ã\81\82ã\82\8bPythonã\83\97ã\83­ã\82°ã\83©ã\83 ã\82\92è¦\8bã\81¤ã\81\91ã\80\81使用します。
\81\93ã\81®ã\82\88ã\81\86ã\81«ã\81\97ã\81¦ã\80\81ã\82¿ã\83¼ã\83\9fã\83\8aã\83«ã\81§`python`ã\81¨å\85¥å\8a\9bã\81\99ã\82\8bã\81¨ã\80\81ã\82·ã\82¹ã\83\86ã\83 ã\81¯`C:\opt\custompython\bin`ï¼\88æ\9c\80å¾\8cã\81®ã\83\87ã\82£ã\83¬ã\82¯ã\83\88ã\83ªï¼\89ã\81«ã\81\82ã\82\8bPythonã\83\97ã\83­ã\82°ã\83©ã\83 ã\82\92è¦\8bã\81¤ã\81\91ã\80\81ã\81\9dã\82\8cã\82\92使用します。
 
-///
+////
 
-つまり、ターミナルで以下のコマンドを入力すると:
+つまり、ターミナルで次のように入力すると:
 
 <div class="termy">
 
-``` console
+```console
 $ python
 ```
 
 </div>
 
-/// tab | Linux, macOS
+//// tab | Linux, macOS
 
-OSは`/opt/custompython/bin`にある`python`プログラムを**見つけ**て実行します。
+システムは`/opt/custompython/bin`にある`python`プログラムを**見つけ**て実行します。
 
\81\93ã\82\8cã\81¯ã\80\81次ã\81®ã\82³ã\83\9eã\83³ã\83\89ã\82\92å\85¥å\8a\9bã\81\97ã\81\9få ´å\90\88ã\81¨ã\81»ã\81¨ã\82\93ã\81©å\90\8cç­\89ã\81§ã\81\99ï¼\9a
\81\93ã\82\8cã\81¯ã\80\81次ã\81®ã\82\88ã\81\86ã\81«å\85¥å\8a\9bã\81\99ã\82\8bã\81®ã\81¨ã\81\8aã\81\8aã\82\80ã\81­å\90\8cç­\89ã\81§ã\81\99:
 
 <div class="termy">
 
@@ -270,13 +267,13 @@ $ /opt/custompython/bin/python
 
 </div>
 
-///
+////
 
-/// tab | Windows
+//// tab | Windows
 
-OSは`C:\opt\custompython\bin\python`にある`python`プログラムを**見つけ**て実行します。
+システムは`C:\opt\custompython\bin\python`にある`python`プログラムを**見つけ**て実行します。
 
\81\93ã\82\8cã\81¯ã\80\81次ã\81®ã\82³ã\83\9eã\83³ã\83\89ã\82\92å\85¥å\8a\9bã\81\97ã\81\9få ´å\90\88ã\81¨ã\81»ã\81¨ã\82\93ã\81©å\90\8cç­\89ã\81§ã\81\99ï¼\9a
\81\93ã\82\8cã\81¯ã\80\81次ã\81®ã\82\88ã\81\86ã\81«å\85¥å\8a\9bã\81\99ã\82\8bã\81®ã\81¨ã\81\8aã\81\8aã\82\80ã\81­å\90\8cç­\89ã\81§ã\81\99:
 
 <div class="termy">
 
@@ -286,16 +283,16 @@ $ C:\opt\custompython\bin\python
 
 </div>
 
-///
+////
 
-この情報は、[Virtual Environments](virtual-environments.md) について学ぶ際にも役立ちます。
+この情報は、[Virtual Environments](virtual-environments.md){.internal-link target=_blank} について学ぶ際にも役立ちます。
 
-## まとめ
+## まとめ { #conclusion }
 
 これで、**環境変数**とは何か、Pythonでどのように使用するかについて、基本的な理解が得られたはずです。
 
-環境変数についての詳細は、<a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Wikipedia: Environment Variable</a> を参照してください。
+環境変数についての詳細は、<a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Wikipedia for Environment Variable</a> も参照してください。
 
-環境変数の用途や適用方法が最初は直感的ではないかもしれませんが、開発中のさまざまなシナリオで繰り返し登場します。そのため、基本を知っておくことが重要です
+多くの場合、環境変数がどのように役立ち、すぐに適用できるのかはあまり明確ではありません。しかし、開発中のさまざまなシナリオで何度も登場するため、知っておくとよいでしょう
 
-たとえば、この情報は次のセクションで扱う[Virtual Environments](virtual-environments.md)にも関連します。
+例えば、次のセクションの[Virtual Environments](virtual-environments.md)でこの情報が必要になります。
index bfaa9e6d754b3e92360fcde8b61e856015514099..9478f5c032ea4f41ac3a7aef2688def9f9747ea6 100644 (file)
@@ -1,8 +1,8 @@
-# 条件付き OpenAPI
+# 条件付き OpenAPI { #conditional-openapi }
 
 必要であれば、設定と環境変数を利用して、環境に応じて条件付きでOpenAPIを構成することが可能です。また、完全にOpenAPIを無効にすることもできます。
 
-## セキュリティとAPI、およびドキュメントについて
+## セキュリティとAPI、およびドキュメントについて { #about-security-apis-and-docs }
 
 本番環境においてドキュメントのUIを非表示にすることによって、APIを保護しようと *すべきではありません*。
 
 * リクエストボディとレスポンスのための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"` のまま宣言しています。
 
index 8dee1ee0351faf169d66a10aa87d88c7d9417e22..67e01ed5351454fe693cfd92ebd059b4ef8ae572 100644 (file)
@@ -1,14 +1,14 @@
-# FastAPI
+# FastAPI { #fastapi }
 
 <style>
 .md-content .md-typeset h1 { display: none; }
 </style>
 
 <p align="center">
-  <a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
+  <a href="https://fastapi.tiangolo.com/ja"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
 </p>
 <p align="center">
-    <em>FastAPI framework, high performance, easy to learn, fast to code, ready for production</em>
+    <em>FastAPI フレームワーク、高パフォーマンス、学びやすい、素早くコーディングできる、本番運用に対応</em>
 </p>
 <p align="center">
 <a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
 
 ---
 
-**ドキュメント**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
+**ドキュメント**: <a href="https://fastapi.tiangolo.com/ja" target="_blank">https://fastapi.tiangolo.com</a>
 
 **ソースコード**: <a href="https://github.com/fastapi/fastapi" target="_blank">https://github.com/fastapi/fastapi</a>
 
 ---
 
-FastAPI は、Pythonの標準である型ヒントに基づいてPython 以降でAPI を構築するための、モダンで、高速(高パフォーマンス)な、Web フレームワークです。
+FastAPI は、Python の標準である型ヒントに基づいて Python で API を構築するための、モダンで、高速(高パフォーマンス)な Web フレームワークです。
 
 主な特徴:
 
-- **高速**: **NodeJS** や **Go** 並みのとても高いパフォーマンス (Starlette と Pydantic のおかげです)。 [最も高速な Python フレームワークの一つです](#_10).
+* **高速**: **NodeJS** や **Go** 並みのとても高いパフォーマンス(Starlette と Pydantic のおかげです)。 [利用可能な最も高速な Python フレームワークの一つです](#performance)。
+* **高速なコーディング**: 開発速度を約 200%〜300% 向上させます。*
+* **少ないバグ**: 開発者起因のヒューマンエラーを約 40% 削減します。*
+* **直感的**: 素晴らしいエディタサポート。あらゆる場所で <abbr title="also known as auto-complete, autocompletion, IntelliSense">補完</abbr> が使えます。デバッグ時間を削減します。
+* **簡単**: 簡単に利用・習得できるようにデザインされています。ドキュメントを読む時間を削減します。
+* **短い**: コードの重複を最小限にします。各パラメータ宣言から複数の機能を得られます。バグも減ります。
+* **堅牢性**: 自動対話型ドキュメントにより、本番環境向けのコードが得られます。
+* **Standards-based**: API のオープンスタンダードに基づいており(そして完全に互換性があります)、<a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a>(以前は Swagger として知られていました)や <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a> をサポートします。
 
-- **高速なコーディング**: 開発速度を約 200%~300%向上させます。 \*
-- **少ないバグ**: 開発者起因のヒューマンエラーを約 40%削減します。 \*
-- **直感的**: 素晴らしいエディタのサポートや <abbr title="also known as auto-complete, autocompletion, IntelliSense">オートコンプリート。</abbr> デバッグ時間を削減します。
-- **簡単**: 簡単に利用、習得できるようにデザインされています。ドキュメントを読む時間を削減します。
-- **短い**: コードの重複を最小限にしています。各パラメータからの複数の機能。少ないバグ。
-- **堅牢性**: 自動対話ドキュメントを使用して、本番環境で使用できるコードを取得します。
-- **Standards-based**: API のオープンスタンダードに基づいており、完全に互換性があります: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (以前は Swagger として知られていました) や <a href="https://json-schema.org/" class="external-link" target="_blank">JSON スキーマ</a>.
+<small>* 本番アプリケーションを構築している社内開発チームのテストに基づく見積もりです。</small>
 
-<small>\* 本番アプリケーションを構築している開発チームのテストによる見積もり。</small>
-
-## Sponsors
+## Sponsors { #sponsors }
 
 <!-- sponsors -->
 
-{% if sponsors %}
+### Keystone Sponsor { #keystone-sponsor }
+
+{% for sponsor in sponsors.keystone -%}
+<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
+{% endfor -%}
+
+### Gold and Silver Sponsors { #gold-and-silver-sponsors }
+
 {% for sponsor in sponsors.gold -%}
 <a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
 {% endfor -%}
 {%- for sponsor in sponsors.silver -%}
 <a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
 {% endfor %}
-{% endif %}
 
 <!-- /sponsors -->
 
-<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Other sponsors</a>
+<a href="https://fastapi.tiangolo.com/ja/fastapi-people/#sponsors" class="external-link" target="_blank">その他のスポンサー</a>
 
-## 評価
+## 評価 { #opinions }
 
-"_[...] 最近 **FastAPI** を使っています。 [...] 実際に私のチームの全ての **Microsoft の機械学習サービス** で使用する予定です。 そのうちのいくつかのコアな**Windows**製品と**Office**製品に統合されつつあります。_"
+"_[...] 最近 **FastAPI** を使っています。 [...] 実際に私のチームの全ての **Microsoft の機械学習サービス** で使用する予定です。 そのうちのいくつかのコアな **Windows** 製品と **Office** 製品に統合されつつあります。_"
 
 <div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
 
 ---
 
-"_FastAPIライブラリを採用し、クエリで**予測値**を取得できる**REST**サーバを構築しました。 [for Ludwig]_"
+"_FastAPIライブラリを採用し、クエリで **予測値** を取得できる **REST** サーバを構築しました。 [for Ludwig]_"
 
 <div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
 
 ---
 
-"_**Netflix** は、**危機管理**オーケストレーションフレームワーク、**Dispatch**のオープンソースリリースを発表できることをうれしく思います。 [built with **FastAPI**]_"
+"_**Netflix** は、**危機管理**オーケストレーションフレームワーク、**Dispatch** のオープンソースリリースを発表できることをうれしく思います。 [built with **FastAPI**]_"
 
 <div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
 
 ---
 
-"_私は**FastAPI**にワクワクしています。 めちゃくちゃ楽しいです!_"
+"_私は **FastAPI** にワクワクしています。 めちゃくちゃ楽しいです!_"
 
 <div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
 
 ---
 
-"_正直、超堅実で洗練されているように見えます。いろんな意味で、それは私がハグしたかったものです。_"
+"_正直、あなたが作ったものは超堅実で洗練されているように見えます。いろんな意味で、それは私が **Hug** にそうなってほしかったものです。誰かがそれを作るのを見るのは本当に刺激的です。_"
 
 <div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
 
 ---
 
-"_REST API を構築するための**モダンなフレームワーク**を学びたい方は、**FastAPI** [...] をチェックしてみてください。 [...] 高速で, 使用、習得が簡単です。[...]_"
+"_REST API を構築するための **モダンなフレームワーク** を学びたい方は、**FastAPI** [...] をチェックしてみてください。 [...] 高速で、使用・習得が簡単です [...]_"
 
-"_私たちの**API**は**FastAPI**に切り替えました。[...] きっと気に入ると思います。 [...]_"
+"_私たちの **API** は **FastAPI** に切り替えました [...] きっと気に入ると思います [...]_"
 
 <div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://x.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
 
 ---
 
-## **Typer**, the FastAPI of CLIs
+"_本番運用の Python API を構築したい方には、**FastAPI** を強くおすすめします。**美しく設計**されており、**使いやすく**、**高いスケーラビリティ**があります。私たちの API ファースト開発戦略の **主要コンポーネント** となり、Virtual TAC Engineer などの多くの自動化やサービスを推進しています。_"
 
-<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
+<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/" target="_blank"><small>(ref)</small></a></div>
 
-もし Web API の代わりにターミナルで使用する<abbr title="Command Line Interface">CLI</abbr>アプリを構築する場合は、<a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>を確認してください。
+---
 
-**Typer**は FastAPI の弟分です。そして、**CLI 版 の FastAPI**を意味しています。
+## FastAPI ミニドキュメンタリー { #fastapi-mini-documentary }
 
-## 必要条件
+2025 年末に公開された <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">FastAPI ミニドキュメンタリー</a>があります。オンラインで視聴できます:
 
-FastAPI は巨人の肩の上に立っています。
+<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
 
-- Web の部分は<a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a>
-- データの部分は<a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>
+## **Typer**、CLI 版 FastAPI { #typer-the-fastapi-of-clis }
 
-## インストール
+<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
 
-<div class="termy">
+Web API の代わりにターミナルで使用する <abbr title="Command Line Interface">CLI</abbr> アプリを構築する場合は、<a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a> を確認してください。
 
-```console
-$ pip install fastapi
+**Typer** は FastAPI の弟分です。そして、**CLI 版 FastAPI** を意図しています。 ⌨️ 🚀
 
----> 100%
-```
+## 必要条件 { #requirements }
 
-</div>
+FastAPI は巨人の肩の上に立っています。
+
+* Web の部分は <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a>
+* データの部分は <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>
 
-本番環境では、<a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a> または、 <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>のような、 ASGI サーバーが必要になります。
+## インストール { #installation }
+
+<a href="https://fastapi.tiangolo.com/ja/virtual-environments/" class="external-link" target="_blank">virtual environment</a> を作成して有効化し、それから FastAPI をインストールします。
 
 <div class="termy">
 
 ```console
-$ pip install "uvicorn[standard]"
+$ pip install "fastapi[standard]"
 
 ---> 100%
 ```
 
 </div>
 
-## アプリケーション例
+**注**: すべてのターミナルで動作するように、`"fastapi[standard]"` は必ずクォートで囲んでください。
+
+## アプリケーション例 { #example }
 
-### アプリケーションの作成
+### 作成 { #create-it }
 
-- `main.py` を作成し、以下のコードを入力します:
+`main.py` ファイルを作成し、以下のコードを入力します。
 
 ```Python
 from fastapi import FastAPI
@@ -163,16 +172,16 @@ def read_root():
 
 
 @app.get("/items/{item_id}")
-def read_item(item_id: int, q: str = None):
+def read_item(item_id: int, q: str | None = None):
     return {"item_id": item_id, "q": q}
 ```
 
 <details markdown="1">
-<summary>または<code>async def</code>を使います...</summary>
+<summary>または <code>async def</code> を使います...</summary>
 
-`async` / `await`を使用するときは、 `async def`を使います:
+コードで `async` / `await` を使用する場合は、`async def` を使います。
 
-```Python hl_lines="7 12"
+```Python hl_lines="7  12"
 from fastapi import FastAPI
 
 app = FastAPI()
@@ -184,28 +193,41 @@ async def read_root():
 
 
 @app.get("/items/{item_id}")
-async def read_item(item_id: int, q: str = None):
+async def read_item(item_id: int, q: str | None = None):
     return {"item_id": item_id, "q": q}
 ```
 
 **注**:
 
-わからない場合は、<a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">ドキュメントの`async` と `await`にある</a>"In a hurry?"セクションをチェックしてください。
+わからない場合は、<a href="https://fastapi.tiangolo.com/ja/async/#in-a-hurry" target="_blank">ドキュメントの `async` と `await` の _"In a hurry?"_ セクション</a>を確認してください。
 
 </details>
 
-### 実行
+### 実行 { #run-it }
 
-以下のコマンドでサーバーを起動します:
+以下のコマンドでサーバーを起動します
 
 <div class="termy">
 
 ```console
-$ uvicorn main:app --reload
-
+$ fastapi dev main.py
+
+ ╭────────── FastAPI CLI - Development mode ───────────╮
+ │                                                     │
+ │  Serving at: http://127.0.0.1:8000                  │
+ │                                                     │
+ │  API docs: http://127.0.0.1:8000/docs               │
+ │                                                     │
+ │  Running in development mode, for production use:   │
+ │                                                     │
+ │  fastapi run                                        │
+ │                                                     │
+ ╰─────────────────────────────────────────────────────╯
+
+INFO:     Will watch for changes in these directories: ['/home/user/code/awesomeapp']
 INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-INFO:     Started reloader process [28720]
-INFO:     Started server process [28722]
+INFO:     Started reloader process [2248755] using WatchFiles
+INFO:     Started server process [2248757]
 INFO:     Waiting for application startup.
 INFO:     Application startup complete.
 ```
@@ -213,56 +235,56 @@ INFO:     Application startup complete.
 </div>
 
 <details markdown="1">
-<summary><code>uvicorn main:app --reload</code>コマンドについて</summary>
+<summary><code>fastapi dev main.py</code> コマンドについて</summary>
+
+`fastapi dev` コマンドは `main.py` ファイルを読み取り、その中の **FastAPI** アプリを検出し、<a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a> を使用してサーバーを起動します。
 
-`uvicorn main:app`コマンドは以下の項目を参照します:
+デフォルトでは、`fastapi dev` はローカル開発向けに自動リロードを有効にして起動します。
 
-- `main`: `main.py`ファイル (Python "モジュール")
-- `app`: `main.py` の`app = FastAPI()`の行で生成されたオブジェクト
-- `--reload`: コードを変更したらサーバーを再起動します。このオプションは開発環境でのみ使用します
+詳しくは <a href="https://fastapi.tiangolo.com/ja/fastapi-cli/" target="_blank">FastAPI CLI docs</a> を参照してください。
 
 </details>
 
-### 動作確認
+### 動作確認 { #check-it }
 
\83\96ã\83©ã\82¦ã\82¶ã\81\8bã\82\89<a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>を開きます。
\83\96ã\83©ã\82¦ã\82¶ã\81§ <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a> を開きます。
 
-以下の JSON のレスポンスが確認できます:
+以下の JSON のレスポンスが確認できます
 
 ```JSON
 {"item_id": 5, "q": "somequery"}
 ```
 
\82\82ã\81\86ã\81\99ã\81§ã\81«ä»¥ä¸\8bã\81® API ã\81\8cä½\9cæ\88\90ã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99:
\81\99ã\81§ã\81«ä»¥ä¸\8bã\81® API ã\81\8cä½\9cæ\88\90ã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99ã\80\82
 
-- `/` と `/items/{item_id}`のパスで HTTP リクエストを受けます。
-- どちらのパスも `GET` <em>操作</em> を取ります。(HTTP メソッドとしても知られています。)
-- `/items/{item_id}` パスのパスパラメータ `item_id` は `int` でなければなりません
-- パス `/items/{item_id}` はオプションの `str` クエリパラメータ `q` を持ちます。
+* _パス_ `/` と `/items/{item_id}` で HTTP リクエストを受け取ります。
+* 両方の _パス_ は `GET` <em>操作</em>(HTTP _メソッド_ としても知られています)を取ります。
+* _パス_ `/items/{item_id}` は `int` であるべき _パスパラメータ_ `item_id` を持ちます
+* _パス_ `/items/{item_id}` はオプションの `str` _クエリパラメータ_ `q` を持ちます。
 
-### 自動対話型の API ドキュメント
+### 自動対話型 API ドキュメント { #interactive-api-docs }
 
-<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>にアクセスしてみてください
+次に、<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> にアクセスします
 
-自動対話型の API ドキュメントが表示されます。 (<a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>が提供しています。):
+自動対話型 API ドキュメントが表示されます(<a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> が提供しています)。
 
 ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
 
-### 代替の API ドキュメント
+### 代替 API ドキュメント { #alternative-api-docs }
 
-<a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>にアクセスしてみてください
+次に、<a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> にアクセスします
 
-代替の自動ドキュメントが表示されます。(<a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>が提供しています。):
+代替の自動ドキュメントが表示されます(<a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> が提供しています)。
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
 
-## アップグレード例
+## アップグレード例 { #example-upgrade }
 
-`PUT`リクエストからボディを受け取るために`main.py`を修正しましょう。
+次に、`PUT` リクエストからボディを受け取るために `main.py` ファイルを修正しましょう。
 
-Pydantic によって、Python の標準的な型を使ってボディを宣言します。
+Pydantic によって、標準的な Python の型を使ってボディを宣言します。
 
-```Python hl_lines="2  7 8 9 10  23 24 25"
+```Python hl_lines="2  7-10 23-25"
 from fastapi import FastAPI
 from pydantic import BaseModel
 
@@ -272,7 +294,7 @@ app = FastAPI()
 class Item(BaseModel):
     name: str
     price: float
-    is_offer: bool = None
+    is_offer: bool | None = None
 
 
 @app.get("/")
@@ -281,7 +303,7 @@ def read_root():
 
 
 @app.get("/items/{item_id}")
-def read_item(item_id: int, q: str = None):
+def read_item(item_id: int, q: str | None = None):
     return {"item_id": item_id, "q": q}
 
 
@@ -290,173 +312,248 @@ def update_item(item_id: int, item: Item):
     return {"item_name": item.name, "item_id": item_id}
 ```
 
-サーバーは自動でリロードされます。(上述の`uvicorn`コマンドで`--reload`オプションを追加しているからです。)
+`fastapi dev` サーバーは自動でリロードされるはずです。
 
-### 自動対話型の API ドキュメントのアップグレード
+### 自動対話型 API ドキュメントのアップグレード { #interactive-api-docs-upgrade }
 
-<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>にアクセスしましょう
+次に、<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> にアクセスします
 
-- 自動対話型の API ドキュメントが新しいボディも含めて自動でアップデートされます:
+* 自動対話型 API ドキュメントは新しいボディも含めて自動でアップデートされます。
 
 ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
 
-- "Try it out"ボタンをクリックしてください。パラメータを入力して API と直接やりとりすることができます:
+* 「Try it out」ボタンをクリックします。パラメータを入力して API と直接やりとりできます。
 
 ![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png)
 
-- それから、"Execute" ボタンをクリックしてください。 ユーザーインターフェースは API と通信し、パラメータを送信し、結果を取得して画面に表示します:
+* 次に、「Execute」ボタンをクリックします。ユーザーインターフェースは API と通信し、パラメータを送信し、結果を取得して画面に表示します。
 
 ![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png)
 
-### 代替の API ドキュメントのアップグレード
+### 代替 API ドキュメントのアップグレード { #alternative-api-docs-upgrade }
 
-<a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>にアクセスしましょう
+次に、<a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> にアクセスします
 
-- 代替の API ドキュメントにも新しいクエリパラメータやボディが反映されます。
+* 代替のドキュメントにも新しいクエリパラメータやボディが反映されます。
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
 
-### まとめ
+### まとめ { #recap }
 
-要約すると、関数のパラメータとして、パラメータやボディ などの型を**一度だけ**宣言します。
+要約すると、関数のパラメータとして、パラメータやボディなどの型を **一度だけ** 宣言します。
 
-æ¨\99æº\96ç\9a\84ã\81ªæ\9c\80æ\96°ã\81® Python ã\81®å\9e\8bã\82\92使ã\81£ã\81¦ã\81\84ã\81¾ã\81\99ã\80\82
+標準的な最新の Python の型を使います。
 
 新しい構文や特定のライブラリのメソッドやクラスなどを覚える必要はありません。
 
-単なる標準的な**3.8 以降の Python**です。
+単なる標準的な **Python** です。
 
-例えば、`int`の場合:
+例えば、`int` の場合:
 
 ```Python
 item_id: int
 ```
 
-または、より複雑な`Item`モデルの場合:
+または、より複雑な `Item` モデルの場合:
 
 ```Python
 item: Item
 ```
 
-...そして、この一度の宣言で、以下のようになります:
-
-- 以下を含むエディタサポート:
-  - 補完
-  - タイプチェック
-- データの検証:
-  - データが無効な場合に自動でエラーをクリアします。
-  - 深い入れ子になった JSON オブジェクトでも検証が可能です。
-- 入力データの<abbr title="also known as: serialization, parsing, marshalling">変換</abbr>: ネットワークから Python のデータや型に変換してから読み取ります:
-  - JSON.
-  - パスパラメータ
-  - クエリパラメータ
-  - クッキー
-  - ヘッダー
-  - フォーム
-  - ファイル
-- 出力データの<abbr title="also known as: serialization, parsing, marshalling">変換</abbr>: Python のデータや型からネットワークデータへ変換します (JSON として):
-  - Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
-  - `datetime` オブジェクト
-  - `UUID` オブジェクト
-  - データベースモデル
-  - ...などなど
-- 2 つの代替ユーザーインターフェースを含む自動インタラクティブ API ドキュメント:
-  - Swagger UI.
-  - ReDoc.
+...そして、この一度の宣言で、以下のようになります
+
+* 以下を含むエディタサポート:
+    * 補完。
+    * 型チェック。
+* データの検証:
+    * データが無効な場合に自動で明確なエラーを返します。
+    * 深い入れ子になった JSON オブジェクトでも検証が可能です。
+* 入力データの <abbr title="also known as: serialization, parsing, marshalling">変換</abbr>: ネットワークから Python のデータや型へ。以下から読み取ります:
+    * JSON。
+    * パスパラメータ。
+    * クエリパラメータ。
+    * Cookie。
+    * ヘッダー。
+    * フォーム。
+    * ファイル。
+* 出力データの <abbr title="also known as: serialization, parsing, marshalling">変換</abbr>: Python のデータや型からネットワークデータへ(JSON として)変換します:
+    * Python の型(`str`、`int`、`float`、`bool`、`list` など)の変換。
+    * `datetime` オブジェクト。
+    * `UUID` オブジェクト。
+    * データベースモデル。
+    * ...などなど。
+* 2 つの代替ユーザーインターフェースを含む自動対話型 API ドキュメント:
+    * Swagger UI。
+    * ReDoc。
 
 ---
 
-コード例に戻りましょう、**FastAPI** は次のようになります:
-
-- `GET`および`PUT`リクエストのパスに`item_id` があることを検証します。
-- `item_id`が`GET`および`PUT`リクエストに対して`int` 型であることを検証します。
-  - そうでない場合は、クライアントは有用で明確なエラーが表示されます。
-- `GET` リクエストに対してオプションのクエリパラメータ `q` (`http://127.0.0.1:8000/items/foo?q=somequery` のように) が存在するかどうかを調べます。
-  - パラメータ `q` は `= None` で宣言されているので、オプションです。
-  - `None`がなければ必須になります(`PUT`の場合のボディと同様です)。
-- `PUT` リクエストを `/items/{item_id}` に送信する場合は、ボディを JSON として読み込みます:
-  - 必須の属性 `name` を確認してください。 それは `str` であるべきです。
-  - 必須の属性 `price` を確認してください。それは `float` でなければならないです。
-  - オプションの属性 `is_offer` を確認してください。値がある場合は、`bool` であるべきです。
-  - これらはすべて、深くネストされた JSON オブジェクトに対しても動作します。
-- JSON から JSON に自動的に変換します。
-- OpenAPIですべてを文書化し、以下を使用することができます:
-  - 対話的なドキュメントシステム。
-  - 多くの言語に対応した自動クライアントコード生成システム。
-- 2 つの対話的なドキュメントのWebインターフェイスを直接提供します。
+前のコード例に戻ると、**FastAPI** は次のように動作します。
+
+* `GET` および `PUT` リクエストのパスに `item_id` があることを検証します。
+* `GET` および `PUT` リクエストに対して `item_id` が `int` 型であることを検証します。
+    * そうでない場合、クライアントは有用で明確なエラーを受け取ります。
+* `GET` リクエストに対して、`q` という名前のオプションのクエリパラメータ(`http://127.0.0.1:8000/items/foo?q=somequery` のような)が存在するかどうかを調べます。
+    * `q` パラメータは `= None` で宣言されているため、オプションです。
+    * `None` がなければ必須になります(`PUT` の場合のボディと同様です)。
+* `PUT` リクエストを `/items/{item_id}` に送信する場合、ボディを JSON として読み込みます:
+    * 必須の属性 `name` があり、`str` であるべきことを確認します。
+    * 必須の属性 `price` があり、`float` でなければならないことを確認します。
+    * オプションの属性 `is_offer` があり、存在する場合は `bool` であるべきことを確認します。
+    * これらはすべて、深くネストされた JSON オブジェクトに対しても動作します。
+* JSON への/からの変換を自動的に行います。
+* OpenAPI ですべてを文書化し、以下で利用できます:
+    * 対話型ドキュメントシステム。
+    * 多くの言語に対応した自動クライアントコード生成システム。
+* 2 つの対話型ドキュメント Web インターフェースを直接提供します。
 
 ---
 
-まだ表面的な部分に触れただけですが、もう全ての仕組みは分かっているはずです。
+まだ表面的な部分に触れただけですが、仕組みはすでにイメージできているはずです。
 
-以下の行を変更してみてください:
+以下の行を変更してみてください
 
 ```Python
     return {"item_name": item.name, "item_id": item_id}
 ```
 
-...以ä¸\8bã\82\92:
+...以ä¸\8bã\81®:
 
 ```Python
         ... "item_name": item.name ...
 ```
 
-...以下のように:
+...:
 
 ```Python
         ... "item_price": item.price ...
 ```
 
-...ã\81\9dã\81\97ã\81¦ã\80\81ã\82¨ã\83\87ã\82£ã\82¿ã\81\8cå±\9eæ\80§ã\82\92è\87ªå\8b\95è£\9cå®\8cã\81\97ã\80\81ã\81\9dã\81®ã\82¿ã\82¤ã\83\97ã\82\92ç\9f¥ã\82\8bæ\96¹æ³\95ã\82\92確èª\8dã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82:
+...ã\81«å¤\89æ\9b´ã\81\97ã\80\81ã\82¨ã\83\87ã\82£ã\82¿ã\81\8cå±\9eæ\80§ã\82\92è\87ªå\8b\95è£\9cå®\8cã\81\97ã\80\81ã\81\9dã\81®å\9e\8bã\82\92ç\9f¥ã\82\8bã\81\93ã\81¨ã\82\92確èª\8dã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82
 
 ![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)
 
-より多くの機能を含む、より完全な例については、<a href="https://fastapi.tiangolo.com/tutorial/">チュートリアル - ユーザーガイド</a>をご覧ください。
+より多くの機能を含む、より完全な例については、<a href="https://fastapi.tiangolo.com/ja/tutorial/">Tutorial - User Guide</a> を参照してください。
+
+**ネタバレ注意**: tutorial - user guide には以下が含まれます。
+
+* **ヘッダー**、**Cookie**、**フォームフィールド**、**ファイル**など、他のさまざまな場所からの **パラメータ** 宣言。
+* `maximum_length` や `regex` のような **検証制約** を設定する方法。
+* 非常に強力で使いやすい **<abbr title="also known as components, resources, providers, services, injectables">依存性注入</abbr>** システム。
+* **JWT トークン**を用いた **OAuth2** や **HTTP Basic** 認証のサポートを含む、セキュリティと認証。
+* **深くネストされた JSON モデル**を宣言するための、より高度な(しかし同様に簡単な)手法(Pydantic のおかげです)。
+* <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> および他のライブラリによる **GraphQL** 統合。
+* 以下のようなたくさんのおまけ機能(Starlette のおかげです):
+    * **WebSockets**
+    * HTTPX と `pytest` に基づく極めて簡単なテスト
+    * **CORS**
+    * **Cookie Sessions**
+    * ...などなど。
+
+### アプリをデプロイ(任意) { #deploy-your-app-optional }
+
+必要に応じて FastAPI アプリを <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> にデプロイできます。まだの場合はウェイティングリストに参加してください。 🚀
 
-**ネタバレ注意**: チュートリアル - ユーザーガイドは以下の情報が含まれています:
+すでに **FastAPI Cloud** アカウント(ウェイティングリストから招待されました 😉)がある場合は、1 コマンドでアプリケーションをデプロイできます。
 
-- **ヘッダー**、**クッキー**、**フォームフィールド**、**ファイル**などの他の場所からの **パラメータ** 宣言。
-- `maximum_length`や`regex`のような**検証や制約**を設定する方法。
-- 非常に強力で使いやすい <abbr title="also known as components, resources, providers, services, injectables">**依存性注入**</abbr>システム。
-- **JWT トークン**を用いた **OAuth2** や **HTTP Basic 認証** のサポートを含む、セキュリティと認証。
-- **深くネストされた JSON モデル**を宣言するためのより高度な(しかし同様に簡単な)技術(Pydantic のおかげです)。
-- 以下のようなたくさんのおまけ機能(Starlette のおかげです):
-  - **WebSockets**
-  - **GraphQL**
-  - `httpx` や `pytest`をもとにした極限に簡単なテスト
-  - **CORS**
-  - **クッキーセッション**
-  - ...などなど。
+デプロイ前に、ログインしていることを確認してください。
 
-## パフォーマンス
+<div class="termy">
+
+```console
+$ fastapi login
+
+You are logged in to FastAPI Cloud 🚀
+```
 
-独立した TechEmpower のベンチマークでは、Uvicorn で動作する**FastAPI**アプリケーションが、<a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">Python フレームワークの中で最も高速なものの 1 つ</a>であり、Starlette と Uvicorn(FastAPI で内部的に使用されています)にのみ下回っていると示されています。
+</div>
 
-詳細は<a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">ベンチマーク</a>セクションをご覧ください
+次に、アプリをデプロイします
 
-## オプションの依存関係
+<div class="termy">
+
+```console
+$ fastapi deploy
+
+Deploying to FastAPI Cloud...
+
+✅ Deployment successful!
+
+🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
+```
+
+</div>
+
+これで完了です!その URL でアプリにアクセスできます。 ✨
+
+#### FastAPI Cloud について { #about-fastapi-cloud }
+
+**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** は **FastAPI** の作者と同じチームによって作られています。
+
+最小限の労力で API を **構築**、**デプロイ**、**アクセス** するためのプロセスを効率化します。
+
+FastAPI でアプリを構築するのと同じ **開発者体験** を、クラウドへの **デプロイ** にももたらします。 🎉
+
+FastAPI Cloud は *FastAPI and friends* オープンソースプロジェクトの主要スポンサーであり、資金提供元です。 ✨
+
+#### 他のクラウドプロバイダにデプロイ { #deploy-to-other-cloud-providers }
+
+FastAPI はオープンソースであり、標準に基づいています。選択した任意のクラウドプロバイダに FastAPI アプリをデプロイできます。
+
+各クラウドプロバイダのガイドに従って、FastAPI アプリをデプロイしてください。 🤓
+
+## パフォーマンス { #performance }
+
+独立した TechEmpower のベンチマークでは、Uvicorn で動作する **FastAPI** アプリケーションが、<a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">利用可能な最も高速な Python フレームワークの一つ</a>であり、Starlette と Uvicorn(FastAPI で内部的に使用されています)にのみ下回っていると示されています。(*)
+
+詳細は <a href="https://fastapi.tiangolo.com/ja/benchmarks/" class="internal-link" target="_blank">Benchmarks</a> セクションをご覧ください。
+
+## 依存関係 { #dependencies }
+
+FastAPI は Pydantic と Starlette に依存しています。
+
+### `standard` 依存関係 { #standard-dependencies }
+
+FastAPI を `pip install "fastapi[standard]"` でインストールすると、`standard` グループのオプション依存関係が含まれます。
 
 Pydantic によって使用されるもの:
 
-- <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email-validator</code></a> - E メールの検証
+* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email-validator</code></a> - メール検証のため。
 
 Starlette によって使用されるもの:
 
-- <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - `TestClient`を使用するために必要です。
-- <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - デフォルトのテンプレート設定を使用する場合は必要です。
-- <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>`request.form()`からの変換をサポートしたい場合は必要です。
-- <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - `SessionMiddleware` サポートのためには必要です。
-- <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Starlette の `SchemaGenerator` サポートのために必要です。 (FastAPI では必要ないでしょう。)
-- <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - `GraphQLApp` サポートのためには必要です。
+* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - `TestClient` を使用したい場合に必要です。
+* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - デフォルトのテンプレート設定を使用したい場合に必要です。
+* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - `request.form()` とともに、フォームの <abbr title="converting the string that comes from an HTTP request into Python data">「parsing」</abbr> をサポートしたい場合に必要です。
+
+FastAPI によって使用されるもの:
+
+* <a href="https://www.uvicorn.dev" target="_blank"><code>uvicorn</code></a> - アプリケーションをロードして提供するサーバーのため。これには `uvicorn[standard]` も含まれ、高性能なサービングに必要な依存関係(例: `uvloop`)が含まれます。
+* `fastapi-cli[standard]` - `fastapi` コマンドを提供します。
+    * これには `fastapi-cloud-cli` が含まれ、FastAPI アプリケーションを <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> にデプロイできます。
+
+### `standard` 依存関係なし { #without-standard-dependencies }
+
+`standard` のオプション依存関係を含めたくない場合は、`pip install "fastapi[standard]"` の代わりに `pip install fastapi` でインストールできます。
+
+### `fastapi-cloud-cli` なし { #without-fastapi-cloud-cli }
+
+標準の依存関係を含めつつ `fastapi-cloud-cli` を除外して FastAPI をインストールしたい場合は、`pip install "fastapi[standard-no-fastapi-cloud-cli]"` でインストールできます。
+
+### 追加のオプション依存関係 { #additional-optional-dependencies }
+
+追加でインストールしたい依存関係があります。
+
+追加のオプション Pydantic 依存関係:
 
-FastAPI / Starlette に使用されるもの:
+* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - 設定管理のため。
+* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - Pydantic で使用する追加の型のため。
 
-- <a href="https://www.uvicorn.dev" target="_blank"><code>uvicorn</code></a> - アプリケーションをロードしてサーブするサーバーのため。
-- <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - `ORJSONResponse`を使用したい場合は必要です。
-- <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - `UJSONResponse`を使用する場合は必須です。
+追加のオプション FastAPI 依存関係:
 
-これらは全て `pip install fastapi[all]`でインストールできます。
+* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - `ORJSONResponse` を使用したい場合に必要です。
+* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - `UJSONResponse` を使用したい場合に必要です。
 
-## ライセンス
+## ライセンス { #license }
 
\81\93ã\81®ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88ã\81¯ MIT ã\83©ã\82¤ã\82»ã\83³ã\82¹ã\81§す。
\81\93ã\81®ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88ã\81¯ MIT ã\83©ã\82¤ã\82»ã\83³ã\82¹ã\81®æ\9d¡é \85ã\81®ä¸\8bã\81§ã\83©ã\82¤ã\82»ã\83³ã\82¹ã\81\95ã\82\8cã\81¦ã\81\84ã\81¾す。
index 2f24c670a7984c92d6b403ea2b6ba62e4f28133c..bcdb1e37ee167a31570aad57e0cdbdb8a4a2a8c3 100644 (file)
@@ -1,5 +1,5 @@
-# 学習
+# 学習 { #learn }
 
 ここでは、**FastAPI** を学習するための入門セクションとチュートリアルを紹介します。
 
-これは、FastAPIを学習するにあたっての**書籍**や**コース**であり、**公式**かつ推奨される方法とみなすことができます 😎
+これは、**書籍**や**コース**、FastAPIを学習するための**公式**かつ推奨される方法とみなすことができます。😎
index daef52efaed1f3051abc5b02f38288752d3579a2..c930fb557c76a3f6ab97119e454064077dc6225c 100644 (file)
@@ -1,84 +1,28 @@
-# プロジェクト生成 - テンプレート
-
-プロジェクトジェネレーターは、初期設定、セキュリティ、データベース、初期APIエンドポイントなどの多くが含まれているため、プロジェクトの開始に利用できます。
-
-プロジェクトジェネレーターは常に非常に意見が分かれる設定がされており、ニーズに合わせて更新および調整する必要があります。しかしきっと、プロジェクトの良い出発点となるでしょう。
-
-## フルスタック FastAPI PostgreSQL
-
-GitHub: <a href="https://github.com/tiangolo/full-stack-fastapi-postgresql" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-fastapi-postgresql</a>
-
-### フルスタック FastAPI PostgreSQL - 機能
-
-* 完全な**Docker**インテグレーション (Dockerベース)。
-* Docker Swarm モードデプロイ。
-* ローカル開発環境向けの**Docker Compose**インテグレーションと最適化。
-* UvicornとGunicornを使用した**リリース可能な** Python web サーバ。
-* Python <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">**FastAPI**</a> バックエンド:
-    * **高速**: **NodeJS** や **Go** 並みのとても高いパフォーマンス (Starlette と Pydantic のおかげ)。
-    * **直感的**: 素晴らしいエディタのサポートや <abbr title="自動補完、インテリセンスとも呼ばれる">補完。</abbr> デバッグ時間の短縮。
-    * **簡単**: 簡単に利用、習得できるようなデザイン。ドキュメントを読む時間を削減。
-    * **短い**: コードの重複を最小限に。パラメータ宣言による複数の機能。
-    * **堅牢性**: 自動対話ドキュメントを使用した、本番環境で使用できるコード。
-    * **標準規格準拠**: API のオープンスタンダードに基く、完全な互換性: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a>や <a href="http://json-schema.org/" class="external-link" target="_blank">JSON スキーマ</a>。
-    * 自動バリデーション、シリアライゼーション、対話的なドキュメント、OAuth2 JWTトークンを用いた認証などを含む、<a href="https://fastapi.tiangolo.com/features/" class="external-link" target="_blank">**その他多くの機能**</a>。
-* **セキュアなパスワード** ハッシュ化 (デフォルトで)。
-* **JWTトークン** 認証。
-* **SQLAlchemy** モデル (Flask用の拡張と独立しているので、Celeryワーカーと直接的に併用できます)。
-* 基本的なユーザーモデル (任意の修正や削除が可能)。
-* **Alembic** マイグレーション。
-* **CORS** (Cross Origin Resource Sharing (オリジン間リソース共有))。
-* **Celery** ワーカー。バックエンドの残りの部分からモデルとコードを選択的にインポートし、使用可能。
-* Dockerと統合された**Pytest**ベースのRESTバックエンドテスト。データベースに依存せずに、全てのAPIをテスト可能。Docker上で動作するので、毎回ゼロから新たなデータストアを構築可能。(ElasticSearch、MongoDB、CouchDBなどを使用して、APIの動作をテスト可能)
-* Atom HydrogenやVisual Studio Code Jupyterなどの拡張機能を使用した、リモートまたはDocker開発用の**Jupyterカーネル**との簡単なPython統合。
-* **Vue** フロントエンド:
-    * Vue CLIにより生成。
-    * **JWT認証**の処理。
-    * ログインビュー。
-    * ログイン後の、メインダッシュボードビュー。
-    * メインダッシュボードでのユーザー作成と編集。
-    * セルフユーザー版
-    * **Vuex**。
-    * **Vue-router**。
-    * 美しいマテリアルデザインコンポーネントのための**Vuetify**。
-    * **TypeScript**。
-    * **Nginx**ベースのDockerサーバ (Vue-routerとうまく協調する構成)。
-    * Dockerマルチステージビルド。コンパイルされたコードの保存やコミットが不要。
-    * ビルド時にフロントエンドテスト実行 (無効化も可能)。
-    * 可能な限りモジュール化されているのでそのまま使用できますが、Vue CLIで再生成したり、必要に応じて作成したりして、必要なものを再利用可能。
-* PostgreSQLデータベースのための**PGAdmin**。(PHPMyAdminとMySQLを使用できるように簡単に変更可能)
-* Celeryジョブ監視のための**Flower**。
-* **Traefik**を使用してフロントエンドとバックエンド間をロードバランシング。同一ドメインに配置しパスで区切る、ただし、異なるコンテナで処理。
-* Traefik統合。Let's Encrypt **HTTPS**証明書の自動生成を含む。
-* GitLab **CI** (継続的インテグレーション)。フロントエンドおよびバックエンドテストを含む。
-
-## フルスタック FastAPI Couchbase
-
-GitHub: <a href="https://github.com/tiangolo/full-stack-fastapi-couchbase" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-fastapi-couchbase</a>
-
-⚠️ **警告** ⚠️
-
-ゼロから新規プロジェクトを始める場合は、ここで代替案を確認してください。
-
-例えば、<a href="https://github.com/tiangolo/full-stack-fastapi-postgresql" class="external-link" target="_blank">フルスタック FastAPI PostgreSQL</a>のプロジェクトジェネレーターは、積極的にメンテナンスされ、利用されているのでより良い代替案かもしれません。また、すべての新機能と改善点が含まれています。
-
-Couchbaseベースのジェネレーターは今も無償提供されています。恐らく正常に動作するでしょう。また、すでにそのジェネレーターで生成されたプロジェクトが存在する場合でも (ニーズに合わせてアップデートしているかもしれません)、同様に正常に動作するはずです。
-
-詳細はレポジトリのドキュメントを参照して下さい。
-
-## フルスタック FastAPI MongoDB
-
-...時間の都合等によっては、今後作成されるかもしれません。😅 🎉
-
-## spaCyとFastAPIを使用した機械学習モデル
-
-GitHub: <a href="https://github.com/microsoft/cookiecutter-spacy-fastapi" class="external-link" target="_blank">https://github.com/microsoft/cookiecutter-spacy-fastapi</a>
-
-### spaCyとFastAPIを使用した機械学習モデル - 機能
-
-* **spaCy** のNERモデルの統合。
-* **Azure Cognitive Search** のリクエストフォーマットを搭載。
-* **リリース可能な** UvicornとGunicornを使用したPythonウェブサーバ。
-* **Azure DevOps** のKubernetes (AKS) CI/CD デプロイを搭載。
-* **多言語** プロジェクトのために、セットアップ時に言語を容易に選択可能 (spaCyに組み込まれている言語の中から)。
-* **簡単に拡張可能**。spaCyだけでなく、他のモデルフレームワーク (Pytorch、Tensorflow) へ。
+# Full Stack FastAPI テンプレート { #full-stack-fastapi-template }
+
+テンプレートは通常、特定のセットアップが含まれていますが、柔軟でカスタマイズできるように設計されています。これにより、プロジェクトの要件に合わせて変更・適応でき、優れた出発点になります。🏁
+
+このテンプレートを使って開始できます。初期セットアップ、セキュリティ、データベース、いくつかのAPIエンドポイントがすでに用意されています。
+
+GitHubリポジトリ: <a href="https://github.com/tiangolo/full-stack-fastapi-template" class="external-link" target="_blank">Full Stack FastAPI Template</a>
+
+## Full Stack FastAPI テンプレート - 技術スタックと機能 { #full-stack-fastapi-template-technology-stack-and-features }
+
+- ⚡ PythonバックエンドAPI向けの [**FastAPI**](https://fastapi.tiangolo.com/ja)。
+  - 🧰 PythonのSQLデータベース操作(ORM)向けの [SQLModel](https://sqlmodel.tiangolo.com)。
+  - 🔍 FastAPIで使用される、データバリデーションと設定管理向けの [Pydantic](https://docs.pydantic.dev)。
+  - 💾 SQLデータベースとしての [PostgreSQL](https://www.postgresql.org)。
+- 🚀 フロントエンド向けの [React](https://react.dev)。
+  - 💃 TypeScript、hooks、Vite、その他のモダンなフロントエンドスタックの各要素を使用。
+  - 🎨 フロントエンドコンポーネント向けの [Tailwind CSS](https://tailwindcss.com) と [shadcn/ui](https://ui.shadcn.com)。
+  - 🤖 自動生成されたフロントエンドクライアント。
+  - 🧪 End-to-Endテスト向けの [Playwright](https://playwright.dev)。
+  - 🦇 ダークモードのサポート。
+- 🐋 開発および本番向けの [Docker Compose](https://www.docker.com)。
+- 🔒 デフォルトでの安全なパスワードハッシュ化。
+- 🔑 JWT(JSON Web Token)認証。
+- 📫 メールベースのパスワードリカバリ。
+- ✅ [Pytest](https://pytest.org) によるテスト。
+- 📞 リバースプロキシ / ロードバランサとしての [Traefik](https://traefik.io)。
+- 🚢 Docker Composeを使用したデプロイ手順(自動HTTPS証明書を処理するフロントエンドTraefikプロキシのセットアップ方法を含む)。
+- 🏭 GitHub Actionsに基づくCI(continuous integration)とCD(continuous deployment)。
index a847ce5d54be3c67b2cd2805ce53ddc493d7d23d..26a9e2193cecab865e1e2c812df03cce54e9a59f 100644 (file)
@@ -1,16 +1,16 @@
-# Pythonの型の紹介
+# Pythonの型の紹介 { #python-types-intro }
 
-**Python 3.6以降** では「型ヒント」オプションがサポートされています。
+Pythonではオプションの「型ヒント」(「型アノテーション」とも呼ばれます)がサポートされています。
 
-これらの **"型ヒント"** は変数の<abbr title="例: str, int, float, bool">型</abbr>を宣言することができる新しい構文です。(Python 3.6以降)
+これらの **「型ヒント」** またはアノテーションは、変数の<abbr title="for example: str, int, float, bool">型</abbr>を宣言できる特別な構文です。
 
-å¤\89æ\95°ã\81«å\9e\8bã\82\92宣è¨\80ã\81\99ã\82\8bã\81\93ã\81¨ã\81§ã\82¨ã\83\87ã\82£ã\82¿ã\83¼ã\82\84ã\83\84ã\83¼ã\83«ã\81\8cã\82\88ã\82\8aè\89¯ã\81\84ã\82µã\83\9dã\83¼ã\83\88ã\82\92æ\8f\90ä¾\9bã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cできます。
+å¤\89æ\95°ã\81«å\9e\8bã\82\92宣è¨\80ã\81\99ã\82\8bã\81\93ã\81¨ã\81§ã\80\81ã\82¨ã\83\87ã\82£ã\82¿ã\83¼ã\82\84ã\83\84ã\83¼ã\83«ã\81\8cã\82\88ã\82\8aè\89¯ã\81\84ã\82µã\83\9dã\83¼ã\83\88ã\82\92æ\8f\90ä¾\9bできます。
 
\81\93ã\81\93ã\81§ã\81¯Pythonã\81®å\9e\8bã\83\92ã\83³ã\83\88ã\81«ã\81¤ã\81\84ã\81¦ã\81® **ã\82¯ã\82¤ã\83\83ã\82¯ã\83\81ã\83¥ã\83¼ã\83\88ã\83ªã\82¢ã\83«/ã\83ªã\83\95ã\83¬ã\83\83ã\82·ã\83¥** ã\81§ã\80\81**FastAPI**ã\81§ã\81\9dã\82\8cã\82\89ã\82\92使用するために必要な最低限のことだけをカバーしています。...実際には本当に少ないです。
\81\93ã\82\8cã\81¯Pythonã\81®å\9e\8bã\83\92ã\83³ã\83\88ã\81«ã\81¤ã\81\84ã\81¦ã\81® **ã\82¯ã\82¤ã\83\83ã\82¯ã\83\81ã\83¥ã\83¼ã\83\88ã\83ªã\82¢ã\83«/ã\83ªã\83\95ã\83¬ã\83\83ã\82·ã\83¥** ã\81«ã\81\99ã\81\8eã\81¾ã\81\9bã\82\93ã\80\82**FastAPI** ã\81§使用するために必要な最低限のことだけをカバーしています。...実際には本当に少ないです。
 
 **FastAPI** はすべてこれらの型ヒントに基づいており、多くの強みと利点を与えてくれます。
 
\81\97ã\81\8bã\81\97ã\81\9fã\81¨ã\81\88ã\81¾ã\81£ã\81\9fã\81\8f **FastAPI** ã\82\92使ç\94¨ã\81\97ã\81ªã\81\84å ´å\90\88ã\81§ã\82\82ã\80\81ã\81\9dã\82\8cã\82\89ã\81«ã\81¤ã\81\84ã\81¦å°\91ã\81\97å­¦ã\81¶ã\81\93ã\81¨ã\81§å\88©ç\82¹ã\82\92å¾\97ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\82\8bã\81§ã\81\97ã\82\87ã\81\86
\81\97ã\81\8bã\81\97ã\80\81ã\81\9fã\81¨ã\81\88 **FastAPI** ã\82\92ã\81¾ã\81£ã\81\9fã\81\8f使ç\94¨ã\81\97ã\81ªã\81\84å ´å\90\88ã\81§ã\82\82ã\80\81ã\81\9dã\82\8cã\82\89ã\81«ã\81¤ã\81\84ã\81¦å°\91ã\81\97å­¦ã\81¶ã\81\93ã\81¨ã\81§å\88©ç\82¹ã\82\92å¾\97ã\82\89ã\82\8cã\81¾ã\81\99
 
 /// note | 備考
 
 
 ///
 
-## 動機
+## 動機 { #motivation }
 
 簡単な例から始めてみましょう:
 
-{* ../../docs_src/python_types/tutorial001.py *}
+{* ../../docs_src/python_types/tutorial001_py39.py *}
 
-
-このプログラムを実行すると以下が出力されます:
+このプログラムを呼び出すと、以下が出力されます:
 
 ```
 John Doe
@@ -35,12 +34,11 @@ John Doe
 
 * `first_name`と`last_name`を取得します。
 * `title()`を用いて、それぞれの最初の文字を大文字に変換します。
-* 真ん中にスペースを入れて<abbr title="次から次へと中身を入れて一つにまとめる">連結</abbr>します。
-
-{* ../../docs_src/python_types/tutorial001.py hl[2] *}
+* 真ん中にスペースを入れて<abbr title="Puts them together, as one. With the contents of one after the other.">連結</abbr>します。
 
+{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
 
-### 編集
+### 編集 { #edit-it }
 
 これはとても簡単なプログラムです。
 
@@ -50,7 +48,7 @@ John Doe
 
 しかし、そうすると「最初の文字を大文字に変換するあのメソッド」を呼び出す必要があります。
 
-それは`upper`でしたか?`uppercase`でしたか?それとも`first_uppercase`?または`capitalize`?
+それは`upper`でしたか?`uppercase`でしたか?`first_uppercase`?`capitalize`?
 
 そして、古くからプログラマーの友人であるエディタで自動補完を試してみます。
 
@@ -58,13 +56,13 @@ John Doe
 
 しかし、悲しいことに、これはなんの役にも立ちません:
 
-<img src="https://fastapi.tiangolo.com/img/python-types/image01.png">
+<img src="/img/python-types/image01.png">
 
-### 型の追加
+### 型の追加 { #add-types }
 
 先ほどのコードから一行変更してみましょう。
 
-以下の関数のパラメータ部分を:
+関数のパラメータである次の断片を、以下から:
 
 ```Python
     first_name, last_name
@@ -80,8 +78,7 @@ John Doe
 
 それが「型ヒント」です:
 
-{* ../../docs_src/python_types/tutorial002.py hl[1] *}
-
+{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
 
 これは、以下のようにデフォルト値を宣言するのと同じではありません:
 
@@ -95,41 +92,39 @@ John Doe
 
 そして、通常、型ヒントを追加しても、それらがない状態と起こることは何も変わりません。
 
-しかし今、あなたが再びその関数を作成している最中に、型ヒントを使っていると想像してみてさい。
+しかし今、あなたが再びその関数を作成している最中に、型ヒントを使っていると想像してみてください。
 
 同じタイミングで`Ctrl+Space`で自動補完を実行すると、以下のようになります:
 
-<img src="https://fastapi.tiangolo.com/img/python-types/image02.png">
+<img src="/img/python-types/image02.png">
 
-これであれば、あなたは「ベルを鳴らす」一つを見つけるまで、オプションを見て、スクロールすることができます:
+これであれば、あなたは「ベルを鳴らす」ものを見つけるまで、オプションを見てスクロールできます:
 
-<img src="https://fastapi.tiangolo.com/img/python-types/image03.png">
+<img src="/img/python-types/image03.png">
 
-## より強い動機
+## より強い動機 { #more-motivation }
 
 この関数を見てください。すでに型ヒントを持っています:
 
-{* ../../docs_src/python_types/tutorial003.py hl[1] *}
+{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
 
+エディタは変数の型を知っているので、補完だけでなく、エラーチェックをすることもできます:
 
-エディタは変数の型を知っているので、補完だけでなく、エラーチェックをすることもできます。
-
-<img src="https://fastapi.tiangolo.com/img/python-types/image04.png">
+<img src="/img/python-types/image04.png">
 
 これで`age`を`str(age)`で文字列に変換して修正する必要があることがわかります:
 
-{* ../../docs_src/python_types/tutorial004.py hl[2] *}
-
+{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
 
-## 型の宣言
+## 型の宣言 { #declaring-types }
 
-関数のパラメータとして、型ヒントを宣言している主な場所を確認しました
+型ヒントを宣言する主な場所を見てきました。関数のパラメータです
 
 これは **FastAPI** で使用する主な場所でもあります。
 
-### 単純な型
+### 単純な型 { #simple-types }
 
-`str`ã\81 ã\81\91ã\81§ã\81ªã\81\8fã\80\81Pythonã\81®æ¨\99æº\96ç\9a\84ã\81ªå\9e\8bã\81\99ã\81¹ã\81¦ã\82\92宣è¨\80ã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\81¾ã\81\99ã\80\82
+`str`だけでなく、Pythonの標準的な型すべてを宣言できます。
 
 例えば、以下を使用可能です:
 
@@ -138,40 +133,47 @@ John Doe
 * `bool`
 * `bytes`
 
-{* ../../docs_src/python_types/tutorial005.py hl[1] *}
+{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
 
+### 型パラメータを持つジェネリック型 { #generic-types-with-type-parameters }
 
-### 型パラメータを持つジェネリック型
+データ構造の中には、`dict`、`list`、`set`、`tuple`のように他の値を含むことができるものがあります。また内部の値も独自の型を持つことができます。
 
-データ構造の中には、`dict`、`list`、`set`、そして`tuple`のように他の値を含むことができるものがあります。また内部の値も独自の型を持つことができます。
+内部の型を持つこれらの型は「**generic**」型と呼ばれます。そして、内部の型も含めて宣言することが可能です。
 
\81\93ã\82\8cã\82\89ã\81®å\9e\8bã\82\84å\86\85é\83¨ã\81®å\9e\8bã\82\92宣è¨\80ã\81\99ã\82\8bã\81«ã\81¯ã\80\81Pythonã\81®æ¨\99æº\96ã\83¢ã\82¸ã\83¥ã\83¼ã\83«`typing`ã\82\92使ç\94¨ã\81\97ます。
\81\93ã\82\8cã\82\89ã\81®å\9e\8bã\82\84å\86\85é\83¨ã\81®å\9e\8bã\82\92宣è¨\80ã\81\99ã\82\8bã\81«ã\81¯ã\80\81Pythonã\81®æ¨\99æº\96ã\83¢ã\82¸ã\83¥ã\83¼ã\83«`typing`ã\82\92使ç\94¨ã\81§ã\81\8dã\81¾ã\81\99ã\80\82ã\81\93ã\82\8cã\82\89ã\81®å\9e\8bã\83\92ã\83³ã\83\88ã\82\92ã\82µã\83\9dã\83¼ã\83\88ã\81\99ã\82\8bã\81\9fã\82\81ã\81«ç\89¹å\88¥ã\81«å­\98å\9c¨ã\81\97ã\81¦ã\81\84ます。
 
-これらの型ヒントをサポートするために特別に存在しています。
+#### 新しいPythonバージョン { #newer-versions-of-python }
 
-#### `List`
+`typing`を使う構文は、Python 3.6から最新バージョンまで(Python 3.9、Python 3.10などを含む)すべてのバージョンと **互換性** があります。
 
-例えば、`str`の`list`の変数を定義してみましょう
+Pythonが進化するにつれ、**新しいバージョン** ではこれらの型アノテーションへのサポートが改善され、多くの場合、型アノテーションを宣言するために`typing`モジュールをインポートして使う必要すらなくなります
 
-`typing`から`List`をインポートします(大文字の`L`を含む):
+プロジェクトでより新しいPythonバージョンを選べるなら、その追加のシンプルさを活用できます。
 
-{* ../../docs_src/python_types/tutorial006.py hl[1] *}
+ドキュメント全体で、Pythonの各バージョンと互換性のある例(差分がある場合)を示しています。
 
+例えば「**Python 3.6+**」はPython 3.6以上(3.7、3.8、3.9、3.10などを含む)と互換性があることを意味します。また「**Python 3.9+**」はPython 3.9以上(3.10などを含む)と互換性があることを意味します。
 
-同じようにコロン(`:`)の構文で変数を宣言します。
+**最新のPythonバージョン** を使えるなら、最新バージョン向けの例を使ってください。例えば「**Python 3.10+**」のように、それらは **最良かつ最もシンプルな構文** になります。
 
-型として、`List`を入力します。
+#### List { #list }
 
-リストはいくつかの内部の型を含む型なので、それらを角括弧で囲んでいます
+例えば、`str`の`list`の変数を定義してみましょう
 
-{* ../../docs_src/python_types/tutorial006.py hl[4] *}
+同じコロン(`:`)の構文で変数を宣言します。
 
+型として、`list`を指定します。
 
-/// tip | 豆知識
+リストはいくつかの内部の型を含む型なので、それらを角括弧で囲みます:
+
+{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
+
+/// info | 情報
 
 角括弧内の内部の型は「型パラメータ」と呼ばれています。
 
-この場合、`str`は`List`に渡される型パラメータです。
+この場合、`str`は`list`に渡される型パラメータです。
 
 ///
 
@@ -179,86 +181,203 @@ John Doe
 
 そうすることで、エディタはリストの項目を処理している間にもサポートを提供できます。
 
-<img src="https://fastapi.tiangolo.com/img/python-types/image05.png">
+<img src="/img/python-types/image05.png">
 
-タイプがなければ、それはほぼ不可能です。
+がなければ、それはほぼ不可能です。
 
 変数`item`はリスト`items`の要素の一つであることに注意してください。
 
 それでも、エディタはそれが`str`であることを知っていて、そのためのサポートを提供しています。
 
-#### `Tuple` と `Set`
+#### Tuple と Set { #tuple-and-set }
 
 `tuple`と`set`の宣言も同様です:
 
-{* ../../docs_src/python_types/tutorial007.py hl[1,4] *}
+{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
+
+つまり:
+
+* 変数`items_t`は`int`、別の`int`、`str`の3つの項目を持つ`tuple`です。
+* 変数`items_s`は`set`であり、その各項目は`bytes`型です。
+
+#### Dict { #dict }
+
+`dict`を定義するには、カンマ区切りで2つの型パラメータを渡します。
+
+最初の型パラメータは`dict`のキーです。
 
+2番目の型パラメータは`dict`の値です:
+
+{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
 
 つまり:
 
-* 変数`items_t`は`int`、`int`、`str`の3つの項目を持つ`tuple`です
+* 変数`prices`は`dict`です:
+    * この`dict`のキーは`str`型です(例えば、各項目の名前)。
+    * この`dict`の値は`float`型です(例えば、各項目の価格)。
 
-* 変数`items_s`はそれぞれの項目が`bytes`型である`set`です。
+#### Union { #union }
 
-#### `Dict`
+変数が**複数の型のいずれか**になり得ることを宣言できます。例えば、`int`または`str`です。
 
-`dict`を宣言するためには、カンマ区切りで2つの型パラメータを渡します。
+Python 3.6以上(Python 3.10を含む)では、`typing`の`Union`型を使い、角括弧の中に受け付ける可能性のある型を入れられます。
 
-最初の型パラメータは`dict`のキーです。
+Python 3.10では、受け付ける可能性のある型を<abbr title='also called "bitwise or operator", but that meaning is not relevant here'>縦棒(`|`)</abbr>で区切って書ける **新しい構文** もあります。
+
+//// tab | Python 3.10+
 
-2番目の型パラメータは`dict`の値です。
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial008b_py310.py!}
+```
 
-{* ../../docs_src/python_types/tutorial008.py hl[1,4] *}
+////
 
+//// tab | Python 3.9+
 
-つまり:
+```Python hl_lines="1  4"
+{!> ../../docs_src/python_types/tutorial008b_py39.py!}
+```
+
+////
+
+どちらの場合も、`item`は`int`または`str`になり得ることを意味します。
+
+#### `None`の可能性 { #possibly-none }
+
+値が`str`のような型を持つ可能性がある一方で、`None`にもなり得ることを宣言できます。
+
+Python 3.6以上(Python 3.10を含む)では、`typing`モジュールから`Optional`をインポートして使うことで宣言できます。
+
+```Python hl_lines="1  4"
+{!../../docs_src/python_types/tutorial009_py39.py!}
+```
+
+ただの`str`の代わりに`Optional[str]`を使用することで、値が常に`str`であると仮定しているときに、実際には`None`である可能性もあるというエラーをエディタが検出するのに役立ちます。
+
+`Optional[Something]`は実際には`Union[Something, None]`のショートカットで、両者は等価です。
+
+これは、Python 3.10では`Something | None`も使えることを意味します:
+
+//// tab | Python 3.10+
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial009_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="1  4"
+{!> ../../docs_src/python_types/tutorial009_py39.py!}
+```
+
+////
+
+//// tab | Python 3.9+ alternative
+
+```Python hl_lines="1  4"
+{!> ../../docs_src/python_types/tutorial009b_py39.py!}
+```
+
+////
+
+#### `Union`または`Optional`の使用 { #using-union-or-optional }
 
-* 変数`prices`は`dict`であり:
-    * この`dict`のキーは`str`型です。(つまり、各項目の名前)
-    * この`dict`の値は`float`型です。(つまり、各項目の価格)
+Python 3.10未満のバージョンを使っている場合、これは私のとても **主観的** な観点からのヒントです:
 
-#### `Optional`
+* 🚨 `Optional[SomeType]`は避けてください
+* 代わりに ✨ **`Union[SomeType, None]`を使ってください** ✨
 
\81¾ã\81\9fã\80\81`Optional`ã\82\92使ç\94¨ã\81\97ã\81¦ã\80\81å¤\89æ\95°ã\81\8c`str`ã\81®ã\82\88ã\81\86ã\81ªå\9e\8bã\82\92æ\8c\81ã\81¤ã\81\93ã\81¨ã\82\92宣è¨\80ã\81\99ã\82\8bã\81\93ã\81¨ã\82\82ã\81§ã\81\8dã\81¾ã\81\99ã\81\8cã\80\81ã\81\9dã\82\8cã\81¯ã\80\8cã\82ªã\83\97ã\82·ã\83§ã\83³ã\80\8dã\81§ã\81\82ã\82\8aã\80\81`None`ã\81«ã\81\99ã\82\8bã\81\93ã\81¨ã\82\82ã\81§ã\81\8dã\81¾す。
\81©ã\81¡ã\82\89ã\82\82ç­\89価ã\81§ã\80\81å\86\85é\83¨ç\9a\84ã\81«ã\81¯å\90\8cã\81\98ã\81§ã\81\99ã\81\8cã\80\81`Optional`ã\82\88ã\82\8a`Union`ã\82\92ã\81\8aã\81\99ã\81\99ã\82\81ã\81\97ã\81¾ã\81\99ã\80\82ã\81¨ã\81\84ã\81\86ã\81®ã\82\82ã\80\8c**optional**ã\80\8dã\81¨ã\81\84ã\81\86å\8d\98èª\9eã\81¯å\80¤ã\81\8cã\82ªã\83\97ã\82·ã\83§ã\83³ã\81§ã\81\82ã\82\8bã\81\93ã\81¨ã\82\92示å\94\86ã\81\99ã\82\8bã\82\88ã\81\86ã\81«è¦\8bã\81\88ã\81¾ã\81\99ã\81\8cã\80\81å®\9fé\9a\9bã\81«ã\81¯ã\80\8c`None`ã\81«ã\81ªã\82\8aå¾\97ã\82\8bã\80\8dã\81¨ã\81\84ã\81\86æ\84\8få\91³ã\81§ã\81\82ã\82\8aã\80\81ã\82ªã\83\97ã\82·ã\83§ã\83³ã\81§ã\81¯ã\81ªã\81\8få¿\85é \88ã\81§ã\81\82ã\82\8bå ´å\90\88ã\81§ã\82\82ã\81\9dã\81\86ã\81 ã\81\8bã\82\89ã\81§す。
 
-```Python hl_lines="1 4"
-{!../../docs_src/python_types/tutorial009.py!}
+`Union[SomeType, None]`のほうが意味がより明示的だと思います。
+
+これは言葉や名前の話にすぎません。しかし、その言葉はあなたやチームメイトがコードをどう考えるかに影響し得ます。
+
+例として、この関数を見てみましょう:
+
+{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
+
+パラメータ`name`は`Optional[str]`として定義されていますが、**オプションではありません**。そのパラメータなしで関数を呼び出せません:
+
+```Python
+say_hi()  # Oh, no, this throws an error! 😱
 ```
 
-ただの`str`の代わりに`Optional[str]`を使用することで、エディタは値が常に`str`であると仮定している場合に実際には`None`である可能性があるエラーを検出するのに役立ちます。
+`name`パラメータはデフォルト値がないため、**依然として必須**(*optional*ではない)です。それでも、`name`は値として`None`を受け付けます:
+
+```Python
+say_hi(name=None)  # This works, None is valid 🎉
+```
+
+良い知らせとして、Python 3.10になればその心配は不要です。型のユニオンを定義するために`|`を単純に使えるからです:
+
+{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
+
+そして、`Optional`や`Union`のような名前について心配する必要もなくなります。😎
 
-#### ジェネリック型
+#### ジェネリック型 { #generic-types }
 
-以下のように角括弧で型パラメータを取る型を:
+角括弧で型パラメータを取るこれらの型は、例えば次のように **Generic types** または **Generics** と呼ばれます:
 
-* `List`
-* `Tuple`
-* `Set`
-* `Dict`
+//// tab | Python 3.10+
+
+同じ組み込み型をジェネリクスとして(角括弧と内部の型で)使えます:
+
+* `list`
+* `tuple`
+* `set`
+* `dict`
+
+また、これまでのPythonバージョンと同様に、`typing`モジュールから:
+
+* `Union`
 * `Optional`
-* ...など
+* ...and others.
 
-**ジェネリック型** または **ジェネリクス** と呼びます。
+Python 3.10では、ジェネリクスの`Union`や`Optional`を使う代替として、型のユニオンを宣言するために<abbr title='also called "bitwise or operator", but that meaning is not relevant here'>縦棒(`|`)</abbr>を使えます。これはずっと良く、よりシンプルです。
 
-### 型としてのクラス
+////
 
-変数の型としてクラスを宣言することもできます。
+//// tab | Python 3.9+
+
+同じ組み込み型をジェネリクスとして(角括弧と内部の型で)使えます:
 
-例えば、`Person`クラスという名前のクラスがあるとしましょう:
+* `list`
+* `tuple`
+* `set`
+* `dict`
 
-{* ../../docs_src/python_types/tutorial010.py hl[1,2,3] *}
+そして`typing`モジュールのジェネリクス:
+
+* `Union`
+* `Optional`
+* ...and others.
+
+////
+
+### 型としてのクラス { #classes-as-types }
+
+変数の型としてクラスを宣言することもできます。
 
+名前を持つ`Person`クラスがあるとしましょう:
 
-変数の型を`Person`として宣言することができます:
+{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
 
-{* ../../docs_src/python_types/tutorial010.py hl[6] *}
+変数を`Person`型として宣言できます:
 
+{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
 
 そして、再び、すべてのエディタのサポートを得ることができます:
 
-<img src="https://fastapi.tiangolo.com/img/python-types/image06.png">
+<img src="/img/python-types/image06.png">
 
-## Pydanticのモデル
+これは「`one_person`はクラス`Person`の**インスタンス**である」ことを意味します。
+
+「`one_person`は`Person`という名前の**クラス**である」という意味ではありません。
+
+## Pydanticのモデル { #pydantic-models }
 
 <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> はデータ検証を行うためのPythonライブラリです。
 
@@ -266,18 +385,17 @@ John Doe
 
 そして、それぞれの属性は型を持ちます。
 
-さらに、いくつかの値を持つクラスのインスタンスを作成すると、その値を検証し、適切な型に変換して(もしそうであれば)てのデータを持つオブジェクトを提供してくれます。
+さらに、いくつかの値を持つクラスのインスタンスを作成すると、その値を検証し、適切な型に変換して(もしそうであれば)すべてのデータを持つオブジェクトを提供してくれます。
 
 また、その結果のオブジェクトですべてのエディタのサポートを受けることができます。
 
-Pydanticの公式ドキュメントから引用:
-
-{* ../../docs_src/python_types/tutorial011.py *}
+Pydanticの公式ドキュメントからの例:
 
+{* ../../docs_src/python_types/tutorial011_py310.py *}
 
 /// info | 情報
 
-Pydanticについてより学びたい方は<a href="https://docs.pydantic.dev/" class="external-link" target="_blank">ドキュメントを参照してください</a>.
+<a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydanticの詳細はドキュメントを参照してください</a>。
 
 ///
 
@@ -285,30 +403,62 @@ Pydanticについてより学びたい方は<a href="https://docs.pydantic.dev/"
 
 すべてのことは[チュートリアル - ユーザーガイド](tutorial/index.md){.internal-link target=_blank}で実際に見ることができます。
 
-## **FastAPI**での型ヒント
+/// tip | 豆知識
+
+Pydanticには、デフォルト値なしで`Optional`または`Union[Something, None]`を使った場合の特別な挙動があります。詳細はPydanticドキュメントの<a href="https://docs.pydantic.dev/2.3/usage/models/#required-fields" class="external-link" target="_blank">Required Optional fields</a>を参照してください。
+
+///
+
+## メタデータアノテーション付き型ヒント { #type-hints-with-metadata-annotations }
+
+Pythonには、`Annotated`を使って型ヒントに**追加の<abbr title="Data about the data, in this case, information about the type, e.g. a description.">メタデータ</abbr>**を付与できる機能もあります。
+
+Python 3.9以降、`Annotated`は標準ライブラリの一部なので、`typing`からインポートできます。
+
+{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
+
+Python自体は、この`Annotated`で何かをするわけではありません。また、エディタや他のツールにとっても、型は依然として`str`です。
+
+しかし、`Annotated`内のこのスペースを使って、アプリケーションをどのように動作させたいかについての追加メタデータを **FastAPI** に提供できます。
+
+覚えておくべき重要な点は、`Annotated`に渡す**最初の*型パラメータ***が**実際の型**であることです。残りは、他のツール向けのメタデータにすぎません。
+
+今のところは、`Annotated`が存在し、それが標準のPythonであることを知っておけば十分です。😎
+
+後で、これがどれほど**強力**になり得るかを見ることになります。
+
+/// tip | 豆知識
+
+これが **標準のPython** であるという事実は、エディタで、使用しているツール(コードの解析やリファクタリングなど)とともに、**可能な限り最高の開発体験**が得られることを意味します。 ✨
+
+また、あなたのコードが他の多くのPythonツールやライブラリとも非常に互換性が高いことも意味します。 🚀
+
+///
+
+## **FastAPI**での型ヒント { #type-hints-in-fastapi }
 
 **FastAPI** はこれらの型ヒントを利用していくつかのことを行います。
 
-**FastAPI** では型ヒントを使ってパラメータを宣言すると以下のものが得られます:
+**FastAPI** では型ヒントを使ってパラメータを宣言すると以下のものが得られます:
 
-* **エディタサポート**.
-* **型チェック**.
+* **エディタサポート**
+* **型チェック**
 
-...そして **FastAPI** は同じように宣言をすると、以下のことを行います:
+...そして **FastAPI** は同じ宣言を使って、以下のことを行います:
 
-* **要件の定義**: リクエストパスパラメータ、クエリパラメータ、ヘッダー、ボディ、依存関係などから要件を定義します。
-* **ã\83\87ã\83¼ã\82¿ã\81®å¤\89æ\8f\9b**: ã\83ªã\82¯ã\82¨ã\82¹ã\83\88ã\81®ã\83\87ã\83¼ã\82¿ã\82\92å¿\85è¦\81ã\81ªå\9e\8bã\81«変換します。
-* **データの検証**: リクエストごとに:
+* **è¦\81ä»¶ã\81®å®\9a義**: ã\83ªã\82¯ã\82¨ã\82¹ã\83\88ã\81®ã\83\91ã\82¹ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\80\81ã\82¯ã\82¨ã\83ªã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\80\81ã\83\98ã\83\83ã\83\80ã\83¼ã\80\81ã\83\9cã\83\87ã\82£ã\80\81ä¾\9då­\98é\96¢ä¿\82ã\81ªã\81©ã\81\8bã\82\89è¦\81ä»¶ã\82\92å®\9a義ã\81\97ã\81¾ã\81\99ã\80\82
+* **ã\83\87ã\83¼ã\82¿ã\81®å¤\89æ\8f\9b**: ã\83ªã\82¯ã\82¨ã\82¹ã\83\88ã\81\8bã\82\89å¿\85è¦\81ã\81ªå\9e\8bã\81«ã\83\87ã\83¼ã\82¿ã\82\92変換します。
+* **データの検証**: 各リクエストから来るデータについて:
     * データが無効な場合にクライアントに返される **自動エラー** を生成します。
-* **ドキュメント** OpenAPIを使用したAPI:
-    * 自動的に対話型ドキュメントのユーザーインターフェイスで使用されます。
+* OpenAPIを使用してAPIを**ドキュメント化**します:
+    * これは自動の対話型ドキュメントのユーザーインターフェイスで使われます。
 
 すべてが抽象的に聞こえるかもしれません。心配しないでください。 この全ての動作は [チュートリアル - ユーザーガイド](tutorial/index.md){.internal-link target=_blank}で見ることができます。
 
-重要なのは、Pythonの標準的な型を使うことで、(クラスやデコレータなどを追加するのではなく)つの場所で **FastAPI** が多くの作業を代わりにやってくれているということです。
+重要なのは、Pythonの標準的な型を使うことで、(クラスやデコレータなどを追加するのではなく)1つの場所で **FastAPI** が多くの作業を代わりにやってくれているということです。
 
 /// info | 情報
 
-すでにすべてのチュートリアルを終えて、型についての詳細を見るためにこのページに戻ってきた場合は、<a href="https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html" class="external-link" target="_blank">`mypy`のチートシートを参照してください</a>
+すでにすべてのチュートリアルを終えて、型についての詳細を見るためにこのページに戻ってきた場合は、良いリソースとして<a href="https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html" class="external-link" target="_blank">`mypy`の「チートシート」</a>があります。
 
 ///
index b289faf12d0dee07c2f4ed1dc8ab6ff608c1b5d2..0ed41ce11494d50df19ee50753501b5a4a833754 100644 (file)
@@ -1,4 +1,4 @@
-# バックグラウンドタスク
+# バックグラウンドタスク { #background-tasks }
 
 レスポンスを返した *後に* 実行されるバックグラウンドタスクを定義できます。
 
@@ -9,17 +9,17 @@
 * 作業実行後のメール通知:
     * メールサーバーへの接続とメールの送信は「遅い」(数秒) 傾向があるため、すぐにレスポンスを返し、バックグラウンドでメール通知ができます。
 * データ処理:
-    * たとえば、時間のかかる処理を必要とするファイル受信時には、「受信済み」(HTTP 202) のレスポンスを返し、バックグラウンドで処理できます。
+    * たとえば、時間のかかる処理を必要とするファイル受信時には、「Accepted」(HTTP 202) のレスポンスを返し、バックグラウンドで処理できます。
 
-## `BackgroundTasks` の使用
+## `BackgroundTasks` の使用 { #using-backgroundtasks }
 
-まず初めに、`BackgroundTasks` をインポートし、` BackgroundTasks` の型宣言と共に、*path operation 関数* のパラメーターを定義します:
+まず初めに、`BackgroundTasks` をインポートし、`BackgroundTasks` の型宣言と共に、*path operation function* のパラメーターを定義します:
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
 
 **FastAPI** は、`BackgroundTasks` 型のオブジェクトを作成し、そのパラメーターに渡します。
 
-## タスク関数の作成
+## タスク関数の作成 { #create-a-task-function }
 
 バックグラウンドタスクとして実行される関数を作成します。
 
 
 また、書き込み操作では `async` と `await` を使用しないため、通常の `def` で関数を定義します。
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
 
-## バックグラウンドタスクの追加
+## バックグラウンドタスクの追加 { #add-the-background-task }
 
-*path operations 関数* 内で、`.add_task()` メソッドを使用してタスク関数を *background tasks* オブジェクトに渡します。
+*path operation function* 内で、`.add_task()` メソッドを使用してタスク関数を *background tasks* オブジェクトに渡します。
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[14] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
 
 `.add_task()` は以下の引数を受け取ります:
 
 * タスク関数に順番に渡す必要のある引数の列 (`email`)。
 * タスク関数に渡す必要のあるキーワード引数 (`message="some notification"`)。
 
-## 依存性注入
+## 依存性注入 { #dependency-injection }
 
-`BackgroundTasks` の使用は依存性注入システムでも機能し、様々な階層 (*path operations 関数*、依存性 (依存可能性)、サブ依存性など) で `BackgroundTasks` 型のパラメーターを宣言できます。
+`BackgroundTasks` の使用は依存性注入システムでも機能し、様々な階層 (*path operation function*、依存性 (dependable)、サブ依存性など) で `BackgroundTasks` 型のパラメーターを宣言できます。
 
-**FastAPI** は、それぞれの場合の処理​​方法と同じオブジェクトの再利用方法を知っているため、すべてのバックグラウンドタスクがマージされ、バックグラウンドで後で実行されます。
+**FastAPI** は、それぞれの場合の処理​​方法と同じオブジェクトの再利用方法を知っているため、すべてのバックグラウンドタスクがマージされ、バックグラウンドで後で実行されます:
+
+
+{* ../../docs_src/background_tasks/tutorial002_an_py310.py hl[13,15,22,25] *}
 
-{* ../../docs_src/background_tasks/tutorial002.py hl[13,15,22,25] *}
 
 この例では、レスポンスが送信された *後* にメッセージが `log.txt` ファイルに書き込まれます。
 
 リクエストにクエリがあった場合、バックグラウンドタスクでログに書き込まれます。
 
-そして、*path operations 関数* で生成された別のバックグラウンドタスクは、`email` パスパラメータを使用してメッセージを書き込みます。
+そして、*path operation function* で生成された別のバックグラウンドタスクは、`email` パスパラメータを使用してメッセージを書き込みます。
 
-## 技術的な詳細
+## 技術的な詳細 { #technical-details }
 
 `BackgroundTasks` クラスは、<a href="https://www.starlette.dev/background/" class="external-link" target="_blank">`starlette.background`</a>から直接取得されます。
 
 これは、FastAPI に直接インポート/インクルードされるため、`fastapi` からインポートできる上に、`starlette.background`から別の `BackgroundTask` (末尾に `s` がない) を誤ってインポートすることを回避できます。
 
-`BackgroundTasks`のみを使用することで (`BackgroundTask` ではなく)、`Request` オブジェクトを直接使用する場合と同様に、それを *path operations 関数* パラメーターとして使用し、**FastAPI** に残りの処理を任せることができます。
+`BackgroundTasks`のみを使用することで (`BackgroundTask` ではなく)、`Request` オブジェクトを直接使用する場合と同様に、それを *path operation function* パラメーターとして使用し、**FastAPI** に残りの処理を任せることができます。
 
 それでも、FastAPI で `BackgroundTask` を単独で使用することは可能ですが、コード内でオブジェクトを作成し、それを含むStarlette `Response` を返す必要があります。
 
-詳細については、<a href="https://www.starlette.dev/background/" class="external-link" target="_blank">バックグラウンドタスクに関する Starlette の公式ドキュメント</a>を参照して下さい。
+詳細については、<a href="https://www.starlette.dev/background/" class="external-link" target="_blank">Starlette のバックグラウンドタスクに関する公式ドキュメント</a>を参照して下さい。
 
-## 警告
+## 注意 { #caveat }
 
-大量のバックグラウンド計算が必要であり、必ずしも同じプロセスで実行する必要がない場合 (たとえば、メモリや変数などを共有する必要がない場合)、<a href="https://www.celeryproject.org/" class="external-link" target="_blank">Celery</a> のようなより大きな他のツールを使用するとメリットがあるかもしれません。
+大量のバックグラウンド計算が必要であり、必ずしも同じプロセスで実行する必要がない場合 (たとえば、メモリや変数などを共有する必要がない場合)、<a href="https://docs.celeryq.dev" class="external-link" target="_blank">Celery</a> のようなより大きな他のツールを使用するとメリットがあるかもしれません。
 
 これらは、より複雑な構成、RabbitMQ や Redis などのメッセージ/ジョブキューマネージャーを必要とする傾向がありますが、複数のプロセス、特に複数のサーバーでバックグラウンドタスクを実行できます。
 
 ただし、同じ **FastAPI** アプリから変数とオブジェクトにアクセスする必要がある場合、または小さなバックグラウンドタスク (電子メール通知の送信など) を実行する必要がある場合は、単に `BackgroundTasks` を使用できます。
 
-## まとめ
+## まとめ { #recap }
 
-`BackgroundTasks` をインポートして、*path operations 関数* や依存関係のパラメータに `BackgroundTasks`を使用し、バックグラウンドタスクを追加して下さい。
+*path operation functions* と依存性のパラメータで `BackgroundTasks`をインポートして使用し、バックグラウンドタスクを追加して下さい。
index ce5630351eba145deae3c362ec774e40d685c7ad..234c99d529b237ac600fcbd0922e07bd2ccfe03d 100644 (file)
@@ -1,12 +1,13 @@
-# ボディ - フィールド
+# ボディ - フィールド { #body-fields }
 
 `Query`や`Path`、`Body`を使って *path operation関数* のパラメータに追加のバリデーションやメタデータを宣言するのと同じように、Pydanticの`Field`を使ってPydanticモデルの内部でバリデーションやメタデータを宣言することができます。
 
-## `Field`のインポート
+## `Field`のインポート { #import-field }
 
 まず、以下のようにインポートします:
 
-{* ../../docs_src/body_fields/tutorial001.py hl[4] *}
+{* ../../docs_src/body_fields/tutorial001_an_py310.py hl[4] *}
+
 
 /// warning | 注意
 
 
 ///
 
-## モデルの属性の宣言
+## モデルの属性の宣言 { #declare-model-attributes }
 
 以下のように`Field`をモデルの属性として使用することができます:
 
-{* ../../docs_src/body_fields/tutorial001.py hl[11,12,13,14] *}
+{* ../../docs_src/body_fields/tutorial001_an_py310.py hl[11:14] *}
 
 `Field`は`Query`や`Path`、`Body`と同じように動作し、全く同様のパラメータなどを持ちます。
 
 
 ///
 
-## 追加情報の追加
+## 追加情報の追加 { #add-extra-information }
 
 追加情報は`Field`や`Query`、`Body`などで宣言することができます。そしてそれは生成されたJSONスキーマに含まれます。
 
 後に例を用いて宣言を学ぶ際に、追加情報を追加する方法を学べます。
 
-## まとめ
+/// warning | 注意
+
+`Field`に渡された追加のキーは、結果として生成されるアプリケーションのOpenAPIスキーマにも含まれます。
+これらのキーは必ずしもOpenAPI仕様の一部であるとは限らないため、例えば[OpenAPI validator](https://validator.swagger.io/)などの一部のOpenAPIツールは、生成されたスキーマでは動作しない場合があります。
+
+///
+
+## まとめ { #recap }
 
 Pydanticの`Field`を使用して、モデルの属性に追加のバリデーションやメタデータを宣言することができます。
 
index cbfdda4b211a51bddd1c0bd857e88cc8f3221c9a..4ce77cc0dc4dbfb08532f89300598b7d709632c7 100644 (file)
@@ -1,24 +1,24 @@
-# ボディ - 複数のパラメータ
+# ボディ - 複数のパラメータ { #body-multiple-parameters }
 
-これまで`Path`と`Query`をどう使うかを見てきましたが、リクエストボディ宣言のより高度な使い方を見てみましょう。
+これまで`Path`と`Query`をどう使うかを見てきましたが、リクエストボディ宣言のより高度な使い方を見てみましょう。
 
-## `Path`、`Query`とボディパラメータを混ぜる
+## `Path`、`Query`とボディパラメータを混ぜる { #mix-path-query-and-body-parameters }
 
-まず、もちろん、`Path`と`Query`とリクエストボディのパラメータ宣言は自由に混ぜることができ、 **FastAPI** は何をするべきかを知っています。
+まず、もちろん、`Path`と`Query`とリクエストボディのパラメータ宣言は自由に混ぜることができ、 **FastAPI** は何をするべきかを知っています。
 
\81¾ã\81\9fã\80\81ã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\81®`None`ã\82\92設定することで、ボディパラメータをオプションとして宣言することもできます:
\81¾ã\81\9fã\80\81ã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\82\92`None`ã\81«設定することで、ボディパラメータをオプションとして宣言することもできます:
 
-{* ../../docs_src/body_multiple_params/tutorial001.py hl[19,20,21] *}
+{* ../../docs_src/body_multiple_params/tutorial001_an_py310.py hl[18:20] *}
 
 /// note | 備考
 
\81\93ã\81®å ´å\90\88ã\80\81ã\83\9cã\83\87ã\82£ã\81\8bã\82\89å\8f\96å¾\97ã\81\99ã\82\8b`item`ã\81¯ã\82ªã\83\97ã\82·ã\83§ã\83³ã\81§ã\81\82ã\82\8bã\81\93ã\81¨ã\81«æ³¨æ\84\8fã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82ã\83\87ã\83\95ã\82©ã\83«ã\83\88å\80¤ã\81¯`None`です。
\81\93ã\81®å ´å\90\88ã\80\81ã\83\9cã\83\87ã\82£ã\81\8bã\82\89å\8f\96å¾\97ã\81\99ã\82\8b`item`ã\81¯ã\82ªã\83\97ã\82·ã\83§ã\83³ã\81§ã\81\82ã\82\8bã\81\93ã\81¨ã\81«æ³¨æ\84\8fã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82ã\83\87ã\83\95ã\82©ã\83«ã\83\88å\80¤ã\81\8c`None`ã\81«ã\81ªã\81£ã\81¦ã\81\84ã\82\8bã\81\9fã\82\81です。
 
 ///
 
-## 複数のボディパラメータ
+## 複数のボディパラメータ { #multiple-body-parameters }
 
-上述の例では、*path operations*は`item`の属性を持つ以下のようなJSONボディを期待していました:
+上述の例では、*path operations*は`Item`の属性を持つ以下のようなJSONボディを期待していました:
 
 ```JSON
 {
 
 しかし、`item`と`user`のように複数のボディパラメータを宣言することもできます:
 
-{* ../../docs_src/body_multiple_params/tutorial002.py hl[22] *}
+{* ../../docs_src/body_multiple_params/tutorial002_py310.py hl[20] *}
 
-この場合、**FastAPI**は関数内に複数のボディパラメータ(Pydanticモデルである2つのパラメータ)があることに気付きます。
 
-そのため、パラメータ名をボディのキー(フィールド名)として使用し、以下のようなボディを期待しています:
+この場合、**FastAPI**は関数内に複数のボディパラメータがあることに気付きます(Pydanticモデルである2つのパラメータがあります)。
+
+そのため、パラメータ名をボディのキー(フィールド名)として使用し、以下のようなボディを期待します:
 
 ```JSON
 {
@@ -62,7 +63,7 @@
 
 複合データの検証を行い、OpenAPIスキーマや自動ドキュメントのように文書化してくれます。
 
-## ボディ内の単数値
+## ボディ内の単数値 { #singular-values-in-body }
 
 クエリとパスパラメータの追加データを定義するための `Query` と `Path` があるのと同じように、 **FastAPI** は同等の `Body` を提供します。
 
 
 しかし、`Body`を使用して、**FastAPI** に別のボディキーとして扱うように指示することができます:
 
+{* ../../docs_src/body_multiple_params/tutorial003_an_py310.py hl[23] *}
 
-{* ../../docs_src/body_multiple_params/tutorial003.py hl[23] *}
 
 この場合、**FastAPI** は以下のようなボディを期待します:
 
-
 ```JSON
 {
     "item": {
 
 繰り返しになりますが、データ型の変換、検証、文書化などを行います。
 
-## 複数のボディパラメータとクエリ
+## 複数のボディパラメータとクエリ { #multiple-body-params-and-query }
 
 もちろん、ボディパラメータに加えて、必要に応じて追加のクエリパラメータを宣言することもできます。
 
\83\87ã\83\95ã\82©ã\83«ã\83\88ã\81§ã\81¯ã\80\81å\8d\98æ\95°å\80¤ã\81¯ã\82¯ã\82¨ã\83ªã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81¨ã\81\97ã\81¦è§£é\87\88ã\81\95ã\82\8cã\82\8bã\81®ã\81§ã\80\81æ\98\8e示ç\9a\84ã\81« `Query` ã\82\92追å\8a ã\81\99ã\82\8bå¿\85è¦\81ã\81¯ã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\80\82
\83\87ã\83\95ã\82©ã\83«ã\83\88ã\81§ã\81¯ã\80\81å\8d\98æ\95°å\80¤ã\81¯ã\82¯ã\82¨ã\83ªã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81¨ã\81\97ã\81¦è§£é\87\88ã\81\95ã\82\8cã\82\8bã\81®ã\81§ã\80\81æ\98\8e示ç\9a\84ã\81« `Query` ã\82\92追å\8a ã\81\99ã\82\8bå¿\85è¦\81ã\81¯ã\81ªã\81\8fã\80\81次ã\81®ã\82\88ã\81\86ã\81«ã\81§ã\81\8dã\81¾ã\81\99:
 
 ```Python
-q: str = None
+q: str | None = None
 ```
 
-以下において:
+またはPython 3.10以上では:
+
+```Python
+q: Union[str, None] = None
+```
 
-{* ../../docs_src/body_multiple_params/tutorial004.py hl[27] *}
+例えば:
+
+{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}
 
 /// info | 情報
 
-`Body`もまた、後述する `Query` や `Path` などと同様に、すべての検証パラメータとメタデータパラメータを持っています。
+`Body`もまた、後述する `Query` や `Path` などと同様に、すべての追加検証パラメータとメタデータパラメータを持っています。
 
 ///
 
-## 単一のボディパラメータの埋め込み
+## 単一のボディパラメータの埋め込み { #embed-a-single-body-parameter }
 
-Pydanticモデル`Item`のボディパラメータ`item`を1つだけ持っているとしましょう。
+Pydanticモデル`Item`の単一の`item`ボディパラメータしかないとしましょう。
 
 デフォルトでは、**FastAPI**はそのボディを直接期待します。
 
\81\97ã\81\8bã\81\97ã\80\81追å\8a ã\81®ã\83\9cã\83\87ã\82£ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\82\92宣è¨\80ã\81\97ã\81\9fã\81¨ã\81\8dã\81®ã\82\88ã\81\86ã\81«ã\80\81ã\82­ã\83¼ `item` ã\82\92æ\8c\81ã\81¤ JSON ã\81¨ã\81\9dã\81®ä¸­ã\81®ã\83¢ã\83\87ã\83«ã\81®内容を期待したい場合は、特別な `Body` パラメータ `embed` を使うことができます:
\81\97ã\81\8bã\81\97ã\80\81追å\8a ã\81®ã\83\9cã\83\87ã\82£ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\82\92宣è¨\80ã\81\97ã\81\9fã\81¨ã\81\8dã\81®ã\82\88ã\81\86ã\81«ã\80\81ã\82­ã\83¼ `item` ã\82\92æ\8c\81ã\81¤ JSON ã\81¨ã\80\81ã\81\9dã\81®ä¸­ã\81®ã\83¢ã\83\87ã\83«内容を期待したい場合は、特別な `Body` パラメータ `embed` を使うことができます:
 
 ```Python
-item: Item = Body(..., embed=True)
+item: Item = Body(embed=True)
 ```
 
 以下において:
 
-{* ../../docs_src/body_multiple_params/tutorial005.py hl[17] *}
+{* ../../docs_src/body_multiple_params/tutorial005_an_py310.py hl[17] *}
+
 
 この場合、**FastAPI** は以下のようなボディを期待します:
 
@@ -156,9 +163,9 @@ item: Item = Body(..., embed=True)
 }
 ```
 
-## まとめ
+## まとめ { #recap }
 
-リクエストが単一のボディしか持てない場合でも、*path operation関数*に複数のボディパラメータを追加することができます。
+リクエストが単一のボディしか持てない場合でも、*path operation function*に複数のボディパラメータを追加することができます。
 
 しかし、**FastAPI** はそれを処理し、関数内の正しいデータを与え、*path operation*内の正しいスキーマを検証し、文書化します。
 
index a1680d10f2525f4026814c6928f1ec43f2aa221e..24eb302082d728819a8cd074fd49d496857c040b 100644 (file)
@@ -1,36 +1,26 @@
-# ボディ - ネストされたモデル
+# ボディ - ネストされたモデル { #body-nested-models }
 
 **FastAPI** を使用すると、深くネストされた任意のモデルを定義、検証、文書化、使用することができます(Pydanticのおかげです)。
 
-## リストのフィールド
+## リストのフィールド { #list-fields }
 
-属性をサブタイプとして定義することができます。例えば、Pythonの`list`は以下のように定義できます:
+属性をサブタイプとして定義することができます。例えば、Pythonの`list`:
 
-{* ../../docs_src/body_nested_models/tutorial001.py hl[12] *}
+{* ../../docs_src/body_nested_models/tutorial001_py310.py hl[12] *}
 
\81\93ã\82\8cã\81«ã\82\88ã\82\8aã\80\81å\90\84é \85ç\9b®ã\81®å\9e\8bã\81¯å®£è¨\80ã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\9bã\82\93ã\81\8cã\80\81`tags`ã\81¯ã\81\82ã\82\8bé \85ç\9b®ã\81®ã\83ªã\82¹ã\83\88ã\81«ã\81ªã\82\8aã\81¾ã\81\99ã\80\82
+これにより、各項目の型は宣言されていませんが、`tags`はリストになります。
 
-## タイプパラメータを持つリストのフィールド
+## タイプパラメータを持つリストのフィールド { #list-fields-with-type-parameter }
 
\81\97ã\81\8bã\81\97ã\80\81Pythonã\81«ã\81¯å\9e\8bã\82\84ã\80\8cã\82¿ã\82¤ã\83\97ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\80\8dã\82\92使ã\81£ã\81¦ã\83ªã\82¹ã\83\88ã\82\92宣è¨\80ã\81\99ã\82\8b方法があります:
\81\97ã\81\8bã\81\97ã\80\81Pythonã\81«ã\81¯å\86\85é\83¨ã\81®å\9e\8bã\80\81ã\81¾ã\81\9fã\81¯ã\80\8cã\82¿ã\82¤ã\83\97ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\80\8dã\82\92使ã\81£ã\81¦ã\83ªã\82¹ã\83\88ã\82\92宣è¨\80ã\81\99ã\82\8bã\81\9fã\82\81ã\81®ç\89¹å®\9aã\81®方法があります:
 
-### typingの`List`をインポート
+### タイプパラメータを持つ`list`の宣言 { #declare-a-list-with-a-type-parameter }
 
-まず、Pythonの標準の`typing`モジュールから`List`をインポートします:
-
-{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *}
-
-### タイプパラメータを持つ`List`の宣言
-
-`list`や`dict`、`tuple`のようなタイプパラメータ(内部の型)を持つ型を宣言するには:
-
-* `typing`モジュールからそれらをインストールします。
-* 角括弧(`[`と`]`)を使って「タイプパラメータ」として内部の型を渡します:
+`list`、`dict`、`tuple`のようにタイプパラメータ(内部の型)を持つ型を宣言するには、
+角括弧(`[`と`]`)を使って内部の型を「タイプパラメータ」として渡します。
 
 ```Python
-from typing import List
-
-my_list: List[str]
+my_list: list[str]
 ```
 
 型宣言の標準的なPythonの構文はこれだけです。
@@ -39,17 +29,17 @@ my_list: List[str]
 
 そのため、以下の例では`tags`を具体的な「文字列のリスト」にすることができます:
 
-{* ../../docs_src/body_nested_models/tutorial002.py hl[14] *}
+{* ../../docs_src/body_nested_models/tutorial002_py310.py hl[12] *}
 
-## セット型
+## セット型 { #set-types }
 
 しかし、よく考えてみると、タグは繰り返すべきではなく、おそらくユニークな文字列になるのではないかと気付いたとします。
 
 そして、Pythonにはユニークな項目のセットのための特別なデータ型`set`があります。
 
\81\9dã\81®ã\81\9fã\82\81ã\80\81以ä¸\8bã\81®ã\82\88ã\81\86ã\81«ã\80\81`Set`ã\82\92ã\82¤ã\83³ã\83\9dã\83¼ã\83\88ã\81\97ã\81¦`str`ã\81®`set`ã\81¨ã\81\97ã\81¦`tags`ã\82\92宣è¨\80ã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cできます:
\81\9dã\81\97ã\81¦ã\80\81`tags`ã\82\92æ\96\87å­\97å\88\97ã\81®ã\82»ã\83\83ã\83\88ã\81¨ã\81\97ã\81¦å®£è¨\80できます:
 
-{* ../../docs_src/body_nested_models/tutorial003.py hl[1,14] *}
+{* ../../docs_src/body_nested_models/tutorial003_py310.py hl[12] *}
 
 これを使えば、データが重複しているリクエストを受けた場合でも、ユニークな項目のセットに変換されます。
 
@@ -57,27 +47,27 @@ my_list: List[str]
 
 また、それに応じて注釈をつけたり、文書化したりします。
 
-## ネストされたモデル
+## ネストされたモデル { #nested-models }
 
 Pydanticモデルの各属性には型があります。
 
 しかし、その型はそれ自体が別のPydanticモデルである可能性があります。
 
-そのため、特定の属性名、型、バリデーションを指定して、深くネストしたJSON`object`を宣言することができます。
+そのため、特定の属性名、型、バリデーションを指定して、深くネストしたJSON「オブジェクト」を宣言することができます。
 
 すべては、任意のネストにされています。
 
-### サブモデルの定義
+### サブモデルの定義 { #define-a-submodel }
 
 例えば、`Image`モデルを定義することができます:
 
-{* ../../docs_src/body_nested_models/tutorial004.py hl[9,10,11] *}
+{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[7:9] *}
 
-### サブモデルを型として使用
+### サブモデルを型として使用 { #use-the-submodel-as-a-type }
 
 そして、それを属性の型として使用することができます:
 
-{* ../../docs_src/body_nested_models/tutorial004.py hl[20] *}
+{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[18] *}
 
 これは **FastAPI** が以下のようなボディを期待することを意味します:
 
@@ -102,23 +92,23 @@ Pydanticモデルの各属性には型があります。
 * データの検証
 * 自動文書化
 
-## 特殊な型とバリデーション
+## 特殊な型とバリデーション { #special-types-and-validation }
 
-`str`ã\82\84`int`ã\80\81`float`ã\81®ã\82\88ã\81\86ã\81ª通常の単数型の他にも、`str`を継承したより複雑な単数型を使うこともできます。
+`str`ã\82\84`int`ã\80\81`float`ã\81ªã\81©ã\81®通常の単数型の他にも、`str`を継承したより複雑な単数型を使うこともできます。
 
-すべてのオプションをみるには、<a href="https://docs.pydantic.dev/latest/concepts/types/" class="external-link" target="_blank">Pydanticのエキゾチック な型</a>のドキュメントを確認してください。次の章でいくつかの例をみることができます。
+すべてのオプションをみるには、<a href="https://docs.pydantic.dev/latest/concepts/types/" class="external-link" target="_blank">Pydanticの型の概要</a>を確認してください。次の章でいくつかの例をみることができます。
 
-ä¾\8bã\81\88ã\81°ã\80\81`Image`ã\83¢ã\83\87ã\83«ã\81®ã\82\88ã\81\86ã\81«`url`ã\83\95ã\82£ã\83¼ã\83«ã\83\89ã\81\8cã\81\82ã\82\8bå ´å\90\88ã\80\81`str`ã\81®ä»£ã\82\8fã\82\8aã\81«Pydanticã\81®`HttpUrl`ã\82\92æ\8c\87å®\9aすることができます:
+ä¾\8bã\81\88ã\81°ã\80\81`Image`ã\83¢ã\83\87ã\83«ã\81®ã\82\88ã\81\86ã\81«`url`ã\83\95ã\82£ã\83¼ã\83«ã\83\89ã\81\8cã\81\82ã\82\8bå ´å\90\88ã\80\81`str`ã\81®ä»£ã\82\8fã\82\8aã\81«Pydanticã\81®`HttpUrl`ã\81®ã\82¤ã\83³ã\82¹ã\82¿ã\83³ã\82¹ã\81¨ã\81\97ã\81¦å®£è¨\80することができます:
 
-{* ../../docs_src/body_nested_models/tutorial005.py hl[4,10] *}
+{* ../../docs_src/body_nested_models/tutorial005_py310.py hl[2,8] *}
 
-文字列は有効なURLであることが確認され、そのようにJSONスキーマ・OpenAPIで文書化されます。
+文字列は有効なURLであることが確認され、そのようにJSON Schema / OpenAPIで文書化されます。
 
-## サブモデルのリストを持つ属性
+## サブモデルのリストを持つ属性 { #attributes-with-lists-of-submodels }
 
 Pydanticモデルを`list`や`set`などのサブタイプとして使用することもできます:
 
-{* ../../docs_src/body_nested_models/tutorial006.py hl[20] *}
+{* ../../docs_src/body_nested_models/tutorial006_py310.py hl[18] *}
 
 これは、次のようなJSONボディを期待します(変換、検証、ドキュメントなど):
 
@@ -152,59 +142,59 @@ Pydanticモデルを`list`や`set`などのサブタイプとして使用する
 
 ///
 
-## 深くネストされたモデル
+## 深くネストされたモデル { #deeply-nested-models }
 
 深くネストされた任意のモデルを定義することができます:
 
-{* ../../docs_src/body_nested_models/tutorial007.py hl[9,14,20,23,27] *}
+{* ../../docs_src/body_nested_models/tutorial007_py310.py hl[7,12,18,21,25] *}
 
 /// info | 情報
 
-`Offer`は`Item`のリストであり、オプションの`Image`のリストを持っていることに注目してください。
+`Offer`ã\81¯`Item`ã\81®ã\83ªã\82¹ã\83\88ã\81§ã\81\82ã\82\8aã\80\81ã\81\9dã\82\8cã\82\89ã\81\8cã\81\95ã\82\89ã\81«ã\82ªã\83\97ã\82·ã\83§ã\83³ã\81®`Image`ã\81®ã\83ªã\82¹ã\83\88ã\82\92æ\8c\81ã\81£ã\81¦ã\81\84ã\82\8bã\81\93ã\81¨ã\81«æ³¨ç\9b®ã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82
 
 ///
 
-## 純粋なリストのボディ
+## 純粋なリストのボディ { #bodies-of-pure-lists }
 
 期待するJSONボディのトップレベルの値がJSON`array`(Pythonの`list`)であれば、Pydanticモデルと同じように、関数のパラメータで型を宣言することができます:
 
 ```Python
-images: List[Image]
+images: list[Image]
 ```
 
 以下のように:
 
-{* ../../docs_src/body_nested_models/tutorial008.py hl[15] *}
+{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
 
-## あらゆる場所でのエディタサポート
+## あらゆる場所でのエディタサポート { #editor-support-everywhere }
 
\82¨ã\83\87ã\82£ã\82¿ã\81®ã\82µã\83\9dã\83¼ã\83\88ã\82\82ã\81©ã\81\93ã\81§ã\82\82å\8f\97ã\81\91ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dます。
\81\9dã\81\97ã\81¦ã\80\81ã\81\82ã\82\89ã\82\86ã\82\8bå ´æ\89\80ã\81§ã\82¨ã\83\87ã\82£ã\82¿ã\82µã\83\9dã\83¼ã\83\88ã\82\92å¾\97ã\82\89ã\82\8cます。
 
 以下のようにリストの中の項目でも:
 
-<img src="https://fastapi.tiangolo.com/img/tutorial/body-nested-models/image01.png">
+<img src="/img/tutorial/body-nested-models/image01.png">
 
 Pydanticモデルではなく、`dict`を直接使用している場合はこのようなエディタのサポートは得られません。
 
-しかし、それらについて心配する必要はありません。入力された辞書は自動的に変換され、出力も自動的にJSONに変換されます。
+しかし、それらについて心配する必要はありません。入力されたdictは自動的に変換され、出力も自動的にJSONに変換されます。
 
-## 任意の`dict`のボディ
+## 任意の`dict`のボディ { #bodies-of-arbitrary-dicts }
 
 また、ある型のキーと別の型の値を持つ`dict`としてボディを宣言することもできます。
 
-有効なフィールド・属性名を事前に知る必要がありません(Pydanticモデルの場合のように)。
+この方法で、有効なフィールド/属性名を事前に知る必要がありません(Pydanticモデルの場合のように)。
 
\81\93ã\82\8cã\81¯ã\80\81ã\81¾ã\81 ç\9f¥ã\82\89ã\81ªã\81\84ã\82­ã\83¼ã\82\92å\8f\97ã\81\91å\8f\96ã\82\8aã\81\9fã\81\84ã\81¨ã\81\8dã\81«ä¾¿å\88©ã\81 ã\81¨æ\80\9dã\81\84ã\81¾す。
\81\93ã\82\8cã\81¯ã\80\81ã\81¾ã\81 ç\9f¥ã\82\89ã\81ªã\81\84ã\82­ã\83¼ã\82\92å\8f\97ã\81\91å\8f\96ã\82\8aã\81\9fã\81\84ã\81¨ã\81\8dã\81«ä¾¿å\88©ã\81§す。
 
 ---
 
-他にも、`int`のように他の型のキーを持ちたい場合などに便利です。
+もうひとつ便利なケースは、別の型(例: `int`)のキーを持ちたい場合です。
 
\81\9dã\82\8cã\82\92ã\81\93ã\81\93ã\81§è¦\8bã\81¦ã\81\84ã\81\8dã\81¾ã\81\97ã\82\87ã\81\86
\81\9dã\82\8cã\82\92ã\81\93ã\81\93ã\81§è¦\8bã\81¦ã\81\84ã\81\8dã\81¾ã\81\99
 
 この場合、`int`のキーと`float`の値を持つものであれば、どんな`dict`でも受け入れることができます:
 
-{* ../../docs_src/body_nested_models/tutorial009.py hl[15] *}
+{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
 
 /// tip | 豆知識
 
@@ -218,14 +208,14 @@ JSONはキーとして`str`しかサポートしていないことに注意し
 
 ///
 
-## まとめ
+## まとめ { #recap }
 
 **FastAPI** を使用すると、Pydanticモデルが提供する最大限の柔軟性を持ちながら、コードをシンプルに短く、エレガントに保つことができます。
 
-以下のような利点があります:
+しかし、以下のような利点があります:
 
 * エディタのサポート(どこでも補完!)
-* データ変換(別名:構文解析シリアライズ)
+* データ変換(別名:構文解析 / シリアライズ)
 * データの検証
 * スキーマ文書
-* 自動文書化
+* 自動ドキュメント
index ffbe52e1db200ba466a4f4fab1f6c753054d0983..e888d5a0d9eb14f396f47aef4741477713c9fb50 100644 (file)
@@ -1,16 +1,16 @@
-# ボディ - 更新
+# ボディ - 更新 { #body-updates }
 
-## `PUT`による置換での更新
+## `PUT`による置換での更新 { #update-replacing-with-put }
 
 項目を更新するには<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT" class="external-link" target="_blank">HTTPの`PUT`</a>操作を使用することができます。
 
-`jsonable_encoder`を用いて、入力データをJSON形式で保存できるデータに変換することができます(例:NoSQLデータベース)。例えば、`datetime`を`str`に変換します。
+`jsonable_encoder`を用いて、入力データをJSONとして保存できるデータに変換することができます(例:NoSQLデータベース)。例えば、`datetime`を`str`に変換します。
 
-{* ../../docs_src/body_updates/tutorial001.py hl[30,31,32,33,34,35] *}
+{* ../../docs_src/body_updates/tutorial001_py310.py hl[28:33] *}
 
-既存のデータを置き換えるべきデータを受け取るために`PUT`は使用されます。
+`PUT`は、既存のデータを置き換えるべきデータを受け取るために使用されます。
 
-### 置換についての注意
+### 置換についての注意 { #warning-about-replacing }
 
 つまり、`PUT`を使用して以下のボディで項目`bar`を更新したい場合は:
 
 }
 ```
 
\81\99ã\81§ã\81«æ ¼ç´\8dã\81\95ã\82\8cã\81¦ã\81\84ã\82\8bå±\9eæ\80§`"tax": 20.2`ã\82\92å\90«ã\81¾ã\81ªã\81\84ã\81\9fã\82\81ã\80\81å\85¥å\8a\9bã\83¢ã\83\87ã\83«ã\81®ã\83\87ã\83\95ã\82©ã\83«ã\83\88å\80¤ã\81¯`"tax": 10.5`ã\81§す。
\81\99ã\81§ã\81«æ ¼ç´\8dã\81\95ã\82\8cã\81¦ã\81\84ã\82\8bå±\9eæ\80§`"tax": 20.2`ã\82\92å\90«ã\81¾ã\81ªã\81\84ã\81\9fã\82\81ã\80\81å\85¥å\8a\9bã\83¢ã\83\87ã\83«ã\81¯`"tax": 10.5`ã\81®ã\83\87ã\83\95ã\82©ã\83«ã\83\88å\80¤ã\82\92å\8f\96ã\82\8aã\81¾す。
 
 そして、データはその「新しい」`10.5`の`tax`と共に保存されます。
 
-## `PATCH`による部分的な更新
+## `PATCH`による部分的な更新 { #partial-updates-with-patch }
 
 また、<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH" class="external-link" target="_blank">HTTPの`PATCH`</a>操作でデータを*部分的に*更新することもできます。
 
 
 ///
 
-### Pydanticの`exclude_unset`パラメータの使用
+### Pydanticの`exclude_unset`パラメータの使用 { #using-pydantics-exclude-unset-parameter }
 
-部分的な更新を受け取りたい場合は、Pydanticモデルの`.dict()`の`exclude_unset`パラメータを使用すると非常に便利です。
+部分的な更新を受け取りたい場合は、Pydanticモデルの`.model_dump()`の`exclude_unset`パラメータを使用すると非常に便利です。
 
-`item.dict(exclude_unset=True)`のように。
+`item.model_dump(exclude_unset=True)`のように。
 
 これにより、`item`モデルの作成時に設定されたデータのみを持つ`dict`が生成され、デフォルト値は除外されます。
 
 これを使うことで、デフォルト値を省略して、設定された(リクエストで送られた)データのみを含む`dict`を生成することができます:
 
-{* ../../docs_src/body_updates/tutorial002.py hl[34] *}
+{* ../../docs_src/body_updates/tutorial002_py310.py hl[32] *}
 
-### Pydanticの`update`パラメータ
+### Pydanticの`update`パラメータの使用 { #using-pydantics-update-parameter }
 
-ここで、`.copy()`を用いて既存のモデルのコピーを作成し、`update`パラメータに更新するデータを含む`dict`を渡すことができます。
+ここで、`.model_copy()`を用いて既存のモデルのコピーを作成し、`update`パラメータに更新するデータを含む`dict`を渡すことができます。
 
-`stored_item_model.copy(update=update_data)`のように:
+`stored_item_model.model_copy(update=update_data)`のように:
 
-{* ../../docs_src/body_updates/tutorial002.py hl[35] *}
+{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
 
-### 部分的更新のまとめ
+### 部分的更新のまとめ { #partial-updates-recap }
 
 まとめると、部分的な更新を適用するには、次のようにします:
 
     * この方法では、モデル内のデフォルト値ですでに保存されている値を上書きするのではなく、ユーザーが実際に設定した値のみを更新することができます。
 * 保存されているモデルのコピーを作成し、受け取った部分的な更新で属性を更新します(`update`パラメータを使用します)。
 * コピーしたモデルをDBに保存できるものに変換します(例えば、`jsonable_encoder`を使用します)。
-    * これはモデルの`.dict()`メソッドを再度利用することに匹敵しますが、値をJSONに変換できるデータ型、例えば`datetime`を`str`に変換します。
+    * これはモデルの`.model_dump()`メソッドを再度利用することに匹敵しますが、値をJSONに変換できるデータ型になるようにし(変換し)、例えば`datetime`を`str`に変換します。
 * データをDBに保存します。
 * 更新されたモデルを返します。
 
-{* ../../docs_src/body_updates/tutorial002.py hl[30,31,32,33,34,35,36,37] *}
+{* ../../docs_src/body_updates/tutorial002_py310.py hl[28:35] *}
 
 /// tip | 豆知識
 
index 1298eec7eb6ad6e6062b0ff332fdec437e8f0981..a219faed046babb674fc6d67f7da88b56ae85f06 100644 (file)
@@ -1,40 +1,41 @@
-# リクエストボディ
+# リクエストボディ { #request-body }
 
-クライアント (ブラウザなど) からAPIにデータを送信する必要があるとき、データを **リクエストボディ (request body)** として送ります。
+クライアント(例えばブラウザ)からAPIにデータを送信する必要がある場合、**リクエストボディ**として送信します。
 
-**リクエスト** ボディはクライアントによってAPIへ送られます。**レスポンス** ボディはAPIがクライアントに送るデータです。
+**リクエスト**ボディは、クライアントからAPIへ送信されるデータです。**レスポンス**ボディは、APIがクライアントに送信するデータです。
 
-APIはほとんどの場合 **レスポンス** ボディを送らなければなりません。しかし、クライアントは必ずしも **リクエスト** ボディを送らなければいけないわけではありません
+APIはほとんどの場合 **レスポンス** ボディを送信する必要があります。しかしクライアントは、常に **リクエストボディ** を送信する必要があるとは限りません。場合によっては、クエリパラメータ付きのパスだけをリクエストして、ボディを送信しないこともあります
 
-**リクエスト** ボディを宣言するために <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> モデルを使用します。そして、その全てのパワーとメリットを利用します。
+**リクエスト**ボディを宣言するには、<a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> モデルを使用し、その強力な機能とメリットをすべて利用します。
 
 /// info | 情報
 
-データを送るには、`POST` (もっともよく使われる)、`PUT`、`DELETE` または `PATCH` を使うべきです。
+データを送信するには、`POST`(より一般的)、`PUT`、`DELETE`、`PATCH` のいずれかを使用すべきです。
 
-GET リクエストでボディを送信することは、仕様では未定義の動作ですが、FastAPI でサポートされており、非常に複雑な(極端な)ユースケースにのみ対応しています。
+`GET` リクエストでボディを送信することは仕様上は未定義の動作ですが、それでもFastAPIではサポートされています。ただし、非常に複雑/極端なユースケースのためだけです。
 
-非推奨なので、Swagger UIを使った対話型のドキュメントにはGETのボディ情報は表示されません。さらに、中継するプロキシが対応していない可能性があります。
+推奨されないため、Swagger UIによる対話的ドキュメントでは `GET` 使用時のボディのドキュメントは表示されず、途中のプロキシが対応していない可能性もあります。
 
 ///
 
-## Pydanticの `BaseModel` をインポート
+## Pydanticの `BaseModel` をインポート { #import-pydantics-basemodel }
 
\81¾ã\81\99å\88\9dã\82\81ã\81«ã\80\81 `pydantic` から `BaseModel` をインポートする必要があります:
\81¾ã\81\9aã\80\81`pydantic` から `BaseModel` をインポートする必要があります:
 
-{* ../../docs_src/body/tutorial001.py hl[4] *}
+{* ../../docs_src/body/tutorial001_py310.py hl[2] *}
 
-## データモデルの作成
+## データモデルの作成 { #create-your-data-model }
 
-そして、`BaseModel` を継承したクラスとしてデータモデルを宣言します。
+次に、`BaseModel` を継承するクラスとしてデータモデルを宣言します。
 
-すべての属性にpython標準の型を使用します:
+すべての属性に標準のPython型を使用します:
 
-{* ../../docs_src/body/tutorial001.py hl[7:11] *}
+{* ../../docs_src/body/tutorial001_py310.py hl[5:9] *}
 
-クエリパラメータの宣言と同様に、モデル属性がデフォルト値をもつとき、必須な属性ではなくなります。それ以外は必須になります。オプショナルな属性にしたい場合は `None` を使用してください。
 
-例えば、上記のモデルは以下の様なJSON「`オブジェクト`」(もしくはPythonの `dict` ) を宣言しています:
+クエリパラメータの宣言と同様に、モデル属性がデフォルト値を持つ場合は必須ではありません。そうでなければ必須です。単にオプションにするには `None` を使用してください。
+
+例えば、上記のモデルは次のようなJSON「`object`」(またはPythonの `dict`)を宣言します:
 
 ```JSON
 {
@@ -45,7 +46,7 @@ GET リクエストでボディを送信することは、仕様では未定義
 }
 ```
 
-...`description` ã\81¨ `tax` ã\81¯ã\82ªã\83\97ã\82·ã\83§ã\83\8aã\83« (ã\83\87ã\83\95ã\82©ã\83«ã\83\88å\80¤ã\81¯ `None`) ã\81ªã\81®ã\81§ã\80\81以ä¸\8bã\81®JSONã\80\8c\82ªã\83\96ã\82¸ã\82§ã\82¯ã\83\88`」も有効です:
+...`description` ã\81¨ `tax` ã\81¯ã\82ªã\83\97ã\82·ã\83§ã\83³ï¼\88ã\83\87ã\83\95ã\82©ã\83«ã\83\88å\80¤ã\81\8c `None`ï¼\89ã\81ªã\81®ã\81§ã\80\81ã\81\93ã\81®JSONã\80\8c`object`」も有効です:
 
 ```JSON
 {
@@ -54,109 +55,112 @@ GET リクエストでボディを送信することは、仕様では未定義
 }
 ```
 
-## パラメータとして宣言
+## パラメータとして宣言 { #declare-it-as-a-parameter }
 
-*パスオペレーション* に加えるために、パスパラメータやクエリパラメータと同じ様に宣言します:
+*path operation* に追加するには、パスパラメータやクエリパラメータを宣言したのと同じ方法で宣言します:
 
-{* ../../docs_src/body/tutorial001.py hl[18] *}
+{* ../../docs_src/body/tutorial001_py310.py hl[16] *}
 
-...ã\81\9dã\81\97ã\81¦ã\80\81ä½\9cæ\88\90ã\81\97ã\81\9fã\83¢ã\83\87ã\83« `Item` ã\81§å\9e\8bã\82\92宣言します。
+...ã\81\9dã\81\97ã\81¦ã\80\81ä½\9cæ\88\90ã\81\97ã\81\9fã\83¢ã\83\87ã\83« `Item` ã\82\92å\9e\8bã\81¨ã\81\97ã\81¦宣言します。
 
-## 結果
+## 結果 { #results }
 
\81\9dã\81®Pythonã\81®å\9e\8b宣è¨\80ã\81 ã\81\91ã\81§ **FastAPI** ã\81¯ä»¥ä¸\8bã\81®ã\81\93ã\81¨ã\82\92è¡\8cã\81\84ã\81¾ã\81\99:
+そのPythonの型宣言だけで **FastAPI** は以下を行います:
 
-* リクエストボディをJSONとして読み取ります。
-* 適当な型に変換します(必要な場合)。
+* ã\83ªã\82¯ã\82¨ã\82¹ã\83\88ã\81®ã\83\9cã\83\87ã\82£ã\82\92JSONã\81¨ã\81\97ã\81¦èª­ã\81¿å\8f\96ã\82\8aã\81¾ã\81\99ã\80\82
+* 対応する型に変換します(必要な場合)。
 * データを検証します。
-    * データが無効な場合は、明確なエラーが返され、どこが不正なデータであったかを示します。
-* 受け取ったデータをパラメータ `item` に変換します。
-    * é\96¢æ\95°å\86\85ã\81§ `Item` å\9e\8bã\81§ã\81\82ã\82\8bã\81¨å®£è¨\80ã\81\97ã\81\9fã\81®ã\81§ã\80\81ã\81\99ã\81¹ã\81¦ã\81®å±\9eæ\80§ã\81¨ã\81\9dã\81®å\9e\8bã\81«å¯¾ã\81\99ã\82\8bã\82¨ã\83\87ã\82£ã\82¿ã\82µã\83\9dã\83¼ã\83\88ï¼\88è£\9cå®\8cã\81ªã\81©ï¼\89ã\82\92ã\81\99ã\81¹ã\81¦ä½¿用できます。
-* モデルの<a href="http://json-schema.org" class="external-link" target="_blank">JSONスキーマ</a>定義を生成し、好きな場所で使用することができます。
-* ã\81\93ã\82\8cã\82\89ã\81®ã\82¹ã\82­ã\83¼ã\83\9eã\81¯ã\80\81ç\94\9fæ\88\90ã\81\95ã\82\8cã\81\9fOpenAPIã\82¹ã\82­ã\83¼ã\83\9eã\81®ä¸\80é\83¨ã\81¨ã\81ªã\82\8aã\80\81è\87ªå\8b\95ã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88ã\81®<abbr title = "User Interfaces">UI</abbr>ã\81«使用されます。
+    * データが無効な場合は、どこで何が不正なデータだったのかを正確に示す、分かりやすい明確なエラーを返します。
+* 受け取ったデータをパラメータ `item` にします。
+    * é\96¢æ\95°å\86\85ã\81§ `Item` å\9e\8bã\81¨ã\81\97ã\81¦å®£è¨\80ã\81\97ã\81\9fã\81\9fã\82\81ã\80\81ã\81\99ã\81¹ã\81¦ã\81®å±\9eæ\80§ã\81¨ã\81\9dã\81®å\9e\8bã\81«ã\81¤ã\81\84ã\81¦ã\80\81ã\82¨ã\83\87ã\82£ã\82¿ã\82µã\83\9dã\83¼ã\83\88ï¼\88è£\9cå®\8cã\81ªã\81©ï¼\89ã\82\82å\88©用できます。
+* モデル向けの <a href="https://json-schema.org" class="external-link" target="_blank">JSON Schema</a> 定義を生成します。プロジェクトにとって意味があるなら、他の場所でも好きなように利用できます。
+* ã\81\9dã\82\8cã\82\89ã\81®ã\82¹ã\82­ã\83¼ã\83\9eã\81¯ç\94\9fæ\88\90ã\81\95ã\82\8cã\82\8bOpenAPIã\82¹ã\82­ã\83¼ã\83\9eã\81®ä¸\80é\83¨ã\81¨ã\81ªã\82\8aã\80\81è\87ªå\8b\95ã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88ã\81® <abbr title="User Interfaces">UIs</abbr> ã\81§使用されます。
 
-## 自動ドキュメント生成
+## 自動ドキュメント { #automatic-docs }
 
-モデルのJSONスキーマはOpenAPIで生成されたスキーマの一部になり、対話的なAPIドキュメントに表示されます:
+モデルのJSON Schemaは、OpenAPIで生成されたスキーマの一部になり、対話的なAPIドキュメントに表示されます:
 
 <img src="/img/tutorial/body/image01.png">
 
\81\9dã\81\97ã\81¦ã\80\81ã\81\9dã\82\8cã\82\89ã\81\8c使ã\82\8fã\82\8cã\82\8b *ã\83\91ã\82¹ã\82ªã\83\9aã\83¬ã\83¼ã\82·ã\83§ã\83³* ã\81®ã\81\9dã\82\8cã\81\9eã\82\8cã\81®APIã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88ã\81«ã\82\82表示されます:
\81¾ã\81\9fã\80\81ã\81\9dã\82\8cã\82\89ã\81\8cå¿\85è¦\81ã\81ªå\90\84 *path operation* å\86\85ã\81®APIã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88ã\81§ã\82\82使ç\94¨されます:
 
 <img src="/img/tutorial/body/image02.png">
 
-## ã\82¨ã\83\87ã\82£ã\82¿ã\83¼ã\82µã\83\9dã\83¼ã\83\88
+## ã\82¨ã\83\87ã\82£ã\82¿ã\82µã\83\9dã\83¼ã\83\88 { #editor-support }
 
-エディターによる型ヒントと補完が関数内で利用できます (Pydanticモデルではなく `dict` を受け取ると、同じサポートは受けられません):
+エディタ上で、関数内のあらゆる場所で型ヒントと補完が得られます(Pydanticモデルの代わりに `dict` を受け取った場合は起きません):
 
 <img src="/img/tutorial/body/image03.png">
 
-型によるエラーチェックも可能です:
+不正な型操作に対するエラーチェックも得られます:
 
 <img src="/img/tutorial/body/image04.png">
 
\81\93ã\82\8cã\81¯å\81¶ç\84¶ã\81§ã\81¯ã\81ªã\81\8fã\80\81ã\81\93ã\81®ã\83\87ã\82¶ã\82¤ã\83³ã\81«å\9fºã\81¥ã\81\84ã\81¦ã\83\95ã\83¬ã\83¼ã\83 ã\83¯ã\83¼ã\82¯ã\81\8cä½\9cã\82\89れています。
\81\93ã\82\8cã\81¯å\81¶ç\84¶ã\81§ã\81¯ã\81ªã\81\8fã\80\81ã\83\95ã\83¬ã\83¼ã\83 ã\83¯ã\83¼ã\82¯å\85¨ä½\93ã\81\8cã\81\9dã\81®è¨­è¨\88ã\82\92中å¿\83ã\81«æ§\8bç¯\89ã\81\95れています。
 
-全てのエディターで機能することを確認するために、実装前の設計時に徹底的にテストしました。
+そして、すべてのエディタで動作することを確実にするために、実装前の設計フェーズで徹底的にテストされました。
 
-これをサポートするためにPydantic自体にもいくつかの変更がありました。
+これをサポートするために、Pydantic自体にもいくつかの変更が加えられました。
 
-上記のスクリーンショットは<a href="https://code.visualstudio.com" class="external-link" target="_blank">Visual Studio Code</a>を撮ったものです。
+前述のスクリーンショットは <a href="https://code.visualstudio.com" class="external-link" target="_blank">Visual Studio Code</a> で撮影されたものです。
 
\81\97ã\81\8bã\81\97ã\80\81<a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>ã\82\84ã\81»ã\81¨ã\82\93ã\81©ã\81®Pythonã\82¨ã\83\87ã\82£ã\82¿ã\81§ã\82\82å\90\8cæ§\98ã\81ªã\82¨ã\83\87ã\82£ã\82¿ã\83¼ã\82µã\83\9dã\83¼ã\83\88ã\82\92å\8f\97ã\81\91られます:
\81\9fã\81 ã\81\97ã\80\81<a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> ã\82\84ã\80\81ä»\96ã\81®ã\81»ã\81¨ã\82\93ã\81©ã\81®Pythonã\82¨ã\83\87ã\82£ã\82¿ã\81§ã\82\82å\90\8cã\81\98ã\82¨ã\83\87ã\82£ã\82¿ã\82µã\83\9dã\83¼ã\83\88ã\82\92å¾\97られます:
 
 <img src="/img/tutorial/body/image05.png">
 
 /// tip | 豆知識
 
-<a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>エディタを使用している場合は、<a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Pydantic PyCharm Plugin</a>が使用可能です。
+エディタとして <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> を使用している場合、<a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Pydantic PyCharm Plugin</a> を使用できます。
 
-以ä¸\8bã\81®ã\82¨ã\83\87ã\82£ã\82¿ã\83¼ã\82µã\83\9dã\83¼ã\83\88ã\81\8cå¼·å\8c\96されます:
+以ä¸\8bã\81«ã\82\88ã\82\8aã\80\81Pydanticã\83¢ã\83\87ã\83«ã\81«å¯¾ã\81\99ã\82\8bã\82¨ã\83\87ã\82£ã\82¿ã\82µã\83\9dã\83¼ã\83\88ã\81\8cæ\94¹å\96\84されます:
 
-* 自動補完
-* 型チェック
-* リファクタリング
-* 検索
-* インスペクション
+* auto-completion
+* type checks
+* refactoring
+* searching
+* inspections
 
 ///
 
-## ã\83¢ã\83\87ã\83«ã\81®ä½¿ç\94¨
+## ã\83¢ã\83\87ã\83«ã\82\92使ç\94¨ã\81\99ã\82\8b { #use-the-model }
 
-関数内部で、モデルの全ての属性に直接アクセスできます:
+関数内では、モデルオブジェクトのすべての属性に直接アクセスできます:
 
-{* ../../docs_src/body/tutorial002.py hl[21] *}
+{* ../../docs_src/body/tutorial002_py310.py *}
 
-## リクエストボディ + パスパラメータ
+## リクエストボディ + パスパラメータ { #request-body-path-parameters }
 
 パスパラメータとリクエストボディを同時に宣言できます。
 
-**FastAPI** はパスパラメータである関数パラメータは**パスから受け取り**、Pydanticモデルによって宣言された関数パラメータは**リクエストボディから受け取る**ということを認識します。
+**FastAPI** は、パスパラメータに一致する関数パラメータは **パスから取得** し、Pydanticモデルとして宣言された関数パラメータは **リクエストボディから取得** すべきだと認識します。
+
+{* ../../docs_src/body/tutorial003_py310.py hl[15:16] *}
 
-{* ../../docs_src/body/tutorial003.py hl[17:18] *}
 
-## リクエストボディ + パスパラメータ + クエリパラメータ
+## リクエストボディ + パス + クエリパラメータ { #request-body-path-query-parameters }
 
-また、**ボディ**と**パス**と**クエリ**のパラメータも同時に宣言できます。
+**body**、**path**、**query** パラメータもすべて同時に宣言できます。
 
-**FastAPI** はそれぞれを認識し、適切な場所からデータを取得します。
+**FastAPI** はそれぞれを認識し、正しい場所からデータを取得します。
 
-{* ../../docs_src/body/tutorial004.py hl[18] *}
+{* ../../docs_src/body/tutorial004_py310.py hl[16] *}
 
-関数パラメータは以下のに認識されます:
+関数パラメータは以下のように認識されます:
 
-* パラメータが**パス**で宣言されている場合は、優先的にパスパラメータとして扱われます。
-* パラメータが**単数型** (`int`、`float`、`str`、`bool` など)の場合は**クエリ**パラメータとして解釈されます。
-* パラメータが **Pydantic モデル**型で宣言された場合、リクエスト**ボディ**として解釈されます。
+* パラメータが **path** でも宣言されている場合、パスパラメータとして使用されます。
+* パラメータが **単数型**(`int`、`float`、`str`、`bool` など)の場合、**query** パラメータとして解釈されます。
+* パラメータが **Pydanticモデル** の型として宣言されている場合、リクエスト **body** として解釈されます。
 
 /// note | 備考
 
-FastAPIは、`= None`があるおかげで、`q`がオプショナルだとわかります。
+FastAPIは、デフォルト値 `= None` があるため、`q` の値が必須ではないことを認識します。
+
+`str | None`(Python 3.10+)や `Union[str, None]`(Python 3.9+)の `Union` は、値が必須ではないことを判断するためにFastAPIでは使用されません。`= None` というデフォルト値があるため、必須ではないことを認識します。
 
-`Optional[str]` の`Optional` はFastAPIでは使用されていません(FastAPIは`str`の部分のみ使用します)。しかし、`Optional[str]` はエディタがコードのエラーを見つけるのを助けてくれます。
+しかし、型アノテーションを追加すると、エディタがより良いサポートを提供し、エラーを検出できるようになります。
 
 ///
 
-## Pydanticを使わない方法
+## Pydanticを使わない方法 { #without-pydantic }
 
-もしPydanticモデルを使用したくない場合は、**Body**パラメータが利用できます。[Body - Multiple Parameters: Singular values in body](body-multiple-params.md#_2){.internal-link target=_blank}を確認してください。
+Pydanticモデルを使いたくない場合は、**Body** パラメータも使用できます。[Body - Multiple Parameters: Singular values in body](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank} のドキュメントを参照してください。
index 8285f44efd996bdd55c9bf41e60dccb91b493ed4..10ffb2566e6043e8d09d1f92995992de081f4af6 100644 (file)
@@ -1,8 +1,8 @@
-# クッキーパラメータモデル
+# クッキーパラメータモデル { #cookie-parameter-models }
 
 もし関連する**複数のクッキー**から成るグループがあるなら、それらを宣言するために、**Pydanticモデル**を作成できます。🍪
 
\81\93ã\81\86ã\81\99ã\82\8bã\81\93ã\81¨ã\81§ã\80\81**è¤\87æ\95°ã\81®å ´æ\89\80**ã\81§**ã\81\9dã\81®Pydanticã\83¢ã\83\87ã\83«ã\82\92å\86\8då\88©ç\94¨**ã\81§ã\81\8dã\80\81ã\83\90ã\83ªã\83\87ã\83¼ã\82·ã\83§ã\83³ã\82\84ã\83¡ã\82¿ã\83\87ã\83¼ã\82¿ã\82\92ã\80\81ã\81\99ã\81¹ã\81¦ã\81®ã\82¯ã\83\83ã\82­ã\83¼ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81«å¯¾ã\81\97ã\81¦ä¸\80度ã\81«å®£è¨\80ã\81§ã\81\8dã\81¾ã\81\99ã\80\82ð\9f\98\8e
+こうすることで、**複数の場所**で**そのPydanticモデルを再利用**でき、バリデーションやメタデータを、すべてのパラメータに対して一度に宣言できます。😎
 
 /// note | 備考
 
 
 ///
 
-## クッキーにPydanticモデルを使用する
+## Pydanticモデルを使用したクッキー { #cookies-with-a-pydantic-model }
 
-å¿\85è¦\81ã\81ªè¤\87æ\95°ã\81®**ã\82¯ã\83\83ã\82­ã\83¼**ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\82\92**Pydanticã\83¢ã\83\87ã\83«**ã\81§å®£è¨\80ã\81\97ã\80\81ã\81\95ã\82\89ã\81«ã\80\81ã\81\9dã\82\8cを `Cookie` として宣言しましょう:
+å¿\85è¦\81ã\81ªè¤\87æ\95°ã\81®**ã\82¯ã\83\83ã\82­ã\83¼**ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\82\92**Pydanticã\83¢ã\83\87ã\83«**ã\81§å®£è¨\80ã\81\97ã\80\81ã\81\95ã\82\89ã\81«ã\80\81ã\83\91ã\83©ã\83¡ã\83¼ã\82¿を `Cookie` として宣言しましょう:
 
 {* ../../docs_src/cookie_param_models/tutorial001_an_py310.py hl[9:12,16] *}
 
-**FastAPI**ã\81¯ã\80\81ã\83ªã\82¯ã\82¨ã\82¹ã\83\88ã\81®**ã\82¯ã\83\83ã\82­ã\83¼**ã\81\8bã\82\89**ã\81\9dã\82\8cã\81\9eã\82\8cã\81®ã\83\95ã\82£ã\83¼ã\83«ã\83\89**ã\81®ã\83\87ã\83¼ã\82¿ã\82\92**æ\8a½å\87º**ã\81\97ã\80\81å®\9a義ã\81\95ã\82\8cã\81\9f**Pydanticã\83¢ã\83\87ã\83«**を提供します。
+**FastAPI**ã\81¯ã\80\81ã\83ªã\82¯ã\82¨ã\82¹ã\83\88ã\81§å\8f\97ã\81\91å\8f\96ã\81£ã\81\9f**ã\82¯ã\83\83ã\82­ã\83¼**ã\81\8bã\82\89**ã\81\9dã\82\8cã\81\9eã\82\8cã\81®ã\83\95ã\82£ã\83¼ã\83«ã\83\89**ã\81®ã\83\87ã\83¼ã\82¿ã\82\92**æ\8a½å\87º**ã\81\97ã\80\81å®\9a義ã\81\97ã\81\9fPydanticã\83¢ã\83\87ã\83«を提供します。
 
-## ドキュメントの確認
+## ドキュメントの確認 { #check-the-docs }
 
 対話的APIドキュメントUI `/docs` で、定義されているクッキーを確認できます:
 
 <img src="/img/tutorial/cookie-param-models/image01.png">
 </div>
 
-/// info | 備考
-
+/// info | 情報
 
 **ブラウザがクッキーを処理し**ていますが、特別な方法で内部的に処理を行っているために、**JavaScript**からは簡単に操作**できない**ことに留意してください。
 
-**対話的APIドキュメントUI** `/docs` にアクセスすれば、*パスオペレーション*に関するクッキーの**ドキュメンテーション**を確認できます。
+**APIドキュメントUI** `/docs` にアクセスすれば、*path operation*に関するクッキーの**ドキュメンテーション**を確認できます。
 
\81\97ã\81\8bã\81\97ã\80\81ã\81\9fã\81¨ã\81\88**ã\82¯ã\83\83ã\82­ã\83¼ã\83\87ã\83¼ã\82¿ã\82\92å\85¥å\8a\9bã\81\97ã\81¦**ã\80\8cExecuteã\80\8dã\82\92ã\82¯ã\83ªã\83\83ã\82¯ã\81\97ã\81¦ã\82\82ã\80\81対話ç\9a\84APIドキュメントUIは**JavaScript**で動作しているためクッキーは送信されず、まるで値を入力しなかったかのような**エラー**メッセージが表示されます。
\81\97ã\81\8bã\81\97ã\80\81ã\81\9fã\81¨ã\81\88**ã\83\87ã\83¼ã\82¿ã\82\92å\85¥å\8a\9bã\81\97ã\81¦**ã\80\8cExecuteã\80\8dã\82\92ã\82¯ã\83ªã\83\83ã\82¯ã\81\97ã\81¦ã\82\82ã\80\81ドキュメントUIは**JavaScript**で動作しているためクッキーは送信されず、まるで値を入力しなかったかのような**エラー**メッセージが表示されます。
 
 ///
 
-## 余分なクッキーを禁止する
+## 余分なクッキーを禁止する { #forbid-extra-cookies }
 
 特定の(あまり一般的ではないかもしれない)ケースで、受け付けるクッキーを**制限**する必要があるかもしれません。
 
@@ -51,7 +50,7 @@
 
 Pydanticのモデルの Configuration を利用して、 `extra` フィールドを `forbid` とすることができます。
 
-{* ../../docs_src/cookie_param_models/tutorial002_an_py39.py hl[10] *}
+{* ../../docs_src/cookie_param_models/tutorial002_an_py310.py hl[10] *}
 
 もしクライアントが**余分なクッキー**を送ろうとすると、**エラー**レスポンスが返されます。
 
@@ -72,6 +71,6 @@ Pydanticのモデルの Configuration を利用して、 `extra` フィールド
 }
 ```
 
-## まとめ
+## まとめ { #summary }
 
 **FastAPI**では、<abbr title="帰ってしまう前に最後のクッキーをどうぞ。🍪 (原文: Have a last cookie before you go. 🍪)">**クッキー**</abbr>を宣言するために、**Pydanticモデル**を使用できます。😎
index 13af6d3c77d3c41fb8a6836851d794830f2eaa6b..1e5a0d3cfd70465608fb4a2be39ac260682102f3 100644 (file)
@@ -1,20 +1,20 @@
-# クッキーのパラメータ
+# クッキーのパラメータ { #cookie-parameters }
 
 クッキーのパラメータは、`Query`や`Path`のパラメータを定義するのと同じ方法で定義できます。
 
-## `Cookie`をインポート
+## `Cookie`をインポート { #import-cookie }
 
 まず、`Cookie`をインポートします:
 
-{* ../../docs_src/cookie_params/tutorial001.py hl[3] *}
+{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[3] *}
 
-## `Cookie`のパラメータを宣言
+## `Cookie`のパラメータを宣言 { #declare-cookie-parameters }
 
 次に、`Path`や`Query`と同じ構造を使ってクッキーのパラメータを宣言します。
 
 最初の値がデフォルト値で、追加の検証パラメータや注釈パラメータをすべて渡すことができます:
 
-{* ../../docs_src/cookie_params/tutorial001.py hl[9] *}
+{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[9] *}
 
 /// note | 技術詳細
 
 
 ///
 
-## まとめ
+/// info | 情報
+
+**ブラウザがクッキーを**特殊な方法で裏側で扱うため、**JavaScript** から簡単には触れられないことを念頭に置いてください。
+
+`/docs` の **API docs UI** に移動すると、*path operation* のクッキーに関する **documentation** を確認できます。
+
+しかし、データを **入力** して「Execute」をクリックしても、docs UI は **JavaScript** で動作するためクッキーは送信されず、値を何も書かなかったかのような **error** メッセージが表示されます。
+
+///
+
+## まとめ { #recap }
 
-クッキーは`Cookie`を使って宣言し、`Query`や`Path`と同じパターンを使用する。
+クッキーは`Cookie`を使って宣言し、`Query`や`Path`と同じ共通のパターンを使用する。
index f7bd59b709ff33065772f99953f20e819345ec8d..a1dfe8e6243a490b2d9ca17dba7d78c4645fd7a3 100644 (file)
@@ -1,8 +1,8 @@
-# CORS (オリジン間リソース共有)
+# CORS (Cross-Origin Resource Sharing) { #cors-cross-origin-resource-sharing }
 
-<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">CORSまたは「オリジン間リソース共有」</a> は、ブラウザで実行されているフロントエンドにバックエンドと通信するJavaScriptコードがあり、そのバックエンドがフロントエンドとは異なる「オリジン」にある状況を指します。
+<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">CORSまたは「Cross-Origin Resource Sharing」</a> は、ブラウザで実行されているフロントエンドにバックエンドと通信するJavaScriptコードがあり、そのバックエンドがフロントエンドとは異なる「オリジン」にある状況を指します。
 
-## オリジン
+## オリジン { #origin }
 
 オリジンはプロトコル (`http`、`https`) とドメイン (`myapp.com`、`localhost`、`localhost.tiangolo.com`) とポート (`80`、`443`、`8080`) の組み合わせです。
 
 
 すべて `localhost` であっても、異なるプロトコルやポートを使用するので、異なる「オリジン」です。
 
-## ステップ
+## ステップ { #steps }
 
 そして、ブラウザ上で実行されているフロントエンド (`http://localhost:8080`) があり、そのJavaScriptが `http://localhost` で実行されているバックエンドと通信するとします。(ポートを指定していないので、ブラウザはデフォルトの`80`ポートを使用します)
 
-次に、ブラウザはHTTPの `OPTIONS` リクエストをバックエンドに送信します。そして、バックエンドがこの異なるオリジン (`http://localhost:8080`) からの通信を許可する適切なヘッダーを送信すると、ブラウザはフロントエンドのJavaScriptにバックエンドへのリクエストを送信させます。
+次に、ブラウザはHTTPの `OPTIONS` リクエストを `:80` のバックエンドに送信します。そして、バックエンドがこの異なるオリジン (`http://localhost:8080`) からの通信を許可する適切なヘッダーを送信すると、`:8080` のブラウザはフロントエンドのJavaScriptに `:80` のバックエンドへのリクエストを送信させます。
 
-これを実現するには、バックエンドに「許可されたオリジン」のリストがなければなりません。
+これを実現するには、`:80` のバックエンドに「許可されたオリジン」のリストがなければなりません。
 
-この場合、フロントエンドを正しく機能させるには、そのリストに `http://localhost:8080` を含める必要があります。
+この場合、`:8080` のフロントエンドを正しく機能させるには、そのリストに `http://localhost:8080` を含める必要があります。
 
-## ワイルドカード
+## ワイルドカード { #wildcards }
 
\83ªã\82¹ã\83\88ã\82\92 `"*"` (ã\83¯ã\82¤ã\83«ã\83\89ã\82«ã\83¼ã\83\89) と宣言して、すべてを許可することもできます。
\83ªã\82¹ã\83\88ã\82\92 `"*"` (ã\80\8cã\83¯ã\82¤ã\83«ã\83\89ã\82«ã\83¼ã\83\89ã\80\8d) と宣言して、すべてを許可することもできます。
 
-ただし、Bearer Tokenで使用されるような認証ヘッダーやCookieなどのクレデンシャル情報に関するものを除いて、特定の種類の通信のみが許可されます。
+ただし、クレデンシャル情報に関するもの、つまりCookie、Bearer Tokenで使用されるようなAuthorizationヘッダーなどを含むものは除外され、特定の種類の通信のみが許可されます。
 
 したがって、すべてを正しく機能させるために、許可されたオリジンの明示的な指定をお勧めします。
 
-## `CORSMiddleware` の使用
+## `CORSMiddleware` の使用 { #use-corsmiddleware }
 
 **FastAPI** アプリケーションでは `CORSMiddleware` を使用して、CORSに関する設定ができます。
 
 
 以下も、バックエンドに許可させるかどうか指定できます:
 
-* クレデンシャル情報 (認証ヘッダー、Cookieなど) 。
+* クレデンシャル情報 (Authorizationヘッダー、Cookieなど) 。
 * 特定のHTTPメソッド (`POST`、`PUT`) またはワイルドカード `"*"` を使用してすべて許可。
 * 特定のHTTPヘッダー、またはワイルドカード `"*"`を使用してすべて許可。
 
-{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *}
+{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
 
-`CORSMiddleware` 実装のデフォルトのパラメータはCORSに関して制限を与えるものになっているので、ブラウザにドメインを跨いで特定のオリジン、メソッド、またはヘッダーを使用可能にするためには、それらを明示的に有効にする必要があります
+
+`CORSMiddleware` 実装で使用されるデフォルトのパラメータはデフォルトで制限が厳しいため、ブラウザがクロスドメインのコンテキストでそれらを使用できるようにするには、特定のオリジン、メソッド、またはヘッダーを明示的に有効にする必要があります。
 
 以下の引数がサポートされています:
 
 * `allow_origins` - オリジン間リクエストを許可するオリジンのリスト。例えば、`['https://example.org', 'https://www.example.org']`。`['*']`を使用して任意のオリジンを許可できます。
 * `allow_origin_regex` - オリジン間リクエストを許可するオリジンの正規表現文字列。例えば、`'https://.*\.example\.org'`。
 * `allow_methods` - オリジン間リクエストで許可するHTTPメソッドのリスト。デフォルトは `['GET']` です。`['*']`を使用してすべての標準メソッドを許可できます。
-* `allow_headers` - オリジン間リクエストでサポートするHTTPリクエストヘッダーのリスト。デフォルトは `[]` です。`['*']`を使用して、すべてのヘッダーを許可できます。CORSリクエストでは、 `Accept` 、 `Accept-Language` 、 `Content-Language` 、 `Content-Type` ヘッダーが常に許可されます。
+* `allow_headers` - オリジン間リクエストでサポートするHTTPリクエストヘッダーのリスト。デフォルトは `[]` です。`['*']`を使用して、すべてのヘッダーを許可できます。<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests" class="external-link" rel="noopener" target="_blank">シンプルなCORSリクエスト</a>では、 `Accept` 、 `Accept-Language` 、 `Content-Language` 、 `Content-Type` ヘッダーが常に許可されます。
 * `allow_credentials` - オリジン間リクエストでCookieをサポートする必要があることを示します。デフォルトは `False` です。
+
+    `allow_credentials` が `True` に設定されている場合、`allow_origins`、`allow_methods`、`allow_headers` のいずれも `['*']` に設定できません。これらはすべて<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#credentialed_requests_and_wildcards" class="external-link" rel="noopener" target="_blank">明示的に指定</a>する必要があります。
+
 * `expose_headers` - ブラウザからアクセスできるようにするレスポンスヘッダーを示します。デフォルトは `[]` です。
 * `max_age` - ブラウザがCORSレスポンスをキャッシュする最大時間を秒単位で設定します。デフォルトは `600` です。
 
 このミドルウェアは2種類のHTTPリクエストに応答します...
 
-### CORSプリフライトリクエスト
+### CORSプリフライトリクエスト { #cors-preflight-requests }
 
 これらは、 `Origin` ヘッダーと `Access-Control-Request-Method` ヘッダーを持つ `OPTIONS` リクエストです。
 
 この場合、ミドルウェアはリクエストを横取りし、適切なCORSヘッダーと共に情報提供のために `200` または `400` のレスポンスを返します。
 
-### シンプルなリクエスト
+### シンプルなリクエスト { #simple-requests }
 
 `Origin` ヘッダーのあるリクエスト。この場合、ミドルウェアは通常どおりリクエストに何もしないですが、レスポンスに適切なCORSヘッダーを加えます。
 
-## より詳しい情報
+## より詳しい情報 { #more-info }
 
-<abbr title="Cross-Origin Resource Sharing (オリジン間リソース共有)">CORS</abbr>についてより詳しい情報は、<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">Mozilla CORS documentation</a> を参照して下さい。
+<abbr title="Cross-Origin Resource Sharing – オリジン間リソース共有">CORS</abbr>についてより詳しい情報は、<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">Mozilla CORS documentation</a> を参照して下さい。
 
 /// note | 技術詳細
 
index 6c29679efd6e7c982074549382e731ce47f4c126..8fe5b2d5d3a35f74749d4e9790e0e8534e7b2ed9 100644 (file)
@@ -1,14 +1,14 @@
-# デバッグ
+# デバッグ { #debugging }
 
 Visual Studio CodeやPyCharmなどを使用して、エディター上でデバッガーと連携できます。
 
-## `uvicorn` ã\81®å®\9fè¡\8c
+## `uvicorn` ã\82\92å\91¼ã\81³å\87ºã\81\99 { #call-uvicorn }
 
 FastAPIアプリケーション上で、`uvicorn` を直接インポートして実行します:
 
-{* ../../docs_src/debugging/tutorial001.py hl[1,15] *}
+{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
 
-### `__name__ == "__main__"` について
+### `__name__ == "__main__"` について { #about-name-main }
 
 `__name__ == "__main__"` の主な目的は、ファイルが次のコマンドで呼び出されたときに実行されるコードを用意することです:
 
@@ -26,7 +26,7 @@ $ python myapp.py
 from myapp import app
 ```
 
-#### より詳しい説明
+#### より詳しい説明 { #more-details }
 
 ファイルの名前が `myapp.py` だとします。
 
@@ -62,7 +62,7 @@ from myapp import app
 # Some more code
 ```
 
-`myapp.py` 内の自動変数には、値が `"__main __"` の変数 `__name__` はありません。
+その場合、`myapp.py` 内の自動的に作成された変数 `__name__` は、値として `"__main__"` を持ちません。
 
 したがって、以下の行:
 
@@ -78,7 +78,7 @@ from myapp import app
 
 ///
 
-## デバッガーでコードを実行
+## デバッガーでコードを実行 { #run-your-code-with-your-debugger }
 
 コードから直接Uvicornサーバーを実行しているため、デバッガーから直接Pythonプログラム (FastAPIアプリケーション) を呼び出せます。
 
index 80153529e5cab8c507a08e930a1bc497e7441b7a..3cb1fe73d99513c78b33bfbe18659e98230e38f5 100644 (file)
@@ -1,12 +1,12 @@
-# 依存関係としてのクラス
+# 依存関係としてのクラス { #classes-as-dependencies }
 
 **依存性注入** システムを深く掘り下げる前に、先ほどの例をアップグレードしてみましょう。
 
-## 前の例の`dict`
+## 前の例の`dict` { #a-dict-from-the-previous-example }
 
 前の例では、依存関係("dependable")から`dict`を返していました:
 
-{* ../../docs_src/dependencies/tutorial001.py hl[9] *}
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[9] *}
 
 しかし、*path operation関数*のパラメータ`commons`に`dict`が含まれています。
 
@@ -14,7 +14,7 @@
 
 もっとうまくやれるはずです...。
 
-## 依存関係を作るもの
+## 依存関係を作るもの { #what-makes-a-dependency }
 
 これまでは、依存関係が関数として宣言されているのを見てきました。
 
@@ -38,7 +38,7 @@ something(some_argument, some_keyword_argument="foo")
 
 これを「呼び出し可能」なものと呼びます。
 
-## 依存関係としてのクラス
+## 依存関係としてのクラス { #classes-as-dependencies_1 }
 
 Pythonのクラスのインスタンスを作成する際に、同じ構文を使用していることに気づくかもしれません。
 
@@ -67,48 +67,66 @@ FastAPIが実際にチェックしているのは、それが「呼び出し可
 
 それは、パラメータが全くない呼び出し可能なものにも適用されます。パラメータのない*path operation関数*と同じように。
 
-そこで、上で紹介した依存関係の`common_parameters`を`CommonQueryParams`クラスに変更します:
+そこで、上で紹介した依存関係の"dependable" `common_parameters`を`CommonQueryParams`クラスに変更します:
 
-{* ../../docs_src/dependencies/tutorial002.py hl[11,12,13,14,15] *}
+{* ../../docs_src/dependencies/tutorial002_an_py310.py hl[11:15] *}
 
 クラスのインスタンスを作成するために使用される`__init__`メソッドに注目してください:
 
-{* ../../docs_src/dependencies/tutorial002.py hl[12] *}
+{* ../../docs_src/dependencies/tutorial002_an_py310.py hl[12] *}
 
 ...以前の`common_parameters`と同じパラメータを持っています:
 
-{* ../../docs_src/dependencies/tutorial001.py hl[8] *}
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[8] *}
 
 これらのパラメータは **FastAPI** が依存関係を「解決」するために使用するものです。
 
 どちらの場合も以下を持っています:
 
-* オプショナルの`q`クエリパラメータ。
-* `skip`クエリパラメータ、デフォルトは`0`
-* `limit`クエリパラメータ、デフォルトは`100`
+* `str`であるオプショナルの`q`クエリパラメータ。
+* デフォルトが`0`である`int`の`skip`クエリパラメータ
+* デフォルトが`100`である`int`の`limit`クエリパラメータ
 
 どちらの場合も、データは変換され、検証され、OpenAPIスキーマなどで文書化されます。
 
-## 使用
+## 使用 { #use-it }
 
 これで、このクラスを使用して依存関係を宣言することができます。
 
-{* ../../docs_src/dependencies/tutorial002.py hl[19] *}
+{* ../../docs_src/dependencies/tutorial002_an_py310.py hl[19] *}
 
 **FastAPI** は`CommonQueryParams`クラスを呼び出します。これにより、そのクラスの「インスタンス」が作成され、インスタンスはパラメータ`commons`として関数に渡されます。
 
-## 型注釈と`Depends`
+## 型注釈と`Depends` { #type-annotation-vs-depends }
 
 上のコードでは`CommonQueryParams`を2回書いていることに注目してください:
 
+//// tab | Python 3.9+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
+```
+
+////
+
+//// tab | Python 3.9+ 注釈なし
+
+/// tip | 豆知識
+
+可能であれば`Annotated`バージョンを使用することを推奨します。
+
+///
+
 ```Python
 commons: CommonQueryParams = Depends(CommonQueryParams)
 ```
 
+////
+
 以下にある最後の`CommonQueryParams`:
 
 ```Python
-... Depends(CommonQueryParams)
+... Depends(CommonQueryParams)
 ```
 
 ...は、**FastAPI** が依存関係を知るために実際に使用するものです。
@@ -119,55 +137,145 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
 
 この場合、以下にある最初の`CommonQueryParams`:
 
+//// tab | Python 3.9+
+
+```Python
+commons: Annotated[CommonQueryParams, ...
+```
+
+////
+
+//// tab | Python 3.9+ 注釈なし
+
+/// tip | 豆知識
+
+可能であれば`Annotated`バージョンを使用することを推奨します。
+
+///
+
 ```Python
 commons: CommonQueryParams ...
 ```
 
-...は **FastAPI** に対して特別な意味をもちません。FastAPIはデータ変換や検証などには使用しません(それらのためには`= Depends(CommonQueryParams)`を使用しています)。
+////
+
+...は **FastAPI** に対して特別な意味をもちません。FastAPIはデータ変換や検証などには使用しません(それらのためには`Depends(CommonQueryParams)`を使用しています)。
 
 実際には以下のように書けばいいだけです:
 
+//// tab | Python 3.9+
+
+```Python
+commons: Annotated[Any, Depends(CommonQueryParams)]
+```
+
+////
+
+//// tab | Python 3.9+ 注釈なし
+
+/// tip | 豆知識
+
+可能であれば`Annotated`バージョンを使用することを推奨します。
+
+///
+
 ```Python
 commons = Depends(CommonQueryParams)
 ```
 
+////
+
 以下にあるように:
 
-{* ../../docs_src/dependencies/tutorial003.py hl[19] *}
+{* ../../docs_src/dependencies/tutorial003_an_py310.py hl[19] *}
 
 しかし、型を宣言することは推奨されています。そうすれば、エディタは`commons`のパラメータとして何が渡されるかを知ることができ、コードの補完や型チェックなどを行うのに役立ちます:
 
-<img src="https://fastapi.tiangolo.com/img/tutorial/dependencies/image02.png">
+<img src="/img/tutorial/dependencies/image02.png">
 
-## ショートカット
+## ショートカット { #shortcut }
 
 しかし、ここでは`CommonQueryParams`を2回書くというコードの繰り返しが発生していることがわかります:
 
+//// tab | Python 3.9+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
+```
+
+////
+
+//// tab | Python 3.9+ 注釈なし
+
+/// tip | 豆知識
+
+可能であれば`Annotated`バージョンを使用することを推奨します。
+
+///
+
 ```Python
 commons: CommonQueryParams = Depends(CommonQueryParams)
 ```
 
+////
+
 依存関係が、クラス自体のインスタンスを作成するために**FastAPI**が「呼び出す」*特定の*クラスである場合、**FastAPI** はこれらのケースのショートカットを提供しています。
 
 それらの具体的なケースについては以下のようにします:
 
 以下のように書く代わりに:
 
+//// tab | Python 3.9+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
+```
+
+////
+
+//// tab | Python 3.9+ 注釈なし
+
+/// tip | 豆知識
+
+可能であれば`Annotated`バージョンを使用することを推奨します。
+
+///
+
 ```Python
 commons: CommonQueryParams = Depends(CommonQueryParams)
 ```
 
+////
+
 ...以下のように書きます:
 
+//// tab | Python 3.9+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends()]
+```
+
+////
+
+//// tab | Python 3.9+ 注釈なし
+
+/// tip | 豆知識
+
+可能であれば`Annotated`バージョンを使用することを推奨します。
+
+///
+
 ```Python
 commons: CommonQueryParams = Depends()
 ```
 
+////
+
 パラメータの型として依存関係を宣言し、`Depends()`の中でパラメータを指定せず、`Depends()`をその関数のパラメータの「デフォルト」値(`=`のあとの値)として使用することで、`Depends(CommonQueryParams)`の中でクラス全体を*もう一度*書かなくてもよくなります。
 
 同じ例では以下のようになります:
 
-{* ../../docs_src/dependencies/tutorial004.py hl[19] *}
+{* ../../docs_src/dependencies/tutorial004_an_py310.py hl[19] *}
 
 ...そして **FastAPI** は何をすべきか知っています。
 
index 0fb15ae02c5f3247ac060828031cfdd8b47cb1e9..2051afc05b98c632a60a94eeb212bb320af05797 100644 (file)
@@ -1,57 +1,69 @@
-# path operationデコレータの依存関係
+# path operation デコレータの依存関係 { #dependencies-in-path-operation-decorators }
 
-場合によっては*path operation関数*の中で依存関係の戻り値を本当に必要としないこともあります。
+場合によっては、*path operation 関数*の中で依存関係の戻り値を実際には必要としないことがあります。
 
\82\82ã\81\97ã\81\8fは、依存関係が値を返さない場合もあります。
\81¾ã\81\9fは、依存関係が値を返さない場合もあります。
 
\81\97ã\81\8bã\81\97ã\80\81ã\81\9dã\82\8cã\81§ã\82\82å®\9fè¡\8cã\83»è§£æ±ºã\81\99る必要があります。
\81\97ã\81\8bã\81\97ã\80\81ã\81\9dã\82\8cã\81§ã\82\82å®\9fè¡\8cã\83»è§£æ±ºã\81\95ã\82\8cる必要があります。
 
\81\93ã\81®ã\82\88ã\81\86ã\81ªå ´å\90\88ã\80\81*path operationé\96¢æ\95°*ã\81®ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\82\92`Depends`ã\81§å®£è¨\80ã\81\99ã\82\8b代ã\82\8fã\82\8aã\81«ã\80\81*path operation decorator*ã\81«`dependencies`ã\81®`list`ã\82\92追å\8a ã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cできます。
\81\9dã\81®ã\82\88ã\81\86ã\81ªå ´å\90\88ã\80\81`Depends` ã\81§ *path operation é\96¢æ\95°* ã\81®ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\82\92宣è¨\80ã\81\99ã\82\8b代ã\82\8fã\82\8aã\81«ã\80\81*path operation ã\83\87ã\82³ã\83¬ã\83¼ã\82¿*ã\81« `dependencies` ã\81® `list` ã\82\92追å\8a できます。
 
-##  *path operationデコレータ*への`dependencies`の追加
+## *path operation デコレータ*に`dependencies`を追加 { #add-dependencies-to-the-path-operation-decorator }
 
-*path operationデコレータ*はオプショナルの引数`dependencies`を受け取ります。
+*path operation デコレータ*はオプション引数`dependencies`を受け取ります。
 
 それは`Depends()`の`list`であるべきです:
 
-{* ../../docs_src/dependencies/tutorial006.py hl[17] *}
+{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *}
 
-これらの依存関係は、通常の依存関係と同様に実行・解決されます。しかし、それらの値(何かを返す場合)は*path operation関数*には渡されません。
+これらの依存関係は、通常の依存関係と同様に実行・解決されます。しかし、それらの値(何かを返す場合)は*path operation 関数*には渡されません。
 
 /// tip | 豆知識
 
-エディタによっては、未使用の関数パラメータをチェックしてエラーとして表示するものもあります。
+一部のエディタは、未使用の関数パラメータをチェックしてエラーとして表示します。
 
-`dependencies`を`path operationデコレータ`で使用することで、エディタやツールのエラーを回避しながら確実に実行することができます。
+これらの`dependencies`を*path operation デコレータ*で使用することで、エディタ/ツールのエラーを回避しつつ、確実に実行されるようにできます。
 
-また、コードの未使用のパラメータがあるのを見て、それが不要だと思ってしまうような新しい開発者の混乱を避けるのにも役立つかもしれません。
+また、コード内の未使用のパラメータを見た新しい開発者が、それを不要だと思って混乱するのを避ける助けにもなるかもしれません。
 
 ///
 
-## 依存関係のエラーと戻り値
+/// info | 情報
 
-通常使用している依存関係の*関数*と同じものを使用することができます。
+この例では、架空のカスタムヘッダー `X-Key` と `X-Token` を使用しています。
 
-### 依存関係の要件
+しかし実際のケースでセキュリティを実装する際は、統合された[Security utilities(次の章)](../security/index.md){.internal-link target=_blank}を使うことで、より多くの利点を得られます。
 
-これらはリクエストの要件(ヘッダのようなもの)やその他のサブ依存関係を宣言することができます:
+///
+
+## 依存関係のエラーと戻り値 { #dependencies-errors-and-return-values }
+
+通常使用している依存関係の*関数*と同じものを使用できます。
+
+### 依存関係の要件 { #dependency-requirements }
 
-{* ../../docs_src/dependencies/tutorial006.py hl[6,11] *}
+これらはリクエストの要件(ヘッダーのようなもの)やその他のサブ依存関係を宣言できます:
 
-### 例外の発生
+{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *}
 
-これらの依存関係は通常の依存関係と同じように、例外を`raise`発生させることができます:
+### 例外の発生 { #raise-exceptions }
 
-{* ../../docs_src/dependencies/tutorial006.py hl[8,13] *}
+これらの依存関係は、通常の依存関係と同じように例外を`raise`できます:
 
-### 戻り値
+{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *}
+
+### 戻り値 { #return-values }
 
 そして、値を返すことも返さないこともできますが、値は使われません。
 
-つまり、すでにどこかで使っている通常の依存関係(値を返すもの)を再利用することができ、値は使われなくても依存関係は実行されます:
+つまり、すでにどこかで使っている通常の依存関係(値を返すもの)を再利用でき、値は使われなくても依存関係は実行されます:
+
+{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *}
+
+## *path operation*のグループに対する依存関係 { #dependencies-for-a-group-of-path-operations }
 
-{* ../../docs_src/dependencies/tutorial006.py hl[9,14] *}
+後で、より大きなアプリケーションを(おそらく複数ファイルで)構造化する方法([Bigger Applications - Multiple Files](../../tutorial/bigger-applications.md){.internal-link target=_blank})について読むときに、*path operation*のグループに対して単一の`dependencies`パラメータを宣言する方法を学びます。
 
-## *path operations*のグループに対する依存関係
+## グローバル依存関係 { #global-dependencies }
 
-後で、より大きなアプリケーションの構造([Bigger Applications - Multiple Files](../../tutorial/bigger-applications.md){.internal-link target=_blank})について読む時に、おそらく複数のファイルを使用して、*path operations*のグループに対して単一の`dependencies`パラメータを宣言する方法を学ぶでしょう
+次に、`FastAPI`アプリケーション全体に依存関係を追加して、各*path operation*に適用する方法を見ていきます
index 35a69de0dfe2db8065ec8a7a6477883b0c6a3d7d..8095114c3f71a12983d2a0c8f56de43a68a88a18 100644 (file)
@@ -1,24 +1,12 @@
-# yieldを持つ依存関係
+# `yield`を持つ依存関係 { #dependencies-with-yield }
 
-FastAPIは、いくつかの<abbr title='時々"exit"、"cleanup"、"teardown"、"close"、"context managers"、 ...のように呼ばれる'>終了後の追加のステップ</abbr>を行う依存関係をサポートしています。
+FastAPIは、いくつかの<abbr title='sometimes also called "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code", etc. – 「exit code」「cleanup code」「teardown code」「closing code」「context manager exit code」などと呼ばれることもあります。'>終了後の追加のステップ</abbr>を行う依存関係をサポートしています。
 
-これを行うには、`return`の代わりに`yield`を使い、その後に追加のステップを書きます。
+これを行うには、`return`の代わりに`yield`を使い、その後に追加のステップ(コード)を書きます。
 
 /// tip | 豆知識
 
-`yield`は必ず一度だけ使用するようにしてください。
-
-///
-
-/// info | 情報
-
-これを動作させるには、**Python 3.7** 以上を使用するか、**Python 3.6** では"backports"をインストールする必要があります:
-
-```
-pip install async-exit-stack async-generator
-```
-
-これにより<a href="https://github.com/sorcio/async_exit_stack" class="external-link" target="_blank">async-exit-stack</a>と<a href="https://github.com/python-trio/async_generator" class="external-link" target="_blank">async-generator</a>がインストールされます。
+`yield`は必ず依存関係ごとに1回だけ使用するようにしてください。
 
 ///
 
@@ -35,21 +23,21 @@ pip install async-exit-stack async-generator
 
 ///
 
-## `yield`を持つデータベースの依存関係
+## `yield`を持つデータベースの依存関係 { #a-database-dependency-with-yield }
 
 例えば、これを使ってデータベースセッションを作成し、終了後にそれを閉じることができます。
 
-レスポンスを送信する前に`yield`文を含む前のコードのみが実行されます。
+レスポンスを作成する前に、`yield`文より前のコード(および`yield`文を含む)が実行されます:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[2,3,4] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
 
 生成された値は、*path operations*や他の依存関係に注入されるものです:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[4] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
 
-`yield`æ\96\87ã\81«ç¶\9aã\81\8fã\82³ã\83¼ã\83\89ã\81¯ã\80\81ã\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\81\8cé\80\81ä¿¡ã\81\95ã\82\8cã\81\9f後に実行されます:
+`yield`æ\96\87ã\81«ç¶\9aã\81\8fã\82³ã\83¼ã\83\89ã\81¯ã\80\81ã\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\81®後に実行されます:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[5,6] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
 
 /// tip | 豆知識
 
@@ -59,27 +47,27 @@ pip install async-exit-stack async-generator
 
 ///
 
-## `yield`と`try`を持つ依存関係
+## `yield`と`try`を持つ依存関係 { #a-dependency-with-yield-and-try }
 
-`yield`を持つ依存関係で`try`ブロックを使用した場合、その依存関係を使用した際に発生した例外を受け取ることになります。
+`yield`を持つ依存関係で`try`ブロックを使用した場合、その依存関係を使用した際にスローされたあらゆる例外を受け取ることになります。
 
-例えば、途中のどこかの時点で、別の依存関係や*path operation*の中で、データベーストランザクションを「ロールバック」したり、その他のエラーを作成したりするコードがあった場合、依存関係の中で例外を受け取ることになります。
+例えば、途中のどこかの時点で、別の依存関係や*path operation*の中で、データベーストランザクションを「ロールバック」したり、その他の例外を作成したりするコードがあった場合、依存関係の中で例外を受け取ることになります。
 
 そのため、依存関係の中にある特定の例外を`except SomeException`で探すことができます。
 
 同様に、`finally`を用いて例外があったかどうかにかかわらず、終了ステップを確実に実行することができます。
 
-{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
 
-## `yield`を持つサブ依存関係
+## `yield`を持つサブ依存関係 { #sub-dependencies-with-yield }
 
 任意の大きさや形のサブ依存関係やサブ依存関係の「ツリー」を持つことができ、その中で`yield`を使用することができます。
 
 **FastAPI** は、`yield`を持つ各依存関係の「終了コード」が正しい順番で実行されていることを確認します。
 
-ä¾\8bã\81\88ã\81°ã\80\81`dependency_c`ã\81¯`dependency_b`ã\81¨`dependency_b`ã\81«ä¾\9då­\98ã\81\99ã\82\8b`dependency_a`ã\81«ã\80\81依存することができます:
+ä¾\8bã\81\88ã\81°ã\80\81`dependency_c`ã\81¯`dependency_b`ã\81«ã\80\81ã\81\9dã\81\97ã\81¦`dependency_b`ã\81¯`dependency_a`ã\81«依存することができます:
 
-{* ../../docs_src/dependencies/tutorial008.py hl[4,12,20] *}
+{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
 
 そして、それらはすべて`yield`を使用することができます。
 
@@ -87,11 +75,11 @@ pip install async-exit-stack async-generator
 
 そして、`dependency_b`は`dependency_a`(ここでは`dep_a`という名前)の値を終了コードで利用できるようにする必要があります。
 
-{* ../../docs_src/dependencies/tutorial008.py hl[16,17,24,25] *}
+{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
 
\90\8cæ§\98ã\81«ã\80\81`yield`ã\81¨`return`ã\81\8cæ··å\9c¨ã\81\97ã\81\9fä¾\9då­\98é\96¢ä¿\82ã\82\92æ\8c\81ã\81¤ã\81\93ã\81¨もできます。
\90\8cæ§\98ã\81«ã\80\81`yield`ã\82\92æ\8c\81ã\81¤ä¾\9då­\98é\96¢ä¿\82ã\81¨`return`ã\82\92æ\8c\81ã\81¤ä»\96ã\81®ä¾\9då­\98é\96¢ä¿\82ã\82\92ã\81\84ã\81\8fã\81¤ã\81\8bæ\8c\81ã\81¡ã\80\81ã\81\9dã\82\8cã\82\89ã\81®ä¸\80é\83¨ã\81\8cä»\96ã\81®ä¸\80é\83¨ã\81«ä¾\9då­\98ã\81\99ã\82\8bã\82\88ã\81\86ã\81«もできます。
 
\81¾ã\81\9fã\80\81å\8d\98ä¸\80ã\81®ä¾\9då­\98é\96¢ä¿\82ã\82\92æ\8c\81ã\81£ã\81¦ã\81\84ã\81¦ã\80\81`yield`ã\81ªã\81©ã\81®他の依存関係をいくつか必要とすることもできます。
\81¾ã\81\9fã\80\81å\8d\98ä¸\80ã\81®ä¾\9då­\98é\96¢ä¿\82ã\82\92æ\8c\81ã\81£ã\81¦ã\81\84ã\81¦ã\80\81`yield`ã\82\92æ\8c\81ã\81¤他の依存関係をいくつか必要とすることもできます。
 
 依存関係の組み合わせは自由です。
 
@@ -105,31 +93,45 @@ pip install async-exit-stack async-generator
 
 ///
 
-## `yield`と`HTTPException`を持つ依存関係
+## `yield`と`HTTPException`を持つ依存関係 { #dependencies-with-yield-and-httpexception }
 
-`yield`ã\81¨ä¾\8bå¤\96ã\82\92ã\82­ã\83£ã\83\83ã\83\81ã\81\99ã\82\8b`try`ã\83\96ã\83­ã\83\83ã\82¯ã\82\92æ\8c\81ã\81¤ã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\82\8bä¾\9då­\98é\96¢ä¿\82ã\82\92使ç\94¨ã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\82\8bã\81\93ã\81¨ã\81\8cã\82\8fかりました。
+`yield`ã\82\92æ\8c\81ã\81¤ä¾\9då­\98é\96¢ä¿\82ã\82\92使ã\81\84ã\80\81ä½\95ã\82\89ã\81\8bã\81®ã\82³ã\83¼ã\83\89ã\82\92å®\9fè¡\8cã\81\97ã\80\81ã\81\9dã\81®å¾\8cã\81«`finally`ã\81®å¾\8cã\81§çµ\82äº\86ã\82³ã\83¼ã\83\89ã\82\92å®\9fè¡\8cã\81\97ã\82\88ã\81\86ã\81¨ã\81\99ã\82\8b`try`ã\83\96ã\83­ã\83\83ã\82¯ã\82\92æ\8c\81ã\81¦ã\82\8bã\81\93ã\81¨ã\81\8cå\88\86かりました。
 
-`yield`の後の終了コードで`HTTPException`などを発生させたくなるかもしれません。しかし**それはうまくいきません**
+また、`except`を使って発生した例外をキャッチし、それに対して何かをすることもできます。
 
-`yield`を持つ依存関係の終了コードは[例外ハンドラ](../handling-errors.md#_4){.internal-link target=_blank}の*後に*実行されます。依存関係によって投げられた例外を終了コード(`yield`の後)でキャッチするものはなにもありません
+例えば、`HTTPException`のように別の例外を発生させることができます
 
-つまり、`yield`の後に`HTTPException`を発生させた場合、`HTTTPException`をキャッチしてHTTP 400のレスポンスを返すデフォルトの(あるいは任意のカスタムの)例外ハンドラは、その例外をキャッチすることができなくなります。
+/// tip | 豆知識
 
\81\93ã\82\8cã\81¯ã\80\81ä¾\9då­\98é\96¢ä¿\82ã\81«è¨­å®\9aã\81\95ã\82\8cã\81¦ã\81\84ã\82\8bã\82\82ã\81®ï¼\88ä¾\8bã\81\88ã\81°ã\80\81DBã\82»ã\83\83ã\82·ã\83§ã\83³ï¼\89ã\82\92ã\80\81ä¾\8bã\81\88ã\81°ã\80\81ã\83\90ã\83\83ã\82¯ã\82°ã\83©ã\82¦ã\83³ã\83\89ã\82¿ã\82¹ã\82¯ã\81§ä½¿ç\94¨ã\81§ã\81\8dã\82\8bã\82\88ã\81\86ã\81«ã\81\99ã\82\8bã\82\82ã\81®です。
\81\93ã\82\8cã\81¯ã\82\84ã\82\84é«\98度ã\81ªã\83\86ã\82¯ã\83\8bã\83\83ã\82¯ã\81§ã\80\81ã\81»ã\81¨ã\82\93ã\81©ã\81®å ´å\90\88ã\81¯æ\9c¬å½\93ã\81«å¿\85è¦\81ã\81«ã\81¯ã\81ªã\82\8aã\81¾ã\81\9bã\82\93ã\80\82ä¾\8bã\81\88ã\81°ã\80\81*path operation é\96¢æ\95°*ã\81ªã\81©ã\80\81ã\82¢ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³ã\82³ã\83¼ã\83\89ã\81®ä»\96ã\81®å ´æ\89\80ã\81\8bã\82\89ï¼\88`HTTPException`ã\82\92å\90«ã\82\80ï¼\89ä¾\8bå¤\96ã\82\92ç\99ºç\94\9fã\81\95ã\81\9bã\82\89ã\82\8cã\82\8bã\81\9fã\82\81です。
 
\83\90ã\83\83ã\82¯ã\82°ã\83©ã\82¦ã\83³ã\83\89ã\82¿ã\82¹ã\82¯ã\81¯ã\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\81\8cé\80\81ä¿¡ã\81\95ã\82\8cã\81\9f*å¾\8c\81«å®\9fè¡\8cã\81\95ã\82\8cã\81¾ã\81\99ã\80\82ã\81\9dã\81®ã\81\9fã\82\81ã\80\81\81\99ã\81§ã\81«é\80\81ä¿¡ã\81\95ã\82\8cã\81¦ã\81\84ã\82\8b\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\82\92å¤\89æ\9b´ã\81\99ã\82\8bæ\96¹æ³\95ã\81\99ã\82\89ã\81ªã\81\84ã\81®ã\81§ã\80\81`HTTPException`ã\82\92ç\99ºç\94\9fã\81\95ã\81\9bã\82\8bæ\96¹æ³\95ã\81¯ã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\80\82
\81\9fã\81 ã\81\97å¿\85è¦\81ã\81§ã\81\82ã\82\8cã\81°ä½¿ã\81\88ã\81¾ã\81\99ã\80\82 ð\9f¤\93
 
-しかし、バックグラウンドタスクがDBエラーを発生させた場合、少なくとも`yield`で依存関係のセッションをロールバックしたり、きれいに閉じたりすることができ、エラーをログに記録したり、リモートのトラッキングシステムに報告したりすることができます。
+///
 
-例外が発生する可能性があるコードがある場合は、最も普通の「Python流」なことをして、コードのその部分に`try`ブロックを追加してください。
+{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
 
-レスポンスを返したり、レスポンスを変更したり、`HTTPException`を発生させたりする*前に*処理したいカスタム例外がある場合は、[カスタム例外ハンドラ](../handling-errors.md#_4){.internal-link target=_blank}を作成してください。
+例外をキャッチして、それに基づいてカスタムレスポンスを作成したい場合は、[カスタム例外ハンドラ](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}を作成してください。
 
-/// tip | 豆知識
+## `yield`と`except`を持つ依存関係 { #dependencies-with-yield-and-except }
 
-`HTTPException`を含む例外は、`yield`の*前*でも発生させることができます。ただし、後ではできません。
+`yield`を持つ依存関係で`except`を使って例外をキャッチし、それを再度raiseしない(または新しい例外をraiseしない)場合、通常のPythonと同じように、FastAPIは例外があったことに気づけません:
 
-///
+{* ../../docs_src/dependencies/tutorial008c_an_py39.py hl[15:16] *}
+
+この場合、(`HTTPException`やそれに類するものをraiseしていないため)クライアントには適切に*HTTP 500 Internal Server Error*レスポンスが返りますが、サーバーには**ログが一切残らず**、何がエラーだったのかを示す他の手がかりもありません。 😱
+
+### `yield`と`except`を持つ依存関係では常に`raise`する { #always-raise-in-dependencies-with-yield-and-except }
+
+`yield`を持つ依存関係で例外をキャッチした場合、別の`HTTPException`などをraiseするのでない限り、**元の例外を再raiseすべきです**。
+
+`raise`を使うと同じ例外を再raiseできます:
+
+{* ../../docs_src/dependencies/tutorial008d_an_py39.py hl[17] *}
+
+これでクライアントは同じ*HTTP 500 Internal Server Error*レスポンスを受け取りますが、サーバーのログにはカスタムの`InternalError`が残ります。 😎
+
+## `yield`を持つ依存関係の実行 { #execution-of-dependencies-with-yield }
 
 実行の順序は多かれ少なかれ以下の図のようになります。時間は上から下へと流れていきます。そして、各列はコードを相互作用させたり、実行したりしている部分の一つです。
 
@@ -142,32 +144,29 @@ participant dep as Dep with yield
 participant operation as Path Operation
 participant tasks as Background tasks
 
-    Note over client,tasks: Can raise exception for dependency, handled after response is sent
-    Note over client,operation: Can raise HTTPException and can change the response
+    Note over client,operation: Can raise exceptions, including HTTPException
     client ->> dep: Start request
     Note over dep: Run code up to yield
-    opt raise
-        dep -->> handler: Raise HTTPException
+    opt raise Exception
+        dep -->> handler: Raise Exception
         handler -->> client: HTTP error response
-        dep -->> dep: Raise other exception
     end
     dep ->> operation: Run dependency, e.g. DB session
     opt raise
-        operation -->> handler: Raise HTTPException
+        operation -->> dep: Raise Exception (e.g. HTTPException)
+        opt handle
+            dep -->> dep: Can catch exception, raise a new HTTPException, raise other exception
+        end
         handler -->> client: HTTP error response
-        operation -->> dep: Raise other exception
     end
+
     operation ->> client: Return response to client
     Note over client,operation: Response is already sent, can't change it anymore
     opt Tasks
         operation -->> tasks: Send background tasks
     end
     opt Raise other exception
-        tasks -->> dep: Raise other exception
-    end
-    Note over dep: After yield
-    opt Handle other exception
-        dep -->> dep: Handle exception, can't change response. E.g. close DB session.
+        tasks -->> tasks: Handle exceptions in the background task code
     end
 ```
 
@@ -181,15 +180,63 @@ participant tasks as Background tasks
 
 /// tip | 豆知識
 
-この図は`HTTPException`を示していますが、[カスタム例外ハンドラ](../handling-errors.md#_4){.internal-link target=_blank}を作成することで、他の例外を発生させることもできます。そして、その例外は依存関係の終了コードではなく、そのカスタム例外ハンドラによって処理されます。
-
-しかし例外ハンドラで処理されない例外を発生させた場合は、依存関係の終了コードで処理されます。
+*path operation 関数*のコードで例外をraiseした場合、`HTTPException`を含め、それはyieldを持つ依存関係に渡されます。ほとんどの場合、その例外が正しく処理されるように、`yield`を持つ依存関係から同じ例外、または新しい例外を再raiseしたくなるでしょう。
 
 ///
 
-## コンテキストマネージャ
+## 早期終了と`scope` { #early-exit-and-scope }
+
+通常、`yield`を持つ依存関係の終了コードは、クライアントに**レスポンスが送信された後**に実行されます。
+
+しかし、*path operation 関数*からreturnした後に依存関係を使う必要がないと分かっている場合は、`Depends(scope="function")`を使って、**レスポンスが送信される前**に、*path operation 関数*のreturn後に依存関係を閉じるべきだとFastAPIに伝えられます。
+
+{* ../../docs_src/dependencies/tutorial008e_an_py39.py hl[12,16] *}
+
+`Depends()`は、以下のいずれかを取る`scope`パラメータを受け取ります:
+
+* `"function"`: リクエストを処理する*path operation 関数*の前に依存関係を開始し、*path operation 関数*の終了後に依存関係を終了しますが、クライアントにレスポンスが返される**前**に終了します。つまり、依存関係関数は*path operation 関数*の**周囲**で実行されます。
+* `"request"`: リクエストを処理する*path operation 関数*の前に依存関係を開始し(`"function"`を使用する場合と同様)、クライアントにレスポンスが返された**後**に終了します。つまり、依存関係関数は**リクエスト**とレスポンスのサイクルの**周囲**で実行されます。
+
+指定されておらず、依存関係に`yield`がある場合、デフォルトで`scope`は`"request"`になります。
+
+### サブ依存関係の`scope` { #scope-for-sub-dependencies }
+
+`scope="request"`(デフォルト)を持つ依存関係を宣言する場合、どのサブ依存関係も`"request"`の`scope`を持つ必要があります。
+
+しかし、`"function"`の`scope`を持つ依存関係は、`"function"`と`"request"`の`scope`を持つ依存関係を持てます。
+
+これは、いずれの依存関係も、サブ依存関係より前に終了コードを実行できる必要があるためです(終了コードの実行中にサブ依存関係をまだ使う必要がある可能性があるためです)。
+
+```mermaid
+sequenceDiagram
+
+participant client as Client
+participant dep_req as Dep scope="request"
+participant dep_func as Dep scope="function"
+participant operation as Path Operation
+
+    client ->> dep_req: Start request
+    Note over dep_req: Run code up to yield
+    dep_req ->> dep_func: Pass dependency
+    Note over dep_func: Run code up to yield
+    dep_func ->> operation: Run path operation with dependency
+    operation ->> dep_func: Return from path operation
+    Note over dep_func: Run code after yield
+    Note over dep_func: ✅ Dependency closed
+    dep_func ->> client: Send response to client
+    Note over client: Response sent
+    Note over dep_req: Run code after yield
+    Note over dep_req: ✅ Dependency closed
+```
+
+## `yield`、`HTTPException`、`except`、バックグラウンドタスクを持つ依存関係 { #dependencies-with-yield-httpexception-except-and-background-tasks }
+
+`yield`を持つ依存関係は、さまざまなユースケースをカバーし、いくつかの問題を修正するために、時間とともに進化してきました。
+
+FastAPIの異なるバージョンで何が変わったのかを知りたい場合は、上級ガイドの[上級の依存関係 - `yield`、`HTTPException`、`except`、バックグラウンドタスクを持つ依存関係](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks){.internal-link target=_blank}で詳しく読めます。
+## コンテキストマネージャ { #context-managers }
 
-### 「コンテキストマネージャ」とは
+### 「コンテキストマネージャ」とは { #what-are-context-managers }
 
 「コンテキストマネージャ」とは、`with`文の中で使用できるPythonオブジェクトのことです。
 
@@ -205,9 +252,9 @@ with open("./somefile.txt") as f:
 
 `with`ブロックが終了すると、例外があったとしてもファイルを確かに閉じます。
 
-`yield`を依存関係を作成すると、**FastAPI** は内部的にそれをコンテキストマネージャに変換し、他の関連ツールと組み合わせます。
+`yield`を持つ依存関係を作成すると、**FastAPI** は内部的にそれをコンテキストマネージャに変換し、他の関連ツールと組み合わせます。
 
-### `yield`を持つ依存関係でのコンテキストマネージャの使用
+### `yield`を持つ依存関係でのコンテキストマネージャの使用 { #using-context-managers-in-dependencies-with-yield }
 
 /// warning | 注意
 
@@ -221,7 +268,7 @@ Pythonでは、<a href="https://docs.python.org/3/reference/datamodel.html#conte
 
 また、依存関数の中で`with`や`async with`文を使用することによって`yield`を持つ **FastAPI** の依存関係の中でそれらを使用することができます:
 
-{* ../../docs_src/dependencies/tutorial010.py hl[1,2,3,4,5,6,7,8,9,13] *}
+{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
 
 /// tip | 豆知識
 
index c2b5e7bba43c264a87396c6de3dab2ecb20a7746..0561935538d371efd3eb257b398aa6fc7212a913 100644 (file)
@@ -1,12 +1,12 @@
-# 依存関係 - 最初のステップ
+# 依存関係 { #dependencies }
 
-** FastAPI** は非常に強力でありながら直感的な **<abbr title="コンポーネント、リソース、プロバイダ、サービス、インジェクタブルとしても知られている">依存性注入</abbr>** システムを持っています。
+**FastAPI** は非常に強力でありながら直感的な **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** システムを持っています。
 
 それは非常にシンプルに使用できるように設計されており、開発者が他のコンポーネント **FastAPI** と統合するのが非常に簡単になるように設計されています。
 
-## 「依存性注入」とは
+## 「Dependency Injection」とは { #what-is-dependency-injection }
 
-**「依存性注入」** とは、プログラミングにおいて、コード(この場合は、*path operation関数*)が動作したり使用したりするために必要なもの(「依存関係」)を宣言する方法があることを意味します:
+**「Dependency Injection」** とは、プログラミングにおいて、コード(この場合は、*path operation 関数*)が動作したり使用したりするために必要なもの(「依存関係」)を宣言する方法があることを意味します:
 
 そして、そのシステム(この場合は、**FastAPI**)は、必要な依存関係をコードに提供するために必要なことは何でも行います(依存関係を「注入」します)。
 
 
 これらすべてを、コードの繰り返しを最小限に抑えながら行います。
 
-## 最初のステップ
+## 最初のステップ { #first-steps }
 
 非常にシンプルな例を見てみましょう。あまりにもシンプルなので、今のところはあまり参考にならないでしょう。
 
-しかし、この方法では **依存性注入** システムがどのように機能するかに焦点を当てることができます。
+しかし、この方法では **Dependency Injection** システムがどのように機能するかに焦点を当てることができます。
 
-### 依存関係の作成
+### 依存関係(「dependable」)の作成 { #create-a-dependency-or-dependable }
 
 まずは依存関係に注目してみましょう。
 
-以下のように、*path operation関数*と同じパラメータを全て取ることができる関数にすぎません:
+以下のように、*path operation 関数*と同じパラメータを全て取ることができる関数にすぎません:
 
-{* ../../docs_src/dependencies/tutorial001.py hl[8,9] *}
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[8:9] *}
 
 これだけです。
 
 **2行**。
 
-そして、それはすべての*path operation関数*が持っているのと同じ形と構造を持っています。
+そして、それはすべての*path operation 関数*が持っているのと同じ形と構造を持っています。
 
-「デコレータ」を含まない(`@app.get("/some-path")`を含まない)*path operation関数*と考えることもできます。
+「デコレータ」を含まない(`@app.get("/some-path")`を含まない)*path operation 関数*と考えることもできます。
 
 そして何でも返すことができます。
 
 
 そして、これらの値を含む`dict`を返します。
 
-### `Depends`のインポート
+/// info | 情報
 
-{* ../../docs_src/dependencies/tutorial001.py hl[3] *}
+FastAPI はバージョン 0.95.0 で `Annotated` のサポートを追加し(そして推奨し始めました)。
 
-### "dependant"での依存関係の宣言
+古いバージョンを使用している場合、`Annotated` を使おうとするとエラーになります。
 
-*path operation関数*のパラメータに`Body`や`Query`などを使用するのと同じように、新しいパラメータに`Depends`を使用することができます:
+`Annotated` を使用する前に、少なくとも 0.95.1 まで [FastAPI のバージョンをアップグレード](../../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} してください。
 
-{* ../../docs_src/dependencies/tutorial001.py hl[13,18] *}
+///
+
+### `Depends`のインポート { #import-depends }
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[3] *}
+
+### 「dependant」での依存関係の宣言 { #declare-the-dependency-in-the-dependant }
+
+*path operation 関数*のパラメータに`Body`や`Query`などを使用するのと同じように、新しいパラメータに`Depends`を使用することができます:
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[13,18] *}
 
 関数のパラメータに`Depends`を使用するのは`Body`や`Query`などと同じですが、`Depends`の動作は少し異なります。
 
@@ -67,7 +77,9 @@
 
 このパラメータは関数のようなものである必要があります。
 
-そして、その関数は、*path operation関数*が行うのと同じ方法でパラメータを取ります。
+直接**呼び出しません**(末尾に括弧を付けません)。`Depends()` のパラメータとして渡すだけです。
+
+そして、その関数は、*path operation 関数*が行うのと同じ方法でパラメータを取ります。
 
 /// tip | 豆知識
 
@@ -79,7 +91,7 @@
 
 * 依存関係("dependable")関数を正しいパラメータで呼び出します。
 * 関数の結果を取得します。
-* *path operation関数*のパラメータにその結果を代入してください。
+* *path operation 関数*のパラメータにその結果を代入してください。
 
 ```mermaid
 graph TB
@@ -92,7 +104,7 @@ common_parameters --> read_items
 common_parameters --> read_users
 ```
 
-この方法では、共有されるコードを一度書き、**FastAPI** が*path operations*のための呼び出しを行います。
+この方法では、共有されるコードを一度書き、**FastAPI** が*path operation*のための呼び出しを行います。
 
 /// check | 確認
 
@@ -102,59 +114,85 @@ common_parameters --> read_users
 
 ///
 
-## `async`にするかどうか
+## `Annotated` 依存関係の共有 { #share-annotated-dependencies }
+
+上の例では、ほんの少し **コードの重複** があることがわかります。
+
+`common_parameters()` 依存関係を使う必要があるときは、型アノテーションと `Depends()` を含むパラメータ全体を書く必要があります:
+
+```Python
+commons: Annotated[dict, Depends(common_parameters)]
+```
+
+しかし、`Annotated` を使用しているので、その `Annotated` 値を変数に格納して複数箇所で使えます:
+
+{* ../../docs_src/dependencies/tutorial001_02_an_py310.py hl[12,16,21] *}
+
+/// tip | 豆知識
+
+これはただの標準 Python で、「type alias」と呼ばれ、**FastAPI** 固有のものではありません。
+
+しかし **FastAPI** は `Annotated` を含む Python 標準に基づいているため、このテクニックをコードで使えます。 😎
+
+///
+
+依存関係は期待どおりに動作し続け、**一番良い点** は **型情報が保持される** ことです。つまり、エディタは **自動補完**、**インラインエラー** などを提供し続けられます。`mypy` のような他のツールでも同様です。
+
+これは **大規模なコードベース** で、**同じ依存関係** を **多くの *path operation*** で何度も使う場合に特に役立ちます。
+
+## `async`にするかどうか { #to-async-or-not-to-async }
 
-依存関係は **FastAPI**(*path operation関数*と同じ)からも呼び出されるため、関数を定義する際にも同じルールが適用されます。
+依存関係は **FastAPI**(*path operation 関数*と同じ)からも呼び出されるため、関数を定義する際にも同じルールが適用されます。
 
 `async def`や通常の`def`を使用することができます。
 
-また、通常の`def`*path operation関数*の中に`async def`を入れて依存関係を宣言したり、`async def`*path operation関数*の中に`def`を入れて依存関係を宣言したりすることなどができます。
+また、通常の`def`*path operation 関数*の中に`async def`を入れて依存関係を宣言したり、`async def`*path operation 関数*の中に`def`を入れて依存関係を宣言したりすることなどができます。
 
 それは重要ではありません。**FastAPI** は何をすべきかを知っています。
 
 /// note | 備考
 
-わからない場合は、ドキュメントの[Async: *"In a hurry?"*](../../async.md){.internal-link target=_blank}の中の`async`と`await`についてのセクションを確認してください。
+わからない場合は、ドキュメントの[Async: *"In a hurry?"*](../../async.md#in-a-hurry){.internal-link target=_blank}の中の`async`と`await`についてのセクションを確認してください。
 
 ///
 
-## OpenAPIとの統合
+## OpenAPIとの統合 { #integrated-with-openapi }
 
 依存関係(およびサブ依存関係)のすべてのリクエスト宣言、検証、および要件は、同じOpenAPIスキーマに統合されます。
 
 つまり、対話型ドキュメントにはこれらの依存関係から得られる全ての情報も含まれているということです:
 
-<img src="https://fastapi.tiangolo.com/img/tutorial/dependencies/image01.png">
+<img src="/img/tutorial/dependencies/image01.png">
 
-## 簡単な使い方
+## 簡単な使い方 { #simple-usage }
 
-見てみると、*path*と*operation*が一致した時に*path operation関数*が宣言されていて、**FastAPI** が正しいパラメータで関数を呼び出してリクエストからデータを抽出する処理をしています。
+見てみると、*path*と*operation*が一致した時に*path operation 関数*が宣言されていて、**FastAPI** が正しいパラメータで関数を呼び出してリクエストからデータを抽出する処理をしています。
 
 実は、すべての(あるいはほとんどの)Webフレームワークは、このように動作します。
 
 これらの関数を直接呼び出すことはありません。これらの関数はフレームワーク(この場合は、**FastAPI**)によって呼び出されます。
 
-依存性注入システムでは、**FastAPI** に*path operation*もまた、*path operation関数*の前に実行されるべき他の何かに「依存」していることを伝えることができ、**FastAPI** がそれを実行し、結果を「注入」することを引き受けます。
+Dependency Injection システムでは、**FastAPI** に*path operation 関数*もまた、*path operation 関数*の前に実行されるべき他の何かに「依存」していることを伝えることができ、**FastAPI** がそれを実行し、結果を「注入」することを引き受けます。
 
-他にも、「依存性注入」と同じような考えの一般的な用語があります:
+他にも、「dependency injection」と同じような考えの一般的な用語があります:
 
-* リソース
-* プロバイダ
-* サービス
-* インジェクタブル
-* コンポーネント
+* resources
+* providers
+* services
+* injectables
+* components
 
-## **FastAPI** プラグイン
+## **FastAPI** プラグイン { #fastapi-plug-ins }
 
-統合や「プラグイン」は **依存性注入** システムを使って構築することができます。しかし、実際には、**「プラグイン」を作成する必要はありません**。依存関係を使用することで、無限の数の統合やインタラクションを宣言することができ、それが**path operation関数*で利用可能になるからです。
+統合や「プラグイン」は **Dependency Injection** システムを使って構築することができます。しかし、実際には、**「プラグイン」を作成する必要はありません**。依存関係を使用することで、無限の数の統合やインタラクションを宣言することができ、それが*path operation 関数*で利用可能になるからです。
 
 依存関係は非常にシンプルで直感的な方法で作成することができ、必要なPythonパッケージをインポートするだけで、*文字通り*数行のコードでAPI関数と統合することができます。
 
 次の章では、リレーショナルデータベースやNoSQLデータベース、セキュリティなどについて、その例を見ていきます。
 
-## **FastAPI** 互換性
+## **FastAPI** 互換性 { #fastapi-compatibility }
 
-依存性注入システムがシンプルなので、**FastAPI** は以下のようなものと互換性があります:
+dependency injection システムがシンプルなので、**FastAPI** は以下のようなものと互換性があります:
 
 * すべてのリレーショナルデータベース
 * NoSQLデータベース
@@ -165,15 +203,15 @@ common_parameters --> read_users
 * レスポンスデータ注入システム
 * など。
 
-## シンプルでパワフル
+## シンプルでパワフル { #simple-and-powerful }
 
-階層依存性注入システムは、定義や使用方法が非常にシンプルであるにもかかわらず、非常に強力なものとなっています。
+階層的な dependency injection システムは、定義や使用方法が非常にシンプルであるにもかかわらず、非常に強力なものとなっています。
 
-依存関係事態を定義する依存関係を定義することができます。
+依存関係が、さらに依存関係を定義することもできます。
 
-最終的には、依存関係の階層ツリーが構築され、**依存性注入**システムが、これらの依存関係(およびそのサブ依存関係)をすべて解決し、各ステップで結果を提供(注入)します。
+最終的には、依存関係の階層ツリーが構築され、**Dependency Injection**システムが、これらの依存関係(およびそのサブ依存関係)をすべて解決し、各ステップで結果を提供(注入)します。
 
-例えば、4つのAPIエンドポイント(*path operations*)があるとします:
+例えば、4つのAPIエンドポイント(*path operation*)があるとします:
 
 * `/items/public/`
 * `/items/private/`
@@ -205,8 +243,8 @@ admin_user --> activate_user
 paying_user --> pro_items
 ```
 
-## **OpenAPI** との統合
+## **OpenAPI** との統合 { #integrated-with-openapi_1 }
 
-これら全ての依存関係は、要件を宣言すると同時に、*path operations*にパラメータやバリデーションを追加します。
+これら全ての依存関係は、要件を宣言すると同時に、*path operation*にパラメータやバリデーションを追加します。
 
 **FastAPI** はそれをすべてOpenAPIスキーマに追加して、対話型のドキュメントシステムに表示されるようにします。
index 211a86a0ab65c384bd43dbf37265984fca445c7d..007c320f331d5238a02610194d291aa77371be61 100644 (file)
@@ -1,4 +1,4 @@
-# サブ依存関係
+# サブ依存関係 { #sub-dependencies }
 
 **サブ依存関係** を持つ依存関係を作成することができます。
 
@@ -6,21 +6,21 @@
 
 **FastAPI** はそれらを解決してくれます。
 
-### 最初の依存関係「依存可能なもの」
+## 最初の依存関係「依存可能なもの」 { #first-dependency-dependable }
 
 以下のような最初の依存関係(「依存可能なもの」)を作成することができます:
 
-{* ../../docs_src/dependencies/tutorial005.py hl[8,9] *}
+{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[8:9] *}
 
 これはオプショナルのクエリパラメータ`q`を`str`として宣言し、それを返すだけです。
 
 これは非常にシンプルです(あまり便利ではありません)が、サブ依存関係がどのように機能するかに焦点を当てるのに役立ちます。
 
-### 第二の依存関係 「依存可能なもの」と「依存」
+## 第二の依存関係 「依存可能なもの」と「依存」 { #second-dependency-dependable-and-dependant }
 
 そして、別の依存関数(「依存可能なもの」)を作成して、同時にそれ自身の依存関係を宣言することができます(つまりそれ自身も「依存」です):
 
-{* ../../docs_src/dependencies/tutorial005.py hl[13] *}
+{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[13] *}
 
 宣言されたパラメータに注目してみましょう:
 
 * また、オプショナルの`last_query`クッキーを`str`として宣言します。
     * ユーザーがクエリ`q`を提供しなかった場合、クッキーに保存していた最後に使用したクエリを使用します。
 
-### 依存関係の使用
+## 依存関係の使用 { #use-the-dependency }
 
 以下のように依存関係を使用することができます:
 
-{* ../../docs_src/dependencies/tutorial005.py hl[21] *}
+{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[23] *}
 
 /// info | 情報
 
-*path operation関数*の中で宣言している依存関係は`query_or_cookie_extractor`の1つだけであることに注意してください。
+*path operation 関数*の中で宣言している依存関係は`query_or_cookie_extractor`の1つだけであることに注意してください。
 
 しかし、**FastAPI** は`query_extractor`を最初に解決し、その結果を`query_or_cookie_extractor`を呼び出す時に渡す必要があることを知っています。
 
@@ -54,24 +54,43 @@ read_query["/items/"]
 query_extractor --> query_or_cookie_extractor --> read_query
 ```
 
-## 同じ依存関係の複数回の使用
+## 同じ依存関係の複数回の使用 { #using-the-same-dependency-multiple-times }
 
-依存関係の1つが同じ*path operation*に対して複数回宣言されている場合、例えば、複数の依存関係が共通のサブ依存関係を持っている場合、**FastAPI** はリクエストごとに1回だけそのサブ依存関係を呼び出します。
+依存関係の1つが同じ*path operation*に対して複数回宣言されている場合、例えば、複数の依存関係が共通のサブ依存関係を持っている場合、**FastAPI** はリクエストごとに1回だけそのサブ依存関係を呼び出します。
 
-そして、返された値を<abbr title="計算された値・生成された値を保存するユーティリティまたはシステム、再計算する代わりに再利用するためのもの">「キャッシュ」</abbr>に保存し、同じリクエストに対して依存関係を何度も呼び出す代わりに、特定のリクエストでそれを必要とする全ての「依存関係」に渡すことになります。
+そして、返された値を<abbr title="A utility/system to store computed/generated values, to reuse them instead of computing them again. – 計算/生成された値を保存し、再計算する代わりに再利用するためのユーティリティ/システム。">「キャッシュ」</abbr>に保存し、同じリクエストに対して依存関係を何度も呼び出す代わりに、その特定のリクエストでそれを必要とする全ての「依存」に渡すことになります。
 
-高度なシナリオでは、「キャッシュされた」値を使うのではなく、同じリクエストの各ステップ(おそらく複数回)で依存関係を呼び出す必要があることがわかっている場合、`Depens`を使用する際に、`use_cache=False`というパラメータを設定することができます。
+高度なシナリオでは、「キャッシュされた」値を使うのではなく、同じリクエストの各ステップ(おそらく複数回)で依存関係を呼び出す必要があることがわかっている場合、`Depends`を使用する際に、`use_cache=False`というパラメータを設定することができます:
+
+//// tab | Python 3.9+
+
+```Python hl_lines="1"
+async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
+    return {"fresh_value": fresh_value}
+```
+
+////
+
+//// tab | Python 3.9+ 非Annotated
+
+/// tip | 豆知識
+
+可能であれば`Annotated`版を使うことを推奨します。
+
+///
 
 ```Python hl_lines="1"
 async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False)):
     return {"fresh_value": fresh_value}
 ```
 
-## まとめ
+////
+
+## まとめ { #recap }
 
-ここで使われている派手な言葉は別にして、**依存性注入** システムは非常にシンプルです。
+ここで使われている派手な言葉は別にして、**Dependency Injection** システムは非常にシンプルです。
 
-*path operation関数*と同じように見えるただの関数です。
+*path operation 関数*と同じように見えるただの関数です。
 
 しかし、それでも非常に強力で、任意の深くネストされた依存関係「グラフ」(ツリー)を宣言することができます。
 
index 309cf8857753e04b20de098ac3458b5d3d41b7ab..33cc6ae48c5d734646e2fd6239cf2f13ac669416 100644 (file)
@@ -1,16 +1,16 @@
-# JSON互換エンコーダ
+# JSON互換エンコーダ { #json-compatible-encoder }
 
\83\87ã\83¼ã\82¿å\9e\8bï¼\88Pydanticã\83¢ã\83\87ã\83«ã\81®ã\82\88ã\81\86ã\81ªï¼\89ã\82\92JSONã\81¨äº\92æ\8f\9bæ\80§ã\81®ã\81\82ã\82\8bã\82\82ã\81®ï¼\88`dict`ã\82\84`list`ã\81ªã\81©ï¼\89ã\81«å¤\89æ\9b´ã\81\99ã\82\8bå¿\85è¦\81ã\81\8cã\81\82ã\82\8bå ´å\90\88があります。
\83\87ã\83¼ã\82¿å\9e\8bï¼\88Pydanticã\83¢ã\83\87ã\83«ã\81®ã\82\88ã\81\86ã\81ªï¼\89ã\82\92JSONã\81¨äº\92æ\8f\9bæ\80§ã\81®ã\81\82ã\82\8bã\82\82ã\81®ï¼\88`dict`ã\82\84`list`ã\81ªã\81©ï¼\89ã\81«å¤\89æ\8f\9bã\81\99ã\82\8bå¿\85è¦\81ã\81\8cã\81\82ã\82\8bã\82±ã\83¼ã\82¹があります。
 
 例えば、データベースに保存する必要がある場合です。
 
 そのために、**FastAPI** は`jsonable_encoder()`関数を提供しています。
 
-## `jsonable_encoder`の使用
+## `jsonable_encoder`の使用 { #using-the-jsonable-encoder }
 
 JSON互換のデータのみを受信するデータベース`fake_db`があるとしましょう。
 
-例えば、`datetime`オブジェクトはJSONと互換性がないので、このデーターベースには受け取られません。
+例えば、`datetime`オブジェクトはJSONと互換性がないので、受け取られません。
 
 そのため、`datetime`オブジェクトは<a href="https://en.wikipedia.org/wiki/ISO_8601" class="external-link" target="_blank">ISO形式</a>のデータを含む`str`に変換されなければなりません。
 
@@ -20,7 +20,7 @@ JSON互換のデータのみを受信するデータベース`fake_db`がある
 
 Pydanticモデルのようなオブジェクトを受け取り、JSON互換版を返します:
 
-{* ../../docs_src/encoder/tutorial001.py hl[5,22] *}
+{* ../../docs_src/encoder/tutorial001_py310.py hl[4,21] *}
 
 この例では、Pydanticモデルを`dict`に、`datetime`を`str`に変換します。
 
index 1be1c3f923ccd4f52cfa6178c19dfee31792694f..4ed84e86f88148a204e057e3f245fd1fc675e801 100644 (file)
@@ -1,6 +1,6 @@
-# 追加データ型
+# 追加データ型 { #extra-data-types }
 
-ä»\8aã\81¾ã\81§ã\81¯ã\80\81以ä¸\8bã\81®ã\82\88ã\81\86ã\81ªä¸\80è\88¬ç\9a\84ã\81ªã\83\87ã\83¼ã\82¿å\9e\8bã\82\92使ç\94¨ã\81\97ã\81¦ã\81\8dã\81¾ã\81\97ã\81\9f:
+今まで、以下のような一般的なデータ型を使用してきました:
 
 * `int`
 * `float`
 
 そして、今まで見てきたのと同じ機能を持つことになります:
 
-* 素晴らしいエディタのサポート
-* 受信したリクエストからのデータ変換
-* レスポンスデータのデータ変換
-* データの検証
-* 自動注釈と文書化
+* 素晴らしいエディタのサポート
+* 受信したリクエストからのデータ変換
+* レスポンスデータのデータ変換
+* データの検証
+* 自動注釈と文書化
 
-## 他のデータ型
+## 他のデータ型 { #other-data-types }
 
 ここでは、使用できる追加のデータ型のいくつかを紹介します:
 
     * リクエストとレスポンスでは`str`として表現されます。
 * `datetime.datetime`:
     * Pythonの`datetime.datetime`です。
-    * リクエストとレスポンスはISO 8601形式の`str`で表現されます: `2008-09-15T15:53:00+05:00`
+    * リクエストとレスポンスはISO 8601形式の`str`で表現されます(例: `2008-09-15T15:53:00+05:00`)。
 * `datetime.date`:
-    * Pythonの`datetime.date`です
-    * リクエストとレスポンスはISO 8601形式の`str`で表現されます: `2008-09-15`
+    * Python `datetime.date`
+    * リクエストとレスポンスはISO 8601形式の`str`で表現されます(例: `2008-09-15`)。
 * `datetime.time`:
-    * Pythonの`datetime.time`.
-    * リクエストとレスポンスはISO 8601形式の`str`で表現されます: `14:23:55.003`
+    * Pythonの`datetime.time`
+    * リクエストとレスポンスはISO 8601形式の`str`で表現されます(例: `14:23:55.003`)。
 * `datetime.timedelta`:
     * Pythonの`datetime.timedelta`です。
     * リクエストとレスポンスでは合計秒数の`float`で表現されます。
-    * Pydanticでは「ISO 8601 time diff encoding」として表現することも可能です。<a href="https://docs.pydantic.dev/latest/concepts/serialization/" class="external-link" target="_blank">詳細はドキュメントを参照してください</a>。
+    * Pydanticでは「ISO 8601 time diff encoding」として表現することも可能です。<a href="https://docs.pydantic.dev/latest/concepts/serialization/#custom-serializers" class="external-link" target="_blank">詳細はドキュメントを参照してください</a>。
 * `frozenset`:
     * リクエストとレスポンスでは`set`と同じように扱われます:
         * リクエストでは、リストが読み込まれ、重複を排除して`set`に変換されます。
 * `bytes`:
     * Pythonの標準的な`bytes`です。
     * リクエストとレスポンスでは`str`として扱われます。
-    * 生成されたスキーマは`str`で`binary`の「フォーマット」持つことを指定します。
+    * 生成されたスキーマは`str`で`binary`の「フォーマット」持つことを指定します。
 * `Decimal`:
     * Pythonの標準的な`Decimal`です。
-    * リクエストやレスポンスでは`float`と同じように扱います。
+    * リクエストとレスポンスでは`float`と同じように扱われます。
+* Pydanticの全ての有効な型はこちらで確認できます: <a href="https://docs.pydantic.dev/latest/usage/types/types/" class="external-link" target="_blank">Pydantic data types</a>。
 
-* Pydanticの全ての有効な型はこちらで確認できます: <a href="https://docs.pydantic.dev/latest/concepts/types/" class="external-link" target="_blank">Pydantic data types</a>。
-## 例
+## 例 { #example }
 
 ここでは、上記の型のいくつかを使用したパラメータを持つ*path operation*の例を示します。
 
-{* ../../docs_src/extra_data_types/tutorial001.py hl[1,2,12:16] *}
+{* ../../docs_src/extra_data_types/tutorial001_an_py310.py hl[1,3,12:16] *}
 
-関数内のパラメータは自然なデータ型を持っていることに注意してください。そして、以下のように通常の日付操作を行うことができます:
\96¢æ\95°å\86\85ã\81®ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81¯è\87ªç\84¶ã\81ªã\83\87ã\83¼ã\82¿å\9e\8bã\82\92æ\8c\81ã\81£ã\81¦ã\81\84ã\82\8bã\81\93ã\81¨ã\81«æ³¨æ\84\8fã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82ã\81\9dã\81\97ã\81¦ã\80\81ä¾\8bã\81\88ã\81°ã\80\81以ä¸\8bã\81®ã\82\88ã\81\86ã\81«é\80\9a常ã\81®æ\97¥ä»\98æ\93\8dä½\9cã\82\92è¡\8cã\81\86ã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\81¾ã\81\99:
 
-{* ../../docs_src/extra_data_types/tutorial001.py hl[18,19] *}
+{* ../../docs_src/extra_data_types/tutorial001_an_py310.py hl[18:19] *}
index b7e215409947f6248a4f8845b103294b0de40b1e..05e267818ccceceb20b7f8de1e12bcac45c4515b 100644 (file)
@@ -1,6 +1,6 @@
-# モデル - より詳しく
+# Extra Models { #extra-models }
 
\85\88ã\81»ã\81©ã\81®ä¾\8bã\81«ç¶\9aã\81\8dã\80\81è¤\87æ\95°ã\81®é\96¢é\80£ã\83¢ã\83\87ã\83«ã\82\92æ\8c\81ã\81¤ã\81\93ã\81¨ã\81\8c一般的です。
\85\88ã\81»ã\81©ã\81®ä¾\8bã\81«ç¶\9aã\81\8dã\80\81è¤\87æ\95°ã\81®é\96¢é\80£ã\83¢ã\83\87ã\83«ã\82\92æ\8c\81ã\81¤ã\81\93ã\81¨ã\81¯一般的です。
 
 これはユーザーモデルの場合は特にそうです。なぜなら:
 
@@ -8,27 +8,27 @@
 * **出力モデル**はパスワードをもつべきではありません。
 * **データベースモデル**はおそらくハッシュ化されたパスワードが必要になるでしょう。
 
-/// danger | 危険
+/// danger
 
-ユーザーの平文のパスワードは絶対に保存しないでください。常に認証に利用可能な「安全なハッシュ」を保存してください。
+ユーザーの平文のパスワードは絶対に保存しないでください。常に検証できる「安全なハッシュ」を保存してください。
 
 知らない方は、[セキュリティの章](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}で「パスワードハッシュ」とは何かを学ぶことができます。
 
 ///
 
-## 複数のモデル
+## Multiple models { #multiple-models }
 
 ここでは、パスワードフィールドをもつモデルがどのように見えるのか、また、どこで使われるのか、大まかなイメージを紹介します:
 
-{* ../../docs_src/extra_models/tutorial001.py hl[9,11,16,22,24,29:30,33:35,40:41] *}
+{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
 
-### `**user_in.dict()`について
+### About `**user_in.model_dump()` { #about-user-in-model-dump }
 
-#### Pydanticの`.dict()`
+#### Pydanticの`.model_dump()` { #pydantics-model-dump }
 
 `user_in`は`UserIn`クラスのPydanticモデルです。
 
-Pydanticモデルには、モデルのデータを含む`dict`を返す`.dict()`メソッドがあります。
+Pydanticモデルには、モデルのデータを含む`dict`を返す`.model_dump()`メソッドがあります。
 
 そこで、以下のようなPydanticオブジェクト`user_in`を作成すると:
 
@@ -39,7 +39,7 @@ user_in = UserIn(username="john", password="secret", email="john.doe@example.com
 そして呼び出すと:
 
 ```Python
-user_dict = user_in.dict()
+user_dict = user_in.model_dump()
 ```
 
 これで変数`user_dict`のデータを持つ`dict`ができました。(これはPydanticモデルのオブジェクトの代わりに`dict`です)。
@@ -61,7 +61,7 @@ print(user_dict)
 }
 ```
 
-#### `dict`の展開
+#### `dict`の展開 { #unpacking-a-dict }
 
 `user_dict`のような`dict`を受け取り、それを`**user_dict`を持つ関数(またはクラス)に渡すと、Pythonはそれを「展開」します。これは`user_dict`のキーと値を直接キー・バリューの引数として渡します。
 
@@ -93,31 +93,31 @@ UserInDB(
 )
 ```
 
-#### å\88¥ã\81®ã\83¢ã\83\87ã\83«ã\81\8bã\82\89ã\81¤ã\81\8fã\82\8bPydanticã\83¢ã\83\87ã\83«
+#### å\88¥ã\81®ã\83¢ã\83\87ã\83«ã\81®å\86\85容ã\81\8bã\82\89ã\81¤ã\81\8fã\82\8bPydanticã\83¢ã\83\87ã\83« { #a-pydantic-model-from-the-contents-of-another }
 
-上述の例では`user_in.dict()`から`user_dict`をこのコードのように取得していますが:
+上述の例では`user_in.model_dump()`から`user_dict`をこのコードのように取得していますが:
 
 ```Python
-user_dict = user_in.dict()
+user_dict = user_in.model_dump()
 UserInDB(**user_dict)
 ```
 
 これは以下と同等です:
 
 ```Python
-UserInDB(**user_in.dict())
+UserInDB(**user_in.model_dump())
 ```
 
-...なぜなら`user_in.dict()`は`dict`であり、`**`を付与して`UserInDB`を渡してPythonに「展開」させているからです。
+...なぜなら`user_in.model_dump()`は`dict`であり、`**`を付与して`UserInDB`を渡してPythonに「展開」させているからです。
 
 そこで、別のPydanticモデルのデータからPydanticモデルを取得します。
 
-#### `dict`の展開と追加引数
+#### `dict`の展開と追加キーワード { #unpacking-a-dict-and-extra-keywords }
 
 そして、追加のキーワード引数`hashed_password=hashed_password`を以下のように追加すると:
 
 ```Python
-UserInDB(**user_in.dict(), hashed_password=hashed_password)
+UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
 ```
 
 ...以下のようになります:
@@ -132,13 +132,13 @@ UserInDB(
 )
 ```
 
-/// warning | 注意
+/// warning
 
-サポートしている追加機能は、データの可能な流れをデモするだけであり、もちろん本当のセキュリティを提供しているわけではありません。
+追加のサポート関数`fake_password_hasher`と`fake_save_user`は、データの可能な流れをデモするだけであり、もちろん本当のセキュリティを提供しているわけではありません。
 
 ///
 
-## 重複の削減
+## Reduce duplication { #reduce-duplication }
 
 コードの重複を減らすことは、**FastAPI**の中核的なアイデアの1つです。
 
@@ -152,40 +152,60 @@ UserInDB(
 
 データの変換、検証、文書化などはすべて通常通りに動作します。
 
-このようにして、モデル間の違いだけを宣言することができます:
+このようにして、モデル間の違いだけを宣言することができます(平文の`password`、`hashed_password`、パスワードなし):
 
-{* ../../docs_src/extra_models/tutorial002.py hl[9,15,16,19,20,23,24] *}
+{* ../../docs_src/extra_models/tutorial002_py310.py hl[7,13:14,17:18,21:22] *}
 
-## `Union`または`anyOf`
+## `Union` or `anyOf` { #union-or-anyof }
 
-レスポンスを2つの型の`Union`として宣言することができます。
+レスポンスを2つ以上の型の`Union`として宣言できます。つまり、そのレスポンスはそれらのいずれかになります。
 
 OpenAPIでは`anyOf`で定義されます。
 
 そのためには、標準的なPythonの型ヒント<a href="https://docs.python.org/3/library/typing.html#typing.Union" class="external-link" target="_blank">`typing.Union`</a>を使用します:
 
-{* ../../docs_src/extra_models/tutorial003.py hl[1,14,15,18,19,20,33] *}
+/// note | 備考
 
-## モデルのリスト
+<a href="https://docs.pydantic.dev/latest/concepts/types/#unions" class="external-link" target="_blank">`Union`</a>を定義する場合は、最も具体的な型を先に、その後により具体性の低い型を含めてください。以下の例では、より具体的な`PlaneItem`が`Union[PlaneItem, CarItem]`内で`CarItem`より前に来ています。
 
-同じように、オブジェクトのリストのレスポンスを宣言することができます。
+///
+
+{* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *}
+
+### Python 3.10の`Union` { #union-in-python-3-10 }
+
+この例では、引数`response_model`の値として`Union[PlaneItem, CarItem]`を渡しています。
+
+**型アノテーション**に書くのではなく、**引数の値**として渡しているため、Python 3.10でも`Union`を使う必要があります。
+
+型アノテーションであれば、次のように縦棒を使用できました:
+
+```Python
+some_variable: PlaneItem | CarItem
+```
+
+しかし、これを代入で`response_model=PlaneItem | CarItem`のように書くと、Pythonはそれを型アノテーションとして解釈するのではなく、`PlaneItem`と`CarItem`の間で**無効な操作**を行おうとしてしまうため、エラーになります。
+
+## List of models { #list-of-models }
+
+同じように、オブジェクトのリストのレスポンスを宣言できます。
 
-そのためには、標準のPythonの`typing.List`を使用する:
+そのためには、標準のPythonの`typing.List`(またはPython 3.9以降では単に`list`)を使用します:
 
-{* ../../docs_src/extra_models/tutorial004.py hl[1,20] *}
+{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
 
-## 任意の`dict`を持つレスポンス
+## Response with arbitrary `dict` { #response-with-arbitrary-dict }
 
 また、Pydanticモデルを使用せずに、キーと値の型だけを定義した任意の`dict`を使ってレスポンスを宣言することもできます。
 
 これは、有効なフィールド・属性名(Pydanticモデルに必要なもの)を事前に知らない場合に便利です。
 
-この場合、`typing.Dict`を使用することができます:
+この場合、`typing.Dict`(またはPython 3.9以降では単に`dict`)を使用できます:
 
-{* ../../docs_src/extra_models/tutorial005.py hl[1,8] *}
+{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
 
-## まとめ
+## Recap { #recap }
 
 複数のPydanticモデルを使用し、ケースごとに自由に継承します。
 
-エンティティが異なる「状態」を持たなければならない場合は、エンティティごとに単一のデータモデルを持つ必要はありません。`password` や `password_hash` やパスワードなしなどのいくつかの「状態」をもつユーザー「エンティティ」の場合の様にすれば良いです。
+エンティティが異なる「状態」を持たなければならない場合は、エンティティごとに単一のデータモデルを持つ必要はありません。`password`、`password_hash`、パスワードなしを含む状態を持つユーザー「エンティティ」の場合と同様です。
index 77f9cba43bc59e516ab7f760d2f9385c500ea03e..ecad2f6ff9764726547838bf79ce705bbf1191f4 100644 (file)
@@ -1,8 +1,8 @@
-# 最初のステップ
+# 最初のステップ { #first-steps }
 
 最もシンプルなFastAPIファイルは以下のようになります:
 
-{* ../../docs_src/first_steps/tutorial001.py *}
+{* ../../docs_src/first_steps/tutorial001_py39.py *}
 
 これを`main.py`にコピーします。
 
 <div class="termy">
 
 ```console
-$ uvicorn main:app --reload
+$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
 
-<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-<span style="color: green;">INFO</span>:     Started reloader process [28720]
-<span style="color: green;">INFO</span>:     Started server process [28722]
-<span style="color: green;">INFO</span>:     Waiting for application startup.
-<span style="color: green;">INFO</span>:     Application startup complete.
-```
+  <span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span>  Starting development server 🚀
 
-</div>
+             Searching for package file structure from directories
+             with <font color="#3465A4">__init__.py</font> files
+             Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
 
-/// note | 備考
+   <span style="background-color:#007166"><font color="#D3D7CF"> module </font></span>  🐍 main.py
 
-`uvicorn main:app`は以下を示します:
+     <span style="background-color:#007166"><font color="#D3D7CF"> code </font></span>  Importing the FastAPI app object from the module with
+             the following code:
 
-* `main`: `main.py`ファイル (Python "module")。
-* `app`:  `main.py`内部で作られるobject(`app = FastAPI()`のように記述される)。
-* `--reload`: コードの変更時にサーバーを再起動させる。開発用。
+             <u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
 
-///
+      <span style="background-color:#007166"><font color="#D3D7CF"> app </font></span>  Using import string: <font color="#3465A4">main:app</font>
+
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font>
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000/docs</u></font>
+
+      <span style="background-color:#007166"><font color="#D3D7CF"> tip </font></span>  Running in development mode, for production use:
+             <b>fastapi run</b>
+
+             Logs:
+
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Will watch for changes in these directories:
+             <b>[</b><font color="#4E9A06">&apos;/home/user/code/awesomeapp&apos;</font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font> <b>(</b>Press CTRL+C
+             to quit<b>)</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started reloader process <b>[</b><font color="#34E2E2"><b>383138</b></font><b>]</b> using WatchFiles
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started server process <b>[</b><font color="#34E2E2"><b>383153</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Waiting for application startup.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Application startup complete.
+```
+
+</div>
 
 出力には次のような行があります:
 
@@ -40,7 +56,7 @@ INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 
 この行はローカルマシンでアプリが提供されているURLを示しています。
 
-### チェック
+### チェック { #check-it }
 
 ブラウザで<a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>を開きます。
 
@@ -50,7 +66,7 @@ INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 {"message": "Hello World"}
 ```
 
-### 対話的APIドキュメント
+### 対話的APIドキュメント { #interactive-api-docs }
 
 次に、<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>にアクセスします。
 
@@ -58,7 +74,7 @@ INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 
 ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
 
-### ä»\96ã\81®APIã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88
+### ä»£æ\9b¿APIã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88 { #alternative-api-docs }
 
 次に、<a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>にアクセスします。
 
@@ -66,31 +82,31 @@ INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
 
-### OpenAPI
+### OpenAPI { #openapi }
 
 **FastAPI**は、APIを定義するための**OpenAPI**標準規格を使用して、すべてのAPIの「スキーマ」を生成します。
 
-#### 「スキーマ」
+#### 「スキーマ」 { #schema }
 
 「スキーマ」は定義または説明です。実装コードではなく、単なる抽象的な説明です。
 
-#### API「スキーマ」
+#### API「スキーマ」 { #api-schema }
 
 ここでは、<a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a>はAPIのスキーマ定義の方法を規定する仕様です。
 
 このスキーマ定義はAPIパス、受け取り可能なパラメータなどが含まれます。
 
-#### データ「スキーマ」
+#### データ「スキーマ」 { #data-schema }
 
 「スキーマ」という用語は、JSONコンテンツなどの一部のデータの形状を指す場合もあります。
 
 そのような場合、スキーマはJSON属性とそれらが持つデータ型などを意味します。
 
-#### OpenAPIおよびJSONスキーマ
+#### OpenAPIおよびJSONスキーマ { #openapi-and-json-schema }
 
 OpenAPIはAPIのためのAPIスキーマを定義します。そして、そのスキーマは**JSONデータスキーマ**の標準規格に準拠したJSONスキーマを利用するAPIによって送受されるデータの定義(または「スキーマ」)を含んでいます。
 
-#### `openapi.json`を確認
+#### `openapi.json`を確認 { #check-the-openapi-json }
 
 素のOpenAPIスキーマがどのようなものか興味がある場合、FastAPIはすべてのAPIの説明を含むJSON(スキーマ)を自動的に生成します。
 
@@ -100,7 +116,7 @@ OpenAPIはAPIのためのAPIスキーマを定義します。そして、その
 
 ```JSON
 {
-    "openapi": "3.0.2",
+    "openapi": "3.1.0",
     "info": {
         "title": "FastAPI",
         "version": "0.1.0"
@@ -119,7 +135,7 @@ OpenAPIはAPIのためのAPIスキーマを定義します。そして、その
 ...
 ```
 
-#### OpenAPIの目的
+#### OpenAPIの目的 { #what-is-openapi-for }
 
 OpenAPIスキーマは、FastAPIに含まれている2つのインタラクティブなドキュメントシステムの動力源です。
 
@@ -127,60 +143,68 @@ OpenAPIスキーマは、FastAPIに含まれている2つのインタラクテ
 
 また、APIと通信するクライアント用のコードを自動的に生成するために使用することもできます。たとえば、フロントエンド、モバイル、またはIoTアプリケーションです。
 
-## ステップ毎の要約
+### アプリをデプロイ(任意) { #deploy-your-app-optional }
 
-### Step 1: `FastAPI`をインポート
+任意でFastAPIアプリを<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>にデプロイできます。まだなら、待機リストに登録してください。 🚀
 
-{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
+すでに**FastAPI Cloud**アカウントがある場合(待機リストから招待済みの場合😉)、1コマンドでアプリケーションをデプロイできます。
 
-`FastAPI`は、APIのすべての機能を提供するPythonクラスです。
-
-/// note | 技術詳細
+デプロイする前に、ログインしていることを確認してください:
 
-`FastAPI`は`Starlette`を直接継承するクラスです。
-
-`FastAPI`でも<a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a>のすべての機能を利用可能です。
-
-///
+<div class="termy">
 
-### Step 2: `FastAPI`の「インスタンス」を生成
+```console
+$ fastapi login
 
-{* ../../docs_src/first_steps/tutorial001.py hl[3] *}
-ここで、`app`変数が`FastAPI`クラスの「インスタンス」になります。
+You are logged in to FastAPI Cloud 🚀
+```
 
-これが、すべてのAPIを作成するための主要なポイントになります。
+</div>
 
\81\93ã\81®`app`ã\81¯ã\82³ã\83\9eã\83³ã\83\89ã\81§`uvicorn`ã\81\8cå\8f\82ç\85§ã\81\99ã\82\8bã\82\82ã\81®ã\81¨å\90\8cã\81\98ã\81§す:
\81\9dã\81®å¾\8cã\80\81ã\82¢ã\83\97ã\83ªã\82\92ã\83\87ã\83\97ã\83­ã\82¤ã\81\97ã\81¾す:
 
 <div class="termy">
 
 ```console
-$ uvicorn main:app --reload
+$ fastapi deploy
+
+Deploying to FastAPI Cloud...
+
+✅ Deployment successful!
 
-<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
 ```
 
 </div>
 
-以ä¸\8bã\81®ã\82\88ã\81\86ã\81ªã\82¢ã\83\97ã\83ªã\82\92ä½\9cæ\88\90ã\81\97ã\81\9fã\81¨ã\81\8d:
+以ä¸\8aã\81§ã\81\99ï¼\81ã\81\93ã\82\8cã\81§ã\80\81ã\81\9dã\81®URLã\81§ã\82¢ã\83\97ã\83ªã\81«ã\82¢ã\82¯ã\82»ã\82¹ã\81§ã\81\8dã\81¾ã\81\99ã\80\82 â\9c¨
 
-{* ../../docs_src/first_steps/tutorial002.py hl[3] *}
+## ステップ毎の要約 { #recap-step-by-step }
 
-そして、それを`main.py`ファイルに置き、次のように`uvicorn`を呼び出します:
+### Step 1: `FastAPI`をインポート { #step-1-import-fastapi }
 
-<div class="termy">
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
 
-```console
-$ uvicorn main:my_awesome_api --reload
+`FastAPI`は、APIのすべての機能を提供するPythonクラスです。
 
-<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-```
+/// note | 技術詳細
 
-</div>
+`FastAPI`は`Starlette`を直接継承するクラスです。
 
-### Step 3: *path operation*を作成
+`FastAPI`でも<a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a>のすべての機能を利用可能です。
+
+///
+
+### Step 2: `FastAPI`の「インスタンス」を生成 { #step-2-create-a-fastapi-instance }
 
-#### パス
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
+ここで、`app`変数が`FastAPI`クラスの「インスタンス」になります。
+
+これが、すべてのAPIを作成するための主要なポイントになります。
+
+### Step 3: *path operation*を作成 { #step-3-create-a-path-operation }
+
+#### パス { #path }
 
 ここでの「パス」とは、最初の`/`から始まるURLの最後の部分を指します。
 
@@ -204,7 +228,7 @@ https://example.com/items/foo
 
 APIを構築する際、「パス」は「関心事」と「リソース」を分離するための主要な方法です。
 
-#### Operation
+#### Operation { #operation }
 
 ここでの「オペレーション」とは、HTTPの「メソッド」の1つを指します。
 
@@ -239,15 +263,16 @@ APIを構築するときは、通常、これらの特定のHTTPメソッドを
 
 「**オペレーションズ**」とも呼ぶことにします。
 
-#### *パスオペレーションデコレータ*を定義
+#### *path operation デコレータ*を定義 { #define-a-path-operation-decorator }
+
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
 
-{* ../../docs_src/first_steps/tutorial001.py hl[6] *}
 `@app.get("/")`は直下の関数が下記のリクエストの処理を担当することを**FastAPI**に伝えます:
 
 * パス `/`
 * <abbr title="an HTTP GET method"><code>get</code> オペレーション</abbr>
 
-/// info | `@decorator` について
+/// info | `@decorator` Info
 
 Pythonにおける`@something`シンタックスはデコレータと呼ばれます。
 
@@ -255,9 +280,9 @@ Pythonにおける`@something`シンタックスはデコレータと呼ばれ
 
 「デコレータ」は直下の関数を受け取り、それを使って何かを行います。
 
-私たちの場合、このデコレーターは直下の関数が**オペレーション** `get`を使用した**パス**` / `に対応することを**FastAPI** に通知します。
+私たちの場合、このデコレーターは直下の関数が**オペレーション** `get`を使用した**パス** `/`に対応することを**FastAPI** に通知します。
 
-これが「*パスオペレーションデコレータ*」です。
+これが「*path operation デコレータ*」です。
 
 ///
 
@@ -286,15 +311,15 @@ Pythonにおける`@something`シンタックスはデコレータと呼ばれ
 
 ///
 
-### Step 4: **パスオペレーション**を定義
+### Step 4: **path operation 関数**を定義 { #step-4-define-the-path-operation-function }
 
-以下は「**パスオペレーション関数**」です:
+以下は「**path operation 関数**」です:
 
 * **パス**: は`/`です。
 * **オペレーション**: は`get`です。
 * **関数**: 「デコレータ」の直下にある関数 (`@app.get("/")`の直下) です。
 
-{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
 
 これは、Pythonの関数です。
 
@@ -306,28 +331,49 @@ Pythonにおける`@something`シンタックスはデコレータと呼ばれ
 
 `async def`の代わりに通常の関数として定義することもできます:
 
-{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
 
 /// note | 備考
 
-違いが分からない場合は、[Async: *"急いでいますか?"*](../async.md#_1){.internal-link target=_blank}を確認してください。
+違いが分からない場合は、[Async: *"急いでいますか?"*](../async.md#in-a-hurry){.internal-link target=_blank}を確認してください。
 
 ///
 
-### Step 5: コンテンツの返信
+### Step 5: コンテンツの返信 { #step-5-return-the-content }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
 
-`dict`、`list`、`str`、`int`などを返すことができます。
+`dict`ã\80\81`list`ã\80\81`str`ã\80\81`int`ã\81ªã\81©ã\81®å\8d\98ä¸\80ã\81®å\80¤ã\82\92è¿\94ã\81\99ã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\81¾ã\81\99ã\80\82
 
 Pydanticモデルを返すこともできます(後で詳しく説明します)。
 
 JSONに自動的に変換されるオブジェクトやモデルは他にもたくさんあります(ORMなど)。 お気に入りのものを使ってみてください。すでにサポートされている可能性が高いです。
 
-## まとめ
+### Step 6: デプロイする { #step-6-deploy-it }
+
+**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>**に1コマンドでアプリをデプロイします: `fastapi deploy`. 🎉
+
+#### FastAPI Cloudについて { #about-fastapi-cloud }
+
+**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>**は、**FastAPI**の作者とそのチームによって開発されています。
+
+最小限の労力でAPIの**構築**、**デプロイ**、**アクセス**を行うプロセスを合理化します。
+
+FastAPIでアプリを構築するのと同じ**開発体験**を、クラウドへの**デプロイ**にもたらします。 🎉
+
+FastAPI Cloudは、*FastAPI and friends*のオープンソースプロジェクトに対する主要スポンサーであり、資金提供元です。 ✨
+
+#### 他のクラウドプロバイダにデプロイする { #deploy-to-other-cloud-providers }
+
+FastAPIはオープンソースで、標準に基づいています。選択した任意のクラウドプロバイダにFastAPIアプリをデプロイできます。
+
+クラウドプロバイダのガイドに従って、FastAPIアプリをデプロイしてください。 🤓
+
+## まとめ { #recap }
 
-* `FastAPI`をインポート
-* `app`インスタンスを生成
-* **パスオペレーションデコレータ**を記述 (`@app.get("/")`)
-* **パスオペレーション関数**を定義 (上記の`def root(): ...`のように)
-* 開発サーバーを起動 (`uvicorn main:app --reload`)
+* `FastAPI`をインポートします。
+* `app`インスタンスを生成します。
+* `@app.get("/")`のようなデコレータを使用して、**path operation デコレータ**を記述します。
+* **path operation 関数**を定義します。例: `def root(): ...`。
+* `fastapi dev`コマンドで開発サーバーを起動します。
+* 任意で`fastapi deploy`を使ってアプリをデプロイします。
index 8578ca33560c06310cb3594e59b54c647636ea6e..945fe07772b72fe10b34a3189239b039a5aea503 100644 (file)
@@ -1,4 +1,4 @@
-# エラーハンドリング
+# エラーハンドリング { #handling-errors }
 
 APIを使用しているクライアントにエラーを通知する必要がある状況はたくさんあります。
 
@@ -19,15 +19,15 @@ APIを使用しているクライアントにエラーを通知する必要が
 
 **"404 Not Found"** のエラー(およびジョーク)を覚えていますか?
 
-## `HTTPException`の使用
+## `HTTPException`の使用 { #use-httpexception }
 
 HTTPレスポンスをエラーでクライアントに返すには、`HTTPException`を使用します。
 
-### `HTTPException`のインポート
+### `HTTPException`のインポート { #import-httpexception }
 
-{* ../../docs_src/handling_errors/tutorial001.py hl[1] *}
+{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
 
-### コード内での`HTTPException`の発生
+### コード内での`HTTPException`の発生 { #raise-an-httpexception-in-your-code }
 
 `HTTPException`は通常のPythonの例外であり、APIに関連するデータを追加したものです。
 
@@ -39,9 +39,9 @@ Pythonの例外なので、`return`ではなく、`raise`です。
 
 この例では、クライアントが存在しないIDでアイテムを要求した場合、`404`のステータスコードを持つ例外を発生させます:
 
-{* ../../docs_src/handling_errors/tutorial001.py hl[11] *}
+{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
 
-### レスポンス結果
+### レスポンス結果 { #the-resulting-response }
 
 クライアントが`http://example.com/items/foo`(`item_id` `"foo"`)をリクエストすると、HTTPステータスコードが200で、以下のJSONレスポンスが返されます:
 
@@ -69,7 +69,7 @@ Pythonの例外なので、`return`ではなく、`raise`です。
 
 ///
 
-## カスタムヘッダーの追加
+## カスタムヘッダーの追加 { #add-custom-headers }
 
 例えば、いくつかのタイプのセキュリティのために、HTTPエラーにカスタムヘッダを追加できると便利な状況がいくつかあります。
 
@@ -77,9 +77,9 @@ Pythonの例外なので、`return`ではなく、`raise`です。
 
 しかし、高度なシナリオのために必要な場合には、カスタムヘッダーを追加することができます:
 
-{* ../../docs_src/handling_errors/tutorial002.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
 
-## カスタム例外ハンドラのインストール
+## カスタム例外ハンドラのインストール { #install-custom-exception-handlers }
 
 カスタム例外ハンドラは<a href="https://www.starlette.dev/exceptions/" class="external-link" target="_blank">Starletteと同じ例外ユーティリティ</a>を使用して追加することができます。
 
@@ -89,7 +89,7 @@ Pythonの例外なので、`return`ではなく、`raise`です。
 
 カスタム例外ハンドラを`@app.exception_handler()`で追加することができます:
 
-{* ../../docs_src/handling_errors/tutorial003.py hl[5,6,7,13,14,15,16,17,18,24] *}
+{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
 
 ここで、`/unicorns/yolo`をリクエストすると、*path operation*は`UnicornException`を`raise`します。
 
@@ -109,7 +109,7 @@ Pythonの例外なので、`return`ではなく、`raise`です。
 
 ///
 
-## デフォルトの例外ハンドラのオーバーライド
+## デフォルトの例外ハンドラのオーバーライド { #override-the-default-exception-handlers }
 
 **FastAPI** にはいくつかのデフォルトの例外ハンドラがあります。
 
@@ -117,7 +117,7 @@ Pythonの例外なので、`return`ではなく、`raise`です。
 
 これらの例外ハンドラを独自のものでオーバーライドすることができます。
 
-### リクエスト検証の例外のオーバーライド
+### リクエスト検証の例外のオーバーライド { #override-request-validation-exceptions }
 
 リクエストに無効なデータが含まれている場合、**FastAPI** は内部的に`RequestValidationError`を発生させます。
 
@@ -125,11 +125,11 @@ Pythonの例外なので、`return`ではなく、`raise`です。
 
 これをオーバーライドするには`RequestValidationError`をインポートして`@app.exception_handler(RequestValidationError)`と一緒に使用して例外ハンドラをデコレートします。
 
-この例外ハンドラは`Requset`と例外を受け取ります。
+この例外ハンドラは`Request`と例外を受け取ります。
 
-{* ../../docs_src/handling_errors/tutorial004.py hl[2,14,15,16] *}
+{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
 
-これで、`/items/foo`にアクセスすると、デフォルトのJSONエラーの代わりに以下が返されます:
+これで、`/items/foo`にアクセスすると、以下のデフォルトのJSONエラーの代わりに:
 
 ```JSON
 {
@@ -146,39 +146,20 @@ Pythonの例外なので、`return`ではなく、`raise`です。
 }
 ```
 
-以ä¸\8bã\81®ã\82\88ã\81\86ã\81ªã\83\86ã\82­ã\82¹ã\83\88ç\89\88ã\82\92å\8f\96å¾\97ã\81\97ã\81¾ã\81\99:
+以下のテキスト版を取得します:
 
 ```
-1 validation error
-path -> item_id
-  value is not a valid integer (type=type_error.integer)
+Validation errors:
+Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to parse string as an integer
 ```
 
-#### `RequestValidationError`と`ValidationError`
-
-/// warning | 注意
-
-これらは今のあなたにとって重要でない場合は省略しても良い技術的な詳細です。
-
-///
-
-`RequestValidationError`はPydanticの<a href="https://docs.pydantic.dev/latest/concepts/models/#error-handling" class="external-link" target="_blank">`ValidationError`</a>のサブクラスです。
-
-**FastAPI** は`response_model`でPydanticモデルを使用していて、データにエラーがあった場合、ログにエラーが表示されるようにこれを使用しています。
-
-しかし、クライアントやユーザーはそれを見ることはありません。その代わりに、クライアントはHTTPステータスコード`500`の「Internal Server Error」を受け取ります。
-
-*レスポンス*やコードのどこか(クライアントの*リクエスト*ではなく)にPydanticの`ValidationError`がある場合、それは実際にはコードのバグなのでこのようにすべきです。
-
-また、あなたがそれを修正している間は、セキュリティの脆弱性が露呈する場合があるため、クライアントやユーザーがエラーに関する内部情報にアクセスできないようにしてください。
-
-### エラーハンドラ`HTTPException`のオーバーライド
+### `HTTPException`エラーハンドラのオーバーライド { #override-the-httpexception-error-handler }
 
 同様に、`HTTPException`ハンドラをオーバーライドすることもできます。
 
 例えば、これらのエラーに対しては、JSONではなくプレーンテキストを返すようにすることができます:
 
-{* ../../docs_src/handling_errors/tutorial004.py hl[3,4,9,10,11,22] *}
+{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
 
 /// note | 技術詳細
 
@@ -188,13 +169,21 @@ path -> item_id
 
 ///
 
-### `RequestValidationError`のボディの使用
+/// warning | 注意
+
+`RequestValidationError`には、検証エラーが発生したファイル名と行番号の情報が含まれているため、必要であれば関連情報と一緒にログに表示できます。
+
+しかし、そのまま文字列に変換して直接その情報を返すと、システムに関する情報が多少漏えいする可能性があります。そのため、ここではコードが各エラーを個別に抽出して表示します。
+
+///
+
+### `RequestValidationError`のボディの使用 { #use-the-requestvalidationerror-body }
 
 `RequestValidationError`には無効なデータを含む`body`が含まれています。
 
-アプリ開発中に本体のログを取ってデバッグしたり、ユーザーに返したりなどに使用することができます。
+アプリ開発中にボディのログを取ってデバッグしたり、ユーザーに返したりなどに使用することができます。
 
-{* ../../docs_src/handling_errors/tutorial005.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
 
 ここで、以下のような無効な項目を送信してみてください:
 
@@ -207,7 +196,7 @@ path -> item_id
 
 受信したボディを含むデータが無効であることを示すレスポンスが表示されます:
 
-```JSON hl_lines="12 13 14 15"
+```JSON hl_lines="12-15"
 {
   "detail": [
     {
@@ -226,36 +215,30 @@ path -> item_id
 }
 ```
 
-#### FastAPIの`HTTPException`とStarletteの`HTTPException`
+#### FastAPIの`HTTPException`とStarletteの`HTTPException` { #fastapis-httpexception-vs-starlettes-httpexception }
 
 **FastAPI**は独自の`HTTPException`を持っています。
 
-また、 **FastAPI**のエラークラス`HTTPException`はStarletteのエラークラス`HTTPException`を継承しています。
-
-唯一の違いは、**FastAPI** の`HTTPException`はレスポンスに含まれるヘッダを追加できることです。
+また、 **FastAPI**の`HTTPException`エラークラスはStarletteの`HTTPException`エラークラスを継承しています。
 
-これはOAuth 2.0といくつかのセキュリティユーティリティのために内部的に必要とされ、使用されています。
+唯一の違いは、**FastAPI** の`HTTPException`は`detail`フィールドにJSONに変換可能な任意のデータを受け付けるのに対し、Starletteの`HTTPException`は文字列のみを受け付けることです。
 
 そのため、コード内では通常通り **FastAPI** の`HTTPException`を発生させ続けることができます。
 
\81\97ã\81\8bã\81\97ã\80\81ä¾\8bå¤\96ã\83\8fã\83³ã\83\89ã\83©ã\82\92ç\99»é\8c²ã\81\99ã\82\8bé\9a\9bã\81«ã\81¯ã\80\81Starletteã\81®`HTTPException`ã\82\92登録しておく必要があります。
\81\97ã\81\8bã\81\97ã\80\81ä¾\8bå¤\96ã\83\8fã\83³ã\83\89ã\83©ã\82\92ç\99»é\8c²ã\81\99ã\82\8bé\9a\9bã\81«ã\81¯ã\80\81Starletteã\81®`HTTPException`ã\81«å¯¾ã\81\97ã\81¦登録しておく必要があります。
 
-これにより、Starletteの内部コードやStarletteの拡張機能やプラグインの一部が`HTTPException`を発生させた場合、ハンドラがそれをキャッチして処理することができるようになります。
+これにより、Starletteの内部コードやStarletteの拡張機能やプラグインの一部がStarletteの`HTTPException`を発生させた場合、ハンドラがそれをキャッチして処理できるようになります。
 
-以下の例では、同じコード内で両方の`HTTPException`を使用できるようにするために、Starletteの例外の名前を`StarletteHTTPException`に変更しています:
+この例では、同じコード内で両方の`HTTPException`を使用できるようにするために、Starletteの例外を`StarletteHTTPException`にリネームしています:
 
 ```Python
 from starlette.exceptions import HTTPException as StarletteHTTPException
 ```
 
-### **FastAPI** の例外ハンドラの再利用
-
-また、何らかの方法で例外を使用することもできますが、**FastAPI** から同じデフォルトの例外ハンドラを使用することもできます。
-
-デフォルトの例外ハンドラを`fastapi.exception_handlers`からインポートして再利用することができます:
+### **FastAPI** の例外ハンドラの再利用 { #reuse-fastapis-exception-handlers }
 
-{* ../../docs_src/handling_errors/tutorial006.py hl[2,3,4,5,15,21] *}
+**FastAPI** から同じデフォルトの例外ハンドラと一緒に例外を使用したい場合は、`fastapi.exception_handlers`からデフォルトの例外ハンドラをインポートして再利用できます:
 
-この例では、非常に表現力のあるメッセージでエラーを`print`しています。
+{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
 
\81\97ã\81\8bã\81\97ã\80\81ä¾\8bå¤\96ã\82\92使ç\94¨ã\81\97ã\81¦ã\80\81ã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\81®ä¾\8bå¤\96ã\83\8fã\83³ã\83\89ã\83©ã\82\92å\86\8då\88©ç\94¨ã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\82\8bã\81¨ã\81\84ã\81\86ã\81\93ã\81¨ã\81\8cç\90\86è§£できます。
\81\93ã\81®ä¾\8bã\81§ã\81¯ã\80\81é\9d\9e常ã\81«è¡¨ç\8f¾å\8a\9bã\81®ã\81\82ã\82\8bã\83¡ã\83\83ã\82»ã\83¼ã\82¸ã\81§ã\82¨ã\83©ã\83¼ã\82\92`print`ã\81\97ã\81¦ã\81\84ã\82\8bã\81 ã\81\91ã\81§ã\81\99ã\81\8cã\80\81è¦\81ç\82¹ã\81¯ç\90\86è§£ã\81§ã\81\8dã\82\8bã\81¯ã\81\9aã\81§ã\81\99ã\80\82ä¾\8bå¤\96ã\82\92使ç\94¨ã\81\97ã\80\81ã\81\9dã\81®å¾\8cã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\81®ä¾\8bå¤\96ã\83\8fã\83³ã\83\89ã\83©ã\82\92å\86\8då\88©ç\94¨できます。
index ac89afbdbaf7110df58d334f1c233bba7fe44305..1916baf61360428e8f315d0327d99dd14147d49b 100644 (file)
@@ -1,20 +1,20 @@
-# ヘッダーのパラメータ
+# ヘッダーのパラメータ { #header-parameters }
 
 ヘッダーのパラメータは、`Query`や`Path`、`Cookie`のパラメータを定義するのと同じように定義できます。
 
-## `Header`をインポート
+## `Header`をインポート { #import-header }
 
 まず、`Header`をインポートします:
 
-{* ../../docs_src/header_params/tutorial001.py hl[3] *}
+{* ../../docs_src/header_params/tutorial001_an_py310.py hl[3] *}
 
-## `Header`のパラメータの宣言
+## `Header`のパラメータの宣言 { #declare-header-parameters }
 
 次に、`Path`や`Query`、`Cookie`と同じ構造を用いてヘッダーのパラメータを宣言します。
 
-最初の値がデフォルト値で、追加の検証パラメータや注釈パラメータをすべて渡すことができます。
+デフォルト値に加えて、追加の検証パラメータや注釈パラメータをすべて定義できます:
 
-{* ../../docs_src/header_params/tutorial001.py hl[9] *}
+{* ../../docs_src/header_params/tutorial001_an_py310.py hl[9] *}
 
 /// note | 技術詳細
 
 
 ///
 
-## 自動変換
+## 自動変換 { #automatic-conversion }
 
 `Header`は`Path`や`Query`、`Cookie`が提供する機能に加え、少しだけ追加の機能を持っています。
 
-ほとんどの標準ヘッダーは、「マイナス記号」(`-`)としても知られる「ハイフン」で区切られています。
+ほとんどの標準ヘッダーは、「マイナス記号」(`-`)としても知られる「ハイフン」文字で区切られています。
 
 しかし、`user-agent`のような変数はPythonでは無効です。
 
-そのため、デフォルトでは、`Header`はパラメータの文字をアンダースコア(`_`)からハイフン(`-`)に変換して、ヘッダーを抽出して文書化します。
+そのため、デフォルトでは、`Header`はパラメータの文字をアンダースコア(`_`)からハイフン(`-`)に変換して、ヘッダーを抽出して文書化します。
 
 また、HTTPヘッダは大文字小文字を区別しないので、Pythonの標準スタイル(別名「スネークケース」)で宣言することができます。
 
 そのため、`User_Agent`などのように最初の文字を大文字にする必要はなく、通常のPythonコードと同じように`user_agent`を使用することができます。
 
-もしなんらかの理由でアンダースコアからハイフンへの自動変換を無効にする必要がある場合は、`Header`の`convert_underscores`に`False`を設定してください:
+もしなんらかの理由でアンダースコアからハイフンへの自動変換を無効にする必要がある場合は、`Header`のパラメータ`convert_underscores`を`False`に設定してください:
 
-{* ../../docs_src/header_params/tutorial002.py hl[9] *}
+{* ../../docs_src/header_params/tutorial002_an_py310.py hl[10] *}
 
 /// warning | 注意
 
 
 ///
 
-## ヘッダーの重複
+## ヘッダーの重複 { #duplicate-headers }
 
 受信したヘッダーが重複することがあります。つまり、同じヘッダーで複数の値を持つということです。
 
-これらの場合、リストの型宣言を使用して定義することができます。
+これらの場合、型宣言でリストを使用して定義することができます。
 
 重複したヘッダーのすべての値をPythonの`list`として受け取ることができます。
 
 例えば、複数回出現する可能性のある`X-Token`のヘッダを定義するには、以下のように書くことができます:
 
-{* ../../docs_src/header_params/tutorial003.py hl[9] *}
+{* ../../docs_src/header_params/tutorial003_an_py310.py hl[9] *}
 
\82\82ã\81\97ã\80\81ã\81\9dã\81®*path operation*ã\81§é\80\9aä¿¡ã\81\99ã\82\8bå ´å\90\88ã\81¯ã\80\81次ã\81®ã\82\88ã\81\86ã\81«ï¼\92ã\81¤ã\81®HTTPã\83\98ã\83\83ã\83\80ã\83¼ã\82\92é\80\81ä¿¡ã\81\97ã\81¾ã\81\99:
\81\9dã\81®*path operation*ã\81¨é\80\9aä¿¡ã\81\99ã\82\8bé\9a\9bã\81«ã\80\81次ã\81®ã\82\88ã\81\86ã\81«2ã\81¤ã\81®HTTPã\83\98ã\83\83ã\83\80ã\83¼ã\82\92é\80\81ä¿¡ã\81\99ã\82\8bå ´å\90\88:
 
 ```
 X-Token: foo
 X-Token: bar
 ```
 
\81\93ã\81®ã\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\81¯ä»¥ä¸\8bã\81®ã\82\88ã\81\86ã\81«ã\81ªã\82\8aã\81¾ã\81\99:
+レスポンスは以下のようになります:
 
 ```JSON
 {
@@ -84,8 +84,8 @@ X-Token: bar
 }
 ```
 
-## まとめ
+## まとめ { #recap }
 
-ヘッダーは`Header`で宣言し、`Query`や`Path`、`Cookie`と同じパターンを使用する
+ヘッダーは`Header`で宣言し、`Query`や`Path`、`Cookie`と同じ共通パターンを使用します
 
 また、変数のアンダースコアを気にする必要はありません。**FastAPI** がそれらの変換をすべて取り持ってくれます。
index 87d3751fd916cc23d532d423f7ae3162b0329864..d298abc62d7d5e5a4660a04d306a2ce26375e251 100644 (file)
@@ -1,83 +1,95 @@
-# チュートリアル - ユーザーガイド
+# チュートリアル - ユーザーガイド { #tutorial-user-guide }
 
\81\93ã\81®ã\83\81ã\83¥ã\83¼ã\83\88ã\83ªã\82¢ã\83«ã\81¯**FastAPI**ã\81®ã\81»ã\81¼ã\81\99ã\81¹ã\81¦ã\81®æ©\9fè\83½ã\81®ä½¿ã\81\84æ\96¹を段階的に紹介します。
\81\93ã\81®ã\83\81ã\83¥ã\83¼ã\83\88ã\83ªã\82¢ã\83«ã\81§ã\81¯ã\80\81**FastAPI**ã\81®ã\81»ã\81¨ã\82\93ã\81©ã\81®æ©\9fè\83½ã\82\92使ã\81\86æ\96¹æ³\95を段階的に紹介します。
 
-各セクションは前のセクションを踏まえた内容になっています。しかし、トピックごとに分割されているので、特定のAPIの要求を満たすようなトピックに直接たどり着けるようになっています。
+各セクションは前のセクションを踏まえた内容になっています。しかし、トピックごとに分割されているので、特定のAPIのニーズを満たすために、任意の特定のトピックに直接進めるようになっています。
 
-また、将来的にリファレンスとして機能するように構築されています。
\81¾ã\81\9fã\80\81å°\86æ\9d¥ç\9a\84ã\81«ã\83ªã\83\95ã\82¡ã\83¬ã\83³ã\82¹ã\81¨ã\81\97ã\81¦æ©\9fè\83½ã\81\99ã\82\8bã\82\88ã\81\86ã\81«æ§\8bç¯\89ã\81\95ã\82\8cã\81¦ã\81\84ã\82\8bã\81®ã\81§ã\80\81å¾\8cã\81§æ\88»ã\81£ã\81¦ã\81\8dã\81¦å¿\85è¦\81ã\81ªã\82\82ã\81®ã\82\92正確ã\81«ç¢ºèª\8dã\81§ã\81\8dã\81¾ã\81\99ã\80\82
 
-従って、後でこのチュートリアルに戻ってきて必要なものを確認できます。
-
-## コードを実行する
+## コードを実行する { #run-the-code }
 
 すべてのコードブロックをコピーして直接使用できます(実際にテストされたPythonファイルです)。
 
-いずれかの例を実行するには、コードを `main.py`ファイルにコピーし、` uvicorn`を次のように起動します:
+いずれかの例を実行するには、コードを `main.py`ファイルにコピーし、次のように `fastapi dev` を起動します:
 
 <div class="termy">
 
 ```console
-$ uvicorn main:app --reload
+$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
+
+  <span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span>  Starting development server 🚀
+
+             Searching for package file structure from directories
+             with <font color="#3465A4">__init__.py</font> files
+             Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
+
+   <span style="background-color:#007166"><font color="#D3D7CF"> module </font></span>  🐍 main.py
+
+     <span style="background-color:#007166"><font color="#D3D7CF"> code </font></span>  Importing the FastAPI app object from the module with
+             the following code:
+
+             <u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
+
+      <span style="background-color:#007166"><font color="#D3D7CF"> app </font></span>  Using import string: <font color="#3465A4">main:app</font>
+
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font>
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000/docs</u></font>
+
+      <span style="background-color:#007166"><font color="#D3D7CF"> tip </font></span>  Running in development mode, for production use:
+             <b>fastapi run</b>
 
-<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-<span style="color: green;">INFO</span>:     Started reloader process [28720]
-<span style="color: green;">INFO</span>:     Started server process [28722]
-<span style="color: green;">INFO</span>:     Waiting for application startup.
-<span style="color: green;">INFO</span>:     Application startup complete.
+             Logs:
+
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Will watch for changes in these directories:
+             <b>[</b><font color="#4E9A06">&apos;/home/user/code/awesomeapp&apos;</font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font> <b>(</b>Press CTRL+C
+             to quit<b>)</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started reloader process <b>[</b><font color="#34E2E2"><b>383138</b></font><b>]</b> using WatchFiles
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started server process <b>[</b><font color="#34E2E2"><b>383153</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Waiting for application startup.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Application startup complete.
 ```
 
 </div>
 
-コードを記述またはコピーし、編集してローカルで実行することを**強くお勧めします**。
+コードを記述またはコピーし、編集してローカルで実行することを**強く推奨します**。
 
\81¾ã\81\9fã\80\81ã\82¨ã\83\87ã\82£ã\82¿ã\83¼ã\81§ä½¿ç\94¨ã\81\99ã\82\8bã\81\93ã\81¨ã\81§ã\80\81æ\9b¸ã\81\8få¿\85è¦\81ã\81®ã\81\82ã\82\8bã\82³ã\83¼ã\83\89ã\81®å°\91ã\81ªã\81\95ã\80\81ã\81\99ã\81¹ã\81¦ã\81®å\9e\8bã\83\81ã\82§ã\83\83ã\82¯ã\80\81è\87ªå\8b\95è£\9cå®\8cã\81ªã\81©ã\81®FastAPIã\81®å\88©ç\82¹ã\82\92実感できます。
\82¨ã\83\87ã\82£ã\82¿ã\83¼ã\81§ä½¿ç\94¨ã\81\99ã\82\8bã\81\93ã\81¨ã\81§ã\80\81æ\9b¸ã\81\8få¿\85è¦\81ã\81®ã\81\82ã\82\8bã\82³ã\83¼ã\83\89ã\81®å°\91ã\81ªã\81\95ã\80\81ã\81\99ã\81¹ã\81¦ã\81®å\9e\8bã\83\81ã\82§ã\83\83ã\82¯ã\80\81è\87ªå\8b\95è£\9cå®\8cã\81ªã\81©ã\80\81FastAPIã\81®å\88©ç\82¹ã\82\92æ\9c¬å½\93ã\81«実感できます。
 
 ---
 
-## FastAPIをインストールする
+## FastAPIをインストールする { #install-fastapi }
 
 最初のステップは、FastAPIのインストールです。
 
-チュートリアルのために、すべてのオプションの依存関係と機能をインストールしたいとき:
+[仮想環境](../virtual-environments.md){.internal-link target=_blank} を作成して有効化し、それから **FastAPIをインストール** してください:
 
 <div class="termy">
 
 ```console
-$ pip install "fastapi[all]"
+$ pip install "fastapi[standard]"
 
 ---> 100%
 ```
 
 </div>
 
-...これには、コードを実行するサーバーとして使用できる `uvicorn`も含まれます。
-
 /// note | 備考
 
-パーツ毎にインストールすることも可能です。
-
-以下は、アプリケーションを本番環境にデプロイする際に行うであろうものです:
+`pip install "fastapi[standard]"` でインストールすると、`fastapi-cloud-cli` を含むいくつかのデフォルトのオプション標準依存関係が付属します。これにより、<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> にデプロイできます。
 
-```
-pip install fastapi
-```
-
-また、サーバーとして動作するように`uvicorn` をインストールします:
-
-```
-pip install "uvicorn[standard]"
-```
+これらのオプション依存関係が不要な場合は、代わりに `pip install fastapi` をインストールできます。
 
-そして、使用したい依存関係をそれぞれ同様にインストールします。
+標準依存関係はインストールしたいが `fastapi-cloud-cli` は不要な場合は、`pip install "fastapi[standard-no-fastapi-cloud-cli]"` でインストールできます。
 
 ///
 
-## 高度なユーザーガイド
+## 高度なユーザーガイド { #advanced-user-guide }
 
-**高度なユーザーガイド**もあり、**チュートリアル - ユーザーガイド**の後で読むことができます。
+この **チュートリアル - ユーザーガイド** の後で、後から読める **高度なユーザーガイド** もあります。
 
-**高度なユーザーガイド**は**チュートリアル - ユーザーガイド**に基づいており、同じ概念を使用し、いくつかの追加機能を紹介しています。
+**高度なユーザーガイド** は本チュートリアルをベースにしており、同じ概念を使用し、いくつかの追加機能を教えます。
 
-ただし、最初に**チュートリアル - ユーザーガイド**(現在読んでいる内容)をお読みください。
+ただし、最初に **チュートリアル - ユーザーガイド**(今読んでいる内容)をお読みください。
 
-**チュートリアル-ユーザーガイド**だけで完全なアプリケーションを構築できるように設計されています。加えて、**高度なユーザーガイド**の中からニーズに応じたアイデアを使用して、様々な拡張が可能です。
+**チュートリアル - ユーザーガイド** だけで完全なアプリケーションを構築できるように設計されており、その後ニーズに応じて、**高度なユーザーガイド** の追加のアイデアのいくつかを使って、さまざまな方法で拡張できます。
index b93dedcb918035856bce976be73fde852674c0de..0ffb8f350541e2b6be1141c252204fa92b4c9844 100644 (file)
@@ -1,47 +1,66 @@
-# メタデータとドキュメントのURL
+# メタデータとドキュメントのURL { #metadata-and-docs-urls }
 
-**FastAPI** アプリケーションのいくつかのメタデータ設定をカスタマイズできます。
+**FastAPI** アプリケーションのいくつかのメタデータ設定をカスタマイズできます。
 
-## タイトル、説明文、バージョン
+## APIのメタデータ { #metadata-for-api }
 
-以下を設定できます:
+OpenAPI仕様および自動APIドキュメントUIで使用される次のフィールドを設定できます:
 
-* **タイトル**: OpenAPIおよび自動APIドキュメントUIでAPIのタイトル/名前として使用される。
-* **説明文**: OpenAPIおよび自動APIドキュメントUIでのAPIの説明文。
-* **バージョン**: APIのバージョン。例: `v2` または `2.5.0`。
-     *たとえば、以前のバージョンのアプリケーションがあり、OpenAPIも使用している場合に便利です。
+| パラメータ | 型 | 説明 |
+|------------|------|-------------|
+| `title` | `str` | APIのタイトルです。 |
+| `summary` | `str` | APIの短い要約です。 <small>OpenAPI 3.1.0、FastAPI 0.99.0 以降で利用できます。</small> |
+| `description` | `str` | APIの短い説明です。Markdownを使用できます。 |
+| `version` | `string` | APIのバージョンです。これはOpenAPIのバージョンではなく、あなた自身のアプリケーションのバージョンです。たとえば `2.5.0` です。 |
+| `terms_of_service` | `str` | APIの利用規約へのURLです。指定する場合、URLである必要があります。 |
+| `contact` | `dict` | 公開されるAPIの連絡先情報です。複数のフィールドを含められます。 <details><summary><code>contact</code> fields</summary><table><thead><tr><th>Parameter</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>連絡先の個人/組織を識別する名前です。</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>連絡先情報を指すURLです。URL形式である必要があります。</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>連絡先の個人/組織のメールアドレスです。メールアドレス形式である必要があります。</td></tr></tbody></table></details> |
+| `license_info` | `dict` | 公開されるAPIのライセンス情報です。複数のフィールドを含められます。 <details><summary><code>license_info</code> fields</summary><table><thead><tr><th>Parameter</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>必須</strong>(<code>license_info</code> が設定されている場合)。APIに使用されるライセンス名です。</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>APIの <a href="https://spdx.org/licenses/" class="external-link" target="_blank">SPDX</a> ライセンス式です。<code>identifier</code> フィールドは <code>url</code> フィールドと同時に指定できません。 <small>OpenAPI 3.1.0、FastAPI 0.99.0 以降で利用できます。</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>APIに使用されるライセンスへのURLです。URL形式である必要があります。</td></tr></tbody></table></details> |
 
-これらを設定するには、パラメータ `title`、`description`、`version` を使用します:
+以下のように設定できます:
 
-{* ../../docs_src/metadata/tutorial001.py hl[4:6] *}
+{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
 
-この設定では、自動APIドキュメントは以下の様になります:
+/// tip | 豆知識
+
+`description` フィールドにはMarkdownを書けて、出力ではレンダリングされます。
+
+///
+
+この設定では、自動APIドキュメントは以下のようになります:
 
 <img src="/img/tutorial/metadata/image01.png">
 
-## タグのためのメタデータ
+## ライセンス識別子 { #license-identifier }
+
+OpenAPI 3.1.0 および FastAPI 0.99.0 以降では、`license_info` を `url` の代わりに `identifier` で設定することもできます。
+
+例:
+
+{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
+
+## タグのメタデータ { #metadata-for-tags }
 
\81\95ã\82\89ã\81«ã\80\81ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ `openapi_tags` ã\82\92使ã\81\86ã\81¨ã\80\81path operations ã\82\92ã\82°ã\83«ã\83¼ã\83\97å\88\86ã\81\91ã\81\99ã\82\8bã\81\9fã\82\81ã\81®è¤\87æ\95°ã\81®ã\82¿ã\82°ã\81«é\96¢ã\81\99ã\82\8bメタデータを追加できます。
\83\91ã\83©ã\83¡ã\83¼ã\82¿ `openapi_tags` ã\82\92使ã\81\86ã\81¨ã\80\81path operation ã\82\92ã\82°ã\83«ã\83¼ã\83\97å\88\86ã\81\91ã\81\99ã\82\8bã\81\9fã\82\81ã\81«ä½¿ç\94¨ã\81\99ã\82\8bå\90\84ã\82¿ã\82°ã\81«è¿½å\8a ã\81®メタデータを追加できます。
 
-それぞれのタグ毎にひとつの辞書を含むリストをとります。
+それぞれのタグごとに1つの辞書を含むリストを取ります。
 
-それぞれの辞書は以下をもつことができます:
+それぞれの辞書は以下を含められます:
 
-* `name` (**必須**): *path operations* および `APIRouter` の `tags` パラメーターで使用するのと同じタグ名である `str`。
-* `description`: ã\82¿ã\82°ã\81®ç°¡å\8d\98ã\81ªèª¬æ\98\8eæ\96\87ã\81§ã\81\82ã\82\8b `str`ã\80\82 Markdownã\81§è¨\98è¿°ã\81§ã\81\8d、ドキュメントUIに表示されます。
-* `externalDocs`: 外部ドキュメントを説明するための `dict`:
-    * `description`: å¤\96é\83¨ã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88ã\81®ç°¡å\8d\98ã\81ªèª¬æ\98\8eæ\96\87ã\81§ã\81\82ã\82\8b `str`。
-    * `url` (**å¿\85é \88**): å¤\96é\83¨ã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88ã\81®URLã\81§ã\81\82ã\82\8b `str`。
+* `name` (**必須**): *path operation* および `APIRouter` の `tags` パラメータで使用するのと同じタグ名の `str`。
+* `description`: ã\82¿ã\82°ã\81®ç\9f­ã\81\84説æ\98\8eã\81® `str`ã\80\82Markdownã\82\92å\90«ã\82\81ã\82\89ã\82\8c、ドキュメントUIに表示されます。
+* `externalDocs`: 外部ドキュメントを説明する `dict`。以下を含みます:
+    * `description`: å¤\96é\83¨ã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88ã\81®ç\9f­ã\81\84説æ\98\8eã\81® `str`。
+    * `url` (**å¿\85é \88**): å¤\96é\83¨ã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88ã\81®URLã\81® `str`。
 
-### ã\82¿ã\82°ã\81®ã\81\9fã\82\81ã\81®ã\83¡ã\82¿ã\83\87ã\83¼ã\82¿ã\81®ä½\9cæ\88\90
+### ã\82¿ã\82°ã\81®ã\83¡ã\82¿ã\83\87ã\83¼ã\82¿ã\81®ä½\9cæ\88\90 { #create-metadata-for-tags }
 
-`users` と `items` のタグを使った例でメタデータの追加を試してみましょう。
+`users` と `items` のタグを使った例で試してみましょう。
 
\82¿ã\82°ã\81®ã\81\9fã\82\81ã\81®ã\83¡ã\82¿ã\83\87ã\83¼ã\82¿ã\82\92ä½\9cæ\88\90ã\81\97ã\80\81ã\81\9dã\82\8cã\82\92 `openapi_tags` ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81«æ¸¡ã\81\97ã\81¾ã\81\99ã\80\82
\82¿ã\82°ã\81®ã\83¡ã\82¿ã\83\87ã\83¼ã\82¿ã\82\92ä½\9cæ\88\90ã\81\97ã\80\81ã\81\9dã\82\8cã\82\92 `openapi_tags` ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81«æ¸¡ã\81\97ã\81¾ã\81\99:
 
-{* ../../docs_src/metadata/tutorial004.py hl[3:16,18] *}
+{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
 
-説明文 (description) の中で Markdown を使用できることに注意してください。たとえば、「login」は太字 (**login**) で表示され、「fancy」は斜体 (_fancy_) で表示されます。
+説明の中でMarkdownを使用できることに注意してください。たとえば「login」は太字 (**login**) で表示され、「fancy」は斜体 (_fancy_) で表示されます。
 
 /// tip | 豆知識
 
 
 ///
 
-### 自作タグの使用
+### タグの使用 { #use-your-tags }
 
-`tags` パラメーターを使用して、それぞれの *path operations* (および `APIRouter`) を異なるタグに割り当てます:
+*path operation*(および `APIRouter`)の `tags` パラメータを使用して、それらを異なるタグに割り当てます:
 
-{* ../../docs_src/metadata/tutorial004.py hl[21,26] *}
+{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
 
 /// info | 情報
 
-タグのより詳しい説明を知りたい場合は [Path Operation Configuration](path-operation-configuration.md#tags){.internal-link target=_blank} を参照して下さい。
+タグの詳細は [Path Operation Configuration](path-operation-configuration.md#tags){.internal-link target=_blank} を参照してください。
 
 ///
 
-### ドキュメントの確認
+### ドキュメントの確認 { #check-the-docs }
 
\81\93ã\81\93ã\81§ã\80\81ã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88ã\82\92確èª\8dã\81\99ã\82\8bã\81¨ã\80\81追å\8a ã\81\97ã\81\9fã\83¡ã\82¿ã\83\87ã\83¼ã\82¿ã\81\8cã\81\99ã\81¹ã\81¦è¡¨ç¤ºã\81\95ã\82\8cã\81¾ã\81\99:
+ここでドキュメントを確認すると、追加したメタデータがすべて表示されます:
 
 <img src="/img/tutorial/metadata/image02.png">
 
-### タグの順番
+### タグの順番 { #order-of-tags }
 
 タグのメタデータ辞書の順序は、ドキュメントUIに表示される順序の定義にもなります。
 
\81\9fã\81¨ã\81\88ã\81°ã\80\81`users` ã\81¯ã\82¢ã\83«ã\83\95ã\82¡ã\83\99ã\83\83ã\83\88é \86ã\81§ã\81¯ `items` ã\81®å¾\8cã\81«ç¶\9aã\81\8dã\81¾ã\81\99ã\80\82ã\81\97ã\81\8bã\81\97ã\80\81ã\83ªã\82¹ã\83\88ã\81®æ\9c\80å\88\9dã\81« `users` ã\81®ã\83¡ã\82¿ã\83\87ã\83¼ã\82¿è¾\9eæ\9b¸ã\82\92追å\8a ã\81\97ã\81\9fã\81\9fã\82\81ã\80\81ã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\88UIã\81§ã\81¯ `users` ã\81\8cå\85\88に表示されます。
\81\9fã\81¨ã\81\88ã\81°ã\80\81`users` ã\81¯ã\82¢ã\83«ã\83\95ã\82¡ã\83\99ã\83\83ã\83\88é \86ã\81§ã\81¯ `items` ã\81®å¾\8cã\81«ç¶\9aã\81\8dã\81¾ã\81\99ã\81\8cã\80\81ã\83ªã\82¹ã\83\88ã\81®æ\9c\80å\88\9dã\81®è¾\9eæ\9b¸ã\81¨ã\81\97ã\81¦ã\83¡ã\82¿ã\83\87ã\83¼ã\82¿ã\82\92追å\8a ã\81\97ã\81\9fã\81\9fã\82\81ã\80\81ã\81\9dã\82\8cã\82\88ã\82\8aå\89\8dに表示されます。
 
-## OpenAPI URL
+## OpenAPI URL { #openapi-url }
 
 デフォルトでは、OpenAPIスキーマは `/openapi.json` で提供されます。
 
 
 たとえば、`/api/v1/openapi.json` で提供されるように設定するには:
 
-{* ../../docs_src/metadata/tutorial002.py hl[3] *}
+{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
 
 OpenAPIスキーマを完全に無効にする場合は、`openapi_url=None` を設定できます。これにより、それを使用するドキュメントUIも無効になります。
 
-## ドキュメントのURL
+## ドキュメントのURL { #docs-urls }
 
-以下の2つのドキュメントUIを構築できます:
+含まれている2つのドキュメントUIを設定できます:
 
 * **Swagger UI**: `/docs` で提供されます。
-     * URL はパラメータ `docs_url` で設定できます。
-     * `docs_url=None` を設定することで無効にできます。
-* ReDoc: `/redoc` で提供されます。
-     * URL はパラメータ `redoc_url` で設定できます。
-     * `redoc_url=None` を設定することで無効にできます。
+    * URL はパラメータ `docs_url` で設定できます。
+    * `docs_url=None` を設定することで無効にできます。
+* **ReDoc**: `/redoc` で提供されます。
+    * URL はパラメータ `redoc_url` で設定できます。
+    * `redoc_url=None` を設定することで無効にできます。
 
 たとえば、`/documentation` でSwagger UIが提供されるように設定し、ReDocを無効にするには:
 
-{* ../../docs_src/metadata/tutorial003.py hl[3] *}
+{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
index 539ec5b8c94c10cdfaaaa2446ce3fa9eee903dc6..12fb57a640a5f865256ac87f9ba7a6321a63f37a 100644 (file)
@@ -1,4 +1,4 @@
-# ミドルウェア
+# ミドルウェア { #middleware }
 
 **FastAPI** アプリケーションにミドルウェアを追加できます。
 
 
 `yield` を使った依存関係をもつ場合は、終了コードはミドルウェアの *後に* 実行されます。
 
-バックグラウンドタスク (後述) がある場合は、それらは全てのミドルウェアの *後に* 実行されます。
+バックグラウンドタスク ([バックグラウンドタスク](background-tasks.md){.internal-link target=_blank} セクションで説明します。後で確認できます) がある場合は、それらは全てのミドルウェアの *後に* 実行されます。
 
 ///
 
-## ミドルウェアの作成
+## ミドルウェアの作成 { #create-a-middleware }
 
 ミドルウェアを作成するには、関数の上部でデコレータ `@app.middleware("http")` を使用します。
 
     * 次に、対応する*path operation*によって生成された `response` を返します。
 * その後、`response` を返す前にさらに `response` を変更することもできます。
 
-{* ../../docs_src/middleware/tutorial001.py hl[8:9,11,14] *}
+{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
 
 /// tip | 豆知識
 
-<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">'X-'プレフィックスを使用</a>してカスタムの独自ヘッダーを追加できます
+カスタムの独自ヘッダーは <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">`X-` プレフィックスを使用</a>して追加できる点に注意してください
 
-ただし、ブラウザのクライアントに表示させたいカスタムヘッダーがある場合は、<a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">StarletteのCORSドキュメント</a>に記載されているパラメータ `expose_headers` を使用して、それらをCORS設定に追加する必要があります ([CORS (オリジン間リソース共有)](cors.md){.internal-link target=_blank})
+ただし、ブラウザのクライアントに表示させたいカスタムヘッダーがある場合は、<a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">StarletteのCORSドキュメント</a>に記載されているパラメータ `expose_headers` を使用して、それらをCORS設定に追加する必要があります ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank})。
 
 ///
 
@@ -49,7 +49,7 @@
 
 ///
 
-### `response` の前後
+### `response` の前後 { #before-and-after-the-response }
 
 *path operation* が `request` を受け取る前に、 `request` とともに実行されるコードを追加できます。
 
 
 例えば、リクエストの処理とレスポンスの生成にかかった秒数を含むカスタムヘッダー `X-Process-Time` を追加できます:
 
-{* ../../docs_src/middleware/tutorial001.py hl[10,12:13] *}
+{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
 
-## その他のミドルウェア
+/// tip | 豆知識
+
+ここでは、これらのユースケースに対してより正確になり得るため、`time.time()` の代わりに <a href="https://docs.python.org/3/library/time.html#time.perf_counter" class="external-link" target="_blank">`time.perf_counter()`</a> を使用しています。 🤓
+
+///
+
+## 複数ミドルウェアの実行順序 { #multiple-middleware-execution-order }
+
+`@app.middleware()` デコレータまたは `app.add_middleware()` メソッドのいずれかを使って複数のミドルウェアを追加すると、新しく追加された各ミドルウェアがアプリケーションをラップし、スタックを形成します。最後に追加されたミドルウェアが *最も外側*、最初に追加されたミドルウェアが *最も内側* になります。
+
+リクエスト経路では、*最も外側* のミドルウェアが最初に実行されます。
+
+レスポンス経路では、最後に実行されます。
+
+例:
+
+```Python
+app.add_middleware(MiddlewareA)
+app.add_middleware(MiddlewareB)
+```
+
+これにより、実行順序は次のようになります:
+
+* **リクエスト**: MiddlewareB → MiddlewareA → route
+
+* **レスポンス**: route → MiddlewareA → MiddlewareB
+
+このスタック動作により、ミドルウェアが予測可能で制御しやすい順序で実行されることが保証されます。
+
+## その他のミドルウェア { #other-middlewares }
 
 他のミドルウェアの詳細については、[高度なユーザーガイド: 高度なミドルウェア](../advanced/middleware.md){.internal-link target=_blank}を参照してください。
 
index 0cc38cb2559def82805b6573168a743ae5a431d1..eb6b6b11a55d146997b363f7d863ff5b1523444a 100644 (file)
@@ -1,14 +1,14 @@
-# Path Operationの設定
+# Path Operationの設定 { #path-operation-configuration }
 
 *path operationデコレータ*を設定するためのパラメータがいくつかあります。
 
 /// warning | 注意
 
-これらのパラメータは*path operation関数*ではなく、*path operationデコレータ*に直接渡されることに注意してください。
+これらのパラメータは*path operationデコレータ*に直接渡され、*path operation関数*に渡されないことに注意してください。
 
 ///
 
-## レスポンスステータスコード
+## レスポンスステータスコード { #response-status-code }
 
 *path operation*のレスポンスで使用する(HTTP)`status_code`を定義することができます。
 
 
 しかし、それぞれの番号コードが何のためのものか覚えていない場合は、`status`のショートカット定数を使用することができます:
 
-{* ../../docs_src/path_operation_configuration/tutorial001.py hl[3,17] *}
+{* ../../docs_src/path_operation_configuration/tutorial001_py310.py hl[1,15] *}
 
 そのステータスコードはレスポンスで使用され、OpenAPIスキーマに追加されます。
 
 /// note | 技術詳細
 
-また、`from starlette import status`を使用することもできます。
+`from starlette import status`を使用することもできます。
 
 **FastAPI** は開発者の利便性を考慮して、`fastapi.status`と同じ`starlette.status`を提供しています。しかし、これはStarletteから直接提供されています。
 
 ///
 
-## タグ
+## タグ { #tags }
 
 `tags`パラメータを`str`の`list`(通常は1つの`str`)と一緒に渡すと、*path operation*にタグを追加できます:
 
-{* ../../docs_src/path_operation_configuration/tutorial002.py hl[17,22,27] *}
+{* ../../docs_src/path_operation_configuration/tutorial002_py310.py hl[15,20,25] *}
 
 これらはOpenAPIスキーマに追加され、自動ドキュメントのインターフェースで使用されます:
 
-<img src="https://fastapi.tiangolo.com/img/tutorial/path-operation-configuration/image01.png">
+<img src="/img/tutorial/path-operation-configuration/image01.png">
 
-## 概要と説明
+### Enumを使ったタグ { #tags-with-enums }
+
+大きなアプリケーションの場合、**複数のタグ**が蓄積されていき、関連する*path operations*に対して常に**同じタグ**を使っていることを確認したくなるかもしれません。
+
+このような場合、タグを`Enum`に格納すると理にかなっています。
+
+**FastAPI** は、プレーンな文字列の場合と同じ方法でそれをサポートしています:
+
+{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
+
+## 概要と説明 { #summary-and-description }
 
 `summary`と`description`を追加できます:
 
-{* ../../docs_src/path_operation_configuration/tutorial003.py hl[20:21] *}
+{* ../../docs_src/path_operation_configuration/tutorial003_py310.py hl[17:18] *}
 
-## docstringを用いた説明
+## docstringを用いた説明 { #description-from-docstring }
 
-説明文は長くて複数行におよぶ傾向があるので、関数<abbr title="ドキュメントに使用される関数内の最初の式(変数に代入されていない)としての複数行の文字列">docstring</abbr>内に*path operation*の説明文を宣言できます。すると、**FastAPI** は説明文を読み込んでくれます。
+説明文は長くて複数行におよぶ傾向があるので、関数<abbr title="a multi-line string as the first expression inside a function (not assigned to any variable) used for documentation – ドキュメントに使用される関数内の最初の式(変数に代入されていない)としての複数行の文字列">docstring</abbr>内に*path operation*の説明文を宣言できます。すると、**FastAPI** は説明文を読み込んでくれます。
 
 docstringに<a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a>を記述すれば、正しく解釈されて表示されます。(docstringのインデントを考慮して)
 
-{* ../../docs_src/path_operation_configuration/tutorial004.py hl[19:27] *}
+{* ../../docs_src/path_operation_configuration/tutorial004_py310.py hl[17:25] *}
 
 これは対話的ドキュメントで使用されます:
 
-<img src="https://fastapi.tiangolo.com/img/tutorial/path-operation-configuration/image02.png">
+<img src="/img/tutorial/path-operation-configuration/image02.png">
 
-## レスポンスの説明
+## レスポンスの説明 { #response-description }
 
 `response_description`パラメータでレスポンスの説明をすることができます。
 
-{* ../../docs_src/path_operation_configuration/tutorial005.py hl[21] *}
+{* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[18] *}
 
 /// info | 情報
 
-`respnse_description`は具体的にレスポンスを参照し、`description`は*path operation*全般を参照していることに注意してください。
+`response_description`は具体的にレスポンスを参照し、`description`は*path operation*全般を参照していることに注意してください。
 
 ///
 
@@ -76,22 +86,22 @@ OpenAPIは*path operation*ごとにレスポンスの説明を必要としてい
 
 ///
 
-<img src="https://fastapi.tiangolo.com/img/tutorial/path-operation-configuration/image03.png">
+<img src="/img/tutorial/path-operation-configuration/image03.png">
 
-## 非推奨の*path operation*
+## *path operation*を非推奨にする { #deprecate-a-path-operation }
 
-*path operation*を<abbr title="非推奨、使わない方がよい">deprecated</abbr>としてマークする必要があるが、それを削除しない場合は、`deprecated`パラメータを渡します:
+*path operation*を<abbr title="obsolete, recommended not to use it – 非推奨、使わない方がよい">deprecated</abbr>としてマークする必要があるが、それを削除しない場合は、`deprecated`パラメータを渡します:
 
-{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *}
+{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
 
 対話的ドキュメントでは非推奨と明記されます:
 
-<img src="https://fastapi.tiangolo.com/img/tutorial/path-operation-configuration/image04.png">
+<img src="/img/tutorial/path-operation-configuration/image04.png">
 
 *path operations*が非推奨である場合とそうでない場合でどのように見えるかを確認してください:
 
-<img src="https://fastapi.tiangolo.com/img/tutorial/path-operation-configuration/image05.png">
+<img src="/img/tutorial/path-operation-configuration/image05.png">
 
-## まとめ
+## まとめ { #recap }
 
 *path operationデコレータ*にパラメータを渡すことで、*path operations*のメタデータを簡単に設定・追加することができます。
index a1810ae37b0d32d740038b25b279a5c3a7ee1eae..6a9ecc4e7b25b5862f01cf6bda2c1dfd5a23a5d2 100644 (file)
@@ -1,40 +1,52 @@
-# パスパラメータと数値の検証
+# パスパラメータと数値の検証 { #path-parameters-and-numeric-validations }
 
 クエリパラメータに対して`Query`でより多くのバリデーションとメタデータを宣言できるのと同じように、パスパラメータに対しても`Path`で同じ種類のバリデーションとメタデータを宣言することができます。
 
-## Pathのインポート
+## `Path`のインポート { #import-path }
 
-まず初めに、`fastapi`から`Path`をインポートします:
\81¾ã\81\9aå\88\9dã\82\81ã\81«ã\80\81`fastapi`ã\81\8bã\82\89`Path`ã\82\92ã\82¤ã\83³ã\83\9dã\83¼ã\83\88ã\81\97ã\80\81`Annotated`ã\82\82ã\82¤ã\83³ã\83\9dã\83¼ã\83\88ã\81\97ã\81¾ã\81\99:
 
-{* ../../docs_src/path_params_numeric_validations/tutorial001.py hl[1] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[1,3] *}
 
-## メタデータの宣言
+/// info | 情報
+
+FastAPI はバージョン 0.95.0 で`Annotated`のサポートを追加し(そして推奨し始めました)。
+
+古いバージョンの場合、`Annotated`を使おうとするとエラーになります。
+
+`Annotated`を使用する前に、FastAPI のバージョンを少なくとも 0.95.1 まで[アップグレードしてください](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank}。
+
+///
+
+## メタデータの宣言 { #declare-metadata }
 
 パラメータは`Query`と同じものを宣言することができます。
 
 例えば、パスパラメータ`item_id`に対して`title`のメタデータを宣言するには以下のようにします:
 
-{* ../../docs_src/path_params_numeric_validations/tutorial001.py hl[8] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[10] *}
 
 /// note | 備考
 
\83\91ã\82¹ã\81®ä¸\80é\83¨ã\81§ã\81ªã\81\91ã\82\8cã\81°ã\81ªã\82\89ã\81ªã\81\84ã\81®ã\81§ã\80\81ã\83\91ã\82¹ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81¯å¸¸ã\81«å¿\85é \88です。
\83\91ã\82¹ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81¯ã\83\91ã\82¹ã\81®ä¸\80é\83¨ã\81§ã\81ªã\81\91ã\82\8cã\81°ã\81ªã\82\89ã\81ªã\81\84ã\81®ã\81§ã\80\81常ã\81«å¿\85é \88ã\81§ã\81\99ã\80\82`None`ã\81§å®£è¨\80ã\81\97ã\81\9fã\82\8aã\83\87ã\83\95ã\82©ã\83«ã\83\88å\80¤ã\82\92設å®\9aã\81\97ã\81\9fã\82\8aã\81\97ã\81¦ã\82\82ä½\95ã\82\82å½±é\9f¿ã\81\9bã\81\9aã\80\81常ã\81«å¿\85é \88ã\81®ã\81¾ã\81¾です。
 
-そのため、`...`を使用して必須と示す必要があります。
+///
 
-それでも、`None`で宣言しても、デフォルト値を設定しても、何の影響もなく、常に必要とされていることに変わりはありません。
+## 必要に応じてパラメータを並び替える { #order-the-parameters-as-you-need }
 
-///
+/// tip | 豆知識
 
-## 必要に応じてパラメータを並び替える
+`Annotated`を使う場合、これはおそらくそれほど重要でも必要でもありません。
+
+///
 
 クエリパラメータ`q`を必須の`str`として宣言したいとしましょう。
 
 また、このパラメータには何も宣言する必要がないので、`Query`を使う必要はありません。
 
-しかし、パスパラメータ`item_id`のために`Path`を使用する必要があります。
+しかし、パスパラメータ`item_id`のために`Path`を使用する必要があります。そして何らかの理由で`Annotated`を使いたくないとします。
 
-Pythonã\81¯ã\80\8cã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\80\8dã\82\92æ\8c\81ã\81\9fã\81ªã\81\84å\80¤ã\81®å\89\8dã\81«ã\80\8cã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\80\8dã\82\92æ\8c\81ã\81¤å\80¤ã\82\92ç½®ã\81\8fã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\81¾ã\81\9bã\82\93
+Pythonã\81¯ã\80\8cã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\80\8dã\82\92æ\8c\81ã\81¤å\80¤ã\82\92ã\80\8cã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\80\8dã\82\92æ\8c\81ã\81\9fã\81ªã\81\84å\80¤ã\81®å\89\8dã\81«ç½®ã\81\8fã\81¨ã\82¨ã\83©ã\83¼ã\81«ã\81ªã\82\8aã\81¾ã\81\99
 
 しかし、それらを並び替えることができ、デフォルト値を持たない値(クエリパラメータ`q`)を最初に持つことができます。
 
@@ -42,63 +54,88 @@ Pythonは「デフォルト」を持たない値の前に「デフォルト」
 
 そのため、以下のように関数を宣言することができます:
 
-{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[8] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
+
+ただし、`Annotated`を使う場合はこの問題は起きないことを覚えておいてください。`Query()`や`Path()`に関数パラメータのデフォルト値を使わないためです。
 
-## 必要に応じてパラメータを並び替えるトリック
+{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py *}
 
-クエリパラメータ`q`を`Query`やデフォルト値なしで宣言し、パスパラメータ`item_id`を`Path`を用いて宣言し、それらを別の順番に並びたい場合、Pythonには少し特殊な構文が用意されています。
+## 必要に応じてパラメータを並び替えるトリック { #order-the-parameters-as-you-need-tricks }
+
+/// tip | 豆知識
+
+`Annotated`を使う場合、これはおそらくそれほど重要でも必要でもありません。
+
+///
+
+これは**小さなトリック**で、便利な場合がありますが、頻繁に必要になることはありません。
+
+次のことをしたい場合:
+
+* `q`クエリパラメータを`Query`もデフォルト値もなしで宣言する
+* パスパラメータ`item_id`を`Path`を使って宣言する
+* それらを別の順番にする
+* `Annotated`を使わない
+
+...Pythonにはそのための少し特殊な構文があります。
 
 関数の最初のパラメータとして`*`を渡します。
 
 Pythonはその`*`で何かをすることはありませんが、それ以降のすべてのパラメータがキーワード引数(キーと値のペア)として呼ばれるべきものであると知っているでしょう。それは<abbr title="From: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>としても知られています。たとえデフォルト値がなくても。
 
-{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[8] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
+
+### `Annotated`のほうがよい { #better-with-annotated }
+
+`Annotated`を使う場合は、関数パラメータのデフォルト値を使わないため、この問題は起きず、おそらく`*`を使う必要もありません。
+
+{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
 
-## 数値の検証: 以上
+## 数値の検証: 以上 { #number-validations-greater-than-or-equal }
 
-`Query`ã\81¨`Path`ï¼\88ã\80\81ã\81\9dã\81\97ã\81¦å¾\8cè¿°ã\81\99ã\82\8bä»\96ã\81®ã\82\82ã\81®ï¼\89ã\82\92ç\94¨ã\81\84ã\81¦ã\80\81æ\96\87å­\97å\88\97ã\81®å\88¶ç´\84ã\82\92宣è¨\80ã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\81¾ã\81\99ã\81\8cã\80\81æ\95°å\80¤ã\81®å\88¶ç´\84ã\82\82å\90\8cæ§\98ã\81«宣言できます。
+`Query`ã\81¨`Path`ï¼\88ã\80\81ã\81\9dã\81\97ã\81¦å¾\8cè¿°ã\81\99ã\82\8bä»\96ã\81®ã\82\82ã\81®ï¼\89ã\82\92ç\94¨ã\81\84ã\81¦ã\80\81æ\95°å\80¤ã\81®å\88¶ç´\84ã\82\92宣言できます。
 
\81\93ã\81\93ã\81§ã\80\81`ge=1`ã\81®å ´å\90\88ã\80\81`item_id`ã\81¯`1`ã\80\8cã\82\88ã\82\8a大ã\81\8dã\81\84`g`ã\81\8bã\80\81å\90\8cã\81\98`e`ã\80\8dæ\95´æ\95°ã\81§ã\81ªã\82\8cã\81\91ばなりません。
\81\93ã\81\93ã\81§ã\80\81`ge=1`ã\81®å ´å\90\88ã\80\81`item_id`ã\81¯`1`ã\80\8cã\82\88ã\82\8a大ã\81\8dã\81\84`g`ã\81\8bã\80\81å\90\8cã\81\98`e`ã\80\8dæ\95´æ\95°ã\81§ã\81ªã\81\91ã\82\8cばなりません。
 
-{* ../../docs_src/path_params_numeric_validations/tutorial004.py hl[8] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
 
-## 数値の検証: より大きいと小なりイコール
+## 数値の検証: より大きいと小なりイコール { #number-validations-greater-than-and-less-than-or-equal }
 
 以下も同様です:
 
-* `gt`: より大きい(`g`reater `t`han)
-* `le`: 小なりイコール(`l`ess than or `e`qual)
+* `gt`: `g`reater `t`han
+* `le`: `l`ess than or `e`qual
 
-{* ../../docs_src/path_params_numeric_validations/tutorial005.py hl[9] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
 
-## 数値の検証: 浮動小数点、 大なり小なり
+## 数値の検証: 浮動小数点、 大なり小なり { #number-validations-floats-greater-than-and-less-than }
 
 数値のバリデーションは`float`の値に対しても有効です。
 
-ここで重要になってくるのは<abbr title="より大きい"><code>gt</code></abbr>だけでなく<abbr title="以下"><code>ge</code></abbr>も宣言できることです。これと同様に、例えば、値が`1`より小さくても`0`より大きくなければならないことを要求することができます。
+ここで重要になってくるのは<abbr title="greater than – より大きい"><code>gt</code></abbr>だけでなく<abbr title="greater than or equal – 以上"><code>ge</code></abbr>も宣言できることです。これと同様に、例えば、値が`1`より小さくても`0`より大きくなければならないことを要求することができます。
 
 したがって、`0.5`は有効な値ですが、`0.0`や`0`はそうではありません。
 
-これは<abbr title="未満"><code>lt</code></abbr>も同じです。
+これは<abbr title="less than – より小さい"><code>lt</code></abbr>も同じです。
 
-{* ../../docs_src/path_params_numeric_validations/tutorial006.py hl[11] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
 
-## まとめ
+## まとめ { #recap }
 
 `Query`と`Path`(そしてまだ見たことない他のもの)では、[クエリパラメータと文字列の検証](query-params-str-validations.md){.internal-link target=_blank}と同じようにメタデータと文字列の検証を宣言することができます。
 
 また、数値のバリデーションを宣言することもできます:
 
-* `gt`: より大きい(`g`reater `t`han)
-* `ge`: 以上(`g`reater than or `e`qual)
-* `lt`: より小さい(`l`ess `t`han)
-* `le`: 以下(`l`ess than or `e`qual)
+* `gt`: `g`reater `t`han
+* `ge`: `g`reater than or `e`qual
+* `lt`: `l`ess `t`han
+* `le`: `l`ess than or `e`qual
 
 /// info | 情報
 
-`Query`ã\80\81`Path`ã\81ªã\81©ã\81¯å¾\8cã\81«å\85±é\80\9aã\81®`Param`ã\82¯ã\83©ã\82¹ã\81®ã\82µã\83\96ã\82¯ã\83©ã\82¹ã\82\92è¦\8bã\82\8bã\81\93ã\81¨ã\81«ã\81ªã\82\8aã\81¾ã\81\99ã\80\82ï¼\88使ã\81\86å¿\85è¦\81ã\81¯ã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ï¼\89
+`Query`ã\80\81`Path`ã\80\81ã\81\8aã\82\88ã\81³å¾\8cã\81§è¦\8bã\82\8bä»\96ã\81®ã\82¯ã\83©ã\82¹ã\81¯ã\80\81å\85±é\80\9aã\81®`Param`ã\82¯ã\83©ã\82¹ã\81®ã\82µã\83\96ã\82¯ã\83©ã\82¹ã\81§ã\81\99ã\80\82
 
\81\9dã\81\97ã\81¦ã\80\81ã\81\9dã\82\8cã\82\89ã\81\99ã\81¹ã\81¦ã\81¯ã\80\81ã\81\93ã\82\8cã\81¾ã\81§è¦\8bã\81¦ã\81\8dã\81\9f追å\8a ã\81®ã\83\90ã\83ªã\83\87ã\83¼ã\82·ã\83§ã\83³ã\81¨ã\83¡ã\82¿ã\83\87ã\83¼ã\82¿ã\81¨同じパラメータを共有しています。
\81\9dã\82\8cã\82\89ã\81¯ã\81\99ã\81¹ã\81¦ã\80\81ã\81\93ã\82\8cã\81¾ã\81§è¦\8bã\81¦ã\81\8dã\81\9f追å\8a ã\81®ã\83\90ã\83ªã\83\87ã\83¼ã\82·ã\83§ã\83³ã\81¨ã\83¡ã\82¿ã\83\87ã\83¼ã\82¿ã\81®同じパラメータを共有しています。
 
 ///
 
index 1893ec12f434d76ca3d3df1d1845acd0248010f3..96a1fe9d1077b6b40aed6b47a9f845d1d6a39602 100644 (file)
@@ -1,22 +1,22 @@
-# パスパラメータ
+# パスパラメータ { #path-parameters }
 
 Pythonのformat文字列と同様のシンタックスで「パスパラメータ」や「パス変数」を宣言できます:
 
-{* ../../docs_src/path_params/tutorial001.py hl[6,7] *}
+{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
 
 パスパラメータ `item_id` の値は、引数 `item_id` として関数に渡されます。
 
\81\97ã\81\8cã\81\9fって、この例を実行して <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a> にアクセスすると、次のレスポンスが表示されます。
\81\97ã\81\9fã\81\8cって、この例を実行して <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a> にアクセスすると、次のレスポンスが表示されます。
 
 ```JSON
 {"item_id":"foo"}
 ```
 
-## パスパラメータと型
+## 型付きパスパラメータ { #path-parameters-with-types }
 
 標準のPythonの型アノテーションを使用して、関数内のパスパラメータの型を宣言できます:
 
-{* ../../docs_src/path_params/tutorial002.py hl[7] *}
+{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
 
 ここでは、 `item_id` は `int` として宣言されています。
 
@@ -26,7 +26,7 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
 
 ///
 
-## データ<abbr title="別名: serialization, parsing, marshalling">変換</abbr>
+## データ<abbr title="別名: serialization, parsing, marshalling">変換</abbr> { #data-conversion }
 
 この例を実行し、ブラウザで <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a> を開くと、次のレスポンスが表示されます:
 
@@ -38,68 +38,69 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
 
 関数が受け取った(および返した)値は、文字列の `"3"` ではなく、Pythonの `int` としての `3` であることに注意してください。
 
-したがって、型宣言を使用すると、**FastAPI**は自動リクエスト <abbr title="HTTPリクエストで受け取った文字列をPythonデータへ変換する">"解析"</abbr> を行います。
+したがって、その型宣言を使うと、**FastAPI**は自動リクエスト <abbr title="HTTPリクエストで受け取った文字列をPythonデータへ変換する">"解析"</abbr> を行います。
 
 ///
 
-## データバリデーション
+## データバリデーション { #data-validation }
 
 しかしブラウザで <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a> を開くと、次のHTTPエラーが表示されます:
 
 ```JSON
 {
-    "detail": [
-        {
-            "loc": [
-                "path",
-                "item_id"
-            ],
-            "msg": "value is not a valid integer",
-            "type": "type_error.integer"
-        }
-    ]
+  "detail": [
+    {
+      "type": "int_parsing",
+      "loc": [
+        "path",
+        "item_id"
+      ],
+      "msg": "Input should be a valid integer, unable to parse string as an integer",
+      "input": "foo"
+    }
+  ]
 }
 ```
 
 これは、パスパラメータ `item_id` が `int` ではない値 `"foo"` だからです。
 
-<a href="http://127.0.0.1:8000/items/4.2" class="external-link" target="_blank">http://127.0.0.1:8000/items/4.2</a> で見られるように、intのかわりに `float` が与えられた場合にも同様なエラーが表示されます。
+<a href="http://127.0.0.1:8000/items/4.2" class="external-link" target="_blank">http://127.0.0.1:8000/items/4.2</a> で見られるように、`int` のかわりに `float` が与えられた場合にも同様なエラーが表示されます。
 
 /// check | 確認
 
-したがって、Pythonの型宣言を使用することで、**FastAPI**はデータのバリデーションを行います。
+したがって、同じPythonの型宣言を使用することで、**FastAPI**はデータのバリデーションを行います。
 
-表示されたエラーには問題のある箇所が明確に指摘されていることに注意してください。
+表示されたエラーには、バリデーションが通らなかった箇所が明確に示されていることに注意してください。
 
\81\93ã\82\8cã\81¯ã\80\81APIã\81«é\96¢é\80£ã\81\99ã\82\8bã\82³ã\83¼ã\83\89ã\81®é\96\8bç\99ºã\81\8aã\82\88ã\81³ã\83\87ã\83\90ã\83\83ã\82°に非常に役立ちます。
\81\93ã\82\8cã\81¯ã\80\81APIã\81¨ã\82\84ã\82\8aå\8f\96ã\82\8aã\81\99ã\82\8bã\82³ã\83¼ã\83\89ã\82\92é\96\8bç\99ºã\83»ã\83\87ã\83\90ã\83\83ã\82°ã\81\99ã\82\8bé\9a\9bに非常に役立ちます。
 
 ///
 
-## ドキュメント
+## ドキュメント { #documentation }
 
-そしてブラウザで <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> を開くと、以下の様な自動的に生成された対話的なドキュメントが表示されます。
+そしてブラウザで <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> を開くと、以下の様な自動的に生成された対話的なAPIドキュメントが表示されます。
 
 <img src="/img/tutorial/path-params/image01.png">
 
 /// check | 確認
 
-繰り返しになりますが、Python型宣言を使用するだけで、**FastAPI**は対話的なAPIドキュメントを自動的に生成します(Swagger UIを統合)。
+繰り返しになりますが、同じPython型宣言を使用するだけで、**FastAPI**は対話的なドキュメントを自動的に生成します(Swagger UIを統合)。
 
 パスパラメータが整数として宣言されていることに注意してください。
 
 ///
 
-## æ¨\99æº\96ã\81§ã\81\82ã\82\8bã\81\93ã\81¨ã\81®ã\83¡ã\83ªã\83\83ã\83\88ã\80\81ã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\86ã\83¼ã\82·ã\83§ã\83³ã\81®ä»£æ\9b¿ç\89©
+## æ¨\99æº\96ã\83\99ã\83¼ã\82¹ã\81®ã\83¡ã\83ªã\83\83ã\83\88ã\80\81ã\83\89ã\82­ã\83¥ã\83¡ã\83³ã\83\86ã\83¼ã\82·ã\83§ã\83³ã\81®ä»£æ\9b¿ç\89© { #standards-based-benefits-alternative-documentation }
 
-また、生成されたスキーマが <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md" class="external-link" target="_blank">OpenAPI</a> 標準に従っているので、互換性のあるツールが多数あります。
+また、生成されたスキーマが <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md" class="external-link" target="_blank">OpenAPI</a> 標準に従っているので、互換性のあるツールが多数あります。
 
 このため、**FastAPI**自体が代替のAPIドキュメントを提供します(ReDocを使用)。これは、 <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> にアクセスすると確認できます。
 
 <img src="/img/tutorial/path-params/image02.png">
 
-同様に、互換性のあるツールが多数あります(多くの言語用のコード生成ツールを含む)
+同様に、互換性のあるツールが多数あります。多くの言語用のコード生成ツールを含みます
 
-## Pydantic
+## Pydantic { #pydantic }
 
 すべてのデータバリデーションは <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> によって内部で実行されるため、Pydanticの全てのメリットが得られます。そして、安心して利用することができます。
 
@@ -107,7 +108,7 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
 
 これらのいくつかについては、チュートリアルの次の章で説明します。
 
-## 順序の問題
+## 順序の問題 { #order-matters }
 
 *path operations* を作成する際、固定パスをもつ状況があり得ます。
 
@@ -117,29 +118,29 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
 
 *path operations* は順に評価されるので、 `/users/me` が `/users/{user_id}` よりも先に宣言されているか確認する必要があります:
 
-{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
 
-それ以外の場合、 `/users/{users_id}` は `/users/me` としてもマッチします。値が「"me"」であるパラメータ `user_id` を受け取ると「考え」ます。
+それ以外の場合、 `/users/{user_id}` は `/users/me` としてもマッチします。値が `"me"` であるパラメータ `user_id` を受け取ると「考え」ます。
 
-## 定義済みの値
+同様に、path operation を再定義することはできません:
 
-*パスパラメータ*を受け取る *path operation* をもち、有効な*パスパラメータ*の値を事前に定義したい場合は、標準のPython <abbr title="Enumeration">`Enum`</abbr> を利用できます。
+{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
 
-### `Enum` クラスの作成
+パスは最初にマッチしたものが常に使われるため、最初のものが常に使用されます。
 
-`Enum` をインポートし、 `str` と `Enum` を継承したサブクラスを作成します。
+## 定義済みの値 { #predefined-values }
 
-`str` を継承することで、APIドキュメントは値が `文字列` でなければいけないことを知り、正確にレンダリングできるようになります。
+*パスパラメータ*を受け取る *path operation* をもち、有効な*パスパラメータ*の値を事前に定義したい場合は、標準のPython <abbr title="Enumeration - 列挙型">`Enum`</abbr> を利用できます。
 
-そして、固定値のクラス属性を作ります。すると、その値が使用可能な値となります:
+### `Enum` クラスの作成 { #create-an-enum-class }
 
-{* ../../docs_src/path_params/tutorial005.py hl[1,6,7,8,9] *}
+`Enum` をインポートし、 `str` と `Enum` を継承したサブクラスを作成します。
 
-/// info | 情報
+`str` を継承することで、APIドキュメントは値が `string` 型でなければいけないことを知り、正確にレンダリングできるようになります。
 
-<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">Enumerations (もしくは、enums)はPython 3.4以降で利用できます</a>。
+そして、固定値のクラス属性を作ります。すると、その値が使用可能な値となります:
 
-///
+{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
 
 /// tip | 豆知識
 
@@ -147,33 +148,33 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
 
 ///
 
-### *パスパラメータ*の宣言
+### *パスパラメータ*の宣言 { #declare-a-path-parameter }
 
 次に、作成したenumクラスである`ModelName`を使用した型アノテーションをもつ*パスパラメータ*を作成します:
 
-{* ../../docs_src/path_params/tutorial005.py hl[16] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
 
-### ドキュメントの確認
+### ドキュメントの確認 { #check-the-docs }
 
 *パスパラメータ*の利用可能な値が事前に定義されているので、対話的なドキュメントで適切に表示できます:
 
 <img src="/img/tutorial/path-params/image03.png">
 
-### Python*列挙型*の利用
+### Python*列挙型*の利用 { #working-with-python-enumerations }
 
 *パスパラメータ*の値は*列挙型メンバ*となります。
 
-#### *列挙型メンバ*の比較
+#### *列挙型メンバ*の比較 { #compare-enumeration-members }
 
 これは、作成した列挙型 `ModelName` の*列挙型メンバ*と比較できます:
 
-{* ../../docs_src/path_params/tutorial005.py hl[17] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
 
-#### *列挙値*の取得
+#### *列挙値*の取得 { #get-the-enumeration-value }
 
 `model_name.value` 、もしくは一般に、 `your_enum_member.value` を使用して実際の値 (この場合は `str`) を取得できます。
 
-{* ../../docs_src/path_params/tutorial005.py hl[20] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
 
 /// tip | 豆知識
 
@@ -181,13 +182,13 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
 
 ///
 
-#### *列挙型メンバ*の返却
+#### *列挙型メンバ*の返却 { #return-enumeration-members }
 
-*path operation* から*列挙型メンバ*を返すことができます。JSONボディ(`dict` など)でネストすることもできます。
+*path operation* から*列挙型メンバ*を返すことができます。JSONボディ(例: `dict`)でネストすることもできます。
 
 それらはクライアントに返される前に適切な値 (この場合は文字列) に変換されます。
 
-{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
 
 クライアントは以下の様なJSONレスポンスを得ます:
 
@@ -198,23 +199,23 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
 }
 ```
 
-## パスを含んだパスパラメータ
+## パスを含んだパスパラメータ { #path-parameters-containing-paths }
 
 パス `/files/{file_path}` となる *path operation* を持っているとしましょう。
 
 ただし、 `home/johndoe/myfile.txt` のような*パス*を含んだ `file_path` が必要です。
 
-したがって、URLは `/files/home/johndoe/myfile.txt` の様になります。
+したがって、そのファイルのURLは `/files/home/johndoe/myfile.txt` の様になります。
 
-### OpenAPIサポート
+### OpenAPIサポート { #openapi-support }
 
 OpenAPIはテストや定義が困難なシナリオにつながる可能性があるため、内部に*パス*を含む*パスパラメータ*の宣言をサポートしていません。
 
 それにも関わらず、Starletteの内部ツールのひとつを使用することで、**FastAPI**はそれが実現できます。
 
-そして、パラメータがパスを含むべきであることを明示的にドキュメントに追加することなく、機能します。
+そして、パラメータがパスを含むべきであることを示すドキュメントを追加しなくても、ドキュメントは動作します。
 
-### パス変換
+### パスコンバーター { #path-convertor }
 
 Starletteのオプションを直接使用することで、以下のURLの様な*パス*を含んだ、*パスパラメータ*の宣言ができます:
 
@@ -226,17 +227,17 @@ Starletteのオプションを直接使用することで、以下のURLの様
 
 したがって、以下の様に使用できます:
 
-{* ../../docs_src/path_params/tutorial004.py hl[6] *}
+{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
 
 /// tip | 豆知識
 
\9c\80å\88\9dã\81®ã\82¹ã\83©ã\83\83ã\82·ã\83¥ (`/`)ã\81\8cä»\98ã\81\84ã\81¦ã\81\84ã\82\8b `/home/johndoe/myfile.txt` ã\82\92ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81\8cå\90«ã\82\93ã\81§ã\81\84ã\82\8bå¿\85è¦\81ã\81\8cã\81\82ã\82\8aã\81¾ã\81\99
\9c\80å\88\9dã\81®ã\82¹ã\83©ã\83\83ã\82·ã\83¥ (`/`)ã\81\8cä»\98ã\81\84ã\81¦ã\81\84ã\82\8b `/home/johndoe/myfile.txt` ã\82\92ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81\8cå\90«ã\82\93ã\81§ã\81\84ã\82\8bå¿\85è¦\81ã\81\8cã\81\82ã\82\8bã\81\8bã\82\82ã\81\97ã\82\8cã\81¾ã\81\9bã\82\93
 
 この場合、URLは `files` と `home` の間にダブルスラッシュ (`//`) のある、 `/files//home/johndoe/myfile.txt` になります。
 
 ///
 
-## まとめ
+## まとめ { #recap }
 
 簡潔で、本質的で、標準的なPythonの型宣言を使用することで、**FastAPI**は以下を行います:
 
index 053d0740bcd467e88fb6106a028fccc4488f1128..d892a57d2274765089061778aba822af8c37d96f 100644 (file)
@@ -1,8 +1,8 @@
-# クエリパラメータモデル
+# クエリパラメータモデル { #query-parameter-models }
 
 もし関連する**複数のクエリパラメータ**から成るグループがあるなら、それらを宣言するために、**Pydanticモデル**を作成できます。
 
-こうすることで、**複数の場所**で**そのPydanticモデルを再利用**でき、バリデーションやメタデータを、すべてのクエリパラメータに対して一度に宣言できます。😎
+こうすることで、**複数の場所**で**そのモデルを再利用**でき、バリデーションやメタデータを、すべてのパラメータに対して一度に宣言できます。😎
 
 /// note | 備考
 
 
 ///
 
-## クエリパラメータにPydanticモデルを使用する
+## Pydanticモデルを使ったクエリパラメータ { #query-parameters-with-a-pydantic-model }
 
-必要な**複数のクエリパラメータ**を**Pydanticモデル**で宣言し、さらに、それを `Query` として宣言しましょう:
+必要な**クエリパラメータ**を**Pydanticモデル**で宣言し、さらに、そのパラメータを `Query` として宣言しましょう:
 
 {* ../../docs_src/query_param_models/tutorial001_an_py310.py hl[9:13,17] *}
 
-**FastAPI**ã\81¯ã\80\81ã\83ªã\82¯ã\82¨ã\82¹ã\83\88ã\81®**ã\82¯ã\82¨ã\83ªã\83\91ã\83©ã\83¡ã\83¼ã\82¿**ã\81\8bã\82\89ã\81\9dã\82\8cã\81\9eã\82\8cã\81®**ã\83\95ã\82£ã\83¼ã\83«ã\83\89**ã\81®ã\83\87ã\83¼ã\82¿ã\82\92**æ\8a½å\87º**ã\81\97ã\80\81å®\9a義ã\81\95ã\82\8cã\81\9f**Pydanticã\83¢ã\83\87ã\83«**を提供します。
+**FastAPI**ã\81¯ã\80\81ã\83ªã\82¯ã\82¨ã\82¹ã\83\88ã\81®**ã\82¯ã\82¨ã\83ªã\83\91ã\83©ã\83¡ã\83¼ã\82¿**ã\81\8bã\82\89ã\81\9dã\82\8cã\81\9eã\82\8cã\81®**ã\83\95ã\82£ã\83¼ã\83«ã\83\89**ã\81®ã\83\87ã\83¼ã\82¿ã\82\92**æ\8a½å\87º**ã\81\97ã\80\81å®\9a義ã\81\97ã\81\9fPydanticã\83¢ã\83\87ã\83«を提供します。
 
-## ドキュメントの確認
+## ドキュメントの確認 { #check-the-docs }
 
 対話的APIドキュメント `/docs` でクエリパラメータを確認できます:
 
 <img src="/img/tutorial/query-param-models/image01.png">
 </div>
 
-## 余分なクエリパラメータを禁止する
+## 余分なクエリパラメータを禁止する { #forbid-extra-query-parameters }
 
\89¹å®\9aã\81®ï¼\88ã\81\82ã\81¾ã\82\8aä¸\80è\88¬ç\9a\84ã\81§ã\81¯ã\81ªã\81\84ã\81\8bã\82\82ã\81\97ã\82\8cã\81ªã\81\84ï¼\89ã\82±ã\83¼ã\82¹ã\81§ã\80\81å\8f\97ã\81\91ä»\98ã\81\91ã\82\8bã\82¯ã\82¨ã\83ªã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\82\92**å\88¶é\99\90**ã\81\99ã\82\8bå¿\85è¦\81ã\81\8cã\81\82ã\82\8bã\81\8bã\82\82ã\81\97ã\82\8cã\81¾ã\81\9bã\82\93
\89¹å®\9aã\81®ï¼\88ã\81\82ã\81¾ã\82\8aä¸\80è\88¬ç\9a\84ã\81§ã\81¯ã\81ªã\81\84ã\81\8bã\82\82ã\81\97ã\82\8cã\81ªã\81\84ï¼\89ã\83¦ã\83¼ã\82¹ã\82±ã\83¼ã\82¹ã\81§ã\80\81å\8f\97ã\81\91å\8f\96ã\82\8aã\81\9fã\81\84ã\82¯ã\82¨ã\83ªã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\82\92**å\88¶é\99\90**ã\81\97ã\81\9fã\81\84å ´å\90\88ã\81\8cã\81\82ã\82\8aã\81¾ã\81\99
 
-Pydanticのモデルの Configuration を利用して、 `extra` フィールドを `forbid` とすることができます。
+Pydanticのモデル設定を使って、あらゆる `extra` フィールドを `forbid` にできます。
 
 {* ../../docs_src/query_param_models/tutorial002_an_py310.py hl[10] *}
 
@@ -42,7 +42,7 @@ Pydanticのモデルの Configuration を利用して、 `extra` フィールド
 https://example.com/items/?limit=10&tool=plumbus
 ```
 
-クエリパラメータ `tool` が許可されていないことを通知する**エラー**レスポンスが返されます。
+クエリパラメータ `tool` が許可されていないことを伝える**エラー**レスポンスが返されます。
 
 ```json
 {
@@ -57,7 +57,7 @@ https://example.com/items/?limit=10&tool=plumbus
 }
 ```
 
-## まとめ
+## まとめ { #summary }
 
 **FastAPI**では、**クエリパラメータ**を宣言するために、**Pydanticモデル**を使用できます。😎
 
index 22b89e452ff44d1e13d8762985e217ffda043a19..e230ef29af3ddf1c3e0157f5322a76c79290d8c7 100644 (file)
-# クエリパラメータと文字列の検証
+# クエリパラメータと文字列の検証 { #query-parameters-and-string-validations }
 
 **FastAPI** ではパラメータの追加情報とバリデーションを宣言することができます。
 
 以下のアプリケーションを例にしてみましょう:
 
-{* ../../docs_src/query_params_str_validations/tutorial001.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *}
 
-クエリパラメータ `q` は `Optional[str]` 型で、`None` を許容する `str` 型を意味しており、デフォルトは `None` です。そのため、FastAPIはそれが必須ではないと理解します。
+クエリパラメータ `q` は `str | None` 型で、`str` 型ですが `None` にもなり得ることを意味し、実際にデフォルト値は `None` なので、FastAPIはそれが必須ではないと理解します。
 
 /// note | 備考
 
-FastAPIは、 `q` はデフォルト値が `=None` であるため、必須ではないと理解します。
+FastAPIは、 `q` はデフォルト値が `= None` であるため、必須ではないと理解します。
 
-`Optional[str]` における `Optional` はFastAPIには利用されませんが、エディターによるより良いサポートとエラー検出を可能にします。
+`str | None` を使うことで、エディターによるより良いサポートとエラー検出を可能にします。
 
 ///
 
-## バリデーションの追加
+## バリデーションの追加 { #additional-validation }
 
-`q`はオプショナルですが、もし値が渡されてきた場合には、**50文字を超えないこと**を強制してみましょう。
+`q`はオプショナルですが、もし値が渡されてきた場合には、**長さが50文字を超えないこと**を強制してみましょう。
 
-### `Query`のインポート
+### `Query` と `Annotated` のインポート { #import-query-and-annotated }
 
-そのために、まずは`fastapi`から`Query`をインポートします:
+そのために、まずは以下をインポートします:
 
-{* ../../docs_src/query_params_str_validations/tutorial002.py hl[3] *}
+* `fastapi` から `Query`
+* `typing` から `Annotated`
 
-## デフォルト値として`Query`を使用
+{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[1,3] *}
 
-パラメータのデフォルト値として使用し、パラメータ`max_length`を50に設定します:
+/// info | 情報
 
-{* ../../docs_src/query_params_str_validations/tutorial002.py hl[9] *}
+FastAPI はバージョン 0.95.0 で `Annotated` のサポートを追加し(推奨し始め)ました。
 
-デフォルト値`None`を`Query(default=None)`に置き換える必要があるので、`Query`の最初の引数はデフォルト値を定義するのと同じです。
+古いバージョンの場合、`Annotated` を使おうとするとエラーになります。
 
-なので:
+`Annotated` を使う前に、FastAPI のバージョンを少なくとも 0.95.1 にするために、[FastAPI のバージョンをアップグレード](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank}してください。
+
+///
+
+## `q` パラメータの型で `Annotated` を使う { #use-annotated-in-the-type-for-the-q-parameter }
+
+以前、[Python Types Intro](../python-types.md#type-hints-with-metadata-annotations){.internal-link target=_blank} で `Annotated` を使ってパラメータにメタデータを追加できると説明したことを覚えていますか?
+
+いよいよ FastAPI で使うときです。 🚀
+
+次の型アノテーションがありました:
+
+//// tab | Python 3.10+
 
 ```Python
-q: Optional[str] = Query(default=None)
+q: str | None = None
 ```
 
-...を以下と同じようにパラメータをオプションにします:
+////
+
+//// tab | Python 3.9+
 
 ```Python
-q: Optional[str] = None
+q: Union[str, None] = None
 ```
 
-しかし、これはクエリパラメータとして明示的に宣言しています。
+////
 
-/// info | 情報
+これを `Annotated` で包んで、次のようにします:
 
-FastAPIは以下の部分を気にすることを覚えておいてください:
+//// tab | Python 3.10+
 
 ```Python
-= None
+q: Annotated[str | None] = None
 ```
 
-もしくは:
+////
+
+//// tab | Python 3.9+
 
 ```Python
-= Query(default=None)
+q: Annotated[Union[str, None]] = None
 ```
 
-そして、 `None` を利用することでクエリパラメータが必須ではないと検知します。
+////
+
+どちらも同じ意味で、`q` は `str` または `None` になり得るパラメータで、デフォルトでは `None` です。
+
+では、面白いところに進みましょう。 🎉
+
+## `q` パラメータの `Annotated` に `Query` を追加する { #add-query-to-annotated-in-the-q-parameter }
+
+追加情報(この場合は追加のバリデーション)を入れられる `Annotated` ができたので、`Annotated` の中に `Query` を追加し、パラメータ `max_length` を `50` に設定します:
+
+{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[9] *}
+
+デフォルト値は引き続き `None` なので、このパラメータは依然としてオプショナルです。
+
+しかし、`Annotated` の中に `Query(max_length=50)` を入れることで、この値に **追加のバリデーション** をしたい、最大 50 文字にしたい、と FastAPI に伝えています。 😎
+
+/// tip | 豆知識
+
+ここでは **クエリパラメータ** なので `Query()` を使っています。後で `Path()`、`Body()`、`Header()`、`Cookie()` など、`Query()` と同じ引数を受け取れるものも見ていきます。
+
+///
+
+FastAPI は次を行います:
+
+* 最大長が 50 文字であることを確かめるようデータを **検証** する
+* データが有効でないときに、クライアントに **明確なエラー** を表示する
+* OpenAPI スキーマの *path operation* にパラメータを **ドキュメント化** する(その結果、**自動ドキュメント UI** に表示されます)
+
+## 代替(古い方法): デフォルト値としての `Query` { #alternative-old-query-as-the-default-value }
 
-`Optional` の部分は、エディターによるより良いサポートを可能にします。
+FastAPI の以前のバージョン(<abbr title="before 2023-03">0.95.0</abbr> より前)では、パラメータのデフォルト値として `Query` を使う必要があり、`Annotated` の中に入れるのではありませんでした。これを使ったコードを見かける可能性が高いので、説明します。
+
+/// tip | 豆知識
+
+新しいコードでは、可能な限り上で説明したとおり `Annotated` を使ってください。複数の利点(後述)があり、欠点はありません。 🍰
 
 ///
 
+関数パラメータのデフォルト値として `Query()` を使い、パラメータ `max_length` を 50 に設定する方法は次のとおりです:
+
+{* ../../docs_src/query_params_str_validations/tutorial002_py310.py hl[7] *}
+
+この場合(`Annotated` を使わない場合)、関数内のデフォルト値 `None` を `Query()` に置き換える必要があるため、`Query(default=None)` のパラメータでデフォルト値を設定する必要があります。これは(少なくとも FastAPI にとっては)そのデフォルト値を定義するのと同じ目的を果たします。
+
+なので:
+
+```Python
+q: str | None = Query(default=None)
+```
+
+...はデフォルト値 `None` を持つオプショナルなパラメータになり、以下と同じです:
+
+
+```Python
+q: str | None = None
+```
+
+ただし `Query` のバージョンでは、クエリパラメータであることを明示的に宣言しています。
+
 そして、さらに多くのパラメータを`Query`に渡すことができます。この場合、文字列に適用される、`max_length`パラメータを指定します。
 
 ```Python
-q: Union[str, None] = Query(default=None, max_length=50)
+q: str | None = Query(default=None, max_length=50)
 ```
 
 これにより、データを検証し、データが有効でない場合は明確なエラーを表示し、OpenAPIスキーマの *path operation* にパラメータを記載します。
 
-## バリデーションをさらに追加する
+### デフォルト値としての `Query` または `Annotated` 内の `Query` { #query-as-the-default-value-or-in-annotated }
+
+`Annotated` の中で `Query` を使う場合、`Query` の `default` パラメータは使えないことに注意してください。
+
+その代わりに、関数パラメータの実際のデフォルト値を使います。そうしないと整合性が取れなくなります。
+
+例えば、これは許可されません:
+
+```Python
+q: Annotated[str, Query(default="rick")] = "morty"
+```
+
+...なぜなら、デフォルト値が `"rick"` なのか `"morty"` なのかが不明確だからです。
+
+そのため、(できれば)次のようにします:
+
+```Python
+q: Annotated[str, Query()] = "rick"
+```
+
+...または、古いコードベースでは次のようなものが見つかるでしょう:
+
+```Python
+q: str = Query(default="rick")
+```
+
+### `Annotated` の利点 { #advantages-of-annotated }
+
+関数パラメータのデフォルト値スタイルではなく、**`Annotated` を使うことが推奨** されます。複数の理由で **より良い** からです。 🤓
+
+**関数パラメータ** の **デフォルト値** は **実際のデフォルト値** であり、Python 全般としてより直感的です。 😌
+
+FastAPI なしで同じ関数を **別の場所** から **呼び出しても**、**期待どおりに動作** します。**必須** パラメータ(デフォルト値がない)があれば、**エディター** がエラーで知らせてくれますし、**Python** も必須パラメータを渡さずに実行すると文句を言います。
+
+`Annotated` を使わずに **(古い)デフォルト値スタイル** を使う場合、FastAPI なしでその関数を **別の場所** で呼び出すとき、正しく動かすために関数へ引数を渡すことを **覚えておく** 必要があります。そうしないと値が期待と異なります(例えば `str` の代わりに `QueryInfo` か、それに類するものになります)。また、エディターも警告せず、Python もその関数の実行で文句を言いません。内部の処理がエラーになるときに初めて問題が出ます。
+
+`Annotated` は複数のメタデータアノテーションを持てるので、<a href="https://typer.tiangolo.com/" class="external-link" target="_blank">Typer</a> のような別ツールと同じ関数を使うこともできます。 🚀
+
+## バリデーションをさらに追加する { #add-more-validations }
 
 パラメータ`min_length`も追加することができます:
 
-{* ../../docs_src/query_params_str_validations/tutorial003.py hl[10] *}
+{* ../../docs_src/query_params_str_validations/tutorial003_an_py310.py hl[10] *}
 
-## 正規表現の追加
+## 正規表現の追加 { #add-regular-expressions }
 
-パラメータが一致するべき<abbr title="正規表現とは、文字列の検索パターンを定義する文字列です。">正規表現</abbr>を定義することができます:
+パラメータが一致するべき <abbr title="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings.">正規表現</abbr> `pattern` を定義することができます:
 
-{* ../../docs_src/query_params_str_validations/tutorial004.py hl[11] *}
+{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
 
-この特定の正規表現は受け取ったパラメータの値をチェックします:
\81\93ã\81®ç\89¹å®\9aã\81®æ­£è¦\8f表ç\8f¾ã\83\91ã\82¿ã\83¼ã\83³ã\81¯å\8f\97ã\81\91å\8f\96ã\81£ã\81\9fã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81®å\80¤ã\82\92ã\83\81ã\82§ã\83\83ã\82¯ã\81\97ã\81¾ã\81\99:
 
 * `^`: は、これ以降の文字で始まり、これより以前には文字はありません。
 * `fixedquery`: は、正確な`fixedquery`を持っています.
 * `$`: で終わる場合、`fixedquery`以降には文字はありません.
 
-もしこれらすべての **正規表現**のアイデアについて迷っていても、心配しないでください。多くの人にとって難しい話題です。正規表現を必要としなくても、まだ、多くのことができます。
+もしこれらすべての **「正規表現」** のアイデアについて迷っていても、心配しないでください。多くの人にとって難しい話題です。正規表現を必要としなくても、まだ、多くのことができます。
 
\81\97ã\81\8bã\81\97ã\80\81ã\81\82ã\81ªã\81\9fã\81\8cã\81\9dã\82\8cã\82\89ã\82\92å¿\85è¦\81ã\81¨ã\81\97ã\80\81å­¦ã\81¶ã\81¨ã\81\8dã\81«ã\81¯ã\81\99ã\81§ã\81«ã\80\81 **FastAPI**ã\81§ç\9b´æ\8e¥ã\81\9dã\82\8cã\82\89ã\82\92使ç\94¨ã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\81¾ã\81\99
\81\93ã\82\8cã\81§ã\80\81å¿\85è¦\81ã\81«ã\81ªã\81£ã\81\9fã\81¨ã\81\8dã\81«ã\81¯ã\81\84ã\81¤ã\81§ã\82\82 **FastAPI** ã\81§ä½¿ã\81\88ã\82\8bã\81\93ã\81¨ã\81\8cå\88\86ã\81\8bã\82\8aã\81¾ã\81\97ã\81\9f
 
-## デフォルト値
+## デフォルト値 { #default-values }
 
-第一引数に`None`を渡して、デフォルト値として使用するのと同じように、他の値を渡すこともできます。
+もちろん、`None` 以外のデフォルト値も使えます。
 
-クエリパラメータ`q`の`min_length`を`3`とし、デフォルト値を`fixedquery`としてみましょう:
+クエリパラメータ `q` の `min_length` を `3` とし、デフォルト値を `"fixedquery"` として宣言したいとします:
 
-{* ../../docs_src/query_params_str_validations/tutorial005.py hl[7] *}
+{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
 
 /// note | 備考
 
-デフォルト値を指定すると、パラメータは任意になります。
+`None` を含む任意の型のデフォルト値があると、パラメータはオプショナル(必須ではない)になります。
 
 ///
 
-## å¿\85é \88ã\81«ã\81\99ã\82\8b
+## å¿\85é \88ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ { #required-parameters }
 
\81\93ã\82\8c以ä¸\8aã\80\81ã\83\90ã\83ªã\83\87ã\83¼ã\82·ã\83§ã\83³ã\82\84ã\83¡ã\82¿ã\83\87ã\83¼ã\82¿ã\82\92宣è¨\80ã\81\99ã\82\8bå¿\85è¦\81ã\81®ã\81ªã\81\84å ´å\90\88ã\81¯ã\80\81ã\83\87ã\83\95ã\82©ã\83«ã\83\88å\80¤ã\82\92æ\8c\87å®\9aã\81\97ã\81ªã\81\84ã\81 ã\81\91ã\81§ã\82¯ã\82¨ã\83ªã\83\91ã\83©ã\83¡ã\83¼ã\82¿`q`ã\82\92å¿\85é \88ã\81«ã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cできます。以下のように:
\81\93ã\82\8c以ä¸\8aã\80\81ã\83\90ã\83ªã\83\87ã\83¼ã\82·ã\83§ã\83³ã\82\84ã\83¡ã\82¿ã\83\87ã\83¼ã\82¿ã\82\92宣è¨\80ã\81\99ã\82\8bå¿\85è¦\81ã\81\8cã\81ªã\81\84å ´å\90\88ã\81¯ã\80\81ã\83\87ã\83\95ã\82©ã\83«ã\83\88å\80¤ã\82\92宣è¨\80ã\81\97ã\81ªã\81\84ã\81 ã\81\91ã\81§ã\82¯ã\82¨ã\83ªã\83\91ã\83©ã\83¡ã\83¼ã\82¿ `q` ã\82\92å¿\85é \88ã\81«できます。以下のように:
 
 ```Python
 q: str
@@ -123,42 +231,42 @@ q: str
 以下の代わりに:
 
 ```Python
-q: Union[str, None] = None
+q: str | None = None
 ```
 
-現在は以下の例のように`Query`で宣言しています:
+しかし今は、例えば次のように `Query` で宣言しています:
 
 ```Python
-q: Union[str, None] = Query(default=None, min_length=3)
+q: Annotated[str | None, Query(min_length=3)] = None
 ```
 
-そのため、`Query`を使用して必須の値を宣言する必要がある場合は、第一引数に`...`を使用することができます:
+そのため、`Query` を使いながら値を必須として宣言したい場合は、単にデフォルト値を宣言しません:
 
-{* ../../docs_src/query_params_str_validations/tutorial006.py hl[7] *}
+{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
 
-/// info | 情報
+### 必須、`None` にできる { #required-can-be-none }
 
\81\93ã\82\8cã\81¾ã\81§`...`ã\82\92è¦\8bã\81\9fã\81\93ã\81¨ã\81\8cã\81ªã\81\84æ\96¹ã\81¸: ã\81\93ã\82\8cã\81¯ç\89¹æ®\8aã\81ªå\8d\98ä¸\80å\80¤ã\81§ã\81\99ã\80\82<a href="https://docs.python.org/3/library/constants.html#Ellipsis" class="external-link" target="_blank">Pythonã\81®ä¸\80é\83¨ã\81§ã\81\82ã\82\8aã\80\81"Ellipsis"ã\81¨å\91¼ã\81°ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99</a>
\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81\8c `None` ã\82\92å\8f\97ã\81\91ä»\98ã\81\91ã\82\8bã\81\8cã\80\81ã\81\9dã\82\8cã\81§ã\82\82å¿\85é \88ã\81§ã\81\82ã\82\8bã\80\81ã\81¨å®£è¨\80ã\81§ã\81\8dã\81¾ã\81\99ã\80\82ã\81\93ã\82\8cã\81«ã\82\88ã\82\8aã\80\81å\80¤ã\81\8c `None` ã\81§ã\81\82ã\81£ã\81¦ã\82\82ã\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88ã\81¯å\80¤ã\82\92é\80\81ã\82\89ã\81ªã\81\91ã\82\8cã\81°ã\81ªã\82\89ã\81ªã\81\8fã\81ªã\82\8aã\81¾ã\81\99
 
-///
+そのために、`None` が有効な型であることを宣言しつつ、単にデフォルト値を宣言しません:
 
-これは **FastAPI** にこのパラメータが必須であることを知らせます。
+{* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *}
 
-## クエリパラメータのリスト / 複数の値
+## クエリパラメータのリスト / 複数の値 { #query-parameter-list-multiple-values }
 
-クエリパラメータを明示的に`Query`で宣言した場合、値のリストを受け取るように宣言したり、複数の値を受け取るように宣言したりすることもできます。
+クエリパラメータを明示的に `Query` で定義すると、値のリストを受け取るように宣言したり、言い換えると複数の値を受け取るように宣言したりすることもできます。
 
 例えば、URL内に複数回出現するクエリパラメータ`q`を宣言するには以下のように書きます:
 
-{* ../../docs_src/query_params_str_validations/tutorial011.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial011_an_py310.py hl[9] *}
 
-そしてURLは以下です:
+そして、次のような URL なら:
 
 ```
 http://localhost:8000/items/?q=foo&q=bar
 ```
 
-複数の*クエリパラメータ*の値`q`(`foo`と`bar`)を*path operation関数*内で*関数パラメータ*`q`としてPythonの`list`を受け取ることになります。
+*path operation function* 内の *function parameter* `q` で、複数の `q` *query parameters'* 値(`foo` と `bar`)を Python の `list` として受け取ります。
 
 そのため、このURLのレスポンスは以下のようになります:
 
@@ -179,15 +287,15 @@ http://localhost:8000/items/?q=foo&q=bar
 
 対話的APIドキュメントは複数の値を許可するために自動的に更新されます。
 
-<img src="https://fastapi.tiangolo.com/img/tutorial/query-params-str-validations/image02.png">
+<img src="/img/tutorial/query-params-str-validations/image02.png">
 
-### デフォルト値を持つ、クエリパラメータのリスト / 複数の値
+### デフォルト値を持つ、クエリパラメータのリスト / 複数の値 { #query-parameter-list-multiple-values-with-defaults }
 
-また、値が指定されていない場合はデフォルトの`list`を定義することもできます。
+また、値が指定されていない場合はデフォルトの `list` を定義することもできます。
 
-{* ../../docs_src/query_params_str_validations/tutorial012.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
 
-以ä¸\8bã\81®URLã\82\92é\96\8bã\81\8fと:
+以ä¸\8bã\81«ã\82¢ã\82¯ã\82»ã\82¹ã\81\99ã\82\8bと:
 
 ```
 http://localhost:8000/items/
@@ -204,21 +312,21 @@ http://localhost:8000/items/
 }
 ```
 
-#### `list`を使う
+#### `list` だけを使う { #using-just-list }
 
-`List[str]`の代わりに直接`list`を使うこともできます:
+`list[str]` の代わりに直接 `list` を使うこともできます:
 
-{* ../../docs_src/query_params_str_validations/tutorial013.py hl[7] *}
+{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
 
 /// note | 備考
 
 この場合、FastAPIはリストの内容をチェックしないことを覚えておいてください。
 
-例えば`List[int]`はリストの内容が整数であるかどうかをチェックします(そして、文書化します)。しかし`list`だけではそうしません。
+例えば`list[int]`はリストの内容が整数であるかどうかをチェックします(そして、文書化します)。しかし`list`だけではそうしません。
 
 ///
 
-## より多くのメタデータを宣言する
+## より多くのメタデータを宣言する { #declare-more-metadata }
 
 パラメータに関する情報をさらに追加することができます。
 
@@ -234,13 +342,13 @@ http://localhost:8000/items/
 
 `title`を追加できます:
 
-{* ../../docs_src/query_params_str_validations/tutorial007.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial007_an_py310.py hl[10] *}
 
 `description`を追加できます:
 
-{* ../../docs_src/query_params_str_validations/tutorial008.py hl[13] *}
+{* ../../docs_src/query_params_str_validations/tutorial008_an_py310.py hl[14] *}
 
-## エイリアスパラメータ
+## エイリアスパラメータ { #alias-parameters }
 
 パラメータに`item-query`を指定するとします.
 
@@ -258,23 +366,91 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
 
 それならば、`alias`を宣言することができます。エイリアスはパラメータの値を見つけるのに使用されます:
 
-{* ../../docs_src/query_params_str_validations/tutorial009.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial009_an_py310.py hl[9] *}
 
-## 非推奨パラメータ
+## パラメータを非推奨にする { #deprecating-parameters }
 
-さて、このパラメータが気に入らなくなったとしましょう
+さて、このパラメータが気に入らなくなったとしましょう
 
-それを使っているクライアントがいるので、しばらくは残しておく必要がありますが、ドキュメントには<abbr title="使わない方がよい">非推奨</abbr>と明記しておきたいです。
+それを使っているクライアントがいるので、しばらくは残しておく必要がありますが、ドキュメントには<abbr title="obsolete, recommended not to use it">deprecated</abbr>と明記しておきたいです。
 
 その場合、`Query`にパラメータ`deprecated=True`を渡します:
 
-{* ../../docs_src/query_params_str_validations/tutorial010.py hl[18] *}
+{* ../../docs_src/query_params_str_validations/tutorial010_an_py310.py hl[19] *}
 
 ドキュメントは以下のようになります:
 
-<img src="https://fastapi.tiangolo.com/img/tutorial/query-params-str-validations/image01.png">
+<img src="/img/tutorial/query-params-str-validations/image01.png">
 
-## まとめ
+## OpenAPI からパラメータを除外する { #exclude-parameters-from-openapi }
+
+生成される OpenAPI スキーマ(つまり自動ドキュメントシステム)からクエリパラメータを除外するには、`Query` のパラメータ `include_in_schema` を `False` に設定します:
+
+{* ../../docs_src/query_params_str_validations/tutorial014_an_py310.py hl[10] *}
+
+## カスタムバリデーション { #custom-validation }
+
+上で示したパラメータではできない **カスタムバリデーション** が必要になる場合があります。
+
+その場合、通常のバリデーション(例: 値が `str` であることの検証)の後に適用される **カスタムバリデータ関数** を使えます。
+
+これを行うには、`Annotated` の中で <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator" class="external-link" target="_blank">Pydantic の `AfterValidator`</a> を使います。
+
+/// tip | 豆知識
+
+Pydantic には <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator" class="external-link" target="_blank">`BeforeValidator`</a> などもあります。 🤓
+
+///
+
+例えば、このカスタムバリデータは、<abbr title="ISBN means International Standard Book Number – 国際標準図書番号">ISBN</abbr> の書籍番号なら item ID が `isbn-` で始まること、<abbr title="IMDB (Internet Movie Database) is a website with information about movies – IMDB(Internet Movie Database)は映画に関する情報を掲載するWebサイトです">IMDB</abbr> の movie URL ID なら `imdb-` で始まることをチェックします:
+
+{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
+
+/// info | 情報
+
+これは Pydantic バージョン 2 以上で利用できます。 😎
+
+///
+
+/// tip | 豆知識
+
+データベースや別の API など、何らかの **外部コンポーネント** との通信が必要なタイプのバリデーションを行う必要がある場合は、代わりに **FastAPI Dependencies** を使うべきです。これについては後で学びます。
+
+これらのカスタムバリデータは、リクエストで提供された **同じデータのみ** でチェックできるもの向けです。
+
+///
+
+### そのコードを理解する { #understand-that-code }
+
+重要なのは、**`Annotated` の中で関数と一緒に `AfterValidator` を使うこと** だけです。この部分は飛ばしても構いません。 🤸
+
+---
+
+ただし、この具体的なコード例が気になっていて、まだ興味が続くなら、追加の詳細を示します。
+
+#### `value.startswith()` を使う文字列 { #string-with-value-startswith }
+
+気づきましたか?`value.startswith()` を使う文字列はタプルを受け取れ、そのタプル内の各値をチェックします:
+
+{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[16:19] hl[17] *}
+
+#### ランダムなアイテム { #a-random-item }
+
+`data.items()` で、辞書の各アイテムのキーと値を含むタプルを持つ <abbr title="Something we can iterate on with a for loop, like a list, set, etc.">反復可能オブジェクト</abbr> を取得します。
+
+この反復可能オブジェクトを `list(data.items())` で適切な `list` に変換します。
+
+そして `random.choice()` でその `list` から **ランダムな値** を取得するので、`(id, name)` のタプルを得ます。これは `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")` のようになります。
+
+次に、そのタプルの **2つの値を代入** して、変数 `id` と `name` に入れます。
+
+つまり、ユーザーが item ID を提供しなかった場合でも、ランダムな提案を受け取ります。
+
+...これを **単一のシンプルな1行** で行っています。 🤯 Python が好きになりませんか? 🐍
+
+{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[22:30] hl[29] *}
+
+## まとめ { #recap }
 
 パラメータに追加のバリデーションとメタデータを宣言することができます。
 
@@ -285,12 +461,14 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
 * `description`
 * `deprecated`
 
\96\87å­\97å\88\97ã\81®ã\81\9fã\82\81のバリデーション:
\96\87å­\97å\88\97ã\81«å\9bºæ\9c\89のバリデーション:
 
 * `min_length`
 * `max_length`
-* `regex`
+* `pattern`
+
+`AfterValidator` を使ったカスタムバリデーション。
 
-この例では、`str`の値のバリデーションを宣言する方法を見てきました。
+この例では、`str` の値のバリデーションを宣言する方法を見てきました。
 
 数値のような他の型のバリデーションを宣言する方法は次の章を参照してください。
index 74e455579e96e87d011bb8d0ffeae1c9db7cfb30..41e51ed782f8c4ef89464b19bd1cf510213e3b13 100644 (file)
@@ -1,8 +1,8 @@
-# クエリパラメータ
+# クエリパラメータ { #query-parameters }
 
-パスパラメータではない関数パラメータを宣言すると、それらは自動的に "クエリ" パラメータとして解釈されます。
+パスパラメータではない関数パラメータを宣言すると、それらは自動的に「クエリ」パラメータとして解釈されます。
 
-{* ../../docs_src/query_params/tutorial001.py hl[9] *}
+{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
 
 クエリはURL内で `?` の後に続くキーとバリューの組で、 `&` で区切られています。
 
@@ -24,11 +24,11 @@ http://127.0.0.1:8000/items/?skip=0&limit=10
 パスパラメータに適用される処理と完全に同様な処理がクエリパラメータにも施されます:
 
 * エディターサポート (明らかに)
-* データ「<abbr title="HTTPリクエストで受け取った文字列をPythonデータへ変換する">解析</abbr>」
+* データ <abbr title="converting the string that comes from an HTTP request into Python data">「解析」</abbr>
 * データバリデーション
 * 自動ドキュメント生成
 
-## デフォルト
+## デフォルト { #defaults }
 
 クエリパラメータはパスの固定部分ではないので、オプショナルとしたり、デフォルト値をもつことができます。
 
@@ -55,13 +55,13 @@ http://127.0.0.1:8000/items/?skip=20
 関数内のパラメータの値は以下の様になります:
 
 * `skip=20`: URL内にセットしたため
-* `limit=10`: デフォルト値
+* `limit=10`: デフォルト値だったため
 
-## オプショナルなパラメータ
+## オプショナルなパラメータ { #optional-parameters }
 
 同様に、デフォルト値を `None` とすることで、オプショナルなクエリパラメータを宣言できます:
 
-{* ../../docs_src/query_params/tutorial002.py hl[9] *}
+{* ../../docs_src/query_params/tutorial002_py310.py hl[7] *}
 
 この場合、関数パラメータ `q` はオプショナルとなり、デフォルトでは `None` になります。
 
@@ -71,11 +71,11 @@ http://127.0.0.1:8000/items/?skip=20
 
 ///
 
-## クエリパラメータの型変換
+## クエリパラメータの型変換 { #query-parameter-type-conversion }
 
-`bool` å\9e\8bã\82\82宣è¨\80ã\81§ã\81\8dã\81¾ã\81\99ã\80\82ã\81\93ã\82\8cã\81¯ä»¥ä¸\8bã\81®æ§\98ã\81«変換されます:
+`bool` å\9e\8bã\82\82宣è¨\80ã\81§ã\81\8dã\80\81変換されます:
 
-{* ../../docs_src/query_params/tutorial003.py hl[9] *}
+{* ../../docs_src/query_params/tutorial003_py310.py hl[7] *}
 
 この場合、以下にアクセスすると:
 
@@ -109,27 +109,28 @@ http://127.0.0.1:8000/items/foo?short=yes
 
 もしくは、他の大文字小文字のバリエーション (アッパーケース、最初の文字だけアッパーケース、など)で、関数は `short` パラメータを `True` な `bool` 値として扱います。それ以外は `False` になります。
 
-## 複数のパスパラメータとクエリパラメータ
 
-複数のパスパラメータとクエリパラメータを同時に宣言できます。**FastAPI**は互いを区別できます。
+## 複数のパスパラメータとクエリパラメータ { #multiple-path-and-query-parameters }
+
+複数のパスパラメータとクエリパラメータを同時に宣言できます。**FastAPI**はどれがどれかを把握しています。
 
 そして特定の順序で宣言しなくてもよいです。
 
 名前で判別されます:
 
-{* ../../docs_src/query_params/tutorial004.py hl[8,10] *}
+{* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *}
 
-## 必須のクエリパラメータ
+## 必須のクエリパラメータ { #required-query-parameters }
 
\83\91ã\82¹ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ä»¥å¤\96ã\81®ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ (ä»\8aã\81®ã\81¨ã\81\93ã\82\8dã\80\81ã\82¯ã\82¨ã\83ªã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81®ã\81¿èª¬æ\98\8eã\81\97ました) のデフォルト値を宣言した場合、そのパラメータは必須ではなくなります。
\83\91ã\82¹ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ä»¥å¤\96ã\81®ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ (ä»\8aã\81®ã\81¨ã\81\93ã\82\8dã\80\81ã\82¯ã\82¨ã\83ªã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81®ã\81¿è¦\8bã\81¦ã\81\8dました) のデフォルト値を宣言した場合、そのパラメータは必須ではなくなります。
 
 特定の値を与えずにただオプショナルにしたい場合はデフォルト値を `None` にして下さい。
 
 しかしクエリパラメータを必須にしたい場合は、ただデフォルト値を宣言しなければよいです:
 
-{* ../../docs_src/query_params/tutorial005.py hl[6:7] *}
+{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
 
-ここで、クエリパラメータ `needy` は `str` 型の必須のクエリパラメータです
+ここで、クエリパラメータ `needy` は `str` 型の必須のクエリパラメータです
 
 以下のURLをブラウザで開くと:
 
@@ -141,16 +142,17 @@ http://127.0.0.1:8000/items/foo-item
 
 ```JSON
 {
-    "detail": [
-        {
-            "loc": [
-                "query",
-                "needy"
-            ],
-            "msg": "field required",
-            "type": "value_error.missing"
-        }
-    ]
+  "detail": [
+    {
+      "type": "missing",
+      "loc": [
+        "query",
+        "needy"
+      ],
+      "msg": "Field required",
+      "input": null
+    }
+  ]
 }
 ```
 
@@ -169,9 +171,9 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
 }
 ```
 
-そして当然、あるパラメータを必須に、別のパラメータにデフォルト値を設定し、また別のパラメータをオプショナルにできます:
+そして当然、あるパラメータを必須に、あるパラメータにデフォルト値を設定し、またあるパラメータを完全にオプショナルにできます:
 
-{* ../../docs_src/query_params/tutorial006.py hl[10] *}
+{* ../../docs_src/query_params/tutorial006_py310.py hl[8] *}
 
 この場合、3つのクエリパラメータがあります。:
 
@@ -181,6 +183,6 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
 
 /// tip | 豆知識
 
-[パスパラメータ](path-params.md#_8){.internal-link target=_blank}と同様に `Enum` を使用できます。
+[パスパラメータ](path-params.md#predefined-values){.internal-link target=_blank}と同様に `Enum` を使用できます。
 
 ///
index 110e3106a6d17f4e1f253cee1e88e90fb0802d0c..09e1277c8cc28239afaa330ded10d01a773ea933 100644 (file)
@@ -1,24 +1,28 @@
-# リクエストフォームとファイル
+# リクエストフォームとファイル { #request-forms-and-files }
 
 `File`と`Form`を同時に使うことでファイルとフォームフィールドを定義することができます。
 
 /// info | 情報
 
-アップロードされたファイルやフォームデータを受信するには、まず<a href="https://andrew-d.github.io/python-multipart/" class="external-link" target="_blank">`python-multipart`</a>をインストールします。
+アップロードされたファイルやフォームデータを受信するには、まず<a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>をインストールします。
 
-例えば、`pip install python-multipart`のように。
+[仮想環境](../virtual-environments.md){.internal-link target=_blank}を作成し、それを有効化してから、例えば次のようにインストールしてください:
+
+```console
+$ pip install python-multipart
+```
 
 ///
 
-## `File`と`Form`のインポート
+## `File`と`Form`のインポート { #import-file-and-form }
 
-{* ../../docs_src/request_forms_and_files/tutorial001.py hl[1] *}
+{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[3] *}
 
-## `File`と`Form`のパラメータの定義
+## `File`と`Form`のパラメータの定義 { #define-file-and-form-parameters }
 
 ファイルやフォームのパラメータは`Body`や`Query`の場合と同じように作成します:
 
-{* ../../docs_src/request_forms_and_files/tutorial001.py hl[8] *}
+{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[10:12] *}
 
 ファイルとフォームフィールドがフォームデータとしてアップロードされ、ファイルとフォームフィールドを受け取ります。
 
@@ -32,6 +36,6 @@
 
 ///
 
-## まとめ
+## まとめ { #recap }
 
 同じリクエストでデータやファイルを受け取る必要がある場合は、`File` と`Form`を一緒に使用します。
index eca2cd6dc712f5fe30968f873b20642eac4b21f0..1bdc28670b937faa1d14954fa9e8530a71a429e4 100644 (file)
@@ -1,4 +1,4 @@
-# フォームデータ
+# フォームデータ { #form-data }
 
 JSONの代わりにフィールドを受け取る場合は、`Form`を使用します。
 
@@ -6,27 +6,31 @@ JSONの代わりにフィールドを受け取る場合は、`Form`を使用し
 
 フォームを使うためには、まず<a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>をインストールします。
 
-たとえば、`pip install python-multipart`のように。
+必ず[仮想環境](../virtual-environments.md){.internal-link target=_blank}を作成して有効化してから、例えば次のようにインストールしてください:
+
+```console
+$ pip install python-multipart
+```
 
 ///
 
-## `Form`のインポート
+## `Form`のインポート { #import-form }
 
 `fastapi`から`Form`をインポートします:
 
-{* ../../docs_src/request_forms/tutorial001.py hl[1] *}
+{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
 
-## `Form`のパラメータの定義
+## `Form`のパラメータの定義 { #define-form-parameters }
 
 `Body`や`Query`の場合と同じようにフォームパラメータを作成します:
 
-{* ../../docs_src/request_forms/tutorial001.py hl[7] *}
+{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
 
 例えば、OAuth2仕様が使用できる方法の1つ(「パスワードフロー」と呼ばれる)では、フォームフィールドとして`username`と`password`を送信する必要があります。
 
-<abbr title="仕様">仕様</abbr>では、フィールドの名前が`username`と`password`であることと、JSONではなくフォームフィールドとして送信されることを要求しています。
+<abbr title="specification – 仕様">spec</abbr>では、フィールドの名前が`username`と`password`であることと、JSONではなくフォームフィールドとして送信されることを要求しています。
 
-`Form`では`Body`(および`Query`や`Path`、`Cookie`)と同じメタデータとバリデーションを宣言することができます。
+`Form`では`Body`(および`Query`や`Path`、`Cookie`)と同じ設定を宣言することができます。これには、バリデーション、例、エイリアス(例えば`username`の代わりに`user-name`)などが含まれます。
 
 /// info | 情報
 
@@ -40,7 +44,7 @@ JSONの代わりにフィールドを受け取る場合は、`Form`を使用し
 
 ///
 
-## 「フォームフィールド」について
+## 「フォームフィールド」について { #about-form-fields }
 
 HTMLフォーム(`<form></form>`)がサーバにデータを送信する方法は、通常、そのデータに「特別な」エンコーディングを使用していますが、これはJSONとは異なります。
 
@@ -64,6 +68,6 @@ HTMLフォーム(`<form></form>`)がサーバにデータを送信する方
 
 ///
 
-## まとめ
+## まとめ { #recap }
 
 フォームデータの入力パラメータを宣言するには、`Form`を使用する。
index b8464a4c73f52729f99866c70050325d65444d65..258eac8e67da9d3e667f0b0c88a13cff99ad24ae 100644 (file)
@@ -1,6 +1,35 @@
-# レスポンスモデル
+# レスポンスモデル - 戻り値の型 { #response-model-return-type }
 
-*path operations* のいずれにおいても、`response_model`パラメータを使用して、レスポンスのモデルを宣言することができます:
+*path operation 関数*の**戻り値の型**にアノテーションを付けることで、レスポンスに使用される型を宣言できます。
+
+関数**パラメータ**の入力データと同じように **型アノテーション** を使用できます。Pydanticモデル、リスト、辞書、整数や真偽値などのスカラー値を使用できます。
+
+{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
+
+FastAPIはこの戻り値の型を使って以下を行います:
+
+* 返却データを**検証**します。
+    * データが不正(例: フィールドが欠けている)であれば、それは*あなた*のアプリコードが壊れていて、返すべきものを返していないことを意味し、不正なデータを返す代わりにサーバーエラーを返します。これにより、あなたとクライアントは、期待されるデータとデータ形状を受け取れることを確実にできます。
+* OpenAPIの *path operation* に、レスポンス用の **JSON Schema** を追加します。
+    * これは**自動ドキュメント**で使用されます。
+    * 自動クライアントコード生成ツールでも使用されます。
+
+しかし、最も重要なのは:
+
+* 戻り値の型で定義された内容に合わせて、出力データを**制限しフィルタリング**します。
+    * これは**セキュリティ**の観点で特に重要です。以下で詳しく見ていきます。
+
+## `response_model`パラメータ { #response-model-parameter }
+
+型が宣言している内容とまったく同じではないデータを返す必要がある、またはそうしたいケースがあります。
+
+例えば、**辞書を返す**、またはデータベースオブジェクトを返したいが、**Pydanticモデルとして宣言**したい場合があります。こうすることで、Pydanticモデルが返したオブジェクト(例: 辞書やデータベースオブジェクト)のドキュメント化、バリデーションなどをすべて行ってくれます。
+
+戻り値の型アノテーションを追加すると、ツールやエディタが(正しく)エラーとして、関数が宣言した型(例: Pydanticモデル)とは異なる型(例: dict)を返していると警告します。
+
+そのような場合、戻り値の型の代わりに、*path operation デコレータ*のパラメータ `response_model` を使用できます。
+
+`response_model`パラメータは、いずれの *path operation* でも使用できます:
 
 * `@app.get()`
 * `@app.post()`
 * `@app.delete()`
 * など。
 
-{* ../../docs_src/response_model/tutorial001.py hl[17] *}
+{* ../../docs_src/response_model/tutorial001_py310.py hl[17,22,24:27] *}
 
 /// note | 備考
 
-`response_model`は「デコレータ」メソッド(`get`、`post`など)のパラメータであることに注意してください。すべてのパラメータやボディのように、*path operation関数* のパラメータではありません。
+`response_model`は「デコレータ」メソッド(`get`、`post`など)のパラメータであることに注意してください。すべてのパラメータやボディのように、*path operation 関数* のパラメータではありません。
 
 ///
 
-Pydanticモデルの属性に対して宣言するのと同じ型を受け取るので、Pydanticモデルになることもできますが、例えば、`List[Item]`のようなPydanticモデルの`list`になることもできます。
+`response_model`は、Pydanticモデルのフィールドで宣言するのと同じ型を受け取ります。そのため、Pydanticモデルにもできますし、例えば `List[Item]` のように、Pydanticモデルの `list` にもできます。
 
-FastAPIは`response_model`を使って以下のことをします:
+FastAPIはこの `response_model` を使って、データのドキュメント化や検証などを行い、さらに出力データを型宣言に合わせて**変換・フィルタリング**します。
 
-* 出力データを型宣言に変換します。
-* データを検証します。
-* OpenAPIの *path operation* で、レスポンス用のJSON Schemaを追加します。
-* 自動ドキュメントシステムで使用されます。
+/// tip | 豆知識
 
\81\97ã\81\8bã\81\97ã\80\81æ\9c\80ã\82\82é\87\8dè¦\81ã\81ªã\81®ã\81¯:
\82¨ã\83\87ã\82£ã\82¿ã\82\84mypyã\81ªã\81©ã\81§å\8e³å¯\86ã\81ªå\9e\8bã\83\81ã\82§ã\83\83ã\82¯ã\82\92ã\81\97ã\81¦ã\81\84ã\82\8bå ´å\90\88ã\80\81é\96¢æ\95°ã\81®æ\88»ã\82\8aå\80¤ã\81®å\9e\8bã\82\92 `Any` ã\81¨ã\81\97ã\81¦å®£è¨\80ã\81§ã\81\8dã\81¾ã\81\99ã\80\82
 
-* 出力データをモデルのデータに限定します。これがどのように重要なのか以下で見ていきましょう
+そうすると、意図的に何でも返していることをエディタに伝えられます。それでもFastAPIは `response_model` を使って、データのドキュメント化、検証、フィルタリングなどを行います
 
-/// note | 技術詳細
+///
 
-レスポンスモデルは、関数の戻り値のアノテーションではなく、このパラメータで宣言されています。なぜなら、パス関数は実際にはそのレスポンスモデルを返すのではなく、`dict`やデータベースオブジェクト、あるいは他のモデルを返し、`response_model`を使用してフィールドの制限やシリアライズを行うからです。
+### `response_model`の優先順位 { #response-model-priority }
 
-///
+戻り値の型と `response_model` の両方を宣言した場合、`response_model` が優先され、FastAPIで使用されます。
+
+これにより、レスポンスモデルとは異なる型を返している場合でも、エディタやmypyなどのツールで使用するために関数へ正しい型アノテーションを追加できます。それでもFastAPIは `response_model` を使用してデータの検証やドキュメント化などを実行できます。
+
+また `response_model=None` を使用して、その*path operation*のレスポンスモデル生成を無効化することもできます。これは、Pydanticのフィールドとして有効ではないものに対して型アノテーションを追加する場合に必要になることがあります。以下のセクションのいずれかで例を示します。
+
+## 同じ入力データの返却 { #return-the-same-input-data }
 
-## 同じ入力データの返却
+ここでは `UserIn` モデルを宣言しています。これには平文のパスワードが含まれます:
 
-ここでは`UserIn`モデルを宣言しています。それには平文のパスワードが含まれています:
+{* ../../docs_src/response_model/tutorial002_py310.py hl[7,9] *}
 
-{* ../../docs_src/response_model/tutorial002.py hl[9,11] *}
+/// info | 情報
+
+`EmailStr` を使用するには、最初に <a href="https://github.com/JoshData/python-email-validator" class="external-link" target="_blank">`email-validator`</a> をインストールしてください。
+
+[仮想環境](../virtual-environments.md){.internal-link target=_blank}を作成して有効化してから、例えば次のようにインストールしてください:
+
+```console
+$ pip install email-validator
+```
+
+または次のようにします:
+
+```console
+$ pip install "pydantic[email]"
+```
+
+///
 
 そして、このモデルを使用して入力を宣言し、同じモデルを使って出力を宣言しています:
 
-{* ../../docs_src/response_model/tutorial002.py hl[17,18] *}
+{* ../../docs_src/response_model/tutorial002_py310.py hl[16] *}
 
 これで、ブラウザがパスワードを使ってユーザーを作成する際に、APIがレスポンスで同じパスワードを返すようになりました。
 
-この場合、ユーザー自身がパスワードを送信しているので問題ないかもしれません。
+この場合、同じユーザーがパスワードを送信しているので問題ないかもしれません。
 
-しかし、同じモデルを別の*path operation*に使用すると、すべてのクライアントにユーザーのパスワードを送信してしまうことになります。
+しかし、同じモデルを別の*path operation*に使用すると、すべてのクライアントにユーザーのパスワードを送信してしまう可能性があります。
 
-/// danger | 危険
+/// danger | 警告
 
\83¦ã\83¼ã\82¶ã\83¼ã\81®å¹³æ\96\87ã\81®ã\83\91ã\82¹ã\83¯ã\83¼ã\83\89ã\82\92ä¿\9då­\98ã\81\97ã\81\9fã\82\8aã\80\81ã\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\81§é\80\81ä¿¡ã\81\97ã\81\9fã\82\8aã\81\99ã\82\8bã\81\93ã\81¨ã\81¯çµ¶å¯¾ã\81«しないでください。
\81\99ã\81¹ã\81¦ã\81®æ³¨æ\84\8fç\82¹ã\82\92ç\90\86è§£ã\81\97ã\81¦ã\81\84ã\81¦ã\80\81è\87ªå\88\86ã\81\8cä½\95ã\82\92ã\81\97ã\81¦ã\81\84ã\82\8bã\81\8bå\88\86ã\81\8bã\81£ã\81¦ã\81\84ã\82\8bå ´å\90\88ã\82\92é\99¤ã\81\8dã\80\81ã\83¦ã\83¼ã\82¶ã\83¼ã\81®å¹³æ\96\87ã\81®ã\83\91ã\82¹ã\83¯ã\83¼ã\83\89ã\82\92ä¿\9då­\98ã\81\97ã\81\9fã\82\8aã\80\81ã\81\93ã\81®ã\82\88ã\81\86ã\81«ã\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\81§é\80\81ä¿¡ã\81\97ã\81\9fã\82\8aしないでください。
 
 ///
 
-## 出力モデルの追加
+## 出力モデルの追加 { #add-an-output-model }
+
+代わりに、平文のパスワードを持つ入力モデルと、パスワードを持たない出力モデルを作成できます:
+
+{* ../../docs_src/response_model/tutorial003_py310.py hl[9,11,16] *}
+
+ここでは、*path operation 関数*がパスワードを含む同じ入力ユーザーを返しているにもかかわらず:
+
+{* ../../docs_src/response_model/tutorial003_py310.py hl[24] *}
+
+...`response_model`を、パスワードを含まない `UserOut` モデルとして宣言しました:
+
+{* ../../docs_src/response_model/tutorial003_py310.py hl[22] *}
+
+そのため、**FastAPI** は出力モデルで宣言されていないすべてのデータをフィルタリングしてくれます(Pydanticを使用)。
+
+### `response_model`または戻り値の型 { #response-model-or-return-type }
+
+このケースでは2つのモデルが異なるため、関数の戻り値の型を `UserOut` としてアノテーションすると、エディタやツールは、異なるクラスなので不正な型を返していると警告します。
+
+そのため、この例では `response_model` パラメータで宣言する必要があります。
 
-代わりに、平文のパスワードを持つ入力モデルと、パスワードを持たない出力モデルを作成することができます:
+...しかし、これを解決する方法を以下で確認しましょう。
 
-{* ../../docs_src/response_model/tutorial003.py hl[9,11,16] *}
+## 戻り値の型とデータフィルタリング { #return-type-and-data-filtering }
 
-ここでは、*path operation関数*がパスワードを含む同じ入力ユーザーを返しているにもかかわらず:
+前の例から続けます。**関数に1つの型をアノテーション**したい一方で、関数からは実際には**より多くのデータ**を含むものを返せるようにしたいとします。
 
-{* ../../docs_src/response_model/tutorial003.py hl[24] *}
+FastAPIにはレスポンスモデルを使用してデータを**フィルタリング**し続けてほしいです。つまり、関数がより多くのデータを返しても、レスポンスにはレスポンスモデルで宣言されたフィールドのみが含まれます。
 
-...`response_model`を`UserOut`と宣言したことで、パスワードが含まれていません:
+前の例ではクラスが異なるため `response_model` パラメータを使う必要がありました。しかしそれは、エディタやツールによる関数の戻り値の型チェックのサポートを受けられないことも意味します。
 
-{* ../../docs_src/response_model/tutorial003.py hl[22] *}
+しかし、このようなことが必要になる多くのケースでは、この例のようにモデルでデータの一部を**フィルタ/削除**したいだけです。
 
\81\9dã\81®ã\81\9fã\82\81ã\80\81**FastAPI** ã\81¯å\87ºå\8a\9bã\83¢ã\83\87ã\83«ã\81§å®£è¨\80ã\81\95ã\82\8cã\81¦ã\81\84ã\81ªã\81\84å\85¨ã\81¦ã\81®ã\83\87ã\83¼ã\82¿ã\82\92ã\83\95ã\82£ã\83«ã\82¿ã\83ªã\83³ã\82°ã\81\97ã\81¦ã\81\8fã\82\8cã\81¾ã\81\99ï¼\88Pydanticã\82\92使ç\94¨ï¼\89
\81\9dã\81®ã\82\88ã\81\86ã\81ªå ´å\90\88ã\80\81ã\82¯ã\83©ã\82¹ã\81¨ç¶\99æ\89¿ã\82\92å\88©ç\94¨ã\81\97ã\81¦é\96¢æ\95°ã\81®**å\9e\8bã\82¢ã\83\8eã\83\86ã\83¼ã\82·ã\83§ã\83³**ã\82\92æ´»ç\94¨ã\81\97ã\80\81ã\82¨ã\83\87ã\82£ã\82¿ã\82\84ã\83\84ã\83¼ã\83«ã\81®ã\82µã\83\9dã\83¼ã\83\88ã\82\92æ\94¹å\96\84ã\81\97ã\81¤ã\81¤ã\80\81FastAPIã\81®**ã\83\87ã\83¼ã\82¿ã\83\95ã\82£ã\83«ã\82¿ã\83ªã\83³ã\82°**ã\82\82å¾\97ã\82\89ã\82\8cã\81¾ã\81\99
 
-## ドキュメントを見る
+{* ../../docs_src/response_model/tutorial003_01_py310.py hl[7:10,13:14,18] *}
 
-自動ドキュメントを見ると、入力モデルと出力モデルがそれぞれ独自のJSON Schemaを持っていることが確認できます。
+これにより、このコードは型として正しいためエディタやmypyからのツール支援を得られますし、FastAPIによるデータフィルタリングも得られます。
 
-<img src="https://fastapi.tiangolo.com/img/tutorial/response-model/image01.png">
+これはどのように動作するのでしょうか?確認してみましょう。🤓
 
-そして、両方のモデルは、対話型のAPIドキュメントに使用されます:
+### 型アノテーションとツール支援 { #type-annotations-and-tooling }
 
-<img src="https://fastapi.tiangolo.com/img/tutorial/response-model/image02.png">
+まず、エディタ、mypy、その他のツールがこれをどう見るかを見てみます。
 
-## レスポンスモデルのエンコーディングパラメータ
+`BaseUser` には基本フィールドがあります。次に `UserIn` が `BaseUser` を継承して `password` フィールドを追加するため、両方のモデルのフィールドがすべて含まれます。
 
-レスポンスモデルにはデフォルト値を設定することができます:
+関数の戻り値の型を `BaseUser` としてアノテーションしますが、実際には `UserIn` インスタンスを返しています。
 
-{* ../../docs_src/response_model/tutorial004.py hl[11,13,14] *}
+エディタやmypyなどのツールはこれに文句を言いません。typingの観点では、`UserIn` は `BaseUser` のサブクラスであり、期待されるものが `BaseUser` であれば `UserIn` は*有効*な型だからです。
 
-* `description: str = None`は`None`がデフォルト値です。
-* `tax: float = 10.5`は`10.5`がデフォルト値です。
-* `tags: List[str] = []` は空のリスト(`[]`)がデフォルト値です。
+### FastAPIのデータフィルタリング { #fastapi-data-filtering }
 
-しかし、実際に保存されていない場合には結果からそれらを省略した方が良いかもしれません。
+一方FastAPIでは、戻り値の型を見て、返す内容にその型で宣言されたフィールド**だけ**が含まれることを確認します。
+
+FastAPIは、返却データのフィルタリングにクラス継承の同じルールが使われてしまわないようにするため、内部でPydanticを使っていくつかの処理を行っています。そうでないと、期待以上に多くのデータを返してしまう可能性があります。
+
+この方法で、**ツール支援**付きの型アノテーションと**データフィルタリング**の両方という、いいとこ取りができます。
+
+## ドキュメントを見る { #see-it-in-the-docs }
+
+自動ドキュメントを見ると、入力モデルと出力モデルがそれぞれ独自のJSON Schemaを持っていることが確認できます:
+
+<img src="/img/tutorial/response-model/image01.png">
+
+そして、両方のモデルは対話型のAPIドキュメントに使用されます:
+
+<img src="/img/tutorial/response-model/image02.png">
+
+## その他の戻り値の型アノテーション { #other-return-type-annotations }
+
+Pydanticフィールドとして有効ではないものを返し、ツール(エディタやmypyなど)が提供するサポートを得るためだけに、関数でそれをアノテーションするケースがあるかもしれません。
+
+### レスポンスを直接返す { #return-a-response-directly }
+
+最も一般的なケースは、[高度なドキュメントで後述する「Responseを直接返す」](../advanced/response-directly.md){.internal-link target=_blank}場合です。
+
+{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
+
+このシンプルなケースは、戻り値の型アノテーションが `Response` のクラス(またはサブクラス)であるため、FastAPIが自動的に処理します。
+
+また `RedirectResponse` と `JSONResponse` の両方は `Response` のサブクラスなので、ツールも型アノテーションが正しいとして問題にしません。
+
+### `Response`のサブクラスをアノテーションする { #annotate-a-response-subclass }
+
+型アノテーションで `Response` のサブクラスを使うこともできます:
+
+{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
+
+これは `RedirectResponse` が `Response` のサブクラスであり、FastAPIがこのシンプルなケースを自動処理するため、同様に動作します。
+
+### 無効な戻り値の型アノテーション { #invalid-return-type-annotations }
+
+しかし、Pydantic型として有効ではない別の任意のオブジェクト(例: データベースオブジェクト)を返し、関数でそのようにアノテーションすると、FastAPIはその型アノテーションからPydanticレスポンスモデルを作成しようとして失敗します。
+
+同様に、<abbr title='複数の型のunionは「これらの型のいずれか」を意味します。'>union</abbr>のように、複数の型のうち1つ以上がPydantic型として有効でないものを含む場合も起こります。例えば次は失敗します 💥:
+
+{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
+
+...これは、型アノテーションがPydantic型ではなく、単一の `Response` クラス(またはサブクラス)でもないために失敗します。`Response` と `dict` の間のunion(どちらか)になっているからです。
+
+### レスポンスモデルを無効化する { #disable-response-model }
+
+上の例を続けると、FastAPIが実行するデフォルトのデータ検証、ドキュメント化、フィルタリングなどを行いたくないこともあるでしょう。
+
+しかし、エディタや型チェッカー(例: mypy)などのツール支援を得るために、関数の戻り値の型アノテーションは残したいかもしれません。
+
+その場合、`response_model=None` を設定することでレスポンスモデルの生成を無効にできます:
+
+{* ../../docs_src/response_model/tutorial003_05_py310.py hl[7] *}
+
+これによりFastAPIはレスポンスモデル生成をスキップし、FastAPIアプリケーションに影響させずに必要な戻り値の型アノテーションを付けられます。🤓
+
+## レスポンスモデルのエンコーディングパラメータ { #response-model-encoding-parameters }
+
+レスポンスモデルには次のようにデフォルト値を設定できます:
+
+{* ../../docs_src/response_model/tutorial004_py310.py hl[9,11:12] *}
+
+* `description: Union[str, None] = None`(またはPython 3.10では `str | None = None`)はデフォルトが `None` です。
+* `tax: float = 10.5` はデフォルトが `10.5` です。
+* `tags: List[str] = []` はデフォルトが空のリスト `[]` です。
+
+ただし、それらが実際には保存されていない場合、結果から省略したいことがあります。
 
 例えば、NoSQLデータベースに多くのオプション属性を持つモデルがあるが、デフォルト値でいっぱいの非常に長いJSONレスポンスを送信したくない場合です。
 
-### `response_model_exclude_unset`パラメータの使用
+### `response_model_exclude_unset`パラメータの使用 { #use-the-response-model-exclude-unset-parameter }
 
-*path operation ã\83\87ã\82³ã\83¬ã\83¼ã\82¿*ã\81«`response_model_exclude_unset=True`ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\82\92設å®\9aã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cできます:
+*path operation ã\83\87ã\82³ã\83¬ã\83¼ã\82¿*ã\81®ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ `response_model_exclude_unset=True` ã\82\92設å®\9aできます:
 
-{* ../../docs_src/response_model/tutorial004.py hl[24] *}
+{* ../../docs_src/response_model/tutorial004_py310.py hl[22] *}
 
\81\9dã\81\97ã\81¦ã\80\81ã\81\93ã\82\8cã\82\89ã\81®デフォルト値はレスポンスに含まれず、実際に設定された値のみが含まれます。
\81\9dã\81\86ã\81\99ã\82\8bã\81¨ã\80\81デフォルト値はレスポンスに含まれず、実際に設定された値のみが含まれます。
 
-そのため、*path operation*にID`foo`が設定されたitemのリクエストを送ると、レスポンスは以下のようになります(デフォルト値を含まない):
+そのため、ID `foo` のitemに対してその *path operation* へリクエストを送ると、レスポンスは以下のようになります(デフォルト値を含まない):
 
 ```JSON
 {
@@ -116,26 +252,20 @@ FastAPIは`response_model`を使って以下のことをします:
 
 /// info | 情報
 
-FastAPIはこれをするために、Pydanticモデルの`.dict()`を<a href="https://docs.pydantic.dev/latest/concepts/serialization/#modeldict" class="external-link" target="_blank">その`exclude_unset`パラメータ</a>で使用しています。
-
-///
-
-/// info | 情報
-
-以下も使用することができます:
+以下も使用できます:
 
 * `response_model_exclude_defaults=True`
 * `response_model_exclude_none=True`
 
-`exclude_defaults`と`exclude_none`については、<a href="https://docs.pydantic.dev/latest/concepts/serialization/#modeldict" class="external-link" target="_blank">Pydanticのドキュメント</a>で説明されている通りです。
+`exclude_defaults` と `exclude_none` については、<a href="https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict" class="external-link" target="_blank">Pydanticのドキュメント</a>で説明されている通りです。
 
 ///
 
-#### ã\83\87ã\83\95ã\82©ã\83«ã\83\88å\80¤ã\82\92æ\8c\81ã\81¤ã\83\95ã\82£ã\83¼ã\83«ã\83\89ã\81®å\80¤ã\82\92æ\8c\81ã\81¤ã\83\87ã\83¼ã\82¿
+#### ã\83\87ã\83\95ã\82©ã\83«ã\83\88å\80¤ã\82\92æ\8c\81ã\81¤ã\83\95ã\82£ã\83¼ã\83«ã\83\89ã\81«å\80¤ã\81\8cã\81\82ã\82\8bã\83\87ã\83¼ã\82¿ { #data-with-values-for-fields-with-defaults }
 
-しかし、ID`bar`のitemのように、デフォルト値が設定されているモデルのフィールドに値が設定されている場合:
+しかし、ID `bar` のitemのように、デフォルト値が設定されているモデルのフィールドに値が設定されている場合:
 
-```Python hl_lines="3 5"
+```Python hl_lines="3  5"
 {
     "name": "Bar",
     "description": "The bartenders",
@@ -146,11 +276,11 @@ FastAPIはこれをするために、Pydanticモデルの`.dict()`を<a href="ht
 
 それらはレスポンスに含まれます。
 
-#### デフォルト値と同じ値を持つデータ
+#### デフォルト値と同じ値を持つデータ { #data-with-the-same-values-as-the-defaults }
 
-ID`baz`のitemのようにデフォルト値と同じ値を持つデータの場合:
+ID `baz` のitemのようにデフォルト値と同じ値を持つデータの場合:
 
-```Python hl_lines="3 6"
+```Python hl_lines="3  5-6"
 {
     "name": "Baz",
     "description": None,
@@ -160,53 +290,54 @@ ID`baz`のitemのようにデフォルト値と同じ値を持つデータの場
 }
 ```
 
-FastAPIは十分に賢いので(実際には、Pydanticが十分に賢い)`description`や`tax`、`tags`はデフォルト値と同じ値を持っているにもかかわらず、明示的に設定されていることを理解しています。(デフォルトから取得するのではなく)
+FastAPIは十分に賢いので(実際には、Pydanticが十分に賢い)、`description` や `tax`、`tags` がデフォルト値と同じ値であっても、明示的に設定された(デフォルトから取得されたのではない)ことを理解します。
 
\81\9dã\81®ã\81\9fã\82\81ã\80\81ã\81\9dã\82\8cã\82\89ã\81¯JSONã\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\81«å\90«ã\81¾ã\82\8cã\82\8bã\81\93ã\81¨ã\81«ã\81ªã\82\8aã\81¾ã\81\99ã\80\82
+そのため、それらはJSONレスポンスに含まれます。
 
 /// tip | 豆知識
 
-デフォルト値は`None`だけでなく、なんでも良いことに注意してください。
-例えば、リスト(`[]`)や`10.5`の`float`などです。
+デフォルト値は `None` だけではないことに注意してください。
+
+リスト(`[]`)や `10.5` の `float` などでも構いません。
 
 ///
 
-### `response_model_include`と`response_model_exclude`
+### `response_model_include`と`response_model_exclude` { #response-model-include-and-response-model-exclude }
 
-*path operationデコレータ*として`response_model_include`と`response_model_exclude`も使用することができます。
+*path operation デコレータ*のパラメータ `response_model_include` と `response_model_exclude` も使用できます。
 
-属性名を持つ`str`の`set`を受け取り、含める(残りを省略する)か、除外(残りを含む)します。
+これらは、含める(残りを省略する)または除外する(残りを含む)属性名を持つ `str` の `set` を受け取ります。
 
-これは、Pydanticモデルが1つしかなく、出力からいくつかのデータを削除したい場合のクイックショートカットとして使用することができます。
+これは、Pydanticモデルが1つしかなく、出力からいくつかのデータを削除したい場合のクイックショートカットとして使用できます。
 
 /// tip | 豆知識
 
-それでも、これらのパラメータではなく、複数のクラスを使用して、上記のようなアイデアを使うことをおすすめします。
+それでも、これらのパラメータではなく、上で示したアイデアのように複数のクラスを使うことが推奨されます。
 
-これは`response_model_include`や`response_mode_exclude`を使用していくつかの属性を省略しても、アプリケーションのOpenAPI(とドキュメント)で生成されたJSON Schemaが完全なモデルになるからです。
+これは、`response_model_include` や `response_model_exclude` を使っていくつかの属性を省略しても、アプリのOpenAPI(とドキュメント)で生成されるJSON Schemaが完全なモデルのままになるためです。
 
-同様に動作する`response_model_by_alias`にも当てはまります。
+同様に動作する `response_model_by_alias` にも当てはまります。
 
 ///
 
-{* ../../docs_src/response_model/tutorial005.py hl[31,37] *}
+{* ../../docs_src/response_model/tutorial005_py310.py hl[29,35] *}
 
 /// tip | 豆知識
 
-`{"name", "description"}`の構文はこれら2つの値をもつ`set`を作成します。
+`{"name", "description"}` の構文は、それら2つの値を持つ `set` を作成します。
 
-これは`set(["name", "description"])`と同等です。
+これは `set(["name", "description"])` と同等です。
 
 ///
 
-#### `set`の代わりに`list`を使用する
+#### `set`の代わりに`list`を使用する { #using-lists-instead-of-sets }
 
-もし`set`を使用することを忘れて、代わりに`list`や`tuple`を使用しても、FastAPIはそれを`set`に変換して正しく動作します:
+もし `set` を使用することを忘れて、代わりに `list` や `tuple` を使用しても、FastAPIはそれを `set` に変換して正しく動作します:
 
-{* ../../docs_src/response_model/tutorial006.py hl[31,37] *}
+{* ../../docs_src/response_model/tutorial006_py310.py hl[29,35] *}
 
-## まとめ
+## まとめ { #recap }
 
-*path operationデコレータの*`response_model`パラメータを使用して、レスポンスモデルを定義し、特にプライベートデータがフィルタリングされていることを保証します。
+*path operation デコレータ*のパラメータ `response_model` を使用してレスポンスモデルを定義し、とくにプライベートデータがフィルタリングされることを保証します。
 
-明示的に設定された値のみを返すには、`response_model_exclude_unset`を使用します。
+明示的に設定された値のみを返すには、`response_model_exclude_unset` を使用します。
index 6d197d543deb311875b8b84f55900aa3ac6aaefe..d3c2194162b840a08a1bd65323ad0f7e4448caa0 100644 (file)
@@ -1,4 +1,4 @@
-# レスポンスステータスコード
+# レスポンスステータスコード { #response-status-code }
 
 レスポンスモデルを指定するのと同じ方法で、レスポンスに使用されるHTTPステータスコードを以下の*path operations*のいずれかの`status_code`パラメータで宣言することもできます。
 
@@ -6,13 +6,13 @@
 * `@app.post()`
 * `@app.put()`
 * `@app.delete()`
-* など。
+* etc.
 
-{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
 
 /// note | 備考
 
-`status_code`は「デコレータ」メソッド(`get`、`post`など)のパラメータであることに注意してください。すべてのパラメータやボディのように、*path operation関数*のものではありません。
+`status_code`は「デコレータ」メソッド(`get`、`post`など)のパラメータであることに注意してください。すべてのパラメータやボディのように、*path operation function*のものではありません。
 
 ///
 
@@ -29,7 +29,7 @@
 * レスポンスでステータスコードを返します。
 * OpenAPIスキーマ(およびユーザーインターフェース)に以下のように文書化します:
 
-<img src="https://fastapi.tiangolo.com/img/tutorial/response-status-code/image01.png">
+<img src="/img/tutorial/response-status-code/image01.png">
 
 /// note | 備考
 
@@ -39,7 +39,7 @@ FastAPIはこれを知っていて、レスポンスボディがないというO
 
 ///
 
-## HTTPステータスコードについて
+## HTTPステータスコードについて { #about-http-status-codes }
 
 /// note | 備考
 
@@ -47,34 +47,34 @@ FastAPIはこれを知っていて、レスポンスボディがないというO
 
 ///
 
-HTTPでは、レスポンスの一部として桁の数字のステータスコードを送信します。
+HTTPでは、レスポンスの一部として3桁の数字のステータスコードを送信します。
 
 これらのステータスコードは、それらを認識するために関連付けられた名前を持っていますが、重要な部分は番号です。
 
 つまり:
 
-* `100`以上は「情報」のためのものです。。直接使うことはほとんどありません。これらのステータスコードを持つレスポンスはボディを持つことができません。
-* **`200`** 以上は「成功」のレスポンスのためのものです。これらは最も利用するであろうものです。
+* `100 - 199` は「情報」のためのものです。直接使うことはほとんどありません。これらのステータスコードを持つレスポンスはボディを持つことができません。
+* **`200 - 299`** は「成功」のレスポンスのためのものです。これらは最も利用するであろうものです。
     * `200`はデフォルトのステータスコードで、すべてが「OK」であったことを意味します。
     * 別の例としては、`201`(Created)があります。これはデータベースに新しいレコードを作成した後によく使用されます。
-    * ç\89¹æ®\8aã\81ªã\82±ã\83¼ã\82¹ã\81¨ã\81\97ã\81¦ã\80\81`204`ï¼\88No Contentï¼\89ã\81\8cã\81\82ã\82\8aã\81¾ã\81\99ã\80\82ã\81\93ã\81®ã\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\81¯ã\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88ã\81«è¿\94ã\81\99ã\82³ã\83³ã\83\86ã\83³ã\83\84ã\81\8cã\81ªã\81\84å ´å\90\88ã\81«ä½¿ç\94¨ã\81\95ã\82\8cã\81¾ã\81\99ã\80\82ã\81\9dã\81\97ã\81¦ã\81\93ã\81®ã\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\81¯ã\83\9cã\83\87ã\82£ã\82\92æ\8c\81ã\81¤ã\81\93ã\81¨ã\81¯ã\81§ã\81\8dません。
-* **`300`** 以上は「リダイレクト」のためのものです。これらのステータスコードを持つレスポンスは`304`(Not Modified)を除き、ボディを持つことも持たないこともできます
-* **`400`** 以上は「クライアントエラー」のレスポンスのためのものです。これらは、おそらく最も多用するであろう2番目のタイプです。
+    * ç\89¹æ®\8aã\81ªã\82±ã\83¼ã\82¹ã\81¨ã\81\97ã\81¦ã\80\81`204`ï¼\88No Contentï¼\89ã\81\8cã\81\82ã\82\8aã\81¾ã\81\99ã\80\82ã\81\93ã\81®ã\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\81¯ã\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88ã\81«è¿\94ã\81\99ã\82³ã\83³ã\83\86ã\83³ã\83\84ã\81\8cã\81ªã\81\84å ´å\90\88ã\81«ä½¿ç\94¨ã\81\95ã\82\8cã\82\8bã\81\9fã\82\81ã\80\81ã\83¬ã\82¹ã\83\9dã\83³ã\82¹ã\81¯ã\83\9cã\83\87ã\82£ã\82\92æ\8c\81ã\81£ã\81¦ã\81¯ã\81\84ã\81\91ません。
+* **`300 - 399`** は「リダイレクト」のためのものです。これらのステータスコードを持つレスポンスは`304`(Not Modified)を除き、ボディを持つことも持たないこともできます。`304`はボディを持ってはいけません
+* **`400 - 499`** は「クライアントエラー」のレスポンスのためのものです。これらは、おそらく最も多用するであろう2番目のタイプです。
     * 例えば、`404`は「Not Found」レスポンスです。
     * クライアントからの一般的なエラーについては、`400`を使用することができます。
-* `500`以上はサーバーエラーのためのものです。これらを直接使うことはほとんどありません。アプリケーションコードやサーバーのどこかで何か問題が発生した場合、これらのステータスコードのいずれかが自動的に返されます。
+* `500 - 599` はサーバーエラーのためのものです。これらを直接使うことはほとんどありません。アプリケーションコードやサーバーのどこかで何か問題が発生した場合、これらのステータスコードのいずれかが自動的に返されます。
 
 /// tip | 豆知識
 
-それぞれのステータスコードとどのコードが何のためのコードなのかについて詳細は<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr> HTTP レスポンスステータスコードについてのドキュメント</a>を参照してください。
+それぞれのステータスコードとどのコードが何のためのコードなのかについて詳細は<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr> documentation about HTTP status codes</a>を参照してください。
 
 ///
 
-## 名前を覚えるための近道
+## 名前を覚えるための近道 { #shortcut-to-remember-the-names }
 
 先ほどの例をもう一度見てみましょう:
 
-{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
 
 `201`は「作成完了」のためのステータスコードです。
 
@@ -82,11 +82,11 @@ HTTPでは、レスポンスの一部として3桁の数字のステータス
 
 `fastapi.status`の便利な変数を利用することができます。
 
-{* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *}
+{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *}
 
-それらは便利です。それらは同じ番号を保持しており、その方法ではエディタの自動補完を使用してそれらを見つけることができます。
+それらは単なる便利なものであり、同じ番号を保持しています。しかし、その方法ではエディタの自動補完を使用してそれらを見つけることができます。
 
-<img src="https://fastapi.tiangolo.com/img/tutorial/response-status-code/image02.png">
+<img src="/img/tutorial/response-status-code/image02.png">
 
 /// note | 技術詳細
 
@@ -96,6 +96,6 @@ HTTPでは、レスポンスの一部として3桁の数字のステータス
 
 ///
 
-## デフォルトの変更
+## デフォルトの変更 { #changing-the-default }
 
 後に、[高度なユーザーガイド](../advanced/response-change-status-code.md){.internal-link target=_blank}で、ここで宣言しているデフォルトとは異なるステータスコードを返す方法を見ていきます。
index 1834e67b27c280c3eb496c5cec567aaae5ca0b78..e526685c2f3e7b1f91d2021759ae52435cd710ac 100644 (file)
-# ã\82¹ã\82­ã\83¼ã\83\9eã\81®è¿½å\8a  - ä¾\8b
+# ã\83ªã\82¯ã\82¨ã\82¹ã\83\88ã\81®Exampleã\83\87ã\83¼ã\82¿ã\81®å®£è¨\80 { #declare-request-example-data }
 
-JSON Schemaに追加する情報を定義することができます。
+アプリが受け取れるデータの例を宣言できます。
 
-一般的なユースケースはこのドキュメントで示されているように`example`を追加することです。
+ここでは、それを行ういくつかの方法を紹介します。
 
-JSON Schemaの追加情報を宣言する方法はいくつかあります。
+## Pydanticモデルでの追加JSON Schemaデータ { #extra-json-schema-data-in-pydantic-models }
 
-## Pydanticの`schema_extra`
+生成されるJSON Schemaに追加されるPydanticモデルの`examples`を宣言できます。
 
-<a href="https://docs.pydantic.dev/latest/concepts/json_schema/#schema-customization" class="external-link" target="_blank">Pydanticのドキュメント: スキーマのカスタマイズ</a>で説明されているように、`Config`と`schema_extra`を使ってPydanticモデルの例を宣言することができます:
+{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *}
 
-{* ../../docs_src/schema_extra_example/tutorial001.py hl[15,16,17,18,19,20,21,22,23] *}
+その追加情報は、そのモデルの出力**JSON Schema**にそのまま追加され、APIドキュメントで使用されます。
 
-その追加情報はそのまま出力され、JSON Schemaに追加されます。
+<a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">Pydanticのドキュメント: Configuration</a>で説明されているように、`dict`を受け取る属性`model_config`を使用できます。
 
-## `Field`の追加引数
+生成されるJSON Schemaに表示したい追加データ(`examples`を含む)を含む`dict`を使って、`"json_schema_extra"`を設定できます。
 
-後述する`Field`、`Path`、`Query`、`Body`などでは、任意の引数を関数に渡すことでJSON Schemaの追加情報を宣言することもできます:
+/// tip | 豆知識
 
-{* ../../docs_src/schema_extra_example/tutorial002.py hl[4,10,11,12,13] *}
+同じ手法を使ってJSON Schemaを拡張し、独自のカスタム追加情報を追加できます。
 
-/// warning | 注意
+例えば、フロントエンドのユーザーインターフェースのためのメタデータを追加する、などに使えます。
+
+///
+
+/// info | 情報
+
+OpenAPI 3.1.0(FastAPI 0.99.0以降で使用)では、**JSON Schema**標準の一部である`examples`がサポートされました。
 
-これらの追加引数が渡されても、文書化のためのバリデーションは追加されず、注釈だけが追加されることを覚えておいてください。
+それ以前は、単一の例を持つキーワード`example`のみがサポートされていました。これはOpenAPI 3.1.0でも引き続きサポートされていますが、非推奨であり、JSON Schema標準の一部ではありません。そのため、`example`から`examples`への移行が推奨されます。🤓
+
+詳細はこのページの最後で読めます。
 
 ///
 
-## `Body`の追加引数
+## `Field`の追加引数 { #field-additional-arguments }
+
+Pydanticモデルで`Field()`を使う場合、追加の`examples`も宣言できます:
+
+{* ../../docs_src/schema_extra_example/tutorial002_py310.py hl[2,8:11] *}
+
+## JSON Schema内の`examples` - OpenAPI { #examples-in-json-schema-openapi }
 
-追加情報を`Field`に渡すのと同じように、`Path`、`Query`、`Body`などでも同じことができます。
+以下のいずれかを使用する場合:
 
-例えば、`Body`にボディリクエストの`example`を渡すことができます:
+* `Path()`
+* `Query()`
+* `Header()`
+* `Cookie()`
+* `Body()`
+* `Form()`
+* `File()`
 
-{* ../../docs_src/schema_extra_example/tutorial003.py hl[21,22,23,24,25,26] *}
+追加情報を含む`examples`のグループを宣言でき、それらは**OpenAPI**内のそれぞれの**JSON Schemas**に追加されます。
 
-## ドキュメントのUIの例
+### `examples`を使う`Body` { #body-with-examples }
+
+ここでは、`Body()`で期待されるデータの例を1つ含む`examples`を渡します:
+
+{* ../../docs_src/schema_extra_example/tutorial003_an_py310.py hl[22:29] *}
+
+### ドキュメントUIでの例 { #example-in-the-docs-ui }
 
 上記のいずれの方法でも、`/docs`の中では以下のようになります:
 
-<img src="https://fastapi.tiangolo.com/img/tutorial/body-fields/image01.png">
+<img src="/img/tutorial/body-fields/image01.png">
+
+### 複数の`examples`を使う`Body` { #body-with-multiple-examples }
+
+もちろん、複数の`examples`を渡すこともできます:
+
+{* ../../docs_src/schema_extra_example/tutorial004_an_py310.py hl[23:38] *}
+
+この場合、examplesはそのボディデータの内部**JSON Schema**の一部になります。
+
+それでも、<abbr title="2023-08-26">執筆時点</abbr>では、ドキュメントUIの表示を担当するツールであるSwagger UIは、**JSON Schema**内のデータに対して複数の例を表示することをサポートしていません。しかし、回避策については以下を読んでください。
+
+### OpenAPI固有の`examples` { #openapi-specific-examples }
+
+**JSON Schema**が`examples`をサポートする前から、OpenAPIは同じく`examples`という別のフィールドをサポートしていました。
+
+この**OpenAPI固有**の`examples`は、OpenAPI仕様の別のセクションに入ります。各JSON Schemaの中ではなく、**各*path operation*の詳細**に入ります。
+
+そしてSwagger UIは、この特定の`examples`フィールドを以前からサポートしています。そのため、これを使って**ドキュメントUIに異なる例を表示**できます。
+
+このOpenAPI固有フィールド`examples`の形は**複数の例**(`list`ではなく)を持つ`dict`であり、それぞれに追加情報が含まれ、その追加情報は**OpenAPI**にも追加されます。
+
+これはOpenAPIに含まれる各JSON Schemaの中には入らず、外側の、*path operation*に直接入ります。
+
+### `openapi_examples`パラメータの使用 { #using-the-openapi-examples-parameter }
+
+FastAPIでは、以下に対してパラメータ`openapi_examples`を使って、OpenAPI固有の`examples`を宣言できます:
+
+* `Path()`
+* `Query()`
+* `Header()`
+* `Cookie()`
+* `Body()`
+* `Form()`
+* `File()`
+
+`dict`のキーは各例を識別し、各値は別の`dict`です。
+
+`examples`内の各特定の例`dict`には、次の内容を含められます:
+
+* `summary`: 例の短い説明。
+* `description`: Markdownテキストを含められる長い説明。
+* `value`: 実際に表示される例(例: `dict`)。
+* `externalValue`: `value`の代替で、例を指すURLです。ただし、`value`ほど多くのツールでサポートされていない可能性があります。
+
+次のように使えます:
+
+{* ../../docs_src/schema_extra_example/tutorial005_an_py310.py hl[23:49] *}
+
+### ドキュメントUIのOpenAPI Examples { #openapi-examples-in-the-docs-ui }
+
+`Body()`に`openapi_examples`を追加すると、`/docs`は次のようになります:
+
+<img src="/img/tutorial/body-fields/image02.png">
+
+## 技術詳細 { #technical-details }
+
+/// tip | 豆知識
+
+すでに**FastAPI**バージョン**0.99.0以上**を使用している場合、おそらくこれらの詳細は**スキップ**できます。
+
+これらは、OpenAPI 3.1.0が利用可能になる前の古いバージョンにより関連します。
+
+これは簡単なOpenAPIとJSON Schemaの**歴史の授業**だと考えられます。🤓
+
+///
+
+/// warning | 注意
+
+ここでは、標準である**JSON Schema**と**OpenAPI**についての非常に技術的な詳細を扱います。
+
+上のアイデアがすでにうまく動いているなら、それで十分かもしれませんし、おそらくこの詳細は不要です。気軽にスキップしてください。
+
+///
+
+OpenAPI 3.1.0より前は、OpenAPIは古く改変されたバージョンの**JSON Schema**を使用していました。
+
+JSON Schemaには`examples`がなかったため、OpenAPIは自身が改変したバージョンに独自の`example`フィールドを追加しました。
+
+OpenAPIは、仕様の他の部分にも`example`と`examples`フィールドを追加しました:
+
+* <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object" class="external-link" target="_blank">`Parameter Object`(仕様内)</a>。FastAPIの以下で使用されました:
+    * `Path()`
+    * `Query()`
+    * `Header()`
+    * `Cookie()`
+* <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object" class="external-link" target="_blank">`Request Body Object`。仕様内の`Media Type Object`の`content`フィールド(仕様内)</a>。FastAPIの以下で使用されました:
+    * `Body()`
+    * `File()`
+    * `Form()`
+
+/// info | 情報
+
+この古いOpenAPI固有の`examples`パラメータは、FastAPI `0.103.0`以降は`openapi_examples`になりました。
+
+///
+
+### JSON Schemaの`examples`フィールド { #json-schemas-examples-field }
+
+しかしその後、JSON Schemaは新しいバージョンの仕様に<a href="https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5" class="external-link" target="_blank">`examples`</a>フィールドを追加しました。
+
+そして、新しいOpenAPI 3.1.0は、この新しいフィールド`examples`を含む最新バージョン(JSON Schema 2020-12)に基づくようになりました。
+
+そして現在、この新しい`examples`フィールドは、古い単一(かつカスタム)の`example`フィールドより優先され、`example`は現在非推奨です。
+
+JSON Schemaのこの新しい`examples`フィールドは、OpenAPIの他の場所(上で説明)にあるような追加メタデータを持つdictではなく、**単なる例の`list`**です。
+
+/// info | 情報
+
+OpenAPI 3.1.0がこのJSON Schemaとの新しいよりシンプルな統合とともにリリースされた後も、しばらくの間、自動ドキュメントを提供するツールであるSwagger UIはOpenAPI 3.1.0をサポートしていませんでした(バージョン5.0.0からサポートされています🎉)。
+
+そのため、FastAPI 0.99.0より前のバージョンは、OpenAPI 3.1.0より低いバージョンのOpenAPIをまだ使用していました。
+
+///
+
+### PydanticとFastAPIの`examples` { #pydantic-and-fastapi-examples }
+
+Pydanticモデル内で、`schema_extra`または`Field(examples=["something"])`を使って`examples`を追加すると、その例はそのPydanticモデルの**JSON Schema**に追加されます。
+
+そしてそのPydanticモデルの**JSON Schema**はAPIの**OpenAPI**に含まれ、ドキュメントUIで使用されます。
+
+FastAPI 0.99.0より前のバージョン(0.99.0以上は新しいOpenAPI 3.1.0を使用)では、他のユーティリティ(`Query()`、`Body()`など)で`example`または`examples`を使っても、それらの例はそのデータを説明するJSON Schema(OpenAPI独自版のJSON Schemaでさえ)には追加されず、OpenAPI内の*path operation*宣言に直接追加されていました(JSON Schemaを使用するOpenAPIの部分の外側)。
 
-## 技術詳細
+しかし、FastAPI 0.99.0以上ではOpenAPI 3.1.0を使用し、それはJSON Schema 2020-12とSwagger UI 5.0.0以上を使うため、すべてがより一貫し、例はJSON Schemaに含まれます。
 
-`example` と `examples`について...
+### Swagger UIとOpenAPI固有の`examples` { #swagger-ui-and-openapi-specific-examples }
 
-JSON Schemaの最新バージョンでは<a href="https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5" class="external-link" target="_blank">`examples`</a>というフィールドを定義していますが、OpenAPIは`examples`を持たない古いバージョンのJSON Schemaをベースにしています
+Swagger UIは複数のJSON Schema examplesをサポートしていなかった(2023-08-26時点)ため、ユーザーはドキュメントで複数の例を表示する手段がありませんでした
 
\81\9dã\81®ã\81\9fã\82\81ã\80\81OpenAPIã\81§ã\81¯å\90\8cã\81\98ç\9b®ç\9a\84ã\81®ã\81\9fã\82\81ã\81«<a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#fixed-fields-20" class="external-link" target="_blank">`example`</a>ã\82\92ç\8b¬è\87ªã\81«å®\9a義ã\81\97ã\81¦ã\81\8aã\82\8aï¼\88`examples`ã\81§ã\81¯ã\81ªã\81\8f`example`ã\81¨ã\81\97ã\81¦ï¼\89ã\80\81ã\81\9dã\82\8cã\81\8cdocs UIï¼\88Swagger UIã\82\92使ç\94¨ï¼\89ã\81§ä½¿ç\94¨ã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99ã\80\82
\81\9dã\82\8cã\82\92解決ã\81\99ã\82\8bã\81\9fã\82\81ã\80\81FastAPI `0.103.0`ã\81¯ã\80\81æ\96°ã\81\97ã\81\84ã\83\91ã\83©ã\83¡ã\83¼ã\82¿`openapi_examples`ã\81§ã\80\81å\90\8cã\81\98å\8f¤ã\81\84**OpenAPIå\9bºæ\9c\89**ã\81®`examples`ã\83\95ã\82£ã\83¼ã\83«ã\83\89ã\82\92宣è¨\80ã\81\99ã\82\8bã\81\9fã\82\81ã\81®**ã\82µã\83\9dã\83¼ã\83\88ã\82\92追å\8a **ã\81\97ã\81¾ã\81\97ã\81\9fã\80\82ð\9f¤\93
 
-つまり、`example`はJSON Schemaの一部ではありませんが、OpenAPIの一部であり、それがdocs UIで使用されることになります。
+### まとめ { #summary }
 
-## その他の情報
+昔は歴史があまり好きではないと言っていました...が、今の私は「技術の歴史」の授業をしています。😅
 
-同じように、フロントエンドのユーザーインターフェースなどをカスタマイズするために、各モデルのJSON Schemaに追加される独自の追加情報を追加することができます。
+要するに、**FastAPI 0.99.0以上にアップグレード**してください。そうすれば、物事はもっと**シンプルで一貫性があり直感的**になり、これらの歴史的詳細を知る必要もありません。😎
index 0ce0f929bee62e803de77d1e5d03e543fcad0264..76ef04db8d6781f873d5482e21d3a8b69ac07d18 100644 (file)
@@ -1,4 +1,4 @@
-# セキュリティ - 最初の一歩
+# セキュリティ - 最初の一歩 { #security-first-steps }
 
 あるドメインに、**バックエンド** APIを持っているとしましょう。
 
 
 **FastAPI**が提供するツールを使って、セキュリティを制御してみましょう。
 
-## どう見えるか
+## どう見えるか { #how-it-looks }
 
 まずはこのコードを使って、どう動くか観察します。その後で、何が起こっているのか理解しましょう。
 
-## `main.py`を作成
+## `main.py`を作成 { #create-main-py }
 
 `main.py`に、下記の例をコピーします:
 
-{* ../../docs_src/security/tutorial001.py *}
+{* ../../docs_src/security/tutorial001_an_py39.py *}
 
-## 実行
+## 実行 { #run-it }
 
 /// info | 情報
 
-まず<a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>をインストールします。
+<a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a> パッケージは、`pip install "fastapi[standard]"` コマンドを実行すると **FastAPI** と一緒に自動的にインストールされます。
 
-例えば、`pip install python-multipart`
+しかし、`pip install fastapi` コマンドを使用する場合、`python-multipart` パッケージはデフォルトでは含まれません
 
-これは、**OAuth2**が `ユーザー名` や `パスワード` を送信するために、「フォームデータ」を使うからです。
+手動でインストールするには、[仮想環境](../../virtual-environments.md){.internal-link target=_blank}を作成して有効化し、次のコマンドでインストールしてください:
+
+```console
+$ pip install python-multipart
+```
+
+これは、**OAuth2**が `username` と `password` を送信するために、「フォームデータ」を使うからです。
 
 ///
 
 <div class="termy">
 
 ```console
-$ uvicorn main:app --reload
+$ fastapi dev main.py
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
 
 </div>
 
-## 確認
+## 確認 { #check-it }
 
 次のインタラクティブなドキュメントにアクセスしてください: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>。
 
@@ -62,7 +68,7 @@ $ uvicorn main:app --reload
 
 ///
 
-それをクリックすると、`ユーザー名`と`パスワード` (およびその他のオプションフィールド) を入力する小さな認証フォームが表示されます:
+それをクリックすると、`username` と `password`(およびその他のオプションフィールド)を入力する小さな認可フォームが表示されます:
 
 <img src="/img/tutorial/security/image02.png">
 
@@ -80,11 +86,11 @@ $ uvicorn main:app --reload
 
 また、同じアプリケーションのデバッグ、チェック、テストのためにも利用できます。
 
-## `パスワード` フロー
+## `password` フロー { #the-password-flow }
 
 では、少し話を戻して、どうなっているか理解しましょう。
 
-`パスワード`の「フロー」は、OAuth2で定義されているセキュリティと認証を扱う方法 (「フロー」) の1つです。
+`password`の「フロー」は、OAuth2で定義されているセキュリティと認証を扱う方法 (「フロー」) の1つです。
 
 OAuth2は、バックエンドやAPIがユーザーを認証するサーバーから独立したものとして設計されていました。
 
@@ -92,9 +98,9 @@ OAuth2は、バックエンドやAPIがユーザーを認証するサーバー
 
 そこで、簡略化した箇所から見直してみましょう:
 
-* ユーザーはフロントエンドで`ユーザー名`と`パスワード`を入力し、`Enter`を押します。
-* フロントエンド (ユーザーのブラウザで実行中) は、`ユーザー名`と`パスワード`をAPIの特定のURL (`tokenUrl="token"`で宣言された) に送信します。
-* APIは`ユーザー名`と`パスワード`をチェックし、「トークン」を返却します (まだ実装していません)。
+* ユーザーはフロントエンドで`username`と`password`を入力し、`Enter`を押します。
+* フロントエンド (ユーザーのブラウザで実行中) は、`username`と`password`をAPIの特定のURL (`tokenUrl="token"`で宣言された) に送信します。
+* APIは`username`と`password`をチェックし、「トークン」を返却します (まだ実装していません)。
     * 「トークン」はただの文字列であり、あとでこのユーザーを検証するために使用します。
     * 通常、トークンは時間が経つと期限切れになるように設定されています。
         * トークンが期限切れの場合は、再度ログインする必要があります。
@@ -106,11 +112,11 @@ OAuth2は、バックエンドやAPIがユーザーを認証するサーバー
     * したがって、APIで認証するため、HTTPヘッダー`Authorization`に`Bearer`の文字列とトークンを加えた値を送信します。
     * トークンに`foobar`が含まれている場合、`Authorization`ヘッダーの内容は次のようになります: `Bearer foobar`。
 
-## **FastAPI**の`OAuth2PasswordBearer`
+## **FastAPI**の`OAuth2PasswordBearer` { #fastapis-oauth2passwordbearer }
 
 **FastAPI**は、これらのセキュリティ機能を実装するために、抽象度の異なる複数のツールを提供しています。
 
-この例では、**Bearer**トークンを使用して**OAuth2**を**パスワード**フローで使用します。これには`OAuth2PasswordBearer`クラスを使用します。
+この例では、**Bearer**トークンを使用して**OAuth2**を**Password**フローで使用します。これには`OAuth2PasswordBearer`クラスを使用します。
 
 /// info | 情報
 
@@ -124,9 +130,9 @@ OAuth2は、バックエンドやAPIがユーザーを認証するサーバー
 
 ///
 
-`OAuth2PasswordBearer` クラスのインスタンスを作成する時に、パラメーター`tokenUrl`を渡します。このパラメーターには、クライアント (ユーザーのブラウザで動作するフロントエンド) がトークンを取得するために`ユーザー名`と`パスワード`を送信するURLを指定します。
+`OAuth2PasswordBearer` クラスのインスタンスを作成する時に、パラメーター`tokenUrl`を渡します。このパラメーターには、クライアント (ユーザーのブラウザで動作するフロントエンド) がトークンを取得するために`username`と`password`を送信するURLを指定します。
 
-{* ../../docs_src/security/tutorial001.py hl[6] *}
+{* ../../docs_src/security/tutorial001_an_py39.py hl[8] *}
 
 /// tip | 豆知識
 
@@ -134,13 +140,13 @@ OAuth2は、バックエンドやAPIがユーザーを認証するサーバー
 
 相対URLを使っているので、APIが`https://example.com/`にある場合、`https://example.com/token`を参照します。しかし、APIが`https://example.com/api/v1/`にある場合は`https://example.com/api/v1/token`を参照することになります。
 
\9b¸å¯¾ URL ã\82\92使ã\81\86ã\81\93ã\81¨ã\81¯ã\80\81\83\97ã\83­ã\82­ã\82·ã\81¨æ\8e¥ç¶\9a](../../advanced/behind-a-proxy.md){.internal-link target=_blank}のような高度なユースケースでもアプリケーションを動作させ続けるために重要です。
\9b¸å¯¾ URL ã\82\92使ã\81\86ã\81\93ã\81¨ã\81¯ã\80\81\83\97ã\83­ã\82­ã\82·ã\81®è\83\8cå¾\8c](../../advanced/behind-a-proxy.md){.internal-link target=_blank}のような高度なユースケースでもアプリケーションを動作させ続けるために重要です。
 
 ///
 
 このパラメーターはエンドポイント/ *path operation*を作成しません。しかし、URL`/token`はクライアントがトークンを取得するために使用するものであると宣言します。この情報は OpenAPI やインタラクティブな API ドキュメントシステムで使われます。
 
-実際のpath operationもすぐに作ります。
+実際の path operation もすぐに作ります。
 
 /// info | 情報
 
@@ -160,13 +166,13 @@ oauth2_scheme(some, parameters)
 
 そのため、`Depends`と一緒に使うことができます。
 
-### 使い方
+### 使い方 { #use-it }
 
 これで`oauth2_scheme`を`Depends`で依存関係に渡すことができます。
 
-{* ../../docs_src/security/tutorial001.py hl[10] *}
+{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
 
-この依存関係は、*path operation function*のパラメーター`token`に代入される`str`を提供します。
+この依存関係は、*path operation 関数*のパラメーター`token`に代入される`str`を提供します。
 
 **FastAPI**は、この依存関係を使用してOpenAPIスキーマ (および自動APIドキュメント) で「セキュリティスキーム」を定義できることを知っています。
 
@@ -178,13 +184,13 @@ OpenAPIと統合するセキュリティユーティリティ (および自動AP
 
 ///
 
-## どのように動作するか
+## 何をするか { #what-it-does }
 
-リクエストの中に`Authorization`ヘッダーを探しに行き、その値が`Bearer`と何らかのトークンを含んでいるかどうかをチェックし、そのトークンを`str`として返します。
+リクエストの中に`Authorization`ヘッダーを探しに行き、その値が`Bearer `と何らかのトークンを含んでいるかどうかをチェックし、そのトークンを`str`として返します。
 
-もし`Authorization`ヘッダーが見つからなかったり、値が`Bearer`トークンを持っていなかったりすると、401 ステータスコードエラー (`UNAUTHORIZED`) で直接応答します。
+もし`Authorization`ヘッダーが見つからなかったり、値が`Bearer `トークンを持っていなかったりすると、401 ステータスコードエラー (`UNAUTHORIZED`) で直接応答します。
 
\83\88ã\83¼ã\82¯ã\83³ã\81\8cå­\98å\9c¨ã\81\99ã\82\8bã\81\8bã\81©ã\81\86ã\81\8bã\82\92ã\83\81ã\82§ã\83\83ã\82¯ã\81\97ã\81¦ã\82¨ã\83©ã\83¼ã\82\92è¿\94ã\81\99å¿\85è¦\81ã\81¯ã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\80\82é\96¢æ\95°ã\81\8cå®\9fè¡\8cã\81\95ã\82\8cã\81\9få ´å\90\88ã\80\81ã\81\9dã\81®ã\83\88ã\83¼ã\82¯ã\83³ã\81«`str`ã\81\8cå\90«ã\81¾ã\82\8cã\81¦ã\81\84ã\82\8bã\81\8b確èª\8dできます。
\83\88ã\83¼ã\82¯ã\83³ã\81\8cå­\98å\9c¨ã\81\99ã\82\8bã\81\8bã\81©ã\81\86ã\81\8bã\82\92ã\83\81ã\82§ã\83\83ã\82¯ã\81\97ã\81¦ã\82¨ã\83©ã\83¼ã\82\92è¿\94ã\81\99å¿\85è¦\81ã\81¯ã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\80\82é\96¢æ\95°ã\81\8cå®\9fè¡\8cã\81\95ã\82\8cã\81\9få ´å\90\88ã\80\81ã\81\9dã\81®ã\83\88ã\83¼ã\82¯ã\83³ã\81«`str`ã\81\8cå\90«ã\81¾ã\82\8cã\81¦ã\81\84ã\82\8bã\81\93ã\81¨ã\82\92確信できます。
 
 インタラクティブなドキュメントですでに試すことができます:
 
@@ -192,6 +198,6 @@ OpenAPIと統合するセキュリティユーティリティ (および自動AP
 
 まだトークンの有効性を検証しているわけではありませんが、これはもう始まっています。
 
-## まとめ
+## まとめ { #recap }
 
 つまり、たった3~4行の追加で、すでに何らかの基礎的なセキュリティの形になっています。
index 9fc46c07c57ad947bf69874f08fdbcdb716ad0c1..39b97cca52400fefa231749fd5157b853910824e 100644 (file)
@@ -1,22 +1,22 @@
-# 現在のユーザーの取得
+# 現在のユーザーの取得 { #get-current-user }
 
-一つ前の章では、(依存性注入システムに基づいた)セキュリティシステムは、 *path operation関数* に `str` として `token` を与えていました:
+一つ前の章では、(依存性注入システムに基づいた)セキュリティシステムは、 *path operation 関数* に `str` として `token` を与えていました:
 
-{* ../../docs_src/security/tutorial001.py hl[10] *}
+{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
 
 しかし、それはまだそんなに有用ではありません。
 
 現在のユーザーを取得するようにしてみましょう。
 
-## ユーザーモデルの作成
+## ユーザーモデルの作成 { #create-a-user-model }
 
 まずは、Pydanticのユーザーモデルを作成しましょう。
 
 ボディを宣言するのにPydanticを使用するのと同じやり方で、Pydanticを別のどんなところでも使うことができます:
 
-{* ../../docs_src/security/tutorial002.py hl[5,12:16] *}
+{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:6] *}
 
-## 依存関係 `get_current_user` を作成
+## 依存関係 `get_current_user` を作成 { #create-a-get-current-user-dependency }
 
 依存関係 `get_current_user` を作ってみましょう。
 
 
 `get_current_user` は前に作成した `oauth2_scheme` と同じ依存関係を持ちます。
 
-以前直接 *path operation* の中でしていたのと同じように、新しい依存関係である `get_current_user` は `str` として `token` を受け取るようになります:
+以前直接 *path operation* の中でしていたのと同じように、新しい依存関係である `get_current_user` はサブ依存関係である `oauth2_scheme` から `str` として `token` を受け取るようになります:
 
-{* ../../docs_src/security/tutorial002.py hl[25] *}
+{* ../../docs_src/security/tutorial002_an_py310.py hl[25] *}
 
-## ユーザーの取得
+## ユーザーの取得 { #get-the-user }
 
 `get_current_user` は作成した(偽物の)ユーティリティ関数を使って、 `str` としてトークンを受け取り、先ほどのPydanticの `User` モデルを返却します:
 
-{* ../../docs_src/security/tutorial002.py hl[19:22,26:27] *}
+{* ../../docs_src/security/tutorial002_an_py310.py hl[19:22,26:27] *}
 
-## 現在のユーザーの注入
+## 現在のユーザーの注入 { #inject-the-current-user }
 
 ですので、 `get_current_user` に対して同様に *path operation* の中で `Depends` を利用できます。
 
-{* ../../docs_src/security/tutorial002.py hl[31] *}
+{* ../../docs_src/security/tutorial002_an_py310.py hl[31] *}
 
 Pydanticモデルの `User` として、 `current_user` の型を宣言することに注意してください。
 
@@ -54,15 +54,15 @@ Pydanticモデルの `User` として、 `current_user` の型を宣言するこ
 
 /// check | 確認
 
-依存関係システムがこのように設計されているおかげで、 `User` モデルを返却する別の依存関係(別の"dependables")を持つことができます。
+依存関係システムがこのように設計されているおかげで、 `User` モデルを返却する別の依存関係(別の「dependables」)を持つことができます。
 
 同じデータ型を返却する依存関係は一つだけしか持てない、という制約が入ることはないのです。
 
 ///
 
-## 別のモデル
+## 別のモデル { #other-models }
 
-これで、*path operation関数* の中で現在のユーザーを直接取得し、`Depends` を使って、 **依存性注入** レベルでセキュリティメカニズムを処理できるようになりました。
+これで、*path operation 関数* の中で現在のユーザーを直接取得し、`Depends` を使って、 **依存性注入** レベルでセキュリティメカニズムを処理できるようになりました。
 
 そして、セキュリティ要件のためにどんなモデルやデータでも利用することができます。(この場合は、 Pydanticモデルの `User`)
 
@@ -76,10 +76,9 @@ Pydanticモデルの `User` として、 `current_user` の型を宣言するこ
 
 あなたのアプリケーションに必要なのがどんな種類のモデル、どんな種類のクラス、どんな種類のデータベースであったとしても、 **FastAPI** は依存性注入システムでカバーしてくれます。
 
+## コードサイズ { #code-size }
 
-## コードサイズ
-
-この例は冗長に見えるかもしれません。セキュリティとデータモデルユーティリティ関数および *path operations* が同じファイルに混在しているということを覚えておいてください。
+この例は冗長に見えるかもしれません。セキュリティとデータモデルユーティリティ関数および *path operation* が同じファイルに混在しているということを覚えておいてください。
 
 しかし、ここに重要なポイントがあります。
 
@@ -87,20 +86,20 @@ Pydanticモデルの `User` として、 `current_user` の型を宣言するこ
 
 そして、それは好きなだけ複雑にすることができます。それでも、一箇所に、一度だけ書くのです。すべての柔軟性を備えます。
 
-しかし、同じセキュリティシステムを使って何千ものエンドポイント(*path operations*)を持つことができます。
+しかし、同じセキュリティシステムを使って何千ものエンドポイント(*path operation*)を持つことができます。
 
 そして、それらエンドポイントのすべて(必要な、どの部分でも)がこうした依存関係や、あなたが作成する別の依存関係を再利用する利点を享受できるのです。
 
-さらに、こうした何千もの *path operations* は、たった3行で表現できるのです:
+さらに、こうした何千もの *path operation* は、たった3行で表現できるのです:
 
-{* ../../docs_src/security/tutorial002.py hl[30:32] *}
+{* ../../docs_src/security/tutorial002_an_py310.py hl[30:32] *}
 
-## まとめ
+## まとめ { #recap }
 
-これで、 *path operation関数* の中で直接現在のユーザーを取得できるようになりました。
+これで、 *path operation 関数* の中で直接現在のユーザーを取得できるようになりました。
 
 既に半分のところまで来ています。
 
-あとは、 `username` と `password` を実際にそのユーザーやクライアントに送る、 *path operation* を追加する必要があるだけです。
+あとは、ユーザー/クライアントが実際に `username` と `password` を送信するための *path operation* を追加する必要があるだけです。
 
 次はそれを説明します。
index 599fc7b069d13c582a9094bb4dfa9c702f8158ab..186936f1ba3e7f55dcfed1c04176ed4ca6f577b9 100644 (file)
@@ -1,4 +1,4 @@
-# パスワード(およびハッシュ化)によるOAuth2、JWTトークンによるBearer
+# パスワード(およびハッシュ化)によるOAuth2、JWTトークンによるBearer { #oauth2-with-password-and-hashing-bearer-with-jwt-tokens }
 
 これでセキュリティの流れが全てわかったので、<abbr title="JSON Web Tokens">JWT</abbr>トークンと安全なパスワードのハッシュ化を使用して、実際にアプリケーションを安全にしてみましょう。
 
@@ -6,7 +6,7 @@
 
 本章では、前章の続きから始めて、コードをアップデートしていきます。
 
-## JWT について
+## JWT について { #about-jwt }
 
 JWTとは「JSON Web Tokens」の略称です。
 
@@ -26,33 +26,31 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4
 
 JWT トークンを使って遊んでみたいという方は、<a href="https://jwt.io/" class="external-link" target="_blank">https://jwt.io</a> をチェックしてください。
 
-## `python-jose` のインストール
+## `PyJWT` のインストール { #install-pyjwt }
 
-PythonでJWTトークンの生成と検証を行うために、`python-jose`をインストールする必要があります:
+PythonでJWTトークンの生成と検証を行うために、`PyJWT`をインストールする必要があります。
+
+[仮想環境](../../virtual-environments.md){.internal-link target=_blank}を作成し、アクティベートしてから、`pyjwt`をインストールしてください。
 
 <div class="termy">
 
 ```console
-$ pip install python-jose[cryptography]
+$ pip install pyjwt
 
 ---> 100%
 ```
 
 </div>
 
-また、<a href="https://github.com/mpdavis/python-jose" class="external-link" target="_blank">Python-jose</a>だけではなく、暗号を扱うためのパッケージを追加で必要とします。
-
-ここでは、推奨されているものを使用します:<a href="https://cryptography.io/" class="external-link" target="_blank">pyca/cryptography</a>。
-
-/// tip | 豆知識
+/// info | 情報
 
-このチュートリアルでは以前、<a href="https://pyjwt.readthedocs.io/" class="external-link" target="_blank">PyJWT</a>を使用していました
+RSAやECDSAのようなデジタル署名アルゴリズムを使用する予定がある場合は、cryptographyライブラリの依存関係`pyjwt[crypto]`をインストールしてください
 
-しかし、Python-joseは、PyJWTのすべての機能に加えて、後に他のツールと統合して構築する際におそらく必要となる可能性のあるいくつかの追加機能を提供しています。そのため、代わりにPython-joseを使用するように更新されました
+詳細は<a href="https://pyjwt.readthedocs.io/en/latest/installation.html" class="external-link" target="_blank">PyJWT Installation docs</a>で確認できます
 
 ///
 
-## パスワードのハッシュ化
+## パスワードのハッシュ化 { #password-hashing }
 
 「ハッシュ化」とは、あるコンテンツ(ここではパスワード)を、規則性のないバイト列(単なる文字列)に変換することです。
 
@@ -60,26 +58,26 @@ $ pip install python-jose[cryptography]
 
 しかし、規則性のないバイト列から元のパスワードに戻すことはできません。
 
-### パスワードのハッシュ化を使う理由
+### パスワードのハッシュ化を使う理由 { #why-use-password-hashing }
 
 データベースが盗まれても、ユーザーの平文のパスワードは盗まれず、ハッシュ値だけが盗まれます。
 
 したがって、泥棒はそのパスワードを別のシステムで使えません(多くのユーザーはどこでも同じパスワードを使用しているため、危険性があります)。
 
-## `passlib` のインストール
+## `pwdlib` のインストール { #install-pwdlib }
 
-PassLib は、パスワードのハッシュを処理するための優れたPythonパッケージです。
+pwdlib は、パスワードのハッシュを処理するための優れたPythonパッケージです。
 
 このパッケージは、多くの安全なハッシュアルゴリズムとユーティリティをサポートします。
 
-推奨されるアルゴリズムは「Bcrypt」です。
+推奨されるアルゴリズムは「Argon2」です。
 
-そのため、Bcryptを指定してPassLibをインストールします:
+[仮想環境](../../virtual-environments.md){.internal-link target=_blank}を作成し、アクティベートしてから、Argon2付きでpwdlibをインストールしてください。
 
 <div class="termy">
 
 ```console
-$ pip install passlib[bcrypt]
+$ pip install "pwdlib[argon2]"
 
 ---> 100%
 ```
@@ -88,7 +86,7 @@ $ pip install passlib[bcrypt]
 
 /// tip | 豆知識
 
-`passlib`を使用すると、**Django**や**Flask**のセキュリティプラグインなどで作成されたパスワードを読み取れるように設定できます。
+`pwdlib`を使用すると、**Django**や**Flask**のセキュリティプラグインなどで作成されたパスワードを読み取れるように設定できます。
 
 例えば、Djangoアプリケーションからデータベース内の同じデータをFastAPIアプリケーションと共有できるだけではなく、同じデータベースを使用してDjangoアプリケーションを徐々に移行することもできます。
 
@@ -96,17 +94,17 @@ $ pip install passlib[bcrypt]
 
 ///
 
-## パスワードのハッシュ化と検証
+## パスワードのハッシュ化と検証 { #hash-and-verify-the-passwords }
 
-必要なツールを `passlib`からインポートします。
+必要なツールを `pwdlib`からインポートします。
 
-PassLib の「context」を作成します。これは、パスワードのハッシュ化と検証に使用されるものです。
+推奨設定でPasswordHashインスタンスを作成します。これは、パスワードのハッシュ化と検証に使用されます。
 
 /// tip | 豆知識
 
-PassLibのcontextには、検証だけが許された非推奨の古いハッシュアルゴリズムを含む、様々なハッシュアルゴリズムを使用した検証機能もあります。
+pwdlibはbcryptハッシュアルゴリズムもサポートしていますが、レガシーアルゴリズムは含みません。古いハッシュを扱うには、passlibライブラリを使用することが推奨されます。
 
-例えば、この機能を使用して、別のシステム(Djangoなど)によって生成されたパスワードを読み取って検証し、Bcryptなどの別のアルゴリズムを使用して新しいパスワードをハッシュするといったことができます。
+例えば、この機能を使用して、別のシステム(Djangoなど)によって生成されたパスワードを読み取って検証し、Argon2やBcryptなどの別のアルゴリズムを使用して新しいパスワードをハッシュするといったことができます。
 
 そして、同時にそれらはすべてに互換性があります。
 
@@ -118,15 +116,15 @@ PassLibのcontextには、検証だけが許された非推奨の古いハッシ
 
 さらに、ユーザーを認証して返す関数も作成します。
 
-{* ../../docs_src/security/tutorial004.py hl[7,48,55:56,59:60,69:75] *}
+{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *}
 
 /// note | 備考
 
-新しい(偽の)データベース`fake_users_db`を確認すると、ハッシュ化されたパスワードが次のようになっていることがわかります:`"$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"`
+新しい(偽の)データベース`fake_users_db`を確認すると、ハッシュ化されたパスワードが次のようになっていることがわかります:`"$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc"`。
 
 ///
 
-## JWTトークンの取り扱い
+## JWTトークンの取り扱い { #handle-jwt-tokens }
 
 インストールした複数のモジュールをインポートします。
 
@@ -148,33 +146,33 @@ $ openssl rand -hex 32
 
 JWTトークンの署名に使用するアルゴリズム`"HS256"`を指定した変数`ALGORITHM`を作成します。
 
-トークンの有効期限を指定した変数`ACCESS_TOKEN_EXPIRE_MINUTES`を作成します。
+トークンの有効期限を指定した変数を作成します。
 
 レスポンスのトークンエンドポイントで使用するPydanticモデルを定義します。
 
 新しいアクセストークンを生成するユーティリティ関数を作成します。
 
-{* ../../docs_src/security/tutorial004.py hl[6,12:14,28:30,78:86] *}
+{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
 
-## 依存関係の更新
+## 依存関係の更新 { #update-the-dependencies }
 
 `get_current_user`を更新して、先ほどと同じトークンを受け取るようにしますが、今回はJWTトークンを使用します。
 
-受け取ったトークンを復号して検証し、現在のユーザーを返します。
+受け取ったトークンをデコードして検証し、現在のユーザーを返します。
 
 トークンが無効な場合は、すぐにHTTPエラーを返します。
 
-{* ../../docs_src/security/tutorial004.py hl[89:106] *}
+{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *}
 
-## `/token` パスオペレーションの更新
+## `/token` *path operation* の更新 { #update-the-token-path-operation }
 
 トークンの有効期限を表す`timedelta`を作成します。
 
-JWTアクセストークンを作成し、それを返します。
+実際のJWTアクセストークンを作成し、それを返します。
 
-{* ../../docs_src/security/tutorial004.py hl[115:130] *}
+{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
 
-### JWTの"subject" `sub` についての技術的な詳細
+### JWTの「subject」`sub` についての技術的な詳細 { #technical-details-about-the-jwt-subject-sub }
 
 JWTの仕様では、トークンのsubjectを表すキー`sub`があるとされています。
 
@@ -192,13 +190,13 @@ JWTは、ユーザーを識別して、そのユーザーがAPI上で直接操
 
 しかしながら、それらのエンティティのいくつかが同じIDを持つ可能性があります。例えば、`foo`(ユーザー`foo`、車 `foo`、ブログ投稿`foo`)などです。
 
-IDの衝突を回避するために、ユーザーのJWTトークンを作成するとき、subキーの値にプレフィックスを付けることができます(例えば、`username:`)。したがって、この例では、`sub`の値は次のようになっている可能性があります:`username:johndoe`
+IDの衝突を回避するために、ユーザーのJWTトークンを作成するとき、subキーの値にプレフィックスを付けることができます(例えば、`username:`)。したがって、この例では、`sub`の値は次のようになっている可能性があります:`username:johndoe`
 
 覚えておくべき重要なことは、`sub`キーはアプリケーション全体で一意の識別子を持ち、文字列である必要があるということです。
 
-## 確認
+## 確認 { #check-it }
 
-サーバーを実行し、ドキュメントに移動します:<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>
+サーバーを実行し、ドキュメントに移動します:<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>
 
 次のようなユーザーインターフェイスが表示されます:
 
@@ -232,17 +230,17 @@ Password: `secret`
 
 <img src="/img/tutorial/security/image09.png">
 
-開発者ツールを開くと、送信されるデータにはトークンだけが含まれており、パスワードはユーザーを認証してアクセストークンを取得する最初のリクエストでのみ送信され、その後は送信されないことがわかります
+開発者ツールを開くと、送信されるデータにはトークンだけが含まれており、パスワードはユーザーを認証してアクセストークンを取得する最初のリクエストでのみ送信され、その後は送信されないことがわかります
 
 <img src="/img/tutorial/security/image10.png">
 
 /// note | 備考
 
-ヘッダーの`Authorization`には、`Bearer`で始まる値があります。
+ヘッダーの`Authorization`には、`Bearer `で始まる値があります。
 
 ///
 
-## `scopes` を使った高度なユースケース
+## `scopes` を使った高度なユースケース { #advanced-usage-with-scopes }
 
 OAuth2には、「スコープ」という概念があります。
 
@@ -252,7 +250,7 @@ OAuth2には、「スコープ」という概念があります。
 
 これらの使用方法や**FastAPI**への統合方法については、**高度なユーザーガイド**で後ほど説明します。
 
-## まとめ
+## まとめ { #recap }
 
 ここまでの説明で、OAuth2やJWTなどの規格を使った安全な**FastAPI**アプリケーションを設定することができます。
 
@@ -266,7 +264,7 @@ OAuth2には、「スコープ」という概念があります。
 
 そのため、プロジェクトに合わせて自由に選択することができます。
 
-また、**FastAPI**は外部パッケージを統合するために複雑な仕組みを必要としないため、`passlib`や`python-jose`のようなよく整備され広く使われている多くのパッケージを直接使用することができます。
+また、**FastAPI**は外部パッケージを統合するために複雑な仕組みを必要としないため、`pwdlib`や`PyJWT`のようなよく整備され広く使われている多くのパッケージを直接使用することができます。
 
 しかし、柔軟性、堅牢性、セキュリティを損なうことなく、可能な限りプロセスを簡素化するためのツールを提供します。
 
index f910d7e36d43aaa518616bc67fc253b559cdd7d2..c79789494caa677446b3ae94acf964c6f02af1ac 100644 (file)
@@ -1,13 +1,13 @@
-# 静的ファイル
+# 静的ファイル { #static-files }
 
 `StaticFiles` を使用して、ディレクトリから静的ファイルを自動的に提供できます。
 
-## `StaticFiles` の使用
+## `StaticFiles` の使用 { #use-staticfiles }
 
 * `StaticFiles` をインポート。
-* `StaticFiles()` ã\82¤ã\83³ã\82¹ã\82¿ã\83³ã\82¹ã\82\92ç\94\9fæ\88\90ã\81\97ã\80\81ç\89¹å®\9aã\81®ã\83\91ã\82¹ã\81«ã\80\8cã\83\9eã\82¦ã\83³ã\83\88ã\80\8dã\80\82
+* `StaticFiles()` インスタンスを特定のパスに「マウント」。
 
-{* ../../docs_src/static_files/tutorial001.py hl[2,6] *}
+{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
 
 /// note | 技術詳細
 
 
 ///
 
-### 「マウント」とは
+### 「マウント」とは { #what-is-mounting }
 
 「マウント」とは、特定のパスに完全な「独立した」アプリケーションを追加することを意味します。これにより、すべてのサブパスの処理がなされます。
 
 これは、マウントされたアプリケーションが完全に独立しているため、`APIRouter` とは異なります。メインアプリケーションのOpenAPIとドキュメントには、マウントされたアプリケーションの内容などは含まれません。
 
-これについて詳しくは、**高度なユーザーガイド** をご覧ください。
+これについて詳しくは、[高度なユーザーガイド](../advanced/index.md){.internal-link target=_blank} をご覧ください。
 
-## 詳細
+## 詳細 { #details }
 
 最初の `"/static"` は、この「サブアプリケーション」が「マウント」されるサブパスを指します。したがって、`"/static"` から始まるパスはすべてサブアプリケーションによって処理されます。
 
@@ -33,8 +33,8 @@
 
 `name="static"` は、**FastAPI** が内部で使用できる名前を付けます。
 
-これらのパラメータはすべて「`静的`」とは異なる場合があり、独自のアプリケーションのニーズと詳細に合わせて調整します。
+これらのパラメータはすべて「`static`」とは異なる場合があり、独自のアプリケーションのニーズと詳細に合わせて調整します。
 
-## より詳しい情報
+## より詳しい情報 { #more-info }
 
 詳細とオプションについては、<a href="https://www.starlette.dev/staticfiles/" class="external-link" target="_blank">Starletteの静的ファイルに関するドキュメント</a>を確認してください。
index 4e8ad4f7cc6df14fb9c2bf849b51ae180b1c8272..0ec6250f317f2ca747e5ac82bcbe49a28e306d19 100644 (file)
@@ -1,12 +1,24 @@
-# テスト
+# テスト { #testing }
 
 <a href="https://www.starlette.dev/testclient/" class="external-link" target="_blank">Starlette</a> のおかげで、**FastAPI** アプリケーションのテストは簡単で楽しいものになっています。
 
-<a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a> ã\81\8cã\83\99ã\83¼ã\82¹ã\81ªã\81®ã\81§ã\80\81é\9d\9e常ã\81«ä½¿ã\81\84ã\82\84ã\81\99ã\81\8f直感的です。
+<a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a> ã\81\8cã\83\99ã\83¼ã\82¹ã\81§ã\80\81ã\81\95ã\82\89ã\81«ã\81\9dã\81®è¨­è¨\88ã\81¯ Requests ã\82\92ã\83\99ã\83¼ã\82¹ã\81«ã\81\97ã\81¦ã\81\84ã\82\8bã\81\9fã\82\81ã\80\81ã\81¨ã\81¦ã\82\82馴æ\9f\93ã\81¿ã\81\8cã\81\82ã\82\8a直感的です。
 
 これを使用すると、**FastAPI** と共に <a href="https://docs.pytest.org/" class="external-link" target="_blank">pytest</a> を直接利用できます。
 
-## `TestClient` を使用
+## `TestClient` を使用 { #using-testclient }
+
+/// info | 情報
+
+`TestClient` を使用するには、まず <a href="https://www.python-httpx.org" class="external-link" target="_blank">`httpx`</a> をインストールします。
+
+[仮想環境](../virtual-environments.md){.internal-link target=_blank} を作成し、それを有効化してから、例えば以下のようにインストールしてください:
+
+```console
+$ pip install httpx
+```
+
+///
 
 `TestClient` をインポートします。
 
@@ -16,9 +28,9 @@
 
 `httpx` と同じ様に `TestClient` オブジェクトを使用します。
 
-チェックしたい Python の標準的な式と共に、シンプルに `assert` 文を記述します。
+チェックしたい Python の標準的な式と共に、シンプルに `assert` 文を記述します (これも `pytest` の標準です)
 
-{* ../../docs_src/app_testing/tutorial001.py hl[2,12,15:18] *}
+{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *}
 
 /// tip | 豆知識
 
@@ -44,48 +56,81 @@ FastAPIアプリケーションへのリクエストの送信とは別に、テ
 
 ///
 
-## テストの分離
+## テストの分離 { #separating-tests }
 
 実際のアプリケーションでは、おそらくテストを別のファイルに保存します。
 
 また、**FastAPI** アプリケーションは、複数のファイル/モジュールなどで構成されている場合もあります。
 
-### **FastAPI** アプリファイル
+### **FastAPI** アプリファイル { #fastapi-app-file }
+
+[Bigger Applications](bigger-applications.md){.internal-link target=_blank} で説明されている、次のようなファイル構成があるとします:
+
+```
+.
+├── app
+│   ├── __init__.py
+│   └── main.py
+```
+
+ファイル `main.py` に **FastAPI** アプリがあります:
+
+
+{* ../../docs_src/app_testing/app_a_py39/main.py *}
+
+### テストファイル { #testing-file }
+
+次に、テストを含む `test_main.py` ファイルを用意できます。これは同じ Python パッケージ (`__init__.py` ファイルがある同じディレクトリ) に置けます:
 
-**FastAPI** アプリに `main.py` ファイルがあるとします:
+``` hl_lines="5"
+.
+├── app
+│   ├── __init__.py
+│   ├── main.py
+│   └── test_main.py
+```
 
-{* ../../docs_src/app_testing/main.py *}
+このファイルは同じパッケージ内にあるため、相対インポートを使って `main` モジュール (`main.py`) からオブジェクト `app` をインポートできます:
 
-### テストファイル
+{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
 
-次に、テストを含む `test_main.py` ファイルを作成し、`main` モジュール (`main.py`) から `app` をインポートします:
 
-{* ../../docs_src/app_testing/test_main.py *}
+...そして、これまでと同じようにテストコードを書けます。
 
-## テスト: 例の拡張
+## テスト: 例の拡張 { #testing-extended-example }
 
 次に、この例を拡張し、詳細を追加して、さまざまなパーツをテストする方法を確認しましょう。
 
+### 拡張版 **FastAPI** アプリファイル { #extended-fastapi-app-file }
+
+先ほどと同じファイル構成で続けます:
+
+```
+.
+├── app
+│   ├── __init__.py
+│   ├── main.py
+│   └── test_main.py
+```
 
-### 拡張版 **FastAPI** アプリファイル
+ここで、**FastAPI** アプリがある `main.py` ファイルには、他の path operation があります。
 
-**FastAPI** アプリに `main_b.py` ファイルがあるとします。
+エラーを返す可能性のある `GET` オペレーションがあります。
 
\81\9dã\81®ã\83\95ã\82¡ã\82¤ã\83«ã\81«ã\81¯ã\80\81ã\82¨ã\83©ã\83¼ã\82\92è¿\94ã\81\99å\8f¯è\83½æ\80§ã\81®ã\81\82ã\82\8b `GET` ã\82ªã\83\9aã\83¬ã\83¼ã\82·ã\83§ã\83³ã\81\8cあります。
\81\84ã\81\8fã\81¤ã\81\8bã\81®ã\82¨ã\83©ã\83¼ã\82\92è¿\94ã\81\99å\8f¯è\83½æ\80§ã\81®ã\81\82ã\82\8b `POST` ã\82ªã\83\9aã\83¬ã\83¼ã\82·ã\83§ã\83³ã\82\82あります。
 
-また、いくつかのエラーを返す可能性のある `POST` オペレーションもあります。
+両方の *path operation* には `X-Token` ヘッダーが必要です。
 
-これらの *path operation* には `X-Token` ヘッダーが必要です。
+{* ../../docs_src/app_testing/app_b_an_py310/main.py *}
 
-{* ../../docs_src/app_testing/app_b_py310/main.py *}
+### 拡張版テストファイル { #extended-testing-file }
 
-### 拡張版テストファイル
+次に、拡張版のテストで `test_main.py` を更新できます:
 
-次に、先程のものに拡張版のテストを加えた、`test_main_b.py` を作成します。
+{* ../../docs_src/app_testing/app_b_an_py310/test_main.py *}
 
-{* ../../docs_src/app_testing/app_b/test_main.py *}
 
-リクエストに情報を渡せるクライアントが必要で、その方法がわからない場合はいつでも、`httpx` での実現方法を検索 (Google) できます。
\83ªã\82¯ã\82¨ã\82¹ã\83\88ã\81«æ\83\85å ±ã\82\92渡ã\81\9bã\82\8bã\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88ã\81\8cå¿\85è¦\81ã\81§ã\80\81ã\81\9dã\81®æ\96¹æ³\95ã\81\8cã\82\8fã\81\8bã\82\89ã\81ªã\81\84å ´å\90\88ã\81¯ã\81\84ã\81¤ã\81§ã\82\82ã\80\81`httpx` ã\81§ã\81®å®\9fç\8f¾æ\96¹æ³\95ã\80\81ã\81\82ã\82\8bã\81\84ã\81¯ HTTPX ã\81®è¨­è¨\88ã\81\8c Requests ã\81®è¨­è¨\88ã\82\92ã\83\99ã\83¼ã\82¹ã\81«ã\81\97ã\81¦ã\81\84ã\82\8bã\81\9fã\82\81 `requests` ã\81§ã\81®å®\9fç\8f¾æ\96¹æ³\95ã\82\92æ¤\9cç´¢ (Google) ã\81§ã\81\8dã\81¾ã\81\99ã\80\82
 
 テストでも同じことを行います。
 
@@ -107,9 +152,11 @@ FastAPIアプリケーションへのリクエストの送信とは別に、テ
 
 ///
 
-## 実行
+## 実行 { #run-it }
+
+その後、`pytest` をインストールするだけです。
 
-後は、`pytest` をインストールするだけです:
+[仮想環境](../virtual-environments.md){.internal-link target=_blank} を作成し、それを有効化してから、例えば以下のようにインストールしてください:
 
 <div class="termy">
 
@@ -121,7 +168,7 @@ $ pip install pytest
 
 </div>
 
\83\95ã\82¡ã\82¤ã\83«ã\82\92æ¤\9cç\9f¥ã\81\97ã\80\81è\87ªå\8b\95ã\83\86ã\82¹ã\83\88ã\82\92å®\9fè¡\8cã\81\97、結果のレポートを返します。
\83\95ã\82¡ã\82¤ã\83«ã\81¨ã\83\86ã\82¹ã\83\88ã\82\92è\87ªå\8b\95ç\9a\84ã\81«æ¤\9cå\87ºã\81\97ã\80\81å®\9fè¡\8cã\81\97ã\81¦、結果のレポートを返します。
 
 以下でテストを実行します:
 
index 791cf64a84246a5160d98456d233a4fe9c1b5f90..6723230632a1e20f357b586c0dbddd5feffe141c 100644 (file)
@@ -1,10 +1,10 @@
-# 仮想環境
+# 仮想環境 { #virtual-environments }
 
 Pythonプロジェクトの作業では、**仮想環境**(または類似の仕組み)を使用し、プロジェクトごとにインストールするパッケージを分離するべきでしょう。
 
 /// info | 情報
 
\82\82ã\81\97ã\80\81ä»®æ\83³ç\92°å¢\83ã\81®æ¦\82è¦\81ã\82\84ä½\9cæ\88\90æ\96¹æ³\95ã\80\81使ç\94¨æ\96¹æ³\95ã\81«ã\81¤ã\81\84ã\81¦æ\97¢ã\81«ã\81\94å­\98ç\9f¥ã\81ªã\82\89ã\80\81ã\81\93ã\81®ã\82»ã\82¯ã\82·ã\83§ã\83³ã\82\92ã\82¹ã\82­ã\83\83ã\83\97ã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\81¾ã\81\99。🤓
\82\82ã\81\97ã\80\81ä»®æ\83³ç\92°å¢\83ã\81®æ¦\82è¦\81ã\82\84ä½\9cæ\88\90æ\96¹æ³\95ã\80\81使ç\94¨æ\96¹æ³\95ã\81«ã\81¤ã\81\84ã\81¦æ\97¢ã\81«ã\81\94å­\98ç\9f¥ã\81ªã\82\89ã\80\81ã\81\93ã\81®ã\82»ã\82¯ã\82·ã\83§ã\83³ã\82\92ã\82¹ã\82­ã\83\83ã\83\97ã\81\97ã\81\9fæ\96¹ã\81\8cã\82\88ã\81\84ã\81\8bã\82\82ã\81\97ã\82\8cã\81¾ã\81\9bã\82\93。🤓
 
 ///
 
@@ -25,7 +25,7 @@ Pythonプロジェクトの作業では、**仮想環境**(または類似の
 
 ///
 
-## プロジェクトの作成
+## プロジェクトの作成 { #create-a-project }
 
 まず、プロジェクト用のディレクトリを作成します。
 
@@ -48,9 +48,9 @@ $ cd awesome-project
 
 </div>
 
-## 仮想環境の作成
+## 仮想環境の作成 { #create-a-virtual-environment }
 
-Pythonプロジェクトでの**初めての**作業を開始する際には、**<abbr title="他の選択肢もありますが、これはシンプルなガイドラインです">プロジェクト内</abbr>**に仮想環境を作成してください。
+Pythonプロジェクトでの**初めての**作業を開始する際には、**<abbr title="there are other options, this is a simple guideline – 他の選択肢もありますが、これはシンプルなガイドラインです">プロジェクト内</abbr>**に仮想環境を作成してください。
 
 /// tip | 豆知識
 
@@ -72,10 +72,10 @@ $ python -m venv .venv
 
 /// details | このコマンドの意味
 
-- `python` : `python` というプログラムを呼び出します
-- `-m` : モジュールをスクリプトとして呼び出します。どのモジュールを呼び出すのか、この次に指定します
-- `venv` : 通常Pythonに付随してインストールされる `venv`モジュールを使用します
-- `.venv` : 仮想環境を`.venv`という新しいディレクトリに作成します
+* `python`: `python` というプログラムを呼び出します
+* `-m`: モジュールをスクリプトとして呼び出します。どのモジュールを呼び出すのか、この次に指定します
+* `venv`: 通常Pythonに付随してインストールされる `venv`モジュールを使用します
+* `.venv`: 仮想環境を`.venv`という新しいディレクトリに作成します
 
 ///
 
@@ -111,13 +111,13 @@ $ uv venv
 
 ///
 
-## 仮想環境の有効化
+## 仮想環境の有効化 { #activate-the-virtual-environment }
 
 実行されるPythonコマンドやインストールされるパッケージが新しく作成した仮想環境を使用するよう、その仮想環境を有効化しましょう。
 
 /// tip | 豆知識
 
\81\9dã\81®ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88ã\81®ä½\9c業ã\81§**æ\96°ã\81\97ã\81\84ã\82¿ã\83¼ã\83\9fã\83\8aã\83«ã\82»ã\83\83ã\82·ã\83§ã\83³**ã\82\92é\96\8bå§\8bã\81\99ã\82\8bé\9a\9bã\81«ã\81¯ã\80\81**æ¯\8eå\9b\9e**æ\9c\89å\8a¹å\8c\96ã\81\8cå¿\85è¦\81ã\81§ã\81\99
\81\9dã\81®ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88ã\81®ä½\9c業ã\81§**æ\96°ã\81\97ã\81\84ã\82¿ã\83¼ã\83\9fã\83\8aã\83«ã\82»ã\83\83ã\82·ã\83§ã\83³**ã\82\92é\96\8bå§\8bã\81\99ã\82\8bé\9a\9bã\81«ã\81¯ã\80\81**æ¯\8eå\9b\9e**æ\9c\89å\8a¹å\8c\96ã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84
 
 ///
 
@@ -161,13 +161,13 @@ $ source .venv/Scripts/activate
 
 /// tip | 豆知識
 
-**æ\96°ã\81\97ã\81\84ã\83\91ã\83\83ã\82±ã\83¼ã\82¸**ã\82\92ä»®æ\83³ç\92°å¢\83ã\81«ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\81\99ã\82\8bã\81¨ã\81\8dã\81«ã\81¯ã\80\81å\86\8d度**有効化**してください。
+**æ\96°ã\81\97ã\81\84ã\83\91ã\83\83ã\82±ã\83¼ã\82¸**ã\82\92ä»®æ\83³ç\92°å¢\83ã\81«ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\81\99ã\82\8bã\81\9fã\81³ã\81«ã\80\81ç\92°å¢\83ã\82\92ã\82\82ã\81\86ä¸\80度**有効化**してください。
 
 こうすることで、そのパッケージがインストールした**ターミナル(<abbr title="command line interface">CLI</abbr>)プログラム**を使用する場合に、仮想環境内のものが確実に使われ、グローバル環境にインストールされている別のもの(おそらく必要なものとは異なるバージョン)を誤って使用することを防ぎます。
 
 ///
 
-## 仮想環境が有効であることを確認する
+## 仮想環境が有効であることを確認する { #check-the-virtual-environment-is-active }
 
 仮想環境が有効である(前のコマンドが正常に機能した)ことを確認します。
 
@@ -197,7 +197,7 @@ $ which python
 
 <div class="termy">
 
-``` console
+```console
 $ Get-Command python
 
 C:\Users\user\code\awesome-project\.venv\Scripts\python
@@ -209,7 +209,7 @@ C:\Users\user\code\awesome-project\.venv\Scripts\python
 
 ////
 
-## `pip` をアップグレードする
+## `pip` をアップグレードする { #upgrade-pip }
 
 /// tip | 豆知識
 
@@ -239,7 +239,27 @@ $ python -m pip install --upgrade pip
 
 </div>
 
-## `.gitignore` を追加する
+/// tip | 豆知識
+
+ときどき、pip をアップグレードしようとすると **`No module named pip`** エラーが表示されることがあります。
+
+その場合は、以下のコマンドで pip をインストールしてアップグレードしてください:
+
+<div class="termy">
+
+```console
+$ python -m ensurepip --upgrade
+
+---> 100%
+```
+
+</div>
+
+このコマンドは、pip がまだインストールされていなければ pip をインストールし、また、インストールされる pip のバージョンが `ensurepip` で利用可能なもの以上に新しいことも保証します。
+
+///
+
+## `.gitignore` を追加する { #add-gitignore }
 
 **Git**を使用している場合(使用するべきでしょう)、 `.gitignore` ファイルを追加して、 `.venv` 内のあらゆるファイルをGitの管理対象から除外します。
 
@@ -265,9 +285,9 @@ $ echo "*" > .venv/.gitignore
 
 /// details | このコマンドの意味
 
-- `echo "*"` : ターミナルに `*` というテキストを「表示」しようとします。(次の部分によってその動作が少し変わります)
-- `>` : `>` の左側のコマンドがターミナルに表示しようとする内容を、ターミナルには表示せず、 `>` の右側のファイルに書き込みます。
-- `.gitignore` : `*` を書き込むファイル名。
+* `echo "*"`: ターミナルに `*` というテキストを「表示」しようとします。(次の部分によってその動作が少し変わります)
+* `>`: `>` の左側のコマンドがターミナルに表示しようとする内容を、ターミナルには表示せず、 `>` の右側のファイルに書き込みます。
+* `.gitignore`: `*` を書き込むファイル名。
 
 ここで、Gitにおける `*` は「すべて」を意味するので、このコマンドによって `.venv` ディレクトリ内のすべてがGitに無視されるようになります。
 
@@ -279,7 +299,7 @@ $ echo "*" > .venv/.gitignore
 
 ///
 
-## パッケージのインストール
+## パッケージのインストール { #install-packages }
 
 仮想環境を有効化した後、その中でパッケージをインストールできます。
 
@@ -291,7 +311,7 @@ $ echo "*" > .venv/.gitignore
 
 ///
 
-### パッケージを直接インストールする
+### パッケージを直接インストールする { #install-packages-directly }
 
 急いでいて、プロジェクトのパッケージ要件を宣言するファイルを使いたくない場合、パッケージを直接インストールできます。
 
@@ -330,7 +350,7 @@ $ uv pip install "fastapi[standard]"
 
 ////
 
-### `requirements.txt` からインストールする
+### `requirements.txt` からインストールする { #install-from-requirements-txt }
 
 もし `requirements.txt` があるなら、パッケージのインストールに使用できます。
 
@@ -373,7 +393,7 @@ pydantic==2.8.0
 
 ///
 
-## プログラムを実行する
+## プログラムを実行する { #run-your-program }
 
 仮想環境を有効化した後、プログラムを実行できます。この際、仮想環境内のPythonと、そこにインストールしたパッケージが使用されます。
 
@@ -387,7 +407,7 @@ Hello World
 
 </div>
 
-## エディタの設定
+## エディタの設定 { #configure-your-editor }
 
 プロジェクトではおそらくエディタを使用するでしょう。コード補完やインラインエラーの表示ができるように、作成した仮想環境をエディタでも使えるよう設定してください。(多くの場合、自動検出されます)
 
@@ -402,7 +422,7 @@ Hello World
 
 ///
 
-## 仮想環境の無効化
+## 仮想環境の無効化 { #deactivate-the-virtual-environment }
 
 プロジェクトの作業が終了したら、その仮想環境を**無効化**できます。
 
@@ -416,9 +436,11 @@ $ deactivate
 
 これにより、 `python` コマンドを実行しても、そのプロジェクト用(のパッケージがインストールされた)仮想環境から `python` プログラムを呼び出そうとはしなくなります。
 
-## 作業準備完了
+## 作業準備完了 { #ready-to-work }
+
+これで、プロジェクトの作業を始める準備が整いました。
+
 
-ここまでで、プロジェクトの作業を始める準備が整いました。
 
 /// tip | 豆知識
 
@@ -428,9 +450,9 @@ $ deactivate
 
 ///
 
-## なぜ仮想環境?
+## なぜ仮想環境? { #why-virtual-environments }
 
-FastAPIを使った作業をするには、 [Python](https://www.python.org/) のインストールが必要です。
+FastAPIを使った作業をするには、<a href="https://www.python.org/" class="external-link" target="_blank">Python</a> のインストールが必要です。
 
 それから、FastAPIや、使用したいその他の**パッケージ**を**インストール**する必要があります。
 
@@ -438,7 +460,7 @@ FastAPIを使った作業をするには、 [Python](https://www.python.org/) 
 
 ただし、`pip` を直接使用すると、パッケージは**グローバルなPython環境**(OS全体にインストールされたPython環境)にインストールされます。
 
-### 問題点
+### 問題点 { #the-problem }
 
 では、グローバルPython環境にパッケージをインストールすることの問題点は何でしょうか?
 
@@ -521,7 +543,7 @@ Pythonのパッケージでは、**新しいバージョン**で**互換性を
 
 また、使用しているOS(Linux、Windows、macOS など)によっては、Pythonがすでにインストールされていることがあります。この場合、特定のバージョンのパッケージが**OSの動作に必要である**ことがあります。グローバル環境にパッケージをインストールすると、OSに付属するプログラムを**壊してしまう**可能性があります。
 
-## パッケージのインストール先
+## パッケージのインストール先 { #where-are-packages-installed }
 
 Pythonをインストールしたとき、ファイルを含んだいくつかのディレクトリが作成されます。
 
@@ -539,7 +561,7 @@ $ pip install "fastapi[standard]"
 
 </div>
 
-FastAPIのコードを含む圧縮ファイルが、通常は [PyPI](https://pypi.org/project/fastapi/) からダウンロードされます。
+FastAPIのコードを含む圧縮ファイルが、通常は <a href="https://pypi.org/project/fastapi/" class="external-link" target="_blank">PyPI</a> からダウンロードされます。
 
 また、FastAPIが依存する他のパッケージも**ダウンロード**されます。
 
@@ -547,7 +569,7 @@ FastAPIのコードを含む圧縮ファイルが、通常は [PyPI](https://pyp
 
 デフォルトでは、これらのファイルはPythonのインストール時に作成されるディレクトリ、つまり**グローバル環境**に配置されます。
 
-## 仮想環境とは
+## 仮想環境とは { #what-are-virtual-environments }
 
 すべてのパッケージをグローバル環境に配置することによって生じる問題の解決策は、作業する**プロジェクトごとの仮想環境**を使用することです。
 
@@ -572,7 +594,7 @@ flowchart TB
     stone-project ~~~ azkaban-project
 ```
 
-## 仮想環境の有効化とは
+## 仮想環境の有効化とは { #what-does-activating-a-virtual-environment-mean }
 
 仮想環境を有効にしたとき、例えば次のコマンドを実行した場合を考えます:
 
@@ -620,7 +642,7 @@ $ source .venv/Scripts/activate
 
 /// tip | 豆知識
 
-`PATH` 変数についての詳細は [環境変数](environment-variables.md#path環境変数){.internal-link target=_blank} を参照してください。
+`PATH` 変数についての詳細は [環境変数](environment-variables.md#path-environment-variable){.internal-link target=_blank} を参照してください。
 
 ///
 
@@ -701,7 +723,7 @@ C:\Users\user\code\awesome-project\.venv\Scripts\python
 
 仮想環境を有効にして変更されることは他にもありますが、これが最も重要な変更のひとつです。
 
-## 仮想環境の確認
+## 仮想環境の確認 { #checking-a-virtual-environment }
 
 仮想環境が有効かどうか、例えば次のように確認できます。:
 
@@ -753,7 +775,7 @@ LinuxやmacOSでは `which` を、Windows PowerShellでは `Get-Command` を使
 
 ///
 
-## なぜ仮想環境を無効化するのか
+## なぜ仮想環境を無効化するのか { #why-deactivate-a-virtual-environment }
 
 例えば、`philosophers-stone` (賢者の石)というプロジェクトで作業をしていて、**その仮想環境を有効にし**、必要なパッケージをインストールしてその環境内で作業を進めているとします。
 
@@ -786,7 +808,7 @@ Traceback (most recent call last):
 
 </div>
 
-しかし、その仮想環境を無効化し、 `prisoner-of-azkaban` (アズカバンの囚人)のための新しい仮想環境を有効にすれば、 `python` を実行したときに `prisoner-of-azkaban` (アズカバンの囚人)の仮想環境の Python が使用されるようになります。
+しかし、その仮想環境を無効化し、 `prisoner-of-askaban` のための新しい仮想環境を有効にすれば、 `python` を実行したときに `prisoner-of-azkaban` (アズカバンの囚人)の仮想環境の Python が使用されるようになります。
 
 <div class="termy">
 
@@ -807,7 +829,7 @@ I solemnly swear 🐺
 
 </div>
 
-## 代替手段
+## 代替手段 { #alternatives }
 
 これは、あらゆる仕組みを**根本から**学ぶためのシンプルな入門ガイドです。
 
@@ -824,7 +846,7 @@ I solemnly swear 🐺
 * パッケージとそのバージョンの、依存関係を含めた**厳密な**組み合わせを保持し、これによって、本番環境で、開発環境と全く同じようにプロジェクトを実行できる(これは**locking**と呼ばれます)
 * その他のさまざまな機能
 
-## まとめ
+## まとめ { #conclusion }
 
 ここまで読みすべて理解したなら、世間の多くの開発者と比べて、仮想環境について**あなたはより多くのことを知っています**。🤓
 
index 18909cd595db00e69fe85794b88fca058518b2cb..de2616746124a3352bcdb9d8d708edade0b67e0f 100644 (file)
@@ -30,8 +30,7 @@ Use the following preferred translations when they apply in documentation prose:
 
 - request (HTTP): リクエスト
 - response (HTTP): レスポンス
-- path operation: パスオペレーション
-- path operation function: パスオペレーション関数
+- path operation: path operation (do not translate)
 
 ### `///` admonitions
 
index 20bf1c1688fb6ef5a93eeb47785c61f3bfaf1b49..ca2baf97dc3d74adf5f31c63d98198fa9d89598b 100644 (file)
@@ -23,6 +23,7 @@ SUPPORTED_LANGS = {
     "en",
     "de",
     "es",
+    "ja",
     "ko",
     "pt",
     "ru",