Python Forum
Undestanding asyncio (Solved)
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Undestanding asyncio (Solved)
#1
Hi,
I've a test code below which connects to a AWS server but it doesn't loop every 10s.
What do I've to do so it loops? Also, I get a warning for line 31 "Coroutine 'create_task' is not awaited".
Appreciate some direction on this issue.

import ssl
import paho.mqtt.client as mqtt
import json
import asyncio

server = 'amazonaws.com'

def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))


async def send_message(client):
    while True:
        data = {"led": "off"}
        client.publish("picow/ctr", json.dumps(data))
        print("Message sent")
        await asyncio.sleep(10)  # Send message every 10 seconds

async def setup_mqtt():
    client = mqtt.Client()
    client.on_connect = on_connect

    client.tls_set(ca_certs = "C:\SharedFiles\Micropython\PICO\PicoW_AWS\AmazonRootCA1.pem",
                   certfile = "C:\SharedFiles\Micropython\PICO\PicoW_AWS\certificate.pem.crt",
                   keyfile = "C:\SharedFiles\Micropython\PICO\PicoW_AWS\private.pem.key",
                   cert_reqs = ssl.CERT_REQUIRED,
                   tls_version = ssl.PROTOCOL_TLS,
                   ciphers = None)

    client.connect(server, 8883)
    asyncio.create_task(send_message(client))
    client.loop_start()

asyncio.run(setup_mqtt())  
Reply
#2
First strip out all the goop to focus on the asyncio
import asyncio


async def send_message():
    while True:
        print("Message sent")
        await asyncio.sleep(10)  # Send message every 10 seconds


async def setup_mqtt():
    asyncio.create_task(send_message())


asyncio.run(setup_mqtt())
When run, this prints "Message sent" once and exits.

Now look at the warning you got when you ran your program. "Coroutine 'create_task' is not awaited". Add code to wait until the coroutine is done running.
import asyncio


async def send_message():
    while True:
        print("Message sent")
        await asyncio.sleep(10)  # Send message every 10 seconds


async def setup_mqtt():
    await asyncio.create_task(send_message())


asyncio.run(setup_mqtt())
Now the program waits for send_message to complete before returning. This results in Message sent being printed every 10 seconds until the program is killed.

asyncio lets you run multiple execution threads at the same time. syncio.create_task(send_message()) immediately returns a Task object allowing your program to perform other operations while the task executes. But in the example there are no other operations to perform, so setup_mqtt() returns immediately and the program reaches it's end.

This is a more realistic example of using asyncio
import asyncio


async def send_message():
    while True:
        print("Message sent")
        await asyncio.sleep(1)


async def setup_mqtt():
    asyncio.create_task(send_message())
    await asyncio.sleep(10)


asyncio.run(setup_mqtt())
In this example we run the send_message() function while setup_mqtt does something else. Here, the something else is just a wait, but you can see how the two tasks interract. send_message() prints "Message sent" once a second for the 10 seconds that setup_mqtt is running.

Using this info, lets take a look at your posted code. Why doesn't the loop in send_message run?
1. setup_mqtt does not wait for the function to finish, instead it immediately calls client.loop_start().
2. loop_start() is non-blocking. It starts the client loop and returns immediately. Do you want to use loop_forever()?
3. After calling loop_start(), there are no commands left in setup_mqtt, so the function returns.
4. After calling setup_mqtt, there are no commands left to execute, so the program ends.
ebolisa likes this post
Reply
#3
(Mar-16-2024, 02:09 PM)deanhystad Wrote: First strip out all the goop to focus on the asyncio
[python]

2. loop_start() is non-blocking. It starts the client loop and returns immediately. Do you want to use loop_forever()?

Thank you much for your elegant explanation and yes, I need to "Publish" data every so often. So, your second example should do it.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [SOLVED] Why is this asyncio task blocking? SecureCoop 1 784 Jun-06-2023, 02:43 PM
Last Post: SecureCoop

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020