個人サイト制作:サイトマップへ戻る

個人サイトへPythonのFlaskを導入する

Flaskは、Pythonというプログラミング言語を使って、ウェブサイトやウェブアプリケーションを作成するためのツールです。
これを「ウェブフレームワーク」と呼びます。
ウェブフレームワークは、ウェブアプリケーションを簡単に作るための土台や便利な機能を提供してくれるものです。
Flaskはとても軽量でシンプルなフレームワークなのですよ。

ちなみに、このボタンは動作検証に使ったシンプルFlaskアプリです。

Flaskのディレクトリ構造

私のサイトは少しだけ変わった感じでFlaskを取り入れているので、基本的な導入方法を見ながらソースコードを書いていきます。

まずはFlaskプロジェクトの一般的なディレクトリ構造を示していきましょう。
この構造はコードを整理しやすくし、プロジェクトを拡張しやすくするためによく使われます。

Flaskの一般的なディレクトリ構造


my_flask_app/
│
├── app/
│ ├── __init__.py
│ ├── routes.py
│ ├── models.py
│ ├── static/
│ │ ├── css/
│ │ ├── js/
│ │ └── images/
│ └── templates/
│ ├── layout.html
│ └── index.html
│
├── venv/
│ └── (仮想環境関連のファイル)
│
├── .gitignore
├── config.py
├── requirements.txt
└── run.py

それぞれのディレクトリやファイルが何を示しているか、説明していきますね。
ちなみに「ディレクトリ」というのは「フォルダ」と解釈して頂いて構いません。

フェードアウト効果の草花写真
my_flask_app/
プロジェクトのルートディレクトリです。
app/
Flaskアプリケーションのメインディレクトリです。
__init__.py
Flaskアプリケーションを初期化するためのファイルです。
Flaskインスタンスを作成し、ルートや設定をここで定義します。
routes.py
アプリケーションのルート(URL)を定義するファイルです。
ルーティングのロジックがここに含まれます。
models.py
データベースのモデルを定義するファイルです。
データベースとやり取りするクラスをここに記述します。
static/
静的ファイル(CSS、JavaScript、画像など)を格納するディレクトリです。
css/
スタイルシートを格納するサブディレクトリです。
js/
JavaScriptファイルを格納するサブディレクトリです。
images/
画像ファイルを格納するサブディレクトリです。
templates/
HTMLテンプレートを格納するディレクトリです。
layout.html
他のテンプレートが継承するベーステンプレートです。
index.html
ホームページのテンプレートです。
venv/
仮想環境を格納するディレクトリです。
仮想環境は、プロジェクトごとにPythonパッケージを管理するためのものです。
.gitignore
Gitに無視させるファイルやディレクトリを記述するファイルです。
仮想環境や一時ファイルなどをここにリストアップします。
config.py
アプリケーションの設定を行うファイルです。
データベースの接続情報やセキュリティキーなどをここに記述します。
requirements.txt
プロジェクトで使用するPythonパッケージをリストアップするファイルです。
これにより、他の開発者が同じ環境を再現できます。
run.py
アプリケーションを実行するためのスクリプトです。
このスクリプトを実行することでFlaskサーバーが起動します。
フェードアウト効果の草花写真

このようなディレクトリ構造を使うことで、Flaskプロジェクトを効率的に管理し、拡張することができます。
この中には私がまだ実装していないものも多数含まれていますが、現段階では動かせるというだけで、後日足していけば良いのですよ。
初めから完璧に完璧に…なんてやってたら大変だからね。
では、次に私のサイトのFlaskフレームワークのディレクトリ構造を見ていきます。

fein's app のFlaskフレームワーク


FEIN-SITES-DEV1/
│  app.yaml          # App Engine の設定ファイル。デプロイと実行環境の設定を定義
│  main.py           # Flask アプリケーションのメインファイル。ルートやサーバーの設定が含まれる
│  README.md         # プロジェクトの概要や使い方を記述する説明ファイル
│  requirements.txt  # アプリケーションが依存する Python パッケージをリストアップするファイル
│
├─static/            # 静的ファイル(CSS, JavaScript, 画像など)を配置するディレクトリ
│   ├─ images/       # 画像ファイルを保存するサブディレクトリ
│   │     example.jpg  # サンプル画像ファイル
│   ├─ css/          # CSS ファイルを保存するサブディレクトリ
│   │     pstyle.css   # プロジェクトのスタイルシート
│   ├─ js/           # JavaScript ファイルを保存するサブディレクトリ
│   │     pscript.js   # プロジェクトのスクリプト
│   └─その他のディレクトリや静的ファイル  # 普通のWebサイトの構造となっている
│
├─templates/         # Flask のテンプレートファイル(HTML ファイル)を配置するディレクトリ
│      top.html      # Flask アプリの動的コンテンツ用 HTML テンプレート
│
│   【上側がFlaskフレームワーク。サーバーサイドスクリプトを活用した動的Webサイトです。】
│   【下側が普通のホームぺージ。フロントエンド3言語による静的Webサイトです。】
│
└─www/               # 静的ウェブサイトのルートディレクトリ。静的な HTML ファイルを配置
    │  index.html      # 静的ウェブサイトのホームページ
    │  .hintrc         # HTMLHint の設定ファイル(コード品質チェック用)
    │  favicon.ico     # ブラウザのタブに表示されるアイコン
    │  manifest.json   # PWA の設定ファイル。アプリのメタデータを定義
    │  robots.txt      # 検索エンジンに対するクローリング設定ファイル
    │  service-worker.js # PWA のサービスワーカー。オフライン対応やキャッシュ管理を実現
    └─その他のディレクトリや静的ファイル  # 普通のWebサイトの構造となっている

私が作っているFlaskフレームワークの構造は、プロジェクトの拡張性とメンテナンス性を優先した設計にしています。
プロジェクトが複雑化しても、できる限り管理しやすいように配慮してるんだよね。

フェードアウト効果の草花写真

Progressive Web App (PWA) の機能が必要なのは、言うまでもなくユーザーエクスペリエンスを向上させるためです。
venv ディレクトリ(仮想環境)はまだ作ってないですね。
小規模プロジェクトで依存関係が少なく、他のプロジェクトと競合しない場合、仮想環境を使わなくても問題は起きないです。
いずれいろいろ整えますが、その折にはまた解説ページ作りますよ。

ここで、ちょっと…このサイト全体の意図みたいなものを説明しておこうかな…

2つの性質が異なるサイトを切り離せる

これは私独特の意図ですよ。
上述したけど、一般的なFlaskフレームワーク構造と、私のサイトのFlaskフレームワーク構造は、ちょーっとだけ異なります。
app.yaml と main.py で全体をコントロールしているのですが、次のように2つのサイトに分かれているんです。

フェードアウト効果の草花写真
  1. index.html はフロントエンド3言語による普通のWebサイト
  2. top.html はFlaskフレームワークによるサーバーサイドスクリプトを活用したWebサイト

特定のページのURLを目指さない限り、私のWebサイトへアクセスすると、まずは 1 の index.html が表示されるよう、設定しています。
2 の top.html が、まるで従属しているような実装のされ方となっています。

これら2つのサイトはそれぞれ templates と www、2つのディレクトリの配下にあります。
CSS と JavaScript は共有していませんが、現状は2つのサイトで同じものを使っています。
Flaskフレームワークを使った普通のWebサイトは、templates ディレクトリに html を格納しておくものなんですよね。─ もちろん例外などいくらでもありますが ─

フェードアウト効果の草花写真

Flaskに限らず、フレームワークというものには流行り廃りがあります。
まず大丈夫だろうけど、Flaskもこれから何十年も使われ続けるとは限らない。
非常に有名なフレームワークなので、終息するにしても、利用者のことを考えてくれるでしょう。
でも未来のことは誰にも分かりません。

そこで、「フロントエンド3言語による普通のWebサイト」と「Flaskフレームワークによるサーバーサイドスクリプトを活用したWebサイト」を簡単に切り離せる仕組みにしたんです。
次の画像なら少しは分かりやすいかも…

Flaskによる構造

FEIN-SITES-DEV1/ が、App Engine のプロジェクトルートディレクトリに当たります。
その配下にFlaskフレームワークがあり、加えて www という静的ウェブサイトのルートディレクトリがある。
何か不測の事態が発生した時には、www ディレクトリだけを切り取り、別の場所へ簡単にデプロイできるのですよ。
HTML・CSS・JavaScript だけで作った普通のホームページであれば、たいていどこのクラウドでも、容易に動かすことができるからです。
Flaskフレームワークのコンテンツにしても、多少の停止はあるでしょうが、移転やリプレイスに耐えられるようにしたいな。

イーロン・マスクがTwitterをおもちゃにしたせいで、多くの人がSNSの移転を検討するようになりました。
そういうのを見ていて、自分が持つコンテンツをいつでも移すことができるというのは、大きな強みになると考えているのです。

静的Webサイトと動的Webサイト

フェードアウト効果の草花写真

静的Webサイトは、主にHTML、CSS、JavaScriptなどの静的ファイルから構成され、サーバーからクライアントにそのまま配信されます。
静的コンテンツはサーバー側で変更されず、クライアント側で表示される際には常に同じ内容になります。
一般的に個人サイトとかホームページなどと呼ばれているのは、このタイプのWebサイトです。
極端な話をすればHTMLだけでも構築できることから、初心者向けの簡単サイトのように言われがちですが、それは誤解と言えます。
シングルページアプリケーション(SPA)というものがあって、まるで動的サイトのような動きを実現することができますよ?

一方、動的Webサイトは、サーバーサイドスクリプトを活用してコンテンツを生成します。
ユーザーの入力やデータベースの情報に応じて、動的にコンテンツが生成されます。
このプロセスにはサーバー側のプログラミング言語やフレームワークが必要で、Flaskはその一例です。
ここで、フレームワークとCGIの違いについて説明しておきましょう。

フレームワークとCGIの違い

CGI(Common Gateway Interface)はウェブサーバーとプログラム(通常はシェルスクリプトやプログラミング言語で書かれたスクリプト)との間のインターフェースです。
1990年代初頭に開発されたもので、ウェブページが動的に生成されるための最初の手段の一つです。
CGIプログラムは、クライアント(ユーザー)がリクエストを送ると、ウェブサーバーがそのリクエストをCGIプログラムに渡し、プログラムが処理を行い、その結果をサーバーに返して表示されます。
一般的にCGIスクリプトはサーバー上で毎回新しくプロセスが生成されるため、パフォーマンスの面で効率が悪いことがあります。
でも決めつけも良くないでしょうね。
私はCGIを古典的手法と教わったけど、何か良い感じのCGIの実装方法があるのかもしれません。

フェードアウト効果の草花写真

一方、フレームワークは特定の用途や機能に特化した一連のツールやライブラリ、規約を提供するソフトウェアです。
フレームワークを使用することで、開発者は共通のタスクを効率的に行うことができ、コーディングの時間や労力を削減できます。
例えば、ウェブ開発用のフレームワークには、Flask(Python)、Django(Python)、Ruby on Rails(Ruby)、Express(Node.js) などがあります。
これらのフレームワークは、ルーティング、セッション管理、テンプレートエンジン、データベース接続など、ウェブアプリケーションを開発する際に頻繁に使われる機能を提供します。

依存関係を管理するrequirements.txt

requirements.txtとは、Pythonのプロジェクトで使用するパッケージ(ライブラリ)をリストアップしたテキストファイルです。
このファイルは、プロジェクトの依存関係を管理し、他の開発者やデプロイ環境で同じパッケージを簡単にインストールできるようにするために使われます。

依存関係を管理するrequirements.txt


Flask==2.3.2
gunicorn==20.1.0

requirements.txtファイルには各パッケージの名前とバージョンが記載されているから、プロジェクトに必要な特定のバージョンのパッケージを確実にインストールすることができますよ。
このファイルを使って依存関係をインストールするには、コマンドラインで以下のコマンドを実行します。


pip install -r requirements.txt

pip install は、Pythonのパッケージ管理ツールである pip を使って、指定したパッケージをインストールするためのコマンドです。
pip は、Pythonパッケージインデックス(PyPI)からパッケージをダウンロードし、インストールするのに使われます。
では、次にこのテキストファイルとApp Engineの関係についてですね。

App Engineとrequirements.txt

requirements.txt をApp Engineに置かないと、Flaskは正常に動作しません。
Flaskアプリケーションが動作するために必要なパッケージや依存関係がインストールされないからです。
このファイルがないと、App Engineはアプリケーションに必要なパッケージを特定できず、結果として必要なライブラリが不足してしまいます。

フェードアウト効果の草花写真

FlaskはPythonのウェブフレームワークであり、他にも様々なライブラリと連携して動作します。
requirements.txt には、そのFlaskアプリケーションが必要とするすべてのライブラリ(およびそのバージョン)がリストアップされています。
例えば、上記のようにFlask本体やGunicornなどのライブラリが含まれます。
このファイルをもとに、App Engineはアプリケーションの環境を正確に構築し、依存関係をインストールします。

App Engineがデプロイ時に requirements.txt を読み込み、指定されたパッケージをインストールすることで、アプリケーションが期待通りに動作する環境が整えられます。
もしこのファイルがなければ、必要なパッケージがインストールされず、アプリケーションが正しく動作しないのですよ。

したがって、この requirements.txt をプロジェクトに含めることは、Flaskアプリケーションが正常に動作するために非常に重要です。
これを「そういう仕様だから」と深く考えずに受け入れることもできますが、実際にはプロジェクトの依存関係を管理するために不可欠なファイルだと理解しておくと良いでしょう。

App EngineとGunicorn

Gunicorn(グニコーン)は、「Green Unicorn」の略で、Pythonで書かれたWSGI(Web Server Gateway Interface)HTTPサーバーです。
主にPythonのウェブフレームワーク(例えばFlaskやDjango)を本番環境で実行するために使用されます。
Gunicornは、WSGIアプリケーションを効率的に処理するために設計されており、並行リクエストを処理するためのマルチプロセスモデルを採用しています。
高いパフォーマンスとスケーラビリティが特徴となっていますね。

フェードアウト効果の草花写真

Google App EngineのPythonランタイムでは、GunicornのようなWSGIサーバーを利用することが推奨されており、公式ドキュメント(App Engine ドキュメント)にもそのように記載されています。
つまり、Google App Engineを利用する際に、FlaskアプリケーションをデプロイするためにGunicornを使用する設定を行う必要があります。
ただし、一部の設定は自動的に行われることも、一応は覚えておくと良いかも。

上述したように、requirements.txt にGunicornを記載する理由は、デプロイ時にApp Engineがプロジェクトの依存関係を正確に把握し、必要なパッケージをインストールするためです。
requirements.txt にGunicornを記載しておくことで、App Engineが依存関係を適切に解決し、Flaskアプリケーションを実行する準備が整います。
公式ドキュメントでは、app.yaml ファイルでGunicornを使用してアプリケーションを起動する方法が説明されています。


runtime: python39
entrypoint: gunicorn -b :$PORT main:app

handlers:
- url: /.*
script: auto

この設定により、App Engineはデプロイ時にGunicornを利用してFlaskアプリケーションを起動します。
手動でGunicornをインストールしなくても、requirements.txt にGunicornを記載することで、必要な依存関係が自動的にインストールされます。

main.pyはFlaskアプリケーションのメインファイル

このサイトのFlaskアプリケーションは、静的コンテンツ(HTML、CSS、画像など)と動的コンテンツ(テンプレートを使用した動的なウェブページ)の両方とも、継続しやすいように構成しています。
上述したように、簡単な構成から始めて、後から段階的に諸機能を実装しやすいようにね。
ひとまず、このソースコードの動作を簡単に説明しておきます。

フェードアウト効果の草花写真
ホームページを表示
/にアクセスすると、wwwディレクトリのindex.htmlが表示されます。
静的ファイルを提供
任意のファイルパス(例えば、/styles.css)にアクセスすると、wwwディレクトリ内の対応するファイルが表示されます。
動的コンテンツを表示
/topにアクセスすると、templatesディレクトリのtop.htmlが表示されます。

では、実際のソースコードを見ていきましょう。

Flaskのメインファイルとなるmain.py


import os
from flask import Flask, render_template, send_from_directory

app = Flask(__name__)

# ルート `/` で `index.html` をレンダリング
@app.route('/')
def serve_static_index():
    return send_from_directory('www', 'index.html')

# 静的ファイルを提供
@app.route('/<path:filename>')
def serve_static_files(filename):
    return send_from_directory('www', filename)

# Flask の動的コンテンツ
@app.route('/top')
def serve_flask_content():
    return render_template('top.html')

if __name__ == '__main__':
    debug_mode = os.getenv('FLASK_DEBUG', 'False') == 'True'
    app.run(debug=debug_mode)

上述したように、このFlaskアプリにしても、可能な限りリプレイスがやりやすいようにしていきたいものです。
今後によりますが、このmain.pyは極力単純なままにしておき、サーバーサイドスクリプトを使ったいろんな動作はソースコードを分けていくことで実装をしていく予定です。

1. インポートとアプリケーションの初期化


import os
from flask import Flask, render_template, send_from_directory

app = Flask(__name__)

import
Pythonでは、他のモジュールやライブラリを使用するためにimportキーワードを使います。
ここでは、osFlaskrender_templatesend_from_directoryをインポートしています。
Flask(__name__)
Flaskアプリケーションを初期化します。
__name__は現在のモジュール名を示します。

2. ルート / で index.html を提供


@app.route('/')
def serve_static_index():
return send_from_directory('www', 'index.html')

@app.route('/')
ルート(エンドポイント)を定義します。
'/'はウェブサイトのホームページ(トップページ)を意味します。
send_from_directory
指定されたディレクトリからファイルを返します。
ここでは、wwwディレクトリのindex.htmlファイルを返します。

3. 静的ファイルの提供


@app.route('/<path:filename>')
def serve_static_files(filename):
return send_from_directory('www', filename)

@app.route('/<path:filename>')
任意のファイルパスを受け取るルートを定義します。
<path:filename>は動的な部分で、URLに含まれるファイル名がここに入ります。
send_from_directory('www', filename')
指定されたファイル名を持つファイルをwwwディレクトリから返します。

4. Flask の動的コンテンツの提供


@app.route('/top')
def serve_flask_content():
return render_template('top.html')

@app.route('/top')
/topというURLパスに対応するルートを定義します。
render_template('top.html')
templatesディレクトリ内のtop.htmlテンプレートファイルをレンダリングして返します。
テンプレートを使用することで、動的なコンテンツを生成できます。

5. アプリケーションの実行


if __name__ == '__main__':
debug_mode = os.getenv('FLASK_DEBUG', 'False') == 'True'
app.run(debug=debug_mode)

if __name__ == '__main__':
このスクリプトが直接実行されている場合にのみ、以下のコードを実行します。
os.getenv('FLASK_DEBUG', 'False') == 'True'
環境変数FLASK_DEBUGTrueに設定されている場合にデバッグモードを有効にします。
app.run(debug=debug_mode)
Flaskアプリケーションを実行します。
debug=debug_modeでデバッグモードを設定します。

ここまで、依存関係を管理するrequirements.txtと、Flaskアプリケーションのメインファイルmain.pyを見てきました。
次はApp Engineのyamlについてです。

Flaskアプリケーションのapp.yaml

このサイトのapp.yamlは、一言で表現すると「Google App Engine 上で動作する Python Flask アプリケーションのデプロイと実行環境を設定するための、静的ファイルのルーティングと動的コンテンツの処理を自動化する設定ファイル」となります。

フェードアウト効果の草花写真

このようになっているんですよね。
実際のコードは次のようになります。

Flaskを構築するためのapp.yaml


runtime: python312
instance_class: F1
env: standard

automatic_scaling:
  min_idle_instances: 0
  max_idle_instances: 1
  max_concurrent_requests: 200

env_variables:
  FLASK_DEBUG: 'False'

handlers:
- url: /static
  static_dir: static

- url: /top
  script: auto

- url: /favicon.ico
  static_files: www/favicon.ico
  upload: www/favicon.ico

- url: /
  static_files: www/index.html
  upload: www/index.html

- url: /(.*)
  static_files: www/\1
  upload: www/(.*)
  http_headers:
    Cache-Control: "public, max-age=3600"

entrypoint: gunicorn -b :$PORT main:app

注意して頂きたいのは、このソースコードはFlaskアプリの稼働開始時を想定しているという点です。
分かりやすく言うと、スペックを最低限に抑えている状態なので、トラフィックが上がってきたら変更するようにしてください。
各セクションの説明をしていきます。

フェードアウト効果の草花写真

runtime: python312

Python 3.12 を使用することを指定しています。
このアプリケーションはPythonのバージョン3.12で動作します。

instance_class: F1

アプリケーションが動作するインスタンスのクラスを指定しています。
F1は標準的なクラスで、主に小規模アプリに使用されます。

env: standard

実行環境を「標準(Standard)」として指定しています。
これは標準環境でアプリケーションを実行することを意味します。

automatic_scaling

自動スケーリングの設定を定義しています。
つまり、アプリケーションの負荷に応じて自動的にインスタンスの数を調整します。

min_idle_instances: 0
アイドル状態(待機状態)で最低0個のインスタンスを保持します。
max_idle_instances: 1
アイドル状態で最大1個のインスタンスを保持します。
max_concurrent_requests: 200
1つのインスタンスが同時に処理できる最大リクエスト数は200です。
フェードアウト効果の草花写真

注意して欲しいのはここなんですよ。
上記の設定では、例えば私のアプリケーション規模だと厳しいのです。
アプリケーションが負荷に耐えられず、リクエストの処理に遅延が生じたり、エラーが発生する可能性があります。
とりあえず max_idle_instances は増やしていますが、Cloud Load Balancing を使うか考えているところです。

env_variables

環境変数の設定を行います。

FLASK_DEBUG: 'False'
Flaskのデバッグモードを無効(False)に設定します。
これは本番環境でデバッグ情報を表示しないようにするためです。

handlers

URLごとに異なる動作を定義するハンドラー設定です。

url: /static
/static というURLにアクセスしたとき、static ディレクトリ内の静的ファイルを提供します。
url: /top
/top というURLにアクセスしたとき、自動的にスクリプトを実行します(auto はFlaskの設定に基づいています)。
url: /favicon.ico
/favicon.ico というURLにアクセスしたとき、www/favicon.ico ファイルを提供します。
url: /
ルートURL(/)にアクセスしたとき、www/index.html ファイルを提供します。
url: /(.*)
その他のすべてのURLに対して、www ディレクトリ内の対応するファイルを提供します。
http_headers
キャッシュ制御の設定を行います。
ここでは、Cache-Control ヘッダーを設定し、公開キャッシュを最大1時間(3600秒)保持します。
フェードアウト効果の草花写真

entrypoint

アプリケーションのエントリーポイントを指定しています。

gunicorn -b :$PORT main:app
GunicornというHTTPサーバーを使用してFlaskアプリケーションを実行します。
$PORTはApp Engineが提供するポート番号で、main:appmain.pyファイル内のFlaskアプリケーションを指します。

この設定ファイルにより、アプリケーションがどのように動作し、どのようにリクエストに応答するかを指定しています。
簡単に言えば、このファイルがアプリケーションの「動作マニュアル」みたいなものです。

上述したapp.yamlで普通とは違う部分があるとすれば、次のハンドラー設定でしょうか。


  - url: /
  static_files: www/index.html
  upload: www/index.html

  - url: /(.*)
  static_files: www/\1
  upload: www/(.*)
  http_headers:
  Cache-Control: "public, max-age=3600"

この設定により、wwwディレクトリ内のファイルが直接提供されるようになっています。

Flaskのurl_for関数

Flaskの url_for は、Flaskが提供する関数で、ビュー関数(ルート)や静的ファイルに対応するURLを動的に生成するために使用されます。
これでアプリケーションのルーティングが変更された場合でも、テンプレート内のリンクを自動で更新でき、一貫性とメンテナンス性が向上します。

url_forの基本的な使い方

1. ビュー関数へのURL生成

例えば、次のようなFlaskアプリケーションがあるとしましょう。


# main.py
from flask import Flask

app = Flask(__name__)

@app.route('/hello')
def hello():
return 'こんにちは、世界!'

テンプレート内で、このhello関数へのリンクを作成するには、次のようにします。


<!-- テンプレートファイル(例:templates/index.html) -->
  <a href="{{ url_for('hello') }}">挨拶ページへ</a>

url_for('hello') は、自動的に /hello というURLを生成します。

2. 静的ファイルへのURL生成

Flaskはデフォルトで static ディレクトリ内のファイルを静的ファイルとして提供します。
静的ファイルへのリンクを作成するには、次のようにします。


<img src="{{ url_for('static', filename='images/logo.png') }}" alt="ロゴ">

この例では、static/images/logo.png にある画像ファイルへのURLを生成します。

url_forを使うメリット

ルーティングの一元管理
ルートのパスを変更しても、テンプレート内のリンクを修正する必要がありません。
エラー防止
ハードコードされたURLを避けることで、タイプミスやパスの変更によるエラーを防ぎます。
動的なURL生成
引数を渡すことで、パラメータ付きのURLを生成できます。

@app.route('/user/<username>')
def profile(username):
return f'{username}さんのプロフィール'


<a href="{{ url_for('profile', username='fein') }}">feinさんのプロフィールを見る</a>

このfein's app独特の設定

上述した内容と少し重複しますが、app.yamlまで説明を終えたことにより、追記できることがあります。
このfein's appのプロジェクト構造では、wwwディレクトリ内のファイルはFlaskではなく、app.yamlの設定によって直接サーバーから提供されています。
このため、url_forを使用しても、wwwディレクトリ内のファイルへのURLを正しく生成できないのです。

フェードアウト効果の草花写真

しかし、これはデメリットではありません。
wwwディレクトリ内にあるHTMLコードをそのまま持って来れるのですよ。
本格的にFlaskを活かしたアプリケーションを構築しつつも、静的ウェブサイトにある資源を活かせるのです。
真新しくFlaskアプリを作り込んでいくのは大変でしょ?
いつでも動的コンテンツを実装できるよう環境を整えつつ、静的ウェブサイトから使えるものを流用できるようにしたわけです。

よって、wwwディレクトリ内のファイルへのリンクは、これまで通りハードコードされたパスが使用されています。─ 少なくともこのページにおいては ─
次のような、普通の a href タグの書き方ができるということですね。


<a href="/index.html">ホーム</a>

VS Codeのtasks.json

tasks.json は、Visual Studio Code(VS Code)で使用するタスクを定義する設定ファイルです。
このファイルを使うと、開発中によく行う作業(コマンドの実行やビルドなど)を簡単に自動化できます。
複雑なコマンドを毎回手動で入力する必要がなくなるんだよね。

次にあるソースコードは、Google Cloud SDK ShellやFlaskのローカル起動をワンタッチでできるようにしたものです。

作業を省力化するtasks.json


{
 "version": "2.0.0",
 "tasks": [
  {
   "label": "Google Cloud SDK Shell を起動",
   "type": "shell",
   "command": "cmd",
   "args": [
    "/c",
    "\"\"C:\\Users\\ユーザー名\\AppData\\Local\\Google\\Cloud SDK\\cloud_env.bat\" && cd \"C:\\Users\\ユーザー名\\OneDrive\\_fein\\google cloud\\fein-sites-dev1\" && cmd\""
   ],
   "problemMatcher": [],
   "group": {
    "kind": "build",
    "isDefault": true
   }
  },
  {
   "label": "Flaskアプリを起動",
   "type": "shell",
   "command": "cmd",
   "args": [
    "/C",
    "\"cd C:\\Users\\ユーザー名\\OneDrive\\_fein\\google cloud\\fein-sites-dev1 && set FLASK_APP=main.py && set FLASK_ENV=development && set FLASK_DEBUG=1 && flask run\""
   ],
   "isBackground": true,
   "problemMatcher": [
    {
     "pattern": [
      {
       "regexp": ".",
       "file": 1,
       "location": 2,
       "message": 3
      }
     ],
     "background": {
      "activeOnStart": true,
      "beginsPattern": ".",
      "endsPattern": "."
     }
    }
   ],
   "presentation": {
    "echo": true,
    "reveal": "always",
    "focus": true,
    "panel": "dedicated"
   }
  },
  {
   "label": "ブラウザを開く",
   "type": "shell",
   "command": "cmd",
   "args": [
    "/C",
    "timeout /T 5 & start msedge \"http://127.0.0.1:5000/\""
   ],
   "presentation": {
    "echo": false,
    "reveal": "never",
    "focus": false,
    "panel": "shared"
   }
  },
  {
   "label": "Flaskアプリ起動とブラウザを開く",
   "dependsOn": [
    "Flaskアプリを起動",
    "ブラウザを開く"
   ],
   "problemMatcher": [],
   "presentation": {
    "echo": false,
    "reveal": "never",
    "focus": false,
    "panel": "shared"
   }
  }
 ]
}

この tasks.json には4つのタスクが定義されています。

  1. Google Cloud SDK Shell を起動
  2. Flaskアプリを起動
  3. ブラウザを開く
  4. Flaskアプリ起動とブラウザを開く

では、各タスクが何をしているのか、一つずつ詳しく見ていきましょう。

Google Cloud SDK Shell を起動
ラベル(label)
Google Cloud SDK Shell を起動
タイプ(type)
"shell"(シェルコマンドを実行するタイプ)
コマンド(command)
"cmd"(Windowsのコマンドプロンプトを起動)
引数(args)
コマンドに渡すパラメータ(詳細は後述)

このタスクは、Google Cloudのコマンドラインツールを使える状態にし、指定したプロジェクトのフォルダに移動します。
argsの内容は次の通りです。


[
"/c",
"\"\"C:\\Users\\ユーザー名\\AppData\\Local\\Google\\Cloud SDK\\cloud_env.bat\" && cd
\"C:\\Users\\ユーザー名\\OneDrive\\_fein\\google cloud\\fein-sites-dev1\" && cmd\""
]

/c は、コマンドプロンプトに指定したコマンドを実行させ、その後に終了させるオプションです。
実行されるコマンドの流れは次のようになります。

1. Google Cloud SDKの環境を設定
"C:\\Users\\ユーザー名\\AppData\\Local\\Google\\Cloud SDK\\cloud_env.bat"を実行します。これにより、Google Cloud SDKが使えるようになります。
2. プロジェクトのフォルダに移動
cd "C:\\Users\\ユーザー名\\OneDrive\\_fein\\google cloud\\fein-sites-dev1"で、あなたのプロジェクトのフォルダに移動します。
3. 新しいコマンドプロンプトを開く
cmdを実行して、新しくコマンドプロンプトを開きます。

このタスクを実行すると、Google Cloud SDKの設定が済んだ状態で、VS Codeのプロジェクトフォルダに移動したコマンドプロンプトが開きます。
すぐにGoogle Cloud関連のコマンドを使える状態になりますよ。

Flaskアプリを起動
ラベル(label)
Flaskアプリを起動
タイプ(type)
"shell"
コマンド(command)
"cmd"
引数(args)
コマンドに渡すパラメータ(詳細は後述)
バックグラウンド実行(isBackground)
true(バックグラウンドで実行する設定)

このタスクはFlaskを起動します。
argsの内容は次の通りです。


[
"/C",
"\"cd C:\\Users\\ユーザー名\\OneDrive\\_fein\\google cloud\\fein-sites-dev1 && set FLASK_APP=main.py && set
FLASK_ENV=development && set FLASK_DEBUG=1 && flask run\""
]

/C は、コマンドプロンプトに指定したコマンドを実行させ、その後に終了させるオプションです。
実行されるコマンドの流れは次のようになります。

フェードアウト効果の草花写真
1. プロジェクトのフォルダに移動
cd C:\\Users\\ユーザー名\\OneDrive\\_fein\\google cloud\\fein-sites-dev1
2. 環境変数の設定
set FLASK_APP=main.py
Flaskにどのファイルを実行するか指定します。main.pyがアプリの本体です。
set FLASK_ENV=development
開発モードに設定します。デバッグ情報が見られます。
set FLASK_DEBUG=1
デバッグモードを有効にします。エラーが出たときに詳しい情報が表示されます。
3. Flaskアプリを起動
flask runでアプリを実行し、ウェブサーバーを立ち上げます。
バックグラウンド実行
isBackground: trueにより、タスクはバックグラウンドで動作します。これで他の作業がしやすくなります。

デバッグモードは開発中は便利ですが、本番環境(みんなが使う環境)ではオフにするのが一般的です。
このタスクを実行すると、Flaskアプリケーションが起動し、ウェブブラウザからアクセスできるようになります。

ブラウザを開く
ラベル(label)
ブラウザを開く
タイプ(type)
"shell"
コマンド(command)
"cmd"
引数(args)
コマンドに渡すパラメータ(詳細は後述)

このタスクは、ブラウザを自動的に開き、起動したFlaskアプリにアクセスします。
argsの内容は次の通りです。


[
"/C",
"timeout /T 5 & start msedge \"http://127.0.0.1:5000/\""
]

/C は、コマンドプロンプトに指定したコマンドを実行させ、その後に終了させるオプションです。
実行されるコマンドの流れは次のようになります。

フェードアウト効果の草花写真
timeout /T 5
5秒間待機します。これは、Flaskアプリが起動するのを待つためです。
&
コマンドを続けて実行するための記号です。
start msedge "http://127.0.0.1:5000/"
Microsoft Edgeを開き、http://127.0.0.1:5000/にアクセスします。
msedge
Microsoft Edgeのことです。他のブラウザを使いたい場合は、chromefirefoxに変更できます。
http://127.0.0.1:5000/
ローカルホスト(自分のコンピュータ)で動いているFlaskアプリのアドレスです。

アプリの起動が遅い場合、待機時間(/T 55)を増やすと良いです。
このタスクを実行すると、自動的にブラウザが開き、作成中のFlaskアプリにアクセスします。

Flaskアプリ起動とブラウザを開く
ラベル(label)
Flaskアプリ起動とブラウザを開く
依存タスク(dependsOn)
["Flaskアプリを起動", "ブラウザを開く"]

このタスクは、先ほどの「Flaskアプリを起動」と「ブラウザを開く」の2つのタスクを順番に実行します。
dependsOn のタスクは他のタスクに依存しています。
つまり、指定したタスクを自動的に実行します。
Flaskアプリを起動し、ブラウザを開きます。
プレゼンテーション設定(presentation)は、次のようになります。


{
"echo": false,
"reveal": "never",
"focus": false,
"panel": "shared"
}

echo: false
実行するコマンドを表示しません。
reveal: "never"
ターミナルを自動的に表示しません。
focus: false
ターミナルにフォーカスしません。
panel: "shared"
ターミナルパネルを共有します。他のタスクと同じパネルを使います。

私はこうやって tasks.json を書いているけど、やりやすい型は人によって違うでしょうね。
あとは Ctrl + Shift + P で「タスクの実行」を選択し、表示されたタスクを選ぶだけ。
「Flaskアプリ起動とブラウザを開く」を選べば、一度にアプリの起動とブラウザのオープンができます。

もしくは、次のように run_flask.bat みたいな名前のbatファイルを作ってもいいでしょう。


@echo off
cd "C:\Users\ユーザー名\OneDrive\_fein\google cloud\fein-sites-dev1"
set FLASK_APP=main.py
set FLASK_ENV=development
set FLASK_DEBUG=1
flask run

このバッチファイルをダブルクリックして実行してもワンタッチでやれます。
私はVS Code内部にいたいから、ターミナルパネルを使っていますね。

このページをFlaskフレームワークのトップページにします


サイトマップ

全ページをリスト化したサイトマップも用意していますが、けっこうなページ数があります。
下記の「カテゴリー分けサイトマップ」のほうが使いやすいでしょう。

アナザーエデン関連ページ・サイトマップ

アナザーエデンの強敵戦やストーリーコンテンツのリスト、お勧めバッジなどを掲載したコーナーです。
期間限定のない普通のRPGですので、初心者でも安心して続けていけるゲームとなっています。
もっとも重要なグラスタについては、場所別に網羅した表があります。

個人サイトのホスティングとコンテンツ作成

個人でウェブサイトを作るにはどうすればいいか。
HTML・CSS・JavaScriptの書き方はもちろん、無料かつ広告なしでホームページを作る方法を掲載したコーナーです。
Webデザインやレイアウトについても書いてあります。

魚釣りなどアウトドアのエリア

ゲームとパソコンだけじゃなく、アウトドアも趣味なんです。
このコーナーでは魚釣りの記録とか、魚料理のレシピ、はたまたサイクリングなどなど。
アウトドアに関連するコンテンツが詰め込まれています。