admiralobvious admiralobvious - 4 years ago 210
JSON Question

Getting 'TypeError: ObjectId('') is not JSON serializable' when using Flask 0.10.1

I forked the Flask example, Minitwit, to work with MongoDB and it was working fine on Flask 0.9, but after upgrading to 0.10.1 I get the error in title when I login when I try to set the session id.

It seems there was changes in Flask 0.10.1 related to json.

Code snippet:

user = db.minitwit.user.find_one({'username': request.form['username']})
session['_id'] = user['_id']

Full code in my github repo.

Basically, I set the Flask session id to the user's _id from MongoDB.

I tried the first two solution from this SO question without success.

Well, doing session['_id'] = str(user['_id']) gets rid of the error message and I'm properly redirected to the timeline page but I am not actually logged in.

How can I fix this?

EDIT: Copy/paste of the traceback:

Thank you.

Answer Source

EDIT: Even easier fix. You don't even need to do any JSON encoding/decoding.

Just save the session['_id'] as a string:

user = db.minitwit.user.find_one({'username': request.form['username']})
session['_id'] = str(user['_id'])

And then everywhere you want to do something with the session['_id'] you have to wrap it with ObjectId() so it's passed as a ObjectId object to MongoDB.

if '_id' in session:
    g.user = db.minitwit.user.find_one({'_id': session['_id']})


if '_id' in session:
    g.user = db.minitwit.user.find_one({'_id': ObjectId(session['_id'])})

You can see the full diff for the fix on my github repo.

If anyone cares to know why the 'TypeError: ObjectId('') is not JSON serializable' "issue" appeared in Flask 0.10.1, it's because they changed the way sessions are stored. They are now stored as JSON so since the '_id' object in MongoDB isn't standard JSON, it failed to serialize the session token, thus giving the TypeError. Read about the change here:

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download