mirror of
https://github.com/fastapi/fastapi.git
synced 2026-02-15 00:31:19 -05:00
Update all
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
|
||||
{* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *}
|
||||
|
||||
/// warning | 注意
|
||||
/// warning
|
||||
|
||||
上の例のように `Response` を直接返すと、それはそのまま返されます。
|
||||
|
||||
@@ -38,4 +38,4 @@
|
||||
|
||||
追加のステータスコードとレスポンスを直接返す場合、それらは OpenAPI スキーマ(API ドキュメント)には含まれません。FastAPI には、事前に何が返されるかを知る方法がないからです。
|
||||
|
||||
しかし、[Additional Responses](additional-responses.md){.internal-link target=_blank} を使ってコード内にドキュメント化できます。
|
||||
しかし、[追加のレスポンス](additional-responses.md){.internal-link target=_blank} を使ってコード内にドキュメント化できます。
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
しかし、返そうとしているコンテンツが **JSONでシリアライズ可能**であることが確実なら、それを直接レスポンスクラスに渡して、FastAPIがレスポンスクラスへ渡す前に返却コンテンツを `jsonable_encoder` に通すことで発生する追加のオーバーヘッドを回避できます。
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
|
||||
{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
|
||||
|
||||
/// info | 情報
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
* `HTMLResponse` をインポートする。
|
||||
* *path operation デコレータ* のパラメータ `response_class` に `HTMLResponse` を渡す。
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
|
||||
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
|
||||
|
||||
/// info | 情報
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
|
||||
上記と同じ例において、 `HTMLResponse` を返すと、このようになります:
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
|
||||
{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *}
|
||||
|
||||
/// warning | 注意
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
|
||||
例えば、このようになります:
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
|
||||
{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *}
|
||||
|
||||
この例では、関数 `generate_html_response()` は、`str` のHTMLを返すのではなく、`Response` を生成して返しています。
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
|
||||
FastAPI(実際にはStarlette)は自動的にContent-Lengthヘッダーを含みます。また、`media_type` に基づいたContent-Typeヘッダーを含み、テキストタイプのためにcharsetを追加します。
|
||||
|
||||
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
|
||||
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
|
||||
|
||||
### `HTMLResponse` { #htmlresponse }
|
||||
|
||||
@@ -146,7 +146,7 @@ FastAPI(実際にはStarlette)は自動的にContent-Lengthヘッダーを
|
||||
|
||||
テキストやバイトを受け取り、プレーンテキストのレスポンスを返します。
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
|
||||
{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *}
|
||||
|
||||
### `JSONResponse` { #jsonresponse }
|
||||
|
||||
@@ -180,7 +180,7 @@ FastAPI(実際にはStarlette)は自動的にContent-Lengthヘッダーを
|
||||
|
||||
///
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
|
||||
{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -194,13 +194,13 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
|
||||
|
||||
`RedirectResponse` を直接返せます:
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
|
||||
{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}
|
||||
|
||||
---
|
||||
|
||||
または、`response_class` パラメータで使用できます:
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
|
||||
{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}
|
||||
|
||||
その場合、*path operation*関数からURLを直接返せます。
|
||||
|
||||
@@ -210,13 +210,13 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
|
||||
|
||||
また、`status_code` パラメータを `response_class` パラメータと組み合わせて使うこともできます:
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
|
||||
{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *}
|
||||
|
||||
### `StreamingResponse` { #streamingresponse }
|
||||
|
||||
非同期ジェネレータ、または通常のジェネレータ/イテレータを受け取り、レスポンスボディをストリームします。
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
|
||||
{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
|
||||
|
||||
#### ファイルライクオブジェクトで `StreamingResponse` を使う { #using-streamingresponse-with-file-like-objects }
|
||||
|
||||
@@ -226,7 +226,7 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
|
||||
|
||||
これにはクラウドストレージとの連携、映像処理など、多くのライブラリが含まれます。
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
|
||||
{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
|
||||
|
||||
1. これはジェネレータ関数です。内部に `yield` 文を含むため「ジェネレータ関数」です。
|
||||
2. `with` ブロックを使うことで、ジェネレータ関数が終わった後(つまりレスポンスの送信が完了した後)にfile-likeオブジェクトが確実にクローズされるようにします。
|
||||
@@ -255,11 +255,11 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
|
||||
|
||||
ファイルレスポンスには、適切な `Content-Length`、`Last-Modified`、`ETag` ヘッダーが含まれます。
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
|
||||
{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *}
|
||||
|
||||
`response_class` パラメータを使うこともできます:
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
|
||||
{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *}
|
||||
|
||||
この場合、*path operation*関数からファイルパスを直接返せます。
|
||||
|
||||
@@ -273,7 +273,7 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
|
||||
|
||||
`CustomORJSONResponse` を作れます。主に必要なのは、コンテンツを `bytes` として返す `Response.render(content)` メソッドを作ることです:
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
|
||||
{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}
|
||||
|
||||
これまでは次のように返していたものが:
|
||||
|
||||
@@ -299,7 +299,7 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
|
||||
|
||||
以下の例では、**FastAPI** はすべての*path operation*で、`JSONResponse` の代わりに `ORJSONResponse` をデフォルトとして使います。
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
|
||||
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ OpenAPIの「エキスパート」でなければ、これはおそらく必要
|
||||
|
||||
各オペレーションで一意になるようにする必要があります。
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py310.py hl[6] *}
|
||||
|
||||
### *path operation関数* の名前をoperationIdとして使用する { #using-the-path-operation-function-name-as-the-operationid }
|
||||
|
||||
@@ -20,7 +20,7 @@ APIの関数名を `operationId` として利用したい場合、すべてのAP
|
||||
|
||||
すべての *path operation* を追加した後に行うべきです。
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -40,7 +40,7 @@ APIの関数名を `operationId` として利用したい場合、すべてのAP
|
||||
|
||||
生成されるOpenAPIスキーマ(つまり、自動ドキュメント生成の仕組み)から *path operation* を除外するには、`include_in_schema` パラメータを使用して `False` に設定します。
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *}
|
||||
|
||||
## docstringによる説明の高度な設定 { #advanced-description-from-docstring }
|
||||
|
||||
@@ -92,7 +92,7 @@ OpenAPI仕様では <a href="https://github.com/OAI/OpenAPI-Specification/blob/m
|
||||
|
||||
この `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] *}
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *}
|
||||
|
||||
自動APIドキュメントを開くと、その拡張は特定の *path operation* の下部に表示されます。
|
||||
|
||||
@@ -139,9 +139,9 @@ OpenAPI仕様では <a href="https://github.com/OAI/OpenAPI-Specification/blob/m
|
||||
|
||||
それは `openapi_extra` で行えます。
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.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()` 関数が、何らかの方法でそれをパースする責務を担います。
|
||||
この例では、Pydanticモデルを一切宣言していません。実際、リクエストボディはJSONとして <dfn title="bytes などのプレーンな形式から Python オブジェクトに変換される">パース</dfn> されず、直接 `bytes` として読み取られます。そして `magic_data_reader()` 関数が、何らかの方法でそれをパースする責務を担います。
|
||||
|
||||
それでも、リクエストボディに期待されるスキーマを宣言できます。
|
||||
|
||||
@@ -153,7 +153,7 @@ OpenAPI仕様では <a href="https://github.com/OAI/OpenAPI-Specification/blob/m
|
||||
|
||||
例えばこのアプリケーションでは、PydanticモデルからJSON Schemaを抽出するFastAPIの統合機能や、JSONの自動バリデーションを使っていません。実際、リクエストのcontent typeをJSONではなくYAMLとして宣言しています。
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *}
|
||||
|
||||
それでも、デフォルトの統合機能を使っていないにもかかわらず、YAMLで受け取りたいデータのために、Pydanticモデルを使って手動でJSON Schemaを生成しています。
|
||||
|
||||
@@ -161,7 +161,7 @@ OpenAPI仕様では <a href="https://github.com/OAI/OpenAPI-Specification/blob/m
|
||||
|
||||
その後、コード内でそのYAMLコンテンツを直接パースし、さらに同じPydanticモデルを使ってYAMLコンテンツを検証しています。
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
XMLを文字列にし、`Response` に含め、それを返します。
|
||||
|
||||
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
|
||||
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
|
||||
|
||||
## 備考 { #notes }
|
||||
|
||||
|
||||
@@ -38,13 +38,13 @@ $ pip install websockets
|
||||
|
||||
しかし、これはWebSocketsのサーバーサイドに焦点を当て、動作する例を示す最も簡単な方法です。
|
||||
|
||||
{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
|
||||
{* ../../docs_src/websockets/tutorial001_py310.py hl[2,6:38,41:43] *}
|
||||
|
||||
## `websocket` を作成する { #create-a-websocket }
|
||||
|
||||
**FastAPI** アプリケーションで、`websocket` を作成します。
|
||||
|
||||
{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
|
||||
{* ../../docs_src/websockets/tutorial001_py310.py hl[1,46:47] *}
|
||||
|
||||
/// note | 技術詳細
|
||||
|
||||
@@ -58,7 +58,7 @@ $ pip install websockets
|
||||
|
||||
WebSocketルートでは、メッセージを待機して送信するために `await` を使用できます。
|
||||
|
||||
{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
|
||||
{* ../../docs_src/websockets/tutorial001_py310.py hl[48:52] *}
|
||||
|
||||
バイナリやテキストデータ、JSONデータを送受信できます。
|
||||
|
||||
@@ -154,7 +154,7 @@ $ fastapi dev main.py
|
||||
|
||||
WebSocket接続が閉じられると、 `await websocket.receive_text()` は例外 `WebSocketDisconnect` を発生させ、この例のようにキャッチして処理することができます。
|
||||
|
||||
{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
|
||||
{* ../../docs_src/websockets/tutorial003_py310.py hl[79:81] *}
|
||||
|
||||
試してみるには、
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# 代替ツールから受けたインスピレーションと比較
|
||||
# 代替ツールから受けたインスピレーションと比較 { #alternatives-inspiration-and-comparisons }
|
||||
|
||||
何が**FastAPI**にインスピレーションを与えたのか、他の代替ツールと比較してどうか、そしてそこから何を学んだのかについて。
|
||||
|
||||
## はじめに
|
||||
## はじめに { #intro }
|
||||
|
||||
**FastAPI**は、代替ツールのこれまでの働きがなければ存在しなかったでしょう。
|
||||
|
||||
@@ -12,17 +12,17 @@
|
||||
|
||||
しかし、その時点では、これらの機能をすべて提供し、以前のツールから優れたアイデアを取り入れ、可能な限り最高の方法でそれらを組み合わせ、それまで利用できなかった言語機能 (Python 3.6以降の型ヒント) を利用したものを作る以外に選択肢はありませんでした。
|
||||
|
||||
## 以前のツール
|
||||
## 以前のツール { #previous-tools }
|
||||
|
||||
### <a href="https://www.djangoproject.com/" class="external-link" target="_blank">Django</a>
|
||||
### <a href="https://www.djangoproject.com/" class="external-link" target="_blank">Django</a> { #django }
|
||||
|
||||
Pythonのフレームワークの中で最もポピュラーで、広く信頼されています。Instagramのようなシステムの構築に使われています。
|
||||
|
||||
リレーショナルデータベース (MySQLやPostgreSQLなど) と比較的強固に結合されているので、NoSQLデータベース (Couchbase、MongoDB、Cassandraなど) をメインに利用することは簡単ではありません。
|
||||
|
||||
バックエンドでHTMLを生成するために作られたものであり、現代的なフロントエンド (ReactやVue.js、Angularなど) や、他のシステム (IoTデバイスなど) と通信するAPIを構築するために作られたものではありません。
|
||||
バックエンドでHTMLを生成するために作られたものであり、現代的なフロントエンド (ReactやVue.js、Angularなど) や、他のシステム (<abbr title="Internet of Things - モノのインターネット">IoT</abbr>デバイスなど) と通信するAPIを構築するために作られたものではありません。
|
||||
|
||||
### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a>
|
||||
### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a> { #django-rest-framework }
|
||||
|
||||
Django REST Frameworkは、Djangoを下敷きにしてWeb APIを構築する柔軟なツールキットとして、APIの機能を向上させるために作られました。
|
||||
|
||||
@@ -42,7 +42,7 @@ Django REST Framework は Tom Christie によって作成されました。Starl
|
||||
|
||||
///
|
||||
|
||||
### <a href="http://flask.pocoo.org/" class="external-link" target="_blank">Flask</a>
|
||||
### <a href="https://flask.palletsprojects.com" class="external-link" target="_blank">Flask</a> { #flask }
|
||||
|
||||
Flask は「マイクロフレームワーク」であり、データベースとの統合のようなDjangoがデフォルトで持つ多くの機能は含まれていません。
|
||||
|
||||
@@ -64,7 +64,7 @@ Flaskのシンプルさを考えると、APIを構築するのに適している
|
||||
|
||||
///
|
||||
|
||||
### <a href="http://docs.python-requests.org" class="external-link" target="_blank">Requests</a>
|
||||
### <a href="https://requests.readthedocs.io" class="external-link" target="_blank">Requests</a> { #requests }
|
||||
|
||||
**FastAPI**は実際には**Requests**の代替ではありません。それらのスコープは大きく異なります。
|
||||
|
||||
@@ -80,7 +80,7 @@ Requestsは非常にシンプルかつ直感的なデザインで使いやすく
|
||||
|
||||
公式サイトで以下のように言われているのは、それが理由です。
|
||||
|
||||
> Requestsは今までで最もダウンロードされたPythonパッケージである
|
||||
> Requestsは史上最もダウンロードされたPythonパッケージのひとつです
|
||||
|
||||
使い方はとても簡単です。例えば、`GET`リクエストを実行するには、このように書けば良いです:
|
||||
|
||||
@@ -88,7 +88,7 @@ Requestsは非常にシンプルかつ直感的なデザインで使いやすく
|
||||
response = requests.get("http://example.com/some/url")
|
||||
```
|
||||
|
||||
対応するFastAPIのパスオペレーションはこのようになります:
|
||||
対応するFastAPIのAPIのpath operationはこのようになります:
|
||||
|
||||
```Python hl_lines="1"
|
||||
@app.get("/some/url")
|
||||
@@ -106,7 +106,7 @@ def read_url():
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://swagger.io/" class="external-link" target="_blank">Swagger</a> / <a href="https://github.com/OAI/OpenAPI-Specification/" class="external-link" target="_blank">OpenAPI</a>
|
||||
### <a href="https://swagger.io/" class="external-link" target="_blank">Swagger</a> / <a href="https://github.com/OAI/OpenAPI-Specification/" class="external-link" target="_blank">OpenAPI</a> { #swagger-openapi }
|
||||
|
||||
私がDjango REST Frameworkに求めていた主な機能は、APIの自動的なドキュメント生成でした。
|
||||
|
||||
@@ -131,13 +131,13 @@ def read_url():
|
||||
|
||||
///
|
||||
|
||||
### Flask REST フレームワーク
|
||||
### Flask REST フレームワーク { #flask-rest-frameworks }
|
||||
|
||||
いくつかのFlask RESTフレームワークがありますが、それらを調査してみたところ、多くのものが不適切な問題が残ったまま、中断されたり放置されていることがわかりました。
|
||||
|
||||
### <a href="https://marshmallow.readthedocs.io/en/3.0/" class="external-link" target="_blank">Marshmallow</a>
|
||||
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #marshmallow }
|
||||
|
||||
APIシステムで必要とされる主な機能の一つに、コード (Python) からデータを取り出して、ネットワークを介して送れるものに変換するデータの「<abbr title="marshalling, conversion">シリアライゼーション</abbr>」があります。例えば、データベースのデータを含むオブジェクトをJSONオブジェクトに変換したり、`datetime` オブジェクトを文字列に変換するなどです。
|
||||
APIシステムで必要とされる主な機能の一つに、コード (Python) からデータを取り出して、ネットワークを介して送れるものに変換するデータの「<dfn title="別名: marshalling、変換">シリアライゼーション</dfn>」があります。例えば、データベースのデータを含むオブジェクトをJSONオブジェクトに変換したり、`datetime` オブジェクトを文字列に変換するなどです。
|
||||
|
||||
APIが必要とするもう一つの大きな機能はデータのバリデーションであり、特定のパラメータが与えられた場合にデータが有効であることを確認することです。例えば、あるフィールドがランダムな文字列ではなく `int` であることなどです。これは特に受信するデータに対して便利です。
|
||||
|
||||
@@ -145,7 +145,7 @@ APIが必要とするもう一つの大きな機能はデータのバリデー
|
||||
|
||||
これらの機能は、Marshmallowが提供するものです。Marshmallowは素晴らしいライブラリで、私も以前に何度も使ったことがあります。
|
||||
|
||||
しかし、それはPythonの型ヒントが存在する前に作られたものです。そのため、すべての<abbr title="データがどのように形成されるべきかの定義">スキーマ</abbr>を定義するためには、Marshmallowが提供する特定のユーティリティやクラスを使用する必要があります。
|
||||
しかし、それはPythonの型ヒントが存在する前に作られたものです。そのため、すべての<dfn title="データがどのように構成されるべきかの定義">スキーマ</dfn>を定義するためには、Marshmallowが提供する特定のユーティリティやクラスを使用する必要があります。
|
||||
|
||||
/// check | **FastAPI**へ与えたインスピレーション
|
||||
|
||||
@@ -153,9 +153,9 @@ APIが必要とするもう一つの大きな機能はデータのバリデー
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a>
|
||||
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
|
||||
|
||||
APIに求められる他の大きな機能として、<abbr title="Pythonデータの読み込みと変換">受信したリクエストデータのパース</abbr>があります。
|
||||
APIに求められる他の大きな機能として、<dfn title="Pythonデータへの読み込みと変換">受信したリクエストデータのパース</dfn>があります。
|
||||
|
||||
WebargsはFlaskをはじめとするいくつかのフレームワークの上にそれを提供するために作られたツールです。
|
||||
|
||||
@@ -175,7 +175,7 @@ Webargsは、Marshmallowと同じ開発者により作られました。
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://apispec.readthedocs.io/en/stable/" class="external-link" target="_blank">APISpec</a>
|
||||
### <a href="https://apispec.readthedocs.io/en/stable/" class="external-link" target="_blank">APISpec</a> { #apispec }
|
||||
|
||||
MarshmallowとWebargsはバリデーション、パース、シリアライゼーションをプラグインとして提供しています。
|
||||
|
||||
@@ -205,7 +205,7 @@ OpenAPIという、APIについてのオープンな標準をサポートして
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://flask-apispec.readthedocs.io/en/latest/" class="external-link" target="_blank">Flask-apispec</a>
|
||||
### <a href="https://flask-apispec.readthedocs.io/en/latest/" class="external-link" target="_blank">Flask-apispec</a> { #flask-apispec }
|
||||
|
||||
Webargs、Marshmallow、APISpecを連携させたFlaskプラグインです。
|
||||
|
||||
@@ -237,7 +237,7 @@ Flask-apispecはMarshmallowと同じ開発者により作成されました。
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://nestjs.com/" class="external-link" target="_blank">NestJS</a> (と<a href="https://angular.io/" class="external-link" target="_blank">Angular</a>)
|
||||
### <a href="https://nestjs.com/" class="external-link" target="_blank">NestJS</a> (と<a href="https://angular.io/" class="external-link" target="_blank">Angular</a>) { #nestjs-and-angular }
|
||||
|
||||
NestJSはAngularにインスパイアされたJavaScript (TypeScript) NodeJSフレームワークで、Pythonですらありません。
|
||||
|
||||
@@ -259,13 +259,13 @@ Angular 2にインスピレーションを受けた、統合された依存性
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://sanic.readthedocs.io/en/latest/" class="external-link" target="_blank">Sanic</a>
|
||||
### <a href="https://sanic.readthedocs.io/en/latest/" class="external-link" target="_blank">Sanic</a> { #sanic }
|
||||
|
||||
`asyncio`に基づいた、Pythonのフレームワークの中でも非常に高速なものの一つです。Flaskと非常に似た作りになっています。
|
||||
|
||||
/// note | 技術詳細
|
||||
|
||||
Pythonの`asyncio`ループの代わりに、`uvloop`が利用されています。それにより、非常に高速です。
|
||||
Pythonの`asyncio`ループの代わりに、<a href="https://github.com/MagicStack/uvloop" class="external-link" target="_blank">`uvloop`</a>が利用されています。それにより、非常に高速です。
|
||||
|
||||
`Uvicorn`と`Starlette`に明らかなインスピレーションを与えており、それらは現在オープンなベンチマークにおいてSanicより高速です。
|
||||
|
||||
@@ -279,12 +279,10 @@ Pythonの`asyncio`ループの代わりに、`uvloop`が利用されています
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://falconframework.org/" class="external-link" target="_blank">Falcon</a>
|
||||
### <a href="https://falconframework.org/" class="external-link" target="_blank">Falcon</a> { #falcon }
|
||||
|
||||
Falconはもう一つの高性能Pythonフレームワークで、ミニマムに設計されており、Hugのような他のフレームワークの基盤として動作します。
|
||||
|
||||
Pythonのウェブフレームワーク標準規格 (WSGI) を使用していますが、それは同期的であるためWebSocketなどの利用には対応していません。とはいえ、それでも非常に高い性能を持っています。
|
||||
|
||||
これは、「リクエスト」と「レスポンス」の2つのパラメータを受け取る関数を持つように設計されています。そして、リクエストからデータを「読み込み」、レスポンスにデータを「書き込み」ます。この設計のため、Python標準の型ヒントでリクエストのパラメータやボディを関数の引数として宣言することはできません。
|
||||
|
||||
そのため、データのバリデーション、シリアライゼーション、ドキュメント化は、自動的にできずコードの中で行わなければなりません。あるいは、HugのようにFalconの上にフレームワークとして実装されなければなりません。このような分断は、パラメータとして1つのリクエストオブジェクトと1つのレスポンスオブジェクトを持つというFalconのデザインにインスピレーションを受けた他のフレームワークでも起こります。
|
||||
@@ -299,7 +297,7 @@ Hug (HugはFalconをベースにしています) と一緒に、**FastAPI**が`r
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://moltenframework.com/" class="external-link" target="_blank">Molten</a>
|
||||
### <a href="https://moltenframework.com/" class="external-link" target="_blank">Molten</a> { #molten }
|
||||
|
||||
**FastAPI**を構築する最初の段階でMoltenを発見しました。そして、それは非常に似たようなアイデアを持っています。
|
||||
|
||||
@@ -323,7 +321,7 @@ Pydanticのようなデータのバリデーション、シリアライゼーシ
|
||||
|
||||
///
|
||||
|
||||
### <a href="http://www.hug.rest/" class="external-link" target="_blank">Hug</a>
|
||||
### <a href="http://www.hug.rest/" class="external-link" target="_blank">Hug</a> { #hug }
|
||||
|
||||
Hugは、Pythonの型ヒントを利用してAPIパラメータの型宣言を実装した最初のフレームワークの1つです。これは素晴らしいアイデアで、他のツールが同じことをするきっかけとなりました。
|
||||
|
||||
@@ -353,7 +351,7 @@ Hugは、**FastAPI**がヘッダーやクッキーを設定するために関数
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://github.com/encode/apistar" class="external-link" target="_blank">APIStar</a> (<= 0.5)
|
||||
### <a href="https://github.com/encode/apistar" class="external-link" target="_blank">APIStar</a> (<= 0.5) { #apistar-0-5 }
|
||||
|
||||
**FastAPI**を構築することを決める直前に、**APIStar**サーバーを見つけました。それは私が探していたものがほぼすべて含まれており、素晴らしいデザインでした。
|
||||
|
||||
@@ -401,9 +399,9 @@ APIStarはTom Christieにより開発されました。以下の開発者でも
|
||||
|
||||
///
|
||||
|
||||
## **FastAPI**が利用しているもの
|
||||
## **FastAPI**が利用しているもの { #used-by-fastapi }
|
||||
|
||||
### <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> { #pydantic }
|
||||
|
||||
Pydanticは、Pythonの型ヒントを元にデータのバリデーション、シリアライゼーション、 (JSON Schemaを使用した) ドキュメントを定義するライブラリです。
|
||||
|
||||
@@ -419,9 +417,9 @@ Marshmallowに匹敵しますが、ベンチマークではMarshmallowよりも
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a>
|
||||
### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #starlette }
|
||||
|
||||
Starletteは、軽量な<abbr title="非同期Python webを構築するための新標準">ASGI</abbr>フレームワーク/ツールキットで、高性能な非同期サービスの構築に最適です。
|
||||
Starletteは、軽量な<dfn title="非同期Python Webアプリケーションを構築するための新しい標準">ASGI</dfn>フレームワーク/ツールキットで、高性能な非同期サービスの構築に最適です。
|
||||
|
||||
非常にシンプルで直感的です。簡単に拡張できるように設計されており、モジュール化されたコンポーネントを持っています。
|
||||
|
||||
@@ -429,15 +427,14 @@ Starletteは、軽量な<abbr title="非同期Python webを構築するための
|
||||
|
||||
* 非常に感動的な性能。
|
||||
* WebSocketのサポート。
|
||||
* GraphQLのサポート。
|
||||
* インプロセスのバックグラウンドタスク。
|
||||
* 起動およびシャットダウンイベント。
|
||||
* requestsに基づいて構築されたテストクライアント。
|
||||
* HTTPXに基づいて構築されたテストクライアント。
|
||||
* CORS、GZip、静的ファイル、ストリーミング応答。
|
||||
* セッションとクッキーのサポート。
|
||||
* 100%のテストカバレッジ。
|
||||
* 100%の型注釈付きコードベース。
|
||||
* ハードな依存関係はない。
|
||||
* ハードな依存関係は少ない。
|
||||
|
||||
Starletteは、現在テストされているPythonフレームワークの中で最も速いフレームワークです。フレームワークではなくサーバーであるUvicornだけが上回っています。
|
||||
|
||||
@@ -465,7 +462,7 @@ webに関するコアな部分を全て扱います。その上に機能を追
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a>
|
||||
### <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a> { #uvicorn }
|
||||
|
||||
Uvicornは非常に高速なASGIサーバーで、uvloopとhttptoolsにより構成されています。
|
||||
|
||||
@@ -477,12 +474,12 @@ Starletteや**FastAPI**のサーバーとして推奨されています。
|
||||
|
||||
**FastAPI**アプリケーションを実行するメインのウェブサーバーである点。
|
||||
|
||||
Gunicornと組み合わせることで、非同期でマルチプロセスなサーバーを持つことがきます。
|
||||
コマンドラインオプション `--workers` を使って、非同期のマルチプロセスサーバーにできます。
|
||||
|
||||
詳細は[デプロイ](deployment/index.md){.internal-link target=_blank}の項目で確認してください。
|
||||
|
||||
///
|
||||
|
||||
## ベンチマーク と スピード
|
||||
## ベンチマーク と スピード { #benchmarks-and-speed }
|
||||
|
||||
Uvicorn、Starlette、FastAPIの違いを理解、比較、確認するには、[ベンチマーク](benchmarks.md){.internal-link target=_blank}を確認してください。
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
# 並行処理と async / await
|
||||
# 並行処理と async / await { #concurrency-and-async-await }
|
||||
|
||||
*path operation 関数*のための `async def` に関する詳細と非同期 (asynchronous) コード、並行処理 (Concurrency)、そして、並列処理 (Parallelism) の背景について。
|
||||
*path operation 関数*のための `async def` 構文に関する詳細と、非同期コード、並行処理、並列処理の背景についてです。
|
||||
|
||||
## 急いでいますか?
|
||||
## 急いでいますか? { #in-a-hurry }
|
||||
|
||||
<abbr title="too long; didn't read (長すぎて読めない人のための要約という意味のスラング)"><strong>TL;DR:</strong></abbr>
|
||||
<abbr title="too long; didn't read - 長すぎて読まなかった"><strong>TL;DR:</strong></abbr>
|
||||
|
||||
次のような、`await` を使用して呼び出すべきサードパーティライブラリを使用している場合:
|
||||
次のように `await` で呼び出すよう指示されているサードパーティライブラリを使っているなら:
|
||||
|
||||
```Python
|
||||
results = await some_library()
|
||||
```
|
||||
|
||||
以下の様に `async def` を使用して*path operation 関数*を宣言します。
|
||||
*path operation 関数*は次のように `async def` で宣言します:
|
||||
|
||||
```Python hl_lines="2"
|
||||
@app.get('/')
|
||||
@@ -23,13 +23,13 @@ async def read_results():
|
||||
|
||||
/// note | 備考
|
||||
|
||||
`async def` を使用して作成された関数の内部でしか `await` は使用できません。
|
||||
`await` は `async def` で作られた関数の内部でしか使えません。
|
||||
|
||||
///
|
||||
|
||||
---
|
||||
|
||||
データベース、API、ファイルシステムなどと通信し、`await` の使用をサポートしていないサードパーティライブラリ (現在のほとんどのデータベースライブラリに当てはまります) を使用している場合、次の様に、単に `def` を使用して通常通り *path operation 関数* を宣言してください:
|
||||
データベース、API、ファイルシステムなどと通信しつつ `await` の使用をサポートしていないサードパーティライブラリ (現在のところ多くのデータベースライブラリが該当します) を使っている場合、*path operation 関数*は通常どおり `def` で宣言してください:
|
||||
|
||||
```Python hl_lines="2"
|
||||
@app.get('/')
|
||||
@@ -40,272 +40,307 @@ def results():
|
||||
|
||||
---
|
||||
|
||||
アプリケーションが (どういうわけか) 他の何とも通信せず、応答を待つ必要がない場合は、`async def` を使用して下さい。
|
||||
アプリケーションが (何らかの理由で) ほかの何とも通信せず応答を待つ必要がないなら、`await` を内部で使わなくても `async def` を使ってください。
|
||||
|
||||
---
|
||||
|
||||
よく分からない場合は、通常の `def` を使用して下さい。
|
||||
よく分からない場合は、通常の `def` を使ってください。
|
||||
|
||||
---
|
||||
|
||||
**備考**: *path operation 関数*に必要なだけ `def` と `async def` を混在させ、それぞれに最適なオプションを使用して定義できます。それに応じてFastAPIは正しい処理を行います。
|
||||
**備考**: 必要に応じて *path operation 関数* では `def` と `async def` を混在させ、それぞれに最適な選択肢で定義できます。FastAPI は適切に処理します。
|
||||
|
||||
とにかく、上記のいずれの場合でもFastAPIは非同期で動作し、非常に高速です。
|
||||
いずれの場合でも、FastAPI は非同期で動作し非常に高速です。
|
||||
|
||||
しかし、上記のステップに従うことで、パフォーマンスの最適化を行えます。
|
||||
ただし上記の手順に従うことで、さらにパフォーマンス最適化が可能になります。
|
||||
|
||||
## 技術詳細
|
||||
## 技術詳細 { #technical-details }
|
||||
|
||||
現代版のPythonは「**非同期コード**」を、「**コルーチン**」と称されるものを利用してサポートしています。これは **`async` と `await`** 構文を用います。
|
||||
モダンな Python は **「非同期コード」** を **「コルーチン」** と呼ばれる仕組みでサポートしており、構文は **`async` と `await`** です。
|
||||
|
||||
次のセクションで、フレーズ内のパーツを順に見ていきましょう:
|
||||
以下のセクションで、このフレーズをパーツごとに見ていきます:
|
||||
|
||||
* **非同期コード**
|
||||
* **`async` と `await`**
|
||||
* **コルーチン**
|
||||
|
||||
## 非同期コード
|
||||
## 非同期コード { #asynchronous-code }
|
||||
|
||||
非同期コードとは、言語💬がコード内のどこかで、コンピュータ/プログラム🤖に *他の何か* がどこか別の箇所で終了するのを待つように伝える手段を持っていることを意味します。*他の何か* は「遅いファイル📝」と呼ばれているとしましょう.
|
||||
非同期コードとは、言語 💬 がコードのどこかの時点で、コンピュータ/プログラム 🤖 に「どこか別のところで終わるまで、別の何か」を待つ必要があると伝える手段を持っている、ということです。その「別の何か」を「遅いファイル」📝 と呼ぶことにしましょう。
|
||||
|
||||
したがって、コンピュータは「遅いファイル📝」が終了するまで、他の処理ができます。
|
||||
その間、コンピュータは「遅いファイル」📝 が終わるまで、他の作業を進められます。
|
||||
|
||||
コンピュータ/プログラム🤖は再び待機する機会があるときや、その時点で行っていたすべての作業が完了するたびに戻ってきます。そして、必要な処理をしながら、コンピュータ/プログラム🤖が待っていた処理のどれかが終わっているかどうか確認します。
|
||||
その後、コンピュータ/プログラム 🤖 は、また待つ機会が来たときや、その時点で抱えていた作業をすべて終えたときに戻ってきます。そして、待っていたタスクのどれかが終わっていないか確認し、必要な処理を実行します。
|
||||
|
||||
次に、それ🤖が最初のタスク (要するに、先程の「遅いファイル📝」)を終わらせて、そのタスクの結果を使う必要がある処理を続けます。
|
||||
次に、最初に終わったタスク (たとえば「遅いファイル」📝) を取り、続きの処理を行います。
|
||||
|
||||
この「他の何かを待つ」とは、通常以下の様なものを待つような (プロセッサとRAMメモリの速度に比べて) 相対的に「遅い」<abbr title="インプットとアウトプット">I/O</abbr> 操作を指します:
|
||||
この「別の何かを待つ」は、通常 <abbr title="Input and Output - 入出力">I/O</abbr> 操作を指し、(プロセッサや RAM の速度に比べて) 相対的に「遅い」待機を伴います。例えば次のようなものです:
|
||||
|
||||
* ネットワーク経由でクライアントから送信されるデータ
|
||||
* ネットワーク経由でクライアントが受信する、プログラムから送信されたデータ
|
||||
* システムによって読み取られ、プログラムに渡されるディスク内のファイル内容
|
||||
* プログラムがシステムに渡して、ディスクに書き込む内容
|
||||
* リモートAPI操作
|
||||
* クライアントからネットワーク経由でデータが送られてくるのを待つ
|
||||
* プログラムが送信したデータをクライアントがネットワーク経由で受け取るのを待つ
|
||||
* ディスク上のファイル内容がシステムにより読み取られ、プログラムに渡されるのを待つ
|
||||
* プログラムがシステムに渡した内容がディスクに書き込まれるのを待つ
|
||||
* リモート API 操作
|
||||
* データベース操作の完了
|
||||
* データベースクエリが結果を返すこと
|
||||
* など。
|
||||
* データベースクエリが結果を返すのを待つ
|
||||
* など
|
||||
|
||||
実行時間のほとんどが<abbr title="インプットとアウトプット">I/O</abbr> 操作の待ち時間が占めるため、このような操作を「I/O バウンド」操作と言います。
|
||||
実行時間の大半が <abbr title="Input and Output - 入出力">I/O</abbr> 操作の待ち時間に費やされるため、これらは「I/O バウンド」な操作と呼ばれます。
|
||||
|
||||
コンピュータ/プログラムがこのような遅いタスクと「同期 (タスクの結果を取得して作業を続行するために、何もせずに、タスクが完了する瞬間を正確に待つ)」する必要がないため、「非同期」と呼ばれます。
|
||||
「非同期」と呼ばれるのは、コンピュータ/プログラムがその遅いタスクと「同期」(タスクがちょうど終わる瞬間を、何もせずに待つ) する必要がないからです。結果を受け取って処理を続けるために、空待ちする必要がありません。
|
||||
|
||||
その代わりに、「非同期」システムであることにより、いったん終了すると、タスクは、コンピュータ/プログラムが既に開始した処理がすべて完了するのをほんの少し (数マイクロ秒) 待って、結果を受け取りに戻ってきます。そして、処理を継続します。
|
||||
代わりに「非同期」システムでは、タスクが終わったら、コンピュータ/プログラムが取りかかっている作業が終わるまで (数マイクロ秒ほど) 少し待ち、結果を受け取りに戻って処理を続けられます。
|
||||
|
||||
「同期」の場合 (「非同期」とは異なり)、「シーケンシャル」という用語もよく使用されます。これは、コンピュータ/プログラムがすべてのステップを (待機が伴う場合でも別のタスクに切り替えることなく) 順番に実行するためです。
|
||||
「非同期」と対になる「同期」は、「シーケンシャル」と呼ばれることもあります。待機が含まれていても、別のタスクに切り替える前にコンピュータ/プログラムが手順を順番に実行するためです。
|
||||
|
||||
### 並行処理とハンバーガー
|
||||
### 並行処理とハンバーガー { #concurrency-and-burgers }
|
||||
|
||||
上記の**非同期**コードのアイデアは、**「並行処理」**と呼ばれることもあります。 **「並列処理」**とは異なります。
|
||||
上で説明した**非同期**コードの考え方は、**「並行処理」** と呼ばれることもあります。これは **「並列処理」** とは異なります。
|
||||
|
||||
**並行処理**と**並列処理**はどちらも「多かれ少なかれ同時に発生するさまざまなこと」に関連しています。
|
||||
**並行処理** も **並列処理** も、「複数のことがだいたい同時に起きる」ことに関係します。
|
||||
|
||||
ただし、*並行処理*と*並列処理*の詳細はまったく異なります。
|
||||
ただし、*並行処理* と *並列処理* の詳細はかなり異なります。
|
||||
|
||||
違いを確認するには、ハンバーガーに関する次の物語を想像してみてください:
|
||||
違いを見るために、ハンバーガーに関する次の物語を想像してみてください。
|
||||
|
||||
### 並行ハンバーガー
|
||||
### 並行ハンバーガー { #concurrent-burgers }
|
||||
|
||||
ファストフード🍔を食べようと、好きな人😍とレジに並んでおり、レジ係💁があなたの前にいる人達の注文を受けつけています。
|
||||
あなたは好きな人とファストフードを買いに行き、前の人たちの注文をレジ係が受ける間、列に並びます。😍
|
||||
|
||||
それからあなたの番になり、好きな人😍と自分のために、2つの非常に豪華なハンバーガー🍔を注文します。
|
||||
<img src="/img/async/concurrent-burgers/concurrent-burgers-01.png" class="illustration">
|
||||
|
||||
料金を支払います💸。
|
||||
やがてあなたの番になり、好きな人と自分のために、とても豪華なハンバーガーを2つ注文します。🍔🍔
|
||||
|
||||
レジ係💁はキッチンの男👨🍳に向かって、あなたのハンバーガー🍔を準備しなければならないと伝えるために何か言いました (彼は現在、前のお客さんの商品を準備していますが)。
|
||||
<img src="/img/async/concurrent-burgers/concurrent-burgers-02.png" class="illustration">
|
||||
|
||||
レジ係💁はあなたに番号札を渡します。
|
||||
レジ係はキッチンの料理人に、あなたのハンバーガーを用意するよう声をかけます (料理人はいま前のお客さんの分を作っています)。
|
||||
|
||||
待っている間、好きな人😍と一緒にテーブルを選んで座り、好きな人😍と長い間話をします (注文したハンバーガーは非常に豪華で、準備に少し時間がかかるので✨🍔✨)。
|
||||
<img src="/img/async/concurrent-burgers/concurrent-burgers-03.png" class="illustration">
|
||||
|
||||
ハンバーガー🍔を待ちながら好きな人😍とテーブルに座っている間、あなたの好きな人がなんて素晴らしく、かわいくて頭がいいんだと✨😍✨惚れ惚れしながら時間を費やすことができます。
|
||||
支払いをします。💸
|
||||
|
||||
好きな人😍と話しながら待っている間、ときどき、カウンターに表示されている番号をチェックして、自分の番かどうかを確認します。
|
||||
レジ係はあなたに番号札を渡します。
|
||||
|
||||
その後、ついにあなたの番になりました。カウンターに行き、ハンバーガー🍔を手に入れてテーブルに戻ります。
|
||||
<img src="/img/async/concurrent-burgers/concurrent-burgers-04.png" class="illustration">
|
||||
|
||||
あなたとあなたの好きな人😍はハンバーガー🍔を食べて、楽しい時間を過ごします✨。
|
||||
待っている間、好きな人とテーブルに移動して座り、(豪華なハンバーガーは時間がかかるので) しばらく話します。
|
||||
|
||||
テーブルで待っている間、好きな人がどれだけ素敵で、かわいくて、頭が良いかを眺めて時間を過ごせます ✨😍✨。
|
||||
|
||||
<img src="/img/async/concurrent-burgers/concurrent-burgers-05.png" class="illustration">
|
||||
|
||||
時々カウンターの表示を見て、自分の番号になっているか確認します。
|
||||
|
||||
やがてあなたの番になります。カウンターに行き、ハンバーガーを受け取り、テーブルに戻ります。
|
||||
|
||||
<img src="/img/async/concurrent-burgers/concurrent-burgers-06.png" class="illustration">
|
||||
|
||||
あなたと好きな人はハンバーガーを食べて、楽しい時間を過ごします。✨
|
||||
|
||||
<img src="/img/async/concurrent-burgers/concurrent-burgers-07.png" class="illustration">
|
||||
|
||||
/// info | 情報
|
||||
|
||||
美しいイラストは <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a> によるものです。🎨
|
||||
|
||||
///
|
||||
|
||||
---
|
||||
|
||||
上記のストーリーで、あなたがコンピュータ/プログラム🤖だと想像してみてください。
|
||||
この物語で、あなた自身がコンピュータ/プログラム 🤖 だと想像してみてください。
|
||||
|
||||
列にいる間、あなたはアイドル状態です😴。何も「生産的」なことをせず、ただ自分の番を待っています。しかし、レジ係💁は注文を受け取るだけなので (商品の準備をしているわけではない)、列は高速です。したがって、何も問題ありません。
|
||||
列にいる間は、何も「生産的」なことをせず、自分の番を待つだけのアイドル状態 😴 です。ただしレジ係は注文を取るだけ (作りはしない) なので列は速く進み、問題ありません。
|
||||
|
||||
それから、あなたの番になったら、実に「生産的な」作業を行います🤓、メニューを確認し、欲しいものを決め、好きな人😍の欲しいものを聞き、料金を支払い💸、現金またはカードを正しく渡したか確認し、正しく清算されたことを確認し、注文が正しく通っているかなどを確認します。
|
||||
あなたの番になると、実際に「生産的」な作業をします。メニューを見て注文を決め、好きな人の分も確認し、支払い、正しい紙幣/カードを渡したか、正しく決済されたか、注文内容が正しいかなどを確認します。
|
||||
|
||||
しかし、ハンバーガー🍔をまだできていないので、ハンバーガーの準備ができるまで待機🕙する必要があるため、レジ係💁との作業は「一時停止⏸」になります。
|
||||
しかし、ハンバーガーはまだ出来上がっていないので、レジ係とのやり取りは「一時停止」⏸ になります。ハンバーガーができるまで待つ 🕙 必要があるからです。
|
||||
|
||||
しかし、カウンターから離れて、番号札を持ってテーブルに座っているときは、注意を好きな人😍に切り替えて🔀、その上で「仕事⏯🤓」を行なえます。その後、好きな人😍といちゃつくかのような、非常に「生産的な🤓」ことを再び行います。
|
||||
ただし、番号札を持ってカウンターから離れテーブルに座れば、注意を好きな人に切り替え 🔀、「その作業」⏯ 🤓 に取り組めます。好きな人といちゃつくという、とても「生産的」🤓 なことがまたできます。
|
||||
|
||||
次に、レジ係💁は、「ハンバーガーの準備ができました🍔」と言って、カウンターのディスプレイに番号を表示しますが、表示番号があなたの番号に変わっても、すぐに狂ったように飛んで行くようなことはありません。あなたは自分の番号札を持っていって、他の人も自分の番号札があるので、あなたのハンバーガー🍔を盗む人がいないことは知っています。
|
||||
レジ係 💁 がカウンターの表示にあなたの番号を出して「ハンバーガーができました」と知らせても、あなたは表示が切り替わった瞬間に飛び跳ねたりしません。自分の番号札があり、他の人にもそれぞれ番号札があるので、ハンバーガーを盗られることはないと知っているからです。
|
||||
|
||||
なので、あなたは好きな人😍が話し終えるのを待って (現在の仕事⏯ / 処理中のタスクを終了します🤓)、優しく微笑んで、ハンバーガーを貰ってくるねと言います⏸。
|
||||
だから、好きな人の話が終わるのを待ち (現在の作業 ⏯ / 処理中のタスクを完了し 🤓)、微笑んで「ハンバーガー取ってくるね」と言います ⏸。
|
||||
|
||||
次に、カウンターへ、いまから完了する最初のタスク⏯へ向かい、ハンバーガー🍔を受け取り、感謝の意を表して、テーブルに持っていきます。これで、カウンターとのやり取りのステップ/タスクが完了しました⏹。これにより、「ハンバーガーを食べる🔀⏯」という新しいタスクが作成されます。しかし、前の「ハンバーガーを取得する」というタスクは終了しました⏹。
|
||||
それからカウンターへ行き 🔀、いま完了した初期のタスク ⏯ に戻って、ハンバーガーを受け取り、礼を言ってテーブルに持っていきます。これでカウンターとのやり取りというステップ/タスクは完了 ⏹ です。その結果として「ハンバーガーを食べる」🔀 ⏯ という新しいタスクが生まれますが、先の「ハンバーガーを受け取る」タスクは完了 ⏹ しています。
|
||||
|
||||
### 並列ハンバーガー
|
||||
### 並列ハンバーガー { #parallel-burgers }
|
||||
|
||||
これらが「並行ハンバーガー」ではなく、「並列ハンバーガー」であるとしましょう。
|
||||
今度は、これが「並行ハンバーガー」ではなく「並列ハンバーガー」だと想像しましょう。
|
||||
|
||||
あなたは好きな人😍と並列ファストフード🍔を買おうとしています。
|
||||
あなたは好きな人と「並列」ファストフードを買いに行きます。
|
||||
|
||||
列に並んでいますが、何人かの料理人兼、レジ係 (8人としましょう) 👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳があなたの前にいる人達の注文を受けつけています。
|
||||
複数のレジ係 (例えば 8 人) が同時に料理人でもあり、前の人たちの注文を受けています。
|
||||
|
||||
8人のレジ係がそれぞれ自分で注文を受けるや否や、次の注文を受ける前にハンバーガーを準備するので、あなたの前の人達はカウンターを離れずに、ハンバーガー🍔ができるのを待っています🕙。
|
||||
8 人のレジ係はそれぞれ、次の注文を取る前にすぐに調理に取りかかるため、あなたの前の人たちはカウンターを離れず、ハンバーガーができるのを待っています。
|
||||
|
||||
それからいよいよあなたの番になり、好きな人😍と自分のために、2つの非常に豪華なハンバーガー🍔を注文します。
|
||||
<img src="/img/async/parallel-burgers/parallel-burgers-01.png" class="illustration">
|
||||
|
||||
料金を支払います💸。
|
||||
ようやくあなたの番になり、好きな人と自分のために豪華なハンバーガーを 2 つ注文します。
|
||||
|
||||
レジ係はキッチンに行きます👨🍳。
|
||||
支払いをします 💸。
|
||||
|
||||
あなたはカウンターの前に立って待ちます🕙。番号札がないので誰もあなたよりも先にハンバーガー🍔を取らないようにします。
|
||||
<img src="/img/async/parallel-burgers/parallel-burgers-02.png" class="illustration">
|
||||
|
||||
あなたと好きな人😍は忙しいので、誰もあなたの前に来させませんし、あなたのハンバーガーが到着したとき🕙に誰にも取ることを許しません。あなたは好きな人に注意を払えません😞。
|
||||
レジ係はキッチンに向かいます。
|
||||
|
||||
これは「同期」作業であり、レジ係/料理人👨🍳と「同期」します。レジ係/料理人👨🍳がハンバーガー🍔を完成させてあなたに渡すまで待つ🕙必要があり、ちょうどその完成の瞬間にそこにいる必要があります。そうでなければ、他の誰かに取られるかもしれません。
|
||||
番号札がないため、他の誰かに先に取られないよう、カウンターの前で立って待ちます 🕙。
|
||||
|
||||
その後、カウンターの前で長い時間待ってから🕙、ついにレジ係/料理人👨🍳がハンバーガー🍔を渡しに戻ってきます。
|
||||
<img src="/img/async/parallel-burgers/parallel-burgers-03.png" class="illustration">
|
||||
|
||||
ハンバーガー🍔を取り、好きな人😍とテーブルに行きます。
|
||||
あなたと好きな人は、誰にも割り込まれずハンバーガーが来たらすぐ受け取れるよう見張っているので、好きな人に注意を向けられません。😞
|
||||
|
||||
ただ食べるだけ、それでおしまいです。🍔⏹。
|
||||
これは「同期」的な作業です。レジ係/料理人 👨🍳 と「同期」しています。レジ係/料理人 👨🍳 がハンバーガーを作り終えて手渡すその瞬間に、待って 🕙 その場にいなければなりません。そうでないと他の誰かに取られるかもしれません。
|
||||
|
||||
ほとんどの時間、カウンターの前で待つのに費やされていたので🕙、あまり話したりいちゃつくことはありませんでした😞。
|
||||
<img src="/img/async/parallel-burgers/parallel-burgers-04.png" class="illustration">
|
||||
|
||||
長い時間 🕙 カウンター前で待った後、ようやくレジ係/料理人 👨🍳 がハンバーガーを持って戻ってきます。
|
||||
|
||||
<img src="/img/async/parallel-burgers/parallel-burgers-05.png" class="illustration">
|
||||
|
||||
ハンバーガーを受け取り、好きな人とテーブルに行きます。
|
||||
|
||||
食べて、おしまいです。⏹
|
||||
|
||||
<img src="/img/async/parallel-burgers/parallel-burgers-06.png" class="illustration">
|
||||
|
||||
ほとんどの時間をカウンター前で待つ 🕙 のに費やしたため、あまり話したり、いちゃついたりできませんでした。😞
|
||||
|
||||
/// info | 情報
|
||||
|
||||
美しいイラストは <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a> によるものです。🎨
|
||||
|
||||
///
|
||||
|
||||
---
|
||||
|
||||
この並列ハンバーガーのシナリオでは、あなたは2つのプロセッサを備えたコンピュータ/プログラム🤖 (あなたとあなたの好きな人😍) であり、両方とも待機🕙していて、彼らは「カウンターで待機🕙」することに専念しています⏯。
|
||||
この「並列ハンバーガー」のシナリオでは、あなたは 2 つのプロセッサ (あなたと好きな人) を持つコンピュータ/プログラム 🤖 で、どちらも長い間 🕙「カウンターでの待機」に注意 ⏯ を専念しています。
|
||||
|
||||
ファストフード店には8つのプロセッサ (レジ係/料理人) 👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳があります。一方、並行ハンバーガー店には2人 (レジ係と料理人) 💁👨🍳しかいなかったかもしれません。
|
||||
ファストフード店には 8 個のプロセッサ (レジ係/料理人) があります。一方、並行ハンバーガーの店には (レジ係 1、人、料理人 1 人の) 2 個しかなかったかもしれません。
|
||||
|
||||
しかし、それでも、最終的な体験は最高ではありません😞。
|
||||
それでも、最終的な体験は最良とは言えません。😞
|
||||
|
||||
---
|
||||
|
||||
これは、ハンバーガー🍔の話と同等な話になります。
|
||||
これはハンバーガーにおける並列版の物語です。🍔
|
||||
|
||||
より「現実的な」例として、銀行を想像してみてください。
|
||||
|
||||
最近まで、ほとんどの銀行は複数の窓口👨💼👨💼👨💼👨💼に、行列🕙🕙🕙🕙🕙🕙🕙🕙ができていました。
|
||||
つい最近まで、ほとんどの銀行には複数の窓口係 👨💼👨💼👨💼👨💼 と長い行列 🕙🕙🕙🕙🕙🕙🕙🕙 がありました。
|
||||
|
||||
すべての窓口で、次々と、一人の客とすべての作業を行います👨💼⏯.
|
||||
各窓口係が、一人ずつ、すべての作業を順番に行います 👨💼⏯。
|
||||
|
||||
その上、長時間、列に並ばなければいけません🕙。そうしないと、順番が回ってきません。
|
||||
そして、長時間 🕙 行列で待たなければ順番を失います。
|
||||
|
||||
銀行🏦での用事にあなたの好きな人😍を連れて行きたくはないでしょう。
|
||||
銀行の用事 🏦 に、好きな人 😍 を連れて行きたいとは思わないでしょう。
|
||||
|
||||
### ハンバーガーのまとめ
|
||||
### ハンバーガーのまとめ { #burger-conclusion }
|
||||
|
||||
この「好きな人とのファストフードハンバーガー」のシナリオでは、待機🕙が多いため、並行システム⏸🔀⏯を使用する方がはるかに理にかなっています。
|
||||
この「好きな人とファストフード」のシナリオでは、待ち時間 🕙 が多いため、並行システム ⏸🔀⏯ を使う方がはるかに理にかなっています。
|
||||
|
||||
これは、ほとんどのWebアプリケーションに当てはまります。
|
||||
これは、ほとんどの Web アプリケーションにも当てはまります。
|
||||
|
||||
多くのユーザーがいますが、サーバーは、あまり強くない回線でのリクエストの送信を待機🕙しています。
|
||||
とても多くのユーザーがいますが、サーバは彼らのあまり速くない回線からリクエストが届くのを待ち 🕙、
|
||||
|
||||
そして、レスポンスが返ってくるのをもう一度待機🕙します。
|
||||
その後、レスポンスが戻ってくるのをまた待ちます 🕙。
|
||||
|
||||
この「待機🕙」はマイクロ秒単位ですが、それでも、すべて合算すると、最終的にはかなり待機することになります。
|
||||
この「待ち」🕙 はマイクロ秒単位で測られますが、すべてを合計すると、結局かなりの待ちになります。
|
||||
|
||||
これが、Web APIへの非同期⏸🔀⏯コードの利用が理にかなっている理由です。
|
||||
だからこそ、Web API には非同期 ⏸🔀⏯ コードを使うのが理にかなっています。
|
||||
|
||||
ほとんどの既存の人気のあるPythonフレームワーク (FlaskやDjangoを含む) は、Pythonの新しい非同期機能ができる前に作成されました。したがって、それらをデプロイする方法は、並列実行と、新機能ほど強力ではない古い形式の非同期実行をサポートします。
|
||||
これが、NodeJS を人気にした要因 (NodeJS 自体は並列ではありません) であり、プログラミング言語としての Go の強みでもあります。
|
||||
|
||||
しかし、WebSocketのサポートを追加するために、非同期Web Python (ASGI) の主な仕様はDjangoで開発されました。
|
||||
そして、それが **FastAPI** で得られるパフォーマンスの水準です。
|
||||
|
||||
そのような非同期性がNodeJSを人気にした理由です (NodeJSは並列ではありませんが)。そして、プログラミング言語としてのGoの強みでもあります。
|
||||
さらに、並列性と非同期性を同時に活用できるため、テストされた多くの NodeJS フレームワークより高い性能を発揮し、C に近いコンパイル言語である Go と同等の性能になります <a href="https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1" class="external-link" target="_blank">(すべて Starlette のおかげです)</a>。
|
||||
|
||||
そして、それは**FastAPI**で得られるパフォーマンスと同じレベルです。
|
||||
### 並行処理は並列処理より優れている? { #is-concurrency-better-than-parallelism }
|
||||
|
||||
また、並列処理と非同期処理を同時に実行できるため、テスト済みのほとんどのNodeJSフレームワークよりも高く、Goと同等のパフォーマンスが得られます。Goは、Cに近いコンパイル言語です <a href="https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1" class="external-link" target="_blank">(Starletteに感謝します)</a>。
|
||||
いいえ!それがこの話の教訓ではありません。
|
||||
|
||||
### 並行は並列よりも優れていますか?
|
||||
並行処理は並列処理とは異なります。そして多くの待ち時間を伴う**特定の**シナリオでは優れています。そのため、一般に Web アプリ開発では並列処理よりはるかに適しています。しかし、すべてに対して最良というわけではありません。
|
||||
|
||||
いや!それはこの話の教訓ではありません。
|
||||
バランスを取るために、次の短い物語を想像してください。
|
||||
|
||||
並行処理は並列処理とは異なります。多くの待機を伴う**特定の**シナリオに適しています。そのため、一般に、Webアプリケーション開発では並列処理よりもはるかに優れています。しかし、すべてに対してより良いというわけではありません。
|
||||
> 大きくて汚れた家を掃除しなければならない。
|
||||
|
||||
なので、バランスをとるために、次の物語を想像して下さい:
|
||||
|
||||
> あなたは大きくて汚れた家を掃除する必要があります。
|
||||
|
||||
*はい、以上です*。
|
||||
*はい、これで物語は全部です*。
|
||||
|
||||
---
|
||||
|
||||
待機🕙せず、家の中の複数の場所でたくさんの仕事をするだけです。
|
||||
どこにも待ち 🕙 はなく、家の複数箇所で大量の作業があるだけです。
|
||||
|
||||
あなたはハンバーガーの例のように、最初はリビングルーム、次にキッチンのように順番にやっていくことができますが、何かを待機🕙しているわけではなく、ただひたすらに掃除をするだけで、順番は何にも影響しません。
|
||||
ハンバーガーの例のように順番を決めて、まずリビング、次にキッチン、と進めてもよいのですが、何かを待つ 🕙 わけではなく、ひたすら掃除するだけなので、順番は何も影響しません。
|
||||
|
||||
順番の有無に関係なく (並行に) 同じ時間がかかり、同じ量の作業が行われることになるでしょう。
|
||||
順番の有無 (並行性の有無) に関係なく、終了までに同じ時間がかかり、同じ作業量をこなすことになります。
|
||||
|
||||
しかし、この場合、8人の元レジ係/料理人/現役清掃員👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳👨🍳を手配できて、それぞれ (さらにあなたも) が家の別々の場所を掃除できれば、追加の助けを借りて、すべての作業を**並列**に行い、はるかに早く終了できるでしょう。
|
||||
しかしこの場合、8 人の元レジ係/料理人/現清掃員を連れてきて、それぞれ (あなたも加えて) 家の別々のエリアを掃除できれば、**並列** に作業でき、より早く終えられます。
|
||||
|
||||
このシナリオでは、清掃員 (あなたを含む) のそれぞれがプロセッサとなり、それぞれの役割を果たします。
|
||||
このシナリオでは、各清掃員 (あなたを含む) がプロセッサであり、それぞれが自分の役割を果たします。
|
||||
|
||||
また、実行時間のほとんどは (待機ではなく) 実際の作業に費やされ、コンピュータでの作業は<abbr title="Central Processing Unit">CPU</abbr>によって行われます。これらの問題は「CPUバウンド」と言います。
|
||||
そして実行時間の大半は (待ちではなく) 実作業が占め、コンピュータでの作業は <abbr title="Central Processing Unit - 中央処理装置">CPU</abbr> によって行われます。これらの問題は「CPU バウンド」と呼ばれます。
|
||||
|
||||
---
|
||||
|
||||
CPUバウンド操作の一般的な例は、複雑な数学処理が必要なものです。
|
||||
CPU バウンドな操作の一般的な例は、複雑な数値処理が必要なものです。
|
||||
|
||||
例えば:
|
||||
|
||||
* **オーディオ** や **画像処理**。
|
||||
* **コンピュータビジョン**: 画像は数百万のピクセルで構成され、各ピクセルには3つの値/色があり、通常、これらのピクセルで何かを同時に計算する必要がある処理。
|
||||
* **機械学習**: 通常、多くの「行列」と「ベクトル」の乗算が必要です。巨大なスプレッドシートに数字を入れて、それを同時に全部掛け合わせることを考えてみてください。
|
||||
* **ディープラーニング**: これは機械学習のサブフィールドであるため、同じことが当てはまります。乗算する数字がある単一のスプレッドシートではなく、それらの膨大な集合で、多くの場合、それらのモデルを構築および/または使用するために特別なプロセッサを使用します。
|
||||
* **コンピュータビジョン**: 画像は数百万のピクセルで構成され、各ピクセルには 3 つの値/色があり、通常、それらのピクセル上で同時に何かを計算する必要があります。
|
||||
* **機械学習**: 多くの「行列」や「ベクトル」の乗算が必要になります。巨大なスプレッドシートに数字が入っていて、それらを同時にすべて掛け合わせることを想像してください。
|
||||
* **ディープラーニング**: 機械学習のサブフィールドなので同様です。掛け合わせる数字が 1 つのスプレッドシートではなく膨大な集合であり、多くの場合、それらのモデルを構築/利用するための特別なプロセッサを使います。
|
||||
|
||||
### 並行処理 + 並列処理: Web + 機械学習
|
||||
### 並行処理 + 並列処理: Web + 機械学習 { #concurrency-parallelism-web-machine-learning }
|
||||
|
||||
**FastAPI**を使用すると、Web開発で非常に一般的な並行処理 (NodeJSの主な魅力と同じもの) を利用できます。
|
||||
**FastAPI** では、Web 開発で非常に一般的な並行処理 (NodeJS の主な魅力と同じ) を活用できます。
|
||||
|
||||
ただし、機械学習システムのような **CPUバウンド** ワークロードに対して、並列処理とマルチプロセッシング (複数のプロセスが並列で実行される) の利点を活用することもできます。
|
||||
同時に、機械学習システムのような **CPU バウンド** なワークロードに対して、並列処理やマルチプロセッシング (複数プロセスの並列実行) の利点も活用できます。
|
||||
|
||||
さらに、Pythonが**データサイエンス**、機械学習、特にディープラーニングの主要言語であるという単純な事実により、FastAPIはデータサイエンス/機械学習のWeb APIおよびアプリケーション (他の多くのアプリケーションとの) に非常によく適合しています。
|
||||
さらに、Python が **データサイエンス**、機械学習、特にディープラーニングの主要言語であるという事実も相まって、FastAPI はデータサイエンス/機械学習の Web API やアプリケーション (ほか多数) に非常に適しています。
|
||||
|
||||
本番環境でこの並列処理を実現する方法については、[デプロイ](deployment/index.md){.internal-link target=_blank}に関するセクションを参照してください。
|
||||
本番環境でこの並列性を実現する方法は、[デプロイ](deployment/index.md){.internal-link target=_blank} のセクションを参照してください。
|
||||
|
||||
## `async` と `await`
|
||||
## `async` と `await` { #async-and-await }
|
||||
|
||||
現代的なバージョンのPythonには、非同期コードを定義する非常に直感的な方法があります。これにより、通常の「シーケンシャル」コードのように見え、適切なタイミングで「待機」します。
|
||||
モダンな Python には、非同期コードをとても直感的に定義する方法があります。これにより、通常の「シーケンシャル」なコードのように書けて、適切なタイミングで「待ち」を行ってくれます。
|
||||
|
||||
結果を返す前に待機する必要があり、これらの新しいPython機能をサポートする操作がある場合は、次のようにコーディングできます。
|
||||
結果を返す前に待ちが必要で、これらの新しい Python 機能をサポートしている操作がある場合、次のように書けます。
|
||||
|
||||
```Python
|
||||
burgers = await get_burgers(2)
|
||||
```
|
||||
|
||||
カギは `await` です。結果を `burgers`に保存する前に、`get_burgers(2)`の処理🕙の完了を待つ⏸必要があることをPythonに伝えます。これでPythonは、その間に (別のリクエストを受信するなど) 何か他のことができる🔀⏯ことを知ります。
|
||||
ここでの鍵は `await` です。`burgers` に結果を保存する前に、`get_burgers(2)` がやるべきことを終えるのを ⏸ 待つ 🕙 ように Python に伝えます。これにより Python は、その間に (別のリクエストを受け取るなど) ほかのことを 🔀 ⏯ できると分かります。
|
||||
|
||||
`await` が機能するためには、非同期処理をサポートする関数内にある必要があります。これは、`async def` で関数を宣言するだけでよいです:
|
||||
`await` が機能するには、この非同期性をサポートする関数の内部でなければなりません。そのためには `async def` で宣言します:
|
||||
|
||||
```Python hl_lines="1"
|
||||
async def get_burgers(number: int):
|
||||
# ハンバーガーを作成するために非同期処理を実行
|
||||
# ハンバーガーを作るために非同期の処理を行う
|
||||
return burgers
|
||||
```
|
||||
|
||||
...`def` のかわりに:
|
||||
...`def` の代わりに:
|
||||
|
||||
```Python hl_lines="2"
|
||||
# 非同期ではない
|
||||
# これは非同期ではない
|
||||
def get_sequential_burgers(number: int):
|
||||
# ハンバーガーを作成するためにシーケンシャルな処理を実行
|
||||
# ハンバーガーを作るためにシーケンシャルな処理を行う
|
||||
return burgers
|
||||
```
|
||||
`async def` を使用すると、Pythonにその関数内で `await` 式 (その関数の実行を「一時停止⏸」し、結果が戻るまで他の何かを実行🔀する) を認識しなければならないと伝えることができます。
|
||||
|
||||
`async def` 関数を呼び出すときは、「await」しなければなりません。したがって、これは機能しません:
|
||||
`async def` を使うと、Python はその関数内で `await` 式に注意し、関数の実行を「一時停止」⏸ してほかのことをしに行き 🔀、戻ってくることができると分かります。
|
||||
|
||||
`async def` な関数を呼ぶときは「await」しなければなりません。したがって、次は動きません:
|
||||
|
||||
```Python
|
||||
# get_burgersはasync defで定義されているので動作しない
|
||||
# 動きません。get_burgers は async def で定義されています
|
||||
burgers = get_burgers(2)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
したがって、 `await` で呼び出すことができるライブラリを使用している場合は、次のように `async def` を使用して、それを使用する*path operation 関数*を作成する必要があります:
|
||||
そのため、`await` で呼べると謳っているライブラリを使っている場合は、それを使う *path operation 関数* を `async def` で作る必要があります。例えば:
|
||||
|
||||
```Python hl_lines="2-3"
|
||||
@app.get('/burgers')
|
||||
@@ -314,86 +349,96 @@ async def read_burgers():
|
||||
return burgers
|
||||
```
|
||||
|
||||
### より発展的な技術詳細
|
||||
### より発展的な技術詳細 { #more-technical-details }
|
||||
|
||||
`await` は `async def` で定義された関数内でのみ使用できることがわかったかと思います。
|
||||
`await` は `async def` で定義された関数の内部でしか使えないことに気づいたかもしれません。
|
||||
|
||||
しかし同時に、`async def` で定義された関数は「awaitされる」必要があります。なので、`async def` を持つ関数は、`async def` で定義された関数内でのみ呼び出せます。
|
||||
同時に、`async def` で定義された関数は「await」される必要があります。つまり、`async def` を持つ関数は、やはり `async def` で定義された関数の内部からしか呼べません。
|
||||
|
||||
では、このニワトリと卵の問題について、最初の `async` 関数をどのように呼び出すのでしょうか?
|
||||
では、ニワトリと卵の話のように、最初の `async` 関数はどう呼ぶのでしょうか?
|
||||
|
||||
**FastAPI**を使用している場合、その「最初の」関数が*path operation 関数*であり、FastAPIが正しく実行する方法を知っているので、心配する必要はありません。
|
||||
**FastAPI** を使っている場合は心配ありません。その「最初の」関数は *path operation 関数* で、FastAPI が適切に実行してくれます。
|
||||
|
||||
しかし、FastAPI以外で `async` / `await` を使用したい場合は、<a href="https://docs.python.org/3/library/asyncio-task.html#coroutine" class="external-link" target="_blank">公式Pythonドキュメントを参照して下さい</a>。
|
||||
しかし、FastAPI を使わずに `async` / `await` を使いたい場合もあります。
|
||||
|
||||
### 非同期コードの他の形式
|
||||
### 自分で async コードを書く { #write-your-own-async-code }
|
||||
|
||||
`async` と `await` を使用するスタイルは、この言語では比較的新しいものです。
|
||||
Starlette (**FastAPI** も) は <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> の上に構築されており、標準ライブラリの <a href="https://docs.python.org/3/library/asyncio-task.html" class="external-link" target="_blank">asyncio</a> と <a href="https://trio.readthedocs.io/en/stable/" class="external-link" target="_blank">Trio</a> の両方に対応しています。
|
||||
|
||||
非同期コードの操作がはるかに簡単になります。
|
||||
特に、あなた自身のコード内で、より高度なパターンを必要とする発展的な並行処理のユースケースに対して、<a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> を直接使えます。
|
||||
|
||||
等価な (またはほとんど同一の) 構文が、最近のバージョンのJavaScript (ブラウザおよびNodeJS) にも最近組み込まれました。
|
||||
仮に FastAPI を使っていなくても、<a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> で独自の async アプリケーションを書けば、高い互換性と利点 (例: 構造化並行性) を得られます。
|
||||
|
||||
しかし、その前は、非同期コードの処理はかなり複雑で難解でした。
|
||||
私は AnyIO の上に薄い層として、型注釈を少し改善し、より良い**補完**や**インラインエラー**などを得るための別ライブラリも作りました。また、**理解**して**自分で async コードを書く**のに役立つフレンドリーなイントロ/チュートリアルもあります: <a href="https://asyncer.tiangolo.com/" class="external-link" target="_blank">Asyncer</a>。特に、**async コードと通常の** (ブロッキング/同期) **コードを組み合わせる**必要がある場合に有用です。
|
||||
|
||||
以前のバージョンのPythonでは、スレッドや<a href="https://www.gevent.org/" class="external-link" target="_blank">Gevent</a>が利用できました。しかし、コードは理解、デバック、そして、考察がはるかに複雑です。
|
||||
### 非同期コードの他の形式 { #other-forms-of-asynchronous-code }
|
||||
|
||||
以前のバージョンのNodeJS / ブラウザJavaScriptでは、「コールバック」を使用していました。これは、「コールバック地獄」につながります。
|
||||
`async` と `await` を使うこのスタイルは、言語としては比較的新しいものです。
|
||||
|
||||
## コルーチン
|
||||
しかし、これにより非同期コードの取り扱いは大幅に簡単になります。
|
||||
|
||||
**コルーチン**は、`async def` 関数によって返されるものを指す非常に洒落た用語です。これは、開始できて、いつか終了する関数のようなものであるが、内部に `await` があるときは内部的に一時停止⏸されることもあるものだとPythonは認識しています。
|
||||
同等 (ほぼ同一) の構文が最近の JavaScript (ブラウザと NodeJS) にも導入されました。
|
||||
|
||||
`async` と `await` を用いた非同期コードを使用するすべての機能は、「コルーチン」を使用するものとして何度もまとめられています。Goの主要機能である「ゴルーチン」に相当します。
|
||||
それ以前は、非同期コードの扱いはかなり複雑で難解でした。
|
||||
|
||||
## まとめ
|
||||
以前の Python ではスレッドや <a href="https://www.gevent.org/" class="external-link" target="_blank">Gevent</a> を使えましたが、コードの理解・デバッグ・思考がはるかに難しくなります。
|
||||
|
||||
上述したフレーズを見てみましょう:
|
||||
以前の NodeJS / ブラウザ JavaScript では「コールバック」を使っており、「コールバック地獄」を招きました。
|
||||
|
||||
> 現代版のPythonは「**非同期コード**」を、「**コルーチン**」と称されるものを利用してサポートしています。これは **`async` と `await`** 構文を用います。
|
||||
## コルーチン { #coroutines }
|
||||
|
||||
今では、この意味がより理解できるはずです。✨
|
||||
**コルーチン**は、`async def` 関数が返すものを指す、ちょっと洒落た用語です。Python はそれを、開始できていつか終了する関数のようなものとして扱いますが、内部に `await` があるたびに内部的に一時停止 ⏸ するかもしれないものとして認識します。
|
||||
|
||||
(Starletteを介して) FastAPIに力を与えて、印象的なパフォーマンスを実現しているものはこれがすべてです。
|
||||
`async` と `await` を用いた非同期コードの機能全体は、しばしば「コルーチンを使う」と要約されます。これは Go の主要機能「Goroutines」に相当します。
|
||||
|
||||
## 非常に発展的な技術的詳細
|
||||
## まとめ { #conclusion }
|
||||
|
||||
上のフレーズをもう一度見てみましょう:
|
||||
|
||||
> モダンな Python は **「非同期コード」** を **「コルーチン」** と呼ばれる仕組みでサポートしており、構文は **`async` と `await`** です。
|
||||
|
||||
今なら、より意味が分かるはずです。✨
|
||||
|
||||
これらすべてが (Starlette を通じて) FastAPI を支え、印象的なパフォーマンスを実現しています。
|
||||
|
||||
## 非常に発展的な技術的詳細 { #very-technical-details }
|
||||
|
||||
/// warning | 注意
|
||||
|
||||
恐らくスキップしても良いでしょう。
|
||||
おそらく読み飛ばしても大丈夫です。
|
||||
|
||||
この部分は**FastAPI**の仕組みに関する非常に技術的な詳細です。
|
||||
これは **FastAPI** の内部動作に関する、とても技術的な詳細です。
|
||||
|
||||
かなりの技術知識 (コルーチン、スレッド、ブロッキングなど) があり、FastAPIが `async def` と通常の `def` をどのように処理するか知りたい場合は、先に進んでください。
|
||||
(コルーチン、スレッド、ブロッキング等の) 技術知識があり、FastAPI が `async def` と通常の `def` をどう扱うかに興味がある場合は、読み進めてください。
|
||||
|
||||
///
|
||||
|
||||
### Path operation 関数
|
||||
### Path operation 関数 { #path-operation-functions }
|
||||
|
||||
*path operation 関数*を `async def` の代わりに通常の `def` で宣言すると、(サーバーをブロックするので) 直接呼び出す代わりに外部スレッドプール (awaitされる) で実行されます。
|
||||
*path operation 関数* を `async def` ではなく通常の `def` で宣言した場合、(サーバをブロックしてしまうため) 直接呼び出されるのではなく、外部のスレッドプールで実行され、それを待機します。
|
||||
|
||||
上記の方法と違った方法の別の非同期フレームワークから来ており、小さなパフォーマンス向上 (約100ナノ秒) のために通常の `def` を使用して些細な演算のみ行う *path operation 関数* を定義するのに慣れている場合は、**FastAPI**ではまったく逆の効果になることに注意してください。このような場合、*path operation 関数* がブロッキング<abbr title="入力/出力: ディスクの読み取りまたは書き込み、ネットワーク通信。">I/O</abbr>を実行しないのであれば、`async def` の使用をお勧めします。
|
||||
上記とは異なる動作の別の非同期フレームワークから来ており、ほんのわずかなパフォーマンス向上 (約 100 ナノ秒) を狙って、計算のみの些細な *path operation 関数* を素の `def` で定義することに慣れている場合、**FastAPI** では効果がまったく逆になる点に注意してください。これらの場合、*path operation 関数* がブロッキングな <abbr title="Input/Output - 入出力: ディスクの読み取りまたは書き込み、ネットワーク通信。">I/O</abbr> を行うコードを使っていない限り、`async def` を使った方が良いです。
|
||||
|
||||
それでも、どちらの状況でも、**FastAPI**が過去のフレームワークよりも (またはそれに匹敵するほど) [高速になる](index.md#_10){.internal-link target=_blank}可能性があります。
|
||||
それでも、どちらの状況でも、**FastAPI** はあなたが以前使っていたフレームワークよりも (少なくとも同等に) [高速である](index.md#performance){.internal-link target=_blank} 可能性が高いです。
|
||||
|
||||
### 依存関係
|
||||
### 依存関係 { #dependencies }
|
||||
|
||||
依存関係についても同様です。依存関係が `async def` ではなく標準の `def` 関数である場合、外部スレッドプールで実行されます。
|
||||
[依存関係](tutorial/dependencies/index.md){.internal-link target=_blank} についても同様です。依存関係が `async def` ではなく標準の `def` 関数である場合、外部のスレッドプールで実行されます。
|
||||
|
||||
### サブ依存関係
|
||||
### サブ依存関係 { #sub-dependencies }
|
||||
|
||||
(関数定義のパラメーターとして) 相互に必要な複数の依存関係とサブ依存関係を設定できます。一部は `async def` で作成され、他の一部は通常の `def` で作成されます。それでも動作し、通常の `def`で作成されたものは、「awaitされる」代わりに (スレッドプールから) 外部スレッドで呼び出されます。
|
||||
複数の依存関係や [サブ依存関係](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} を (関数定義のパラメータとして) 相互に要求させられます。その一部は `async def`、他は通常の `def` で作られていても動作します。通常の `def` で作られたものは「await」される代わりに、外部スレッドプールからスレッド上で呼び出されます。
|
||||
|
||||
### その他のユーティリティ関数
|
||||
### その他のユーティリティ関数 { #other-utility-functions }
|
||||
|
||||
あなたが直接呼び出すユーティリティ関数は通常の `def` または `async def` で作成でき、FastAPIは呼び出す方法に影響を与えません。
|
||||
あなたが直接呼び出すユーティリティ関数は、通常の `def` でも `async def` でも構いません。FastAPI はその呼び出し方に影響を与えません。
|
||||
|
||||
これは、FastAPIが呼び出す関数と対照的です: *path operation 関数*と依存関係。
|
||||
これは、FastAPI があなたの代わりに呼び出す関数 (すなわち *path operation 関数* と依存関係) とは対照的です。
|
||||
|
||||
ユーティリティ関数が `def` を使用した通常の関数である場合、スレッドプールではなく直接 (コードで記述したとおりに) 呼び出されます。関数が `async def` を使用して作成されている場合は、呼び出す際に `await` する必要があります。
|
||||
ユーティリティ関数が `def` の通常関数であれば、(あなたのコードに書いたとおりに) 直接呼び出され、スレッドプールでは実行されません。関数が `async def` で作られている場合は、その関数を呼ぶときに `await` すべきです。
|
||||
|
||||
---
|
||||
|
||||
繰り返しになりますが、これらは非常に技術的な詳細であり、検索して辿り着いた場合は役立つでしょう。
|
||||
繰り返しになりますが、これらは非常に技術的な詳細で、該当事項を検索してここにたどり着いた場合には役立つでしょう。
|
||||
|
||||
それ以外の場合は、上記のセクションのガイドラインで問題ないはずです: <a href="#_1">急いでいますか?</a>。
|
||||
それ以外の場合は、上のセクションのガイドラインに従えば十分です: <a href="#in-a-hurry">急いでいますか?</a>。
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
## セキュリティ - 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**によって提供されることが一般的です。このプロキシは通信の暗号化を担当します。
|
||||
@@ -193,7 +192,6 @@ FastAPI アプリケーションでは、Uvicorn を実行する `fastapi` コ
|
||||
同じ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つのプロセスだけであることを覚えていますでしょうか?
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Linuxコンテナの使用には、**セキュリティ**、**反復可能性(
|
||||
<summary>Dockerfile Preview 👀</summary>
|
||||
|
||||
```Dockerfile
|
||||
FROM python:3.9
|
||||
FROM python:3.14
|
||||
|
||||
WORKDIR /code
|
||||
|
||||
@@ -166,7 +166,7 @@ def read_item(item_id: int, q: str | None = None):
|
||||
|
||||
```{ .dockerfile .annotate }
|
||||
# (1)!
|
||||
FROM python:3.9
|
||||
FROM python:3.14
|
||||
|
||||
# (2)!
|
||||
WORKDIR /code
|
||||
@@ -392,7 +392,7 @@ FastAPI が単一のファイル、例えば `./app` ディレクトリのない
|
||||
そうすれば、`Dockerfile`の中にファイルをコピーするために、対応するパスを変更するだけでよいです:
|
||||
|
||||
```{ .dockerfile .annotate hl_lines="10 13" }
|
||||
FROM python:3.9
|
||||
FROM python:3.14
|
||||
|
||||
WORKDIR /code
|
||||
|
||||
@@ -456,7 +456,7 @@ TraefikはDockerやKubernetesなどと統合されているので、コンテナ
|
||||
|
||||
## レプリケーション - プロセス数 { #replication-number-of-processes }
|
||||
|
||||
**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** や Docker Swarm モード、Nomad、あるいは複数のマシン上で分散コンテナを管理するための同様の複雑なシステムを使ってマシンの<dfn title="ある方法で接続され、連携して動作するように構成されたマシンの集まり">クラスタ</dfn>を構成している場合、 各コンテナで(Workerを持つUvicornのような)**プロセスマネージャ**を使用する代わりに、**クラスター・レベル**で**レプリケーション**を処理したいと思うでしょう。
|
||||
|
||||
Kubernetesのような分散コンテナ管理システムの1つは通常、入ってくるリクエストの**ロードバランシング**をサポートしながら、**コンテナのレプリケーション**を処理する統合された方法を持っています。このことはすべて**クラスタレベル**にてです。
|
||||
|
||||
@@ -501,7 +501,7 @@ HTTPSに使われるものと同じ**TLS Termination Proxy**コンポーネン
|
||||
そのような場合、`--workers` コマンドラインオプションを使って、実行したいワーカー数を設定できます:
|
||||
|
||||
```{ .dockerfile .annotate }
|
||||
FROM python:3.9
|
||||
FROM python:3.14
|
||||
|
||||
WORKDIR /code
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ HTTPSは単に「有効」か「無効」かで決まるものだと思いがち
|
||||
* **デフォルトでは**、**IPアドレスごとに1つのHTTPS証明書**しか持てないことになります。
|
||||
* これは、サーバーの規模やアプリケーションの規模に寄りません。
|
||||
* しかし、これには**解決策**があります。
|
||||
* **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>**と呼ばれる**拡張**があります。
|
||||
* **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のまま**です。
|
||||
@@ -66,7 +66,7 @@ Let's Encrypt以前は、これらの**HTTPS証明書**は信頼できる第三
|
||||
|
||||
ステップの初めは、**ドメイン名**を**取得すること**から始まるでしょう。その後、DNSサーバー(おそらく同じクラウドプロバイダー)に設定します。
|
||||
|
||||
おそらくクラウドサーバー(仮想マシン)かそれに類するものを手に入れ、<abbr title="That doesn't change – 変わらない">fixed</abbr> **パブリックIPアドレス**を持つことになるでしょう。
|
||||
おそらくクラウドサーバー(仮想マシン)かそれに類するものを手に入れ、<dfn title="時間とともに変化しない。動的ではない。">固定の</dfn> **パブリックIPアドレス**を持つことになるでしょう。
|
||||
|
||||
DNSサーバーでは、**取得したドメイン**をあなたのサーバーのパプリック**IPアドレス**に向けるレコード(「`A record`」)を設定します。
|
||||
|
||||
|
||||
@@ -1,12 +1,82 @@
|
||||
# 手動デプロイ
|
||||
# サーバーを手動で実行する { #run-a-server-manually }
|
||||
|
||||
**FastAPI** を手動でデプロイすることもできます。
|
||||
## fastapi run コマンドを使う { #use-the-fastapi-run-command }
|
||||
|
||||
以下の様なASGI対応のサーバをインストールする必要があります:
|
||||
結論として、FastAPI アプリケーションを提供するには `fastapi run` を使います:
|
||||
|
||||
//// tab | Uvicorn
|
||||
<div class="termy">
|
||||
|
||||
* <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a>, uvloopとhttptoolsを基にした高速なASGIサーバ。
|
||||
```console
|
||||
$ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid">main.py</u>
|
||||
|
||||
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting production 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://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>
|
||||
|
||||
Logs:
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>2306215</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.
|
||||
<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>
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
これでほとんどのケースは動作します。😎
|
||||
|
||||
このコマンドは、たとえばコンテナやサーバー内で **FastAPI** アプリを起動するのに使えます。
|
||||
|
||||
## ASGIサーバー { #asgi-servers }
|
||||
|
||||
少し詳しく見ていきます。
|
||||
|
||||
FastAPI は、Python の Web フレームワークとサーバーのための標準である <abbr title="Asynchronous Server Gateway Interface - 非同期サーバーゲートウェイインターフェース">ASGI</abbr> を使います。FastAPI は ASGI Web フレームワークです。
|
||||
|
||||
リモートのサーバーマシンで **FastAPI** アプリケーション(や他の ASGI アプリケーション)を実行するのに主に必要なのは **Uvicorn** のような ASGI サーバープログラムです。これは `fastapi` コマンドにデフォルトで含まれています。
|
||||
|
||||
他にもいくつかの選択肢があります:
|
||||
|
||||
* <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a>: 高性能な ASGI サーバー。
|
||||
* <a href="https://hypercorn.readthedocs.io/" class="external-link" target="_blank">Hypercorn</a>: HTTP/2 や Trio に対応する ASGI サーバーなど。
|
||||
* <a href="https://github.com/django/daphne" class="external-link" target="_blank">Daphne</a>: Django Channels のために作られた ASGI サーバー。
|
||||
* <a href="https://github.com/emmett-framework/granian" class="external-link" target="_blank">Granian</a>: Python アプリケーション向けの Rust 製 HTTP サーバー。
|
||||
* <a href="https://unit.nginx.org/howto/fastapi/" class="external-link" target="_blank">NGINX Unit</a>: 軽量で多用途な Web アプリケーションランタイム。
|
||||
|
||||
## サーバーマシンとサーバープログラム { #server-machine-and-server-program }
|
||||
|
||||
名称に関する小さな注意点があります。💡
|
||||
|
||||
「サーバー」という言葉は、リモート/クラウド上のコンピュータ(物理/仮想マシン)と、そのマシン上で動作しているプログラム(例: Uvicorn)の両方を指すのに一般的に使われます。
|
||||
|
||||
一般に「サーバー」と書かれているときは、そのどちらかを指している可能性があることを覚えておいてください。
|
||||
|
||||
リモートマシンを指す場合、「サーバー」のほか「マシン」「VM(仮想マシン)」「ノード」などとも呼ばれます。いずれも通常 Linux を実行し、そこでプログラムを動かすリモートマシンを指します。
|
||||
|
||||
## サーバープログラムをインストール { #install-the-server-program }
|
||||
|
||||
FastAPI をインストールすると、本番サーバーの Uvicorn が同梱されており、`fastapi run` コマンドで起動できます。
|
||||
|
||||
ただし、ASGI サーバーを手動でインストールすることもできます。
|
||||
|
||||
[仮想環境](../virtual-environments.md){.internal-link target=_blank}を作成して有効化し、サーバーアプリケーションをインストールしてください。
|
||||
|
||||
例として、Uvicorn をインストールするには:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
@@ -18,37 +88,21 @@ $ pip install "uvicorn[standard]"
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
他の ASGI サーバープログラムでも同様の手順です。
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
`standard` を加えることで、Uvicornがインストールされ、いくつかの推奨される依存関係を利用するようになります。
|
||||
`standard` を付けると、Uvicorn は推奨の追加依存関係もインストールして使用します。
|
||||
|
||||
これには、`asyncio` の高性能な完全互換品である `uvloop` が含まれ、並行処理のパフォーマンスが大幅に向上します。
|
||||
その中には、`asyncio` の高性能なドロップイン代替であり、大きな並行実行性能の向上をもたらす `uvloop` も含まれます。
|
||||
|
||||
`pip install "fastapi[standard]"` のように FastAPI をインストールした場合は、すでに `uvicorn[standard]` も含まれます。
|
||||
|
||||
///
|
||||
|
||||
//// tab | Hypercorn
|
||||
## サーバープログラムを起動 { #run-the-server-program }
|
||||
|
||||
* <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>, HTTP/2にも対応しているASGIサーバ。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install hypercorn
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
...または、これら以外のASGIサーバ。
|
||||
|
||||
////
|
||||
|
||||
そして、チュートリアルと同様な方法でアプリケーションを起動して下さい。ただし、以下の様に`--reload` オプションは使用しないで下さい:
|
||||
|
||||
//// tab | Uvicorn
|
||||
ASGI サーバーを手動でインストールした場合、通常は FastAPI アプリケーションをインポートさせるために、特別な形式のインポート文字列を渡す必要があります:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
@@ -60,26 +114,44 @@ $ uvicorn main:app --host 0.0.0.0 --port 80
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
/// note | 備考
|
||||
|
||||
//// tab | Hypercorn
|
||||
`uvicorn main:app` というコマンドは次を指します:
|
||||
|
||||
<div class="termy">
|
||||
* `main`: ファイル `main.py`(Python の「モジュール」)。
|
||||
* `app`: `main.py` 内で `app = FastAPI()` により作成されたオブジェクト。
|
||||
|
||||
```console
|
||||
$ hypercorn main:app --bind 0.0.0.0:80
|
||||
これは次と等価です:
|
||||
|
||||
Running on 0.0.0.0:8080 over http (CTRL + C to quit)
|
||||
```Python
|
||||
from main import app
|
||||
```
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
////
|
||||
他の ASGI サーバープログラムでも同様のコマンドがあり、詳細はそれぞれのドキュメントを参照してください。
|
||||
|
||||
停止した場合に自動的に再起動させるツールを設定したいかもしれません。
|
||||
/// warning | 注意
|
||||
|
||||
さらに、<a href="https://gunicorn.org/" class="external-link" target="_blank">Gunicorn</a>をインストールして<a href="https://www.uvicorn.dev/#running-with-gunicorn" class="external-link" target="_blank">Uvicornのマネージャーとして使用したり</a>、複数のワーカーでHypercornを使用したいかもしれません。
|
||||
Uvicorn などのサーバーは、開発時に便利な `--reload` オプションをサポートしています。
|
||||
|
||||
ワーカー数などの微調整も行いたいかもしれません。
|
||||
しかし `--reload` は多くのリソースを消費し、不安定になるなどの性質があります。
|
||||
|
||||
しかしこれら全てをやろうとすると、自動的にこれらを行うDockerイメージを使う方が楽かもしれません。
|
||||
開発中には非常に役立ちますが、 本番環境では使用すべきではありません。
|
||||
|
||||
///
|
||||
|
||||
## デプロイの概念 { #deployment-concepts }
|
||||
|
||||
これらの例は、サーバープログラム(例: Uvicorn)を実行し、事前に決めたポート(例: `80`)で、すべての IP(`0.0.0.0`)をリッスンする「単一プロセス」を起動します。
|
||||
|
||||
これが基本的な考え方です。ただし、次のような追加事項にも対応したくなるでしょう:
|
||||
|
||||
* セキュリティ - HTTPS
|
||||
* 起動時に実行
|
||||
* 再起動
|
||||
* レプリケーション(実行プロセス数)
|
||||
* メモリ
|
||||
* 起動前の事前ステップ
|
||||
|
||||
これらの各概念についての考え方や、対処するための具体例・戦略を次の章で説明します。🚀
|
||||
|
||||
@@ -62,17 +62,17 @@ $ <font color="#4E9A06">fastapi</font> run --workers 4 <u style="text-decoration
|
||||
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>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.
|
||||
<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.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
@@ -153,7 +153,7 @@ Hello World from Python
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
詳しくは <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a> を参照してください。
|
||||
詳しくは <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: 設定</a> を参照してください。
|
||||
|
||||
///
|
||||
|
||||
@@ -291,7 +291,7 @@ $ C:\opt\custompython\bin\python
|
||||
|
||||
これで、**環境変数**とは何か、Pythonでどのように使用するかについて、基本的な理解が得られたはずです。
|
||||
|
||||
環境変数についての詳細は、<a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Wikipedia for Environment Variable</a> も参照してください。
|
||||
環境変数についての詳細は、<a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Wikipedia の環境変数</a> も参照してください。
|
||||
|
||||
多くの場合、環境変数がどのように役立ち、すぐに適用できるのかはあまり明確ではありません。しかし、開発中のさまざまなシナリオで何度も登場するため、知っておくとよいでしょう。
|
||||
|
||||
|
||||
@@ -1,54 +1,55 @@
|
||||
# 機能
|
||||
# 機能 { #features }
|
||||
|
||||
## FastAPIの機能
|
||||
## FastAPIの機能 { #fastapi-features }
|
||||
|
||||
**FastAPI** は以下の機能をもちます:
|
||||
**FastAPI** は次のものを提供します:
|
||||
|
||||
### オープンスタンダード準拠
|
||||
### オープンスタンダード準拠 { #based-on-open-standards }
|
||||
|
||||
* API作成のための<a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a>。これは、<abbr title="also known as: endpoints, routes">path</abbr> <abbr title="also known as HTTP methods, as POST, GET, PUT, DELETE">operations</abbr>の宣言、パラメータ、ボディリクエスト、セキュリティなどを含んでいます。
|
||||
* <a href="http://json-schema.org/" class="external-link" target="_blank"><strong>JSONスキーマ</strong></a>を使用したデータモデルのドキュメント自動生成(OpenAPIはJSONスキーマに基づいている)。
|
||||
* 綿密な調査の結果、上層に後付けするのではなく、これらの基準に基づいて設計されました。
|
||||
* API 作成のための <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a>。<dfn title="別名: エンドポイント、ルート">path</dfn> <dfn title="別名: HTTP メソッド(POST、GET、PUT、DELETE など)">operations</dfn>、パラメータ、リクエストボディ、セキュリティなどの宣言を含みます。
|
||||
* <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> によるデータモデルの自動ドキュメント化(OpenAPI 自体が JSON Schema に基づいています)。
|
||||
* 入念な調査のうえ、これらの標準を中心に設計されています。後付けのレイヤーではありません。
|
||||
* これにより、多くの言語で自動 **クライアントコード生成** が可能です。
|
||||
|
||||
### 自動ドキュメント生成
|
||||
対話的なAPIドキュメントと探索的なwebユーザーインターフェースを提供します。フレームワークはOpenAPIを基にしているため、いくつかのオプションがあり、デフォルトで2つ含まれています。
|
||||
### 自動ドキュメント { #automatic-docs }
|
||||
|
||||
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a>で、インタラクティブな探索をしながら、ブラウザから直接APIを呼び出してテストが行えます。
|
||||
対話的な API ドキュメントと探索的な Web ユーザーインターフェース。フレームワークは OpenAPI に基づいているため、複数のオプションがあり、デフォルトで 2 つ含まれます。
|
||||
|
||||
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a>。インタラクティブに探索しつつ、ブラウザから直接 API を呼び出してテストできます。
|
||||
|
||||

|
||||
|
||||
* <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a>を使用したもう一つのAPIドキュメント生成。
|
||||
* <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a> による代替の API ドキュメント。
|
||||
|
||||

|
||||
|
||||
### 現代的なPython
|
||||
### 現代的なPythonのみ { #just-modern-python }
|
||||
|
||||
FastAPIの機能はすべて、標準のPython 3.8型宣言に基づいています(Pydanticの功績)。新しい構文はありません。ただの現代的な標準のPythonです。
|
||||
すべて標準の **Python の型** 宣言(Pydantic に感謝)に基づいています。新しい構文を学ぶ必要はありません。標準的でモダンな Python だけです。
|
||||
|
||||
(FastAPIを使用しない場合でも)Pythonの型の使用方法について簡単な復習が必要な場合は、短いチュートリアル([Python Types](python-types.md){.internal-link target=_blank})を参照してください。
|
||||
(FastAPI を使わない場合でも)Python の型の使い方を 2 分で復習したい場合は、短いチュートリアル [Python Types](python-types.md){.internal-link target=_blank} を参照してください。
|
||||
|
||||
型を使用した標準的なPythonを記述します:
|
||||
型を使った標準的な Python を記述します:
|
||||
|
||||
```Python
|
||||
from datetime import date
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
# Declare a variable as a str
|
||||
# and get editor support inside the function
|
||||
# 変数を str として宣言
|
||||
# そして関数内でエディタ支援を受ける
|
||||
def main(user_id: str):
|
||||
return user_id
|
||||
|
||||
|
||||
# A Pydantic model
|
||||
# Pydantic モデル
|
||||
class User(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
joined: date
|
||||
```
|
||||
|
||||
これは以下のように用いられます:
|
||||
これは次のように使えます:
|
||||
|
||||
```Python
|
||||
my_user: User = User(id=3, name="John Doe", joined="2018-07-19")
|
||||
@@ -62,143 +63,139 @@ second_user_data = {
|
||||
my_second_user: User = User(**second_user_data)
|
||||
```
|
||||
|
||||
/// info | 情報
|
||||
/// info
|
||||
|
||||
`**second_user_data` は以下を意味します:
|
||||
`**second_user_data` は次の意味です:
|
||||
|
||||
`second_user_data`辞書のキーと値を直接、キーと値の引数として渡します。これは、`User(id=4, name="Mary", joined="2018-11-30")`と同等です。
|
||||
`second_user_data` 辞書のキーと値を、そのままキーバリュー引数として渡します。これは `User(id=4, name="Mary", joined="2018-11-30")` と同等です。
|
||||
|
||||
///
|
||||
|
||||
### エディタのサポート
|
||||
### エディタのサポート { #editor-support }
|
||||
|
||||
すべてのフレームワークは使いやすく直感的に使用できるように設計されており、すべての決定は開発を開始する前でも複数のエディターでテストされ、最高の開発体験が保証されます。
|
||||
フレームワーク全体が使いやすく直感的になるよう設計されており、最高の開発体験を確保するため、開発開始前から複数のエディタであらゆる判断が検証されています。
|
||||
|
||||
前回のPython開発者調査では、<a href="https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features" class="external-link" target="_blank">最も使用されている機能が「オートコンプリート」であることが明らかになりました。</a>
|
||||
Python 開発者調査では、<a href="https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features" class="external-link" target="_blank">最もよく使われる機能の 1 つが「オートコンプリート」であることが明らかです</a>。
|
||||
|
||||
**FastAPI** フレームワークは、この要求を満たすことを基本としています。オートコンプリートはどこでも機能します。
|
||||
**FastAPI** はその要求を満たすことを基盤にしています。オートコンプリートはどこでも機能します。
|
||||
|
||||
ドキュメントに戻る必要はほとんどありません。
|
||||
|
||||
エディターがどのように役立つかを以下に示します:
|
||||
エディタがどのように役立つかの例です:
|
||||
|
||||
* <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> の場合:
|
||||
|
||||

|
||||
|
||||
* <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>の場合:
|
||||
* <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> の場合:
|
||||
|
||||

|
||||
|
||||
以前は不可能だと考えていたコードでさえ補完されます。例えば、リクエストからのJSONボディ(ネストされている可能性がある)内の `price`キーです。
|
||||
以前は不可能だと思っていたコードでも補完が得られます。例えば、リクエストから届く(ネストされている可能性のある)JSON ボディ内の `price` キーなどです。
|
||||
|
||||
間違ったキー名を入力したり、ドキュメント間を行き来したり、上下にスクロールして`username`と`user_name`のどちらを使用したか調べたりする必要はもうありません。
|
||||
もう間違ったキー名を入力したり、ドキュメントを行き来したり、上下にスクロールして最終的に `username` と `user_name` のどちらを使ったのか探す必要はありません。
|
||||
|
||||
### 簡潔
|
||||
### 簡潔 { #short }
|
||||
|
||||
すべてに適切な**デフォルト**があり、オプションの構成ができます。必要なことを実行し、必要なAPIを定義するためにすべてのパラメーターを調整できます。
|
||||
すべてに妥当な **デフォルト** があり、どこでもオプションで構成できます。必要に応じてすべてのパラメータを微調整して、求める API を定義できます。
|
||||
|
||||
ただし、デフォルトでもすべて **うまくいきます**。
|
||||
しかしデフォルトのままでも、すべて **うまく動きます**。
|
||||
|
||||
### 検証
|
||||
### 検証 { #validation }
|
||||
|
||||
* 以下の様な、ほとんどの(すべての?)Python **データ型**の検証:
|
||||
* JSONオブジェクト(`dict`)
|
||||
* 項目の型を定義するJSON配列(`list`)
|
||||
* 最小長と最大長のある文字列(`str`)フィールド
|
||||
* 最小値と最大値のある数値(`int`、` float`)
|
||||
* ほとんど(あるいはすべて?)の Python の **データ型** に対する検証:
|
||||
* JSON オブジェクト(`dict`)。
|
||||
* 項目の型を定義する JSON 配列(`list`)。
|
||||
* 文字列(`str`)フィールドの最小/最大長。
|
||||
* 数値(`int`、`float`)の最小/最大値、など。
|
||||
|
||||
* よりエキゾチックな型の検証:
|
||||
* URL
|
||||
* Eメール
|
||||
* UUID
|
||||
* ...その他
|
||||
* よりエキゾチックな型の検証:
|
||||
* URL。
|
||||
* Email。
|
||||
* UUID。
|
||||
* ...その他。
|
||||
|
||||
すべての検証は、確立された堅牢な **Pydantic** によって処理されます。
|
||||
すべての検証は、確立され堅牢な **Pydantic** によって処理されます。
|
||||
|
||||
### セキュリティと認証
|
||||
### セキュリティと認証 { #security-and-authentication }
|
||||
|
||||
セキュリティと認証が統合されています。 データベースまたはデータモデルについても妥協していません。
|
||||
セキュリティと認証が統合されています。データベースやデータモデルとの妥協はありません。
|
||||
|
||||
以下のOpenAPIで定義されているすべてのセキュリティスキームを含む:
|
||||
OpenAPI で定義されたすべてのセキュリティスキームをサポートします:
|
||||
|
||||
* HTTPベーシック
|
||||
* **OAuth2**(**JWTトークン**も使用)。 JWTを使用したOAuth2のチュートリアル([OAuth2 with JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank})を確認してください。
|
||||
* APIキー:
|
||||
* ヘッダー
|
||||
* クエリパラメータ
|
||||
* クッキー、等
|
||||
* HTTP Basic。
|
||||
* **OAuth2**(**JWT トークン** も可)。チュートリアル [JWT を用いた OAuth2](tutorial/security/oauth2-jwt.md){.internal-link target=_blank} を確認してください。
|
||||
* API キー(以下の場所):
|
||||
* ヘッダー。
|
||||
* クエリパラメータ。
|
||||
* クッキー、など。
|
||||
|
||||
さらに、Starletteのすべてのセキュリティ機能も含みます(**セッションCookie**を含む)。
|
||||
さらに、Starlette のすべてのセキュリティ機能(**セッション Cookie** を含む)も利用できます。
|
||||
|
||||
これらは、システム、データストア、リレーショナルデータベース、NoSQLデータベースなどと簡単に統合できる再利用可能なツールとコンポーネントとして構築されています。
|
||||
これらはすべて再利用可能なツールやコンポーネントとして構築されており、システム、データストア、リレーショナル/NoSQL データベース等と容易に統合できます。
|
||||
|
||||
### 依存性の注入(Dependency Injection)
|
||||
### 依存性の注入 { #dependency-injection }
|
||||
|
||||
FastAPIには非常に使いやすく、非常に強力な<abbr title='also known as "components", "resources", "services", "providers"'><strong>依存性の注入</strong></abbr>システムを備えています。
|
||||
FastAPI には、非常に使いやすく、かつ非常に強力な <dfn title='別名: コンポーネント、リソース、サービス、プロバイダー'><strong>依存性の注入</strong></dfn> システムがあります。
|
||||
|
||||
* 依存関係でさえも依存関係を持つことができ、階層または **依存関係の"グラフ"** を作成することができます。
|
||||
* 依存関係は依存関係を持つこともでき、階層または **依存関係の「グラフ」** を作成できます。
|
||||
* すべてフレームワークによって**自動的に処理**されます。
|
||||
* すべての依存関係はリクエストからデータを要求でき、*path operation* の制約と自動ドキュメントを**拡張**できます。
|
||||
* 依存関係で定義された *path operation* のパラメータについても**自動検証**されます。
|
||||
* 複雑なユーザー認証システム、**データベース接続** などのサポート。
|
||||
* **データベースやフロントエンド等との妥協は不要**。すべてと簡単に統合できます。
|
||||
|
||||
* フレームワークによってすべて**自動的に処理**されます。
|
||||
* すべての依存関係はリクエストからのデータを要請できて、**path operationsの制約と自動ドキュメンテーションを拡張できます**。
|
||||
* 依存関係で定義された *path operation* パラメータも**自動検証**が可能です。
|
||||
* 複雑なユーザー認証システム、**データベース接続**などのサポート
|
||||
* **データベース、フロントエンドなどに対する妥協はありません**。それらすべてと簡単に統合できます。
|
||||
### 無制限の「プラグイン」 { #unlimited-plug-ins }
|
||||
|
||||
### 無制限の「プラグイン」
|
||||
別の言い方をすれば、プラグインは不要で、必要なコードをインポートして使うだけです。
|
||||
|
||||
他の方法では、それらを必要とせず、必要なコードをインポートして使用します。
|
||||
あらゆる統合は(依存関係を用いて)非常に簡単に使えるよう設計されており、*path operation* で使うのと同じ構造と構文で、2 行のコードでアプリケーション用の「プラグイン」を作れます。
|
||||
|
||||
統合は非常に簡単に使用できるように設計されており(依存関係を用いて)、*path operations* で使用されているのと同じ構造と構文を使用して、2行のコードでアプリケーションの「プラグイン」を作成できます。
|
||||
### テスト済み { #tested }
|
||||
|
||||
* 100% の <dfn title="自動的にテストされるコードの量">テストカバレッジ</dfn>。
|
||||
* 100% <dfn title="Python の型アノテーション。これにより、エディタや外部ツールからより良い支援が受けられます">型アノテーション付き</dfn>のコードベース。
|
||||
* 本番アプリケーションで使用されています。
|
||||
|
||||
### テスト
|
||||
## Starletteの機能 { #starlette-features }
|
||||
|
||||
* <abbr title = "自動的にテストされるコードの量">テストカバレッジ</abbr> 100%
|
||||
* <abbr title = "Python型アノテーション。これにより、ユーザーはより良いエディターと外部ツールのサポート受けられる。">型アノテーション</abbr>100%のコードベース
|
||||
* 本番アプリケーションで使用されます
|
||||
**FastAPI** は <a href="https://www.starlette.dev/" class="external-link" target="_blank"><strong>Starlette</strong></a> と完全に互換性があり(かつそれに基づいています)。そのため、手元の Starlette の追加コードも動作します。
|
||||
|
||||
## Starletteの機能
|
||||
`FastAPI` は実際には `Starlette` のサブクラスです。すでに Starlette を知っている、あるいは使っているなら、ほとんどの機能は同じように動作します。
|
||||
|
||||
**FastAPI**は、<a href="https://www.starlette.dev/" class="external-link" target="_blank"><strong>Starlette </strong></a>と完全に互換性があります(そしてベースになっています)。したがって、追加のStarletteコードがあれば、それも機能します。
|
||||
**FastAPI** では **Starlette** のすべての機能が利用できます(FastAPI は強化された Starlette にすぎません):
|
||||
|
||||
`FastAPI`は実際には`Starlette`のサブクラスです。したがって、Starletteをすでに知っているか使用している場合は、ほとんどの機能が同じように機能します。
|
||||
|
||||
**FastAPI**を使用すると、以下のような、**Starlette**のすべての機能を利用できます(FastAPIはStarletteを強化したものにすぎないため):
|
||||
|
||||
* 見事なパフォーマンス。<a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank"> **NodeJS**および**Go**に匹敵する、最速のPythonフレームワークの1つです。</a>
|
||||
|
||||
* **WebSocket**のサポート
|
||||
* **GraphQL**のサポート
|
||||
* プロセス内バックグラウンドタスク
|
||||
* 起動およびシャットダウンイベント
|
||||
* `httpx`に基づいて構築されたテストクライアント
|
||||
* **CORS**、GZip、静的ファイル、ストリーミング応答
|
||||
* **セッションとCookie**のサポート
|
||||
* テストカバレッジ100%
|
||||
* 型アノテーション100%のコードベース
|
||||
|
||||
## Pydanticの特徴
|
||||
|
||||
**FastAPI**は<a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic </strong></a>と完全に互換性があります(そしてベースになっています)。したがって、追加のPydanticコードがあれば、それも機能します。
|
||||
|
||||
データベースのために<abbr title = "Object-Relational Mapper">ORM</abbr>sや、<abbr title = "Object-Document Mapper">ODM</abbr>sなどの、Pydanticに基づく外部ライブラリを備えています。
|
||||
|
||||
これは、すべてが自動的に検証されるため、多くの場合、リクエストから取得したオブジェクトを**データベースに直接**渡すことができるということを意味しています。
|
||||
|
||||
同じことがその逆にも当てはまり、多くの場合、データベースから取得したオブジェクトを**クライアントに直接**渡すことができます。
|
||||
|
||||
**FastAPI**を使用すると、**Pydantic**のすべての機能を利用できます(FastAPIがPydanticに基づいてすべてのデータ処理を行っているため)。
|
||||
|
||||
* **brainfuckなし**:
|
||||
* スキーマ定義のためのマイクロ言語を新たに学習する必要はありません。
|
||||
* Pythonの型を知っている場合は、既にPydanticの使用方法を知っているに等しいです。
|
||||
* ユーザーの **<abbr title = "コードエディターに似た統合開発環境">IDE</abbr>/<abbr title = "コードエラーをチェックするプログラム">リンター</abbr>/思考 とうまく連携します**:
|
||||
* Pydanticのデータ構造は、ユーザーが定義するクラスの単なるインスタンスであるため、オートコンプリート、リンティング、mypy、およびユーザーの直感はすべて、検証済みのデータで適切に機能するはずです。
|
||||
* **複雑な構造**を検証:
|
||||
* 階層的なPydanticモデルや、Pythonの「`typing`」の「`list`」と「`dict`」などの利用。
|
||||
* バリデーターにより、複雑なデータスキーマを明確かつ簡単に定義、チェックし、JSONスキーマとして文書化できます。
|
||||
* 深く**ネストされたJSON**オブジェクトを作成し、それらすべてを検証してアノテーションを付けることができます。
|
||||
* **拡張可能**:
|
||||
* Pydanticでは、カスタムデータ型を定義できます。または、バリデーターデコレーターで装飾されたモデルのメソッドを使用して検証を拡張できます。
|
||||
* 圧倒的なパフォーマンス。<a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank">利用可能な最速クラスの Python フレームワークの 1 つで、**NodeJS** や **Go** と同等です</a>。
|
||||
* **WebSocket** のサポート。
|
||||
* プロセス内バックグラウンドタスク。
|
||||
* 起動およびシャットダウンイベント。
|
||||
* HTTPX に基づくテストクライアント。
|
||||
* **CORS**、GZip、静的ファイル、ストリーミングレスポンス。
|
||||
* **セッションと Cookie** のサポート。
|
||||
* テストカバレッジ 100%。
|
||||
* 型アノテーション 100% のコードベース。
|
||||
|
||||
## Pydanticの機能 { #pydantic-features }
|
||||
|
||||
**FastAPI** は <a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic</strong></a> と完全に互換性があり(かつそれに基づいています)。そのため、手元の Pydantic の追加コードも動作します。
|
||||
|
||||
Pydantic に基づく外部ライブラリ(データベース用の <abbr title="Object-Relational Mapper - オブジェクト関係マッパー">ORM</abbr>、<abbr title="Object-Document Mapper - オブジェクトドキュメントマッパー">ODM</abbr> など)も含まれます。
|
||||
|
||||
これは、すべてが自動的に検証されるため、多くの場合、リクエストから取得したオブジェクトを **そのままデータベースに** 渡せることを意味します。
|
||||
|
||||
逆方向も同様で、多くの場合、データベースから取得したオブジェクトを **そのままクライアントに** 渡せます。
|
||||
|
||||
**FastAPI** では **Pydantic** のすべての機能が利用できます(FastAPI はデータ処理のすべてで Pydantic に基づいています):
|
||||
|
||||
* **brainfuck なし**:
|
||||
* スキーマ定義のための新しいマイクロ言語を学ぶ必要はありません。
|
||||
* Python の型を知っていれば、Pydantic の使い方もわかります。
|
||||
* **<abbr title="Integrated Development Environment - 統合開発環境: コードエディタに類似">IDE</abbr>/<dfn title="コードのエラーを検査するプログラム">リンター</dfn>/思考** と気持ちよく連携します:
|
||||
* Pydantic のデータ構造は、あなたが定義するクラスの単なるインスタンスなので、オートコンプリート、リンティング、mypy、そしてあなたの直感が、検証済みデータに対して適切に機能します。
|
||||
* **複雑な構造** を検証:
|
||||
* 階層的な Pydantic モデルや、Python の `typing` にある `List` や `Dict` などを利用できます。
|
||||
* さらにバリデータにより、複雑なデータスキーマを明確かつ容易に定義・検査でき、JSON Schema として文書化できます。
|
||||
* 深く **ネストされた JSON** オブジェクトを扱え、それらすべてを検証してアノテーションを付与できます。
|
||||
* **拡張可能**:
|
||||
* Pydantic ではカスタムデータ型を定義できますし、バリデータデコレーターで装飾したモデルメソッドで検証を拡張できます。
|
||||
* テストカバレッジ 100%。
|
||||
|
||||
@@ -1,101 +1,255 @@
|
||||
# FastAPIを応援 - ヘルプの入手
|
||||
# FastAPIを応援 - ヘルプの入手 { #help-fastapi-get-help }
|
||||
|
||||
**FastAPI** は気に入りましたか?
|
||||
|
||||
FastAPIやユーザーや開発者を応援したいですか?
|
||||
FastAPIや他のユーザー、作者を応援したいですか?
|
||||
|
||||
もしくは、 **FastAPI** についてヘルプが必要ですか?
|
||||
それとも **FastAPI** についてヘルプが必要ですか?
|
||||
|
||||
とても簡単に応援できます (ただ1、2回クリックするだけのものもあります)。
|
||||
とても簡単に応援できる方法があります(1、2回クリックするだけのものもあります)。
|
||||
|
||||
また、ヘルプを入手する手段がいくつかあります。
|
||||
ヘルプを得る方法もいくつかあります。
|
||||
|
||||
## GitHubで **FastAPI** にStar
|
||||
## ニュースレターを購読 { #subscribe-to-the-newsletter }
|
||||
|
||||
GitHubでFastAPIに「Star」をつけることができます (右上部のStarボタンをクリック): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. ⭐️
|
||||
[**FastAPI and friends** ニュースレター](newsletter.md){.internal-link target=_blank}(配信はまれです)を購読すると、次の情報をキャッチアップできます:
|
||||
|
||||
スターを増やすことで、他のユーザーの目につきやすくなり、多くの人にとって便利なものであることを示せます。
|
||||
* FastAPI と関連プロジェクトのニュース 🚀
|
||||
* ガイド 📝
|
||||
* 機能 ✨
|
||||
* 互換性に影響する変更 🚨
|
||||
* ヒントやコツ ✅
|
||||
|
||||
## GitHubレポジトリのリリースをWatch
|
||||
## X (Twitter) で FastAPI をフォロー { #follow-fastapi-on-x-twitter }
|
||||
|
||||
GitHubでFastAPIを「Watch」できます (右上部のWatchボタンをクリック): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. 👀
|
||||
<a href="https://x.com/fastapi" class="external-link" target="_blank">**X (Twitter)** で @fastapi をフォロー</a>して、**FastAPI** の最新情報を受け取りましょう。🐦
|
||||
|
||||
## GitHubで **FastAPI** にStar { #star-fastapi-in-github }
|
||||
|
||||
GitHubでFastAPIに「Star」をつけることができます(右上部のStarボタンをクリック): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>。⭐️
|
||||
|
||||
スターを増やすことで、他のユーザーの目につきやすくなり、すでに多くの人の役に立っていることが伝わります。
|
||||
|
||||
## GitHubレポジトリのリリースをWatch { #watch-the-github-repository-for-releases }
|
||||
|
||||
GitHubでFastAPIを「Watch」できます(右上部の「Watch」ボタンをクリック): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>。👀
|
||||
|
||||
そこで「Releases only」を選択できます。
|
||||
|
||||
これを行うと、**FastAPI** バグ修正や新機能の実装などの新しいリリース (新しいバージョン) があるたびに (メールで) 通知を受け取れます。
|
||||
これを行うと、バグ修正や新機能を含む **FastAPI** の新しいリリース(新バージョン)があるたびに、(メールで)通知を受け取れます。
|
||||
|
||||
## 開発者とつながる
|
||||
## 開発者とつながる { #connect-with-the-author }
|
||||
|
||||
以下で、<a href="https://tiangolo.com" class="external-link" target="_blank">開発者 (Sebastián Ramírez / `tiangolo`)</a> とコンタクトをとれます:
|
||||
作者である<a href="https://tiangolo.com" class="external-link" target="_blank">私(Sebastián Ramírez / `tiangolo`)</a>とつながれます。
|
||||
|
||||
できること:
|
||||
|
||||
* <a href="https://github.com/tiangolo" class="external-link" target="_blank">**GitHub** でフォロー</a>。
|
||||
* 他のオープンソースプロジェクトを確認できます。何かの助けになるものが見つかるかもしれません。
|
||||
* 新たなオープンソースプロジェクトを作成したときに通知されます。
|
||||
* <a href="https://x.com/tiangolo" class="external-link" target="_blank">**X (Twitter)** でフォロー</a>。
|
||||
* FastAPIの使用用途を教えてください (聞いてみたいです)。
|
||||
* 新たなツールの発表やリリースが聞けます。
|
||||
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">**Linkedin** でつながる</a>。
|
||||
* 新たなツールの発表やリリースが聞けます (ただしX (Twitter)の方が利用頻度が高いですが 🤷♂)。
|
||||
* <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> や <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a> で著作物を読む (またはフォロー)。
|
||||
* アイデアや作成ツールについての記事が読めます。
|
||||
* 新規記事の執筆を通知してくれます。
|
||||
* 役に立つかもしれない、私が作成した他のオープンソースプロジェクトを見られます。
|
||||
* 新しいオープンソースプロジェクトを作成したときにわかります。
|
||||
* <a href="https://x.com/tiangolo" class="external-link" target="_blank">**X (Twitter)** でフォロー</a> または <a href="https://fosstodon.org/@tiangolo" class="external-link" target="_blank">Mastodon</a>。
|
||||
* あなたがどのようにFastAPIを使っているか教えてください(聞けると嬉しいです)。
|
||||
* 新しいツールの告知やリリースを聞けます。
|
||||
* さらに、<a href="https://x.com/fastapi" class="external-link" target="_blank">X (Twitter) の @fastapi</a>(別アカウント)もフォローできます。
|
||||
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">**LinkedIn** でフォロー</a>。
|
||||
* 新しいツールの告知やリリースを聞けます(ただしX (Twitter) の方をよく使っています 🤷♂)。
|
||||
* <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> や <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a> で執筆内容を読む(またはフォロー)。
|
||||
* 私のアイデアや、作成したツールに関する記事を読めます。
|
||||
* 新しい記事を公開したときに読めます。
|
||||
|
||||
## **FastAPI** に関するツイート
|
||||
## **FastAPI** についてツイート { #tweet-about-fastapi }
|
||||
|
||||
<a href="https://x.com/compose/tweet?text=I'm loving FastAPI because... https://github.com/fastapi/fastapi cc @tiangolo" class="external-link" target="_blank">**FastAPI** についてツイート</a>し、開発者や他の人にどこが気に入ったのか教えてください。🎉
|
||||
<a href="https://x.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/fastapi/fastapi" class="external-link" target="_blank">**FastAPI** についてツイート</a>して、なぜ気に入っているのかを私や他の人に教えてください。🎉
|
||||
|
||||
**FastAPI** がどのように使われ、どこが気に入られ、どんなプロジェクト/会社で使われているかなどについて知りたいです。
|
||||
**FastAPI** がどのように使われているか、どこを気に入っているか、どのプロジェクト/会社で使っているか等、聞けると嬉しいです。
|
||||
|
||||
## FastAPIに投票
|
||||
## FastAPIに投票 { #vote-for-fastapi }
|
||||
|
||||
* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">Slantで **FastAPI** に投票</a>
|
||||
* <a href="https://alternativeto.net/software/fastapi/" class="external-link" target="_blank">AlternativeToで **FastAPI** に投票</a>
|
||||
* <a href="https://github.com/marmelab/awesome-rest/pull/93" class="external-link" target="_blank">awesome-restで **FastAPI** に投票</a>
|
||||
* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">Slantで **FastAPI** に投票</a>。
|
||||
* <a href="https://alternativeto.net/software/fastapi/about/" class="external-link" target="_blank">AlternativeToで **FastAPI** に投票</a>。
|
||||
* <a href="https://stackshare.io/pypi-fastapi" class="external-link" target="_blank">StackShare で **FastAPI** を使っていると宣言</a>。
|
||||
|
||||
## GitHub issuesで他の人を助ける
|
||||
## GitHubで質問に困っている人を助ける { #help-others-with-questions-in-github }
|
||||
|
||||
<a href="https://github.com/fastapi/fastapi/issues" class="external-link" target="_blank">既存のissues</a>を確認して、他の人を助けてみてください。皆さんが回答を知っているかもしれない質問がほとんどです。🤓
|
||||
次の場所で、他の人の質問を手助けできます:
|
||||
|
||||
## GitHubレポジトリをWatch
|
||||
* <a href="https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered" class="external-link" target="_blank">GitHub Discussions</a>
|
||||
* <a href="https://github.com/fastapi/fastapi/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aquestion+-label%3Aanswered+" class="external-link" target="_blank">GitHub Issues</a>
|
||||
|
||||
GitHubでFastAPIを「watch」できます (右上部の「watch」ボタンをクリック): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. 👀
|
||||
多くの場合、その質問の答えをすでに知っているかもしれません。🤓
|
||||
|
||||
「Releases only」ではなく「Watching」を選択すると、新たなissueが立てられた際に通知されます。
|
||||
もし多くの人の質問に答えて助けてくれたなら、あなたは公式の[FastAPI Expert](fastapi-people.md#fastapi-experts){.internal-link target=_blank}になります。🎉
|
||||
|
||||
そして、issueを解決し他の人を助けることができます。
|
||||
最も大事なポイントは「親切であること」を心がけることです。人はフラストレーションを抱えてやって来るので、必ずしも最良の聞き方をしているとは限りませんが、できる限り親切に対応しましょう。🤗
|
||||
|
||||
## issuesを立てる
|
||||
**FastAPI** コミュニティは親切で歓迎的であることを目指しています。同時に、いじめや他者への無礼な振る舞いは受け入れないでください。お互いを大事にしましょう。
|
||||
|
||||
GitHubレポジトリで<a href="https://github.com/fastapi/fastapi/issues/new/choose" class="external-link" target="_blank">新たなissueを立てられます</a>。例えば:
|
||||
---
|
||||
|
||||
* 質問、または、問題の報告
|
||||
* 新機能の提案
|
||||
以下は(Discussions や Issues で)他の人の質問を手助けする方法です:
|
||||
|
||||
**Note**: issueを立てた人は、他の人の手助けもお願いします。😉
|
||||
### 質問を理解する { #understand-the-question }
|
||||
|
||||
## プルリクエストをする
|
||||
* 質問者の「目的」やユースケースを理解できるか確認します。
|
||||
|
||||
以下の様な<a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">プルリクエストを作成</a>できます:
|
||||
* 次に、質問(大半は質問です)が「明確」か確認します。
|
||||
|
||||
* ドキュメントのタイプミスを修正。
|
||||
* 新たなドキュメントセクションを提案。
|
||||
* 既存のissue/バグを修正。
|
||||
* 新機能を追加。
|
||||
* 多くの場合、ユーザーが想像した解決策についての質問になっていますが、もっと「良い」方法があるかもしれません。問題やユースケースをよりよく理解できれば、より良い「代替解決策」を提案できるかもしれません。
|
||||
|
||||
## 開発者のスポンサーになる
|
||||
* 質問が理解できない場合は、さらに「詳細」を尋ねます。
|
||||
|
||||
<a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a>を通して開発者を経済的にサポートできます。
|
||||
### 問題を再現する { #reproduce-the-problem }
|
||||
|
||||
そこで、感謝の気持ちを伝えるためにコーヒー☕️を買うことができます 😄。
|
||||
多くのケースや質問は、その人の「元のコード」に関係しています。
|
||||
|
||||
## FastAPIを強化するツールのスポンサーになる
|
||||
しばしばコードの断片だけが共有されますが、それでは問題を「再現」するには不十分です。
|
||||
|
||||
ドキュメントで見たように、FastAPIはStarletteとPydanticという巨人の肩に乗っています。
|
||||
* ローカルで同じエラーや挙動を確認できるように、またはユースケースをよりよく理解できるように、**コピー&ペースト**して実行できる<a href="https://stackoverflow.com/help/minimal-reproducible-example" class="external-link" target="_blank">最小の再現可能な例</a>の提供を依頼できます。
|
||||
|
||||
以下のスポンサーになることもできます:
|
||||
* とても寛大な気分なら、問題の説明だけをもとに、あなた自身でそのような**例を作成**してみることもできます。ただし時間がかかる可能性が高いので、まずは問題の明確化を依頼した方が良い場合もあります。
|
||||
|
||||
* <a href="https://github.com/sponsors/samuelcolvin" class="external-link" target="_blank">Samuel Colvin (Pydantic)</a>
|
||||
* <a href="https://github.com/sponsors/encode" class="external-link" target="_blank">Encode (Starlette, Uvicorn)</a>
|
||||
### 解決策を提案する { #suggest-solutions }
|
||||
|
||||
* 質問を理解できたら、可能な**回答**を提示できます。
|
||||
|
||||
* 多くの場合、相手の「根本的な問題やユースケース」を理解することが重要です。相手が試している方法より良い解決方法があるかもしれないからです。
|
||||
|
||||
### クローズを依頼する { #ask-to-close }
|
||||
|
||||
もし相手が返信してきて、あなたが問題を解決できたなら、おめでとう、**あなたはヒーロー**です!🦸
|
||||
|
||||
* その場合、次のように依頼できます:
|
||||
|
||||
* GitHub Discussions: コメントを**回答**としてマークしてもらう。
|
||||
* GitHub Issues: issue を**クローズ**してもらう。
|
||||
|
||||
## GitHubレポジトリをWatch { #watch-the-github-repository }
|
||||
|
||||
GitHubでFastAPIを「Watch」できます(右上部の「Watch」ボタンをクリック): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>。👀
|
||||
|
||||
「Releases only」ではなく「Watching」を選択すると、新しい issue や質問が作成されたときに通知を受け取れます。新しい issue のみ、Discussions のみ、PR のみ、など通知対象を絞ることもできます。
|
||||
|
||||
その上で、そうした質問の解決を手助けできます。
|
||||
|
||||
## 質問する { #ask-questions }
|
||||
|
||||
GitHubレポジトリで<a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">新しい質問</a>を作成できます。例えば:
|
||||
|
||||
* **質問**をする、または**問題**について尋ねる。
|
||||
* 新しい**機能**を提案する。
|
||||
|
||||
**Note**: もしそうするなら、他の人の手助けもお願いします。😉
|
||||
|
||||
## プルリクエストをレビュー { #review-pull-requests }
|
||||
|
||||
他の人からのプルリクエストのレビューを手伝ってもらえます。
|
||||
|
||||
ここでも、できる限り親切であるようにしてください。🤗
|
||||
|
||||
---
|
||||
|
||||
プルリクエストをレビューするときのポイントです:
|
||||
|
||||
### 問題を理解する { #understand-the-problem }
|
||||
|
||||
* まず、そのプルリクエストが解決しようとしている**問題を理解**してください。長めの議論が GitHub Discussion や issue にあるかもしれません。
|
||||
|
||||
* その問題は実は**別の方法**で解決でき、プルリクエスト自体が不要な場合もあります。その場合は、その提案や質問をしても良いでしょう。
|
||||
|
||||
### スタイルは気にしすぎない { #dont-worry-about-style }
|
||||
|
||||
* コミットメッセージのスタイルなどはあまり気にしなくて大丈夫です。私は squash and merge を使い、コミットを手動で調整します。
|
||||
|
||||
* スタイルルールについても心配無用です。自動化ツールがすでにチェックしています。
|
||||
|
||||
ほかにスタイルや一貫性の要件があれば、私から直接依頼しますし、必要な変更を上に積む形でコミットを追加します。
|
||||
|
||||
### コードを確認 { #check-the-code }
|
||||
|
||||
* コードを確認して読み、妥当かどうかを見て、**ローカルで実行**し、本当に問題を解決しているか確かめてください。
|
||||
|
||||
* そのうえで、それを行ったことを**コメント**で伝えてください。そうすれば、実際に確認してくれたとわかります。
|
||||
|
||||
/// info | 情報
|
||||
|
||||
残念ながら、承認が複数ついただけのPRを、そのまま信頼することはできません。
|
||||
|
||||
説明が魅力的なためか、3件、5件以上の承認がついていても、実際にPRを確認すると壊れていたり、バグがあったり、主張する問題を解決していなかったりすることが何度もありました。😅
|
||||
|
||||
ですので、実際にコードを読み、実行して確認し、それをコメントで知らせてもらえることが本当に重要です。🤓
|
||||
|
||||
///
|
||||
|
||||
* もしPRを簡素化できそうなら、その依頼をしても構いませんが、細かい点にこだわり過ぎる必要はありません。主観的な見方が多く(私にもあります 🙈)、基本的な点に集中できるとより良いでしょう。
|
||||
|
||||
### テスト { #tests }
|
||||
|
||||
* PRに**テスト**があるか確認を手伝ってください。
|
||||
|
||||
* PR前はテストが**失敗**することを確認します。🚨
|
||||
|
||||
* そしてPR後にテストが**成功**することを確認します。✅
|
||||
|
||||
* 多くのPRにはテストがありません。テストの追加を**リマインド**したり、テストを**提案**したりできます。これは最も時間を消費する部分の一つで、大いに助けになります。
|
||||
|
||||
* 何を試したかもコメントしてください。そうすれば、確認してくれたことがわかります。🤓
|
||||
|
||||
## プルリクエストを作成 { #create-a-pull-request }
|
||||
|
||||
[貢献](contributing.md){.internal-link target=_blank}として、次のようにプルリクエストでソースコードに貢献できます:
|
||||
|
||||
* ドキュメントで見つけたタイポの修正。
|
||||
* 自分が作成/発見した FastAPI に関する記事・動画・ポッドキャストを、<a href="https://github.com/fastapi/fastapi/edit/master/docs/en/data/external_links.yml" class="external-link" target="_blank">このファイルを編集</a>して共有。
|
||||
* 該当セクションの先頭にリンクを追加してください。
|
||||
* 自分の言語への[ドキュメント翻訳を手伝う](contributing.md#translations){.internal-link target=_blank}。
|
||||
* 他の人が作成した翻訳のレビューも手伝えます。
|
||||
* 新しいドキュメントセクションの提案。
|
||||
* 既存のissue/バグの修正。
|
||||
* テストを追加してください。
|
||||
* 新機能の追加。
|
||||
* テストを追加してください。
|
||||
* 関連があればドキュメントも追加してください。
|
||||
|
||||
## FastAPIのメンテナンスを手伝う { #help-maintain-fastapi }
|
||||
|
||||
**FastAPI** のメンテナンスを手伝ってください!🤓
|
||||
|
||||
やることはたくさんあり、その多くは**あなた**にもできます。
|
||||
|
||||
今すぐできる主なタスクは次のとおりです:
|
||||
|
||||
* [GitHubで質問に困っている人を助ける](#help-others-with-questions-in-github){.internal-link target=_blank}(上のセクションを参照)。
|
||||
* [プルリクエストをレビュー](#review-pull-requests){.internal-link target=_blank}(上のセクションを参照)。
|
||||
|
||||
この2つが**最も時間を消費**します。FastAPI のメンテナンス作業の中心です。
|
||||
|
||||
これを手伝ってもらえると、**FastAPIのメンテナンスに貢献**し、**より速く・より良く前進**できるようになります。🚀
|
||||
|
||||
## チャットに参加 { #join-the-chat }
|
||||
|
||||
👥 <a href="https://discord.gg/VQjSZaeJmf" class="external-link" target="_blank">Discord チャットサーバー</a> 👥 に参加し、FastAPI コミュニティのみんなと交流しましょう。
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
質問は <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">GitHub Discussions</a> に投稿してください。そこなら[FastAPI Experts](fastapi-people.md#fastapi-experts){.internal-link target=_blank}から助けてもらえる可能性がずっと高いです。
|
||||
|
||||
チャットは一般的な会話のみに使いましょう。
|
||||
|
||||
///
|
||||
|
||||
### 質問でチャットを使わない { #dont-use-the-chat-for-questions }
|
||||
|
||||
チャットは「自由な会話」がしやすいため、一般的すぎて答えにくい質問になりがちです。そのため、回答が得られない可能性があります。
|
||||
|
||||
GitHub では、テンプレートが正しい形で質問を書くのを助けてくれるため、良い回答を得やすくなりますし、質問する前に自分で問題を解決できることもあります。さらにGitHubなら、時間がかかっても私が必ずすべてに回答できるようにできます。チャットでは私個人にはそれができません。😅
|
||||
|
||||
チャットでの会話はGitHubほど検索しやすくないため、質問と回答が会話に埋もれがちです。そして、[FastAPI Expert](fastapi-people.md#fastapi-experts){.internal-link target=_blank}になるためにカウントされるのはGitHub上の活動だけです。ですから、GitHubの方が注目を集めやすいでしょう。
|
||||
|
||||
一方で、チャットには数千人のユーザーがいるため、ほぼ常に誰かと会話できる可能性が高いです。😄
|
||||
|
||||
## 作者をスポンサー { #sponsor-the-author }
|
||||
|
||||
あなたの**製品/会社**が **FastAPI** に依存している、または関連しており、そのユーザーにリーチしたい場合は、<a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a> を通じて作者(私)を支援できます。プランに応じて、ドキュメントにバッジが表示されるなどの特典がある場合があります。🎁
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
# 歴史、設計、そしてこれから
|
||||
# 歴史、設計、そしてこれから { #history-design-and-future }
|
||||
|
||||
少し前に、<a href="https://github.com/fastapi/fastapi/issues/3#issuecomment-454956920" class="external-link" target="_blank">**FastAPI**
|
||||
のユーザーに以下の様に尋ねられました</a>:
|
||||
少し前に、<a href="https://github.com/fastapi/fastapi/issues/3#issuecomment-454956920" class="external-link" target="_blank">**FastAPI**のユーザーに以下の様に尋ねられました</a>:
|
||||
|
||||
> このプロジェクトの歴史は?何もないところから、数週間ですごいものができているようです。 [...]
|
||||
|
||||
これがその歴史のほんの一部です。
|
||||
|
||||
## 代替手段
|
||||
## 代替手段 { #alternatives }
|
||||
|
||||
数年前から、私は複雑な要件を持つAPI (機械学習、分散システム、非同期ジョブ、NoSQLデータベースなど) を作成しており、いくつかの開発者チームを率いています。
|
||||
|
||||
@@ -19,7 +18,7 @@
|
||||
|
||||
<blockquote markdown="1">
|
||||
|
||||
**FastAPI**は、代替ツールのこれまでの働きがなければ存在しなかったでしょう。
|
||||
**FastAPI**は、他の人々のこれまでの働きがなければ存在しなかったでしょう。
|
||||
|
||||
以前に作られた多くのツールが、作成における刺激として役立ってきました。
|
||||
|
||||
@@ -29,7 +28,7 @@
|
||||
|
||||
</blockquote>
|
||||
|
||||
## 調査
|
||||
## 調査 { #investigation }
|
||||
|
||||
すべて既存の代替手段を使うことで、そのすべてを学び、アイデアを得て、自分や一緒に仕事をしてきた開発者のチームにとって最良の方法で組み合わせる機会を得ました。
|
||||
|
||||
@@ -39,7 +38,7 @@
|
||||
|
||||
そこで、**FastAPI**のコードを書き始める前に、OpenAPI、JSON Schema、OAuth2などの仕様を数ヶ月かけて勉強し、それらの関係、重複する箇所、相違点を理解しました。
|
||||
|
||||
## 設計
|
||||
## 設計 { #design }
|
||||
|
||||
その後、 (FastAPIを使う開発者として) ユーザーが欲しい「API」の設計に時間を費やしました。
|
||||
|
||||
@@ -53,19 +52,19 @@
|
||||
|
||||
すべての箇所で、すべての開発者に最高の開発体験を提供しました。
|
||||
|
||||
## 要件
|
||||
## 要件 { #requirements }
|
||||
|
||||
いくつかの代替手法を試したあと、私は<a href="https://docs.pydantic.dev/" class="external-link" target="_blank">**Pydantic**</a>の強みを利用することを決めました。
|
||||
|
||||
そして、JSON Schemaに完全に準拠するようにしたり、制約宣言を定義するさまざまな方法をサポートしたり、いくつかのエディターでのテストに基づいてエディターのサポート (型チェック、自動補完) を改善するために貢献しました。
|
||||
|
||||
開発中、もう1つの重要な鍵となる<a href="https://www.starlette.dev/" class="external-link" target="_blank">**Starlette**</a>、にも貢献しました。
|
||||
開発中、もう1つの重要な鍵となる<a href="https://www.starlette.dev/" class="external-link" target="_blank">**Starlette**</a>にも貢献しました。
|
||||
|
||||
## 開発
|
||||
## 開発 { #development }
|
||||
|
||||
私が**FastAPI**自体の作成を開始した時には、ほとんどの部分がすでに準備されており、設計が定義され、必要な条件とツールの準備ができていました。そして規格や仕様に関する知識が、明確になり、更新されていました。
|
||||
|
||||
## これから
|
||||
## これから { #future }
|
||||
|
||||
この時点ですでに、これらのアイデアを持った**FastAPI**が多くの人の役に立っていることは明らかです。
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
もしセキュリティ上の欠陥がソースコードにあるならば、それは存在したままです。
|
||||
|
||||
ドキュメンテーションを非表示にするのは、単にあなたのAPIへのアクセス方法を難解にするだけでなく、同時にあなた自身の本番環境でのAPIのデバッグを困難にしてしまう可能性があります。単純に、 <a href="https://en.wikipedia.org/wiki/Security_through_obscurity" class="external-link" target="_blank">Security through obscurity</a> の一つの形態として考えられるでしょう。
|
||||
ドキュメンテーションを非表示にするのは、単にあなたのAPIへのアクセス方法を難解にするだけでなく、同時にあなた自身の本番環境でのAPIのデバッグを困難にしてしまう可能性があります。単純に、 <a href="https://en.wikipedia.org/wiki/Security_through_obscurity" class="external-link" target="_blank">秘匿によるセキュリティ</a> の一つの形態として考えられるでしょう。
|
||||
|
||||
もしあなたのAPIのセキュリティを強化したいなら、いくつかのよりよい方法があります。例を示すと、
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
例えば、
|
||||
|
||||
{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
|
||||
{* ../../docs_src/conditional_openapi/tutorial001_py310.py hl[6,11] *}
|
||||
|
||||
ここでは `openapi_url` の設定を、デフォルトの `"/openapi.json"` のまま宣言しています。
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ FastAPI は、Python の標準である型ヒントに基づいて Python で AP
|
||||
* **高速**: **NodeJS** や **Go** 並みのとても高いパフォーマンス(Starlette と Pydantic のおかげです)。 [利用可能な最も高速な Python フレームワークの一つです](#performance)。
|
||||
* **高速なコーディング**: 開発速度を約 200%〜300% 向上させます。*
|
||||
* **少ないバグ**: 開発者起因のヒューマンエラーを約 40% 削減します。*
|
||||
* **直感的**: 素晴らしいエディタサポート。あらゆる場所で <abbr title="also known as auto-complete, autocompletion, IntelliSense">補完</abbr> が使えます。デバッグ時間を削減します。
|
||||
* **直感的**: 素晴らしいエディタサポート。<dfn title="別名: auto-complete、autocompletion、IntelliSense">補完</dfn> があらゆる場所で使えます。デバッグ時間を削減します。
|
||||
* **簡単**: 簡単に利用・習得できるようにデザインされています。ドキュメントを読む時間を削減します。
|
||||
* **短い**: コードの重複を最小限にします。各パラメータ宣言から複数の機能を得られます。バグも減ります。
|
||||
* **堅牢性**: 自動対話型ドキュメントにより、本番環境向けのコードが得られます。
|
||||
@@ -127,7 +127,7 @@ FastAPI は、Python の標準である型ヒントに基づいて Python で AP
|
||||
|
||||
<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>
|
||||
|
||||
Web API の代わりにターミナルで使用する <abbr title="Command Line Interface">CLI</abbr> アプリを構築する場合は、<a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a> を確認してください。
|
||||
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** を意図しています。 ⌨️ 🚀
|
||||
|
||||
@@ -368,7 +368,7 @@ item: Item
|
||||
* データの検証:
|
||||
* データが無効な場合に自動で明確なエラーを返します。
|
||||
* 深い入れ子になった JSON オブジェクトでも検証が可能です。
|
||||
* 入力データの <abbr title="also known as: serialization, parsing, marshalling">変換</abbr>: ネットワークから Python のデータや型へ。以下から読み取ります:
|
||||
* 入力データの <dfn title="別名: serialization、parsing、marshalling">変換</dfn>: ネットワークから Python のデータや型へ。以下から読み取ります:
|
||||
* JSON。
|
||||
* パスパラメータ。
|
||||
* クエリパラメータ。
|
||||
@@ -376,7 +376,7 @@ item: Item
|
||||
* ヘッダー。
|
||||
* フォーム。
|
||||
* ファイル。
|
||||
* 出力データの <abbr title="also known as: serialization, parsing, marshalling">変換</abbr>: Python のデータや型からネットワークデータへ(JSON として)変換します:
|
||||
* 出力データの <dfn title="別名: serialization、parsing、marshalling">変換</dfn>: Python のデータや型からネットワークデータへ(JSON として)変換します:
|
||||
* Python の型(`str`、`int`、`float`、`bool`、`list` など)の変換。
|
||||
* `datetime` オブジェクト。
|
||||
* `UUID` オブジェクト。
|
||||
@@ -439,7 +439,7 @@ item: Item
|
||||
|
||||
* **ヘッダー**、**Cookie**、**フォームフィールド**、**ファイル**など、他のさまざまな場所からの **パラメータ** 宣言。
|
||||
* `maximum_length` や `regex` のような **検証制約** を設定する方法。
|
||||
* 非常に強力で使いやすい **<abbr title="also known as components, resources, providers, services, injectables">依存性注入</abbr>** システム。
|
||||
* 非常に強力で使いやすい **<dfn title="別名: components、resources、providers、services、injectables">依存性注入</dfn>** システム。
|
||||
* **JWT トークン**を用いた **OAuth2** や **HTTP Basic** 認証のサポートを含む、セキュリティと認証。
|
||||
* **深くネストされた JSON モデル**を宣言するための、より高度な(しかし同様に簡単な)手法(Pydantic のおかげです)。
|
||||
* <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> および他のライブラリによる **GraphQL** 統合。
|
||||
@@ -524,7 +524,7 @@ 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> - `request.form()` とともに、フォームの <abbr title="converting the string that comes from an HTTP request into Python data">「parsing」</abbr> をサポートしたい場合に必要です。
|
||||
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - `request.form()` とともに、フォームの <dfn title="HTTP リクエストから届く文字列を Python データに変換すること">「parsing」</dfn> をサポートしたい場合に必要です。
|
||||
|
||||
FastAPI によって使用されるもの:
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Pythonの型の紹介 { #python-types-intro }
|
||||
|
||||
Pythonではオプションの「型ヒント」(「型アノテーション」とも呼ばれます)がサポートされています。
|
||||
Python にはオプションの「型ヒント」(「型アノテーション」とも呼ばれます)がサポートされています。
|
||||
|
||||
これらの **「型ヒント」** またはアノテーションは、変数の<abbr title="for example: str, int, float, bool">型</abbr>を宣言できる特別な構文です。
|
||||
これらの **「型ヒント」** やアノテーションは、変数の<dfn title="例えば: str、int、float、bool">型</dfn>を宣言できる特別な構文です。
|
||||
|
||||
変数に型を宣言することで、エディターやツールがより良いサポートを提供できます。
|
||||
|
||||
これはPythonの型ヒントについての **クイックチュートリアル/リフレッシュ** にすぎません。**FastAPI** で使用するために必要な最低限のことだけをカバーしています。...実際には本当に少ないです。
|
||||
これは Python の型ヒントについての **クイックチュートリアル/リフレッシュ** にすぎません。**FastAPI** で使うために必要な最低限のことだけをカバーしています。...実際には本当に少ないです。
|
||||
|
||||
**FastAPI** はすべてこれらの型ヒントに基づいており、多くの強みと利点を与えてくれます。
|
||||
|
||||
@@ -14,7 +14,7 @@ Pythonではオプションの「型ヒント」(「型アノテーション
|
||||
|
||||
/// note | 備考
|
||||
|
||||
もしあなたがPythonの専門家で、すでに型ヒントについてすべて知っているのであれば、次の章まで読み飛ばしてください。
|
||||
もしあなたが Python の専門家で、すでに型ヒントについてすべて知っているのであれば、次の章まで読み飛ばしてください。
|
||||
|
||||
///
|
||||
|
||||
@@ -22,7 +22,7 @@ Pythonではオプションの「型ヒント」(「型アノテーション
|
||||
|
||||
簡単な例から始めてみましょう:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial001_py39.py *}
|
||||
{* ../../docs_src/python_types/tutorial001_py310.py *}
|
||||
|
||||
このプログラムを呼び出すと、以下が出力されます:
|
||||
|
||||
@@ -32,11 +32,11 @@ John Doe
|
||||
|
||||
この関数は以下のようなことを行います:
|
||||
|
||||
* `first_name`と`last_name`を取得します。
|
||||
* `title()`を用いて、それぞれの最初の文字を大文字に変換します。
|
||||
* 真ん中にスペースを入れて<abbr title="Puts them together, as one. With the contents of one after the other.">連結</abbr>します。
|
||||
* `first_name` と `last_name` を取得します。
|
||||
* `title()` を用いて、それぞれの最初の文字を大文字に変換します。
|
||||
* 真ん中にスペースを入れて<dfn title="1つにまとめます。片方の内容をもう片方の後ろに続けます。">連結</dfn>します。
|
||||
|
||||
{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
|
||||
{* ../../docs_src/python_types/tutorial001_py310.py hl[2] *}
|
||||
|
||||
### 編集 { #edit-it }
|
||||
|
||||
@@ -48,11 +48,11 @@ John Doe
|
||||
|
||||
しかし、そうすると「最初の文字を大文字に変換するあのメソッド」を呼び出す必要があります。
|
||||
|
||||
それは`upper`でしたか?`uppercase`でしたか?`first_uppercase`?`capitalize`?
|
||||
それは `upper` でしたか?`uppercase` でしたか?`first_uppercase`?`capitalize`?
|
||||
|
||||
そして、古くからプログラマーの友人であるエディタで自動補完を試してみます。
|
||||
|
||||
関数の最初のパラメータ`first_name`を入力し、ドット(`.`)を入力してから、`Ctrl+Space`を押すと補完が実行されます。
|
||||
関数の最初のパラメータ `first_name` を入力し、ドット(`.`)を入力してから、`Ctrl+Space` を押すと補完が実行されます。
|
||||
|
||||
しかし、悲しいことに、これはなんの役にも立ちません:
|
||||
|
||||
@@ -78,7 +78,7 @@ John Doe
|
||||
|
||||
それが「型ヒント」です:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
|
||||
{* ../../docs_src/python_types/tutorial002_py310.py hl[1] *}
|
||||
|
||||
これは、以下のようにデフォルト値を宣言するのと同じではありません:
|
||||
|
||||
@@ -94,7 +94,7 @@ John Doe
|
||||
|
||||
しかし今、あなたが再びその関数を作成している最中に、型ヒントを使っていると想像してみてください。
|
||||
|
||||
同じタイミングで`Ctrl+Space`で自動補完を実行すると、以下のようになります:
|
||||
同じタイミングで `Ctrl+Space` で自動補完を実行すると、以下のようになります:
|
||||
|
||||
<img src="/img/python-types/image02.png">
|
||||
|
||||
@@ -106,15 +106,15 @@ John Doe
|
||||
|
||||
この関数を見てください。すでに型ヒントを持っています:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
|
||||
{* ../../docs_src/python_types/tutorial003_py310.py hl[1] *}
|
||||
|
||||
エディタは変数の型を知っているので、補完だけでなく、エラーチェックをすることもできます:
|
||||
|
||||
<img src="/img/python-types/image04.png">
|
||||
|
||||
これで`age`を`str(age)`で文字列に変換して修正する必要があることがわかります:
|
||||
これで `age` を `str(age)` で文字列に変換して修正する必要があることがわかります:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
|
||||
{* ../../docs_src/python_types/tutorial004_py310.py hl[2] *}
|
||||
|
||||
## 型の宣言 { #declaring-types }
|
||||
|
||||
@@ -124,7 +124,7 @@ John Doe
|
||||
|
||||
### 単純な型 { #simple-types }
|
||||
|
||||
`str`だけでなく、Pythonの標準的な型すべてを宣言できます。
|
||||
`str` だけでなく、Python の標準的な型すべてを宣言できます。
|
||||
|
||||
例えば、以下を使用可能です:
|
||||
|
||||
@@ -133,51 +133,54 @@ John Doe
|
||||
* `bool`
|
||||
* `bytes`
|
||||
|
||||
{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
|
||||
{* ../../docs_src/python_types/tutorial005_py310.py hl[1] *}
|
||||
|
||||
### 型パラメータを持つジェネリック型 { #generic-types-with-type-parameters }
|
||||
### `typing` モジュール { #typing-module }
|
||||
|
||||
データ構造の中には、`dict`、`list`、`set`、`tuple`のように他の値を含むことができるものがあります。また内部の値も独自の型を持つことができます。
|
||||
いくつかの追加のユースケースでは、標準ライブラリの `typing` モジュールから何かをインポートする必要があるかもしれません。例えば「任意の型」を受け付けることを宣言したい場合、`typing` の `Any` を使えます:
|
||||
|
||||
内部の型を持つこれらの型は「**generic**」型と呼ばれます。そして、内部の型も含めて宣言することが可能です。
|
||||
```python
|
||||
from typing import Any
|
||||
|
||||
これらの型や内部の型を宣言するには、Pythonの標準モジュール`typing`を使用できます。これらの型ヒントをサポートするために特別に存在しています。
|
||||
|
||||
#### 新しいPythonバージョン { #newer-versions-of-python }
|
||||
def some_function(data: Any):
|
||||
print(data)
|
||||
```
|
||||
|
||||
`typing`を使う構文は、Python 3.6から最新バージョンまで(Python 3.9、Python 3.10などを含む)すべてのバージョンと **互換性** があります。
|
||||
### ジェネリック型 { #generic-types }
|
||||
|
||||
Pythonが進化するにつれ、**新しいバージョン** ではこれらの型アノテーションへのサポートが改善され、多くの場合、型アノテーションを宣言するために`typing`モジュールをインポートして使う必要すらなくなります。
|
||||
一部の型は、角括弧内で「型パラメータ」を受け取り、内部の型を定義できます。例えば「文字列のリスト」は `list[str]` として宣言します。
|
||||
|
||||
プロジェクトでより新しいPythonバージョンを選べるなら、その追加のシンプルさを活用できます。
|
||||
このように型パラメータを取れる型は **Generic types**(ジェネリクス)と呼ばれます。
|
||||
|
||||
ドキュメント全体で、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`
|
||||
* `tuple`
|
||||
* `set`
|
||||
* `dict`
|
||||
|
||||
#### List { #list }
|
||||
|
||||
例えば、`str`の`list`の変数を定義してみましょう。
|
||||
例えば、`str` の `list` の変数を定義してみましょう。
|
||||
|
||||
同じコロン(`:`)の構文で変数を宣言します。
|
||||
|
||||
型として、`list`を指定します。
|
||||
型として、`list` を指定します。
|
||||
|
||||
リストはいくつかの内部の型を含む型なので、それらを角括弧で囲みます:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
|
||||
{* ../../docs_src/python_types/tutorial006_py310.py hl[1] *}
|
||||
|
||||
/// info | 情報
|
||||
|
||||
角括弧内の内部の型は「型パラメータ」と呼ばれています。
|
||||
|
||||
この場合、`str`は`list`に渡される型パラメータです。
|
||||
この場合、`str` は `list` に渡される型パラメータです。
|
||||
|
||||
///
|
||||
|
||||
つまり: 変数`items`は`list`であり、このリストの各項目は`str`です。
|
||||
つまり: 変数 `items` は `list` であり、このリストの各項目は `str` です。
|
||||
|
||||
そうすることで、エディタはリストの項目を処理している間にもサポートを提供できます。
|
||||
|
||||
@@ -185,78 +188,54 @@ Pythonが進化するにつれ、**新しいバージョン** ではこれらの
|
||||
|
||||
型がなければ、それはほぼ不可能です。
|
||||
|
||||
変数`item`はリスト`items`の要素の一つであることに注意してください。
|
||||
変数 `item` はリスト `items` の要素の一つであることに注意してください。
|
||||
|
||||
それでも、エディタはそれが`str`であることを知っていて、そのためのサポートを提供しています。
|
||||
それでも、エディタはそれが `str` であることを知っていて、そのためのサポートを提供しています。
|
||||
|
||||
#### Tuple と Set { #tuple-and-set }
|
||||
|
||||
`tuple`と`set`の宣言も同様です:
|
||||
`tuple` と `set` の宣言も同様です:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
|
||||
{* ../../docs_src/python_types/tutorial007_py310.py hl[1] *}
|
||||
|
||||
つまり:
|
||||
|
||||
* 変数`items_t`は`int`、別の`int`、`str`の3つの項目を持つ`tuple`です。
|
||||
* 変数`items_s`は`set`であり、その各項目は`bytes`型です。
|
||||
* 変数 `items_t` は `int`、別の `int`、`str` の 3 つの項目を持つ `tuple` です。
|
||||
* 変数 `items_s` は `set` であり、その各項目は `bytes` 型です。
|
||||
|
||||
#### Dict { #dict }
|
||||
|
||||
`dict`を定義するには、カンマ区切りで2つの型パラメータを渡します。
|
||||
`dict` を定義するには、カンマ区切りで 2 つの型パラメータを渡します。
|
||||
|
||||
最初の型パラメータは`dict`のキーです。
|
||||
最初の型パラメータは `dict` のキーです。
|
||||
|
||||
2番目の型パラメータは`dict`の値です:
|
||||
2 番目の型パラメータは `dict` の値です:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
|
||||
{* ../../docs_src/python_types/tutorial008_py310.py hl[1] *}
|
||||
|
||||
つまり:
|
||||
|
||||
* 変数`prices`は`dict`です:
|
||||
* この`dict`のキーは`str`型です(例えば、各項目の名前)。
|
||||
* この`dict`の値は`float`型です(例えば、各項目の価格)。
|
||||
* 変数 `prices` は `dict` です:
|
||||
* この `dict` のキーは `str` 型です(例えば、各項目の名前)。
|
||||
* この `dict` の値は `float` 型です(例えば、各項目の価格)。
|
||||
|
||||
#### Union { #union }
|
||||
|
||||
変数が**複数の型のいずれか**になり得ることを宣言できます。例えば、`int`または`str`です。
|
||||
変数が **複数の型のいずれか** になり得ることを宣言できます。例えば、`int` または `str` です。
|
||||
|
||||
Python 3.6以上(Python 3.10を含む)では、`typing`の`Union`型を使い、角括弧の中に受け付ける可能性のある型を入れられます。
|
||||
それを定義するには、両方の型を区切るために <dfn title="「ビット単位の OR 演算子」とも呼ばれますが、ここでの意味とは関係ありません。">縦棒(`|`)</dfn> を使います。
|
||||
|
||||
Python 3.10では、受け付ける可能性のある型を<abbr title='also called "bitwise or operator", but that meaning is not relevant here'>縦棒(`|`)</abbr>で区切って書ける **新しい構文** もあります。
|
||||
|
||||
//// tab | Python 3.10+
|
||||
これは「ユニオン(union)」と呼ばれます。変数がそれら 2 つの型の集合の和集合のいずれかになり得るからです。
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial008b_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
これは `item` が `int` または `str` になり得ることを意味します.
|
||||
|
||||
//// tab | Python 3.9+
|
||||
#### `None` の可能性 { #possibly-none }
|
||||
|
||||
```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`も使えることを意味します:
|
||||
値が `str` のような型を持つ可能性がある一方で、`None` にもなり得ることを宣言できます。
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
@@ -266,120 +245,31 @@ Python 3.6以上(Python 3.10を含む)では、`typing`モジュールから
|
||||
|
||||
////
|
||||
|
||||
//// 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 }
|
||||
|
||||
Python 3.10未満のバージョンを使っている場合、これは私のとても **主観的** な観点からのヒントです:
|
||||
|
||||
* 🚨 `Optional[SomeType]`は避けてください
|
||||
* 代わりに ✨ **`Union[SomeType, None]`を使ってください** ✨
|
||||
|
||||
どちらも等価で、内部的には同じですが、`Optional`より`Union`をおすすめします。というのも「**optional**」という単語は値がオプションであることを示唆するように見えますが、実際には「`None`になり得る」という意味であり、オプションではなく必須である場合でもそうだからです。
|
||||
|
||||
`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! 😱
|
||||
```
|
||||
|
||||
`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** と呼ばれます:
|
||||
|
||||
//// 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+
|
||||
|
||||
同じ組み込み型をジェネリクスとして(角括弧と内部の型で)使えます:
|
||||
|
||||
* `list`
|
||||
* `tuple`
|
||||
* `set`
|
||||
* `dict`
|
||||
|
||||
そして`typing`モジュールのジェネリクス:
|
||||
|
||||
* `Union`
|
||||
* `Optional`
|
||||
* ...and others.
|
||||
|
||||
////
|
||||
ただの `str` の代わりに `str | None` を使用することで、値が常に `str` であると仮定しているときに、実際には `None` である可能性もあるというエラーをエディタが検出するのに役立ちます。
|
||||
|
||||
### 型としてのクラス { #classes-as-types }
|
||||
|
||||
変数の型としてクラスを宣言することもできます。
|
||||
|
||||
名前を持つ`Person`クラスがあるとしましょう:
|
||||
名前を持つ `Person` クラスがあるとしましょう:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
|
||||
{* ../../docs_src/python_types/tutorial010_py310.py hl[1:3] *}
|
||||
|
||||
変数を`Person`型として宣言できます:
|
||||
変数を `Person` 型として宣言できます:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
|
||||
{* ../../docs_src/python_types/tutorial010_py310.py hl[6] *}
|
||||
|
||||
そして、再び、すべてのエディタのサポートを得ることができます:
|
||||
|
||||
<img src="/img/python-types/image06.png">
|
||||
|
||||
これは「`one_person`はクラス`Person`の**インスタンス**である」ことを意味します。
|
||||
これは「`one_person` はクラス `Person` の **インスタンス** である」ことを意味します。
|
||||
|
||||
「`one_person`は`Person`という名前の**クラス**である」という意味ではありません。
|
||||
「`one_person` は `Person` という名前の **クラス** である」という意味ではありません。
|
||||
|
||||
## Pydanticのモデル { #pydantic-models }
|
||||
## Pydantic のモデル { #pydantic-models }
|
||||
|
||||
<a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> はデータ検証を行うためのPythonライブラリです。
|
||||
<a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> はデータ検証を行うための Python ライブラリです。
|
||||
|
||||
データの「形」を属性付きのクラスとして宣言します。
|
||||
|
||||
@@ -389,53 +279,47 @@ Python 3.10では、ジェネリクスの`Union`や`Optional`を使う代替と
|
||||
|
||||
また、その結果のオブジェクトですべてのエディタのサポートを受けることができます。
|
||||
|
||||
Pydanticの公式ドキュメントからの例:
|
||||
Pydantic の公式ドキュメントからの例:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial011_py310.py *}
|
||||
|
||||
/// info | 情報
|
||||
|
||||
<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>。
|
||||
|
||||
///
|
||||
|
||||
**FastAPI** はすべてPydanticをベースにしています。
|
||||
**FastAPI** はすべて Pydantic をベースにしています。
|
||||
|
||||
すべてのことは[チュートリアル - ユーザーガイド](tutorial/index.md){.internal-link target=_blank}で実際に見ることができます。
|
||||
|
||||
/// 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>を参照してください。
|
||||
|
||||
///
|
||||
すべてのことは [チュートリアル - ユーザーガイド](tutorial/index.md){.internal-link target=_blank} で実際に見ることができます。
|
||||
|
||||
## メタデータアノテーション付き型ヒント { #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 には、`Annotated` を使って型ヒントに **追加の <dfn title="データに関するデータ。この場合は型に関する情報(例えば説明)。">メタデータ</dfn>** を付与できる機能もあります。
|
||||
|
||||
Python 3.9以降、`Annotated`は標準ライブラリの一部なので、`typing`からインポートできます。
|
||||
`Annotated` は `typing` からインポートできます。
|
||||
|
||||
{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
|
||||
{* ../../docs_src/python_types/tutorial013_py310.py hl[1,4] *}
|
||||
|
||||
Python自体は、この`Annotated`で何かをするわけではありません。また、エディタや他のツールにとっても、型は依然として`str`です。
|
||||
Python 自体は、この `Annotated` で何かをするわけではありません。また、エディタや他のツールにとっても、型は依然として `str` です。
|
||||
|
||||
しかし、`Annotated`内のこのスペースを使って、アプリケーションをどのように動作させたいかについての追加メタデータを **FastAPI** に提供できます。
|
||||
しかし、`Annotated` 内のこのスペースを使って、アプリケーションをどのように動作させたいかについての追加メタデータを **FastAPI** に提供できます。
|
||||
|
||||
覚えておくべき重要な点は、`Annotated`に渡す**最初の*型パラメータ***が**実際の型**であることです。残りは、他のツール向けのメタデータにすぎません。
|
||||
覚えておくべき重要な点は、`Annotated` に渡す **最初の「型パラメータ」** が **実際の型** であることです。残りは、他のツール向けのメタデータにすぎません。
|
||||
|
||||
今のところは、`Annotated`が存在し、それが標準のPythonであることを知っておけば十分です。😎
|
||||
今のところは、`Annotated` が存在し、それが標準の Python であることを知っておけば十分です。😎
|
||||
|
||||
後で、これがどれほど**強力**になり得るかを見ることになります。
|
||||
後で、これがどれほど **強力** になり得るかを見ることになります。
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
これが **標準のPython** であるという事実は、エディタで、使用しているツール(コードの解析やリファクタリングなど)とともに、**可能な限り最高の開発体験**が得られることを意味します。 ✨
|
||||
これが **標準の Python** であるという事実は、エディタで、使用しているツール(コードの解析やリファクタリングなど)とともに、**可能な限り最高の開発体験** が得られることを意味します。 ✨
|
||||
|
||||
また、あなたのコードが他の多くのPythonツールやライブラリとも非常に互換性が高いことも意味します。 🚀
|
||||
また、あなたのコードが他の多くの Python ツールやライブラリとも非常に互換性が高いことも意味します。 🚀
|
||||
|
||||
///
|
||||
|
||||
## **FastAPI**での型ヒント { #type-hints-in-fastapi }
|
||||
## **FastAPI** での型ヒント { #type-hints-in-fastapi }
|
||||
|
||||
**FastAPI** はこれらの型ヒントを利用していくつかのことを行います。
|
||||
|
||||
@@ -450,15 +334,15 @@ Python自体は、この`Annotated`で何かをするわけではありません
|
||||
* **データの変換**: リクエストから必要な型にデータを変換します。
|
||||
* **データの検証**: 各リクエストから来るデータについて:
|
||||
* データが無効な場合にクライアントに返される **自動エラー** を生成します。
|
||||
* OpenAPIを使用してAPIを**ドキュメント化**します:
|
||||
* OpenAPI を使用して API を **ドキュメント化** します:
|
||||
* これは自動の対話型ドキュメントのユーザーインターフェイスで使われます。
|
||||
|
||||
すべてが抽象的に聞こえるかもしれません。心配しないでください。 この全ての動作は [チュートリアル - ユーザーガイド](tutorial/index.md){.internal-link target=_blank}で見ることができます。
|
||||
すべてが抽象的に聞こえるかもしれません。心配しないでください。 この全ての動作は [チュートリアル - ユーザーガイド](tutorial/index.md){.internal-link target=_blank} で見ることができます。
|
||||
|
||||
重要なのは、Pythonの標準的な型を使うことで、(クラスやデコレータなどを追加するのではなく)1つの場所で **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> があります。
|
||||
|
||||
///
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
まず初めに、`BackgroundTasks` をインポートし、`BackgroundTasks` の型宣言と共に、*path operation function* のパラメーターを定義します:
|
||||
|
||||
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
|
||||
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[1,13] *}
|
||||
|
||||
**FastAPI** は、`BackgroundTasks` 型のオブジェクトを作成し、そのパラメーターに渡します。
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
|
||||
また、書き込み操作では `async` と `await` を使用しないため、通常の `def` で関数を定義します。
|
||||
|
||||
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
|
||||
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[6:9] *}
|
||||
|
||||
## バックグラウンドタスクの追加 { #add-the-background-task }
|
||||
|
||||
*path operation function* 内で、`.add_task()` メソッドを使用してタスク関数を *background tasks* オブジェクトに渡します。
|
||||
|
||||
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
|
||||
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[14] *}
|
||||
|
||||
`.add_task()` は以下の引数を受け取ります:
|
||||
|
||||
|
||||
@@ -106,12 +106,6 @@
|
||||
q: str | None = None
|
||||
```
|
||||
|
||||
またはPython 3.10以上では:
|
||||
|
||||
```Python
|
||||
q: Union[str, None] = None
|
||||
```
|
||||
|
||||
例えば:
|
||||
|
||||
{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}
|
||||
|
||||
@@ -164,7 +164,7 @@ images: list[Image]
|
||||
|
||||
以下のように:
|
||||
|
||||
{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
|
||||
{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *}
|
||||
|
||||
## あらゆる場所でのエディタサポート { #editor-support-everywhere }
|
||||
|
||||
@@ -194,7 +194,7 @@ Pydanticモデルではなく、`dict`を直接使用している場合はこの
|
||||
|
||||
この場合、`int`のキーと`float`の値を持つものであれば、どんな`dict`でも受け入れることができます:
|
||||
|
||||
{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
|
||||
{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
|
||||
まとめると、部分的な更新を適用するには、次のようにします:
|
||||
|
||||
* (オプションで)`PUT`の代わりに`PATCH`を使用します。
|
||||
* (オプションで)`PATCH`の代わりに`PUT`を使用します。
|
||||
* 保存されているデータを取得します。
|
||||
* そのデータをPydanticモデルにいれます。
|
||||
* 入力モデルからデフォルト値を含まない`dict`を生成します(`exclude_unset`を使用します)。
|
||||
|
||||
@@ -74,7 +74,7 @@ APIはほとんどの場合 **レスポンス** ボディを送信する必要
|
||||
* 受け取ったデータをパラメータ `item` に渡します。
|
||||
* 関数内で `Item` 型として宣言したため、すべての属性とその型について、エディタサポート(補完など)も利用できます。
|
||||
* モデル向けの <a href="https://json-schema.org" class="external-link" target="_blank">JSON Schema</a> 定義を生成します。プロジェクトにとって意味があるなら、他の場所でも好きなように利用できます。
|
||||
* それらのスキーマは生成されるOpenAPIスキーマの一部となり、自動ドキュメントの <abbr title="User Interfaces">UIs</abbr> で使用されます。
|
||||
* それらのスキーマは生成されるOpenAPIスキーマの一部となり、自動ドキュメントの <abbr title="User Interfaces - ユーザーインターフェース">UIs</abbr> で使用されます。
|
||||
|
||||
## 自動ドキュメント { #automatic-docs }
|
||||
|
||||
@@ -155,7 +155,7 @@ APIはほとんどの場合 **レスポンス** ボディを送信する必要
|
||||
|
||||
FastAPIは、デフォルト値 `= None` があるため、`q` の値が必須ではないことを認識します。
|
||||
|
||||
`str | None`(Python 3.10+)や `Union[str, None]`(Python 3.9+)の `Union` は、値が必須ではないことを判断するためにFastAPIでは使用されません。`= None` というデフォルト値があるため、必須ではないことを認識します。
|
||||
`str | None` は、値が必須ではないことを判断するためにFastAPIでは使用されません。`= None` というデフォルト値があるため、必須ではないことを認識します。
|
||||
|
||||
しかし、型アノテーションを追加すると、エディタがより良いサポートを提供し、エラーを検出できるようになります。
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
特定の(あまり一般的ではないかもしれない)ケースで、受け付けるクッキーを**制限**する必要があるかもしれません。
|
||||
|
||||
あなたのAPIは独自の <abbr title="念のためですが、これはジョークです。クッキー同意とは関係ありませんが、APIでさえ不適切なクッキーを拒否できるとは愉快ですね。クッキーでも食べてください。🍪 (原文: This is a joke, just in case. It has nothing to do with cookie consents, but it's funny that even the API can now reject the poor cookies. Have a cookie. 🍪)">クッキー同意</abbr> を管理する能力を持っています。 🤪🍪
|
||||
あなたのAPIは独自の <dfn title="念のためですが、これはジョークです。クッキー同意とは関係ありませんが、APIでさえ今やかわいそうなクッキーを拒否できるのは面白いですね。クッキーでもどうぞ。🍪">クッキー同意</dfn> を管理する能力を持っています。 🤪🍪
|
||||
|
||||
Pydanticのモデルの Configuration を利用して、 `extra` フィールドを `forbid` とすることができます。
|
||||
|
||||
@@ -54,9 +54,9 @@ Pydanticのモデルの Configuration を利用して、 `extra` フィールド
|
||||
|
||||
もしクライアントが**余分なクッキー**を送ろうとすると、**エラー**レスポンスが返されます。
|
||||
|
||||
<abbr title="これもジョークです。気にしないでください。クッキーのお供にコーヒーでも飲んでください。☕ (原文: This is another joke. Don't pay attention to me. Have some coffee for your cookie. ☕)">どうせAPIに拒否されるのに</abbr>あなたの同意を得ようと精一杯努力する可哀想なクッキーバナーたち... 🍪
|
||||
<dfn title="これもジョークです。気にしないでください。クッキーのお供にコーヒーでもどうぞ。☕">どうせAPIに拒否されるのに</dfn>あなたの同意を得ようと精一杯努力する可哀想なクッキーバナーたち... 🍪
|
||||
|
||||
例えば、クライアントがクッキー `santa_tracker` を `good-list-please` という値で送ろうとすると、`santa_tracker` という <abbr title="サンタはクッキー不足を良しとはしないでしょう。🎅 はい、クッキージョークはもう止めておきます。(原文: Santa disapproves the lack of cookies. 🎅 Okay, no more cookie jokes.)">クッキーが許可されていない</abbr> ことを通知する**エラー**レスポンスが返されます:
|
||||
例えば、クライアントがクッキー `santa_tracker` を `good-list-please` という値で送ろうとすると、`santa_tracker` という <dfn title="サンタはクッキー不足を良しとしません。🎅 はい、クッキージョークはこれでおしまい。">クッキーが許可されていない</dfn> ことを通知する**エラー**レスポンスが返されます:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -73,4 +73,4 @@ Pydanticのモデルの Configuration を利用して、 `extra` フィールド
|
||||
|
||||
## まとめ { #summary }
|
||||
|
||||
**FastAPI**では、<abbr title="帰ってしまう前に最後のクッキーをどうぞ。🍪 (原文: Have a last cookie before you go. 🍪)">**クッキー**</abbr>を宣言するために、**Pydanticモデル**を使用できます。😎
|
||||
**FastAPI**では、<dfn title="帰る前に最後のクッキーをどうぞ。🍪">**クッキー**</dfn>を宣言するために、**Pydanticモデル**を使用できます。😎
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
* 特定のHTTPメソッド (`POST`、`PUT`) またはワイルドカード `"*"` を使用してすべて許可。
|
||||
* 特定のHTTPヘッダー、またはワイルドカード `"*"`を使用してすべて許可。
|
||||
|
||||
{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
|
||||
{* ../../docs_src/cors/tutorial001_py310.py hl[2,6:11,13:19] *}
|
||||
|
||||
|
||||
`CORSMiddleware` 実装で使用されるデフォルトのパラメータはデフォルトで制限が厳しいため、ブラウザがクロスドメインのコンテキストでそれらを使用できるようにするには、特定のオリジン、メソッド、またはヘッダーを明示的に有効にする必要があります。
|
||||
|
||||
@@ -6,7 +6,7 @@ Visual Studio CodeやPyCharmなどを使用して、エディター上でデバ
|
||||
|
||||
FastAPIアプリケーション上で、`uvicorn` を直接インポートして実行します:
|
||||
|
||||
{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
|
||||
{* ../../docs_src/debugging/tutorial001_py310.py hl[1,15] *}
|
||||
|
||||
### `__name__ == "__main__"` について { #about-name-main }
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ FastAPIが実際にチェックしているのは、それが「呼び出し可
|
||||
|
||||
上のコードでは`CommonQueryParams`を2回書いていることに注目してください:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
@@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ 注釈なし
|
||||
//// tab | Python 3.10+ 注釈なし
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -137,7 +137,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
|
||||
この場合、以下にある最初の`CommonQueryParams`:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, ...
|
||||
@@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ 注釈なし
|
||||
//// tab | Python 3.10+ 注釈なし
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -163,7 +163,7 @@ commons: CommonQueryParams ...
|
||||
|
||||
実際には以下のように書けばいいだけです:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
commons: Annotated[Any, Depends(CommonQueryParams)]
|
||||
@@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ 注釈なし
|
||||
//// tab | Python 3.10+ 注釈なし
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -197,7 +197,7 @@ commons = Depends(CommonQueryParams)
|
||||
|
||||
しかし、ここでは`CommonQueryParams`を2回書くというコードの繰り返しが発生していることがわかります:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
@@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ 注釈なし
|
||||
//// tab | Python 3.10+ 注釈なし
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -225,7 +225,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
|
||||
以下のように書く代わりに:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
@@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ 注釈なし
|
||||
//// tab | Python 3.10+ 注釈なし
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
|
||||
...以下のように書きます:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends()]
|
||||
@@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ 注釈なし
|
||||
//// tab | Python 3.10+ 注釈なし
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
それは`Depends()`の`list`であるべきです:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *}
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[19] *}
|
||||
|
||||
これらの依存関係は、通常の依存関係と同様に実行・解決されます。しかし、それらの値(何かを返す場合)は*path operation 関数*には渡されません。
|
||||
|
||||
@@ -44,13 +44,13 @@
|
||||
|
||||
これらはリクエストの要件(ヘッダーのようなもの)やその他のサブ依存関係を宣言できます:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *}
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[8,13] *}
|
||||
|
||||
### 例外の発生 { #raise-exceptions }
|
||||
|
||||
これらの依存関係は、通常の依存関係と同じように例外を`raise`できます:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *}
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[10,15] *}
|
||||
|
||||
### 戻り値 { #return-values }
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
つまり、すでにどこかで使っている通常の依存関係(値を返すもの)を再利用でき、値は使われなくても依存関係は実行されます:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *}
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[11,16] *}
|
||||
|
||||
## *path operation*のグループに対する依存関係 { #dependencies-for-a-group-of-path-operations }
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# `yield`を持つ依存関係 { #dependencies-with-yield }
|
||||
|
||||
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>を行う依存関係をサポートしています。
|
||||
FastAPIは、いくつかの<dfn title="「終了コード」「クリーンアップコード」「ティアダウンコード」「クローズコード」「コンテキストマネージャの終了コード」などと呼ばれることもあります">終了後の追加のステップ</dfn>を行う依存関係をサポートしています。
|
||||
|
||||
これを行うには、`return`の代わりに`yield`を使い、その後に追加のステップ(コード)を書きます。
|
||||
|
||||
@@ -29,15 +29,15 @@ FastAPIは、いくつかの<abbr title='sometimes also called "exit code", "cle
|
||||
|
||||
レスポンスを作成する前に、`yield`文より前のコード(および`yield`文を含む)が実行されます:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
|
||||
{* ../../docs_src/dependencies/tutorial007_py310.py hl[2:4] *}
|
||||
|
||||
生成された値は、*path operations*や他の依存関係に注入されるものです:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
|
||||
{* ../../docs_src/dependencies/tutorial007_py310.py hl[4] *}
|
||||
|
||||
`yield`文に続くコードは、レスポンスの後に実行されます:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
|
||||
{* ../../docs_src/dependencies/tutorial007_py310.py hl[5:6] *}
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -57,7 +57,7 @@ FastAPIは、いくつかの<abbr title='sometimes also called "exit code", "cle
|
||||
|
||||
同様に、`finally`を用いて例外があったかどうかにかかわらず、終了ステップを確実に実行することができます。
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
|
||||
{* ../../docs_src/dependencies/tutorial007_py310.py hl[3,5] *}
|
||||
|
||||
## `yield`を持つサブ依存関係 { #sub-dependencies-with-yield }
|
||||
|
||||
@@ -67,7 +67,7 @@ FastAPIは、いくつかの<abbr title='sometimes also called "exit code", "cle
|
||||
|
||||
例えば、`dependency_c`は`dependency_b`に、そして`dependency_b`は`dependency_a`に依存することができます:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
|
||||
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[6,14,22] *}
|
||||
|
||||
そして、それらはすべて`yield`を使用することができます。
|
||||
|
||||
@@ -75,7 +75,7 @@ FastAPIは、いくつかの<abbr title='sometimes also called "exit code", "cle
|
||||
|
||||
そして、`dependency_b`は`dependency_a`(ここでは`dep_a`という名前)の値を終了コードで利用できるようにする必要があります。
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
|
||||
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[18:19,26:27] *}
|
||||
|
||||
同様に、`yield`を持つ依存関係と`return`を持つ他の依存関係をいくつか持ち、それらの一部が他の一部に依存するようにもできます。
|
||||
|
||||
@@ -109,7 +109,7 @@ FastAPIは、いくつかの<abbr title='sometimes also called "exit code", "cle
|
||||
|
||||
///
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
|
||||
{* ../../docs_src/dependencies/tutorial008b_an_py310.py hl[18:22,31] *}
|
||||
|
||||
例外をキャッチして、それに基づいてカスタムレスポンスを作成したい場合は、[カスタム例外ハンドラ](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}を作成してください。
|
||||
|
||||
@@ -117,7 +117,7 @@ FastAPIは、いくつかの<abbr title='sometimes also called "exit code", "cle
|
||||
|
||||
`yield`を持つ依存関係で`except`を使って例外をキャッチし、それを再度raiseしない(または新しい例外をraiseしない)場合、通常のPythonと同じように、FastAPIは例外があったことに気づけません:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial008c_an_py39.py hl[15:16] *}
|
||||
{* ../../docs_src/dependencies/tutorial008c_an_py310.py hl[15:16] *}
|
||||
|
||||
この場合、(`HTTPException`やそれに類するものをraiseしていないため)クライアントには適切に*HTTP 500 Internal Server Error*レスポンスが返りますが、サーバーには**ログが一切残らず**、何がエラーだったのかを示す他の手がかりもありません。 😱
|
||||
|
||||
@@ -127,7 +127,7 @@ FastAPIは、いくつかの<abbr title='sometimes also called "exit code", "cle
|
||||
|
||||
`raise`を使うと同じ例外を再raiseできます:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial008d_an_py39.py hl[17] *}
|
||||
{* ../../docs_src/dependencies/tutorial008d_an_py310.py hl[17] *}
|
||||
|
||||
これでクライアントは同じ*HTTP 500 Internal Server Error*レスポンスを受け取りますが、サーバーのログにはカスタムの`InternalError`が残ります。 😎
|
||||
|
||||
@@ -190,7 +190,7 @@ participant tasks as Background tasks
|
||||
|
||||
しかし、*path operation 関数*からreturnした後に依存関係を使う必要がないと分かっている場合は、`Depends(scope="function")`を使って、**レスポンスが送信される前**に、*path operation 関数*のreturn後に依存関係を閉じるべきだとFastAPIに伝えられます。
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial008e_an_py39.py hl[12,16] *}
|
||||
{* ../../docs_src/dependencies/tutorial008e_an_py310.py hl[12,16] *}
|
||||
|
||||
`Depends()`は、以下のいずれかを取る`scope`パラメータを受け取ります:
|
||||
|
||||
@@ -268,7 +268,7 @@ Pythonでは、<a href="https://docs.python.org/3/reference/datamodel.html#conte
|
||||
|
||||
また、依存関数の中で`with`や`async with`文を使用することによって`yield`を持つ **FastAPI** の依存関係の中でそれらを使用することができます:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
|
||||
{* ../../docs_src/dependencies/tutorial010_py310.py hl[1:9,13] *}
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 依存関係 { #dependencies }
|
||||
|
||||
**FastAPI** は非常に強力でありながら直感的な **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** システムを持っています。
|
||||
**FastAPI** は非常に強力でありながら直感的な **<dfn title="別名: コンポーネント、リソース、プロバイダ、サービス、インジェクタブル">依存性注入</dfn>** システムを持っています。
|
||||
|
||||
それは非常にシンプルに使用できるように設計されており、開発者が他のコンポーネント **FastAPI** と統合するのが非常に簡単になるように設計されています。
|
||||
|
||||
|
||||
@@ -58,11 +58,11 @@ query_extractor --> query_or_cookie_extractor --> read_query
|
||||
|
||||
依存関係の1つが同じ*path operation*に対して複数回宣言されている場合、例えば、複数の依存関係が共通のサブ依存関係を持っている場合、**FastAPI** はリクエストごとに1回だけそのサブ依存関係を呼び出します。
|
||||
|
||||
そして、返された値を<abbr title="A utility/system to store computed/generated values, to reuse them instead of computing them again. – 計算/生成された値を保存し、再計算する代わりに再利用するためのユーティリティ/システム。">「キャッシュ」</abbr>に保存し、同じリクエストに対して依存関係を何度も呼び出す代わりに、その特定のリクエストでそれを必要とする全ての「依存」に渡すことになります。
|
||||
そして、返された値を<dfn title="計算/生成された値を保存し、再計算する代わりに再利用するためのユーティリティ/システム">「キャッシュ」</dfn>に保存し、同じリクエストに対して依存関係を何度も呼び出す代わりに、その特定のリクエストでそれを必要とする全ての「依存」に渡すことになります。
|
||||
|
||||
高度なシナリオでは、「キャッシュされた」値を使うのではなく、同じリクエストの各ステップ(おそらく複数回)で依存関係を呼び出す必要があることがわかっている場合、`Depends`を使用する際に、`use_cache=False`というパラメータを設定することができます:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="1"
|
||||
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
|
||||
@@ -71,7 +71,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ 非Annotated
|
||||
//// tab | Python 3.10+ 非Annotated
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Extra Models { #extra-models }
|
||||
# 追加のモデル { #extra-models }
|
||||
|
||||
先ほどの例に続き、複数の関連モデルを持つことは一般的です。
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* **出力モデル**はパスワードをもつべきではありません。
|
||||
* **データベースモデル**はおそらくハッシュ化されたパスワードが必要になるでしょう。
|
||||
|
||||
/// danger
|
||||
/// danger | 警告
|
||||
|
||||
ユーザーの平文のパスワードは絶対に保存しないでください。常に検証できる「安全なハッシュ」を保存してください。
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
///
|
||||
|
||||
## Multiple models { #multiple-models }
|
||||
## 複数のモデル { #multiple-models }
|
||||
|
||||
ここでは、パスワードフィールドをもつモデルがどのように見えるのか、また、どこで使われるのか、大まかなイメージを紹介します:
|
||||
|
||||
{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
|
||||
|
||||
### About `**user_in.model_dump()` { #about-user-in-model-dump }
|
||||
### `**user_in.model_dump()` について { #about-user-in-model-dump }
|
||||
|
||||
#### Pydanticの`.model_dump()` { #pydantics-model-dump }
|
||||
|
||||
@@ -132,13 +132,13 @@ UserInDB(
|
||||
)
|
||||
```
|
||||
|
||||
/// warning
|
||||
/// warning | 注意
|
||||
|
||||
追加のサポート関数`fake_password_hasher`と`fake_save_user`は、データの可能な流れをデモするだけであり、もちろん本当のセキュリティを提供しているわけではありません。
|
||||
|
||||
///
|
||||
|
||||
## Reduce duplication { #reduce-duplication }
|
||||
## 重複の削減 { #reduce-duplication }
|
||||
|
||||
コードの重複を減らすことは、**FastAPI**の中核的なアイデアの1つです。
|
||||
|
||||
@@ -156,7 +156,7 @@ UserInDB(
|
||||
|
||||
{* ../../docs_src/extra_models/tutorial002_py310.py hl[7,13:14,17:18,21:22] *}
|
||||
|
||||
## `Union` or `anyOf` { #union-or-anyof }
|
||||
## `Union` または `anyOf` { #union-or-anyof }
|
||||
|
||||
レスポンスを2つ以上の型の`Union`として宣言できます。つまり、そのレスポンスはそれらのいずれかになります。
|
||||
|
||||
@@ -186,25 +186,25 @@ some_variable: PlaneItem | CarItem
|
||||
|
||||
しかし、これを代入で`response_model=PlaneItem | CarItem`のように書くと、Pythonはそれを型アノテーションとして解釈するのではなく、`PlaneItem`と`CarItem`の間で**無効な操作**を行おうとしてしまうため、エラーになります。
|
||||
|
||||
## List of models { #list-of-models }
|
||||
## モデルのリスト { #list-of-models }
|
||||
|
||||
同じように、オブジェクトのリストのレスポンスを宣言できます。
|
||||
|
||||
そのためには、標準のPythonの`typing.List`(またはPython 3.9以降では単に`list`)を使用します:
|
||||
そのためには、標準のPythonの`list`を使用します:
|
||||
|
||||
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
|
||||
{* ../../docs_src/extra_models/tutorial004_py310.py hl[18] *}
|
||||
|
||||
## Response with arbitrary `dict` { #response-with-arbitrary-dict }
|
||||
## 任意の`dict`によるレスポンス { #response-with-arbitrary-dict }
|
||||
|
||||
また、Pydanticモデルを使用せずに、キーと値の型だけを定義した任意の`dict`を使ってレスポンスを宣言することもできます。
|
||||
|
||||
これは、有効なフィールド・属性名(Pydanticモデルに必要なもの)を事前に知らない場合に便利です。
|
||||
|
||||
この場合、`typing.Dict`(またはPython 3.9以降では単に`dict`)を使用できます:
|
||||
この場合、`dict`を使用できます:
|
||||
|
||||
{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
|
||||
{* ../../docs_src/extra_models/tutorial005_py310.py hl[6] *}
|
||||
|
||||
## Recap { #recap }
|
||||
## まとめ { #recap }
|
||||
|
||||
複数のPydanticモデルを使用し、ケースごとに自由に継承します。
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
最もシンプルなFastAPIファイルは以下のようになります:
|
||||
|
||||
{* ../../docs_src/first_steps/tutorial001_py39.py *}
|
||||
{* ../../docs_src/first_steps/tutorial001_py310.py *}
|
||||
|
||||
これを`main.py`にコピーします。
|
||||
|
||||
@@ -104,7 +104,7 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
|
||||
#### OpenAPIおよびJSONスキーマ { #openapi-and-json-schema }
|
||||
|
||||
OpenAPIはAPIのためのAPIスキーマを定義します。そして、そのスキーマは**JSONデータスキーマ**の標準規格に準拠したJSONスキーマを利用するAPIによって送受されるデータの定義(または「スキーマ」)を含んでいます。
|
||||
OpenAPIはAPIのためのAPIスキーマを定義します。そして、そのスキーマは**JSONデータスキーマ**の標準規格である**JSON Schema**を利用するAPIによって送受されるデータの定義(または「スキーマ」)を含んでいます。
|
||||
|
||||
#### `openapi.json`を確認 { #check-the-openapi-json }
|
||||
|
||||
@@ -183,7 +183,7 @@ Deploying to FastAPI Cloud...
|
||||
|
||||
### Step 1: `FastAPI`をインポート { #step-1-import-fastapi }
|
||||
|
||||
{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
|
||||
{* ../../docs_src/first_steps/tutorial001_py310.py hl[1] *}
|
||||
|
||||
`FastAPI`は、APIのすべての機能を提供するPythonクラスです。
|
||||
|
||||
@@ -197,7 +197,7 @@ Deploying to FastAPI Cloud...
|
||||
|
||||
### Step 2: `FastAPI`の「インスタンス」を生成 { #step-2-create-a-fastapi-instance }
|
||||
|
||||
{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
|
||||
{* ../../docs_src/first_steps/tutorial001_py310.py hl[3] *}
|
||||
ここで、`app`変数が`FastAPI`クラスの「インスタンス」になります。
|
||||
|
||||
これが、すべてのAPIを作成するための主要なポイントになります。
|
||||
@@ -265,12 +265,12 @@ APIを構築するときは、通常、これらの特定のHTTPメソッドを
|
||||
|
||||
#### *path operation デコレータ*を定義 { #define-a-path-operation-decorator }
|
||||
|
||||
{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
|
||||
{* ../../docs_src/first_steps/tutorial001_py310.py hl[6] *}
|
||||
|
||||
`@app.get("/")`は直下の関数が下記のリクエストの処理を担当することを**FastAPI**に伝えます:
|
||||
|
||||
* パス `/`
|
||||
* <abbr title="an HTTP GET method"><code>get</code> オペレーション</abbr>
|
||||
* <dfn title="HTTP GET メソッド"><code>get</code> オペレーション</dfn>
|
||||
|
||||
/// info | `@decorator` Info
|
||||
|
||||
@@ -319,7 +319,7 @@ Pythonにおける`@something`シンタックスはデコレータと呼ばれ
|
||||
* **オペレーション**: は`get`です。
|
||||
* **関数**: 「デコレータ」の直下にある関数 (`@app.get("/")`の直下) です。
|
||||
|
||||
{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
|
||||
{* ../../docs_src/first_steps/tutorial001_py310.py hl[7] *}
|
||||
|
||||
これは、Pythonの関数です。
|
||||
|
||||
@@ -331,7 +331,7 @@ Pythonにおける`@something`シンタックスはデコレータと呼ばれ
|
||||
|
||||
`async def`の代わりに通常の関数として定義することもできます:
|
||||
|
||||
{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
|
||||
{* ../../docs_src/first_steps/tutorial003_py310.py hl[7] *}
|
||||
|
||||
/// note | 備考
|
||||
|
||||
@@ -341,7 +341,7 @@ Pythonにおける`@something`シンタックスはデコレータと呼ばれ
|
||||
|
||||
### Step 5: コンテンツの返信 { #step-5-return-the-content }
|
||||
|
||||
{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
|
||||
{* ../../docs_src/first_steps/tutorial001_py310.py hl[8] *}
|
||||
|
||||
`dict`、`list`、`str`、`int`などの単一の値を返すことができます。
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ HTTPレスポンスをエラーでクライアントに返すには、`HTTPExcep
|
||||
|
||||
### `HTTPException`のインポート { #import-httpexception }
|
||||
|
||||
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
|
||||
{* ../../docs_src/handling_errors/tutorial001_py310.py hl[1] *}
|
||||
|
||||
### コード内での`HTTPException`の発生 { #raise-an-httpexception-in-your-code }
|
||||
|
||||
@@ -39,7 +39,7 @@ Pythonの例外なので、`return`ではなく、`raise`です。
|
||||
|
||||
この例では、クライアントが存在しないIDでアイテムを要求した場合、`404`のステータスコードを持つ例外を発生させます:
|
||||
|
||||
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
|
||||
{* ../../docs_src/handling_errors/tutorial001_py310.py hl[11] *}
|
||||
|
||||
### レスポンス結果 { #the-resulting-response }
|
||||
|
||||
@@ -77,7 +77,7 @@ Pythonの例外なので、`return`ではなく、`raise`です。
|
||||
|
||||
しかし、高度なシナリオのために必要な場合には、カスタムヘッダーを追加することができます:
|
||||
|
||||
{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
|
||||
{* ../../docs_src/handling_errors/tutorial002_py310.py hl[14] *}
|
||||
|
||||
## カスタム例外ハンドラのインストール { #install-custom-exception-handlers }
|
||||
|
||||
@@ -89,7 +89,7 @@ Pythonの例外なので、`return`ではなく、`raise`です。
|
||||
|
||||
カスタム例外ハンドラを`@app.exception_handler()`で追加することができます:
|
||||
|
||||
{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
|
||||
{* ../../docs_src/handling_errors/tutorial003_py310.py hl[5:7,13:18,24] *}
|
||||
|
||||
ここで、`/unicorns/yolo`をリクエストすると、*path operation*は`UnicornException`を`raise`します。
|
||||
|
||||
@@ -127,7 +127,7 @@ Pythonの例外なので、`return`ではなく、`raise`です。
|
||||
|
||||
この例外ハンドラは`Request`と例外を受け取ります。
|
||||
|
||||
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
|
||||
{* ../../docs_src/handling_errors/tutorial004_py310.py hl[2,14:19] *}
|
||||
|
||||
これで、`/items/foo`にアクセスすると、以下のデフォルトのJSONエラーの代わりに:
|
||||
|
||||
@@ -159,7 +159,7 @@ Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to pa
|
||||
|
||||
例えば、これらのエラーに対しては、JSONではなくプレーンテキストを返すようにすることができます:
|
||||
|
||||
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
|
||||
{* ../../docs_src/handling_errors/tutorial004_py310.py hl[3:4,9:11,25] *}
|
||||
|
||||
/// note | 技術詳細
|
||||
|
||||
@@ -183,7 +183,7 @@ Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to pa
|
||||
|
||||
アプリ開発中にボディのログを取ってデバッグしたり、ユーザーに返したりなどに使用することができます。
|
||||
|
||||
{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
|
||||
{* ../../docs_src/handling_errors/tutorial005_py310.py hl[14] *}
|
||||
|
||||
ここで、以下のような無効な項目を送信してみてください:
|
||||
|
||||
@@ -239,6 +239,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
|
||||
|
||||
**FastAPI** から同じデフォルトの例外ハンドラと一緒に例外を使用したい場合は、`fastapi.exception_handlers`からデフォルトの例外ハンドラをインポートして再利用できます:
|
||||
|
||||
{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
|
||||
{* ../../docs_src/handling_errors/tutorial006_py310.py hl[2:5,15,21] *}
|
||||
|
||||
この例では、非常に表現力のあるメッセージでエラーを`print`しているだけですが、要点は理解できるはずです。例外を使用し、その後デフォルトの例外ハンドラを再利用できます。
|
||||
|
||||
@@ -18,7 +18,7 @@ OpenAPI仕様および自動APIドキュメントUIで使用される次のフ
|
||||
|
||||
以下のように設定できます:
|
||||
|
||||
{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
|
||||
{* ../../docs_src/metadata/tutorial001_py310.py hl[3:16, 19:32] *}
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -36,7 +36,7 @@ OpenAPI 3.1.0 および FastAPI 0.99.0 以降では、`license_info` を `url`
|
||||
|
||||
例:
|
||||
|
||||
{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
|
||||
{* ../../docs_src/metadata/tutorial001_1_py310.py hl[31] *}
|
||||
|
||||
## タグのメタデータ { #metadata-for-tags }
|
||||
|
||||
@@ -58,7 +58,7 @@ OpenAPI 3.1.0 および FastAPI 0.99.0 以降では、`license_info` を `url`
|
||||
|
||||
タグのメタデータを作成し、それを `openapi_tags` パラメータに渡します:
|
||||
|
||||
{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
|
||||
{* ../../docs_src/metadata/tutorial004_py310.py hl[3:16,18] *}
|
||||
|
||||
説明の中でMarkdownを使用できることに注意してください。たとえば「login」は太字 (**login**) で表示され、「fancy」は斜体 (_fancy_) で表示されます。
|
||||
|
||||
@@ -72,7 +72,7 @@ OpenAPI 3.1.0 および FastAPI 0.99.0 以降では、`license_info` を `url`
|
||||
|
||||
*path operation*(および `APIRouter`)の `tags` パラメータを使用して、それらを異なるタグに割り当てます:
|
||||
|
||||
{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
|
||||
{* ../../docs_src/metadata/tutorial004_py310.py hl[21,26] *}
|
||||
|
||||
/// info | 情報
|
||||
|
||||
@@ -100,7 +100,7 @@ OpenAPI 3.1.0 および FastAPI 0.99.0 以降では、`license_info` を `url`
|
||||
|
||||
たとえば、`/api/v1/openapi.json` で提供されるように設定するには:
|
||||
|
||||
{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
|
||||
{* ../../docs_src/metadata/tutorial002_py310.py hl[3] *}
|
||||
|
||||
OpenAPIスキーマを完全に無効にする場合は、`openapi_url=None` を設定できます。これにより、それを使用するドキュメントUIも無効になります。
|
||||
|
||||
@@ -117,4 +117,4 @@ OpenAPIスキーマを完全に無効にする場合は、`openapi_url=None` を
|
||||
|
||||
たとえば、`/documentation` でSwagger UIが提供されるように設定し、ReDocを無効にするには:
|
||||
|
||||
{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
|
||||
{* ../../docs_src/metadata/tutorial003_py310.py hl[3] *}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
* 次に、対応する*path operation*によって生成された `response` を返します。
|
||||
* その後、`response` を返す前にさらに `response` を変更することもできます。
|
||||
|
||||
{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
|
||||
{* ../../docs_src/middleware/tutorial001_py310.py hl[8:9,11,14] *}
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
例えば、リクエストの処理とレスポンスの生成にかかった秒数を含むカスタムヘッダー `X-Process-Time` を追加できます:
|
||||
|
||||
{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
|
||||
{* ../../docs_src/middleware/tutorial001_py310.py hl[10,12:13] *}
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -92,4 +92,4 @@ app.add_middleware(MiddlewareB)
|
||||
|
||||
他のミドルウェアの詳細については、[高度なユーザーガイド: 高度なミドルウェア](../advanced/middleware.md){.internal-link target=_blank}を参照してください。
|
||||
|
||||
次のセクションでは、ミドルウェアを使用して <abbr title="Cross-Origin Resource Sharing">CORS</abbr> を処理する方法について説明します。
|
||||
次のセクションでは、ミドルウェアを使用して <abbr title="Cross-Origin Resource Sharing - クロスオリジンリソース共有">CORS</abbr> を処理する方法について説明します。
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
**FastAPI** は、プレーンな文字列の場合と同じ方法でそれをサポートしています:
|
||||
|
||||
{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
|
||||
{* ../../docs_src/path_operation_configuration/tutorial002b_py310.py hl[1,8:10,13,18] *}
|
||||
|
||||
## 概要と説明 { #summary-and-description }
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
## docstringを用いた説明 { #description-from-docstring }
|
||||
|
||||
説明文は長くて複数行におよぶ傾向があるので、関数<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** は説明文を読み込んでくれます。
|
||||
説明文は長くて複数行におよぶ傾向があるので、関数<dfn title="関数内の最初の式(どの変数にも代入されない)として記述される、ドキュメント用の複数行の文字列">docstring</dfn>内に*path operation*の説明文を宣言できます。すると、**FastAPI** は説明文を読み込んでくれます。
|
||||
|
||||
docstringに<a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a>を記述すれば、正しく解釈されて表示されます。(docstringのインデントを考慮して)
|
||||
|
||||
@@ -90,9 +90,9 @@ OpenAPIは*path operation*ごとにレスポンスの説明を必要としてい
|
||||
|
||||
## *path operation*を非推奨にする { #deprecate-a-path-operation }
|
||||
|
||||
*path operation*を<abbr title="obsolete, recommended not to use it – 非推奨、使わない方がよい">deprecated</abbr>としてマークする必要があるが、それを削除しない場合は、`deprecated`パラメータを渡します:
|
||||
*path operation*を<dfn title="非推奨、使用しないことを推奨">deprecated</dfn>としてマークする必要があるが、それを削除しない場合は、`deprecated`パラメータを渡します:
|
||||
|
||||
{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
|
||||
{* ../../docs_src/path_operation_configuration/tutorial006_py310.py hl[16] *}
|
||||
|
||||
対話的ドキュメントでは非推奨と明記されます:
|
||||
|
||||
|
||||
@@ -54,11 +54,11 @@ Pythonは「デフォルト」を持つ値を「デフォルト」を持たな
|
||||
|
||||
そのため、以下のように関数を宣言することができます:
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial002_py310.py hl[7] *}
|
||||
|
||||
ただし、`Annotated`を使う場合はこの問題は起きないことを覚えておいてください。`Query()`や`Path()`に関数パラメータのデフォルト値を使わないためです。
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py *}
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py310.py *}
|
||||
|
||||
## 必要に応じてパラメータを並び替えるトリック { #order-the-parameters-as-you-need-tricks }
|
||||
|
||||
@@ -81,15 +81,15 @@ Pythonは「デフォルト」を持つ値を「デフォルト」を持たな
|
||||
|
||||
関数の最初のパラメータとして`*`を渡します。
|
||||
|
||||
Pythonはその`*`で何かをすることはありませんが、それ以降のすべてのパラメータがキーワード引数(キーと値のペア)として呼ばれるべきものであると知っているでしょう。それは<abbr title="From: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>としても知られています。たとえデフォルト値がなくても。
|
||||
Pythonはその`*`で何かをすることはありませんが、それ以降のすべてのパラメータがキーワード引数(キーと値のペア)として呼ばれるべきものであると知っているでしょう。それは<abbr title="From: K-ey W-ord Arg-uments - キーワード引数"><code>kwargs</code></abbr>としても知られています。たとえデフォルト値がなくても。
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial003_py310.py hl[7] *}
|
||||
|
||||
### `Annotated`のほうがよい { #better-with-annotated }
|
||||
|
||||
`Annotated`を使う場合は、関数パラメータのデフォルト値を使わないため、この問題は起きず、おそらく`*`を使う必要もありません。
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py310.py hl[10] *}
|
||||
|
||||
## 数値の検証: 以上 { #number-validations-greater-than-or-equal }
|
||||
|
||||
@@ -97,7 +97,7 @@ Pythonはその`*`で何かをすることはありませんが、それ以降
|
||||
|
||||
ここで、`ge=1`の場合、`item_id`は`1`「より大きい`g`か、同じ`e`」整数でなければなりません。
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py310.py hl[10] *}
|
||||
|
||||
## 数値の検証: より大きいと小なりイコール { #number-validations-greater-than-and-less-than-or-equal }
|
||||
|
||||
@@ -106,7 +106,7 @@ Pythonはその`*`で何かをすることはありませんが、それ以降
|
||||
* `gt`: `g`reater `t`han
|
||||
* `le`: `l`ess than or `e`qual
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py310.py hl[10] *}
|
||||
|
||||
## 数値の検証: 浮動小数点、 大なり小なり { #number-validations-floats-greater-than-and-less-than }
|
||||
|
||||
@@ -118,7 +118,7 @@ Pythonはその`*`で何かをすることはありませんが、それ以降
|
||||
|
||||
これは<abbr title="less than – より小さい"><code>lt</code></abbr>も同じです。
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py310.py hl[13] *}
|
||||
|
||||
## まとめ { #recap }
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Pythonのformat文字列と同様のシンタックスで「パスパラメータ」や「パス変数」を宣言できます:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
|
||||
{* ../../docs_src/path_params/tutorial001_py310.py hl[6:7] *}
|
||||
|
||||
パスパラメータ `item_id` の値は、引数 `item_id` として関数に渡されます。
|
||||
|
||||
@@ -16,7 +16,7 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
|
||||
|
||||
標準のPythonの型アノテーションを使用して、関数内のパスパラメータの型を宣言できます:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
|
||||
{* ../../docs_src/path_params/tutorial002_py310.py hl[7] *}
|
||||
|
||||
ここでは、 `item_id` は `int` として宣言されています。
|
||||
|
||||
@@ -26,7 +26,7 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
|
||||
|
||||
///
|
||||
|
||||
## データ<abbr title="別名: serialization, parsing, marshalling">変換</abbr> { #data-conversion }
|
||||
## データ<dfn title="別名: シリアライズ、パース、マーシャリング">変換</dfn> { #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,7 +38,7 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
|
||||
|
||||
関数が受け取った(および返した)値は、文字列の `"3"` ではなく、Pythonの `int` としての `3` であることに注意してください。
|
||||
|
||||
したがって、その型宣言を使うと、**FastAPI**は自動リクエスト <abbr title="HTTPリクエストで受け取った文字列をPythonデータへ変換する">"解析"</abbr> を行います。
|
||||
したがって、その型宣言を使うと、**FastAPI**は自動リクエスト <dfn title="HTTPリクエストから受け取った文字列をPythonのデータに変換する">"解析"</dfn> を行います。
|
||||
|
||||
///
|
||||
|
||||
@@ -118,13 +118,13 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
|
||||
|
||||
*path operations* は順に評価されるので、 `/users/me` が `/users/{user_id}` よりも先に宣言されているか確認する必要があります:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
|
||||
{* ../../docs_src/path_params/tutorial003_py310.py hl[6,11] *}
|
||||
|
||||
それ以外の場合、 `/users/{user_id}` は `/users/me` としてもマッチします。値が `"me"` であるパラメータ `user_id` を受け取ると「考え」ます。
|
||||
|
||||
同様に、path operation を再定義することはできません:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
|
||||
{* ../../docs_src/path_params/tutorial003b_py310.py hl[6,11] *}
|
||||
|
||||
パスは最初にマッチしたものが常に使われるため、最初のものが常に使用されます。
|
||||
|
||||
@@ -140,11 +140,11 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
|
||||
|
||||
そして、固定値のクラス属性を作ります。すると、その値が使用可能な値となります:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
|
||||
{* ../../docs_src/path_params/tutorial005_py310.py hl[1,6:9] *}
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
"AlexNet"、"ResNet"そして"LeNet"は機械学習<abbr title="Technically, Deep Learning model architectures">モデル</abbr>の名前です。
|
||||
"AlexNet"、"ResNet"そして"LeNet"は機械学習<dfn title="厳密には、Deep Learning のモデルアーキテクチャ">モデル</dfn>の名前です。
|
||||
|
||||
///
|
||||
|
||||
@@ -152,7 +152,7 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
|
||||
|
||||
次に、作成したenumクラスである`ModelName`を使用した型アノテーションをもつ*パスパラメータ*を作成します:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
|
||||
{* ../../docs_src/path_params/tutorial005_py310.py hl[16] *}
|
||||
|
||||
### ドキュメントの確認 { #check-the-docs }
|
||||
|
||||
@@ -168,13 +168,13 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
|
||||
|
||||
これは、作成した列挙型 `ModelName` の*列挙型メンバ*と比較できます:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
|
||||
{* ../../docs_src/path_params/tutorial005_py310.py hl[17] *}
|
||||
|
||||
#### *列挙値*の取得 { #get-the-enumeration-value }
|
||||
|
||||
`model_name.value` 、もしくは一般に、 `your_enum_member.value` を使用して実際の値 (この場合は `str`) を取得できます。
|
||||
|
||||
{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
|
||||
{* ../../docs_src/path_params/tutorial005_py310.py hl[20] *}
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -188,7 +188,7 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
|
||||
|
||||
それらはクライアントに返される前に適切な値 (この場合は文字列) に変換されます。
|
||||
|
||||
{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
|
||||
{* ../../docs_src/path_params/tutorial005_py310.py hl[18,21,23] *}
|
||||
|
||||
クライアントは以下の様なJSONレスポンスを得ます:
|
||||
|
||||
@@ -227,7 +227,7 @@ Starletteのオプションを直接使用することで、以下のURLの様
|
||||
|
||||
したがって、以下の様に使用できます:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
|
||||
{* ../../docs_src/path_params/tutorial004_py310.py hl[6] *}
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -242,7 +242,7 @@ Starletteのオプションを直接使用することで、以下のURLの様
|
||||
簡潔で、本質的で、標準的なPythonの型宣言を使用することで、**FastAPI**は以下を行います:
|
||||
|
||||
* エディターサポート: エラーチェック、自動補完、など
|
||||
* データ「<abbr title="HTTPリクエストで受け取った文字列をPythonデータへ変換する">解析</abbr>」
|
||||
* データ「<dfn title="HTTPリクエストから受け取った文字列をPythonのデータに変換する">解析</dfn>」
|
||||
* データバリデーション
|
||||
* APIアノテーションと自動ドキュメント生成
|
||||
|
||||
|
||||
@@ -47,40 +47,16 @@ FastAPI はバージョン 0.95.0 で `Annotated` のサポートを追加し(
|
||||
|
||||
次の型アノテーションがありました:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
q: str | None = None
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python
|
||||
q: Union[str, None] = None
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
これを `Annotated` で包んで、次のようにします:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
q: Annotated[str | None] = None
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python
|
||||
q: Annotated[Union[str, None]] = None
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
どちらも同じ意味で、`q` は `str` または `None` になり得るパラメータで、デフォルトでは `None` です。
|
||||
|
||||
では、面白いところに進みましょう。 🎉
|
||||
@@ -109,7 +85,7 @@ FastAPI は次を行います:
|
||||
|
||||
## 代替(古い方法): デフォルト値としての `Query` { #alternative-old-query-as-the-default-value }
|
||||
|
||||
FastAPI の以前のバージョン(<abbr title="before 2023-03">0.95.0</abbr> より前)では、パラメータのデフォルト値として `Query` を使う必要があり、`Annotated` の中に入れるのではありませんでした。これを使ったコードを見かける可能性が高いので、説明します。
|
||||
FastAPI の以前のバージョン(<dfn title="2023-03 より前">0.95.0</dfn> より前)では、パラメータのデフォルト値として `Query` を使う必要があり、`Annotated` の中に入れるのではありませんでした。これを使ったコードを見かける可能性が高いので、説明します。
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -192,7 +168,7 @@ FastAPI なしで同じ関数を **別の場所** から **呼び出しても**
|
||||
|
||||
## 正規表現の追加 { #add-regular-expressions }
|
||||
|
||||
パラメータが一致するべき <abbr title="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings.">正規表現</abbr> `pattern` を定義することができます:
|
||||
パラメータが一致するべき <dfn title="正規表現、regex、regexp は、文字列に対する検索パターンを定義する文字の並びです。">正規表現</dfn> `pattern` を定義することができます:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
|
||||
|
||||
@@ -212,7 +188,7 @@ FastAPI なしで同じ関数を **別の場所** から **呼び出しても**
|
||||
|
||||
クエリパラメータ `q` の `min_length` を `3` とし、デフォルト値を `"fixedquery"` として宣言したいとします:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
|
||||
{* ../../docs_src/query_params_str_validations/tutorial005_an_py310.py hl[9] *}
|
||||
|
||||
/// note | 備考
|
||||
|
||||
@@ -242,7 +218,7 @@ q: Annotated[str | None, Query(min_length=3)] = None
|
||||
|
||||
そのため、`Query` を使いながら値を必須として宣言したい場合は、単にデフォルト値を宣言しません:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
|
||||
{* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *}
|
||||
|
||||
### 必須、`None` にできる { #required-can-be-none }
|
||||
|
||||
@@ -293,7 +269,7 @@ http://localhost:8000/items/?q=foo&q=bar
|
||||
|
||||
また、値が指定されていない場合はデフォルトの `list` を定義することもできます。
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
|
||||
{* ../../docs_src/query_params_str_validations/tutorial012_an_py310.py hl[9] *}
|
||||
|
||||
以下にアクセスすると:
|
||||
|
||||
@@ -316,7 +292,7 @@ http://localhost:8000/items/
|
||||
|
||||
`list[str]` の代わりに直接 `list` を使うこともできます:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
|
||||
{* ../../docs_src/query_params_str_validations/tutorial013_an_py310.py hl[9] *}
|
||||
|
||||
/// note | 備考
|
||||
|
||||
@@ -372,7 +348,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
|
||||
|
||||
さて、このパラメータが気に入らなくなったとしましょう。
|
||||
|
||||
それを使っているクライアントがいるので、しばらくは残しておく必要がありますが、ドキュメントには<abbr title="obsolete, recommended not to use it">deprecated</abbr>と明記しておきたいです。
|
||||
それを使っているクライアントがいるので、しばらくは残しておく必要がありますが、ドキュメントには<abbr title="obsolete, recommended not to use it - 廃止予定、使用は推奨されません">deprecated</abbr>と明記しておきたいです。
|
||||
|
||||
その場合、`Query`にパラメータ`deprecated=True`を渡します:
|
||||
|
||||
@@ -402,7 +378,7 @@ Pydantic には <a href="https://docs.pydantic.dev/latest/concepts/validators/#f
|
||||
|
||||
///
|
||||
|
||||
例えば、このカスタムバリデータは、<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-` で始まることをチェックします:
|
||||
例えば、このカスタムバリデータは、<abbr title="International Standard Book Number - 国際標準図書番号">ISBN</abbr> の書籍番号なら item ID が `isbn-` で始まること、<abbr title="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] *}
|
||||
|
||||
@@ -436,7 +412,7 @@ Pydantic には <a href="https://docs.pydantic.dev/latest/concepts/validators/#f
|
||||
|
||||
#### ランダムなアイテム { #a-random-item }
|
||||
|
||||
`data.items()` で、辞書の各アイテムのキーと値を含むタプルを持つ <abbr title="Something we can iterate on with a for loop, like a list, set, etc.">反復可能オブジェクト</abbr> を取得します。
|
||||
`data.items()` で、辞書の各アイテムのキーと値を含むタプルを持つ <dfn title="for ループで繰り返し処理できるもの(list、set など)">反復可能オブジェクト</dfn> を取得します。
|
||||
|
||||
この反復可能オブジェクトを `list(data.items())` で適切な `list` に変換します。
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
パスパラメータではない関数パラメータを宣言すると、それらは自動的に「クエリ」パラメータとして解釈されます。
|
||||
|
||||
{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
|
||||
{* ../../docs_src/query_params/tutorial001_py310.py hl[9] *}
|
||||
|
||||
クエリはURL内で `?` の後に続くキーとバリューの組で、 `&` で区切られています。
|
||||
|
||||
@@ -24,7 +24,7 @@ http://127.0.0.1:8000/items/?skip=0&limit=10
|
||||
パスパラメータに適用される処理と完全に同様な処理がクエリパラメータにも施されます:
|
||||
|
||||
* エディターサポート (明らかに)
|
||||
* データ <abbr title="converting the string that comes from an HTTP request into Python data">「解析」</abbr>
|
||||
* データ <dfn title="HTTP リクエストから来る文字列を Python のデータに変換すること">「解析」</dfn>
|
||||
* データバリデーション
|
||||
* 自動ドキュメント生成
|
||||
|
||||
@@ -128,7 +128,7 @@ http://127.0.0.1:8000/items/foo?short=yes
|
||||
|
||||
しかしクエリパラメータを必須にしたい場合は、ただデフォルト値を宣言しなければよいです:
|
||||
|
||||
{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
|
||||
{* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *}
|
||||
|
||||
ここで、クエリパラメータ `needy` は `str` 型の必須のクエリパラメータです。
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@ $ pip install python-multipart
|
||||
|
||||
## `File`と`Form`のインポート { #import-file-and-form }
|
||||
|
||||
{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[3] *}
|
||||
{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[3] *}
|
||||
|
||||
## `File`と`Form`のパラメータの定義 { #define-file-and-form-parameters }
|
||||
|
||||
ファイルやフォームのパラメータは`Body`や`Query`の場合と同じように作成します:
|
||||
|
||||
{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[10:12] *}
|
||||
{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[10:12] *}
|
||||
|
||||
ファイルとフォームフィールドがフォームデータとしてアップロードされ、ファイルとフォームフィールドを受け取ります。
|
||||
|
||||
|
||||
@@ -18,17 +18,17 @@ $ pip install python-multipart
|
||||
|
||||
`fastapi`から`Form`をインポートします:
|
||||
|
||||
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
|
||||
{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[3] *}
|
||||
|
||||
## `Form`のパラメータの定義 { #define-form-parameters }
|
||||
|
||||
`Body`や`Query`の場合と同じようにフォームパラメータを作成します:
|
||||
|
||||
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
|
||||
{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[9] *}
|
||||
|
||||
例えば、OAuth2仕様が使用できる方法の1つ(「パスワードフロー」と呼ばれる)では、フォームフィールドとして`username`と`password`を送信する必要があります。
|
||||
|
||||
<abbr title="specification – 仕様">spec</abbr>では、フィールドの名前が`username`と`password`であることと、JSONではなくフォームフィールドとして送信されることを要求しています。
|
||||
<dfn title="仕様">仕様</dfn>では、フィールドの名前が正確に`username`と`password`であることと、JSONではなくフォームフィールドとして送信されることを要求しています。
|
||||
|
||||
`Form`では`Body`(および`Query`や`Path`、`Cookie`)と同じ設定を宣言することができます。これには、バリデーション、例、エイリアス(例えば`username`の代わりに`user-name`)などが含まれます。
|
||||
|
||||
@@ -56,13 +56,13 @@ HTMLフォーム(`<form></form>`)がサーバにデータを送信する方
|
||||
|
||||
しかし、フォームがファイルを含む場合は、`multipart/form-data`としてエンコードされます。ファイルの扱いについては次の章で説明します。
|
||||
|
||||
これらのエンコーディングやフォームフィールドの詳細については、<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr>の<code>POST</code></a>のウェブドキュメントを参照してください。
|
||||
これらのエンコーディングやフォームフィールドの詳細については、<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Mozilla 開発者ネットワーク">MDN</abbr>の<code>POST</code></a>のウェブドキュメントを参照してください。
|
||||
|
||||
///
|
||||
|
||||
/// warning | 注意
|
||||
|
||||
*path operation*で複数の`Form`パラメータを宣言することができますが、JSONとして受け取ることを期待している`Body`フィールドを宣言することはできません。なぜなら、リクエストは`application/json`の代わりに`application/x-www-form-urlencoded`を使ってボディをエンコードするからです。
|
||||
*path operation*で複数の`Form`パラメータを宣言することができますが、JSONとして受け取ることを期待している`Body`フィールドを宣言することはできません。なぜなら、リクエストは`application/x-www-form-urlencoded`の代わりに`application/json`を使ってボディをエンコードするからです。
|
||||
|
||||
これは **FastAPI**の制限ではなく、HTTPプロトコルの一部です。
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ FastAPIはこの戻り値の型を使って以下を行います:
|
||||
|
||||
/// note | 備考
|
||||
|
||||
`response_model`は「デコレータ」メソッド(`get`、`post`など)のパラメータであることに注意してください。すべてのパラメータやボディのように、*path operation 関数* のパラメータではありません。
|
||||
`response_model`は「デコレータ」メソッド(`get`、`post`など)のパラメータです。関数のパラメータやボディなどとは違い、*path operation 関数*のパラメータではありません。
|
||||
|
||||
///
|
||||
|
||||
@@ -183,7 +183,7 @@ Pydanticフィールドとして有効ではないものを返し、ツール(
|
||||
|
||||
最も一般的なケースは、[高度なドキュメントで後述する「Responseを直接返す」](../advanced/response-directly.md){.internal-link target=_blank}場合です。
|
||||
|
||||
{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
|
||||
{* ../../docs_src/response_model/tutorial003_02_py310.py hl[8,10:11] *}
|
||||
|
||||
このシンプルなケースは、戻り値の型アノテーションが `Response` のクラス(またはサブクラス)であるため、FastAPIが自動的に処理します。
|
||||
|
||||
@@ -193,7 +193,7 @@ Pydanticフィールドとして有効ではないものを返し、ツール(
|
||||
|
||||
型アノテーションで `Response` のサブクラスを使うこともできます:
|
||||
|
||||
{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
|
||||
{* ../../docs_src/response_model/tutorial003_03_py310.py hl[8:9] *}
|
||||
|
||||
これは `RedirectResponse` が `Response` のサブクラスであり、FastAPIがこのシンプルなケースを自動処理するため、同様に動作します。
|
||||
|
||||
@@ -201,7 +201,7 @@ Pydanticフィールドとして有効ではないものを返し、ツール(
|
||||
|
||||
しかし、Pydantic型として有効ではない別の任意のオブジェクト(例: データベースオブジェクト)を返し、関数でそのようにアノテーションすると、FastAPIはその型アノテーションからPydanticレスポンスモデルを作成しようとして失敗します。
|
||||
|
||||
同様に、<abbr title='複数の型のunionは「これらの型のいずれか」を意味します。'>union</abbr>のように、複数の型のうち1つ以上がPydantic型として有効でないものを含む場合も起こります。例えば次は失敗します 💥:
|
||||
同様に、<dfn title="複数の型のユニオンは「これらの型のいずれか」を意味します。">ユニオン</dfn>のように、複数の型のうち1つ以上がPydantic型として有効でないものを含む場合も起こります。例えば次は失敗します 💥:
|
||||
|
||||
{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* `@app.delete()`
|
||||
* etc.
|
||||
|
||||
{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
|
||||
{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
|
||||
|
||||
/// note | 備考
|
||||
|
||||
@@ -74,7 +74,7 @@ HTTPでは、レスポンスの一部として3桁の数字のステータスコ
|
||||
|
||||
先ほどの例をもう一度見てみましょう:
|
||||
|
||||
{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
|
||||
{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
|
||||
|
||||
`201`は「作成完了」のためのステータスコードです。
|
||||
|
||||
@@ -82,7 +82,7 @@ HTTPでは、レスポンスの一部として3桁の数字のステータスコ
|
||||
|
||||
`fastapi.status`の便利な変数を利用することができます。
|
||||
|
||||
{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *}
|
||||
{* ../../docs_src/response_status_code/tutorial002_py310.py hl[1,6] *}
|
||||
|
||||
それらは単なる便利なものであり、同じ番号を保持しています。しかし、その方法ではエディタの自動補完を使用してそれらを見つけることができます。
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ Pydanticモデルで`Field()`を使う場合、追加の`examples`も宣言で
|
||||
|
||||
この場合、examplesはそのボディデータの内部**JSON Schema**の一部になります。
|
||||
|
||||
それでも、<abbr title="2023-08-26">執筆時点</abbr>では、ドキュメントUIの表示を担当するツールであるSwagger UIは、**JSON Schema**内のデータに対して複数の例を表示することをサポートしていません。しかし、回避策については以下を読んでください。
|
||||
それでも、<dfn title="2023-08-26">執筆時点</dfn>では、ドキュメントUIの表示を担当するツールであるSwagger UIは、**JSON Schema**内のデータに対して複数の例を表示することをサポートしていません。しかし、回避策については以下を読んでください。
|
||||
|
||||
### OpenAPI固有の`examples` { #openapi-specific-examples }
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
`main.py`に、下記の例をコピーします:
|
||||
|
||||
{* ../../docs_src/security/tutorial001_an_py39.py *}
|
||||
{* ../../docs_src/security/tutorial001_an_py310.py *}
|
||||
|
||||
## 実行 { #run-it }
|
||||
|
||||
@@ -132,7 +132,7 @@ OAuth2は、バックエンドやAPIがユーザーを認証するサーバー
|
||||
|
||||
`OAuth2PasswordBearer` クラスのインスタンスを作成する時に、パラメーター`tokenUrl`を渡します。このパラメーターには、クライアント (ユーザーのブラウザで動作するフロントエンド) がトークンを取得するために`username`と`password`を送信するURLを指定します。
|
||||
|
||||
{* ../../docs_src/security/tutorial001_an_py39.py hl[8] *}
|
||||
{* ../../docs_src/security/tutorial001_an_py310.py hl[8] *}
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -150,7 +150,7 @@ OAuth2は、バックエンドやAPIがユーザーを認証するサーバー
|
||||
|
||||
/// info | 情報
|
||||
|
||||
非常に厳格な「Pythonista」であれば、パラメーター名のスタイルが`token_url`ではなく`tokenUrl`であることを気に入らないかもしれません。
|
||||
非常に厳格な「Pythonista」であれば、パラメーター名のスタイルが`tokenUrl`ではなく`token_url`であることを気に入らないかもしれません。
|
||||
|
||||
それはOpenAPI仕様と同じ名前を使用しているからです。そのため、これらのセキュリティスキームについてもっと調べる必要がある場合は、それをコピーして貼り付ければ、それについての詳細な情報を見つけることができます。
|
||||
|
||||
@@ -170,7 +170,7 @@ oauth2_scheme(some, parameters)
|
||||
|
||||
これで`oauth2_scheme`を`Depends`で依存関係に渡すことができます。
|
||||
|
||||
{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
|
||||
{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
|
||||
|
||||
この依存関係は、*path operation 関数*のパラメーター`token`に代入される`str`を提供します。
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
一つ前の章では、(依存性注入システムに基づいた)セキュリティシステムは、 *path operation 関数* に `str` として `token` を与えていました:
|
||||
|
||||
{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
|
||||
{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
|
||||
|
||||
しかし、それはまだそんなに有用ではありません。
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# セキュリティ入門
|
||||
# セキュリティ入門 { #security }
|
||||
|
||||
セキュリティ、認証、認可を扱うには多くの方法があります。
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
|
||||
しかし、その前に、いくつかの小さな概念を確認しましょう。
|
||||
|
||||
## お急ぎですか?
|
||||
## お急ぎですか? { #in-a-hurry }
|
||||
|
||||
もし、これらの用語に興味がなく、ユーザー名とパスワードに基づく認証でセキュリティを**今すぐ**確保する必要がある場合は、次の章に進んでください。
|
||||
|
||||
## OAuth2
|
||||
## OAuth2 { #oauth2 }
|
||||
|
||||
OAuth2は、認証と認可を処理するためのいくつかの方法を定義した仕様です。
|
||||
|
||||
@@ -24,7 +24,7 @@ OAuth2は、認証と認可を処理するためのいくつかの方法を定
|
||||
|
||||
これが、「Facebook、Google、X (Twitter)、GitHubを使ってログイン」を使用したすべてのシステムの背後で使われている仕組みです。
|
||||
|
||||
### OAuth 1
|
||||
### OAuth 1 { #oauth-1 }
|
||||
|
||||
OAuth 1というものもありましたが、これはOAuth2とは全く異なり、通信をどのように暗号化するかという仕様が直接的に含まれており、より複雑なものとなっています。
|
||||
|
||||
@@ -38,7 +38,7 @@ OAuth2は、通信を暗号化する方法を指定せず、アプリケーシ
|
||||
|
||||
///
|
||||
|
||||
## OpenID Connect
|
||||
## OpenID Connect { #openid-connect }
|
||||
|
||||
OpenID Connectは、**OAuth2**をベースにした別の仕様です。
|
||||
|
||||
@@ -48,7 +48,7 @@ OpenID Connectは、**OAuth2**をベースにした別の仕様です。
|
||||
|
||||
しかし、FacebookのログインはOpenID Connectをサポートしていません。OAuth2を独自にアレンジしています。
|
||||
|
||||
### OpenID (「OpenID Connect」ではない)
|
||||
### OpenID (「OpenID Connect」ではない) { #openid-not-openid-connect }
|
||||
|
||||
また、「OpenID」という仕様もありました。それは、**OpenID Connect**と同じことを解決しようとしたものですが、OAuth2に基づいているわけではありませんでした。
|
||||
|
||||
@@ -56,7 +56,7 @@ OpenID Connectは、**OAuth2**をベースにした別の仕様です。
|
||||
|
||||
現在ではあまり普及していませんし、使われてもいません。
|
||||
|
||||
## OpenAPI
|
||||
## OpenAPI { #openapi }
|
||||
|
||||
OpenAPI(以前はSwaggerとして知られていました)は、APIを構築するためのオープンな仕様です(現在はLinux Foundationの一部になっています)。
|
||||
|
||||
@@ -97,7 +97,7 @@ Google、Facebook、X (Twitter)、GitHubなど、他の認証/認可プロバイ
|
||||
|
||||
///
|
||||
|
||||
## **FastAPI** ユーティリティ
|
||||
## **FastAPI** ユーティリティ { #fastapi-utilities }
|
||||
|
||||
FastAPIは `fastapi.security` モジュールの中で、これらのセキュリティスキームごとにいくつかのツールを提供し、これらのセキュリティメカニズムを簡単に使用できるようにします。
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# パスワード(およびハッシュ化)によるOAuth2、JWTトークンによるBearer { #oauth2-with-password-and-hashing-bearer-with-jwt-tokens }
|
||||
|
||||
これでセキュリティの流れが全てわかったので、<abbr title="JSON Web Tokens">JWT</abbr>トークンと安全なパスワードのハッシュ化を使用して、実際にアプリケーションを安全にしてみましょう。
|
||||
これでセキュリティの流れが全てわかったので、<abbr title="JSON Web Tokens - JSON Web Token">JWT</abbr>トークンと安全なパスワードのハッシュ化を使用して、実際にアプリケーションを安全にしてみましょう。
|
||||
|
||||
このコードは、アプリケーションで実際に使用したり、パスワードハッシュをデータベースに保存するといった用途に利用できます。
|
||||
|
||||
@@ -116,7 +116,11 @@ pwdlibはbcryptハッシュアルゴリズムもサポートしていますが
|
||||
|
||||
さらに、ユーザーを認証して返す関数も作成します。
|
||||
|
||||
{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *}
|
||||
{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,51,58:59,62:63,72:79] *}
|
||||
|
||||
`authenticate_user` がデータベースに存在しないユーザー名で呼び出された場合でも、ダミーのハッシュを使って `verify_password` を実行します。
|
||||
|
||||
これにより、ユーザー名が有効かどうかに関わらずエンドポイントの応答時間がおおよそ同じになり、既存のユーザー名を列挙するために悪用されうる「タイミング攻撃」を防止できます。
|
||||
|
||||
/// note | 備考
|
||||
|
||||
@@ -152,7 +156,7 @@ JWTトークンの署名に使用するアルゴリズム`"HS256"`を指定し
|
||||
|
||||
新しいアクセストークンを生成するユーティリティ関数を作成します。
|
||||
|
||||
{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
|
||||
{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,82:90] *}
|
||||
|
||||
## 依存関係の更新 { #update-the-dependencies }
|
||||
|
||||
@@ -162,7 +166,7 @@ JWTトークンの署名に使用するアルゴリズム`"HS256"`を指定し
|
||||
|
||||
トークンが無効な場合は、すぐにHTTPエラーを返します。
|
||||
|
||||
{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *}
|
||||
{* ../../docs_src/security/tutorial004_an_py310.py hl[93:110] *}
|
||||
|
||||
## `/token` *path operation* の更新 { #update-the-token-path-operation }
|
||||
|
||||
@@ -170,7 +174,7 @@ JWTトークンの署名に使用するアルゴリズム`"HS256"`を指定し
|
||||
|
||||
実際のJWTアクセストークンを作成し、それを返します。
|
||||
|
||||
{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
|
||||
{* ../../docs_src/security/tutorial004_an_py310.py hl[121:136] *}
|
||||
|
||||
### JWTの「subject」`sub` についての技術的な詳細 { #technical-details-about-the-jwt-subject-sub }
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* `StaticFiles` をインポート。
|
||||
* `StaticFiles()` インスタンスを特定のパスに「マウント」。
|
||||
|
||||
{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
|
||||
{* ../../docs_src/static_files/tutorial001_py310.py hl[2,6] *}
|
||||
|
||||
/// note | 技術詳細
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ $ pip install httpx
|
||||
|
||||
チェックしたい Python の標準的な式と共に、シンプルに `assert` 文を記述します (これも `pytest` の標準です)。
|
||||
|
||||
{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *}
|
||||
{* ../../docs_src/app_testing/tutorial001_py310.py hl[2,12,15:18] *}
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -76,7 +76,7 @@ FastAPIアプリケーションへのリクエストの送信とは別に、テ
|
||||
ファイル `main.py` に **FastAPI** アプリがあります:
|
||||
|
||||
|
||||
{* ../../docs_src/app_testing/app_a_py39/main.py *}
|
||||
{* ../../docs_src/app_testing/app_a_py310/main.py *}
|
||||
|
||||
### テストファイル { #testing-file }
|
||||
|
||||
@@ -92,7 +92,7 @@ FastAPIアプリケーションへのリクエストの送信とは別に、テ
|
||||
|
||||
このファイルは同じパッケージ内にあるため、相対インポートを使って `main` モジュール (`main.py`) からオブジェクト `app` をインポートできます:
|
||||
|
||||
{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
|
||||
{* ../../docs_src/app_testing/app_a_py310/test_main.py hl[3] *}
|
||||
|
||||
|
||||
...そして、これまでと同じようにテストコードを書けます。
|
||||
|
||||
@@ -50,7 +50,7 @@ $ cd awesome-project
|
||||
|
||||
## 仮想環境の作成 { #create-a-virtual-environment }
|
||||
|
||||
Pythonプロジェクトでの**初めての**作業を開始する際には、**<abbr title="there are other options, this is a simple guideline – 他の選択肢もありますが、これはシンプルなガイドラインです">プロジェクト内</abbr>**に仮想環境を作成してください。
|
||||
Pythonプロジェクトでの**初めての**作業を開始する際には、**<dfn title="他の選択肢もありますが、これはシンプルなガイドラインです">プロジェクト内</dfn>**に仮想環境を作成してください。
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
@@ -163,7 +163,7 @@ $ source .venv/Scripts/activate
|
||||
|
||||
**新しいパッケージ**を仮想環境にインストールするたびに、環境をもう一度**有効化**してください。
|
||||
|
||||
こうすることで、そのパッケージがインストールした**ターミナル(<abbr title="command line interface">CLI</abbr>)プログラム**を使用する場合に、仮想環境内のものが確実に使われ、グローバル環境にインストールされている別のもの(おそらく必要なものとは異なるバージョン)を誤って使用することを防ぎます。
|
||||
こうすることで、そのパッケージがインストールした**ターミナル(<abbr title="command line interface - コマンドラインインターフェース">CLI</abbr>)プログラム**を使用する場合に、仮想環境内のものが確実に使われ、グローバル環境にインストールされている別のもの(おそらく必要なものとは異なるバージョン)を誤って使用することを防ぎます。
|
||||
|
||||
///
|
||||
|
||||
|
||||
Reference in New Issue
Block a user