flaskもよく忘れるのでチートシートを作ってみました
一番基本のhttp
webアプリのサーバーがやっていることを超ざっくりいうとこんな感じです

flaskなどたいていのフレームワークは①②④をやってくれるのでプログラマが書くのはおもに③になります
基本のコード
from flask import Flask #Flaskをインポート
app = Flask(__name__) #インスタンス作成
#ルーティングはデコレータがやってくれる
@app.route('/aaa', methods=['GET']) #/aaaにgetメソッドでアクセスされたとき以下実行
def aaa(): #中身の関数
return "<h1>hello</h1>" #helloを太字で出力
if __name__ == "__main__": #いつものやつw
app.run(debug=True) #デバッグオンで動かすと、コード変更時に楽なので
起動方法
サーバー起動 python app.py
ブラウザからは http://127.0.0.1:5000/aaa でアクセス
テンプレートを使う(jinja2)
htmlファイルは必ずtemplatesフォルダに格納すること
from flask import Flask, render_template #新たなメソッドの導入
app = Flask(__name__)
@app.route('/aaa', methods=['GET'])
def aaa():
return render_template("bbb.html") #render_templateでbbb.htmlを呼び出す
if __name__ == "__main__":
app.run(debug=True)
<html><head><meta charset="utf-8"></title></style></head>
<body>
<h3>world</h3>
</body></html>
テンプレートにパラメータを渡す
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/aaa', methods=['GET'])
def aaa():
return render_template("ccc.html",x=" wide",y=" web ")#ここで引数を渡している
if __name__ == "__main__":
app.run(debug=True)
うけとった引数を表示するには {{引数}} のように書く
<html><head><meta charset="utf-8"></title></style></head>
<body>
<h3>world{{x}}{{y}}</h3>
</body></html>
htmlからformでデータを送信(GET)
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/', methods=['GET'])#フォームの送信
def index():
return render_template('form.html')
@app.route('/ggg', methods=['GET'])#結果の処理
def index2():
name = request.args.get('name')
return render_template('form2.html', name=name)
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html>
<head>
<title>Flask Form GET</title>
</head>
<body>
<form action="/ggg" method="get">
<input type="text" name="name">
<input type="submit" value="Submit">
</form>
</body>
</html>
結果を表示するためのhtml
</head>
<body>
<h2>{{name}}</h2>
</body>
</html>
htmlからformでデータを送信(POST)
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/', methods=['GET'])#フォームの送信
def index():
return render_template('formP.html')
#結果の処理部分
@app.route('/ggg', methods=['POST']) #POSTになっている点に注目
def index2():
name = request.form.get('name')
return render_template('form2.html', name=name)
if __name__ == '__main__':
app.run(debug=True)
フォーム(method="post"になっている)
<!DOCTYPE html>
<html>
<head>
<title>Flask Form GET</title>
</head>
<body>
<form action="/ggg" method="post">
<input type="text" name="name">
<input type="submit" value="Submit">
</form>
</body>
</html>
結果表示のためのhtml
</head>
<body>
<h2>{{name}}</h2>
</body>
</html>
テンプレート(jinja)に辞書を渡してキーとバリューを表示
前提 dicに辞書が入っている、pythonからは render_template(aaa.html result=dic)とする
<ul>
{% for key, value in results.items() %}
<li>{{ key }}: {{ value }}</li>
{% endfor %}
</ul>
リダイレクト
from flask import Flask, redirect, url_for
リダイレクトの実装
以下の例は、/old にアクセスすると /new にリダイレクトされます
@app.route('/old')
def old_endpoint():
return redirect(url_for('new_endpoint'))
@app.route('/new')
def new_endpoint():
return "This is the new endpoint!"
リダイレクトは意外とわかりにくいので細かく解説します。
これのフローイメージは以下のとおりです
①リクエスト(/old): クライアントが /old エンドポイントにアクセスを試みます。
②リダイレクト命令: サーバーはクライアントに対して、新しいエンドポイント /new にリダイレクトするよう命じます。これは通常、HTTPステータスコード302(一時的リダイレクト)または301(永続的リダイレクト)で行われます。
③リクエスト(/new): クライアントはサーバーからのリダイレクト指示に従い、自動的に /new エンドポイントに新たなリクエストを送信します。
④レスポンス文字列: /new エンドポイントからの応答として「This is the new endpoint!」という文字列がクライアントに送られます。
サーバー側のコードを再掲します。図と対比させてみてください。
@app.route('/old') #①でココに飛んでくる
def old_endpoint():
return redirect(url_for('new_endpoint')) #②のリダイレクト命令
@app.route('/new') #③でここに飛んでくる
def new_endpoint():
return "This is the new endpoint!" #④のレスポンス文字列送信
そもそもリダイレクトとは?
たとえばサイトを引っ越したり、ページ名を変更したり(/about→/company)、ログインしていないのでログインページに誘導したり、モバイルユーザーをモバイル用のページへ誘導といった目的で使います、もしリダイレクトがなければ、古いURLにアクセスしたユーザーがエラー画面や空白ページを見てしまうことになります。
このように ユーザーを正しい場所に誘導するために存在するのがリダイレクトです。
その方法としてHTTPステータスコードの 301や302が使われます。
ステータスコード
ステータスコードは3桁の数字で、サーバーからの返事(成功、失敗、転送など)です。
最初の1桁でおおまかな「カテゴリ」が決まります。
1xx リクエスト継続中(ほぼ使わない)
2xx 処理に成功
3xx リダイレクト
4xx エラー
5xx サーバーエラー
200番代とか400番代は見たことがあるのではないでしょうか
300番代がリダイレクトに使われるコードです。
パスワードの暗号化
Flaskでパスワードを暗号化するために、bcryptというライブラリを使用します
pip install Flask-Bcrypt
from flask import Flask
from flask_bcrypt import Bcrypt
app = Flask(__name__)
bcrypt = Bcrypt(app)
パスワードの暗号化
ユーザーから受け取ったパスワード(pw)を暗号化します。
hashed_pw = bcrypt.generate_password_hash(pw).decode('utf-8')
パスワードのチェック
ユーザーがログイン時に入力したパスワードと、データベースに保存されているハッシュ化されたパスワードを比較
check = bcrypt.check_password_hash(hashed_pw, pw)
if check:
print("Password is correct!")
else:
print("Password is incorrect!")
セッション クライアント側にデータを保持する場合
セッションデータをクライアント側に持つのは、あまり良くないとされていますが、デフォルトの場合はこんな使い方になります
from flask import Flask, session
app = Flask(__name__)
app.secret_key = 'secret_key'# セッションの暗号化に使用される秘密鍵
# セッションから情報を取得する
var = session.get('result')
#または
var = session['result']
キーがセッションに存在するかどうかが不明確な場合、KeyErrorを防ぐために session.get('result') のようなメソッドを使用することが推奨されます。しかし、キーの存在が保証されている場合、直接 session['result'] としてアクセスすることができます。
セッション サーバー側にデータを保持する場合
flaskはセッションデータをデフォルトではクライアント側に保持するのですが、安全性を高めたいときはサーバー側に持つのが良いとされています。(phpやdjangoではデフォルトがサーバー側)。というわけでサーバー側に保持する場合のやり方です。
from flask import Flask, session
from flask_session import Session
app.config['SECRET_KEY'] = 'your_secret_key_here'#秘密鍵
app.config['SESSION_TYPE'] = 'filesystem'#ファイルに保存
Session(app)
このあとは普通に
var = session.get('result') #キーがない可能性がある場合
session["result"] = var #キーが存在する場合
↑書き込みの場合
var = session["result"]
↑読み込みの場合(キーの存在を気にせず直接書き込めます)
flash()関数
シンプルなようで意外とわかりにくいのがflash()関数。chatGPTに聞くと
以下のように返ってきます
ーーーーーーーーーー
Flaskのflash()関数は、ユーザーへの一時的なメッセージを提供するために使用されます。これは、例えばフォームのバリデーションエラーや操作の成功・失敗の通知など、一時的なフィードバックが必要な場面で役立ちます。flash()関数で生成されたメッセージは、リクエスト間で一時的に保存され、次のリクエストで表示された後に消えます。
ーーーーーーーーーー
なるほどわからん!
私はセッション付きのrender_template()関数と理解しました。以下サンプルとリクエストレスポンスのフローイメージです
from flask import Flask, flash, redirect, url_for, render_template
app = Flask(__name__)
app.secret_key = '!!#$%' # セッションデータを暗号化するためのキー
@app.route('/sample')
def sample():
flash('This is a flash message!')
#このメッセージは最終的にindex.htmlに渡されるが一時的にセッションに保存
return redirect(url_for('index'))
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html>
<head>
<title>Flash Example</title>
</head>
<body>
{% for message in get_flashed_messages() %}#ここでセッションから取り出される
<div>{{ message }}</div>
{% endfor %}
</body>
</html>
上のコードでのやり取り (リクエストレスポンスのフローイメージ)
blueprint
webアプリの機能が増えてくると、とうぜんファイルを分割したくなります。このときappというインスタンス(一番さいしょn基本でつくったやつ)を各モジュールの中で使い回すのがやっかいになってきます。
そこで、appインスタンスに相当するインスタンスを各モジュールで作成しておいてapp.pyではこれらをimportし、登録しておくと機能を追加してもモジュール単位で独立しているので管理がしやすくなります。
ちなみにappインスタンスとは
from flask import Flask #Flaskをインポート
app = Flask(__name__) #インスタンス作成
でつくったインスタンスで、run()やroute()などのメソッドやプロパティをもっています
chatGPTに調べてもらったら以下のようにでてきました





