aiocoap.resource module

Basic resource implementations

A resource in URL / CoAP / REST terminology is the thing identified by a URI.

Here, a Resource is the place where server functionality is implemented. In many cases, there exists one persistent Resource object for a given resource (eg. a TimeResource() is responsible for serving the /time location). On the other hand, an aiocoap server context accepts only one thing as its serversite, and that is a Resource too (typically of the Site class).

Resources are most easily implemented by deriving from Resource and implementing render_get, render_post and similar coroutine methods. Those take a single request message object and must return a aiocoap.Message object or raise an error.RenderableError (eg. raise UnsupportedMediaType()).

To serve more than one resource on a site, use the Site class to dispatch requests based on the Uri-Path header.

aiocoap.resource.hashing_etag(request, response)

Helper function for render_get handlers that allows them to use ETags based on the payload’s hash value

Run this on your request and response before returning from render_get; it is safe to use this function with all kinds of responses, it will only act on 2.05 Content. The hash used are the first 8 bytes of the sha1 sum of the payload.

Note that this method is not ideal from a server performance point of view (a file server, for example, might want to hash only the stat() result of a file instead of reading it in full), but it saves bandwith for the simple cases.

>>> from aiocoap import *
>>> req = Message(code=GET)
>>> hash_of_hello = b'\xaa\xf4\xc6\x1d\xdc\xc5\xe8\xa2'
>>> req.opt.etags = [hash_of_hello]
>>> resp = Message(code=CONTENT)
>>> resp.payload = b'hello'
>>> hashing_etag(req, resp)
>>> resp                                            
<aiocoap.Message at ... 2.03 Valid ... 1 option(s)>
class aiocoap.resource.Resource

Bases: aiocoap.resource._ExposesWellknownAttributes, aiocoap.interfaces.Resource

Simple base implementation of the interfaces.Resource interface

The render method delegates content creation to render_$method methods, and responds appropriately to unsupported methods.

Moreover, this class provides a get_link_description method as used by .well-known/core to expose a resource’s .ct, .rt and .if_ (alternative name for if as that’s a Python keyword) attributes.

needs_blockwise_assembly(request)
render(request)
class aiocoap.resource.ObservableResource

Bases: aiocoap.resource.Resource, aiocoap.interfaces.ObservableResource

add_observation(request, serverobservation)
update_observation_count(newcount)

Hook into this method to be notified when the number of observations on the resource changes.

updated_state(response=None)

Call this whenever the resource was updated, and a notification should be sent to observers.

class aiocoap.resource.WKCResource(listgenerator)

Bases: aiocoap.resource.Resource

Read-only dynamic resource list, suitable as .well-known/core.

This resource renders a link_header.LinkHeader object (which describes a collection of resources) as application/link-format (RFC 6690).

The list to be rendered is obtained from a function passed into the constructor; typically, that function would be a bound Site.get_resources_as_linkheader() method.

ct = 40
render_get(request)
class aiocoap.resource.PathCapable

Bases: object

Class that indicates that a resource promises to parse the uri_path option, and can thus be given requests for render()ing that contain a uri_path

class aiocoap.resource.Site

Bases: aiocoap.interfaces.ObservableResource, aiocoap.resource.PathCapable

Typical root element that gets passed to a Context and contains all the resources that can be found when the endpoint gets accessed as a server.

This provides easy registration of statical resources. Add resources at absolute locations using the add_resource() method.

For example, the site at

>>> site = Site()
>>> site.add_resource(["hello"], Resource())

will have requests to </hello> rendered by the new resource.

You can add another Site (or another instance of PathCapable) as well, those will be nested and integrally reported in a WKCResource. The path of a site should not end with an empty string (ie. a slash in the URI) – the child site’s own root resource will then have the trailing slash address. Subsites can not have link-header attributes on their own (eg. rt) and will never respond to a request that does not at least contain a single slash after the the given path part.

For example,

>>> batch = Site()
>>> batch.add_resource(["light1"], Resource())
>>> batch.add_resource(["light2"], Resource())
>>> batch.add_resource([], Resource())
>>> s = Site()
>>> s.add_resource("batch", batch)

will have the three created resources rendered at </batch/light1>, </batch/light2> and </batch/>.

If it is necessary to respond to requests to </batch> or report its attributes in .well-known/core in addition to the above, a non-PathCapable resource can be added with the same path. This is usually considered an odd design, not fully supported, and for example doesn’t support removal of resources from the site.

needs_blockwise_assembly(request)
render(request)
add_observation(request, serverobservation)
add_resource(path, resource)
remove_resource(path)
get_resources_as_linkheader()