Editor’s note: We found an interesting series of articlesLearn 30 New Technologies in 30 Days, is being translated, an update a day, year-end gift package. Here’s day 23.


Today’sLearn 30 New Technologies in 30 DaysI decided to put away my JavaScripts for a while and learn a new one calledTornadoWeb framework. The reason I decided to learn Tornado was so I could write Web applications in Python. I just learnedFlask framework, so I think Tornado would add to my knowledge of Python Web development. The application we describe in this blog post uses Tornado as the REST backend,MongoDBAs a database,AngularJSAs the client side of the JavaScripts MVC Framework, thenOpenShiftAs a platform for deployment.

What is Tornado?

Tornado is an open source Python Web framework, which is a non-blocking Web server originally developed on FriendFeed. After the acquisition of FriendFeed, Facebook maintained and continued to grow Tornado. Due to its non-blocking network I/O nature, it is highly scalable and can support more than a thousand connections at a time.

The application case

In this blog post, we will be developing a social bookmarking application that allows users to post and share links. You can see the actual program running on OpenShift here. This is the application we developed on Day 22, so refer to that blog post to better understand this application example.

Making the warehouse

The code for today’s demo application is available on GitHub: day25-tornado-demo-app.

preparation

Before we can start Tornado, we need to install Python and VirtualEnv on the machine. For this post, I’m using version 2.7 of Python

This application uses MongoDB as the data storage software, so please download the latest MongoDB distribution for your operating system.

Development of Tornado MongoDB applications

We will use PIP to install Tornado. For those of you who are not familiar with PIP, PIP is a Python package manager. We can install PIP from the official website. Open the terminal, go to any convenient directory on the file system, and run the following command:

$mkdir getbookmarks $CD getbookmarks $virtualenv venv --python=python2.7 $. Venv /bin/activate $PIP install tornado $ pip install pymongo

The above command creates a GetBookmarks directory on your machine, then activates VirtualEnv under Python 2.7, then installs the Tornado package, and finally installs PyMongo. Among them, PyMongo is the official MongoDB Python driver; We will use this to write stories into MongoDB.

In the getbookmarks directory, create a file called getbookmarks.py:

$ touch getbookmarks.py

Copy the following code and paste it into the getBookmarks.py source file:

import os from tornado import ioloop,web from pymongo import MongoClient import json from bson import json_util from bson.objectid import ObjectId class IndexHandler(web.RequestHandler): def get(self): self.write("Hello World!!" ) settings = { "template_path": os.path.join(os.path.dirname(__file__), "templates"), "static_path": os.path.join(os.path.dirname(__file__), "static"), "debug" : True } application = web.Application([ (r'/', IndexHandler), (r'/index', IndexHandler), ],**settings) if __name__ == "__main__": application.listen(8888) ioloop.IOLoop.instance().start()

The above code does the following: 1. We start by importing the required library; 2. Next, we define a new class that extends the Web.RequestHandler class: IndexHandler. A Tornado Web application will correspond to URLs or URL patterns to subclasses of Web.RequestHandler. These classes define methods such as get(), post(), and so on to handle HTTP GET or POST requests to the URL. When a GET request is received at the address ‘/’, the IndexHandler returns a “Hello World!!” 3. Then we defined some Settings for the application. The TEMPLATE_PATH setting tells Tornado applications to look for application templates in the template directory. The static_path setting tells the application to use static files such as CSS, images, and JavaScript files in the static directory. By setting debug to True, you will automatically reload the project after you have made changes to it without having to reboot to see how it looks. We keep the debugger running in the background during application development. This provides an efficient development environment. 4. Next, we create a Tornado application instance, passing in the Routes and Settings. 5. Finally, we use the Python getbookmarks.py command to start the server to run the application

Open the http://localhost:8888 and http://localhost:8888/index to see if see “Hello World!!!!!”

Configuration mongo

After importing the library, add the following statement:

MONGODB_DB_URL = os.environ.get('OPENSHIFT_MONGODB_DB_URL') if os.environ.get('OPENSHIFT_MONGODB_DB_URL') else 'mongodb://localhost:27017/'
MONGODB_DB_NAME = os.environ.get('OPENSHIFT_APP_NAME') if os.environ.get('OPENSHIFT_APP_NAME') else 'getbookmarks'

client = MongoClient(MONGODB_DB_URL)
db = client[MONGODB_DB_NAME]

We define the route and the name of the database for the MongoDB connection. If the application is deployed to OpenShift, the OpenShift-specific environment variables will be used first; if not, the configuration on the machine will be used.

We create an instance of MongoClient and pass in the connection route. This connection route is a mongod instance that only wants to run. We then use the MongoClient instance to work with the database

Create and list all Stories

Now we’ll add the ability to create new stories and list all stories. Let’s start by adding routing to the following application example:

application = web.Application([
    (r'/', IndexHandler),
    (r'/index', IndexHandler),
    (r'/api/v1/stories',StoriesHandler),
],**settings)

Next, we define a StoriesHandler that saves stories in MongoDB and finds all stories in it:

class StoriesHandler(web.RequestHandler):
    def get(self):
        stories = db.stories.find()
        self.set_header("Content-Type", "application/json")
        self.write(json.dumps(list(stories),default=json_util.default))


    def post(self):
        story_data = json.loads(self.request.body)
        story_id = db.stories.insert(story_data)
        print('story created with id ' + str(story_id))
        self.set_header("Content-Type", "application/json")
        self.set_status(201)

1. When a user makes a GET request to/API /v1/stories, we make a Find() request to MongoDB. Since we didn’t specifically declare it to be any query, it pulls all the stories from MongoDB. We set the content type to application/json and dump the JSON response. 2. When the user sends a POST request to/API /v1/stories, we first decode the JSON content into a dictionary and write the data to MongoDB. We will set the Response Status to 201 (created).

View individual stories

As a final back-end function to view individual stories, we first specify the route:

application = web.Application([
    (r'/', IndexHandler),
    (r'/index', IndexHandler),
    (r'/api/v1/stories',StoriesHandler),
    (r'/api/v1/stories/(.*)', StoryHandler)
],**settings)

So let’s write our StoryHandler

class StoryHandler(web.RequestHandler):
    def get(self , story_id):
        story = db.stories.find_one({"_id":ObjectId(str(story_id))})
        self.set_header("Content-Type", "application/json")
        self.write(json.dumps((story),default=json_util.default))

The above code looks for the story that corresponds to story_id and rolls out the JSON response.

AngualarJS front-end

I decided to reuse the front end I wrote on day 22. Day 22 showed you how to use AngularJS with the Java Spring framework as the back end. The great thing about using the MVC architecture with JavaScripts is that you can reuse the front-end code if your application conforms to the requirements of the REST client interface. You can read more about Day 22.

You can download the AngularJS front end from my GiHub repository. Copy the static file and the template folder and paste it into the folder where getbookmarks.py is located.

Deploy the application to OpenShift

Before we can build the application, we need to make some Settings:

  1. Sign up for an OpenShift account. Registration is completely free, and Red Hat gives each user three free Gear sets that you can use to run your app. At the time of this writing, each user gets a total of 1.5 GB of RAM and 3 GB of hard disk space for free.

  2. Install the RHC client tool. RHC is a Ruby gem, so you need Ruby 1.8.7 or higher on your machine. Simply type sudo gem install RHC to install RHC. If you’ve already installed it, make sure it’s the latest version. Run sudo gem update RHC to upgrade. Detailed information on configuring RHC command-line tool, please refer to: https://openshift.redhat.com/community/developers/rhc-client-tools-install

  3. Use RHC’s setup command to configure your OpenShift account. This command will help you create a namespace and upload your SSH public key to the OpenShift server.

The deployment of application

To deploy the application to OpenShift, enter the following command:

$RHC create - app day25demo python 2.7 mongo - 2 - from - code https://github.com/shekhargulati/day25-tornado-demo-app.git

This command will create the application, set up the public DNS, create a private Git repository, and deploy the application using the code in your GitHub repository. The application can be accessed through http://day25demo-shekhargulati.rhcloud.com/#/.

That’s all for today. Feedback is welcome.


Day 25: Tornado–Combining Tornado, MongoDB, and AngularJS to Build an App to translate SegmentFault