FastAPIとdotenvでCORSの設定をする話

TL;DL.

  • dotenv は複数行の設定をサポートする
  • FastAPIのCORSMiddleware、ALLOW_ORIGIN設定は、リストである
  • dotenvで読み込み、改行と , で区切って読み込んだ話

最初に長い自分語り

Qiitaに書こうかなと思ったが、そもそもこの記事が2つの事項を連結させた記事であって、ニーズも微妙、解説もうまくできるか微妙、ターゲットも微妙ということで、ここに体験談としてのみ残そうと思ったので書いている。しかも、結論はすでに書いた。サンプルコードは本文に示す。

出発点

そもそも、python-dotenv と FastAPIを使っていて、しかも設定を.envにまとめようとしたのが事の発端である。

それをしたい人がどれぐらいいるのか。

まあ、LagnChainだのOpenAIだのClaudeだのが、そろいもそろって環境変数にAPI-KEYを設定することを求めている昨今であるから、いやいやながら .env を使い始めたら、意外とみんな使っていて慣れてしまった、という私のような人間もいるであろうから、きっとニーズはあると思い込むことにする。


閑話休題


本記事の前提

対象とする読者は狭い。次のような事柄に付きあたった場合の記事である。

  • FastAPI を使っている
  • 設定は .env からすることを常としている
  • CORSの存在と設定に悩み、.env にその設定を隠すことを思いついた

サンプルコード

もったいぶらずにサンプルコードを提示しよう。

env ファイルには、次のようにAllowOriginを記述する。

ALLOW_ORIGINS="
    127.0.0.1,
    localhost,
    http://localhost:*,
    http://127.0.0.1:*,
    null
"

続けて、FastAPI のCORSMiddleware適用時に、次のように記述する。

from dotenv import load_dotenv
load_dotenv()

app = FastAPI(...オプション略...)

allow_origins = os.getenv('ALLOW_ORIGINS', "localhost")
origins = [o.strip() for o in allow_origins.split(",") if o.strip()]
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
    

ポイント

二つある。

  1. (さんざん書いたが)load_dotenv を使って複数行のデータは記述できる。"" で囲んで書けばよい。
  2. CORSMiddlewareのALLOW_ORIGINSに適用する際に、文字列を分割する必要があるので、splitする

1の参照は次の通り
python-dotenv · PyPI

2については、Cursorで召喚してもらったので、よくあることなのだろう(すごい時代だ)

おまけ


ところで、書いていて思い出したのだが、ローカルファイルを直接開いた場合に、CORSの問題にぶち当たる人は多いのではないだろうか。これについても、どういうわけかCursorが召喚してくれたコードが上記の通りであった。

ALLOW_ORIGINSは、viteやローカルサーバーを立てて実行する場合は、localhost127.0.0.1 のように、ホスト名を指定する。本番運用でも私はそうすると思う。

一方で、ローカルファイルを直接開いた場合のCORS設定は、
http://localhost:8000 のような、http:// から初めて、ホスト名のみの記述ではない形にすると解決できる。

それがなぜのか、調べようと思ったが残念な気持ちで撤退した次第である。そういう気持ちもあったがゆえに今このような記事を書いているのだろう、と自分を納得させている。


終わりに

こうやって文章を書いていると、ついついかっこいいことを書きたくなる。「CORSは絶対設定しとけ、ローカル開発中もだ」「設定は絶対隠匿するようにしろ、開発中だからこそだ」など。

だが、本心で思ったことを冷静に思い出したとき「またか」である。多分、自分なりの答えを持っておくこと、それが呪文のようであっても知っておくことが重要なのだろう。そうだ。どうせまたブラウザから怒られるんだ。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です