Tornadoとはじめてふれあう

そいえばブラウザを介したWebSocketでの通信ってあまりやってなかったなーと思って、いろいろ調べてるうちにTornadoがよさそうだなと思って、まずはHello Worldからやりました。

Tornadoとは

ここによると、

Apache Licence 2.0に基づくオープンソースのノンブロッキングなWebサーバ&Webフレームワーク

  • ノンブロッキングI/O
  • リアルタイム性
  • シンプルなテンプレート
  • シングルスレッド、シングルプロセス

だそうです。

先程も書きましたが、ノンブロッキングI/Oな感じならばWebSocketにも向いてるんじゃないか?と考え、Tornadoを選んでいます。

インストール

$ pip install tornado

Hello World

# -*- 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(8000)
    tornado.ioloop.IOLoop.instance().start()

そしてhttp://localhost:8000/にアクセスします。

f:id:naari_3:20161204230226p:plain

ハンドラーを継承して書いていくからか、きれいなコードにまとまりました。多分大規模な開発に向いてるんだろうなと思います。flaskやbottleとの違いですね

テンプレートにレンダリング

この前触り始めたばかりですが、僕はPugが好きです。閉じ忘れが無くなったり、見やすくなったりでいいことが多かったです。

なので、テンプレートにはPugを使おうと思います。

pypugjsを使う

$ pip install pypugjs

github.com

PythonでPugをレンダリングするライブラリです。

PyPugJS is a high performance port of PugJS for python, that converts any .pug source to the each Template-language (Django, Jinja2, Mako or Tornado).

さまざまなPythonのWebフレームワークに対応しているようです。

Append this after importing tornado.template

from tornado import template
from pypugjs.ext.tornado import patch_tornado
patch_tornado()

とても手軽にPugを使う準備が出来ました。

実際に使う

書いてみると、こんな感じになりました。

# -*- coding: utf-8 -*-
import os
import time

from pypugjs.ext.tornado import patch_tornado

import tornado.ioloop
import tornado.web

from tornado import template

patch_tornado()


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("index.pug", nowtime=time.time())


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(8000)
    tornado.ioloop.IOLoop.instance().start()
// templates/index.pug
doctype html
html(lang="ja")
  head
    meta(charset="utf-8")
    style(src="{{ static_url('css/style.css') }}")
    title render test
  body
    h1.sitettl Hello World 2
    main.main
      h2.content_ttl あ
      span {{ nowtime }}

{{}} で囲んだ変数名の部分に埋め込まれます。

{{ static_url('file/to/path') }} で静的なファイルの場所を示すことが出来ます。

f:id:naari_3:20161205003928p:plain

まとまった感じがして好印象が持てました。

おわりに

flaskやbottleと違い、ハンドラーを継承して書いていくので、大きなものを作るとしたらとても作りやすそうです。

今回のソースコードはこちらに置いてあります。↓

github.com

次の記事ではTornadoを使い、WebSocketで通信する予定です。

naari.hatenablog.com