TypeError: ObjectId('') is not JSON serializable TypeError: ObjectId('') is not JSON serializable flask flask

TypeError: ObjectId('') is not JSON serializable


Pymongo provides json_util - you can use that one instead to handle BSON types

def parse_json(data):    return json.loads(json_util.dumps(data))


You should define you own JSONEncoder and using it:

import jsonfrom bson import ObjectIdclass JSONEncoder(json.JSONEncoder):    def default(self, o):        if isinstance(o, ObjectId):            return str(o)        return json.JSONEncoder.default(self, o)JSONEncoder().encode(analytics)

It's also possible to use it in the following way.

json.encode(analytics, cls=JSONEncoder)


>>> from bson import Binary, Code>>> from bson.json_util import dumps>>> dumps([{'foo': [1, 2]},...        {'bar': {'hello': 'world'}},...        {'code': Code("function x() { return 1; }")},...        {'bin': Binary("")}])'[{"foo": [1, 2]}, {"bar": {"hello": "world"}}, {"code": {"$code": "function x() { return 1; }", "$scope": {}}}, {"bin": {"$binary": "AQIDBA==", "$type": "00"}}]'

Actual example from json_util.

Unlike Flask's jsonify, "dumps" will return a string, so it cannot be used as a 1:1 replacement of Flask's jsonify.

But this question shows that we can serialize using json_util.dumps(), convert back to dict using json.loads() and finally call Flask's jsonify on it.

Example (derived from previous question's answer):

from bson import json_util, ObjectIdimport json#Lets create some dummy document to prove it will workpage = {'foo': ObjectId(), 'bar': [ObjectId(), ObjectId()]}#Dump loaded BSON to valid JSON string and reload it as dictpage_sanitized = json.loads(json_util.dumps(page))return page_sanitized

This solution will convert ObjectId and others (ie Binary, Code, etc) to a string equivalent such as "$oid."

JSON output would look like this:

{  "_id": {    "$oid": "abc123"  }}