PythonのWEBフレームワークの一つであるFlaskの公式ドキュメントに沿ってクイックスタートを実践していきます。
前提条件
- Flaskインストール済
Flaskのインストールについては次の記事をご覧ください。
最小のアプリケーション
Flaskの最小のアプリケーションコードは次のようになります。
「hello.py」のようなファイルに保存しておきます。
※「flask.py」のような名前はFlaskと競合するので避けましょう。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
それで、そのコードは何をしているのでしょうか?
1.まず、Flask クラスをインポートしました。このクラスのインスタンスが WSGI アプリケーションになります。
2.次に、このクラスのインスタンスを作成します。最初の引数は、アプリケーションのモジュールまたはパッケージの名前です。 __name__ は、ほとんどの場合に適したこのための便利なショートカットです。これは、Flask がテンプレートや静的ファイルなどのリソースをどこで探せばよいかを知るために必要です。
3.次に、route() デコレータを使用して、どの URL が関数をトリガーするかを Flask に指示します。
4.この関数は、ユーザーのブラウザに表示したいメッセージを返します。デフォルトのコンテンツ タイプは HTML であるため、文字列内の HTML はブラウザによってレンダリングされます。
アプリケーションを実行するには、flask コマンドまたは python -m flask を使用します。 –app オプションを使用して、アプリケーションの場所を Flask に伝える必要があります。
flask --app hello run

WEBブラウザで http://127.0.0.1:5000/ にアクセスしてみます。

「Hello, World!」が表示されました。
アプリケーション検出の動作
ショートカットとして、ファイルの名前が app.py または wsgi.py の場合は、–app を使用する必要はありません。詳細については、「コマンド ライン インターフェイス」を参照してください。
外部から見えるサーバー
サーバーを実行すると、サーバーには自分のコンピュータからのみアクセスでき、ネットワーク内の他のコンピュータからはアクセスできないことがわかります。デバッグ モードでは、アプリケーションのユーザーがコンピュータ上で任意の Python コードを実行できるため、これがデフォルトです。デバッガを無効にしている場合、またはネットワーク上のユーザーを信頼している場合は、コマンド ラインに –host=0.0.0.0 を追加するだけでサーバーを公開できます。
$ flask run –host=0.0.0.0
これにより、オペレーティング システムがすべてのパブリック IP をリッスンするように指示されます。
デバグモード
flask run コマンドは、開発サーバーを起動するだけではありません。デバッグ モードを有効にすると、コードが変更された場合にサーバーが自動的にリロードされ、リクエスト中にエラーが発生した場合にブラウザに対話型デバッガが表示されます。
警告
デバッガを使用すると、ブラウザから任意の Python コードを実行できます。 PIN によって保護されていますが、依然として重大なセキュリティ リスクを伴います。開発サーバーまたはデバッガを運用環境で実行しないでください。
デバグモードを有効にするには「–debug」オプションを使用します。
flask --app hello run --debug

▼WEBブラウザにアクセスした際にコードのエラーがある場合

HTMLエスケープ
HTML (Flask のデフォルトの応答タイプ) を返す場合、出力内でレンダリングされるユーザー指定の値はすべて、インジェクション攻撃から保護するためにエスケープする必要があります。後で紹介する Jinja でレンダリングされた HTML テンプレートは、これを自動的に行います。
ここに示されているescape()は手動で使用できます。簡潔にするためにほとんどの例では省略されていますが、信頼できないデータをどのように使用しているかに常に注意する必要があります。
▼「hello.py」:escape()を使わないケース
from flask import Flask
from markupsafe import escape
app = Flask(__name__)
name = "<h1>Hoge</h1><script>alert('hello');</script>"
@app.route("/")
def hello():
return f"Hello, {name}!"
▼http://127.0.0.1:5000/ にアクセスした場合

HTMLタグとJavascriptのインジェクションが有効になっています。
▼「hello.py」:escape()を使うケース
from flask import Flask
from markupsafe import escape
app = Flask(__name__)
name = "<h1>Hoge</h1><script>alert('hello');</script>"
@app.route("/")
def hello():
return f"Hello, {escape(name)}!"
▼http://127.0.0.1:5000/hoge%20fuga にアクセスした場合

※出力されたHTML

HTMLがエスケープされ、Javascriptのインジェクションも無効になっています。
ルーティング
最新の Web アプリケーションは、ユーザーを支援するために意味のある URL を使用します。ユーザーが覚えていて、ページに直接アクセスするために使用できる意味のある URL がページで使用されている場合、ユーザーはそのページを気に入って戻ってくる可能性が高くなります。
関数を URL にバインドするには、route() デコレータを使用します。
▼「hello.py」
from flask import Flask
from markupsafe import escape
app = Flask(__name__)
@app.route('/')
def index():
return 'Index Page'
@app.route('/hello')
def hello():
return 'Hello, World'
▼http://127.0.0.1:5000/ にアクセスした場合

▼http://127.0.0.1:5000/hello にアクセスした場合

ルーティングの変数ルール
セクションに <variable_name> をマークすることで、URL に変数セクションを追加できます。次に、関数はキーワード引数として <variable_name> を受け取ります。オプションで、コンバーターを使用して、 <converter:variable_name> のように引数の型を指定できます。
コンバーターの種類
| コンバーター | 説明 |
|---|---|
| string | (デフォルト)スラッシュ以外のテキストを受け付ける |
| int | 正の整数を受け付ける |
| float | 正の浮動小数点数を受け付ける |
| path | stringに加えてスラッシュも受け付ける |
| uuid | UUID文字列を受け付ける |
▼「hello.py」
from flask import Flask
from markupsafe import escape
app = Flask(__name__)
@app.route('/user/<username>')
def show_user_profile(username):
# show the user profile for that user
return f'User {escape(username)}'
@app.route('/post/<int:post_id>')
def show_post(post_id):
# show the post with the given id, the id is an integer
return f'Post {post_id}'
@app.route('/path/<path:subpath>')
def show_subpath(subpath):
# show the subpath after /path/
return f'Subpath {escape(subpath)}'
▼http://127.0.0.1:5000/user/hoge にアクセスした場合

▼http://127.0.0.1:5000/post/hoge にアクセスした場合

▼http://127.0.0.1:5000/post/1 にアクセスした場合

▼http://127.0.0.1:5000/path/hoge/fuga にアクセスした場合

ユニークURLとリダイレクトの振る舞い
次の 2 つのルールは、末尾のスラッシュの使用方法が異なります。
@app.route('/projects/')
def projects():
return 'The project page'
@app.route('/about')
def about():
return 'The about page'
プロジェクト エンドポイントの正規 URL には末尾にスラッシュが付いています。ファイル システムのフォルダーに似ています。末尾のスラッシュ (/projects) のない URL にアクセスすると、Flask は末尾のスラッシュ (/projects/) のある正規の URL にリダイレクトします。
about エンドポイントの正規 URL には末尾のスラッシュがありません。ファイルのパス名に似ています。末尾にスラッシュ (/about/) が付いている URL にアクセスすると、404「Not Found」エラーが発生します。これにより、これらのリソースの URL を一意に保つことができ、検索エンジンが同じページに 2 回インデックスを作成することを回避できます。
URL構築
特定の関数への URL を構築するには、url_for() 関数を使用します。最初の引数として関数の名前を受け入れ、それぞれが URL ルールの可変部分に対応する任意の数のキーワード引数を受け入れます。不明な変数部分がクエリ パラメータとして URL に追加されます。
URL をテンプレートにハードコーディングするのではなく、URL 逆関数 url_for() を使用して URL を構築するのはなぜでしょうか。
1.多くの場合、URL をハードコーディングするよりも、逆変換の方がわかりやすいです。
2.ハードコーディングされた URL を手動で変更することを忘れずに、一度に URL を変更できます。
3.URL 構築では、特殊文字のエスケープが透過的に処理されます。
4.生成されるパスは常に絶対パスであり、ブラウザーでの相対パスの予期しない動作を回避します。
5.アプリケーションが URL ルートの外側、たとえば / ではなく /myapplication に配置されている場合、url_for() はそれを適切に処理します。
●書式: url_for(関数名, [変数名1=値1, 変数名2=値2, …])
●戻り値:指定関数に該当する絶対URLを返す。
●「hello.py」での使用例:
from flask import Flask
from markupsafe import escape
from flask import url_for
app = Flask(__name__)
@app.route('/')
def index():
return 'index'
@app.route('/login')
def login():
return 'login'
@app.route('/user/<username>')
def profile(username):
return f'{username}\'s profile'
with app.test_request_context():
print(url_for('index'))
print(url_for('login'))
print(url_for('login', next='/'))
print(url_for('profile', username='John Doe', detail=True))
●上記コード保存直後のターミナルの出力

たとえば、ここでは test_request_context() メソッドを使用して url_for() を試します。 test_request_context() は、Python シェルを使用しているときでも、あたかもリクエストを処理しているかのように動作するように Flask に指示します。
今回は以上です。次回はこの続きを予定しています。
- 0
- 0
- 0
- 0


コメント