FastAPI + SQLAlchemy (Postgres) でHerokuにデプロイ
TL;DR
FastAPIはRestfulなAPIをPythonで構築するときに非常に便利なマイクロウェブフレームワークで、パフォーマンスにも優れています。また、型についてサポートしており、Swagger UIでAPIドキュメントが自動的に生成される点も素晴らしいです。
実際にAPIを構築するにあたって、Herokuは無料で利用でき、デプロイも簡単なのでテストサーバーを作成するときに重宝します。Herokuが無料枠でサポートしているのはPostgres SQLだけなので、もしデータベースを絡めようと思うと、必然的にPostgresを使う必要があります。
使い方を書いてある記事はあるのですが、単純にデプロイするだけ、といったことに焦点を当てた記事がなかったので書きました。
Dependencies
ORMとしてsqlalchemyを利用します。また、postgresと接続するためにpsycopg2-binaryを使います。個人的にpipenvを使っているので、Pipfileを用意します。あとはpostのデータには型がついていてほしいのでpydanticを使います。
Pipfile
FastAPIを試運転
依存関係をインストールします。個人的にいつもapp/下にpythonファイルとかを作成しているので、今回もそうします。
app/main.py
起動してみます。
https://localhost:8002で{"message": "Hello World"}で見えていれば成功です。
local環境の構築
dockerを使ってローカルでDBに関してもテストできるようにします。
Dockerfile
docker-compose.yml
モデルの定義
SQLalechemyのためにモデルを定義します。今回はTODOテーブルを作成します。 テーブルは自動で作成されてほしいので、
app/model.py
で作成するようにしています。
また、_asdictメソッドがないので、自前で辞書型に変換する関数を定義しています。
app/model.py
TODOに対するPOSTとGETを定義します。Postの際に、必ずtitleとdescriptionをリクエストボディに入れてほしいので、pydanticでDataクラスを定義しています。
app/main.py
http://localhost:8002/docsにアクセスしてSwagger UIでGetとPostのテストをしてみてください。このへんまでのcommitです。
Herokuにデプロイ
好みのやり方でプロジェクトを作って、Postgres SQLのアドオンを有効にしてください。
ちょっとハマりどころなのが、herokuでPostgres SQLアドオンを追加すると環境変数としてDATABASE_URLが提供されるんですが、これをそのままcreate_engineに入れてもうまく行かないという点です。というのはDATABASE_URLはpostgres://....みたいな感じなんですが、create_engineの引数としてはpostgresql://...みたいな感じである必要があります。
この点を考慮して、create_engineを書き直します。
のような感じにします。
次にProcfileを書きます。
Procfile
あとはデプロイしたら終わりです。
終わりに
FastAPI、型があって嬉しいですね。 完成品はgithubにあります。