Tornado is a Python web framework that provides a non-blocking web server (I used Tornado on a number of projects in the past that required WebSockets), this snippet provides a template for creating a Tornado application that uses MongoFrames.

There are various ways of creating a Tornado application, we're going to be using an application factory:

# app.py

import argparse
import importlib

from mongoframes import *
from pymongo import MongoClient
from tornado.ioloop import IOLoop
from tornado.web import Application

from handlers import IndexHandler


def create_app(env):
    """
    We use an application factory to allow the app to be configured from the
    command line at start up.
    """

    # Import the settings class
    config = importlib.import_module('settings.' + env).Config
    config.ENV = env

    # Create the app
    app = Application([
            (r'/', IndexHandler),
            # ...other URLs...
        ],
        debug=config.DEBUG
    )

    # Store a reference to the config against the application
    app.config = config

    # Set up mongoframes
    app.mongo = MongoClient(app.config['MONGO_URI'])
    Frame._client = app.mongo
    if app.config.MONGO_PASSWORD:
        Frame.get_db().authenticate(
            app.config.MONGO_USERNAME,
            app.config.MONGO_PASSWORD
            )

    # ...other application set up tasks...

    return app


if __name__ == "__main__":

    # Parse the command-line arguments
    parser = argparse.ArgumentParser(description='Application server')
    parser.add_argument(
        '-e',
        '--env',
        choices=['dev', 'local', 'prod'],
        default='local',
        dest='env',
        required=False
        )
    args = parser.parse_args()

    # Create and run the application
    app = create_app(args.env)
    app.listen(app.config.PORT)
    IOLoop.current().start()

The application code here can be configured to different environments (in this case local, development or production), to start the application in the production environment we'd enter the following at the command line:

$ python app.py --prod

Each environment requires its own settings file which is used to configure the application (including potentially different database credentials), at the same level as the app.py file we create a settings folder and add Python files for each environment (e.g local.py, dev.py, prod.py). Each settings file must define a Config class the attributes of which are used as settings:

# settings/prod.py

class Config:

    # Database
    MONGO_URI = 'mongodb://localhost:27017/mydb'
    MONGO_USERNAME = 'mydb'
    MONGO_PASSWORD = 'password'

    # Debugging
    DEBUG = False

    # Networking
    PORT = 8888
    PREFERRED_URL_SCHEME = 'https'
    SERVER_NAME = 'mywebsite.com'

In my own set up I also create a DefaultConfig class which the other environment Config classes inherit from.

And that's it, you can now use MongoFrames with your Tornado application :)

Keep in mind

Tornado is a non-blocking server that queues requests to be processed, I/O with other applications (such as calling a web API, or querying a database) can be made asynchronous allowing other requests in the queue to be processed while waiting for a response. However in order for I/O not to block, the code communicating with the other application must support asynchronous I/O.

MongoFrames (via PyMongo) communicates synchronously with MongoDB and therefore if you're performing operations that take a long time then MongoFrames might not be the right choice for your Tornado application. You could instead consider using a library such as Motor, a PyMongo-like library that supports asynchronous I/O and works with Tornado.

In my experience database queries are rarely the bottleneck with Tornado and a good rule of thumb is to try to make sure you keep them as fast as possible.