FastAPIでメールフォームを作ってみた件
今日はFASTAPIを用いてメールフォームを作成していて、やっとこさ動いたので、アウトプットする。
参考記事
STEP①利用するモジュールをインポートしていく
今回のメールフォーム作成では「FastAPI-Mail」モジュールを用いて作成する。
インポートの仕方は下記を参照。
仮想環境にインストールしていない人は、インストールしてね。
ここで「FastAPI-Mail」、「MessageSchema」、「FastMail」、「ConnctionConfig」それぞれの機能と使い方について理解しておこう。
利用するモジュールの機能
- FastAPI-Mail :電子メールを簡単に行うことができるモジュール
- MessageSchema :送信されるメールの詳細情報を設定する
- ConnectionConfig:SMTPサーバーの接続設定をするためのクラス。
- FastMail:メース送信に関する機能を提供するクラス
利用するモジュールの使い方
- fastapi_mail
- インストール
- SMTP接続情報の設定
- FastMailオブジェクトの初期化
- ConnectionConfig
- MesseageSchema (MessageSchemaオブジェクトを生成し、オブジェクト内にメールの情報を記載する
メールフォーム作成の流れ
- fastapi_emailモジュールから、MesseageSchemaとFastMail、ConnectionConfig関数をインストール
- ConnectionConfigで、メールサーバーとの接続を書く
- ここで詰まった。どうやら参考記事と自分が使っていたfastapi_mailのバージョンが違っていて、最新は書き方が変わったらしい。
- FastMailのインスタンスを生成
-
fm = FastMail(conf)
- ConnectionConfigをFastMailの引数として渡して、SMTP設定を引き継がせる。これにより、FastMailオブジェクトを使い、メールが送信できるようになる。FastMailオブジェクトがないと、メールの送信ができない。
-
- pydanticのEmailSchemaクラスを用いて、メール送信時の各フィールドのバリデーションを行う
-
class EmailSchema(BaseModel):name:stremail:strcontents: strtel: str
- これがないと、POSTで受け取った時に型が不一致になってエラーの原因になるので、優秀なクラスっぽい。pydanticすげえ。。。
-
- 情報がpostされた時に行う処理をルーティング含め書いていく
- MessageSchemaで、受信時のメッセージを作成していく
- returnに、ユーザー側に表示される内容を作っていく。これthanks.htmlとかでもええかも
コードを書き終えて、フォームからPOSTすると、下記のエラーになった。
{"detail":[{"loc":["body"],"msg":"value is not a valid dict","type":"type_error.dict"}]}
エラーが意味するのは、フォームからPOSTされた値のバリデーションが辞書型ではなく、正しくないですよ。とのこと。
FastAPIはデフォルトだと、JSON形式のデータを受け取ることを想定している。JSON形式のデータというのは、「KeyとValueのペアである辞書型」なのだ。
今回の場合、フォームから送信されたデータをPydanticモデル(EmailSchema)に従って
バリデーションし、データの形式を確認する。
しかし、HTMLフォームからデータを送信する場合、
multipart/form-dataエンコーディングが使用されるらしい。そしてmultipart/form-dataエンコーディングは、フォームのフィールドを個別のパートとして送信するそうな。
そのため、FASTAPIがEmailSchemaを通して、自動でバリデーションできなくなるよう。
ここでコードを下記のように変更した。
旧コード:
async def submit_form(email: EmailSchema):
email:EmailSchemaというのは、関数submit_formに引数emailを渡している。そして型はEmailSchemaだよということ。受け取ったデータを、EmailSchemaを通して、バリデーションするのだ。
新コード: