Flask メモ
Flask を実際触ってみたメモを残す
Python の情報
Python 自体の情報について Python 3.6.4
を今回使った。
Install Flask
インストールメモ
$ pip install Flask $ pip show Flask
上記コマンドで Flask
をインストールして、インストールされたことを確認する。
2018-09-24 現在 Flask
のバージョンは、 1.0.2
が最新であった。
最新にするには、下記コマンドで出来る。
$ pip install -U Flask
Make Script
スクリプトを実際につくってみる
アプリケーション用のディレクトリを作る
$ mkdir flask $ cd flask
動作確認も含めた最初のスクリプトを作る
ファイル名: app.py
# coding: utf-8 from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): return 'hello, world!'
ちなみに、 app = Flask(__name__)
について。
__name__
はアプリケーションを直接実行したばいい、 __main__
が入る。
インポートした Flask
に対し、引数として __main__
をつけて app
というインスタンスを作成する。
というのがこの一文のはず。 その後は、作成した app
というインスタンスに対して動作を定義していく。
ちなみに、モジュールとして他のアプリケーションから呼ばれて動作するか、スクリプトとして実行されているかで、 __name__
の中身が変わります。
(だから何を気をつければよいかはパッと出てこない。ごめんなさい)
実行する
$ export FLASK_APP=app.py $ flask run * Serving Flask app "app.py" * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Warning 出ているけど、仮想環境を作っていないからだと思われる。(個人的には仮想環境的を作るより、 Vagrant や Cloud 環境を使って試したほうが良いと考えている)
動作確認
ブラウザを開いて、 http://localhost:5000/
にリクエストを投げる。
hello, world!
と出力されたらOK
もしくは、
$ curl -sSv http://localhost:5000/ * Hostname was NOT found in DNS cache * Trying 127.0.0.1... * Connected to localhost (127.0.0.1) port 5000 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.35.0 > Host: localhost:5000 > Accept: */* > * HTTP 1.0, assume close after body < HTTP/1.0 200 OK < Content-Type: text/html; charset=utf-8 < Content-Length: 13 < Server: Werkzeug/0.14.1 Python/3.6.4 < Date: Mon, 24 Sep 2018 08:02:55 GMT < * Closing connection 0 hello, world!$
のように、コマンドで確認しても良い。
上記の場合、 localhost:5000
に対して GET
リクエストを出しているのがわかる。
Responce で HTTP/1.0 200 OK
となっていることから、リクエストが正常にレスポンスされていることがわかる。
Closing connection 0
のあとで、
hello, world!
が出力されていることがわかる。 !
の後ろに改行コードを入れていないことから、レスポンス文字列は改行されず、プロンプトの $
が出力されていることがわかる。
Deep dive a bit
ちょっとだけ深く潜ってみる。
app.py
# coding: utf-8 from flask import Flask, render_template app = Flask(__name__) @app.route("/") def hello_world(): return 'hello, world!' @app.route("/about") def about(): return "<h1>About: </h1>" @app.route("/hello1/<whom>") def hello1(whom): return "Hello {}\n".format(whom) @app.route("/hello2/<whom>") def hello2(whom): return render_template("hello.html", whom=whom) @app.route("/100_plus/<int:n>") def adder(n): return "100+{}={}".format(n, 100+n)
上記スクリプトでは、テンプレートから参照できるようにもしている。
テンプレートもこのタイミングで作ってみる。
$ mkdir templates
テンプレートの html ファイルを作成する。
hello.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Hello</title> </head> <body> <h1>Using Jinja2 Template engine</h1> <h2>Hello {{whom}}<h2> </body> </html>
上記テンプレートは、 def hello2(whom):
内で呼ばれる。
動作確認
$ curl -sSv http://localhost:5000/about * Hostname was NOT found in DNS cache * Trying 127.0.0.1... * Connected to localhost (127.0.0.1) port 5000 (#0) > GET /about HTTP/1.1 > User-Agent: curl/7.35.0 > Host: localhost:5000 > Accept: */* > * HTTP 1.0, assume close after body < HTTP/1.0 200 OK < Content-Type: text/html; charset=utf-8 < Content-Length: 16 < Server: Werkzeug/0.14.1 Python/3.6.4 < Date: Mon, 24 Sep 2018 08:17:30 GMT < * Closing connection 0 <h1>About: </h1>$
ヘッダとして About:
文字列が表示されている
$ curl -sSv http://localhost:5000/hello1/someone * Hostname was NOT found in DNS cache * Trying 127.0.0.1... * Connected to localhost (127.0.0.1) port 5000 (#0) > GET /hello1/someone HTTP/1.1 > User-Agent: curl/7.35.0 > Host: localhost:5000 > Accept: */* > * HTTP 1.0, assume close after body < HTTP/1.0 200 OK < Content-Type: text/html; charset=utf-8 < Content-Length: 14 < Server: Werkzeug/0.14.1 Python/3.6.4 < Date: Mon, 24 Sep 2018 08:19:13 GMT < Hello someone * Closing connection 0 $
Hello の後に、 URL の文字列で渡した、 someone
が反映されているのがわかる。
$ curl -sSv http://localhost:5000/hello2/somebody * Hostname was NOT found in DNS cache * Trying 127.0.0.1... * Connected to localhost (127.0.0.1) port 5000 (#0) > GET /hello2/somebody HTTP/1.1 > User-Agent: curl/7.35.0 > Host: localhost:5000 > Accept: */* > * HTTP 1.0, assume close after body < HTTP/1.0 200 OK < Content-Type: text/html; charset=utf-8 < Content-Length: 183 < Server: Werkzeug/0.14.1 Python/3.6.4 < Date: Mon, 24 Sep 2018 08:21:15 GMT < <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Hello</title> </head> <body> <h1>Using Jinja2 Template engine</h1> <h2>Hello somebody<h2> </body> * Closing connection 0 </html>$
テンプレートを使ってレンダリングしていることがわかる。また、 {{whom}}
の内容が、 URL で渡された文字列になっていることがわかる。
- URL の文字列を
@app.route("/hello2/<whom>)
の<whom>
で受け取る def hello2(whom):
でwhom
に値を渡すrender_template("hello.html", whom=whom)
で、テンプレートhello.html
を利用し、且つテンプレート内のwhom
変数に対し、whom
の変数に入っている値を渡してあげた上で、レンダリングしていることがわかる
$ curl -sSv http://localhost:5000/100_plus/100 * Hostname was NOT found in DNS cache * Trying 127.0.0.1... * Connected to localhost (127.0.0.1) port 5000 (#0) > GET /100_plus/100 HTTP/1.1 > User-Agent: curl/7.35.0 > Host: localhost:5000 > Accept: */* > * HTTP 1.0, assume close after body < HTTP/1.0 200 OK < Content-Type: text/html; charset=utf-8 < Content-Length: 11 < Server: Werkzeug/0.14.1 Python/3.6.4 < Date: Mon, 24 Sep 2018 08:28:53 GMT < * Closing connection 0 100+100=200$
100100
という文字列結合ではなく、 200
という計算結果になっていることから、与えられた値が int
型として与えられていることがわかる。
では、文字列を渡してみる。
$ curl -sSv http://localhost:5000/100_plus/foo * Hostname was NOT found in DNS cache * Trying 127.0.0.1... * Connected to localhost (127.0.0.1) port 5000 (#0) > GET /100_plus/foo HTTP/1.1 > User-Agent: curl/7.35.0 > Host: localhost:5000 > Accept: */* > * HTTP 1.0, assume close after body < HTTP/1.0 404 NOT FOUND < Content-Type: text/html < Content-Length: 233 < Server: Werkzeug/0.14.1 Python/3.6.4 < Date: Mon, 24 Sep 2018 08:31:37 GMT < <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>404 Not Found</title> <h1>Not Found</h1> <p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p> * Closing connection 0
404 エラーになった。
int
型になりうる値以外は例外を出すという処理に対して期待どおりに動くことがわかった。
バリデーションに使えそう。
ちなみにこれらのひととおりの app.py
側のログは以下のように出力された。
127.0.0.1 - - [24/Sep/2018 17:17:03] "GET /about HTTP/1.1" 200 - 127.0.0.1 - - [24/Sep/2018 17:17:17] "GET /about HTTP/1.1" 200 - 127.0.0.1 - - [24/Sep/2018 17:17:30] "GET /about HTTP/1.1" 200 - 127.0.0.1 - - [24/Sep/2018 17:19:13] "GET /hello1/someone HTTP/1.1" 200 - 127.0.0.1 - - [24/Sep/2018 17:21:15] "GET /hello2/somebody HTTP/1.1" 200 - 127.0.0.1 - - [24/Sep/2018 17:28:53] "GET /100_plus/100 HTTP/1.1" 200 - 127.0.0.1 - - [24/Sep/2018 17:31:37] "GET /100_plus/foo HTTP/1.1" 404 -
出来れば日時表記は ISO 規格に合わせたいところである。
以上、やってみたログでした。