PythonのWebフレームワークTornadoを使ってみる その1

# はじめに

最近[Tornado](http://www.tornadoweb.org/en/stable/)で遊んでいるので、その使い方をまとます。

今回は、ほぼ公式Topの焼き直しです。次回に期待してください。なお、質問や要望があればお答えします。

## 実行環境

私の実行環境は以下の通りですが、Pythonが動作する環境なら問題ないと思います。

* CentOS release 6.5 (Final)
* Python 2.6.6

## 関連記事
* [PythonのWebフレームワークTornadoを使ってみる その2](http://qiita.com/intermezzo-fr/items/cea126c0a6e9e879f216)


# Tornadoとは
[Tornado](http://www.tornadoweb.org/en/stable/index.html)とは、Pythonで書かれたWebフレームワーク/非同期通信ライブラリであり以下の特徴があります。

* FriendFeedにより開発（現在はFacebook）
* OpenSource(Apache 2.0)
* Python2系, Python3系, PyPyで動作
* シングルプロセス、シングルスレッド
* シンプル
* シンプルだから高速
* シンプルだからスケーラブル（らしい）
* テンプレートエンジンが同梱されている
* 後発なので、いい所どりができる

以後、インストールからHello, worldまでを扱います。

# Tornadoのインストール
Tornadoのインストールはpipで行います。

```bash
$ pip install tornado
```

なお、pipを導入してない方は以下のサイトを参考に導入するとよいでしょう。

* [そこはかとなく書くよん。 \- pipの使い方 (2014/1バージョン)](http://tdoc.info/blog/2014/01/15/pip.html)

pipなんて使いたくないよという場合は、tar.gzを落としてきて、いつも通り、setup.pyを使いましょう。

```bash
tar xvzf tornado-3.2.2.tar.gz
cd tornado-3.2.2
python setup.py build
sudo python setup.py install
```


# Hello, world
インストールしてしまえば、あとはimportして適当なコードを書いて、listenするだけです。
ここでは、最も簡単な例として、ブラウザに"Hello, world"という文字列を表示してみます。
Hello, worldを表示するには、以下のコードを適当なディレクトリで適当な名前（ここではserver.py）を付けて保存して実行します。

## ソースコード

```py:server.py
#!/bin/env python
# -*- coding: utf-8 -*-
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
```

## 起動
pythonにスクリプトを与えてやるだけです。

```bash
$ python server.py
```

ターミナルには何も表示されませんが、この状態でブラウザでアクセスすれば、"Hello, world"が表示されます。

## 閲覧
![helloworld.png](https://qiita-image-store.s3.amazonaws.com/0/37377/d9d9fd0b-beb9-ffa6-52a7-3b9a0eeec3cb.png)

# もう少しだけ遊んでみる
文字列を表示するだけではつまらないので、せめてhtmlファイルを返すところまでやってみます。
スタイルシートとHTMLファイルを用意し、server.pyを以下のように書き換えます。
ここまでの知識で、適当にスタイル付けされた静的なページを返す大昔のWebサイトは構築できるはずです。


## ディレクトリ構成
staticディレクトリにstyle.cssを、templatesディレクトリにindex.htmlを用意します。

```bash
$ tree --charset=x
.
|-- server.py
|-- static
|   `-- style.css
`-- templates
    `-- index.html
```

## ソースコード
server.pyの主な変更点は以下の通りです。

* Python2系でも3系でも動くように、"from \__future__ import print_function"をimport
* パスを扱うため"os"をインポート
* writeメソッドの代わりに、renderメソッドを使う
* templatesとstaticディレクトリを追加（意味は次回）
* せっかくなので、serverが起動したことを標準出力に表示

```py:server.py
#!/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import os
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("index.html")

application = tornado.web.Application([
    (r"/", MainHandler)
    ],
    template_path=os.path.join(os.getcwd(),  "templates"),
    static_path=os.path.join(os.getcwd(),  "static"),
)

if __name__ == "__main__":
    application.listen(8888)
    print("Server is up ...")
    tornado.ioloop.IOLoop.instance().start()

```

```css:style.css
body {
  font-family:'Lucida Grande', 'Hiragino Kaku Gothic ProN', 'ヒラギノ角ゴ ProN W3', "ＭＳ Ｐゴシック", sans-serif;
  width: 80%;
  margin: 0 auto;
}
p {
  color:#BEAF71;
  font-size:200%;
}
```

```jinja:index.html
<!DOCTYPE html>
<html>
  <head>
    <title>Hello, world</title>
    <link rel="stylesheet" href="{{ static_url("style.css") }}"/>
  </head>
  <body>
    <div id="container">
      <div id="main">
        <p>Hello, world</p>
      </div>
    </div>
  </body>
</html>
```

## 起動

```bash
$ python server.py
print("Server is up ...")
```

## 閲覧
確かにHTMLが返ってきていることがわかります。

![helloworld.png](https://qiita-image-store.s3.amazonaws.com/0/37377/dfaa3b9b-c10d-572b-68d8-cc64ce1350ea.png)
![helloworld.png](https://qiita-image-store.s3.amazonaws.com/0/37377/b66627e3-3fdd-53b5-0b23-95959928fd54.png)