aiocoap module¶
The aiocoap package is a library that implements CoAP, the Constrained Application Protocol.
If you are reading this through the Python documentation, be aware that there
is additional documentation available online and in the source code’s doc
directory.
Module contents¶
This root module re-exports the most commonly used classes in aiocoap:
Context
, Message
as well as all commonly used numeric
constants from numbers
; see their respective documentation entries.
The presence of Message
and Context
in the root module is
stable.
-
class
aiocoap.
Code
¶ Bases:
aiocoap.util.ExtensibleIntEnum
Value for the CoAP “Code” field.
As the number range for the code values is separated, the rough meaning of a code can be determined using the
is_request()
,is_response()
andis_successful()
methods.-
EMPTY
= <Code 0 "EMPTY">¶
-
GET
= <Request Code 1 "GET">¶
-
POST
= <Request Code 2 "POST">¶
-
PUT
= <Request Code 3 "PUT">¶
-
DELETE
= <Request Code 4 "DELETE">¶
-
FETCH
= <Request Code 5 "FETCH">¶
-
PATCH
= <Request Code 6 "PATCH">¶
-
iPATCH
= <Request Code 7 "iPATCH">¶
-
CREATED
= <Successful Response Code 65 "2.01 Created">¶
-
DELETED
= <Successful Response Code 66 "2.02 Deleted">¶
-
VALID
= <Successful Response Code 67 "2.03 Valid">¶
-
CHANGED
= <Successful Response Code 68 "2.04 Changed">¶
-
CONTENT
= <Successful Response Code 69 "2.05 Content">¶
-
CONTINUE
= <Successful Response Code 95 "2.31 Continue">¶
-
BAD_REQUEST
= <Response Code 128 "4.00 Bad Request">¶
-
UNAUTHORIZED
= <Response Code 129 "4.01 Unauthorized">¶
-
BAD_OPTION
= <Response Code 130 "4.02 Bad Option">¶
-
FORBIDDEN
= <Response Code 131 "4.03 Forbidden">¶
-
NOT_FOUND
= <Response Code 132 "4.04 Not Found">¶
-
METHOD_NOT_ALLOWED
= <Response Code 133 "4.05 Method Not Allowed">¶
-
NOT_ACCEPTABLE
= <Response Code 134 "4.06 Not Acceptable">¶
-
REQUEST_ENTITY_INCOMPLETE
= <Response Code 136 "4.08 Request Entity Incomplete">¶
-
CONFLICT
= <Response Code 137 "4.09 Conflict">¶
-
PRECONDITION_FAILED
= <Response Code 140 "4.12 Precondition Failed">¶
-
REQUEST_ENTITY_TOO_LARGE
= <Response Code 141 "4.13 Request Entity Too Large">¶
-
UNSUPPORTED_CONTENT_FORMAT
= <Response Code 143 "4.15 Unsupported Media Type">¶
-
UNSUPPORTED_MEDIA_TYPE
= <Response Code 143 "4.15 Unsupported Media Type">¶
-
UNPROCESSABLE_ENTITY
= <Response Code 150 "4.22 Unprocessable Entity">¶
-
TOO_MANY_REQUESTS
= <Response Code 157 "4.29 Too Many Requests">¶
-
INTERNAL_SERVER_ERROR
= <Response Code 160 "5.00 Internal Server Error">¶
-
NOT_IMPLEMENTED
= <Response Code 161 "5.01 Not Implemented">¶
-
BAD_GATEWAY
= <Response Code 162 "5.02 Bad Gateway">¶
-
SERVICE_UNAVAILABLE
= <Response Code 163 "5.03 Service Unavailable">¶
-
GATEWAY_TIMEOUT
= <Response Code 164 "5.04 Gateway Timeout">¶
-
PROXYING_NOT_SUPPORTED
= <Response Code 165 "5.05 Proxying Not Supported">¶
-
HOP_LIMIT_REACHED
= <Response Code 168 "5.08 Hop Limit Reached">¶
-
CSM
= <Code 225 "7.01 Csm">¶
-
PING
= <Code 226 "7.02 Ping">¶
-
PONG
= <Code 227 "7.03 Pong">¶
-
RELEASE
= <Code 228 "7.04 Release">¶
-
ABORT
= <Code 229 "7.05 Abort">¶
-
is_request
()¶ True if the code is in the request code range
-
is_response
()¶ True if the code is in the response code range
-
is_signalling
()¶
-
is_successful
()¶ True if the code is in the successful subrange of the response code range
-
can_have_payload
()¶ True if a message with that code can carry a payload. This is not checked for strictly, but used as an indicator.
-
class_
¶ The class of a code (distinguishing whether it’s successful, a request or a response error or more).
>>> Code.CONTENT <Successful Response Code 69 "2.05 Content"> >>> Code.CONTENT.class_ 2 >>> Code.BAD_GATEWAY <Response Code 162 "5.02 Bad Gateway"> >>> Code.BAD_GATEWAY.class_ 5
-
dotted
¶ The numeric value three-decimal-digits (c.dd) form
-
name_printable
¶ The name of the code in human-readable form
-
name
¶ The constant name of the code (equals name_printable readable in all-caps and with underscores)
-
-
class
aiocoap.
OptionNumber
¶ Bases:
aiocoap.util.ExtensibleIntEnum
A CoAP option number.
As the option number contains information on whether the option is critical, and whether it is safe-to-forward, those properties can be queried using the is_* group of methods.
Note that whether an option may be repeated or not does not only depend on the option, but also on the context, and is thus handled in the Options object instead.
-
IF_MATCH
= <OptionNumber 1 "IF_MATCH">¶
-
URI_HOST
= <OptionNumber 3 "URI_HOST">¶
-
ETAG
= <OptionNumber 4 "ETAG">¶
-
IF_NONE_MATCH
= <OptionNumber 5 "IF_NONE_MATCH">¶
-
OBSERVE
= <OptionNumber 6 "OBSERVE">¶
-
URI_PORT
= <OptionNumber 7 "URI_PORT">¶
-
LOCATION_PATH
= <OptionNumber 8 "LOCATION_PATH">¶
-
OSCORE
= <OptionNumber 9 "OBJECT_SECURITY">¶
-
OBJECT_SECURITY
= <OptionNumber 9 "OBJECT_SECURITY">¶
-
URI_PATH
= <OptionNumber 11 "URI_PATH">¶
-
CONTENT_FORMAT
= <OptionNumber 12 "CONTENT_FORMAT">¶
-
MAX_AGE
= <OptionNumber 14 "MAX_AGE">¶
-
URI_QUERY
= <OptionNumber 15 "URI_QUERY">¶
-
HOP_LIMIT
= <OptionNumber 16 "HOP_LIMIT">¶
-
ACCEPT
= <OptionNumber 17 "ACCEPT">¶
-
Q_BLOCK1
= <OptionNumber 19 "Q_BLOCK1">¶
-
LOCATION_QUERY
= <OptionNumber 20 "LOCATION_QUERY">¶
-
EDHOC
= <OptionNumber 21 "EDHOC">¶
-
BLOCK2
= <OptionNumber 23 "BLOCK2">¶
-
BLOCK1
= <OptionNumber 27 "BLOCK1">¶
-
SIZE2
= <OptionNumber 28 "SIZE2">¶
-
Q_BLOCK2
= <OptionNumber 31 "Q_BLOCK2">¶
-
PROXY_URI
= <OptionNumber 35 "PROXY_URI">¶
-
PROXY_SCHEME
= <OptionNumber 39 "PROXY_SCHEME">¶
-
SIZE1
= <OptionNumber 60 "SIZE1">¶
-
ECHO
= <OptionNumber 252 "ECHO">¶
-
NO_RESPONSE
= <OptionNumber 258 "NO_RESPONSE">¶
-
REQUEST_TAG
= <OptionNumber 292 "REQUEST_TAG">¶
-
REQUEST_HASH
= <OptionNumber 548 "REQUEST_HASH">¶
-
is_critical
()¶
-
is_elective
()¶
-
is_unsafe
()¶
-
is_safetoforward
()¶
-
is_nocachekey
()¶
-
is_cachekey
()¶
-
format
¶
-
create_option
(decode=None, value=None)¶ Return an Option element of the appropriate class from this option number.
An initial value may be set using the decode or value options, and will be fed to the resulting object’s decode method or value property, respectively.
-
-
class
aiocoap.
ContentFormat
¶ Bases:
aiocoap.util.ExtensibleIntEnum
Entry in the CoAP Content-Formats registry of the IANA Constrained RESTful Environments (Core) Parameters group
Known entries have
.media_type
and.encoding
attributes:>>> ContentFormat(0).media_type 'text/plain; charset=utf-8' >>> int(ContentFormat.by_media_type('text/plain;charset=utf-8')) 0 >>> ContentFormat(60) <ContentFormat 60, media_type='application/cbor', encoding='identity'> >>> ContentFormat(11060).encoding 'deflate'
Unknown entries do not have these properties:
>>> ContentFormat(12345).is_known() False >>> ContentFormat(12345).media_type # doctest: +ELLIPSIS Traceback (most recent call last): ... AttributeError: ...
Only a few formats are available as attributes for easy access. Their selection and naming are arbitrary and biased. The remaining known types are available through the
by_media_type()
class method. >>> ContentFormat.TEXT <ContentFormat 0, media_type=’text/plain; charset=utf-8’, encoding=’identity’>A convenient property of ContentFormat is that any known content format is true in a boolean context, and thus when used in alternation with None, can be assigned defaults easily:
>>> requested_by_client = ContentFormat.TEXT >>> int(requested_by_client) # Usually, this would always pick the default 0 >>> used = requested_by_client or ContentFormat.LINKFORMAT >>> assert used == ContentFormat.TEXT
-
classmethod
by_media_type
(media_type: str, encoding: str = 'identity') → aiocoap.numbers.contentformat.ContentFormat¶ Produce known entry for a known media type (and encoding, though ‘identity’ is default due to its prevalence), or raise KeyError.
-
is_known
()¶
-
TEXT
= <ContentFormat 0, media_type='text/plain; charset=utf-8', encoding='identity'>¶
-
LINKFORMAT
= <ContentFormat 40, media_type='application/link-format', encoding='identity'>¶
-
OCTETSTREAM
= <ContentFormat 42, media_type='application/octet-stream', encoding='identity'>¶
-
JSON
= <ContentFormat 50, media_type='application/json', encoding='identity'>¶
-
CBOR
= <ContentFormat 60, media_type='application/cbor', encoding='identity'>¶
-
SENML
= <ContentFormat 112, media_type='application/senml+cbor', encoding='identity'>¶
-
classmethod
-
class
aiocoap.
Message
(*, mtype=None, mid=None, code=None, payload=b'', token=b'', uri=None, **kwargs)¶ Bases:
object
CoAP Message with some handling metadata
This object’s attributes provide access to the fields in a CoAP message and can be directly manipulated.
- Some attributes are additional data that do not round-trip through serialization and deserialization. They are marked as “non-roundtrippable”.
- Some attributes that need to be filled for submission of the message can be left empty by most applications, and will be taken care of by the library. Those are marked as “managed”.
The attributes are:
payload
: The payload (body) of the message as bytes.mtype
: Message type (CON, ACK etc, seenumbers.types
). Managed unless set by the application.code
: The code (either request or response code), seenumbers.codes
.opt
: A container for the options, seeoptions.Options
.mid
: The message ID. Managed by theContext
.token
: The message’s token as bytes. Managed by theContext
.remote
: The socket address of the other side, managed by theprotocol.Request
by resolving the.opt.uri_host
orunresolved_remote
, or theResponder
by echoing the incoming request’s. Follows theinterfaces.EndpointAddress
interface. Non-roundtrippable.While a message has not been transmitted, the property is managed by the
Message
itself using theset_request_uri()
or the constructor uri argument.request
: The request to which an incoming response message belongs; only available at the client. Managed by theinterfaces.RequestProvider
(typically aContext
).
These properties are still available but deprecated:
requested_*: Managed by the
protocol.Request
a response results from, and filled with the request’s URL data. Non-roundtrippable.unresolved_remote:
host[:port]
(strictly speaking; hostinfo as in a URI) formatted string. If this attribute is set, it overrides.RequestManageropt.uri_host
(and-_port
) when it comes to filling theremote
in an outgoing request.Use this when you want to send a request with a host name that would not normally resolve to the destination address. (Typically, this is used for proxying.)
Options can be given as further keyword arguments at message construction time. This feature is experimental, as future message parameters could collide with options.
Requester Responder +-------------+ +-------------+ | request msg | ---- send request ---> | request msg | +-------------+ +-------------+ | processed into | v +-------------+ +-------------+ | response m. | <--- send response --- | response m. | +-------------+ +-------------+
The above shows the four message instances involved in communication between an aiocoap client and server process. Boxes represent instances of Message, and the messages on the same line represent a single CoAP as passed around on the network. Still, they differ in some aspects:
- The requested URI will look different between requester and responder if the requester uses a host name and does not send it in the message.
- If the request was sent via multicast, the response’s requested URI differs from the request URI because it has the responder’s address filled in. That address is not known at the responder’s side yet, as it is typically filled out by the network stack.
- It is yet unclear whether the response’s URI should contain an IP literal or a host name in the unicast case if the Uri-Host option was not sent.
- Properties like Message ID and token will differ if a proxy was involved.
- Some options or even the payload may differ if a proxy was involved.
-
copy
(**kwargs)¶ Create a copy of the Message. kwargs are treated like the named arguments in the constructor, and update the copy.
-
classmethod
decode
(rawdata, remote=None)¶ Create Message object from binary representation of message.
-
encode
()¶ Create binary representation of message from Message object.
-
get_cache_key
(ignore_options=())¶ Generate a hashable and comparable object (currently a tuple) from the message’s code and all option values that are part of the cache key and not in the optional list of ignore_options (which is the list of option numbers that are not technically NoCacheKey but handled by the application using this method).
>>> from aiocoap.numbers import GET >>> m1 = Message(code=GET) >>> m2 = Message(code=GET) >>> m1.opt.uri_path = ('s', '1') >>> m2.opt.uri_path = ('s', '1') >>> m1.opt.size1 = 10 # the only no-cache-key option in the base spec >>> m2.opt.size1 = 20 >>> m1.get_cache_key() == m2.get_cache_key() True >>> m2.opt.etag = b'000' >>> m1.get_cache_key() == m2.get_cache_key() False >>> from aiocoap.numbers.optionnumbers import OptionNumber >>> ignore = [OptionNumber.ETAG] >>> m1.get_cache_key(ignore) == m2.get_cache_key(ignore) True
-
get_request_uri
(*, local_is_server=False)¶ The absolute URI this message belongs to.
For requests, this is composed from the options (falling back to the remote). For responses, this is largely taken from the original request message (so far, that could have been trackecd by the requesting application as well), but – in case of a multicast request – with the host replaced by the responder’s endpoint details.
This implements Section 6.5 of RFC7252.
By default, these values are only valid on the client. To determine a message’s request URI on the server, set the local_is_server argument to True. Note that determining the request URI on the server is brittle when behind a reverse proxy, may not be possible on all platforms, and can only be applied to a request message in a renderer (for the response message created by the renderer will only be populated when it gets transmitted; simple manual copying of the request’s remote to the response will not magically make this work, for in the very case where the request and response’s URIs differ, that would not catch the difference and still report the multicast address, while the actual sending address will only be populated by the operating system later).
-
set_request_uri
(uri, *, set_uri_host=True)¶ Parse a given URI into the uri_* fields of the options.
The remote does not get set automatically; instead, the remote data is stored in the uri_host and uri_port options. That is because name resolution is coupled with network specifics the protocol will know better by the time the message is sent. Whatever sends the message, be it the protocol itself, a proxy wrapper or an alternative transport, will know how to handle the information correctly.
When
set_uri_host=False
is passed, the host/port is stored in theunresolved_remote
message property instead of the uri_host option; as a result, the unresolved host name is not sent on the wire, which breaks virtual hosts but makes message sizes smaller.This implements Section 6.4 of RFC7252.
-
unresolved_remote
¶
-
requested_scheme
¶
-
requested_proxy_uri
¶
-
requested_hostinfo
¶
-
requested_path
¶
-
requested_query
¶
-
class
aiocoap.
Context
(loop=None, serversite=None, loggername='coap', client_credentials=None, server_credentials=None)¶ Bases:
aiocoap.interfaces.RequestProvider
Applications’ entry point to the network
A
Context
coordinates one or more networktransports
implementations and dispatches data between them and the application.The application can start requests using the message dispatch methods, and set a
resources.Site
that will answer requests directed to the application as a server.On the library-internals side, it is the prime implementation of the
interfaces.RequestProvider
interface, createsRequest
andResponse
classes on demand, and decides which transport implementations to start and which are to handle which messages.Context creation and destruction
The following functions are provided for creating and stopping a context:
Note
A typical application should only ever create one context, even (or especially when) it acts both as a server and as a client (in which case a server context should be created).
A context that is not used any more must be shut down using
shutdown()
, but typical applications will not need to because they use the context for the full process lifetime.-
classmethod
create_client_context
(*, loggername='coap', loop=None, transports: Optional[List[str]] = None)¶ Create a context bound to all addresses on a random listening port.
This is the easiest way to get a context suitable for sending client requests.
-
classmethod
create_server_context
(site, bind=None, *, loggername='coap-server', loop=None, _ssl_context=None, multicast=[], server_credentials=None, transports: Optional[List[str]] = None)¶ Create a context, bound to all addresses on the CoAP port (unless otherwise specified in the
bind
argument).This is the easiest way to get a context suitable both for sending client and accepting server requests.
The
bind
argument, if given, needs to be a 2-tuple of IP address string and port number, where the port number can be None to use the default port.If
multicast
is given, it needs to be a list of (multicast address, interface name) tuples, which will all be joined. (The IPv4 style of selecting the interface by a local address is not supported; users may want to use the netifaces package to arrive at an interface name for an address).As a shortcut, the list may also contain interface names alone. Those will be joined for the ‘all CoAP nodes’ groups of IPv4 and IPv6 (with scopes 2 and 5) as well as the respective ‘all nodes’ groups in IPv6.
Under some circumstances you may already need a context to pass into the site for creation; this is typically the case for servers that trigger requests on their own. For those cases, it is usually easiest to pass None in as a site, and set the fully constructed site later by assigning to the
serversite
attribute.
-
shutdown
()¶ Take down any listening sockets and stop all related timers.
After this coroutine terminates, and once all external references to the object are dropped, it should be garbage-collectable.
This method takes up to
aiocoap.numbers.constants.SHUTDOWN_TIMEOUT
seconds, allowing transports to perform any cleanup implemented in them (such as orderly connection shutdown and cancelling observations, where the latter is currently not implemented).
Dispatching messages
CoAP requests can be sent using the following functions:
-
request
(request_message, handle_blockwise=True)¶ Create and act on a a
Request
object that will be handled according to the provider’s implementation.Note that the request is not necessarily sent on the wire immediately; it may (but, depend on the transport does not necessarily) rely on the response to be waited for.
If more control is needed, you can create a
Request
yourself and pass the context to it.Other methods and properties
The remaining methods and properties are to be considered unstable even when the project reaches a stable version number; please file a feature request for stabilization if you want to reliably access any of them.
(Sorry for the duplicates, still looking for a way to make autodoc list everything not already mentioned).
-
request
(request_message, handle_blockwise=True) Create and act on a a
Request
object that will be handled according to the provider’s implementation.Note that the request is not necessarily sent on the wire immediately; it may (but, depend on the transport does not necessarily) rely on the response to be waited for.
-
render_to_pipe
(pipe)¶ Fill a pipe by running the site’s render_to_pipe interface and handling errors.
-
classmethod
create_client_context
(*, loggername='coap', loop=None, transports: Optional[List[str]] = None) Create a context bound to all addresses on a random listening port.
This is the easiest way to get a context suitable for sending client requests.
-
classmethod
create_server_context
(site, bind=None, *, loggername='coap-server', loop=None, _ssl_context=None, multicast=[], server_credentials=None, transports: Optional[List[str]] = None) Create a context, bound to all addresses on the CoAP port (unless otherwise specified in the
bind
argument).This is the easiest way to get a context suitable both for sending client and accepting server requests.
The
bind
argument, if given, needs to be a 2-tuple of IP address string and port number, where the port number can be None to use the default port.If
multicast
is given, it needs to be a list of (multicast address, interface name) tuples, which will all be joined. (The IPv4 style of selecting the interface by a local address is not supported; users may want to use the netifaces package to arrive at an interface name for an address).As a shortcut, the list may also contain interface names alone. Those will be joined for the ‘all CoAP nodes’ groups of IPv4 and IPv6 (with scopes 2 and 5) as well as the respective ‘all nodes’ groups in IPv6.
Under some circumstances you may already need a context to pass into the site for creation; this is typically the case for servers that trigger requests on their own. For those cases, it is usually easiest to pass None in as a site, and set the fully constructed site later by assigning to the
serversite
attribute.
-
find_remote_and_interface
(message)¶
-
shutdown
() Take down any listening sockets and stop all related timers.
After this coroutine terminates, and once all external references to the object are dropped, it should be garbage-collectable.
This method takes up to
aiocoap.numbers.constants.SHUTDOWN_TIMEOUT
seconds, allowing transports to perform any cleanup implemented in them (such as orderly connection shutdown and cancelling observations, where the latter is currently not implemented).
-
classmethod