Flask Rest API with MongoDB

I found the great article, How to Build an API with Python and Flask. This post describes how to build REST API using Flask and MySQL. As I’d like to use MongoDB as a database. I’d like to explain how to create REST API using Flask and MongoDB in this post based on How to Build an API with Python and Flask.

1. Set up MongoDB
Please refer http://docs.mongodb.org/manual/installation/.

2. Import data into MongoDB
2.a. Download dataset from Download the raw text file of UFO sightings. This is TSV formated data.
2.b. This TSV file does not have header. So I manually added heder. See below.

$ head sightings.tsv
index	sighted_at	reported_at	location	shape	duration	description	latitude	longitude
0	19951009	19951009	Iowa City, IA			Man repts. witnessing "flash, followed by a classic UFO, w/ a tailfin at back." Red color on top half of tailfin. Became triangular.	41.6611277	-91.5301683

2.c. Also, as mongoimport command does not work well with double-quoted (“) string, I striped double-quotes from file with following command.

cat sightings.tsv | sed 's/"//g' > data.tsv

2.d. Following is command to import TSV formated data into MongoDB.

mongoimport --db ufo --collection ufo --type tsv --file data.tsv

2.e Make sure if data is loaded correctly.

$ mongo ufo
MongoDB shell version: 2.4.3
connecting to: ufo
> db.ufo.count()
60504
>

3. Install PyMongo, which is Python based driver to access MongoDB

$ pip install pymongo

4. Python codes with Flask and PyMongo
4.a Create connection to MongoDB using PyMongo
4.b toJson(data): To generate JSON from MongoDB objects,  use json_util (http://api.mongodb.org/python/1.7/api/pymongo/json_util.html).
4.c sightings(): PyMongo’s find() method returns Cursor (data is not yet loaded). So it is unable to directly serialize to JSON. So, it requires to read data into another object(s)
4.d sighting(sighting_id): To query by _id, use ObjectId. find_one() method returns object (not cursor).

from flask import Flask, request
import json
from bson import json_util
from bson.objectid import ObjectId
from pymongo import Connection

# Flask
app = Flask(__name__)

# MongoDB connection
connection = Connection('localhost', 27017)
db = connection.ufo
def toJson(data):
"""Convert Mongo object(s) to JSON"""
return json.dumps(data, default=json_util.default)

@app.route('/sightings/', methods=['GET'])
def sightings():
  """Return a list of all UFO sightings
  ex) GET /sightings/?limit=10&offset=20
  """
  if request.method == 'GET':
    lim = int(request.args.get('limit', 10))
    off = int(request.args.get('offset', 0))
    results = db['ufo'].find().skip(off).limit(lim)
    json_results = []
    for result in results:
      json_results.append(result)
    return toJson(json_results)

@app.route('/sightings/<sighting_id>', methods=['GET'])
def sighting(sighting_id):
  """Return specific UFO sighting
  ex) GET /sightings/123456
  """
  if request.method == 'GET':
    result = db['ufo'].find_one({'_id': ObjectId(sighting_id)})
    return toJson(result)

if __name__ == '__main__':
  app.run(debug=True)

6. How to test
Start flask dev server

python sightings.py

Test URLs

http://127.0.0.1:5000/sightings/?offset=10&limit=3
http://127.0.0.1:5000/sightings/517d625aee2f8817d3609574

Note: For Geo query with MongoDB, I will post how to do it with MongoDB as soon as I could figure out.

One thought on “Flask Rest API with MongoDB

Leave a comment