Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Export WebSocketState in fastapi.websockets #4376

Merged
merged 2 commits into from Sep 4, 2022

Conversation

matiuszka
Copy link
Contributor

Trivial improvement about exposing WebSocketState. It will eliminate the need of importing it from starlette directly.

Previously:

from fastapi.websockets import WebSocket
from starlette.websockets import WebSocketState

After:

from fastapi.websockets import WebSocket, WebSocketState

@Kludex
Copy link
Sponsor Collaborator

Kludex commented Aug 31, 2022

How do you use WebSocketState?

@matiuszka
Copy link
Contributor Author

So there is an endpoint that is sending some data, usually very rarely but still, and is receiving nothing. So while we are not sending any data and the WebSocket connection was closed by the client, the task is still running. So to add functionality that if the connection is closed task will be closed also we are monitoring the WebSocket status, by simple .recevie.

The endpoint more or less looks like that:

@router.websocket("/subscribe/some/data/changes")
async def subscribe_connectors_status(
    websocket: WebSocket,
) -> None:
    async def send_some_data() -> None:
        last_data = await get_data()
        await websocket.send_json({"data": last_data})
        while True:
            await asyncio.sleep(1)
            new_data = await get_data()
            if new_data != last_data:
                # This happens very rarely that's why I would like to close all of these unused tasks.
                last_data = new_data
                await websocket.send_json({"foo": last_data})

    async def watch_status() -> None:
        while websocket.client_state == WebSocketState.CONNECTED:
            # We are not expecting any data, but this will change to the client state if the connection will be closed.
            await websocket.receive()

        tg.cancel_scope.cancel()

    await websocket.accept()
    async with create_task_group() as tg:
        tg.start_soon(watch_status)
        tg.start_soon(send_some_data)

@codecov
Copy link

codecov bot commented Aug 31, 2022

Codecov Report

Merging #4376 (36dadce) into master (0bb8920) will not change coverage.
The diff coverage is 100.00%.

@@            Coverage Diff            @@
##            master     #4376   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          535       535           
  Lines        13825     13826    +1     
=========================================
+ Hits         13825     13826    +1     
Impacted Files Coverage Δ
fastapi/websockets.py 100.00% <100.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@github-actions
Copy link
Contributor

📝 Docs preview for commit 36dadce at: https://630fd8992dbce202ce9f181a--fastapi.netlify.app

@tiangolo tiangolo changed the title Expose WebSocketState ✨ Export WebSocketState in fastapi.websockets Sep 4, 2022
@tiangolo
Copy link
Owner

tiangolo commented Sep 4, 2022

Thanks for the contribution @matiuszka! 🍰

And thanks @Kludex for the help! 🙇

Knowing how you are using it made me feel it makes sense to have this in, so I'll take it. 🚀

Thanks! ☕

@tiangolo tiangolo merged commit dacb689 into tiangolo:master Sep 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants