これは、エンジニア未経験のど素人が、終末エンジニアとして
PythonとFlaskでWebアプリを作成するためのメモ記事です。
ランディングページ
Flask
-> [flaskr起動&test編]このページ
[Docker] (http://qiita.com/yuusei/items/51b3917f1ce3f2fbb5e6)
-> Dockerコマンド
Web開発
#起動の手順
setup.py
さて、Flask編 で一通りコードの説明は終わりなんですが、起動までにはまだ長い(ど素人限定かと思いますが・・・)道のりがあります。
flaskr.py や schema.sql 、 layout.html や login.html だけでなく、setup.py というファイルが必要になります。そんな事このflaskのTutorialには書いてない。まだ途中なのか?
setup.pyの中身についてはいちいち書いていてもしょうがないし、このエントリの主眼ではないのでスキップして、とりあえずflaskr以外のアプリも一緒にGitHubのこのページからdownloadします。
ダウンロードしたら、flaskrページにあるREADMEに従って起動します。
~ How I use it?
ここではREADMEの中身についてメモして行きます。
1. edit the configuration
flaskr.py内のconfigを書き換えて、設定を正しくします(ダウンロードした場合はそのままの設定でとりあえず起動できるのでスキップ可能)
2. install the app
Flaskrはパッケージなのでpythonのパッケージ管理システムpipのコマンドオプション “—editable”を使ってローカルパッケージとしてインストールする書式は下記の通り。
pip install --editable [setup.pyの入っているフォルダpath]
3. Instruct flask
正しく使うために、flaskを呼び込んで(読み込んで?)あげる。
export FLASK_APP=flaskr
正直、ここのコマンドが何をしているのかよく分からない・・・。
4. initialize the database
flask initdb
でDBを初期化する(2回目以降必要)
5. now you can run
flask run
で起動する。
起動した先のLocalhost名は http://localhost:5000/ に準じる。
以上です。このあとTerminal上に表示されたURLをブラウザに入力すると、下記の画面が出るので動作できていることがわかります。
初めての起動なので、~Unbelievable. No entries here so far~ と表示されます。これは show.html に記載のあった文章ですね。次は実際に動作するかを確かめて行きたいと思います。
#テストしてみた
作成したアプリの動作確認として、ここでは二つの方法をとります。
- Flask 公式が用意している test_flaskr.py を使用する事による動作確認。
- 自分の手で実際にアプリを使ってみて確認。
見た目にわかりやすいのは後者だと思うので、まずは後者から行きましょう。
アプリを実際に使って動作確認してみた
まず、トップ画面の右上にある log inボタンをクリックして、ログイン画面を起動します。
ここで入力するのは、flaskr.py 内にあるapp.config.updateの中で設定した管理者IDとパスです。
このアプリにはサインイン機能は存在していないため管理者IDとパス以外のものを入力すると、エラーメッセージが出ます。
管理者IDとパスで入ると、log in したとのメッセージとともに、ブログ投稿欄が出てきます。
とりあえず入力してみましょう。
入力した文章はエントリの下に時系列的に出てきます。
一通り入力したところで、一旦 log out します。log out してもさっきまで入力したメッセージはそのまま表示されます。
(注:再度 log in フォームに移ると非表示になりました)
ここで、一旦手元のファイルにどのように反映されているかを探してみました。
flask initdb
でDBを初期化していたのを思い出してください。
つまり、入力した内容はここに格納されているわけです。
“flaskr.db”ファイルを確認したところ、ありました。一部抜粋すると、下記のような形でDBにデータが格納されていました。
これ16進数なんでしょうか?このサイトに突っ込むと 多少意味のある言葉になって帰ってくるので、間違いではないと思うんですが、入力したものがそのまま返ってきてないのが気になる。どうもsqliteの構文が書かれてる感じ・・・ほかのファイルを一通り見てみても、更新日付的にここなんですよね。なので、一旦ここに入っているという事で進めます。
あとでもう一度 initdb すればわかる話。
追記 1) Initdb したところ、上記と全く同じファイルが作成されていました。つまり、ここには書き込んだ内容は保管されてないわけです。(じゃあどこにあるんだ???)
追記 2) 後ほど “Test” “Hello World” だけで再度調査したところ、flaskr.dbから”2354 6573 7448 656c 6c6f 2057 6f72 6c64”を発見しました。ただ、上記の列が記載されている場所よりも大分離れたところに入っていました。ともあれ、ここに格納されているのは確かなので、dbから直接データ取り出したい場合は、pythonのcodecsと何かを組み合わせて、キーワードを検索するモジュールを作るのがいいかもしれません。
ちなみに、Terminalには起動してからのすべての動作が記録されます。
日付、時間、POSTなのかGETなのかまで丸わかり(怖ッ!)
Ctrl + C で離脱すると、サーバーが落とされ、ローカルホストを入力してもブラウザにflaskrは表示されません。
以上です。
test_flaskr.py を使用した動作確認
flaskrにはテスト用のpythonスクリプト “test_flaskr.py” があり、そのコピーライトはArmin Ronacher氏が保持しています。
テストの内容は作りたいアプリケーションによって変わりますが、
flaskr において必要なテストは「ログイン/アウト」のテストと「メッセージ表示」のテストになります。
ログイン/アウトテスト
test_flaskr.py の中に、 test_login_logut() 関数が定義されています。
中身を見ていきましょう。
def login(client, username, password):
return client.post('/login', data=dict(
username=username,
password=password
), follow_redirects=True)def logout(client):
return client.get('/logout', follow_redirects=True)・・・(省略)・・・
def test_login_logout(client):
"""Make sure login and logout works"""
rv = login(client, flaskr.app.config['USERNAME'],
flaskr.app.config['PASSWORD'])
assert b'You were logged in' in rv.data
rv = logout(client)
assert b'You were logged out' in rv.data
rv = login(client, flaskr.app.config['USERNAME'] + 'x',
flaskr.app.config['PASSWORD'])
assert b'Invalid username' in rv.data
rv = login(client, flaskr.app.config['USERNAME'],
flaskr.app.config['PASSWORD'] + 'x')
assert b'Invalid password' in rv.data
前半は login/logutの関数を定義して、後半で実際に”username”と”password”を利用したテストが行われています。
問題なければ “OK” のメッセージがTerminalに出力されます。
メッセージ表示テスト
さっきはlogin 関数のクラスを追加しましたが、
こっちは test_message() 関数を設定するだけです。
def test_messages(client):
"""Test that messages work"""
login(client, flaskr.app.config['USERNAME'],
flaskr.app.config['PASSWORD'])
rv = client.post('/add', data=dict(
title='',
text='HTML allowed here'
), follow_redirects=True)
assert b'No entries here so far' not in rv.data
assert b'<Hello>' in rv.data
assert b'HTML allowed here' in rv.data
ここではタイトルを「Hello」、本文を「HTML allowed here」として、
さっきもあった assert というのはpythonにあるデバッグ用のコードらしいです。例外を故意に発生させる為のものらしいです。
書式は
assert [論理文], “error時の表示条件(オプション)
であり、例えば test_message() の下から二番目の一文では、
「Helloがrv.dataの中にバイナリで格納されているか」をチェックしています。
この二つ以外のテストについては、別途テスト用の関数を書き下す必要があります。
このようにして、テスト関数が用意できたら、実際にテストして見ます。
書いたテストコードを走らせる。
Flaskrの”README”においては、
~ Is it tested?
You betcha. Run `python setup.py test` to see the tests pass.
「テストしましたか?」
「もちろんだよ!”python setup.py” testを走らせて確認したさ!」
とありますので、これを走らせれば大丈夫です。
Terminal上で実際に走らせて見ると、こうなります。
[workingdirectry]$ python setup.py test
running test
running egg_info
writing flaskr.egg-info/PKG-INFO
writing dependency_links to flaskr.egg-info/dependency_links.txt
writing requirements to flaskr.egg-info/requires.txt
writing top-level names to flaskr.egg-info/top_level.txt
reading manifest file 'flaskr.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'flaskr.egg-info/SOURCES.txt'
running build_ext
Ran 0 tests in 0.000s
OK
あれ?テストしてないですね。
なんででしょうか?
続きます。