I'm having some trouble with Mongodb and Python (Flask).
I have this api.py file, and I want all requests and responses to be in JSON, so I implement as such.
#
# Imports
#
from datetime import datetime
from flask import Flask
from flask import g
from flask import jsonify
from flask import json
from flask import request
from flask import url_for
from flask import redirect
from flask import render_template
from flask import make_response
import pymongo
from pymongo import Connection
from bson import BSON
from bson import json_util
#
# App Create
#
app = Flask(__name__)
app.config.from_object(__name__)
#
# Database
#
# connect
connection = Connection()
db = connection['storage']
units = db['storage']
#
# Request Mixins
#
@app.before_request
def before_request():
#before
return
@app.teardown_request
def teardown_request(exception):
#after
return
#
# Functions
#
def isInt(n):
try:
num = int(n)
return True
except ValueError:
return False
def isFloat(n):
try:
num = float(n)
return True
except ValueError:
return False
def jd(obj):
return json.dumps(obj, default=json_util.default)
def jl(obj):
return json.loads(obj, object_hook=json_util.object_hook)
#
# Response
#
def response(data={}, code=200):
resp = {
"code" : code,
"data" : data
}
response = make_response(jd(resp))
response.headers['Status Code'] = resp['code']
response.headers['Content-Type'] = "application/json"
return response
#
# REST API calls
#
# index
@app.route('/')
def index():
return response()
# search
@app.route('/search', methods=['POST'])
def search():
return response()
# add
@app.route('/add', methods=['POST'])
def add():
unit = request.json
_id = units.save(unit)
return response(_id)
# get
@app.route('/show', methods=['GET'])
def show():
import pdb; pdb.set_trace();
return response(db.units.find())
#
# Error handing
#
@app.errorhandler(404)
def page_not_found(error):
return response({},404)
#
# Run it!
#
if __name__ == '__main__':
app.debug = True
app.run()
The problem here is json encoding data coming to and from mongo. It seems I've been able to "hack" the add route by passing the request.json as the dictionary for save, so thats good... the problem is /show. This code does not work... When I do some logging I get
TypeError: <pymongo.cursor.Cursor object at 0x109bda150> is not JSON serializable
Any ideas? I also welcome any suggestions on the rest of the code, but the JSON is killing me.
Thanks in advance!
While @ErenGüven shows you a nice manual approach to solving this json serializing issue, pymongo comes with a utility to accomplish this for you. I use this in my own django mongodb project:
import json
from bson import json_util
json_docs = []
for doc in cursor:
json_doc = json.dumps(doc, default=json_util.default)
json_docs.append(json_doc)
Or simply:
json_docs = [json.dumps(doc, default=json_util.default) for doc in cursor]
And to get them back from json again:
docs = [json.loads(j_doc, object_hook=json_util.object_hook) for j_doc in json_docs]
The helper utilities tell json
how to handle the custom mongodb objects.