FastAPI「Error loading ASGI app. Could not import module」の原因と直し方
Could not import module は、main.py のある場所で uvicorn を実行するか、app.main:app のように書けば直る。main:app の main はモジュール名、app は変数名だ。
公開: 更新:
要約
FastAPI のアプリを uvicorn で起動しようとすると、サーバーが立ち上がらずに次の 1 行で止まる(終了コード 3)。
ERROR: Error loading ASGI app. Could not import module "main".uvicorn main:app の main はファイル main.py(モジュール)、app はその中で app = FastAPI() と代入した変数を指す。公式ドキュメント(新しいタブで開く)のとおり、これは from main import app と同じ意味で、uvicorn は実行したディレクトリを起点に main を探す。main.py がそこから見えなければこのエラーになる。
上の表示は Python 3.12・FastAPI 0.143.0・uvicorn 0.54.0 で、app/main.py だけを置いたディレクトリで uvicorn main:app を実行したものだ。
解決策
1. main.py のあるディレクトリで実行する
cd backend
uvicorn main:app --reload2. サブディレクトリならドット区切りで書く
app/main.py にあるなら、その親ディレクトリから次のように書く。app/ に __init__.py が無くても起動できた。
uvicorn app.main:app --reloadディレクトリを移動できない事情があるなら、--app-dir(新しいタブで開く) で探す場所を足す。
指定したディレクトリが PYTHONPATH に加わる。
uvicorn --app-dir app main:app逆に、app.main:app をさらに上のディレクトリで実行すると、No module named 'app' のトレースバックになる。
どちらの書き方でも、起点は実行したディレクトリだ。
3. : の右側を変数名に合わせる
Attribute "app" not found と出たら、main.py で FastAPI() を代入している変数の名前を確かめる。api = FastAPI() なら uvicorn main:api と書く。
4. トレースバックの最後の行を読む
Could not import module が出ずにトレースバックで終わるときは、main.py 自体は見つかっている。
最後の行の No module named '…' に出たパッケージを、uvicorn と同じ Python 環境にインストールする。
よくある原因
- 別のディレクトリで実行している: リポジトリのルートやホームで実行し、
main.pyがカレントディレクトリに無い。 - サブディレクトリに置いている:
app/main.pyのような構成でmain:appと書いている。
モジュール名はapp.mainになる。 - 変数名が違う:
api = FastAPI()と書いてmain:appで起動すると、メッセージがAttribute "app" not found in module "main".に変わる(終了コードは同じ 3)。 - 中で import しているパッケージが無い:
main.pyは見つかっても、その中のimport sqlalchemyなどが失敗すると、Could not import moduleではなくModuleNotFoundError: No module named 'sqlalchemy'のトレースバックで終わる(終了コード 1)。