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.