python

【Python】FastAPIの404エラーを自作ハンドラーで返却する

今回はPythonのFastAPIで404エラーをハンドリングする方法を解説します。

最近業務で自作ハンドラーを作成する機会があったのでまとめです。

404エラーをハンドリングする

エラーハンドリング作成前のコードはこちらです。

import uvicorn
from fastapi import FastAPI

app = FastAPI()


@app.get(path="/hello")
def hello_world():
    return {"hello": "world"}


def main():
    uvicorn.run("main:app", port=8000, host="0.0.0.0", reload=True)


if __name__ == "__main__":
    main()

この状態で立ち上げをして、存在しないURLにアクセスしてみます。

今回はvscodeのREST Clientという拡張機能を使い、http:localhost:8000/itemにアクセスしてみます。

REST Clientの説明はこちら

https://marketplace.visualstudio.com/items?itemName=humao.rest-client

するとこんな画面になります。

デフォルトでは404エラー時に{“detail”: “Not Found”}とでています。

これを自分の好きなレスポンスの形にしてみます。

自作ハンドラーを定義

自作ハンドラーについては公式ドキュメントに使用例が載っています。

https://fastapi.tiangolo.com/ja/tutorial/handling-errors/

ここを参考にしつつ、404エラーを拾う処理を書いたものがこちらになります。

import uvicorn
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import JSONResponse

app = FastAPI()


@app.get(path="/hello")
def hello_world():
    return {"hello": "world"}

# 自作ハンドラー定義
@app.exception_handler(404)
def not_found_error(req: Request, exc: HTTPException):
    return JSONResponse(content={"hoge": "hoge", "foo": "bar"}, status_code=404)


def main():
    uvicorn.run("main:app", port=8000, host="0.0.0.0", reload=True)


if __name__ == "__main__":
    main()

自作ハンドラーを定義するにはFastAPIインスタンスのexception_handlerをデコレートすれば良いです。

引数にintを指定した場合、該当ステータス時に指定した処理が走るようになります。

JSONResponse()に返却したい内容を記述します。

この状態で起動し、もう一度リクエストを送ってみます。

先程からかわり、自分で定義したbodyが返却されているのがわかります。

JSONResponseのスタータスコードを変更すれば404で受けたリクエストを別ステータスで返却することもできます。

import uvicorn
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import JSONResponse

app = FastAPI()


@app.get(path="/hello")
def hello_world():
    return {"hello": "world"}


@app.exception_handler(404)
def not_found_error(req: Request, exc: HTTPException):
    return JSONResponse(content={"hoge": "hoge", "foo": "bar"}, status_code=418)


def main():
    uvicorn.run("main:app", port=8000, host="0.0.0.0", reload=True)


if __name__ == "__main__":
    main()

status_code引数を418にしてみました。

ちなみに418ステータスはI’m a Teapotというジョークレスポンスらしいです。

https://developer.mozilla.org/ja/docs/Web/HTTP/Status/418

これでリクエストを送ってみます。

返却されているステータスコードが418になっていることが確認できました。

まとめ

今回はFastAPIで404ステータスにエラーハンドリングする方法を解説しました。

まとめです。

exception_handler(404)のデコレータを定義する。

JSONResponseで好きなレスポンスを定義する。

以上になります。