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.