VS Codeのエージェントモードを拡張するには、を試してください!

Visual Studio Code での Flask チュートリアル

Flask は、Web アプリケーション向けの軽量な Python フレームワークであり、URL ルーティングとページレンダリングの基本機能を提供します。

Flask は「マイクロ」フレームワークと呼ばれています。これは、フォーム検証、データベース抽象化、認証などの機能を直接提供しないためです。これらの機能は、Flask 拡張機能と呼ばれる特別な Python パッケージによって提供されます。拡張機能は Flask とシームレスに統合されるため、あたかも Flask 自体の一部であるかのように見えます。たとえば、Flask はページテンプレートエンジンを提供しませんが、Flask をインストールすると、デフォルトで Jinja テンプレートエンジンが含まれます。便宜上、私たちは通常、これらのデフォルトを Flask の一部として話します。

この Flask チュートリアルでは、共通のベーステンプレートを使用する 3 ページのシンプルな Flask アプリケーションを作成します。その過程で、ターミナル、エディター、デバッガー、コードスニペットなど、Visual Studio Code の多くの機能を体験します。

この Flask チュートリアルの完成したコードプロジェクトは GitHub で見つけることができます: python-sample-vscode-flask-tutorial

問題が発生した場合は、Python 拡張機能 Discussions Q&A で回答を検索したり、質問したりできます。

前提条件

この Flask チュートリアルを正常に完了するには、次のことを行う必要があります (これは一般的な Python チュートリアルの手順と同じです)。

  1. Python 拡張機能をインストールします。

  2. Python 3 のバージョン (このチュートリアルはこれに合わせて書かれています) をインストールします。選択肢には次のものがあります。

    • (すべてのオペレーティングシステム) python.org からダウンロードします。通常、ページに最初に表示される Download ボタンを使用します。
    • (Linux) 組み込みの Python 3 インストールでも問題ありませんが、他の Python パッケージをインストールするには、ターミナルで `sudo apt install python3-pip` を実行する必要があります。
    • (macOS) macOS 上でHomebrew を使用して `brew install python3` でインストールします。
    • (すべてのオペレーティングシステム) Anaconda からダウンロードします (データサイエンス目的の場合)。
  3. Windows では、Python インタープリターの場所が PATH 環境変数に含まれていることを確認してください。場所はコマンドプロンプトで `path` を実行することで確認できます。Python インタープリターのフォルダーが含まれていない場合は、Windows の設定を開き、「環境」を検索して アカウントの環境変数を編集 を選択し、Path 変数を編集してそのフォルダーを追加します。

Flask チュートリアルのためのプロジェクト環境を作成する

このセクションでは、Flask がインストールされる仮想環境を作成します。仮想環境を使用することで、Flask をグローバルな Python 環境にインストールすることを避け、アプリケーションで使用されるライブラリを正確に制御できます。

  1. ファイルシステムに、このチュートリアル用のフォルダー (例: `hello_flask`) を作成します。

  2. ターミナルでそのフォルダーに移動して `code .` を実行するか、VS Code を実行して ファイル > フォルダーを開く コマンドを使用して、このフォルダーを VS Code で開きます。

  3. VS Code で、コマンドパレット (表示 > コマンド パレット または (⇧⌘P (Windows, Linux Ctrl+Shift+P))) を開きます。次に、Python: 環境の作成 コマンドを選択して、ワークスペースに仮想環境を作成します。`venv` を選択し、次にそれを作成するために使用したい Python 環境を選択します。

    注意: 手動で環境を作成したい場合や、環境作成プロセスでエラーが発生した場合は、環境のページをご覧ください。

    Flask tutorial: opening the Command Palette in VS Code

  4. 仮想環境の作成が完了したら、コマンドパレットから ターミナル: 新しいターミナルを作成する (⌃⇧` (Windows, Linux Ctrl+Shift+`)) を実行します。これによりターミナルが作成され、アクティベーションスクリプトを実行して仮想環境が自動的にアクティブ化されます。

    注意: Windows で、デフォルトのターミナルタイプが PowerShell の場合、システムでスクリプトの実行が無効になっているため activate.ps1 を実行できないというエラーが表示されることがあります。このエラーには、スクリプトを許可する方法に関する情報へのリンクが提供されます。それ以外の場合は、ターミナル: 既定のプロファイルの選択 を使用して、"Command Prompt" または "Git Bash" をデフォルトに設定してください。

  5. VS Code ターミナルで次のコマンドを実行して、仮想環境に Flask をインストールします。

    python -m pip install flask
    

これで、Flask コードを書くための自己完結型の環境ができました。VS Code は ターミナル: 新しいターミナルを作成する を使用すると、自動的に環境をアクティブ化します。別のコマンドプロンプトやターミナルを開いた場合は、`source .venv/bin/activate` (Linux/macOS) または `.venv\Scripts\Activate.ps1` (Windows) を実行して環境をアクティブ化します。コマンドプロンプトの先頭に (.venv) と表示されたら、環境がアクティブ化されていることがわかります。

最小限の Flask アプリを作成して実行する

  1. VS Code で、メニューから ファイル > 新規作成 を使用するか、Ctrl+N を押すか、エクスプローラー ビューの新しいファイル アイコン (下記参照) を使用して、プロジェクトフォルダーに `app.py` という名前の新しいファイルを作成します。

    Flask tutorial: new file icon in Explorer View

  2. `app.py` に、Flask をインポートし、Flask オブジェクトのインスタンスを作成するコードを追加します。以下のコードをコピーアンドペーストするのではなく入力すると、VS Code の IntelliSense と自動補完を観察できます。

    from flask import Flask
    app = Flask(__name__)
    
  3. 同じく `app.py` に、コンテンツ (この場合は単純な文字列) を返す関数を追加し、Flask の `app.route` デコレーターを使用して URL ルート `/` をその関数にマッピングします。

    @app.route("/")
    def home():
        return "Hello, Flask!"
    

    ヒント: 同じ関数に複数のデコレーターを、1行に1つずつ使用できます。これは、同じ関数にいくつの異なるルートをマッピングしたいかによります。

  4. `app.py` ファイルを保存します (⌘S (Windows, Linux Ctrl+S))。

  5. 統合ターミナルで、`python -m flask run` と入力してアプリを実行します。これにより Flask 開発サーバーが実行されます。開発サーバーはデフォルトで `app.py` を探します。Flask を実行すると、次のような出力が表示されるはずです。

    (.venv) D:\py\\hello_flask>python -m flask run
     * 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)
    

    Flask モジュールが見つからないというエラーが表示された場合は、前のセクションの最後で説明したように、仮想環境で `python -m pip install flask` を実行したことを確認してください。

    また、開発サーバーを別の IP アドレスやポートで実行したい場合は、`--host=0.0.0.0 --port=80` のように、host と port のコマンドライン引数を使用します。

  6. ターミナル内の `http://127.0.0.1:5000/` URL を Ctrl+クリック して、デフォルトのブラウザーでレンダリングされたページを開きます。

    Flask tutorial: the running app in a browser

  7. / のような URL にアクセスすると、デバッグターミナルに HTTP リクエストを示すメッセージが表示されることを確認してください。

    127.0.0.1 - - [11/Jul/2018 08:40:15] "GET / HTTP/1.1" 200 -
    
  8. ターミナルで Ctrl+C を使用してアプリを停止します。

ヒント: `app.py` 以外のファイル名 (例: `webapp.py`) を使用する場合は、FLASK_APP という名前の環境変数を定義し、その値を自分で選んだファイルに設定する必要があります。そうすると、Flask の開発サーバーはデフォルトの `app.py` の代わりに FLASK_APP の値を使用します。詳細については、Flask コマンドラインインターフェイスを参照してください。

デバッガーでアプリを実行する

デバッグは、実行中のプログラムを特定のコード行で一時停止する機会を与えてくれます。プログラムが一時停止している間、変数を調べたり、デバッグコンソールパネルでコードを実行したり、デバッグで説明されている機能を活用したりできます。デバッガーを実行すると、デバッグセッションが始まる前に変更されたファイルも自動的に保存されます。

始める前に: 前のセクションの最後で、ターミナルで Ctrl+C を使用して実行中のアプリを停止したことを確認してください。1つのターミナルでアプリを実行したままにすると、そのポートは占有され続けます。その結果、同じポートを使用してデバッガーでアプリを実行すると、元の実行中のアプリがすべてのリクエストを処理し、デバッグ中のアプリでは何もアクティビティが見られず、プログラムはブレークポイントで停止しません。つまり、デバッガーが機能していないように見える場合は、アプリの他のインスタンスがまだ実行中でないことを確認してください。

  1. `app.py` の内容を次のコードに置き換えます。これにより、デバッガーでステップ実行できる2番目のルートと関数が追加されます。

    import re
    from datetime import datetime
    
    from flask import Flask
    
    app = Flask(__name__)
    
    
    @app.route("/")
    def home():
        return "Hello, Flask!"
    
    
    @app.route("/hello/<name>")
    def hello_there(name):
        now = datetime.now()
        formatted_now = now.strftime("%A, %d %B, %Y at %X")
    
        # Filter the name argument to letters only using regular expressions. URL arguments
        # can contain arbitrary text, so we restrict to safe characters only.
        match_object = re.match("[a-zA-Z]+", name)
    
        if match_object:
            clean_name = match_object.group(0)
        else:
            clean_name = "Friend"
    
        content = "Hello there, " + clean_name + "! It's " + formatted_now
        return content
    

    新しい URL ルート `/hello/` に使用されるデコレーターは、任意の追加の値を受け入れることができるエンドポイント /hello/ を定義します。ルート内の `<` と `>` の中の識別子は、関数に渡され、コードで使用できる変数を定義します。

    URL ルートでは大文字と小文字が区別されます。たとえば、ルート `/hello/` は `/Hello/` とは異なります。同じ関数で両方を処理したい場合は、各バリアントにデコレーターを使用します。

    コードのコメントで説明されているように、アプリへの様々な攻撃を避けるために、任意にユーザーから提供された情報は常にフィルタリングしてください。この場合、コードは name 引数を文字のみを含むようにフィルタリングし、制御文字や HTML などの注入を防ぎます。(次のセクションでテンプレートを使用すると、Flask が自動的にフィルタリングを行うため、このコードは不要になります。)

  2. 次のいずれかの方法で、`hello_there` 関数の最初のコード行 (`now = datetime.now()`) にブレークポイントを設定します。

    • その行にカーソルを置いて F9 を押すか、
    • その行にカーソルを置いて、実行 > ブレークポイントの切り替え メニューコマンドを選択するか、
    • 行番号の左側のマージンを直接クリックします (そこにマウスを合わせると、薄い赤色の点が表示されます)。

    ブレークポイントは左マージンに赤い点として表示されます。

    Flask tutorial: a breakpoint set on the first line of the hello_there function

  3. VS Code の 実行とデバッグ ビューに切り替えます (左側のアクティビティバーまたは ⇧⌘D (Windows, Linux Ctrl+Shift+D) を使用)。「実行とデバッグをカスタマイズするには、launch.json ファイルを作成します」というメッセージが表示される場合があります。これは、まだデバッグ構成を含む `launch.json` ファイルがないことを意味します。launch.json ファイルの作成 リンクをクリックすると、VS Code がファイルを作成してくれます。

    Flask tutorial: initial view of the debug panel

  4. リンクを選択すると、VS Code はデバッグ構成を要求します。ドロップダウンから Flask を選択すると、VS Code は新しい `launch.json` ファイルに Flask の実行構成を自動的に入力します。`launch.json` ファイルには多数のデバッグ構成が含まれており、それぞれが `configuration` 配列内の別々の JSON オブジェクトです。

  5. スクロールダウンして、「Python: Flask」という名前の構成を確認します。この構成には `"module": "flask"` が含まれており、デバッガーを起動する際に VS Code に Python を `-m flask` で実行するように指示します。また、`env` プロパティで FLASK_APP 環境変数を定義して、起動ファイルを識別します。デフォルトは `app.py` ですが、簡単に別のファイルを指定できます。ホストやポートを変更したい場合は、`args` 配列を使用できます。

    {
        "name": "Python Debugger: Flask",
        "type": "debugpy",
        "request": "launch",
        "module": "flask",
        "env": {
            "FLASK_APP": "app.py",
            "FLASK_DEBUG": "1"
        },
        "args": [
            "run",
            "--no-debugger",
            "--no-reload"
        ],
        "jinja": true,
        "justMyCode": true
    },
    

    注意: 構成の `env` エントリに `"FLASK_APP": "${workspaceFolder}/app.py"` が含まれている場合は、上記のように `"FLASK_APP": "app.py"` に変更してください。そうしないと、「モジュール C をインポートできません」のようなエラーメッセージに遭遇する可能性があります。ここで C はプロジェクトフォルダーが存在するドライブ文字です。

    注意: `launch.json` が作成されると、エディターに 構成の追加 ボタンが表示されます。このボタンは、構成リストの先頭に追加する追加の構成のリストを表示します。(実行 > 構成の追加 メニューコマンドも同じ動作をします。)

  6. `launch.json` を保存します (⌘S (Windows, Linux Ctrl+S))。デバッグ構成のドロップダウンリストで、Python: Flask 構成を選択します。

    Flask tutorial: selecting the Flask debugging configuration

  7. 実行 > デバッグの開始 メニューコマンドを選択するか、リストの横にある緑色の デバッグの開始 矢印 (F5) を選択してデバッガーを開始します。

    Flask tutorial: start debugging/continue arrow on the debug toolbar

    ステータスバーの色がデバッグ中を示す色に変わることを確認してください。

    Flask tutorial: appearance of the debugging status bar

    VS Code にはデバッグツールバー (下記参照) も表示され、次の順序でコマンドが含まれています: 一時停止 (または続行、F5)、ステップオーバー (F10)、ステップイン (F11)、ステップアウト (⇧F11 (Windows, Linux Shift+F11))、再起動 (⇧⌘F5 (Windows, Linux Ctrl+Shift+F5))、停止 (⇧F5 (Windows, Linux Shift+F5))。各コマンドの説明については、VS Code のデバッグ を参照してください。

    Flask tutorial: the VS Code debug toolbar

  8. 出力は「Python デバッグ コンソール」ターミナルに表示されます。そのターミナル内の `http://127.0.0.1:5000/` リンクを Ctrl+クリック して、その URL をブラウザーで開きます。ブラウザーのアドレスバーで、`http://127.0.0.1:5000/hello/VSCode` に移動します。ページがレンダリングされる前に、VS Code は設定したブレークポイントでプログラムを一時停止します。ブレークポイント上の小さな黄色の矢印は、それが次に実行されるコード行であることを示します。

    Flask tutorial: VS Code paused at a breakpoint

  9. ステップ オーバーを使用して `now = datetime.now()` ステートメントを実行します。

  10. VS Code ウィンドウの左側には、`now` のようなローカル変数や `name` のような引数を表示する 変数 ペインが表示されます。その下には、ウォッチコール スタックブレークポイント のペインがあります (詳細は VS Code のデバッグ を参照)。ローカル セクションで、さまざまな値を展開してみてください。値をダブルクリック (または Enter (Windows, Linux F2) を使用) して変更することもできます。ただし、`now` のような変数を変更すると、プログラムが壊れる可能性があります。開発者は通常、コードが最初に正しい値を生成しなかった場合に値を修正するためにのみ変更を加えます。

    Flask tutorial: local variables and arguments in VS Code during debugging

  11. プログラムが一時停止している間、デバッグ コンソール パネル (ターミナル パネルの「Python デバッグ コンソール」とは異なります) を使用して、式を試したり、プログラムの現在の状態を使用してコードの一部を試したりできます。たとえば、`now = datetime.now()` の行をステップオーバーした後、さまざまな日付/時刻形式を試すことができます。エディターで `now.strftime("%A, %d %B, %Y at %X")` というコードを選択し、右クリックして デバッグ コンソールで評価 を選択してそのコードをデバッグ コンソールに送信し、そこで実行します。

    now.strftime("%A, %d %B, %Y at %X")
    'Wednesday, 31 October, 2018 at 18:13:39'
    

    ヒント: デバッグコンソールには、ターミナルに表示されない可能性のあるアプリ内からの例外も表示されます。たとえば、実行とデバッグビューのコールスタック領域に「例外で一時停止」というメッセージが表示された場合は、デバッグコンソールに切り替えて例外メッセージを確認してください。

  12. その行をデバッグコンソールの下部にある > プロンプトにコピーし、フォーマットを変更してみてください。

    now.strftime("%a, %d %B, %Y at %X")
    'Wed, 31 October, 2018 at 18:13:39'
    now.strftime("%a, %d %b, %Y at %X")
    'Wed, 31 Oct, 2018 at 18:13:39'
    now.strftime("%a, %d %b, %y at %X")
    'Wed, 31 Oct, 18 at 18:13:39'
    
  13. 必要であれば、さらにいくつかのコード行をステップ実行し、続行 (F5) を選択してプログラムを実行させます。ブラウザーウィンドウに結果が表示されます。

    Flask tutorial: result of the modified program

  14. コードの行を `now.strftime("%a, %d %b, %y at %X")` のように、異なる日時形式を使用するように変更してから、ファイルを保存します。Flask サーバーは自動的にリロードされるため、デバッガーを再起動する必要なく変更が適用されます。ブラウザーでページを更新して、更新内容を確認してください。

  15. 終わったらブラウザーを閉じてデバッガーを停止します。デバッガーを停止するには、停止ツールバーボタン (赤い四角) または 実行 > デバッグの停止 コマンド (⇧F5 (Windows, Linux Shift+F5)) を使用します。

ヒント: `http://127.0.0.1:5000/hello/VSCode` のような特定の URL に繰り返し移動しやすくするには、`print` ステートメントを使用してその URL を出力します。URL はターミナルに表示され、そこで Ctrl+クリック してブラウザーで開くことができます。

[定義へ移動] と [定義をここに表示] コマンド

Flask やその他のライブラリを操作していると、それらのライブラリ自体のコードを調べたいことがあるかもしれません。VS Code は、任意のコード内のクラスやその他のオブジェクトの定義に直接移動できる 2 つの便利なコマンドを提供しています。

  • 定義へ移動 は、自分のコードからオブジェクトを定義しているコードにジャンプします。たとえば、`app.py` で `Flask` クラス (行 `app = Flask(__name__)` 内) を右クリックし、定義へ移動 を選択する (または F12 を使用する) と、Flask ライブラリ内のクラス定義に移動します。

  • 定義をここに表示 (⌥F12 (Windows Alt+F12, Linux Ctrl+Shift+F10)、右クリックコンテキストメニューにもあります) も同様ですが、クラス定義をエディター内に直接表示します (エディターウィンドウにスペースを確保して、他のコードを隠さないようにします)。Escape を押して Peek ウィンドウを閉じるか、右上隅の x を使用します。

    Flask tutorial: peek definition showing the Flask class inline

テンプレートを使用してページをレンダリングする

このチュートリアルでこれまでに作成したアプリは、Python コードからプレーンテキストのウェブページのみを生成します。コード内で直接 HTML を生成することも可能ですが、開発者はアプリをクロスサイトスクリプティング (XSS) 攻撃にさらすことになるため、そのような方法は避けます。このチュートリアルの `hello_there` 関数では、たとえば、`content = "

Hello there, " + clean_name + "!

"` のようにコードで出力をフォーマットすることを考えるかもしれませんが、`content` の結果は直接ブラウザに渡されます。この隙間により、攻撃者は URL に悪意のある HTML (JavaScript コードを含む) を仕込み、それが `clean_name` に入り、結果的にブラウザで実行されてしまいます。

はるかに良い方法は、テンプレートを使用してコードからHTMLを完全に分離することです。そうすれば、コードはレンダリングではなくデータ値のみに関心を持つようになります。

  • テンプレートは、実行時にコードが提供する値のプレースホルダーを含む HTML ファイルです。テンプレートエンジンは、ページをレンダリングする際に置換を行います。したがって、コードはデータ値のみに関心を持ち、テンプレートはマークアップのみに関心を持つことになります。
  • Flask のデフォルトのテンプレートエンジンは Jinja で、Flask をインストールすると自動的にインストールされます。このエンジンは、自動エスケープ (XSS 攻撃を防ぐため) やテンプレートの継承など、柔軟なオプションを提供します。継承を使用すると、共通のマークアップを持つベースページを定義し、そのベースの上にページ固有の追加を行うことができます。

このセクションでは、テンプレートを使用して単一のページを作成します。続くセクションでは、静的ファイルを提供するためにアプリを構成し、その後、ベーステンプレートからナビゲーションバーを含む複数のページをアプリに作成します。

  1. `hello_flask` フォルダ内に `templates` という名前のフォルダを作成します。これは Flask がデフォルトでテンプレートを探す場所です。

  2. `templates` フォルダに、以下の内容で `hello_there.html` という名前のファイルを作成します。このテンプレートには "name" と "date" という2つのプレースホルダーが含まれており、これらは二重の中括弧 `{{` と `}}` で区切られています。ご覧のとおり、テンプレートに直接フォーマットコードを含めることもできます。

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title>Hello, Flask</title>
        </head>
        <body>
            {%if name %}
                <strong>Hello there, {{ name }}!</strong> It's {{ date.strftime("%A, %d %B, %Y at %X") }}.
            {% else %}
                What's your name? Provide it after /hello/ in the URL.
            {% endif %}
        </body>
    </html>
    

    ヒント: Flask 開発者は、日付の書式設定に `strftime` ではなく、flask-babel 拡張機能をよく使用します。flask-babel はロケールとタイムゾーンを考慮するためです。

  3. `app.py` で、ファイルの先頭近くに Flask の `render_template` 関数をインポートします。

    from flask import render_template
    
  4. 同じく `app.py` で、`hello_there` 関数を `render_template` を使ってテンプレートを読み込み、名前付きの値を適用するように修正します (そして、名前がない場合を認識するためのルートを追加します)。`render_template` は、最初の引数が `templates` フォルダからの相対パスであると想定します。通常、開発者はテンプレートにそれを使用する関数と同じ名前を付けますが、コード内で常に正確なファイル名を指定するため、名前を一致させる必要はありません。

    @app.route("/hello/")
    @app.route("/hello/<name>")
    def hello_there(name = None):
        return render_template(
            "hello_there.html",
            name=name,
            date=datetime.now()
        )
    

    マークアップとフォーマットがすべてテンプレートに含まれているため、コードがはるかにシンプルになり、データ値のみに関心を持つようになったことがわかります。

  5. プログラムを起動し (デバッガーの内外で、⌃F5 (Windows, Linux Ctrl+F5) を使用)、/hello/name の URL に移動して結果を確認してください。

  6. また、`` のような名前を使用して /hello/name の URL に移動し、Flask の自動エスケープが機能していることを確認してください。「name」の値は、実際の要素としてレンダリングされるのではなく、ブラウザでプレーンテキストとして表示されます。

静的ファイルの提供

静的ファイルには2つのタイプがあります。1つ目は、ページテンプレートが直接参照できるスタイルシートのようなファイルです。このようなファイルはアプリ内のどのフォルダーに置いてもかまいませんが、一般的には `static` フォルダー内に配置されます。

2番目のタイプは、静的ファイルを返す API エンドポイントを実装したい場合など、コードで扱いたいファイルです。この目的のために、Flask オブジェクトには組み込みのメソッド `send_static_file` があり、アプリの `static` フォルダー内にある静的ファイルを含むレスポンスを生成します。

次のセクションでは、両方のタイプの静的ファイルについて説明します。

テンプレートで静的ファイルを参照する

  1. `hello_flask` フォルダに `static` という名前のフォルダを作成します。

  2. `static` フォルダー内に、次の内容で `site.css` という名前のファイルを作成します。このコードを入力した後、VS Code が CSS ファイルに提供する構文ハイライト (カラープレビューを含む) も確認してください。

    .message {
        font-weight: 600;
        color: blue;
    }
    
  3. `templates/hello_there.html` で、`` タグの前に次の行を追加します。これにより、スタイルシートへの参照が作成されます。

    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='site.css')}}" />
    

    ここで使用されている Flask の url_for タグは、ファイルへの適切なパスを作成します。`url_for` は引数として変数を受け入れることができるため、必要に応じてプログラムで生成されるパスを制御できます。

  4. また、`templates/hello_there.html` で、`` 要素の内容を、`` タグの代わりに `message` スタイルを使用する以下のマークアップに置き換えます (名前なしで hello/ URL を使用した場合のメッセージも表示されます)。

    {%if name %}
        <span class="message">Hello there, {{ name }}!</span> It's {{ date.strftime("%A, %d %B, %Y at %X") }}.
    {% else %}
        <span class="message">What's your name? Provide it after /hello/ in the URL.</span>
    {% endif %}
    
  5. アプリを実行し、/hello/name の URL に移動して、メッセージが青色で表示されることを確認します。終了したらアプリを停止してください。

コードから静的ファイルを提供する

  1. `static` フォルダに、以下の内容で `data.json` という名前の JSON データファイルを作成します (これは意味のないサンプルデータです)。

    {
      "01": {
        "note": "This data is very simple because we're demonstrating only the mechanism."
      }
    }
    
  2. `app.py` に、`/api/data` ルートを持つ関数を追加し、`send_static_file` メソッドを使用して静的データファイルを返します。

    @app.route("/api/data")
    def get_data():
        return app.send_static_file("data.json")
    
  3. アプリを実行し、/api/data エンドポイントに移動して静的ファイルが返されることを確認します。終了したらアプリを停止してください。

ベーステンプレートを拡張する複数のテンプレートを作成する

ほとんどのWebアプリは複数のページを持ち、それらのページは通常多くの共通要素を共有するため、開発者はそれらの共通要素をベースページテンプレートに分離し、他のページテンプレートがそれを拡張できるようにします (これはテンプレート継承とも呼ばれます)。

また、同じテンプレートを拡張する多くのページを作成する可能性が高いため、VS Code でコードスニペットを作成しておくと、新しいページテンプレートをすばやく初期化できます。スニペットは、単一のソースから一貫したコードを提供し、既存のコードからのコピー&ペーストで発生しがちなエラーを回避するのに役立ちます。

以下のセクションでは、このプロセスのさまざまな部分について説明します。

ベースページテンプレートとスタイルを作成する

Flask のベースページテンプレートには、CSS ファイルやスクリプトファイルへの参照など、一連のページの共有部分がすべて含まれています。ベーステンプレートはまた、ベースを拡張する他のテンプレートが上書きすることを期待される 1 つ以上の block タグを定義します。block タグは、ベーステンプレートと拡張テンプレートの両方で `{% block %}` と `{% endblock %}` で区切られます。

以下の手順では、ベーステンプレートの作成方法を説明します。

  1. `templates` フォルダに、以下の内容で `layout.html` という名前のファイルを作成します。これには "title" と "content" という名前のブロックが含まれています。ご覧のとおり、マークアップはホーム、アバウト、コンタクトページへのリンクを持つシンプルなナビゲーションバー構造を定義しており、これらは後のセクションで作成します。各リンクは、実行時に一致するルートのリンクを生成するために、再び Flask の `url_for` タグを使用します。

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title>{% block title %}{% endblock %}</title>
            <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='site.css')}}" />
        </head>
    
        <body>
            <div class="navbar">
                <a href="{{ url_for('home') }}" class="navbar-brand">Home</a>
                <a href="{{ url_for('about') }}" class="navbar-item">About</a>
                <a href="{{ url_for('contact') }}" class="navbar-item">Contact</a>
            </div>
    
            <div class="body-content">
                {% block content %}
                {% endblock %}
                <hr/>
                <footer>
                    <p>&copy; 2018</p>
                </footer>
            </div>
        </body>
    </html>
    
  2. 既存の "message" スタイルの下に、`static/site.css` に次のスタイルを追加して、ファイルを保存します。このチュートリアルではレスポンシブデザインを実演しようとはしていないことに注意してください。これらのスタイルは、単にそこそこ興味深い結果を生成するだけです。

    .navbar {
        background-color: lightslategray;
        font-size: 1em;
        font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
        color: white;
        padding: 8px 5px 8px 5px;
    }
    
    .navbar a {
        text-decoration: none;
        color: inherit;
    }
    
    .navbar-brand {
        font-size: 1.2em;
        font-weight: 600;
    }
    
    .navbar-item {
        font-variant: small-caps;
        margin-left: 30px;
    }
    
    .body-content {
        padding: 5px;
        font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }
    

この時点でアプリを実行できますが、ベーステンプレートをどこにも使用しておらず、コードファイルも変更していないため、結果は前のステップと同じです。残りのセクションを完了して、最終的な効果を確認してください。

コードスニペットを作成する

次のセクションで作成する3つのページは `layout.html` を拡張するため、ベーステンプレートへの適切な参照を持つ新しいテンプレートファイルを初期化するためのコードスニペットを作成すると時間を節約できます。コードスニペットは、単一のソースから一貫したコードを提供するため、既存のコードからコピー&ペーストする際に紛れ込む可能性のあるエラーを回避できます。

  1. VS Code で、ファイル > ユーザー設定 > ユーザースニペットの構成 を選択します。

  2. 表示されるリストで html を選択します。以前にスニペットを作成したことがある場合は、このオプションがリストの 既存のスニペット セクションに "html.json" と表示されることがあります。

  3. VS Code が `html.json` を開いたら、既存の中括弧内に次のエントリを追加します (ここには示されていない説明コメントには、`$0` の行がスニペット挿入後に VS Code がカーソルを置く場所を示すなど、詳細が記述されています)。

    "Flask Tutorial: template extending layout.html": {
        "prefix": "flextlayout",
        "body": [
            "{% extends \"layout.html\" %}",
            "{% block title %}",
            "$0",
            "{% endblock %}",
            "{% block content %}",
            "{% endblock %}"
        ],
    
        "description": "Boilerplate template that extends layout.html"
    },
    
  4. `html.json` ファイルを保存します (⌘S (Windows, Linux Ctrl+S))。

  5. これで、スニペットのプレフィックス (例: `flext`) を入力し始めるといつでも、VS Code は次のセクションで示すように、オートコンプリートの選択肢としてスニペットを提供します。また、スニペットの挿入 コマンドを使用してメニューからスニペットを選択することもできます。

コードスニペット全般に関する詳細については、スニペットの作成 を参照してください。

コードスニペットを使用してページを追加する

コードスニペットが用意できたので、ホーム、アバウト、コンタクトページのテンプレートを素早く作成できます。

  1. `templates` フォルダに `home.html` という名前の新しいファイルを作成し、次に `flext` と入力し始めると、スニペットが補完候補として表示されます。

    Flask tutorial: autocompletion for the flextlayout code snippet

    補完を選択すると、スニペットのコードが表示され、カーソルがスニペットの挿入点に置かれます。

    Flask tutorial: insertion of the flextlayout code snippet

  2. "title" ブロックの挿入ポイントに `Home` と書き、"content" ブロックに `

    Home page for the Visual Studio Code Flask tutorial.

    ` と書いてファイルを保存します。これらの行が、拡張されたページテンプレートの唯一のユニークな部分です。

  3. `templates` フォルダに `about.html` を作成し、スニペットを使って定型マークアップを挿入し、"title" ブロックと "content" ブロックにそれぞれ `About us` と `

    About page for the Visual Studio Code Flask tutorial.

    ` を挿入して、ファイルを保存します。

  4. 前の手順を繰り返して `templates/contact.html` を作成し、2 つのコンテンツブロックに `Contact us` と `

    Contact page for the Visual Studio Code Flask tutorial.

    ` を使用します。

  5. `app.py` に、/about/ と /contact/ ルート用の関数を追加し、それぞれのページテンプレートを参照するようにします。また、`home` 関数を `home.html` テンプレートを使用するように変更します。

    # Replace the existing home function with the one below
    @app.route("/")
    def home():
        return render_template("home.html")
    
    # New functions
    @app.route("/about/")
    def about():
        return render_template("about.html")
    
    @app.route("/contact/")
    def contact():
        return render_template("contact.html")
    

アプリを実行する

すべてのページテンプレートが配置されたので、`app.py` を保存し、アプリを実行し、ブラウザを開いて結果を確認します。ページ間を移動して、ページテンプレートがベーステンプレートを正しく拡張していることを確認してください。

Flask tutorial: app rendering a common nav bar from the base template

注意: 最新の変更が表示されない場合は、キャッシュされたファイルではなく、ページをハードリフレッシュする必要があるかもしれません。

オプションのアクティビティ

以下のセクションでは、Python と Visual Studio Code の作業で役立つ可能性のある追加の手順について説明します。

環境用の requirements.txt ファイルを作成する

アプリのコードをソース管理やその他の手段で共有する場合、仮想環境内のすべてのファイルをコピーするのは意味がありません。なぜなら、受け取った側はいつでも自分で環境を再作成できるからです。

そのため、開発者は通常、仮想環境フォルダーをソース管理から除外し、代わりに `requirements.txt` ファイルを使用してアプリの依存関係を記述します。

ファイルは手動で作成できますが、`pip freeze` コマンドを使用して、アクティブ化された環境にインストールされている正確なライブラリに基づいてファイルを生成することもできます。

  1. Python: インタープリターの選択 コマンドを使用して選択した環境で、ターミナル: 新しいターミナルを作成する コマンド (⌃⇧` (Windows, Linux Ctrl+Shift+`)) を実行して、その環境がアクティブ化されたターミナルを開きます。

  2. ターミナルで `pip freeze > requirements.txt` を実行して、プロジェクトフォルダーに `requirements.txt` ファイルを作成します。

プロジェクトのコピーを受け取った人 (またはビルドサーバー) は、`pip install -r requirements.txt` コマンドを実行するだけで、元の環境のパッケージを再インストールできます。(ただし、受け取った側はまだ独自の仮想環境を作成する必要があります。)

注意: `pip freeze` は、現在使用していないパッケージを含め、現在の環境にインストールされているすべての Python パッケージをリストアップします。このコマンドは、パッケージを正確なバージョン番号でリストアップしますが、将来の柔軟性のために範囲に変換したい場合があるかもしれません。詳細については、pip コマンドドキュメントの Requirements Files を参照してください。

さらなる開発をサポートするためにプロジェクトをリファクタリングする

この Flask チュートリアル全体を通して、すべてのアプリコードは単一の `app.py` ファイルに含まれていました。今後の開発を可能にし、関心事を分離するために、`app.py` の各部分を別々のファイルにリファクタリングすると便利です。

  1. プロジェクトフォルダに、アプリ用のフォルダ (例: `hello_app`) を作成し、そのファイルを `requirements.txt` や、VS Code が設定やデバッグ構成ファイルを保存する `.vscode` フォルダなどの他のプロジェクトレベルのファイルから分離します。

  2. `static` と `templates` フォルダは間違いなくアプリのコードを含んでいるので、`hello_app` に移動します。

  3. `hello_app` フォルダに、ルーティングとビュー関数を含む `views.py` という名前のファイルを作成します。

    from flask import Flask
    from flask import render_template
    from datetime import datetime
    from . import app
    
    @app.route("/")
    def home():
        return render_template("home.html")
    
    @app.route("/about/")
    def about():
        return render_template("about.html")
    
    @app.route("/contact/")
    def contact():
        return render_template("contact.html")
    
    @app.route("/hello/")
    @app.route("/hello/<name>")
    def hello_there(name = None):
        return render_template(
            "hello_there.html",
            name=name,
            date=datetime.now()
        )
    
    @app.route("/api/data")
    def get_data():
        return app.send_static_file("data.json")
    
  4. `hello_app` フォルダに、以下の内容で `__init__.py` というファイルを作成します。

    import flask
    app = flask.Flask(__name__)
    
  5. `hello_app` フォルダに、以下の内容で `webapp.py` というファイルを作成します。

    # Entry point for the application.
    from . import app    # For application discovery by the 'flask' command.
    from . import views  # For import side-effects of setting up routes.
    
  6. デバッグ構成ファイル `launch.json` を開き、`env` プロパティを次のように更新して、スタートアップオブジェクトを指すようにします。

    "env": {
        "FLASK_APP": "hello_app.webapp"
    },
    
  7. プロジェクトのルートにある元の `app.py` ファイルは、その内容が他のアプリファイルに移動されたため、削除します。

  8. プロジェクトの構造は次のようになっているはずです。

    Flask tutorial: modified project structure with separate files and folders for parts of the app

  9. デバッガーでアプリを再度実行して、すべてが機能することを確認してください。VS Code デバッガーの外部でアプリを実行するには、ターミナルから次の手順を使用します。

    1. `FLASK_APP` の環境変数を設定します。Linux と macOS では `export set FLASK_APP=webapp` を、Windows では PowerShell を使用している場合は `$env:FLASK_APP=webapp` を、コマンドプロンプトを使用している場合は `set FLASK_APP=webapp` を使用します。
    2. `hello_app` フォルダに移動し、`python -m flask run` を使用してプログラムを起動します。

コンテナーツール拡張機能を使用して Flask アプリ用のコンテナーを作成する

コンテナー ツール拡張機能 を使用すると、Visual Studio Code からコンテナー化されたアプリケーションを簡単にビルド、管理、デプロイできます。このチュートリアルで開発した Flask アプリ用の Python コンテナーの作成方法に興味がある場合は、コンテナー内の Python チュートリアルをご覧ください。このチュートリアルでは、以下の方法を順を追って説明します。

  • シンプルな Python コンテナーを記述する Dockerfile ファイルを作成する。
  • Flask アプリの機能をビルド、実行、検証する。
  • コンテナーで実行されているアプリをデバッグする。

問題が発生した場合は、Python 拡張機能 Discussions Q&A で回答を検索したり、質問したりできます。

次のステップ

Visual Studio Code での Flask の操作に関するこのウォークスルーを完了したことをお祝いします!

このチュートリアルの完成したコードプロジェクトは GitHub で見つけることができます: python-sample-vscode-flask-tutorial

このチュートリアルではページテンプレートの表面的な部分しか触れていないため、テンプレートに関する詳細については Jinja2 ドキュメントを参照してください。テンプレートデザイナードキュメントには、テンプレート言語に関するすべての詳細が含まれています。また、公式 Flask チュートリアルや Flask 拡張機能のドキュメントも確認するとよいでしょう。

本番ウェブサイトでアプリを試すには、チュートリアルDocker コンテナーを使用して Python アプリを Azure App Service にデプロイするをご覧ください。Azure はまた、VS Code 内からウェブアプリをデプロイできる標準コンテナーApp Service on Linuxも提供しています。

また、Python に関連する VS Code ドキュメントの以下の記事を確認することをお勧めします。