Tornadoとは?
TornadoはPythonで書かれた強力かつ拡張可能なWebサーバーです。高トラフィック環境でも効率的に動作し、軽量な設計により様々なアプリケーションやツールに利用されています。
Tornadoは元々FriendFeedによって開発され、その後Facebookによる買収後にオープンソース化されました。このフレームワークはC10K問題に対応するために設計されており、高いパフォーマンスを提供します。さらに、セキュリティ、ユーザー認証、ソーシャルネットワーク機能、外部サービスとの非同期通信などのツールも備えています。
C10K問題とは?
従来のスレッドベースのサーバー(例: Apache)では、大規模な負荷がかかるとメモリリソースを迅速に枯渇させることがあります。これに対して、Tornadoのような非同期サーバーは、コラボレーション型のマルチタスク方式を採用し、よりスムーズに拡張できます。
# サンプルコード
def 非同期処理():
# リクエスト待機中
pass
def コールバック():
# 応答受信後の処理
pass
# Tornadoでの非同期処理の例
tornado.ioloop.IOLoop.current().add_callback(非同期処理)
初期設定
**1. Tornadoのインストール**
pip install tornado
# ソースからのインストール
# https://pypi.python.org/packages/source/t/tornado/tornado-4.3.tar.gz
**2. 最初のTornadoプログラム**
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import tornado.ioloop
import tornado.web
class HelloHandler(tornado.web.RequestHandler):
def get(self):
self.write("こんにちは、世界!")
app = tornado.web.Application([
(r"/hello", HelloHandler),
])
if __name__ == "__main__":
app.listen(9000)
tornado.ioloop.IOLoop.instance().start()
テンプレートエンジン
TornadoのテンプレートエンジンはDjangoに似ており、制御文や式をサポートしています。以下は簡単な例です:
# テンプレートファイル example.html
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ message }}</h1>
</body>
</html>
# Pythonコード
class ExampleHandler(tornado.web.RequestHandler):
def get(self):
self.render('example.html', title='タイトル', message='メッセージ内容')
静的ファイルの管理
静的ファイル(CSS、JavaScriptなど)を扱うには、以下のように設定します:
settings = {
'static_path': os.path.join(os.path.dirname(__file__), 'static'),
}
application = tornado.web.Application([
(r"/static/(.*)", tornado.web.StaticFileHandler, {"path": settings['static_path']}),
], **settings)
if __name__ == "__main__":
application.listen(9000)
tornado.ioloop.IOLoop.instance().start()
CSRF対策
TornadoでCSRF攻撃を防ぐためには、以下の設定を行います:
settings = {
"xsrf_cookies": True,
}
セッション管理
Tornadoにはデフォルトでセッション管理機能はありませんが、以下のようにカスタム実装が可能です:
import uuid
import json
class SessionManager:
session_store = {}
@staticmethod
def create_session(request_handler):
session_id = str(uuid.uuid4())
request_handler.set_secure_cookie('session_id', session_id)
SessionManager.session_store[session_id] = {}
return session_id
@staticmethod
def get_session(request_handler):
session_id = request_handler.get_secure_cookie('session_id')
if not session_id:
return None
return SessionManager.session_store.get(session_id.decode(), {})
@staticmethod
def set_session_value(request_handler, key, value):
session_id = request_handler.get_secure_cookie('session_id')
if session_id:
SessionManager.session_store[session_id.decode()][key] = value