TypeError: ObjectId('') is not JSON serializable

My response back from MongoDB after querying an aggregated function on document using Python, It returns valid response and i can print it but can not return it.

Error:

    TypeError: ObjectId('51948e86c25f4b1d1c0d303c') is not JSON serializable

Print:

    {'result': [{'_id': ObjectId('51948e86c25f4b1d1c0d303c'), 'api_calls_with_key': 4, 'api_calls_per_day': 0.375, 'api_calls_total': 6, 'api_calls_without_key': 2}], 'ok': 1.0}

But When i try to return:

    TypeError: ObjectId('51948e86c25f4b1d1c0d303c') is not JSON serializable

It is RESTfull call:

    @appv1.route('/v1/analytics')
    def get_api_analytics():
        # get handle to collections in MongoDB
        statistics = sldb.statistics

        objectid = ObjectId("51948e86c25f4b1d1c0d303c")

        analytics = statistics.aggregate([
        {'$match': {'owner': objectid}},
        {'$project': {'owner': "$owner",
        'api_calls_with_key': {'$cond': [{'$eq': ["$apikey", None]}, 0, 1]},
        'api_calls_without_key': {'$cond': [{'$ne': ["$apikey", None]}, 0, 1]}
        }},
        {'$group': {'_id': "$owner",
        'api_calls_with_key': {'$sum': "$api_calls_with_key"},
        'api_calls_without_key': {'$sum': "$api_calls_without_key"}
        }},
        {'$project': {'api_calls_with_key': "$api_calls_with_key",
        'api_calls_without_key': "$api_calls_without_key",
        'api_calls_total': {'$add': ["$api_calls_with_key", "$api_calls_without_key"]},
        'api_calls_per_day': {'$divide': [{'$add': ["$api_calls_with_key", "$api_calls_without_key"]}, {'$dayOfMonth': datetime.now()}]},
        }}
        ])


        print(analytics)

        return analytics

db is well connected and collection is there too and I got back valid expected result but when i try to return it gives me Json error. Any idea how to convert the response back into JOSON. Thanks

You should define you own JSONEncoder and using it:

    import json
    from bson import ObjectId

    class 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: stackoverflow.com/q/16586180