FastAPI でレスポンスステータスコードを宣言する:`status_code` パラメータと OpenAPI への反映
FastAPI でレスポンスステータスコードを宣言するstatus_codeパラメータと OpenAPI への反映【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapiapp.get()やapp.post()といったpath operationsのデコレータにstatus_codeを渡すだけで、その API が返す HTTP ステータスコードを宣言できます。宣言したコードは実際のレスポンスに反映されるだけでなく、OpenAPI スキーマと Swagger UI・ReDoc などの自動生成ドキュメントにも正しく記録されます。本記事では、このstatus_codeの使い方、HTTP ステータスコードの分類、fastapi.statusを使った命名定数の活用方法を、FastAPI のソースコードとテスト実装を交えて解説します。status_codeでレスポンスのステータスコードを宣言するレスポンスモデルresponse_modelを指定するのと同じ感覚で、path operationsのいずれかのstatus_codeパラメータに、レスポンスで使う HTTP ステータスコードを宣言できます。対応するデコレータは次のとおりです。app.get()app.post()app.put()app.delete()app.patch()など実際のコード例は tutorial001_py310.py です。from fastapi import FastAPI app FastAPI() app.post(/items/, status_code201) async def create_item(name: str): return {name: name}この例ではPOST /items/に対し、作成が成功したことを表す201Createdを宣言しています。実行すると次の 2 つの効果があります。レスポンスでそのステータスコードここでは201を返します。OpenAPI スキーマおよびユーザーインターフェースにもステータスコードとして文書化されます。重要な注意点デコレータのパラメータであることstatus_codeは「デコレータ」メソッドget、postなどのパラメータであり、通常のクエリパラメータやボディとは違い、path operation functionエンドポイント関数のパラメータではありません。この点を混同しないようにしてください。受け取れる値数値とIntEnumstatus_codeパラメータは HTTP ステータスコードを含む数値をそのまま受け取ります。加えて、Python 標準ライブラリのhttp.HTTPStatusのようなIntEnumも受け取れます。この「IntEnumも受け付ける」仕様はソースコード上でも確認できます。ルート定義時の処理を見ると、routing.py で次のように列挙型をintに正規化してから保存しています。# normalize enums e.g. http.HTTPStatus if isinstance(status_code, IntEnum): status_code int(status_code) route.status_code status_code実際のリポジトリ内テスト tests/main.py にも、http.HTTPStatus.CREATEDをそのまま渡している例があります。app.get(/enum-status-code, status_codehttp.HTTPStatus.CREATED) def get_enum_status_code(): return foo barそして test_application.py では、このエンドポイントへのリクエストが201を返すこと、OpenAPI のpathsに201のレスポンス定義が含まれることが検証されています。ボディを持たないステータスコードの扱い一部のレスポンスコード次節で説明は、レスポンスにボディが存在しないことを示します。FastAPI はこれを認識しており、レスポンスボディがない旨の OpenAPI ドキュメントを生成します。この「ボディを持てるかどうか」の判定は utils.py のis_body_allowed_for_status_code()に実装されており、204・205・304および200未満のコードをボディ禁止としています。また routing.py では、response_modelを持つルートに対してこの判定をassertで強制しています。if route.response_model: assert is_body_allowed_for_status_code(status_code), ( fStatus code {status_code} must not have a response body )なお、OpenAPI スキーマ生成時には openapi/utils.py でroute.status_codeが文字列化され、operation[responses]のキーとして採用されます。つまり宣言したステータスコードがそのまま/openapi.jsonや Swagger UI・ReDoc に現れる仕組みです。HTTP ステータスコードについてHTTP では、レスポンスの一部として 3 桁の数字からなるステータスコードを送信します。各ステータスコードには識別用の名前が付けられていますが、重要なのはその数字そのものです。おおまかな分類は次のとおりです。100 - 199「情報」用です。直接使うことはほとんどありません。これらのステータスコードを持つレスポンスはボディを持つことができません。200 - 299「成功」レスポンス用で、最もよく使う範囲です。200はデフォルトのステータスコードで、すべてが「OK」であることを意味します。別の例として201Createdがあり、データベースに新しいレコードを作成した後によく使われます。特殊なケースとして204No Contentがあります。クライアントに返すコンテンツがない場合に使うため、レスポンスはボディを持ってはいけません。300 - 399「リダイレクト」用です。これらのレスポンスは、ボディを持たなければならない304Not Modifiedを除き、ボディを持つことも持たないこともできます。400 - 499「クライアントエラー」レスポンス用で、2 番目に多用するタイプでしょう。例として404は「Not Found」レスポンスです。クライアント側の一般的なエラーには400を使えます。500 - 599サーバーエラー用です。直接使うことはほとんどありません。アプリケーションコードやサーバーのどこかで問題が発生した場合は、これらのステータスコードのいずれかが自動的に返されます。それぞれのステータスコードが何のためにあるのかをより詳しく知りたい場合は、MDN の「HTTP レスポンスステータスコード」ドキュメントが参考になります。名前を覚えるための近道fastapi.status先ほどの例を振り返りましょう。from fastapi import FastAPI app FastAPI() app.post(/items/, status_code201) async def create_item(name: str): return {name: name}201は「作成完了Created」のためのステータスコードです。とはいえ、すべてのコードの意味を暗記する必要はありません。fastapi.statusの便利な定数を利用できます。コード例は tutorial002_py310.py です。from fastapi import FastAPI, status app FastAPI() app.post(/items/, status_codestatus.HTTP_201_CREATED) async def create_item(name: str): return {name: name}status.HTTP_201_CREATEDは201と同じ数値を保持しているだけの「便利な名前」であり、機能面での違いはありません。しかし、この書き方であればエディタの自動補完を使って該当する定数を探せるため、数値を暗記する必要がなくなります。技術詳細fastapi.statusとstarlette.statusの関係from starlette import statusと書くこともできます。FastAPI は開発者の利便性のために、starlette.statusと同じものをfastapi.statusとして公開していますが、その実体は Starlette が提供しているものです。実際、リポジトリの fastapi/init.py には次の 1 行があるだけで、FastAPI 自身が status 定数を再定義しているわけではありません。from starlette import status as statusつまり、fastapi.status.HTTP_201_CREATEDもstarlette.status.HTTP_201_CREATEDも同じ定数を指しており、どちらを使っても挙動は変わりません。宣言したステータスコードが使われる仕組みルーティング層では、レスポンスの組み立て時にステータスコードを次のように解決していますrouting.py 付近。current_status_code ( status_code if status_code else solved_result.response.status_code ) ... if current_status_code is not None: response_args[status_code] current_status_codeこの処理からわかるのは、デコレータでstatus_codeを明示した場合はそれが優先され、省略した場合Noneはレスポンスオブジェクトが持つデフォルト値通常は200が使われるということです。したがって、エンドポイント関数側でResponseを直接返してstatus_codeを指定した場合などは、関数側の値が優先される設計になっています。また、OpenAPI スキーマの生成時にも、明示的にstatus_codeを宣言していないルートについては、レスポンスクラスのコンストラクタのデフォルト値からステータスコードを推測する処理が入っていますopenapi/utils.py 付近。このため、自動生成ドキュメント上のレスポンス定義は、宣言の有無を問わず実際の挙動と一致しやすくなっています。デフォルトの変更と次のステップ宣言していない場合のデフォルトのステータスコードは200OKです。しかし実際のアプリケーションでは、エンドポイントの処理結果に応じて動的にステータスコードを変えたいケースがよくあります。たとえば、作成時に201を返すと宣言しておきながら、何らかの条件で別のコードを返す、といった処理です。こうした「ここで宣言しているデフォルトとは異なるステータスコードを返す方法」については、高度なユーザーガイドレスポンスのステータスコードを変更する英語版は docs/en/docs/advanced/response-change-status-code.mdで詳しく解説されています。エンドポイント関数内でResponseオブジェクトを直接操作する方法を学べるので、宣言型のstatus_codeとあわせて使い分けることで、より柔軟なレスポンス制御が可能になります。【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考