覆盖 FastAPI 中 jsonable_encoder 的默认编码器

Kar*_*son 9 python fastapi

我有使用Fast API 的代码,看起来像这样:

class EnumTestT(Enum):
    test_t_value = 0

object = { 
    test: test_t_value
}

enum_mapping = {
    test_t_value: "Test"
}

def enum_encoder(val: EnumTestT) -> str:
    return enum_mapping[val]

custom_encoder = {
    EnumTestT: enum_encoder
}

@app.get("/test")
async def test_get():
    return jsonable_encoder(object, custom_encoder=custom_encoder)
Run Code Online (Sandbox Code Playgroud)

问题是jsonable_encoder在默认编码器之后应用自定义编码器。有什么方法可以在默认编码器之前应用它们。因为对于Enum任何派生类,报告的是枚举值而不是映射值。

cod*_* vx 6

FastAPI 使用 ENCODERS_BY_TYPE (来自 pydantic.json)来编码一些基本数据类型。

ENCODERS_BY_TYPE: Dict[Type[Any], Callable[[Any], Any]] = {
    bytes: lambda o: o.decode(),
    Color: str,
    datetime.date: isoformat,
    datetime.datetime: isoformat,
    datetime.time: isoformat,
    datetime.timedelta: lambda td: td.total_seconds(),
    Decimal: decimal_encoder,
    Enum: lambda o: o.value,
Run Code Online (Sandbox Code Playgroud)

所以对我来说要覆盖默认的日期时间编码,就像

 ENCODERS_BY_TYPE[datetime] = lambda date_obj: date_obj.strftime("%Y-%m-%d %H:%M:%S")

Run Code Online (Sandbox Code Playgroud)


Kar*_*son 5

现在我正在使用自定义编码器,json.dumps如下所示:

class TestEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, EnumTestT):
            return TestEncoder.process_enum_test_t(obj)

Run Code Online (Sandbox Code Playgroud)

FastAPI 应用程序内的响应将是:

json_str = json.dumps(json_list, cls=TestEncoder).encode('utf-8')
return Response(media_type="application/json", content=json_str)
Run Code Online (Sandbox Code Playgroud)

使用自定义编码器的 FastAPI 的问题在于,在调用所有标准编码器之后才调用自定义编码器,并且无法覆盖该顺序。