パイソニスタの皆さん、こんにちは!![]()
FastAPIでAPIエンドポイントを実装していたところ、
TypeError: Object of type datetime is not JSON serializable
というエラーに出会いましたので、こちらの解説と回避策をご紹介します。
何をしたら起きたの?
ある日の業務で、FastAPIライブラリを使って次のコードを実装していました。
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from datetime import datetime
app = FastAPI()
@app.get("/")
def main_endpoint():
# 実際はデータベースから取得したタイムスタンプデータです。
datetime_data = datetime(2025, 9, 20, 15, 45, 30)
response_dict = {"timestamp": datetime_data}
return JSONResponse(content=response_dict)
実際のコードとは異なりますが、得られる挙動は同じです。
ここで、uvicorn君を起動してエンドポイントにアクセスすると、以下のエラーが表示されました。
TypeError: Object of type datetime is not JSON serializable
datetime型のオブジェクトはJSONシリアライズできません
どうやら、datetimeオブジェクトが原因でFastAPIのJSONResponse関数実行中にエラーが起きたようです。
どうやって直したの?
調べたところ、Python標準のJSONエンコーダはdatetime型をそのまま扱えないことが分かりました。
そこで、datetimeオブジェクトを文字列に変換して対応しました。
[方法1] str関数で文字列化する
標準関数のstr()でdatetimeオブジェクトを囲むと、文字列に変換できます。
from datetime import datetime
datetime_data = datetime(2025, 9, 20, 15, 45, 30)
response_dict = {"timestamp": str(datetime_data)} # datetimeを文字列化
[方法2] FastAPIのシリアライズ関数でJSON化する
FastAPIには、datetimeオブジェクトをISO 8601形式の文字列に変換した上でJSONにシリアライズする「jsonable_encoder関数」があります。
これを使うと、datetimeオブジェクトを直接触らなくてもシリアライズできます。
from fastapi.encoders import jsonable_encoder
from datetime import datetime
datetime_data = datetime(2025, 9, 20, 15, 45, 30)
response_dict = {"timestamp": datetime_data} # datetime_dataはdatetimeオブジェクト
return JSONResponse(content=jsonable_encoder(response_dict)) # datetimeを文字列化してJSONシリアライズ
なんでJSON化できないの?
さて、今回のエラーの原因となったJSONですが、なぜdatetimeオブジェクトを格納できないのでしょうか。
JSONは、IETFが発行する標準文書「RFC (Request for Comments)」によって定義されています。
JSONについて規定したRFC 8259を参照すると、次の通り定義されています。
JavaScript Object Notation (JSON) is a text format for the serialization of structured data. It is derived from the object literals of JavaScript, as defined in the ECMAScript Programming Language Standard, Third Edition [ECMA-262].
JSON can represent four primitive types (strings, numbers, booleans,and null) and two structured types (objects and arrays).
(1.introductionより引用)
(筆者訳)
JavaScript Object Notation(JSON)は、構造化データをシリアライズするためのテキスト形式である。これは、ECMAScriptプログラミング言語標準 第3版 [ECMA-262] で定義されている JavaScript のオブジェクトリテラルから派生している。
JSONは、4つのプリミティブ型(文字列、数値、真偽値、null)と、2つの構造化型(オブジェクトと配列)を表現できる。
つまり、JSONは
- 文字列
- 数値
- 真偽値 (True, False)
- null
を格納する配列とオブジェクト(キーと値のペア)しか表現できません。
したがって、datetimeやUUIDのような専用オブジェクトは仕様上そのまま表現できず、文字列などの対応可能な型に変換してから格納する必要があります。
今回のエラーはこれが原因で発生したわけです。
(参照) シリアライズ
(参照) オブジェクト
以上です!
最後までお読みいただき、ありがとうございました!