WIP
はじめに
Flaskを使ってWebサーバーを書くことが多いので、よく参考にするページをまとめておきます。
とりあえずはリンク集になるかと思いますが、時間があれば内容も書き足して行きたいです。
(そろそろFastAPIつかってみたい)
主な環境
- Python 3.8 (pipenv, pyenv)
- Flask
- MySQL 8.0 - SQLAlchemy
- gunicorn
- Nginx
- (Docker, docker-compose)
- Ubuntu 20.04 LTS
Flaskまわり
-
SECRET_KEY
について
公式チュートリアルには、os.urandom(12)
を用いるのが良いとされているが、これはアンチパターン
gunicornを複数のWorkderで動かしたときに、workerによって異なるSECRET_KEYが設定されてしまうため、SessionやCSRFProtection(Flask-WTF)が正常に動かない
session
ブラウザセッション
プラグインを何も入れていないバニラのFlaskでは
- cookie session
- base64encode
となっている。
公式Docにはapp.Config
にSecretKey
を設定する旨が記載されているが、これはsessionに格納された内容の改竄を防ぐためのhash計算にこのキーを用いているだけであり、sessionの中身自体が暗号化されるわけではない。
server session
プラグインを導入する必要がある。sessionを保存するバックエンドの選択肢としては、Redis, その他NoSQL, FileSystem, SQL等がある
有名所のプラグインとしては
などがある。FLask-Sessionは、Sessionを保持するバックエンドに対してFlask内からアクセスするが、Beakerは使用するWSGI(例えばGunicorn)のミドルウェアとして動作する。
また後者はCache機能も提供する。
なお、Flask-Sessionは、バックエンドにSQLAlchemyを指定した場合(つまりSQL)正しく動作しないバグが確認されている。(2020.5月時点)
logging
Flaskやそのプラグインは、ログ出力機能が提供されていることが多い。出力されているログをFlask本体のログハンドルで捉えて出力させるには、
import logging
from flask.logging import default_handler #flask本体のログハンドラ
# その他のimportなど
from flask_cors import CORS
def create_app():
# init_app等の諸々の処理
# ここでは、ログを取りたいプラグインを`flask_cors`とする
cors_err_lggr = logger.getLogger('flask_cors')
# 大体のプラグインは内蔵loggerの名前を__name__で指定している?
cors_err_lggr.setLever(logging.DEBUG)
# デフォルトのログハンドラを追加
cors_err_lggr.addHandler(default_handler)
# その他諸々の処理
return app
test
DB(MySQL, SQLAlchemy)まわり
- SQLAlchemy relationship 公式Doc
- SQLAlchemy many:many relation 解説記事
- SQLAlchemy relation パラメタの解説が詳しい
N:N中間テーブルに存在する独立したカラムを取得する変わり種
many:manyの中間テーブルに、独立したカラム(ForeignKeyでないカラム)を設定する場合、relation
を用いるよりも、association_proxy
を使ったほうが良い。
association_proxyに関する公式Doc、実装例付き
Nginx, Gunicornまわり
- [Fabricを用いずに、Gunicornをvirtualenv上でホットデプロイするコード?] (http://wingu.github.io/zero-downtime-gunicorn.html)
- gunicorn kill -HUP restart
Dockerまわり
デプロイまわり
- Fabric2がいいらしい?
公式ドキュメント
CapistranoとかDeployerみたいな感じ
解説記事1
解説記事2
おわりに
いや、FastAPI良くないか?