Encoding Python Enum to JSON
It is an old question. But no one gave this very simple answer.
You just need to subclass your Enum from str.
import json
from enum import Enum
class TestEnum(str, Enum):
one = "first"
two = "second"
three = "third"
test = {TestEnum.one : "This",
TestEnum.two : "should",
TestEnum.three : "work!"}
print(json.dumps(test))
outputs:
{"first": "This", "second": "should", "third": "work!"}
You can't use anything but strings as keys in dictionaries you want to convert to JSON. The encoder doesn't give you any other options; the default
hook is only called for values of unknown type, never for keys.
Convert your keys to strings up front:
def convert_keys(obj, convert=str):
if isinstance(obj, list):
return [convert_keys(i, convert) for i in obj]
if not isinstance(obj, dict):
return obj
return {convert(k): convert_keys(v, convert) for k, v in obj.items()}
json.dumps(convert_keys(test))
This recursively handles your dictionary keys. Note that I included a hook; you can then choose how to convert enumeration values to strings:
def enum_names(key):
if isinstance(key, TestEnum):
return key.name
return str(key)
json.dumps(convert_keys(test, enum_names))
You can use the same function to reverse the process when loading from JSON:
def names_to_enum(key):
try:
return TestEnum[key]
except KeyError:
return key
convert_keys(json.loads(json_data), names_to_enum)
Demo:
>>> def enum_names(key):
... if isinstance(key, TestEnum):
... return key.name
... return str(key)
...
>>> json_data = json.dumps(convert_keys(test, enum_names))
>>> json_data
'{"one": "This", "two": "should", "three": "work!"}'
>>> def names_to_enum(key):
... try:
... return TestEnum[key]
... except KeyError:
... return key
...
>>> convert_keys(json.loads(json_data), names_to_enum)
{<TestEnum.one: 'first'>: 'This', <TestEnum.two: 'second'>: 'should', <TestEnum.three: 'third'>: 'work!'}