【Python】Flaskとは?FlaskでWeb開発の基礎を学ぼう!

Flaskとは

Flask(フラスコ/フラスク)とは、PythonのWebアプリケーションフレームワークで、小規模向けの簡単なWebアプリケーションを作るのに適しています。
Webフレームワークとは、ウェブサイトやウェブアプリケーションを作るための機能を提供し、ウェブフレームワークを使わない時よりもより容易にWebアプリケーションを作ることができるものです。
ちなみに、PythonにはいくつものWebアプリケーションフレームワークがあり、例えば、Djnago(ジャンゴ)pyramidbottleなど他にもありますが、この章では、学習コストの低いFlaskを扱って行きます。また近年では、Gradio(グラディオ)と呼ばれる機械学習モデルのデモを行うWebアプリケーションを簡単に作ることができるライブラリも人気です。Flaskの基本を学んだ後に、Gradioも利用してみてください。

関連記事:Gradioとは? Pythonで機械学習Webアプリケーションをサクッと作ろう!

Flaskのインストール

pip install flask

Mac OSの方は、ターミナルを起動し、Windowsの方はコマンドプロンプト(cmd)を起動し、上記のpipコマンドにてflaskをインストールしてください。
インストールが終えたら、実際にインストールが成功したか確認します。

確認のため、Pythonの対話型シェルを起動します。
起動するには、pythonコマンドを入力&実行することで、Pythonの対話型シェル(インタラクティブシェル)に切り替えます。
それでは、以下のコードを実行してみましょう。

python

Pythonの対話型シェル(インタラクティブシェル)で入力&実行する部分は>>>の後からです。
次の>>>部分は入力してなくて大丈夫です。

>>> import flask
>>> flask.__version__
'0.12'

バージョンが表示されればインストール成功です。
ターミナルやコマンドプロンプトは一旦閉じて終了してください。
※ターミナルやコマンドプロンプトを終了する場合は、そのまま閉じるか、exit()コマンドを用いることでも終了可能です。
※表示されるバージョンはインストールした時期によってテキストと異なる場合がございます。

Flaskを動かしてみる

実際にFlask(フラスク)を動かしていきましょう。
下のプログラムをflask_sample.pyという名前でDesktop(デスクトップ)に保存してください。

from flask import Flask
app = Flask(__name__, static_folder='.', static_url_path='')
@app.route('/')
def index():
    return app.send_static_file('index.html')

app.run(port=8000, debug=True)

※Windows OSをご利用の方で、上記コードがエラーとなる場合、
port番号の部分、debugの部分を次のようにしてみてください。

app.run(port=12345, debug=False)

次に、index.htmlファイルを作ります。
拡張子はHTMLファイルですので、「.html」になります。
この際、index.htmlを保存するディレクトリはflask_sample.pyと同じ階層であることに注意してください。
HTMLに関しては、ドットインストールのHTMLなどを利用し予習してみてください。

<!DOCTYPE html>
<html lang="ja">
<head>
    <title>初めてのFlaskアプリケーション</title>
</head>
<body>
<p>Flask</p>
</body>
</html>

では、ターミナルまたはコマンドプロンプト上で、flask_sample.pyのあるディレクトリまでcdコマンドを用いて移動してみましょう。
*この時、先ほどFlaskのバージョンを表示しているターミナルやコマンドプロンプトは一旦閉じて、再度ターミナルもしくはコマンドプロンプトを起動し、cdコマンドにより移動してください。

移動方法は、cdコマンドを利用します。
Macの方は、ターミナル、Windowsの方はコマンドプロンプト(cmd)を起動します。

cd ~/Desktop

で移動出来ます。
上記コマンドは、Desktopに保存したflask_sample.pyがある想定です。

では、移動出来ましたら次のコマンドでflask_sample.pyを実行しましょう。

python flask_sample.py

ターミナルもしくはコマンドプロンプトに、様々な出力があり、サーバーが起動した状態になります。
localhost:8000にアクセスし、上記の画面が表示されればOKです。

次に、hello関数を実装してみましょう。
*Windowsユーザーの方で、app.run()の引数に、port番号を指定した場合、(例えば、app.run(port=12345, debug=False)など)『localhost:数字』の数字の部分を指定したport番号に変えて実行し直してみてください。

以下のコードをapp.run(port=8000, debug=True)の上に追加します。
この時一番最後の行のapp.run(port=8000, debug=True)の上に記述してください。

@app.route('/hello/<name>')
def hello(name):
    return name

上記コードはブラウザのURLにてlocalhost:8000/hello/python
と入力し、ブラウザにアクセスすると、次のように画面に表示されます。
(*上記リンクを飛ぶと環境によっては、真っ白いページになる場合がありますので、その場合リロード(再読み込み)してみてください。)

@app.routeの関数内の<・・・>の部分に任意の名前(ここでは)を記述することで、その名称を次の関数(ここではhello関数)にてroute内の<・・・>で記述した値を引数として利用することが可能になります。
今回は’/hello/’としましたが、<・・・>の・・・の部分は自由な名称をつけることが可能です。

次にルーティングの説明です。
ルーティングとは、URLとFlaskの処理を対応づけることで、URLと関数を紐付けることが出来ます。
Flaskでルーティングを記述するには、route()を用います。
flask_sample.pyの全体像は次のようになります。

import os
from flask import Flask, url_for

app = Flask(__name__)

# ルーティング
@app.route("/hello")
def hello_world():
    return "Hello world"

@app.route("/")
def index():
    return url_for("show_user_profile", username="ai_academy")

@app.route("/user/<username>")
def show_user_profile(username):
    return "UserName: " + str(username)

@app.route("/post/<int:post_id>")
def show_post(post_id):
    return "Post" + str(post_id)


if __name__ == "__main__":
    app.run(port=8000, debug=True)

プログラムの解説を致します。
まずは、何もrouting設定しなかった場合、show_user_profile()という16行目で定義した関数が走ります。
引数では、username=”ai_academy”が渡され、表示は以下のようになります。
http://127.0.0.1:8000/

次に以下のURLにアクセスしてください。
http://127.0.0.1:8000/user/AI
ここでURLの中にある、AIの部分を変えて挙動を確認してください。

次に、 http://127.0.0.1:8000/hello では、Hello World!が出力されるのをみてください。

次に、型を指定したURL参照をしてみましょう。数値123を他の値に変えることで参考にできます。
URLは http://127.0.0.1:8000/post/123 をみてください。

flask側で型を固定してあるので、違う型のものを入れるとエラーが出るかと思います。
URLは http://127.0.0.1:8000/post/test をみてください。

サーバ側のプログラムをPython(Flask)で記述することで、動的な処理ができるようになります。
なお、「動的な動き」という表現はよく聞きますが、対照的なものとして、「静的な動き」という表現があります。
例えばhtmlファイル(index.html等)は静的なファイルですので、記述されたことが表示されるだけで、動的な動きはしません。
こちらに何かしらの値を、サーバー側から出力させたいときに動的な動きをさせる必要があります。

https://aiacademy.jp/bootcamp/

This image has an empty alt attribute; its file name is bootcamp_ad_72ppi-1024x341.png

render_templateによる読み込み

Flaskでは、render_template関数を使う方法でも、htmlファイルを表示させ、htmlファイルに簡単に値を入れることができます。
render_templateを使う場合には、importによる記述と、templatesフォルダを新たに作成しそこにhtmlファイルを置きます。
render_templateを用いる際には、templatesフォルダを作成する必要があり、作成していないとhtmlファイルを読み込むことが出来ませんのでご注意ください。

まずは、階層を以下のように作ってください。

- app.py(flaskでサーバー処理を行うpythonファイル)
- templates(HTMLファイルが沢山入るフォルダ)
    └ index.html
    └form.html

app.pyを以下の内容を記述し、保存してください。

from flask import Flask,render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html', message="花子さん")

if __name__ == "__main__":
    app.run(port=8000, debug=True)

※Windows OSをご利用の方で、上記コードがエラーとなる場合、
port番号の部分、debugの部分を次のようにしてみてください。

app.run(port=12345, debug=False)

また、Jupyter Notebookを用いてFlaskを動作させる場合、
合わせて、if name == “main“:の部分をコメントアウトし次のようにしてみてください。

from flask import Flask,render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html', message="花子さん")

app.run(port=12345, debug=Falase)

続いて、templatesフォルダ内にindex.htmlを作成して以下コードを記述し、保存してください。

<!DOCTYPE html>
<html>
<head>
  <title>flask練習</title>
</head>
<body>
  <h1>こんにちは{{ message }}</h1>
</body>
</html>

では、再度ファイルの構成を確認してみましょう。
上記で作成したコードは次のようになっていますでしょうか?

- app.py(flaskでサーバー処理を行うpythonファイル)
- templates(HTMLファイルが沢山入るフォルダ)
    └ index.html

上記の構成であれば、app.pyを起動し動作確認してみましょう。

Mac OSの方は、ターミナルを起動し、Windowsの方はコマンドプロンプト(cmd)を起動し、以下のコマンドを実行してみましょう。

python app.py

その後、ターミナル(もしくはコマンドプロンプト)の方に、次のようなログが出力されていれば、OKです。

 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:8000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 284-231-902

http://127.0.0.1:8000/にアクセスしてみると、以下のように出力がされるはずです。

このように簡単に静的ファイル(htmlファイルで作成したページのこと)にサーバー側から値を出力することに成功しました。

htmlで入力されたデータをpythonで扱う

例えば、以下のようなログイン画面を見たことはないでしょうか?

こういったログイン機能では、LoginID(もしくはユーザー名など)とPasswordの正しい値を入力すると、次の画面に遷移し、正しくない入力をすると、「正しく入力をしてください」などと表示されます。
実現方法としては、HTML上に入力された値をサーバーサイドにPOSTで送ることによって、その値がデータベースのものと正しいかどうか参照することによって、機能は実装できます。
POSTとは、HTTP通信の、データを送る際の手段の一つです。
HTTP通信については深くはここでは触れませんので、詳しくは、こちらをご覧ください。

では、どのようにデータをflask側に送れば良いのでしょうか?
データを送る際には、formタグの中にinputタグを入れればOKです。実際にコードを見てみましょう。

<!DOCTYPE html>
<html>
<head>
  <title>form練習</title>
</head>
<body>
  <form method="POST">
    <input type="text" name="id" placeholder="userID">
    <input type="password" name="pwd" placeholder="Password">
    <input type="submit" value="送信">
  </form>
</body>
</html>

このファイルをform.htmlなどで出力をさせると以下のようになります。

次に、こちらのファイルから受け取ったデータをpythonで扱えるようにしましょう。
flaskで作るので、templatesフォルダに今作成したform.htmlを入れてください。
さらに、そのrender_templatesの上の階層にlogin.pyというファイルを作り以下のように記述してください。

また現状の構成は次の通りです。

- app.py(flaskでサーバー処理を行うpythonファイル)
- login.py(今作成したlogin.py)
- templates(HTMLファイルが沢山入るフォルダ)
    └ index.html

app.pyは先ほど作成したファイルですので、この後は使用しません。

次のコードはこれから作成するlogin.pyの中身です。

from flask import Flask, request,render_template

app = Flask(__name__)

# login処理です
@app.route('/', methods=['GET', 'POST'])
def form():
    # 2回目以降データが送られてきた時の処理です
    if request.method == 'POST':
        print("POSTされたIDは?" + str(request.form['id']))
        print("POSTされたPASSWORDは?" + str(request.form['pwd']))
        return render_template('form.html')
    # 1回目のデータが何も送られてこなかった時の処理です。
    else:
        return render_template('form.html')

# アプリケーションを動かすためのおまじない
if __name__ == "__main__":
    app.run(port = 8000, debug=True)

ここで、このlogin.pyを先ほどと同じ方法で実行し、起動してましょう。
その後、ブラウザの画面http://127.0.0.1:8000/では、次のような表示になります。
その画面のテキストフィールドの中に、何かしらの値を入れて送信ボタンを押してみてください。

ターミナルやコマンドプロンプト上では以下のように出力がされます。

これで、HTMLに入力された値もpythonで扱えるようになりました。

Webサービスの構成とAPIサーバー

近年Webサービスを作る上で、幾つか異なる役割を持ったサーバ構成になっています。
例えば、ユーザー情報を管理するDBサーバや、APIサーバー、またはWebサーバーや画像サーバなどで構成されています。
APIサーバはクライアントからHTTPもしくはHTTPSリクエストを受けとり、そのリクエストのパラメータに従って処理を行い、DBサーバーから情報を受け取り、クライアントにレスポンスを返します。

Web API (JSON API)

ここでは、Flaskを使ってWeb APIを作ってみます。
まずはイメージをして頂きたいので、簡単なものを作ってみます。
ファイル名は任意で構いません。(login_api.pyなど好きな名前で作成してください)

from flask import Flask
import flask

app = Flask(__name__, static_folder='.', static_url_path='')

@app.route('/')
def index():
    return app.send_static_file('index.html')

@app.route("/mypage")
def mypage():
    # login = False
    login = True
    if login is False:
        return flask.jsonify({
            "code" : 400,
            "msg"  : "Bad Request"
        })

    user_data = {"user_name": "ai_academy"}
    return flask.jsonify({
        "code": 200,
        "msg" : "OK",
        "result": user_data
    })


if __name__ == "__main__":
    app.run(port=8000, debug=True)

上記コードを記述出来ましたら、以下コマンドを実行してください。

python login_api.py

変数loginの初期状態がTrueですので、ここでは既にログインをしていることを意味しています。
ですので、ログイン成功したことを意味するjsonが出力されています。

では、変数loginの値をFalseにしてみてください。

このように、JSONの出力が変わっていることが確認できます。
上記プログラム内でflask.jsonifyというのを使用していますが、
これはPythonの辞書型をJSONの文字列に変換し、必要なレスポンスヘッダー等も自動で設定してくれます。

まとめ

この記事では、Flaskとは何か?またFlaskの基礎を学び、HTMLにデータをどのように渡すか、どのようにHTMLで入力された値を扱うかを学びました。
本記事で学んだFlaskと合わせて、この記事では解説しておりませんが、HTML/CSS/JavaScriptを合わせることでWebアプリケーションを作ることが可能です。
Webアプリケーションの制作をしてみた方は、是非Web開発にチャレンジしてみてください。

オススメ記事