0

I have a flask-restful project that interfaces with some custom classes, containing uuid (uuid.UUID) types used as ids. There are a couple of api endpoints which return the object associated with the given id, parsed by flask as an UUID. The issue is that, when I return them as a json payload, I get the following exception:

UUID('…') is not JSON serializable

I want to have those uuids represented as strings to the final user, making the process seamless (the user can take the returned uuid and use it for his next api request).

HitLuca
  • 1,040
  • 9
  • 33

1 Answers1

1

In order to fix this problem, I had to put together suggestions from two different places:

first, I need to create a custom json encoder, which when dealing with uuids, returns their string representation. StackOverflow answer here

import json
from uuid import UUID


class UUIDEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, UUID):
            # if the obj is uuid, we simply return the value of uuid
            return str(obj) # <- notice I'm not returning obj.hex as the original answer
        return json.JSONEncoder.default(self, obj)

second, I need to take this new encoder and set it as the flask-restful encoder used for the responses. GitHub answer here

class MyConfig(object):
    RESTFUL_JSON = {'cls': MyCustomEncoder}

app = Flask(__name__)
app.config.from_object(MyConfig)
api = Api(app)

putting it together:

# ?: custom json encoder to be able to fix the UUID('…') is not JSON serializable
class UUIDEncoder(json.JSONEncoder):
    def default(self, obj: Any) -> Any:  # pylint:disable=arguments-differ
        if isinstance(obj, UUID):
            return str(obj) # <- notice I'm not returning obj.hex as the original answer
        return json.JSONEncoder.default(self, obj)


# ?: api configuration to switch the json encoder
class MyConfig(object):
    RESTFUL_JSON = {"cls": UUIDEncoder}


app = Flask(__name__)
app.config.from_object(MyConfig)
api = Api(app)

on a side note, if you are using vanilla flask, the process is simpler, just set your app json encoder directly (app.json_encoder = UUIDEncoder)

I hope it's useful to someone!

HitLuca
  • 1,040
  • 9
  • 33