Sales Lead Tracking with PHP and MongoDB via MongoLab REST API

I'm not exactly a PHP programmer, although back in 2001 I did quite a bit of work with PHP and PostgreSQL for my job. I long ago stopped web programming in PHP and moved to Ruby, then Python and most recently Node.JS/JavaScript. I can't call myself a fan of the PHP language or paradigm either. However, PHP is everywhere and if you need some simple server-side code like a form mailer, it can be a good choice. Despite the disdain for PHP amongst most hackers, it remains extremely simple to deploy. Chances are you can just drop a .php file onto your web host and it will just work.

Why PHP

For my site offering hosting, support and consulting around Strider Continuous Integration & Deployment, I happened to be in just that situation. My web server is already configured for PHP and although I could spend the time to spin up a Python or Node.JS server, it adds needless complexity. All I wanted to do is one simple thing: track new sales leads in a MongoDB collection.

Lovely Free Cloud MongoDB from MongoLab

My web server doesn't run MongoDB, but it doesn't need to. MongoLab have a generous free plan which gives you a cloud-hosted MongoDB instance with up to 500M of storage. That is total overkill for my little sales lead database, and performance is more than adequate. Furthermore they will handle backup/restore and failover etc for me so it's likely a lot more reliable than running my own setup.

MongoDB REST API Benefits

Furthermore, MongoLab offer a HTTP REST API for MongoDB which is very fully-featured. Why would I want to use their REST API instead of a native driver? Well it turns out that my web server doesn't have the PHP MongoDB driver installed. It does however have the cURL library installed. Instead of bothering to figure out how to install the PHP MongoDB driver (which I suspect maybe be non-trivial under OpenBSD) I could just use their REST API.

Writing with MongoLab REST API from PHP

I didn't find much info online about using the REST API from PHP so I thought I'd post my little script here. It is quite straight forward. It simply JSON encodes some fields to produce the document I wish to write to my MongoDB collection. Then it sends a HTTP POST request with the JSON data as the POST body.

Niall O'Higgins is an author and software developer. He wrote the O'Reilly book MongoDB and Python. He also develops Strider Open Source Continuous Deployment and offers full-stack consulting services at FrozenRidge.co.

Read and Post Comments

MongoSF 2011

I was at the MongoSF 2011 conference in May. Very much enjoyed the 1-day conference, made some great connections and the 10gen folks hooked me up with O'Reilly to work on a book "MongoDB and Python", which I hope to have out in a couple of months.

My talk: MongoDB with Python, Pylons, and Pyramid

I was very happy to be invited to speak at MongoSF. My talk covers using Python with MongoDB, goes into a little bit of detail on the Web frameworks Pylons and Pyramid. Watch the video.

Niall O'Higgins is an author and software developer. He wrote the O'Reilly book MongoDB and Python. He also develops Strider Open Source Continuous Deployment and offers full-stack consulting services at FrozenRidge.co.

Read and Post Comments

 

Pylons vs Pyramid

If you weren't already aware of it, the Pylons project has recently sprouted an all-new Python Web framework called Pyramid. Pyramid is kinda like Pylons 2.0 - it is a completely new codebase with no code-level backwards compatibility. It is actually based on repoz.bfg. However, many of the concepts are very similar to the older Pylons 1.x. Pyramid is where all the new development is happening, and it has fantastic code test coverage and documentation.

You can learn more about Pyramid in the Pyramid FAQ.

What Is Akhet

On its own, Pyramid is just a framework - a set of libraries you can use. Projects are most easily started from a template. A number of different templates are included, offering different persistence options, URL mappers and session implementations.

Akhet is a Pyramid project template (AKA scaffold) which tries to give you a more Pylons 1.x-like environment. Personally, I'm much more familiar with Pylons than Pyramid and so Akhet is a great place to start.

It is well worth your while reading the Akhet documentation. However, the subject of this post, working with MongoDB, takes advantage of a few changes I have made myself to my Akhet fork on BitBucket. I am hoping Mike Orr will accept my changes upstream, but for now you will need to build the egg from my sources. I will explain how in the next section.

Starting A Pyramid Project With MongoDB

First you need to create a virtual env for your project. Depending on your platform, you should be able to install the virtualenv tool through a package manager (sudo port install virtualenv-2.7 in Mac Ports, for example).

Install Pyramid

Once you have the virtual env tool installed, create the virtualenv, install Pyramid and its dependencies into it:

$ mkdir ~/projects/ahket-example
$ virtualenv --no-site-packages myenv
$ cd myenv
$ source bin/activate
$ easy_install pyramid

Install Akhet

Now you have Pyramid and all its dependencies installed. However, you still need Akhet and its dependencies like PyMongo etc. We are going to use my fork of Akhet, because it has MongoDB support at the moment.

In a new terminal, type the following (you will need Mercurial installed to fetch the sources from BitBucket):

$ cd ~/projects/akhet-example
$ hg clone https://bitbucket.org/niallohiggins/akhet
$ cd akhet
$ python setup.py sdist

Now you have the Akhet with MongoDB support module available. Install it in your virtual env (go back to original terminal, or re-source ~/projects/akhet-example/myenv/bin/activate):

$ pip install ~/projects/akhet-example/akhet/dist/Akhet-1.0.1.tar.gz

Create Pyramid Project with Akhet and MongoDB Support

Okay, great - you can create your Pyramid project now! We shall call it "mongofu".

$ cd ~/projects/akhet-example
$ paster create -t akhet mongofu
Selected and implied templates:
  Akhet#akhet  A Pylons-like Pyramid project

Enter project name: mongofu
Variables:
  egg:      mongofu
  package:  mongofu
  project:  mongofu
Enter sqlalchemy (Include SQLAlchemy configuration? (y/n)) [True]: n
Enter mongodb (Include MongoDB configuration? (y/n)) [False]: y

Install Akhet Dependencies

You are just about ready to go. You need to make sure your virtual environment has all the dependencies needed by your mongofu project (e.g. the PyMongo driver). To do so run the following:

$ cd mongofu ; python setup.py develop

Assuming all went well, you should now have a directory called "mongofu" with a whole bunch of stuff in it. The default configuration files tell Pyramid to connect to a MongoDB server on localhost, and a database called mydb. If you need to change that, simply edit the mongodb.url and mongodb.db_name settings in the INI-files.

Start The Development Server

Now try starting up a development server:

$ paster serve development.ini
If things are working correctly, you should see a message like this on your terminal:
Starting server in PID 6020.
serving on http://127.0.0.1:5000

Talking to MongoDB with Pyramid/Akhet

Now you are ready to write some MongoDB queries! Edit the file mongofu/handlers/main.py.
In the Main class, we can add a simple query to the "index" action method, referencing the request.db property - which is a handle to our MongoDB database:

class Main(base.Handler):
    @action(renderer="index.html")
    def index(self):
        # Do some logging.
        log.debug("testing logging; entered Main.index()")
        # MongoDB Query
        # can just as easily write request.db.mycollection.find()
        records = request.db['mycollection'].find()
        # Push a flash message if query param 'flash' is non-empty.
        if self.request.params.get("flash"):
            import random
            num = random.randint(0, 999999)
            message = "Random number of the day is:  %s." % num
            self.request.session.flash(message)
            # Normally you'd redirect at this point but we have nothing to
            # redirect to.
        # Return a dict of template variables for the renderer.
        return {"project":"mongofu"}

As you can see, we specify a collection in that database to query against. We're not doing anything with the results, but that is enough to demonstrate how to talk to MongoDB with Pyramid and Akhet.

Niall O'Higgins is an author and software developer. He wrote the O'Reilly book MongoDB and Python. He also develops Strider Open Source Continuous Deployment and offers full-stack consulting services at FrozenRidge.co.

Read and Post Comments

MongoDB + Pylons at PyCon 2011

March 18, 2011 at 05:04 PM | categories: Python, MongoDB, Cloud | View Comments |

PyCon 2011

I was at the awesome PyCon 2011 last week, where I had a fantastic time. Really great conference - tons of incredible talks and wonderful conversation. Definitely the best technical conference I've attended. Everyone I met was super friendly, down-to-earth and just all-around fun.

Had the pleasure to hang out with the Pylons/Pyramid crew who are a great bunch. I will certainly be going in 2012, when the event is scheduled to be held in Santa Clara. Plan to stay for the sprints next time!

My talk: MongoDB + Pylons at Catch.com

I was very happy to be able to present a talk on some of my work at Catch.com, where I designed and implemented the platform backend using Pylons and MongoDB. The video of my talk is embedded below:

Niall O'Higgins is an author and software developer. He wrote the O'Reilly book MongoDB and Python. He also develops Strider Open Source Continuous Deployment and offers full-stack consulting services at FrozenRidge.co.

Read and Post Comments