FastAPIでWebSocketを使っていてUvicornとWebSocketsライブラリの食い合わせでエラーが出た時の話

出てきたエラー:AttributeError: ‘WebSocketProtocol’ object has no attribute ‘transfer_data_task’. Did you mean: ‘transfer_data_exc’?

最初に、現実的にこの情報の対処法を知りたい人への情報を置いておこう

発生条件

私は次の条件で発生。まずは多分問題と関係のない条件から。

  • Docker コンテナ内で Pythonを実行(python:3.14-slimを利用)
  • Windowsホストで利用

で、問題が起こるのは

という条件を満たす場合。

問題の再現コード

次に置いた。

blog-article-sources/UvicornAndWebSockets at master · suzuki-no-suke/blog-article-sources · GitHub

正味のところ、フロントエンド・バックエンドのコードは普通のWebSocketsであるので、特筆すべき点はない。FastAPIの公式サンプルでも再現する気がする。試してない、、、以下にリンクを張っておく

WebSockets – FastAPI

対処法

Uvicornに、WebSocketsライブラリの詳細実装を指定するオプションを追加する必要がある。

  • (エラー発生) uvicorn --host 0.0.0.0 --port 8878 server:app
  • (修正後) uvicorn --host 0.0.0.0 --port 8878 server:app --reload --ws websockets-sansio

これは、Uvicornが利用するWebSocketの実装を切り替えるためのオプションで、ここに明示的にwebsockets-sansio を指定してやることによって問題は解消する。

原因について

後述するが、Perplexityで検索させたため、個別の情報源を確認していない。とはいえ、わかることはある。

現状の理解としては「WebSocketsライブラリの実装」について、「Uvicornが選択するデフォルトの実装」が、「どうもWebSocketsの中では古い実装になっている」ために、「古い実装では、現在存在しない関数」を参照するために起こるようである。

そのため、対処法(ワークアラウンドレベルかもしれないのではあるが)としては、WebSocketsの最新実装である、Sans-I/Oを利用した実装を参照するように明示してやることで、問題は解消する。

バージョンの確認

今後発生しなくなる可能性は、、、わからん

  • Python : 3.14.3
  • uvicorn: 0.40.0
  • websockets: 16.0


この答え、Perplexityが瞬殺した

多分調べる人はエラーメッセージで見るだろう、私はPerplexityに答えを聞いた。

この記事が、エラーメッセージで検索してきた誰かの役に立てば幸いである。

それで終わらないことにした

。。。このPerplexityの答えと、それについての分析について、別の記事を作成する。

これについて、お暇な方は見ていただければ幸いである。

コメントを残す

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