aiocoap-client tool does not print subsequent observation notifications
The aiocoap-client CLI, when using --observe, does print only the first response on the initial observation registration, but does not print any update received after that, although each notification packet is indeed ACK'd to the server – visible in Wireshark and
I also assume it's not my server's fault as a hacky Python script using aiocoap does work, (edit) as well as some other CaAP client.
Am I doing something wrong?
Related: --observe-exec does not seem to do anything.
Full output:
(.venv) f@X:~/xxx$ aiocoap-client coap://192.168.4.8/topic/topic/topic --observe -v
INFO:coap.aiocoap-client:Sending request:
INFO:coap.aiocoap-client:GET to coap://192.168.4.8
INFO:coap.aiocoap-client:- Observe (6): 0
INFO:coap.aiocoap-client:- Uri-Path (11): 'topic'
INFO:coap.aiocoap-client:- Uri-Path (11): 'topic'
INFO:coap.aiocoap-client:- Uri-Path (11): 'topic'
INFO:coap.aiocoap-client:No payload
INFO:coap.aiocoap-client:Received response:
INFO:coap.aiocoap-client:2.00 (Unknown) from coap://192.168.4.8
INFO:coap.aiocoap-client:- Observe (6): 3
INFO:coap.aiocoap-client:No payload
No additions for any notification packet. It does not change by putting a payload (and status 2.05 CONTENT) in the initial response.
Environment – although experience is identical on Windows, WSL and Mac OS:
PS C:\> python -m aiocoap.cli.defaults
Python version: 3.13.7 (tags/v3.13.7:bcee1c3, Aug 14 2025, 14:15:11) [MSC v.1944 64 bit (AMD64)]
aiocoap version: 0.4.16
Modules missing for subsystems:
dtls: missing DTLSSocket
oscore: missing cryptography, ge25519, lakers-python
linkheader: everything there
prettyprint: everything there
ws: missing websockets
Python platform: win32
Default server transports: tcpserver:tcpclient:tlsserver:tlsclient:simple6:simplesocketserver
Selected server transports: tcpserver:tcpclient:tlsserver:tlsclient:simple6:simplesocketserver
Default client transports: tcpclient:tlsclient:simple6
Selected client transports: tcpclient:tlsclient:simple6
SO_REUSEPORT available (default, selected): False, False
Just a quick check while I can't test that on mobile: Do your notifications have different payload from each other?
For my endpoint I didn't exactly tested otherwise as the initial response is supposed to be different, but when testing with Zephyr's obs server sample, which has nearly identical responses and even in text/plain charset=utf-8, there are no subsequent prints also.
Same behaviour in combination with this project's server.py:
aiocoap-client coap://127.0.0.1/time --observe
2025-11-03 16:54
No further output, despite every 5 seconds some output is shown in the server.py's console and corresponding CoAP packages shown in Wireshark.
I had a look at client.py. The code seems to use deprecated non-async calls into protocol.py. I gave it a shot to change that, and it seems to work. So now I'm preparing a proper patch.
Finally managed to check: aiocoap-client was using a deprecated API. Not that that should fail, but those warnings would have shown for years in other places (something about the way aiocoap-client gets invoked in tests didn't set -Xdev), and I'll probably remove them before I get around to fixing them. A fix for aiocoap-client is in !49 and soon in main; please reopen if issues persist.
Thanks for reporting this!
I was about to finally create the PR* today, but now see that you fixed it on master already, which works, too, and with the minor fixes, great! (didn't try the exec feature)
*: As said before I was about to de-deprecate the aiocoap-client, but noticed that the previous master could be fixed by simply removing the seemingly-misplaced call requester.observation.cancel() so I wanted to create a fix PR for that before I make a bigger one for the callbacks and stuff.
What held me back there and what is still sub par on current master: The behavior of Ctrl+C during observations. What might help is adding the following except:
except error.LibraryShutdown:
raise StopAsyncIteration
to the try in https://github.com/chrysn/aiocoap/blob/73904ddf3495ef0fae1f19ba18f1bc461f035026/aiocoap/protocol.py#L1094-L1107.
Then it's less exception output, but still an "ERROR:asyncio:Future exception was never retrieved", at which point my asyncio knowledge isn't enough, but I guess you know more.