Flask と Python 3 を使用して最初のウェブアプリケーションを作成する方法

著者は、Write for DOnationsプログラムの一環として、寄付を受け取るためにFree and Open Source Fundを選択しました。

はじめに

Flaskは、Python言語でWebアプリケーションを作成するための便利なツールや機能を提供する軽量のPython Webフレームワークです。開発者に柔軟性を提供し、単一のPythonファイルを使用してWebアプリケーションを迅速に構築できるため、新しい開発者にとっても使いやすいフレームワークです。Flaskは拡張可能であり、特定のディレクトリ構造を強制したり、開始する前に複雑な定型コードを必要としないため、開発を始めるのが容易です。

Flaskを学ぶことで、Pythonで迅速にWebアプリケーションを作成できるようになります。データベースにデータを保存したり、Webフォームを検証したりするなど、Pythonライブラリを活用してWebアプリケーションに高度な機能を追加することができます。

このチュートリアルでは、ブラウザ上にHTMLテキストをレンダリングする小さなWebアプリケーションを構築します。Flaskをインストールし、Flaskアプリケーションを作成・実行し、開発モードでアプリケーションを実行します。ルーティングを使用して、Webアプリケーション内で異なる目的を果たす様々なWebページを表示します。また、ビュー関数を使用して、ユーザーが動的ルートを通じてアプリケーションと対話できるようにします。最後に、デバッガーを使用してエラーのトラブルシューティングを行います。

前提条件

ステップ1 — Flaskのインストール

このステップでは、Python環境をアクティブにし、pipパッケージインストーラを使用してFlaskをインストールします。

まだアクティブにしていない場合は、プログラミング環境をアクティブにします:

  1. source env/bin/activate

プログラミング環境をアクティブにしたら、pip installコマンドを使用してFlaskをインストールします:

  1. pip install flask

インストールが完了すると、出力の最後の部分にインストールされたパッケージのリストが表示されます。次のようなものです:

Output
... Installing collected packages: Werkzeug, MarkupSafe, Jinja2, itsdangerous, click, flask Successfully installed Jinja2-3.0.1 MarkupSafe-2.0.1 Werkzeug-2.0.1 click-8.0.1 flask-2.0.1 itsdangerous-2.0.1

これは、Flaskをインストールする際に他のいくつかのパッケージもインストールされたことを意味します。これらのパッケージは、Flaskがさまざまな機能を実行するために必要な依存関係です。

プロジェクトフォルダ、仮想環境を作成し、Flaskをインストールしました。これで、シンプルなアプリケーションのセットアップに進むことができます。

ステップ2 — シンプルなアプリケーションの作成

これでプログラミング環境が整ったので、Flaskを使い始めます。このステップでは、Pythonファイル内に小さなFlaskウェブアプリケーションを作成し、ブラウザに表示するHTMLコードを記述します。

あなたのflask_appディレクトリで、app.pyという名前のファイルを編集用に開きます。nanoまたはお好みのテキストエディタを使用してください:

  1. nano app.py

app.pyファイル内に以下のコードを記述してください:

flask_app/app.py

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello():
    return '<h1>Hello, World!</h1>'

ファイルを保存して閉じます。

上記のコードブロックでは、まずflaskパッケージからFlaskオブジェクトをインポートします。次に、それを使用してFlaskアプリケーションインスタンスを作成し、appという名前を付けます。特別な変数__name__を渡します。これは現在のPythonモジュールの名前を保持しています。この名前はインスタンスがどこにあるかを伝えます。Flaskは裏でいくつかのパスを設定するためにこれが必要です。

appインスタンスを作成したら、それを使用して受信したウェブリクエストを処理し、ユーザーにレスポンスを送信できます。@app.routeは、通常のPython関数をFlaskのビュー関数に変換するデコレータです。これにより、関数の戻り値がHTTPレスポンスに変換され、ウェブブラウザなどのHTTPクライアントに表示されます。@app.route()'/'の値を渡すことで、この関数がメインURLであるURL/へのウェブリクエストに応答することを示します。

hello()ビュー関数は、文字列 '<h1>Hello, World!</h1>' をHTTPレスポンスとして返します。

これで、app.pyというPythonファイルにシンプルなFlaskアプリケーションができました。次のステップでは、このアプリケーションを実行して、hello()ビュー関数の結果をウェブブラウザで表示します。

ステップ3 — アプリケーションの実行

Flaskアプリケーションを含むファイルを作成した後、Flaskコマンドラインインターフェイスを使用して開発サーバーを起動し、前のステップでhello()ビュー関数の戻り値として書いたHTMLコードをブラウザでレンダリングします。

まず、仮想環境がアクティブな状態でflask_appディレクトリにいる間に、アプリケーション(app.py)の場所をFlaskに伝えるために、以下のコマンドでFLASK_APP環境変数を使用します(Windowsの場合はexportの代わりにsetを使用します):

  1. export FLASK_APP=app

次に、開発モードでアプリケーションを実行することを指定します(デバッガーを使用してエラーをキャッチできます)FLASK_ENV環境変数を使用します:

  1. export FLASK_ENV=development

最後に、flask runコマンドを使用してアプリケーションを実行します:

  1. flask run

アプリケーションが実行されると、出力は次のようになります:

Output
* Serving Flask app "app" (lazy loading) * Environment: development * Debug mode: on * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 296-353-699

前述の出力にはいくつかの情報が含まれています。

  • 実行しているアプリケーションの名前("app")。
  • アプリケーションが実行されている環境(development)。
  • Debug mode: onは、Flaskデバッガが実行されていることを示しています。これは開発中に有用で、何か問題が発生した際に詳細なエラーメッセージを提供するため、トラブルシューティングが容易になります。
  • アプリケーションはローカルのURL http://127.0.0.1:5000/ で実行されています。127.0.0.1はあなたのマシンのlocalhostを表し、:5000はポート番号です。

ブラウザを開き、URL http://127.0.0.1:5000/ を入力してください。Hello, World!というテキストが<h1>見出しとして表示されるはずです。これにより、アプリケーションが正常に実行されていることが確認できます。

開発サーバーを停止したい場合は、CTRL+Cを押してください。

警告: Flask は開発環境でアプリケーションを提供するためにシンプルなウェブサーバーを使用しており、これはまた Flask デバッガーがエラーの捕捉を容易にするために実行されていることも意味します。この開発サーバーは本番環境での展開には使用しないでください。詳細については Flask ドキュメンテーションの展開オプションページを参照してください。Gunicorn を使った Flask 展開チュートリアルuWSGI を使ったチュートリアルを確認することもできますし、DigitalOcean App Platform を使用してGunicorn を使って App Platform に Flask アプリを展開する方法チュートリアルに従って Flask アプリケーションを展開することもできます。

app.py アプリケーションの開発を続けるには、開発サーバーを実行したまま別のターミナルウィンドウを開いてください。flask_app ディレクトリに移動し、仮想環境をアクティブにし、環境変数 FLASK_ENVFLASK_APP を設定して、次のステップに進んでください。(これらのコマンドはこのステップの前半にリストされています。)

注意: 新しいターミナルを開く際、または開発サーバーを実行しているターミナルを閉じて再実行したい場合、仮想環境のアクティベーションと環境変数 FLASK_ENV および FLASK_APP を設定することを忘れないでください。これらは flask run コマンドが正しく機能するために必要です。

サーバーは一つのターミナルウィンドウで一度だけ実行するだけで十分です。

Flaskアプリケーションの開発サーバーが既に実行中の場合、同じ flask run コマンドで別のFlaskアプリケーションを実行することはできません。これは、flask run がデフォルトでポート番号 5000 を使用し、一度使用されると他のアプリケーションでは利用できなくなるため、次のようなエラーが発生します:

Output
OSError: [Errno 98] Address already in use

この問題を解決するには、現在実行中のサーバーを CTRL+C で停止し、再度 flask run を実行するか、両方のアプリケーションを同時に実行したい場合は、-p 引数に別のポート番号を指定します。例えば、ポート 5001 で別のアプリケーションを実行するには次のコマンドを使用します:

  1. flask run -p 5001

これにより、一つのアプリケーションを http://127.0.0.1:5000/ で、もう一つを http://127.0.0.1:5001/ で実行できます。

これで小さなFlaskウェブアプリケーションが完成しました。アプリケーションを実行し、ウェブブラウザに情報を表示しました。次に、ルートについて学び、複数のウェブページを提供する方法を学びます。

ステップ4 — ルートとビュー関数

このステップでは、アプリケーションにいくつかのルートを追加して、リクエストされたURLに応じて異なるページを表示します。また、ビュー関数について学び、それらをどのように使用するかを理解します。

ルートは、ユーザーがブラウザであなたのウェブアプリケーションを訪れたときに何を受け取るかを決定するために使用できるURLです。例えば、http://127.0.0.1:5000/はインデックスページを表示するために使用されるメインルートかもしれません。URL http://127.0.0.1:5000/aboutは、ウェブアプリケーションに関する情報を訪問者に提供するために使用される別のルートです。同様に、ユーザーがhttp://127.0.0.1:5000/loginでアプリケーションにサインインできるルートを作成することもできます。

現在、あなたのFlaskアプリケーションには、メインURL(http://127.0.0.1:5000/)をリクエストするユーザーに対応する1つのルートがあります。新しいウェブページをアプリケーションに追加する方法を示すために、アプリケーションファイルを編集して、http://127.0.0.1:5000/aboutでウェブアプリケーションに関する情報を提供する別のルートを追加します。

まず、app.pyファイルを編集用に開きます:

  1. nano app.py

ファイルの最後に以下の強調表示されたコードを追加して編集します:

flask_app/app.py
from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello():
    return '<h1>Hello, World!</h1>'


@app.route('/about/')
def about():
    return '<h3>This is a Flask web application.</h3>'

ファイルを保存して閉じます。

新しい関数about()を追加しました。この関数は@app.route()デコレータで装飾されており、ビュー関数に変換され、http://127.0.0.1:5000/aboutエンドポイントへのリクエストを処理します。

開発サーバーを実行している状態で、ブラウザを使用して以下のURLにアクセスしてください:

http://127.0.0.1:5000/about

テキストThis is a Flask web application.<h3>HTML見出しで表示されます。

また、1つのビュー関数に対して複数のルートを使用することもできます。例えば、インデックスページを//index/の両方で提供できます。そのためには、app.pyファイルを編集用に開いてください:

  1. nano app.py

hello()ビュー関数に別のデコレータを追加してファイルを編集します:

flask_app/app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
@app.route('/index/')
def hello():
    return '<h1>Hello, World!</h1>'

@app.route('/about/')
def about():
    return '<h3>This is a Flask web application.</h3>'

ファイルを保存して閉じます。

この新しいデコレータを追加した後、インデックスページにhttp://127.0.0.1:5000/http://127.0.0.1:5000/indexの両方からアクセスできます。

ルートが何であるか、それを使ってビュー関数を作成する方法、そしてアプリケーションに新しいルートを追加する方法を理解しました。次に、動的ルートを使用してユーザーがアプリケーションのレスポンスを制御できるようにします。

ステップ5 — 動的ルート

このステップでは、ダイナミックルートを使用して、ユーザーがアプリケーションと対話できるようにします。URLを介して渡された単語を大文字にするルートと、2つの数値を加算して結果を表示するルートを作成します。

通常、ユーザーは手動でURLを編集することでウェブアプリケーションと対話することはありません。むしろ、ユーザーはページ上の要素と対話し、ユーザーの入力やアクションに応じて異なるURLに誘導されますが、このチュートリアルの目的のために、URLを編集してアプリケーションが異なるURLに対して異なる応答をする方法をデモンストレーションします。

まず、app.pyファイルを編集用に開いてください:

  1. nano app.py

ユーザーがウェブアプリケーションに何かを送信できるようにする場合、例えば次の編集で行うようにURLに値を送信する場合、アプリケーションが信頼できないデータ(ユーザーが送信したデータ)を直接表示しないように常に留意する必要があります。ユーザーデータを安全に表示するために、Flaskと一緒にインストールされたmarkupsafeパッケージに含まれるescape()関数を使用してください。

app.pyを編集し、Flaskインポートの上に次の行を追加してください:

flask_app/app.py
from markupsafe import escape
from flask import Flask

# ...

次に、ファイルの末尾に次のルートを追加してください:

flask_app/app.py
# ...

@app.route('/capitalize/<word>/')
def capitalize(word):
    return '<h1>{}</h1>'.format(escape(word.capitalize()))

ファイルを保存して閉じます。

この新しいルートには、可変部分<word>があります。これは、FlaskにURLから値を取得し、それをビュー関数に渡すよう指示します。URL変数<word>は、キーワード引数をcapitalize()ビュー関数に渡します。引数の名前はURL変数と同じです(この場合はword)。これにより、URLを通じて渡された単語にアクセスし、Pythonのcapitalize()メソッドを使用してその単語の大文字バージョンで応答することができます。

以前にインポートしたescape()関数を使用して、word文字列をテキストとしてレンダリングします。これは、クロスサイトスクリプティング(XSS)攻撃を防ぐために重要です。ユーザーが単語の代わりに悪意のあるJavaScriptを送信した場合、escape()はそれをテキストとしてレンダリングし、ブラウザはそれを実行せず、ウェブアプリケーションを安全に保ちます。

大文字に変換された単語を<h1>HTML見出し内に表示するために、format()Pythonメソッドを使用します。このメソッドの詳細については、Python 3で文字列フォーマッタを使用する方法を参照してください。

開発サーバーを実行している状態で、ブラウザを開いて以下のURLにアクセスしてください。強調表示された単語を任意の単語に置き換えることができます。

http://127.0.0.1:5000/capitalize/hello
http://127.0.0.1:5000/capitalize/flask
http://127.0.0.1:5000/capitalize/python

ページ上の<h1>タグ内で、URL内の単語が大文字に変換されて表示されるのを確認できます。

ルートで複数の変数を使用することもできます。これを実証するために、2つの正の整数を加算して結果を表示するルートを追加します。

編集のためにapp.pyファイルを開きます:

  1. nano app.py

ファイルの最後に以下のルートを追加します:

flask_app/app.py
# ...

@app.route('/add/<int:n1>/<int:n2>/')
def add(n1, n2):
    return '<h1>{}</h1>'.format(n1 + n2)

ファイルを保存して閉じます。

このルートでは、URL変数(/add/<int:n1>/<int:n2>/)で正の整数のみを受け入れる特殊なコンバータ intを使用しています。デフォルトでは、URL変数は文字列と見なされ、そのように扱われます。

開発サーバーを実行している状態で、ブラウザを開いて次のURLにアクセスします:

http://127.0.0.1:5000/add/5/5/

結果は2つの数値の合計(この場合は10)になります。

これで、リクエストされたURLに応じて単一のルートで異なるレスポンスを表示するための動的ルートの使用方法を理解できました。次に、エラーが発生した場合にFlaskアプリケーションのトラブルシューティングとデバッグを行う方法を学びます。

ステップ6 — Flaskアプリケーションのデバッグ

ウェブアプリケーションを開発する際、期待する動作ではなくエラーが表示される状況に頻繁に遭遇するでしょう。変数のスペルミスや関数の定義やインポートを忘れることもあるかもしれません。これらの問題を解決しやすくするために、Flaskは開発モードでアプリケーションを実行する際にデバッガを提供しています。このステップでは、Flaskデバッガを使用してアプリケーションのエラーを修正する方法を学びます。

エラー処理の方法をデモンストレーションするために、ユーザー名のリストからユーザーにあいさつするルートを作成します。

編集のためにapp.pyファイルを開きます:

  1. nano app.py

ファイルの末尾に以下のルートを追加します:

flask_app/app.py
# ...

@app.route('/users/<int:user_id>/')
def greet_user(user_id):
    users = ['Bob', 'Jane', 'Adam']
    return '<h2>Hi {}</h2>'.format(users[user_id])

ファイルを保存して閉じます。

上記のルートでは、greet_user()ビュー関数はuser_id URL変数からuser_id引数を受け取ります。正の整数を受け入れるためにintコンバータを使用しています。関数内では、ユーザー名を表す3つの文字列を含むPythonリストであるusersがあります。ビュー関数は、提供されたuser_idに応じて構築された文字列を返します。user_id0の場合、レスポンスはusers[0]の値であるBobが最初のアイテムなので、<h2>タグ内のHi Bobになります。

開発サーバーを実行している状態で、ブラウザを開いて以下のURLにアクセスします:

http://127.0.0.1:5000/users/0
http://127.0.0.1:5000/users/1
http://127.0.0.1:5000/users/2

以下のレスポンスが得られます:

Output
Hi Bob Hi Jane Hi Adam

これまでのところうまく機能していますが、存在しないユーザーに挨拶を要求すると問題が発生する可能性があります。Flaskデバッガーの動作を示すために、次のURLにアクセスしてください:

http://127.0.0.1:5000/users/3

次のようなページが表示されます:

ページの上部には、Pythonの例外の名前が表示されます。この場合、IndexErrorとなり、リストのインデックス(この場合は3)がリストの範囲外であることを示しています(リストには3つのアイテムしかないため、範囲は0から2までです)。デバッガーでは、この例外を引き起こしたコードの行を示すトレースバックを見ることができます。

トレースバックの最後の2行は通常、エラーの原因を示しています。あなたの場合、次のような行になるかもしれません:

File "/home/USER/flask_app/app.py", line 28, in greet_user
    return '<h2>Hi {}</h2>'.format(users[user_id])

これにより、エラーがapp.pyファイル内のgreet_user()関数から発生しており、特にreturn行であることがわかります。

例外を引き起こした元の行を知ることで、コードのどこに問題があったのかを特定し、修正方法を決定するのに役立ちます。

この場合、シンプルなtry...except句を使用してこのエラーを修正できます。要求されたURLのインデックスがリストの範囲外の場合、ユーザーには404 Not Foundエラーが表示されます。これは、ユーザーが探しているページが存在しないことを示すHTTPエラーです。

編集のためにapp.pyファイルを開いてください。

  1. nano app.py

HTTP 404エラーに応答するには、Flaskのabort()関数が必要です。これはHTTPエラー応答を作成するために使用できます。ファイルの2行目を変更して、この関数もインポートします:

flask_app/app.py
from markupsafe import escape
from flask import Flask, abort

次に、greet_user()ビュー関数を次のように編集します:

flask_app/app.py
# ...

@app.route('/users/<int:user_id>/')
def greet_user(user_id):
    users = ['Bob', 'Jane', 'Adam']
    try:
        return '<h2>Hi {}</h2>'.format(users[user_id])
    except IndexError:
        abort(404)

上記のtryを使用して、return式のエラーをテストします。エラーがない場合、つまりuser_idusersリストのインデックスに一致する値を持っている場合、アプリケーションは適切な挨拶で応答します。user_idの値がリストの範囲外の場合、IndexError例外が発生し、exceptを使用してエラーをキャッチし、abort() Flaskヘルパー関数を使用してHTTP 404エラーで応答します。

ここで、開発サーバーを実行して、再度URLにアクセスします:

http://127.0.0.1:5000/users/3

今回は、ページが存在しないことをユーザーに通知する標準的な404エラーページが表示されます。

このチュートリアルの終わりに、app.pyファイルは次のようになります:

flask_app/app.py
from markupsafe import escape
from flask import Flask, abort

app = Flask(__name__)


@app.route('/')
@app.route('/index/')
def hello():
    return '<h1>Hello, World!</h1>'


@app.route('/about/')
def about():
    return '<h3>This is a Flask web application.</h3>'

@app.route('/capitalize/<word>/')
def capitalize(word):
    return '<h1>{}</h1>'.format(escape(word.capitalize()))

@app.route('/add/<int:n1>/<int:n2>/')
def add(n1, n2):
    return '<h1>{}</h1>'.format(n1 + n2)

@app.route('/users/<int:user_id>/')
def greet_user(user_id):
    users = ['Bob', 'Jane', 'Adam']
    try:
        return '<h2>Hi {}</h2>'.format(users[user_id])
    except IndexError:
        abort(404)

これで、Flaskデバッガを使用してエラーをトラブルシューティングし、適切な対処法を決定する方法について一般的な理解が得られました。

結論

あなたは現在、Flaskとは何か、そのインストール方法、そしてそれを使ってウェブアプリケーションを書く方法、開発サーバーを起動する方法、ルートとビュー関数を使って特定の目的を持つ異なるウェブページを表示する方法を一般的に理解しています。また、動的ルートを使ってユーザーがURLを通じてウェブアプリケーションとやり取りできるようにする方法や、デバッガを使ってエラーをトラブルシューティングする方法も学びました。

Flaskについてさらに詳しく読みたい場合は、Flaskトピックページをチェックしてください。

Source:
https://www.digitalocean.com/community/tutorials/how-to-create-your-first-web-application-using-flask-and-python-3