3

I have the following code that uses Pydantic BaseModel data class

from enum import Enum

import requests
from pydantic import BaseModel
from requests import Response


class PetType(Enum):
    DOG: str = 'dog'
    CAT: str = 'cat'


class Pet(BaseModel):
    name: str
    type: PetType


my_dog: Pet = Pet(name='Lucky', type=PetType.DOG)

# This works
resp: Response = requests.post('https://postman-echo.com/post', json=my_dog.json())
print(resp.json())

#This doesn't work
resp: Response = requests.post('https://postman-echo.com/post', json=my_dog.dict())
print(resp.json())

That when I send json equals to model's dict(), I get the error:

> TypeError: Object of type 'PetType' is not JSON serializable

How do I overcome this error and make PetType also serializable?

P.S. The above example is short and simple, but I hit a use case where both cases of sending

json=my_dog.json() 

and

json=my_dog.dict() 

don't work. This is why I need to solve sending using dict()

RaamEE
  • 3,017
  • 4
  • 33
  • 53

1 Answers1

11

**<---- Addition ----> **

Look for Pydantic's parameter "use_enum_values" in Pydantic Model Config

use_enum_values whether to populate models with the value property of enums, rather than the raw enum. This may be useful if you want to serialise model.dict() later (default: False)

It looks like setting this value to True will do the same as the below solution.


Turns out that this is a behavior of ENum, which is discussed here: https://github.com/samuelcolvin/pydantic/issues/2278

The way you should define the enum is using

class PetType(str, Enum):

instead of

class PetType(Enum):

For integers this Python's Enum library provides the type IntEnum: https://docs.python.org/3.10/library/enum.html#enum.IntEnum

which is basically

class IntEnum(int, Enum):
    pass

If you look at the above Enum documentation you will find that a type like StrEnum doesn't exist but following the example for PetType you can define it easily.

I am attaching the working code below

from enum import Enum

import requests
from pydantic import BaseModel
from requests import Response


class PetType(str, Enum):
    DOG: str = 'dog'
    CAT: str = 'cat'


class Pet(BaseModel):
    name: str
    type: PetType


my_dog: Pet = Pet(name='Lucky', type=PetType.DOG)

# This works
resp: Response = requests.post('https://postman-echo.com/post', json=my_dog.json())
print(resp.json())

# Now this also works
resp: Response = requests.post('https://postman-echo.com/post', json=my_dog.dict())
print(resp.json())
RaamEE
  • 3,017
  • 4
  • 33
  • 53