主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

Python: 最近のWebフレームワーク

                
 PythonでWebアプリを公開したいとなると、手順がかなり手っ取り早く済むGoogleAppEngine。当初はオリジナルのフレームワークのみで開発だったが、最近はFlask、Django、bottleで開発ができるようになっており選択の幅が広まっている。しかしデータストアはGoogleの提供する独自のものしか使えない。これはこれで結構使えるんだけど、mongoDBに興味が出てきたので使ってみたくて、そのためにはGAEを脱する必要がある。そんなわけでGoogleAppEngineから入門したけど他の環境でのWebアプリ構築も可能になりたいという考えでPythonの代表的なフレームワークをあさってみる。なるべく規模が小さいものがいいのでDjango以外で。
 比較のために"Hello, world"プラスαのコードを各フレームワークで書いてみる。ただ"Hello World"を表示するものならそれぞれのフレームワークの紹介ページに出ている。とくに使われるであろうHTTPリクエストにはGETやPOSTなど数種類のメソッドがあり、それをどう使い分けるのかも知りたい。フォームに名前を入力してポストし、サーバはJSONで入力された名前を返すページも用意する。
14033001.jpg

import webapp2

import json

class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.write('Hello, World!')

class GreetingHandler(webapp2.RequestHandler):
def get(self):
html = """<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
function send()
{
$.post("/g", {name:$("#name_form").val()}, function(data)
{
$("#greeting").prepend("Welcome, " + data["name"] + "<br>");
}, "json");
}
</script>
</head>
<body>
your name:<input id="name_form"/>
<button onclick="send();">greeting</button>
<div id="greeting"></div>
</body>
</html>
"""
self.response.write(html)

def post(self):
name = self.request.get("name")
j = {"name":name}
self.response.headers['Content-Type'] = "application/json"
self.response.write(json.dumps(j))

application = webapp2.WSGIApplication([
('/', MainHandler),
('/g', GreetingHandler),
], debug=True)


 GAEで使われているwebapp2は外でも使えるように公開されている。なかなかコンパクトで使いやすいけど、3.xに対応する前に開発がストップしてしまっている。今後のことを考えると3への対応は欲しいのでwebapp2は切ることにする。ただwebappの書き方に慣れているので、こういうクラスベースで書くwebpyと似たようなフレームワークだとありがたい。


 FacebookでオープンソースにされているTornadoというものがある。webpyやwebapp2に酷似していてとっつきやすいが、ノンブロッキングというめずらしい特徴がとくにデータストアを使う上で独自性を出すことになる。まあそのあたりは別の機会に。
import tornado.ioloop
import tornado.web

import json

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

class GreetingHandler(tornado.web.RequestHandler):
def get(self):
html = """<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
function send()
{
$.post("/g", {name:$("#name_form").val()}, function(data)
{
$("#greeting").prepend("Welcome, " + data["name"] + "<br>");
}, "json");
}
</script>
</head>
<body>
your name:<input id="name_form"/>
<button onclick="send();">greeting</button>
<div id="greeting"></div>
</body>
</html>
"""
self.write(html)

def post(self):
name = self.get_argument("name")
j = {"name":name}
self.write(json.dumps(j))

if __name__ == "__main__":
application = tornado.web.Application([(r"/", MainHandler),
(r"/g", GreetingHandler),
], debug=True)
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()



 続いてFlask。これは現行でかなり人気が高いらしく、高機能ならDjangoで軽さならFlaskだと聞いたような気がする。関数ベースで書くようなのでちょっと不慣れ。だけどその辺は慣れればいいだけのはなしだ。Python 3.xもサポートに入っているし。
from flask import Flask
from flask import request
app = Flask(__name__)

import json

@app.route("/")
def hello():
return "Hello World!"

@app.route('/g', methods=["GET", "POST"])
def greet():
if request.method == "GET":
html = """<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
function send()
{
$.post("/g", {name:$("#name_form").val()}, function(data)
{
$("#greeting").prepend("Welcome, " + data["name"] + "<br>");
}, "json");
}
</script>
</head>
<body>
your name:<input id="name_form"/>
<button onclick="send();">greeting</button>
<div id="greeting"></div>
</body>
</html>
"""
return html

elif request.method == "POST":
name = request.form["name"]
j = {"name":name}
return json.dumps(j)

if __name__ == '__main__':
app.run(debug=True)



 最後にBottle。とりあえずFlaskとあまり変わらないコードになった。こっちも開発が継続中で、Python 3.xにも対応している。
from bottle import route, run, request

import json


@route("/")
def hello():
return "Hello World!"

@route('/g', method=["GET", "POST"])
def greet():
if request.method == "GET":
html = """<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
function send()
{
$.post("/g", {name:$("#name_form").val()}, function(data)
{
$("#greeting").prepend("Welcome, " + data["name"] + "<br>");
}, "json");
}
</script>
</head>
<body>
your name:<input id="name_form"/>
<button onclick="send();">greeting</button>
<div id="greeting"></div>
</body>
</html>
"""
return html

elif request.method == "POST":
name = request.forms.get("name")
j = {"name":name}
return json.dumps(j)

run(host='localhost', port=8888)


Pyramidというのも人気を博してきているが、中規模以上に向いていてちょっと小さくないという印象。

 webpyやwebapp2がPython 3.xに対応していればよかったんだけど、先々のことを考えて他の選択肢を探ろうといくつかWebフレームワークにあたってみた。どれもそれらにそっくりそのままというわけにはいかないけど、それなり共通部分があって難しくなさそう。こういう場合は開発頻度やコミュニティで選べばいいのかな。
スポンサーサイト



プロフィール

h

Author:h

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon