【Flask】クイックスタート

Flask

PythonのWEBフレームワークの一つであるFlaskの公式ドキュメントに沿ってクイックスタートを実践していきます。

Quickstart — Flask Documentation (3.1.x)

前提条件

  • 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正の浮動小数点数を受け付ける
pathstringに加えてスラッシュも受け付ける
uuidUUID文字列を受け付ける

▼「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

コメント

タイトルとURLをコピーしました