aiocoap Python CoAP Library

repository·master·Indexed 43 days ago

https://github.com/chrysn/aiocoap

A 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.

Tokens
39.2K
Snippets
117
Records
172
Agent score
52%

What's inside aiocoap

  1. Overview of aiocoap

    master
    aiocoap is a Python implementation of the Constrained Application Protocol (CoAP), designed for interacting with network-enabled embedded IoT devices. It is built using Python 3's native asyncio to support concurrent operations through an easy-to-use interface.
  2. Explore aiocoap contrib tools

    master

    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.
    • Jupyter Notebooks (*.ipynb): Useful for interactive exploration, especially when using Pyodide.
  3. What is OSCORE in aiocoap

    master

    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.

  4. IPv6 requirement for aiocoap

    master

    Warning: Do not disable IPv6 system-wide

    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.

  5. How OSCORE stateful usage works

    master

    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.

  6. How messages are represented in aiocoap

    master

    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.

    Key characteristics

    • Flexibility: Applications have full access to setting and reacting to CoAP options.
    • Abstraction level: The library treats application-level messages similarly to how a CoAP-over-UDP message would be treated (assuming arbitrarily long messages).
    • Observe numbers: If you are manually setting Observe numbers, you should pack them into a 4-byte integer. This ensures consistency across transports, as the TCP transport might otherwise elide them.
    • Simplified patterns: For developers who prefer predefined patterns (like content-format negotiation or GET/PUT getter-setters), simplified handlers can be built using examples found in the contrib directory.
  7. How aiocoap handles message properties and proxy behavior

    master

    aiocoap operates with a hybrid model that balances being a CoAP proxy and a transport protocol.

    Proxy-like behaviors

    By default, the library performs certain convenience operations following RFC7959 guidance, such as:

    • Block-wise transfers: Automatically splitting large messages into chunks unless explicitly disabled.
    • Observe notifications: Intermittently dropping notifications as a proxy might.

    Application control

    To prevent the library from making too many decisions for the user, it allows:

    • First-hop control: Application authors can still set message properties for the initial hop (e.g., choosing between reliable or unreliable transport).
    • Proxy-unsafe options: The library does not reject messages containing options that might be considered 'proxy-unsafe', trusting the application to manage them.

    Message properties and attributes

    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.
  8. How multicast support works in aiocoap

    master

    Multicast support in aiocoap is currently limited and behaves differently for servers and clients.

    Server-side Multicast

    Servers join multicast groups during context creation using aiocoap.protocol.Context.create_server_context.

    Client-side Multicast

    • Protocol Level: Requests to multicast addresses are handled correctly (e.g., CON requests are not sent).
    • API Limitation: The 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.
    • Interface Specification: Multicast requests often require an explicit interface specification to avoid being underspecified.

    Example: Multicast Discovery via CLI

    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 --non
  9. Jupyter HTML Representations in aiocoap

    master

    When 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:

    • Options
    • Payload
    • Tooltips for constants and options that indicate their underlying numeric values.
  10. Understand aiocoap API stability and usage

    master

    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:

    • Documentation is authoritative: Do not rely solely on __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.
    • Abstract Guarantees: A stable API might guarantee that a method returns an instance of an abstract base class, even if the actual implementation returns a specific concrete class. Always code against the stable interface/base class described in the docs.
  11. Configure EDHOC credentials in aiocoap

    master

    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.

    Client Credential Structure

    A client credential entry describes both the client-side and server-side credentials, along with the URI(s) for which to use them.

    Server Credential Structure

    • For any requested origin (the URI excluding the path), the server stores one record containing its own credentials.
    • For each known client, the server stores one record listing and labeling the peer's credentials.
  12. Configure OSCORE credentials using JSON files

    master

    OSCORE uses an experimental JSON-based credentials format to describe security contexts.

    • For Clients: The credentials file maps specific URIs to an OSCORE context.
    • For Servers: The credentials file indicates available OSCORE contexts that clients can use, providing labels for them.

    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.