はじめに
こちらの記事は求ム!Pythonを使ってAzureで開発する時のTips!【PR】日本マイクロソフト Advent Calendar 2020の16日目の記事です。
最近触り始めたFastAPI.このフレームワークで作成したサンプルアプリをAzure上にデプロイすべく手順をまとめてみます。
サンプルアプリと言いつつもHelloWorldだけだと少し味気ないのでDBが絡むような簡単なコードを実装してみました。
何ができるようになるのか
- 開発環境からAzureへのFastAPIを利用したアプリのデプロイ
- Python(SQLAlcemy)を利用してAzure Database for MySQLへのSSL/TLS接続構成
動作環境
以下のシステム要件を想定しております。
- Docker最新版 ※ローカルで動作確認を行うため
- App Service on Linux(Python3.7系)
- Azure Database for MySQL5.7
- VSCodeのApp Service拡張機能
手順
ローカルでの動作確認
- ここからローカルにソースをクローンします。
-
.env.sample
から.env
をコピーする。※編集はこの後行います。 -
docker-compose up --build
で起動します。 - 起動したら
http://localhost:8000/
にアクセスし{"message":"Hello World"}
が表示されたらOKです。
App Serviceを作成
-
こちらの手順を元にApp Service、WebAppsを作成します。ランタイムは
python3.7
としてください。
Azure Database for MySQLを作成
-
Azure Potalにアクセスします。
-
Azure Database for MySQLをクリックし、[単一サーバー] or [フレキシブルサーバー]の選択となります。今回はサンプルということもあるので[フレキシブルサーバー]にしたいと思います。
-
基本設定は下記の通りとしてます。
-
SKUは下記の通りとしてます。※今回はミニマムとしてます。
-
ネットワーク設定ですが、今回は[パブリックアクセス]とし、 AppServiceからの接続とローカル(開発端末) からのみ許可しました。要件によってはVNET IntegrationとPrivate Endpointを組み合わせてセキュアにしても良いかもしれません。送信元IPはこちらのページを参考に確認ください。
DB初期設定
- 下記の手順で初期設定を行います。
# 接続
mysql -h fastapi.mysql.database.azure.com -u <ユーザ名> -p
# DB作成 ※こちらは控えておいてください。
create database <DB名>;
# DB指定
use <DB名>;
# テーブル作成
CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL DEFAULT '',
email VARCHAR(255) NOT NULL DEFAULT '',
password VARCHAR(255) NOT NULL DEFAULT '',
token TEXT,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
# 初期データ追加
INSERT INTO users (name, email, password) VALUES ("admin", "admin@example.com", "<hash password>");
※passwordの作成方法は後述します。
環境変数の設定とアップロード
- ローカルでの動作確認の項で作成した
.env
を下記の通り更新します。
...
ENVIRONMENT="production"
SECRET_KEY="<任意の文字列>"
ALGORITHM="HS256"
ACCESS_TOKEN_EXPIRE_MINUTES=60
# MySQL
MYSQL_SERVER="<Azure Database for MySQLのサーバー名>"
MYSQL_USER="<Azure Database for MySQLのユーザ名>"
MYSQL_PASSWORD="<Azure Database for MySQLのパスワード>"
MYSQL_DB="<Azure Database for MySQLのスキーマ名>"
...
※フレキシブルサーバの場合はユーザ名は単一サーバー版とは異なり、hoge@hostnameではなく、hogeのみで良さそうです。
スタートアップファイルの設定
Webappsの[構成]ブレードの全般設定タブのスタートアップコマンドに startup.txt
を登録しておきます。
startup.txtの中身はこのような感じです。必要に応じてオプションを付け足してみてください。 オプションの詳細はこちら
python -m uvicorn src.main:app --host 0.0.0.0
ソースのデプロイ
VSCodeからアップロードします。赤囲みの矢印ボタンをクリックし
デプロイ中は[output]タブにて進行状況が確認できます。
デプロイが正常終了するとこのような表示になります。
TOPページ
試しにJWTを取得するAPIを叩いても問題なくレスポンスが返ってきます。
補足
- パスワードの作成について
passlibを用いハッシュしてます。
pipでpasslib
,bcrypt
をそれぞれインストールした上で下記を実行すると作成できます。
import passlib.hash
secret = "plain text"
salt = "saltsalt"
hashed = passlib.hash.sha512_crypt.hash(secret, salt=salt)
print(hashed)
最後に
FlaskやDjangoをApp Serviceにデプロイする記事は見かけることはありましたが、FastAPIの記事はまだ少ない印象でしたので、参考になれば幸いです。
サンプルコードがまだまだ成熟し切っていないので、さわりだけ掴んでもらえればと思います。
雛形にできるよう今後も少しずつ改善してきます。