How can I combine Asyncio and Websockets such that data keeps comming in while other functions run concurrently?

Question:

I have a stream of data comming in which I want to use while it’s comming in. Besides that I want to run another function every 30 seconds. Thus, while I am using the data stream to compute things I would like to run another function every 30 seconds. The code I have now:

import asyncio
import websockets

async def other_function():
    while True:
        print("Do stuff")
        await asyncio.sleep(30)

async def main():
    async with websockets.connect("url") as websocket:
        while True:
            await other_function()
            message = websocket.recv()
            print(message)

if __name__ == "__main__":
    asyncio.run(main())

I know what is going wrong, but I have no idea how to fix it. I also understand that the computations I do with the data stream will stop while the other function is running. I just want the 30 seconds of wait time to be on the ‘background’.

Asked By: Boyd Werkman

||

Answers:

You can use asyncio.create_task() to create background task. For example:

import asyncio
import websockets


async def other_function():
    while True:
        print("Do stuff")
        await asyncio.sleep(3)


async def main():
    bg_task = asyncio.create_task(other_function())

    async with websockets.connect(
        "wss://demo.piesocket.com/v3/channel_123?api_key=VCXCEuvhGcBDP7XhiJJUDvR1e1D3eiVjgZ9VRiaV&notify_self"
    ) as websocket:
        while True:
            print("Sending Hello World!")
            await websocket.send("Hello World!")
            print("Response is:", await websocket.recv())
            await asyncio.sleep(1)


if __name__ == "__main__":
    asyncio.run(main())

Prints:

Do stuff
Sending Hello World!
Response is: Hello World!
Sending Hello World!
Response is: Hello World!
Do stuff
Sending Hello World!
Response is: Hello World!
Sending Hello World!
Response is: Hello World!
Sending Hello World!
Response is: Hello World!
Do stuff

...and so on.
Answered By: Andrej Kesely

After reading the documentation I found the following solution:

import asyncio
import websockets

async def other_function():
    while True:
        print("Do stuff")
        await asyncio.sleep(30)

async def receive_messages():
    async with websockets.connect("url") as websocket:
        while True:
            message = await websocket.recv()
            print(message)


async def main():
    task1 = asyncio.create_task(other_function())
    task2 = asyncio.create_task(receive_messages())

    await task1
    await task2

if __name__ == "__main__":
    asyncio.run(main())
Answered By: Boyd Werkman
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.