尝试使用 websockets 从 FastAPI 获取实时数据流时如何修复错误(不支持的升级请求。)?

Posted

技术标签:

【中文标题】尝试使用 websockets 从 FastAPI 获取实时数据流时如何修复错误(不支持的升级请求。)?【英文标题】:How to fix an error when trying to get the live stream of data from FastAPI using websockets (Unsupported upgrade request.)? 【发布时间】:2020-11-13 09:26:00 【问题描述】:

我如何才能获得每次迭代的响应,例如实时流源?

这里是 RestAPI main.py:

from fastapi import FastAPI
from fastapi import Request
from fastapi import WebSocket
import asyncio

app = FastAPI()


@app.get("/ws_res")
async def websoc(websocket: WebSocket):
    await websocket.accept()
    for i in range(100000):
        i = "John"
        await asyncio.sleep(0.01)
        await websocket.send_json("msg": i)
    await websocket.close()

现在,我正在尝试从 python 代码中获取响应,但我收到一条错误消息,上面写着 Unsupported upgrade request.

这是 API 端的输出:

INFO:     Started server process [67680]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
WARNING:  Unsupported upgrade request.

这是我用来访问 API (test.py) 的 python 代码:

import asyncio
import websockets

async def hello():
    uri = "ws://127.0.0.1:8000/ws_res"
    async with websockets.connect(uri) as websocket:
        greeting = await websocket.recv()
        print(f"< greeting['msg']")


asyncio.get_event_loop().run_until_complete(hello())

Traceback (most recent call last):
  File "test.py", line 12, in <module>
    asyncio.get_event_loop().run_until_complete(hello())
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "test.py", line 7, in hello
    async with websockets.connect(uri) as websocket:
  File "/home/test/env/lib/python3.8/site-packages/websockets/client.py", line 517, in __aenter__
    return await self
  File "/home/test/env/lib/python3.8/site-packages/websockets/client.py", line 542, in __await_impl__
    await protocol.handshake(
  File "/home/test/env/lib/python3.8/site-packages/websockets/client.py", line 296, in handshake
    raise InvalidStatusCode(status_code)
websockets.exceptions.InvalidStatusCode: server rejected WebSocket connection: HTTP 400

【问题讨论】:

为什么每次循环都关闭websocket? @Mause 抱歉,它不在 for 循环中。当我在这里复制代码时出现小错误。更新 您是否在您用于 fastapi 的虚拟环境中安装了websockets 包? @Mause 是的,我将它安装在同一个环境中 【参考方案1】:

Fastapi websocket 端点需要使用websocket 装饰器定义,而不是get 装饰器:

@app.websocket("/ws_res")
async def websoc(websocket: WebSocket):
    await websocket.accept()
    for i in range(100000):
        i = "John"
        await asyncio.sleep(0.01)
        await websocket.send_json("msg": i)
    await websocket.close()

完整详情请参阅文档:https://fastapi.tiangolo.com/advanced/websockets/

【讨论】:

以上是关于尝试使用 websockets 从 FastAPI 获取实时数据流时如何修复错误(不支持的升级请求。)?的主要内容,如果未能解决你的问题,请参考以下文章

在 Python FastAPI 中使用 websocket 并行发送/接收

FastAPI中音频流的Websockets桥接器

FastAPI websocket ping/pong 超时

FastAPI websocket 无法处理大量数据传入?

FastAPI 在子进程中从 websocket 发送

如何将 socket.io 挂载到 fastapi 应用程序并向所有连接的客户端发送广播