hirokinkoの(胃痛にのた打ち回る)日記 RSSフィード

2010-07-18 先月SmartQ V7を注文したのに音沙汰がない・・・。

Flaskのチュートリアルをやってみた(その1・ステップ0〜ステップ2まで)

| 14:06 | Flaskのチュートリアルをやってみた(その1・ステップ0〜ステップ2まで)のブックマークコメント

PythonのWEBアプリフレームワークのFlaskのチュートリアルをやってみました。

Flaskとは・・・id:mopemopeさんが3ヶ月も前に紹介してる(http://d.hatena.ne.jp/mopemope/20100429/p1)ので細かいことは割愛します。

Rubyistな方にはPython版Sinatraと言えば理解が早いと思います*1


さて、本題。

やったことはhttp://flask.pocoo.org/docs/tutorial/の内容をほぼそのままなぞっただけです。

まぁ、WEBアプリフレームワークのチュートリアルにありがちな「簡単なblogアプリを作ってみて基本を覚えよう!」ですね。


必要なのは

  • Python*2
  • flask(0.5.1)
  • sqlite3

たったこれだけです。


ステップ0 下準備

こんなディレクトリ構成を用意します。

/flaskr
	/static
	/templates

ここで

flaskr ・・・ flaskr(このチュートリアルで作るblogアプリの名前)本体*3

static ・・・ 画像やcssとかの静的ファイルの置き場

templates ・・・ テンプレートファイルの置き場


ステップ1、ステップ2 セットアップとDB周り

SQLファイルを用意します。

ファイル名はschema.sqlとします。

ソースはこんな感じ。

drop table if exists entries;
create table entries (
	id integer primary key autoincrement,
	title string not null,
	text string not null
);

まぁ、キーとなるID、タイトル、本文・・・とやっぱりチュートリアルにありがちな到ってシンプルな構成ですね。


続いてアプリ本体となるflaskr.pyを用意します。

インポート部とコンフィグ部分はこんな感じ。

import sqlite3
from flask import Flask, request, session, g, redirect, url_for, \
		abort, render_template, flash

DATABASE = '/tmp/flaskr.db'		# ここはお好みで場所や名前を変えましょう
DEBUG = True
SECRET_KEY = 'development key'
USERNAME = 'admin'
PASSWORD = 'default'

そしてアプリの初期化はとってもシンプル。

app = Flask(__name__)
app.config.from_object(__name__)

設定ファイルを外にうっちゃりたくなった場合、他に方法は2種類あって、

1つは環境変数に定義してうっちゃるやり方、もう1つはPythonの他モジュールにうっちゃるやり方です。


環境変数にうっちゃる場合はこんな感じで環境変数を用意し

export FLASKR_SETTING=/hoge/foo/bar/settings.ini

fron_envvar()メソッドで初期化します。

app.config.from_envvar('FLASKR_SETTINGS' silent=True)

ここで「silent=True」としている名前付き引数ですが、ここはTrueにすると設定ファイルが見つからない等で設定に失敗しても通知しません。

Falseにすると設定に失敗した時点でエラーを吐いて停止します。


Pythonのソースにうっちゃる場合は

app.config.from_pyfile('hoge.py')

となります。

詳しい事はAPIドキュメントのhttp://flask.pocoo.org/docs/api/#configurationを参照してください。


続いてDBに接続する関数とお約束のmainです。

def connect_db():
	return sqlite3.connect(app.config['DATABASE'])

ここは特に注意することはありませんね。

あ、そうそう設定を使う時は上のようにconfigという辞書に変数名が文字列のキーとして格納されるので辞書として使います。


mainは

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

とやっぱりシンプルですね。

デフォルトのホストやポート番号を変えたい場合は次のようになります。

run(host='127.0.0.1', port=8080)

長くなってきたし、キリもいいのでここで一旦切ります。

Flaskのチュートリアルをやってみた(その2 ステップ3、4)

| 23:54 |  Flaskのチュートリアルをやってみた(その2 ステップ3、4)のブックマークコメント

http://d.hatena.ne.jp/hirokinko/20100718#1279429575の続きです。

ステップ3 DBの構築

ステップ1で作成したSQLを実行するコードを書きます。

SQLite3で実行するなら

sqlite3 /tmp/flaskr.db < schema.sql

こんな感じでしょうか。

flaskrでのサンプルは次のような感じです。


インポートの追加

ここは作者のMitsuhikoさんの環境は2.5系なんでしょうか?

2.6系以降をお使いの場合は__future__モジュールからのインポートは不要です。

from __future__ import with_statement		# Python2.5以前の環境の場合(2.6系以降では不要)
from contextlib import closing

DB初期化関数の追加

下の関数を追加します。

単純にsqliteに接続して、schema.sqlを実行してコミットする、ただそれだけの関数です。

def init_db():
	with closing(connect_db()) as db:
		with app.open_resource('schema.sql') as f:
			db.cursor().executescript(f.read())
		db.commit()

DBの初期化

コンソールでPythonのシェルを立ち上げて次のように実行するだけです。

ハマりどころは特にない・・・はずです。

>>> from flaskr import init_db
>>> init_db()

ステップ4 DBコネクションのリクエスト

Flaskではbefore_request()とafter_request()というデコレータがあり、名前の通りリクエストの処理前、処理後にこれらのデコレータを付加した関数が呼ばれます。

正しいかどうかは何とも言い難いですが、JavaのServletで言うところのフィルタのようなものと考えた方がいいでしょうか。

それぞれ複数あったらどうなるのか、複数あった場合の順番は?などはまだ試していません・・・。

実装は以下です。

@app.before_request
def before_request():
	g.db = connect_db()

@app.after_request
def after_request(response):
	g.db.close()
	return response

見ての通りリクエストの処理前にDBに接続し、処理後にDBの接続をクローズしてレスポンスを返すというシンプルな実装です。

ここで突然出てきた「g」とは何ぞや?とお思いのことでしょう。

この「g」とはグローバルのように使えて、かつリクエストごとに異なる値を返すことを保証する特殊なオブジェクト・・・という解釈で合ってるんでしょうか。

英語力がかなりアレなので正直自信がありません。

詳しい事はこちら(http://flask.pocoo.org/docs/api/#application-globals)を参照してください。


・・・と、その2はこの辺にて。

次からいよいよWEBアプリっぽくなってきます。

が、思いっきり投げやりな内容なのであんまり期待しないでください。

*1:こんな表現すると怒られそうな気もしてますが・・・

*2:とりあえずhirokinkoの環境では2.6.5

*3:こいつはPythonのモジュールではないので__init__.pyは不要

トラックバック - http://d.hatena.ne.jp/hirokinko/20100718