その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 にデプロイします。


