[Python] How to make a non-blocking Websocket endpoint in FastAPI?

Discussão em 'Python' iniciado por Stack, Fevereiro 3, 2025.

  1. Stack

    Stack Membro Participativo

    I'm fairly new to async in Python. Currently I'm trying to implement a Websocket endpoint with FastAPI that performs a long-running task. The following code is used:

    @router.websocket("/ws/catalog.check")
    async def websocket_endpoint(ws: WebSocket, user: Annotated[UserWithGroupEntity, Depends(user_middleware_ws)]) -> None:
    manager = WSManager()
    await manager.connect(ws)

    try:
    raw_req = await ws.receive_json()
    req = CatalogCheckRequest.model_validate(raw_req)

    await manager.send_personal_json(CatalogCheckResponse(message=CatalogCheckMessage(data='Process started')),
    ws)

    #long-running task
    check_result = await create_task(CatalogHandler.catalog_check(user.group_name, req.source, req.csv))

    await manager.send_personal_json(CatalogCheckResponse(result=check_result), ws)
    except Exception as e:
    await manager.send_personal_json(CatalogCheckResponse(message=CatalogCheckMessage(data=repr(e), warning=True)),
    ws)

    await manager.disconnect(ws)


    However, when this process is running and I'm sending request to another HTTP endpoint in gets blocked. For example, the following /health.check endpoint will only be executed when long-runnning task is finished:

    @router.get("/health.check")
    def health_check(config: Annotated[Config, Depends(get_config)],
    log: Annotated[Log, Depends(get_logger)]) -> Dict[str, Any]:
    try:
    conf = config.model_dump()

    log.info(conf)

    resp = {"status": "ok"}
    except Exception as e:
    resp = {"status": repr(e)}

    return resp


    This messes the whole idea of my API. What can I do to make this Websocket endpoint non-blocking?

    Continue reading...

Compartilhe esta Página