その4 からの続きです。テストプログラムを用意します、Flask の簡単な使い方もメモしておきます。
環境設定
まず testapp
というフォルダを作成し、そこにアプリ開発用の仮想環境を作成しておきます。仮想環境が何かは別途ググって下さい。 python3 -m venv [仮想環境名]
で作成可能です。ここでは .venv
としておきます。.
を付けると隠しファイル/フォルダ扱いになります。
$ mkdir testapp
$ cd testapp
$ python3 -m venv .venv
VScode を使っているなら、その仮想環境を使うかどうか質問され、次回以降も自動的に選んでくれます。手動で仮想環境を有効化するなら
$ source .venv/bin/activate
です。コンソールに (.venv)
の表示が出ると思います。また、作ったばかりの仮想環境にはまだ Flask がインストールされていないので、これもインストールしておきます。
$ pip install flask
以下のように画像などの固定ファイルを格納する static
フォルダと、ページ表示用の html ファイルを格納する templates
フォルダ、さらにメインプログラムの app.py
を作ります。これがFlaskの基本構成になります。
testapp/
├ .venv/
├ static/
├ templates/
└ app.py
まだプログラムは書きません、先にウェブページ構成を考えます。とりあえず簡単なものとして、「トップページ」と「フォーム入力ページ」があり、その切替 & フォーム送信をすることを考えます。Flask は他のフレームワークや PHP での include
同様に、レイアウトのテンプレートを用意して使い回せるので、それを layout.html
として用意し、さらに個別ページの内容ファイルも作ります。具体的には以下のようになります。
testapp/
├ .venv/
├ static/
├ templates/
│ ├ layout.html
│ ├ top.html
│ └ form.html
└ app.py
html ファイル作成
ファイルの中身を書いていきます。まずはページ切替用のリンクを持つレイアウトです。{% block ブロックの名前 %}
{% endblock %}
で囲んだ範囲に、他のファイルを埋め込めます。
<!DOCTYPE html>
<html>
<head>
<title>Test Page</title>
</head>
<body>
<ol>
<li><a href="/">トップページ</a></li>
<li><a href="/form">フォームページ</a></li>
</ol>
{% block content %}
<!-- 他のhtmlファイルをここに表示 -->
{% endblock %}
</body>
</html>
レイアウト内に埋め込まれるトップページのコンテンツです。{% extends ファイル名 %}
でどのファイルに埋め込むか指定します。
{% extends "layout.html" %}
{% block content %}
<h4>トップページです</h4>
{% endblock %}
レイアウト内に埋め込まれるフォームページのコンテンツです。フォーム送信したら、下に表示されるようにします。Flask の用いている jinja2 というレンダリングエンジンでは {% if 条件 %}
, {% endif %}
の中に条件分岐処理を書きます。
{{ 変数名 }}
で Flask から受け取った変数をそのまま html 内に表示できます。
{% extends "layout.html" %}
{% block content %}
<h4>入力フォーム</h4>
<form action="/form" method="POST">
<input type="text" name="input_text">
</form>
{% if result %} <!-- result という変数がある時 = POST後のサーバーからのレスポンス -->
<h4>送信内容</h4>
<p>{{ result }}</p> <!-- 変数 result を表示 -->
{% endif %}
{% endblock %}
python ファイル作成
続いてメインプログラムを用意します。細かい説明は省きますが、デコレータ @app.route('<URL>', methods=['GET','POST'])
を関数の前につけ、return render_template(表示するhtmlファイル名)
とすることで、URLと表示ファイルの紐付け (ルーティング) が可能になります。この時、変数を同時に渡し、その値を html 内に埋め込むことが可能になります。単に return 変数
とした場合は、html ファイルの表示はされず、返したその値がそのURLに何の飾りもなく表示されるだけになります。
import random
from flask import Flask, request, render_template
app = Flask(__name__) # flask インスタンス作成
# URLルーティング : トップページ
@app.route('/', methods=['GET', 'POST'])
def toppage():
return render_template('top.html') # top.html の内容をレンダリング
# URLルーティング : フォームページ
@app.route('/form', methods=['GET', 'POST'])
def formpage():
if request.method == 'GET': # GET ならそのままページ表示
return render_template('form.html')
elif request.method == 'POST': # POST ならフォーム送信内容を返す
input_text = request.form['input_text'] # フォーム中の input_text の値を取得
return render_template('form.html', result=input_text) # form.html のレンダリング & 変数 input_text を result という名で渡す
if __name__ == "__main__":
# ポート番号は自由
# debug=True だと、ファイル更新時に自動でリロードする
app.run(host="0.0.0.0", port=80, debug=True)
とりあえずこの状態で立ち上げてみます。
$ python app.py
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
こんな感じで立ち上がれば成功です。ブラウザに http://0.0.0.0:80/
, 0.0.0.0
localhost
などと入力すればページが表示されるはずです。
ここでポート番号を port=80
にしておきましたが、Apache などのローカルサーバーが立ち上がっている場合、このポートは既に使われている可能性があります。その際は適当に port=5000
などに変えて実行して下さい。
アプリの挙動
こんな感じで、送信内容をそのままおうむ返しするだけのアプリが完成しました。
その6 でこれを EC2 にデプロイします。