Why does pydantic not encode my bool in json?

Viewed 834

I want to have Pydantic write booleans as either "y" or "n". The Pydantic documentation on encoders suggests that I can configure a way to encode values based on their data type, in my case bool.

from pydantic import BaseModel

class MyStuff(BaseModel):
    do_it: bool = False

    class Config:
        json_encoders = {
            bool: lambda b: "y" if b else "n",
        }

ms = MyStuff()
print(ms.json(exclude_defaults=False))

When I run this, I get

{"do_it": false}

when I expected

{"do_it": "n"}

Other tries:

  • It does not matter whether I specify a default or not.

  • I cannot get it to work for other basic data types like int either, but it does work for pathlib.Path.

  • It does not work either if I replace the lambda with a function like this:

def convert_my_bool(b: bool) -> str:
    if b:
        return "y"
    return "n"

class MyStuff(BaseModel):
    do_it: bool

    class Config:
        json_encoders = {
            bool: convert_my_bool,
        }

What am I missing here? How do I need to write my Config to write booleans in my model as "y" or "n"?

1 Answers
import orjson
from pydantic import BaseModel


def orjson_dumps(v, *, default=None):
    for key, value in v.items():
        if isinstance(value, bool):
            v[key] = "y" if value else "n"

    return orjson.dumps(
        v,
        default=default,
    ).decode()


class MyStuff(BaseModel):
    do_it: bool = False

    class Config:
        # Change default json encoders/decoders to orjson ones
        json_loads = orjson.loads
        json_dumps = orjson_dumps


ms = MyStuff()
print(ms.json(exclude_defaults=False))
Related