Sleepy.Mongoose: A MongoDB HTTP Interface

The first half of the MongoDB book is due this week, so I wrote a REST interface for Mongo (I’m a prolific procrastinator).  Anyway, it’s called Sleepy.Mongoose and it’s available at

Installing Sleepy.Mongoose

  1. Install MongoDB.
  2. Install the Python driver:
    $ easy_install pymongo
  3. Download Sleepy.Mongoose.
  4. From the mongoose directory, run:
    $ python

You’ll see something that looks like:

|      MongoDB REST Server      |

listening for connections on http://localhost:27080

Using Sleepy.Mongoose

First, we’re just going to ping Sleepy.Mongoose to make sure it’s awake. You can use curl:

$ curl 'http://localhost:27080/_hello'

and it’ll send back a Star Wars quote.

To really use the interface, we need to connect to a database server. To do this, we post our database server address to the URI “/_connect” (all actions start with an underscore):

$ curl --data server=localhost:27017 'http://localhost:27080/_connect'

This connects to the database running at localhost:27017.

Now let’s insert something into a collection.

$ curl --data 'docs=[{"x":1}]' 'http://localhost:27080/foo/bar/_insert'

This will insert the document {“x” : 1} into the foo database’s bar collection. If we open up the JavaScript shell (mongo), we can see the document we just added:

> use foo
{ "_id" : ObjectId("4b7edc9a1d41c8137e000000"), "x" : 1 }

But why bother opening the shell when we can query with curl?

$ curl -X GET 'http://localhost:27080/foo/bar/_find'
{"ok": 1, "results": [{"x": 1, "_id": {"$oid": "4b7edc9a1d41c8137e000000"}}], "id": 0}

Note that queries are GET requests, whereas the other requests up to this point have been posts (well, the _hello can be either).

A query returns three fields:

  • “ok”, which will be 1 if the query succeeded, 0 otherwise
  • “results” which is an array of documents from the db
  • “id” which is an identifier for that particular query

In this case “id” is irrelevant as we only have one document in the collection but if we had a bunch, we could use the id to get more results (_find only returns the first 15 matching documents by default, although it’s configurable). This will probably be clearer with an example, so let’s add some more documents to see how this works:

$ curl --data 'docs=[{"x":2},{"x":3}]' 'http://localhost:27080/foo/bar/_insert'
{"ok" : 1}

Now we have three documents. Let’s do a query and ask for it to return one result at a time:

$ curl -X GET 'http://localhost:27080/foo/bar/_find?batch_size=1'
{"ok": 1, "results": [{"x": 1, "_id": {"$oid": "4b7edc9a1d41c8137e000000"}}], "id": 1}

The only difference between this query and the one above is the “?batch_size=1” which means “send one document back.” Notice that the cursor id is 1 now, too (not 0). To get the next result, we can do:

$ curl -X GET 'http://localhost:27080/foo/bar/_more?id=1&batch_size=1'
{"ok": 1, "results": [{"x": 2, "_id": {"$oid": "4b7ee0731d41c8137e000001"}}], "id": 1}
$ curl -X GET 'http://localhost:27080/foo/bar/_more?id=1&batch_size=1'
{"ok": 1, "results": [{"x": 3, "_id": {"$oid": "4b7ee0731d41c8137e000002"}}], "id": 1}

Now let’s remove a document:

$ curl --data 'criteria={"x":2}' 'http://localhost:27080/foo/bar/_remove'
{"ok" : 1}

Now if we do a _find, it only returns two documents:

$ curl -X GET 'http://localhost:27080/foo/bar/_find'
{"ok": 1, "results": [{"x": 1, "_id": {"$oid": "4b7edc9a1d41c8137e000000"}}, {"x": 3, "_id": {"$oid": "4b7ee0731d41c8137e000002"}}], "id": 2}

And finally, updates:

$ curl --data 'criteria={"x":1}&newobj={"$inc":{"x":1}}' 'http://localhost:27080/foo/bar/_update'

Let’s do a _find to see the updated object, this time using criteria: {“x”:2}. To put this in a URL, we need to escape the ‘{‘ and ‘}’ characters. You can do this by copy-pasting it into any javascript interpreter (Rhino, Spidermonkey, mongo, Firebug, Chome’s dev tools) as follows:

> escape('{"x":2}')

And now we can use that in our URL:

$ curl -X GET 'http://localhost:27080/foo/bar/_find?criteria=%7B%22x%22%3A2%7D'
{"ok": 1, "results": [{"x": 2, "_id": {"$oid": "4b7edc9a1d41c8137e000000"}}], "id": 0}

If you’re looking to go beyond the basic CRUD, there’s more documentation in the wiki.

This code is super-alpha. Comments, questions, suggestions, patches, and forks are all welcome.

Note: Sleepy.Mongoose is an offshoot of something I’m actually supposed to be working on: a JavaScript API we’re going to use to make an awesome sharding tool.  Administrating your cluster will be a point-and-click interface.  You’ll be able to see how everything is doing, drag n’ drop chunks, visually split collections… it’s going to be so cool.

  • kristina1

    Yeah, probably. It’s not really a REST interface, it’s just an HTTP interface.

  • kajal

    can I insert a json file into mongoDb collection using this REST API?

  • kristina1

    Yes, as either blobs or structured data.

  • antonimmo

    I solved the CORS problem by editing “”, replacing

    response_headers = []
    response_headers = [[‘Access-Control-Allow-Origin’,’*’]]

  • Antonio Quintana

    Hey, hi!

    Do you know how to enable gzip compression if requested by the client?

  • kristina1

    It looks like there is no trivial way (, but if you’d like to implement one of the options listed in that thread, I’d be happy to merge in the patch.

  • sowjanya

    Hi kristina,
    I am unable to run 4th step python command it shownig error like this ImportError: No module named bson.son

  • kristina1

    Have you installed pymongo?

  • Wojciech Bogucki

    Great Toturial, I was playing around with few MongoDB HTTP/REST Interfacases and this is the one which I was abe to configure quite fast

  • Wojciech Bogucki

    Guys I cannot insert data into the database, its showing the error couldnt parse json

  • kristina1

    Python is very picky about JSON formatting. Make sure thinks it’s valid.

  • Amir Mursal

    How to combine two collections in Sleepy Mongoose?

  • kristina1

    You cannot do a join using MongoDB, regardless of driver. See

  • Amir Mursal

    How we will achieve MAP REDUCE in sleepy.mongoose?

  • Mathumitha


    I get couldnt parse json error when inserting data. I tested the json with the link you had given and it says valid. I am using the below curl in windows command prompt
    curl –data docs={“x”:”1″} http://localhost:27080/test/firstCollection/_insert

  • Mathumitha

    Hi Kristina,

    I face 2 issues with sleepy mongoose.

    1. I have downloaded sleepy mongoose and i am able to do a get request but when i try to insert data i face issue
    ‘couldn’t parse json’. I use the below curl command
    curl –data docs=[{“x”:1}] http://localhost:27080/test/first/_insert

    I also tried using the rest client in mozila firefox but did not get any response. In the logs i found a not indexable error.

    2. I have enabled authentication for mongodb. How can the credentials be passed for a find or insert.

    Can you please suggest a solution


  • Mathumitha

    Hi Kristina,

    I see a curl command for authenticate. Is there any way in sleepy mongoose to close an existing connection after querying

    Thank you

  • kristina1

    You can call to de-authenticate. I don’t think there’s an explicit disconnect command.

  • Mathumitha

    Thanks Kristina.
    Is there any url or http call to logout similar to _authenticate?

  • kristina1
  • Mathumitha

    For any post using curl and windows, i get json cannot be parsed error. I tried
    curl –data “cmd={logout : 1}” http://localhost:27080/test/_cmd
    curl –data ‘docs=[{“x”:1}]’ “http://localhost:27080/test/firstCollection/_insert”

  • Mathumitha

    Thanks Kristina. With your suggestion i am able to achieve a solution.

  • Usman Pervaiz

    Hey Kristina , when i run this command

    curl –data server=localhost:27017 ‘http://localhost:27080/_connect’
    on terminal and browse http://localhost:27080/_connect then it’ll send back a errmsg

    {“ok” : 0, “errmsg” : “_connect must be a POST request”} how to fix it ??

  • kristina1

    When you say “browse http://localhost:27080/_connect“, do you mean in a browser? If so, that’s your problem, you can’t do a POST request by typing a URL in the address bar of your browser. You can from the command line (as you wrote above) or by using an HTTP library in whatever language you’re comfortable with.

  • Guest

    Thank you for replying, Actualy i want to access database of EDX via browser so when i do this in browser is displays a message like ”
    It looks like you are trying to access MongoDB over HTTP on the native driver port.” That’s why i use sleepy mongoose so that i may be able to access database though browser like phpmyadmin . If you can help me with this i will be very thankful to you .. 🙂

  • Usman Pervaiz

    Thank you for reply, Actualy i want to access database of EDX via
    browser so when i do this in browser it displays a
    message like ”
    It looks like you are trying to access MongoDB over
    HTTP on the native driver port.” That’s why i use sleepy mongoose so
    that i may be able to access database though browser like phpmyadmin .
    If you can help me with this i will be very thankful to you .. 🙂

  • kristina1

    Neither PyMongo nor Sleepy.Mongoose are similar to phpmyadmin, and _cannot_ be used through the browser the way you’re attempting. lists a ton of phpmyadmin-like programs. Please ask on!forum/mongodb-user if you have any questions about using these tools.

  • Usman Pervaiz

    Thank You. 🙂

  • c24b

    Nice work. Just a detail in Pymongo, Connection could not be imported anymore. So to make will work if you first import MongoClient in
    ”’ from pymongo import MongoClient”’
    and then l.57
    replace Connection() by MongoClient()
    connection = MongoClient(uri, network_timeout = 2)
    except (ConnectionFailure, ConfigurationError):
    return None

  • Amir Mursal

    Hi kristina,, I am stuck at this point

    Traceback (most recent call last): File “”, line 17, in from handlers import MongoHandler File “/home/ubuntu/sleepy.mongoose-master/sleepymongoose/”, line 15, in from bson.son import SON ImportError: No module named bson.son

  • kristina1

    Please follow the instructions at and contact!forum/mongodb-user if you have any issues.

  • Julian

    Sleepy.Mongoose script is not ready for python33 , you need to use python27

  • Mario Camara

    In fact, also the network_timeout must be left out:

    connection = MongoClient(uri)

    There are different timeouts that could configured according to

  • Abdul Ashu

    hi, I am unable to get results for keywords containing chinese characters or non english characters. I am adding my search query in the url of sleepy mongoose and send the request. But I am unable to get results. Can any one help me what should I do.

  • Mahib

    Hi Kristina,

    I’ve got the same problem. “_connect must be a POST request”. But I’m trying a post request with jquery. The following are my codes. Where am I doing wrong?

    var mongooesLocation2 = “http://localhost:27080/_connect”;
    var dbServerAddress = {
    server: “localhost:27017”,
    login: “”,
    password: “”

    type: “POST”,
    url: mongooesLocation2,
    beforeSend: function(xhr) {
    xhr.setRequestHeader(“Authorization”, “Basic”);

    data: dbServerAddress,
    contentType: “application/json; charset=utf-8”,
    dataType: “jsonp”,
    error: function(msg) {},
    success: function(response) {

  • Flap

    I’m writing this here for future wonderers. It took me some time to figure how to make the UPSERT work :

    url –data ‘criteria={“x”:1}&newobj={“$inc”:{“x”:1}}&upsert=true’ ‘http://localhost:27080/foo/bar/_update’

kristina chodorow's blog