Overview of aiocoap
masterasyncio to support concurrent operations through an easy-to-use interface.repository·master·Indexed 43 days ago
https://github.com/chrysn/aiocoapA Python implementation of the Constrained Application Protocol (CoAP) for IoT applications. Built on asyncio for high concurrency, it supports Blockwise transfers, Observe, and OSCORE. The library includes a core API with Context and Message classes, utilities for blockwise request assembly (Block1Spool) and response caching (Block2Cache), and the aiocoap-client CLI for interacting with CoAP servers.
asyncio to support concurrent operations through an easy-to-use interface.The contrib/ directory contains experimental or specialized tools that serve as inspiration for custom implementations. These are useful for testing specific interfaces or seeing how to implement complex CoAP behaviors.
Key items in contrib/:
aiocoap-widgets: Gtk3-based graphical implementations of CoAP devices (e.g., light bulbs, switches) using the gobject asyncio loop. Demonstrates CoRE interfaces and discovery.aiocoap-kivy-widget: A smaller widget implementation using the Kivy framework.oscore-plugtest: Server and client implementations used for OSCORE interoperability testing.rd-relay: An experimental tool for testing Resource Directory discovery processes.*.ipynb): Useful for interactive exploration, especially when using Pyodide.OSCORE (RFC8613) is an end-to-end security mechanism for CoAP implemented in aiocoap. Unlike lower-layer protections like IPsec or (D)TLS, OSCORE can leverage any CoAP transport (including HTTP), traverse proxies while preserving features like block-wise fragmentation and retransmission, and supports multicast/group communication scenarios.
Important Security Note: OSCORE does not include a key exchange protocol. It relies on external protocols like EDHOC or the ACE-OSCORE profile to establish keys. It is highly recommended to use aiocoap with EDHOC instead of manually setting up OSCORE to ensure security.
aiocoap will fail to start if IPv6 is disabled on the host system.
Reasoning: The default transport uses APIs designed for IPv6 that work for both IPv4 and IPv6 packets. Re-implementing these specifically for IPv4 would introduce portability issues and increased error rates, as IPv4 interfaces are not specified identically across all platforms.
To allow instantaneous trusted requests (e.g., a client waking up with a different network address and sending a single UDP packet that the server can immediately trust), OSCORE requires storing run-time information alongside the OSCORE key.
In aiocoap, this means OSCORE keys reside in writable directories and are updated occasionally at startup, shutdown, or runtime.
Critical Security Requirement: Stored OSCORE contexts must never be copied, only moved. If a copy is made (e.g., during a system backup), it must be considered lost and reestablished via different means unless it can be proven that the original was never written to after the backup was taken.
In aiocoap, requests and responses are handed to the application as CoAP Message objects. This design provides high flexibility for exploring CoAP extensions but requires more verbosity than high-level getter/setter patterns.
contrib directory.aiocoap operates with a hybrid model that balances being a CoAP proxy and a transport protocol.
By default, the library performs certain convenience operations following RFC7959 guidance, such as:
To prevent the library from making too many decisions for the user, it allows:
Properties that are not part of the standard CoAP options or payload are handled via custom attributes on the message object. Common examples include:
aiocoap.Message.remote: Information about the remote endpoint.aiocoap.Message.mtype: The message type.Multicast support in aiocoap is currently limited and behaves differently for servers and clients.
Servers join multicast groups during context creation using aiocoap.protocol.Context.create_server_context.
CON requests are not sent).aiocoap.protocol.Context.request interface only exposes the first response received. This makes it suitable for discovery (where you only need one response) but not for gathering data from multiple devices simultaneously.To perform discovery on a specific interface (e.g., eth0), use the --non flag to avoid CON requests:
./aiocoap-client coap://'[ff02::fd%eth0]'/.well-known/core --non#!/bin/bash
./aiocoap-client coap://'[ff02::fd%eth0]'/.well-known/core --nonWhen using aiocoap within a Jupyter environment (either via Pyodide in the browser or a server-side Python session), messages support enhanced HTML __repr__ presentations.
Instead of plain text, messages will display an HTML expandable view containing:
The aiocoap library uses a specific definition for its public API that differs from Python's internal/external naming conventions (like _ prefixes).
To determine if a function, method, or property is safe to use in a production environment, you must check its documentation for the term "stable".
Key rules for consumers:
__all__ attributes or the absence of a leading underscore to determine if an interface is public. If the documentation does not explicitly describe an interface as "stable", it should be considered subject to change.EDHOC (RFC9528) is a key establishment protocol used in aiocoap to provide secure communication. Credentials for EDHOC are stored in JSON/CBOR/EDN based files, similar to OSCORE and (D)TLS.
A client credential entry describes both the client-side and server-side credentials, along with the URI(s) for which to use them.
OSCORE uses an experimental JSON-based credentials format to describe security contexts.
Keys and IDs are stored in a directory referenced by the basedir key within the credentials file, allowing state writes to be performed independently of the main credentials map.