CoAPthon is a python library to the CoAP protocol aligned with the RFC
Python
Clone or download
Latest commit 4042852 May 16, 2018
Permalink
Failed to load latest commit information.
coapthon Added option to start mongod. May 16, 2018
docs release 4.0.1 Mar 1, 2017
.coveragerc multicast testing Feb 28, 2017
.gitignore logging bug fix Dec 5, 2015
.travis.yml remove test on IPv6 Jan 8, 2018
LICENSE README and License Oct 26, 2015
MANIFEST.in Add MANIFEST.in Jul 26, 2017
README.md Update README and examples. May 16, 2018
cache_test.py cache test Jul 6, 2017
coapclient.py clean code Dec 18, 2016
coapforwardproxy.py cache test Jul 6, 2017
coapping.py docs Dec 6, 2015
coapreverseproxy.py multicast testing Feb 28, 2017
coapserver.py multicast testing Feb 28, 2017
collectclient.py bug fixing Jan 10, 2018
collectmapping.json bug fixing Jan 10, 2018
collectserver.py example Jan 23, 2018
coverage_test.py coverage Jul 6, 2017
coverage_testIPv6.py fix PUT response with payload #45 Dec 16, 2016
coverage_test_advanced.py new advanced optional interface for resource's methods Feb 27, 2017
coverage_test_multicast.py multicast testing Feb 28, 2017
coverage_test_multicast_ipv6.py multicast testing Feb 28, 2017
coverage_test_proxy.py fix travis on coverage proxy test Dec 15, 2016
coverage_test_reverse_proxy.py fix server location path Jan 5, 2016
exampleresources.py new advanced optional interface for resource's methods Feb 27, 2017
examplesresourcedirectory.py Update README and examples. May 16, 2018
logging.conf add logging.conf Dec 16, 2016
lorem_impsum.txt client Oct 26, 2015
plugtest.py update for tests Feb 22, 2017
plugtest_coapserver.py clean code Dec 18, 2016
plugtest_resources.py clean code Dec 18, 2016
requirements.txt Added pymongo to requirements May 9, 2018
resourcedirectory_test.py Changed payload check and updated tests May 16, 2018
resourcedirectoryserver.py Added author. May 13, 2018
reverse_proxy_mapping.xml fix travis on coverage reverse proxy test Dec 15, 2016
setup.py Added pymongo to requirements May 9, 2018
test_secure.py For examples on how to use CoAPthon with pyDTLS, please have a look a… Apr 3, 2017
tests.py fix incorrect handling of oqaque options Jan 10, 2017

README.md

Build Status Coverage Status Documentation Status

CoAPthon

CoAPthon is a python 2.7 library to the CoAP protocol compliant with the RFC. Branch is available for the Twisted framework.

For python 3 please visit https://github.com/Tanganelli/CoAPthon3

Citation

If you use CoAPthon software in your research, please cite:

G.Tanganelli, C. Vallati, E.Mingozzi, "CoAPthon: Easy Development of CoAP-based IoT Applications with Python", IEEE World Forum on Internet of Things (WF-IoT 2015)

Software available at https://github.com/Tanganelli/CoAPthon

What is implemented

  • CoAP server
  • CoAP client
  • CoAP to CoAP Forward proxy
  • CoAP to CoAP Reverse Proxy
  • HTTP to CoAP Forward Proxy
  • Caching feature
  • Observe feature
  • CoRE Link Format parsing
  • Multicast server discovery
  • Blockwise feature

TODO

  • CoAP to HTTP Proxy
  • DTLS support

Install instructions

To install the library you need the pip program:

Debian/Ubuntu

$ sudo apt-get install python-pip

Fedora/CentOS

$ sudo yum install python-pip

Archlinux

$ sudo pacman -S python-pip

To install last release:

$ sudo pip install CoAPthon

To install master branch:

$ git clone https://github.com/Tanganelli/CoAPthon.git
$ cd CoAPthon
$ python setup.py sdist
$ sudo pip install dist/CoAPthon-4.0.2.tar.gz -r requirements.txt

Running:

The library is installed in the default path as well as the bins that you can use and customize. In order to start the example CoAP server issue:

$ coapserver.py

To uninstall:

$ sudo pip uninstall CoAPthon

Install instructions on Arduino Yun

Log through ssh to the Yun and issue the following:

# opkg update #updates the available packages list
# opkg install distribute #it contains the easy_install command line tool
# opkg install python-openssl #adds ssl support to python
# easy_install pip #installs pip

Then you need to modify the setup.py and comment the line conditionalExtensions=getExtensions(). Then :

# python setup.py build_py build_scripts install --skip-build

Install instructions for CoRE Resource Directory

To use Resource Directory functionalities, you need to install mongoDB database following the official documentation.

Then you need to configure Resource Directory database. Start mongod process and open a mongo shell. In mongo shell use these commands:

> use resourceDirectory
> db.createUser( {user: "RD",pwd: "res-dir",roles: [ { role: "readWrite", db: "resourceDirectory" } ] } )
> db.resources.createIndex( { "ep": 1, "d": 1 }, { unique: true } )

You can change user, password and database name in the commands above. If you change some parameters, then you must change them also in mongoDB parameters in coapthon/defines.py file where you will find also the path for your mongoDB configuration file. The default configuration file is /usr/local/etc/mongod.conf.

User Guide

CoAP server

In order to implements a CoAP server the basic class must be extended. Moreover the server must add some resources.

from coapthon.server.coap import CoAP
from exampleresources import BasicResource

class CoAPServer(CoAP):
    def __init__(self, host, port):
        CoAP.__init__(self, (host, port))
        self.add_resource('basic/', BasicResource())

def main():
    server = CoAPServer("0.0.0.0", 5683)
    try:
        server.listen(10)
    except KeyboardInterrupt:
        print "Server Shutdown"
        server.close()
        print "Exiting..."

if __name__ == '__main__':
    main()

Resources are extended from the class resource.Resource. Simple examples can be found in example_resource.py.

from coapthon.resources.resource import Resource

class BasicResource(Resource):
    def __init__(self, name="BasicResource", coap_server=None):
        super(BasicResource, self).__init__(name, coap_server, visible=True,
                                            observable=True, allow_children=True)
        self.payload = "Basic Resource"

    def render_GET(self, request):
        return self

    def render_PUT(self, request):
        self.payload = request.payload
        return self

    def render_POST(self, request):
        res = BasicResource()
        res.location_query = request.uri_query
        res.payload = request.payload
        return res

    def render_DELETE(self, request):
        return True

Advanced Use

Separate Responses

To always reply following the separate mode:

from coapthon.resources.resource import Resource

class Separate(Resource):

    def __init__(self, name="Separate", coap_server=None):
        super(Separate, self).__init__(name, coap_server, visible=True, observable=True, allow_children=True)
        self.payload = "Separate"
        self.max_age = 60

    def render_GET(self, request):
        return self, self.render_GET_separate

    def render_GET_separate(self, request):
        time.sleep(5)
        return self

    def render_POST(self, request):
        return self, self.render_POST_separate

    def render_POST_separate(self, request):
        self.payload = request.payload
        return self

    def render_PUT(self, request):
        return self, self.render_PUT_separate

    def render_PUT_separate(self, request):
        self.payload = request.payload
        return self

    def render_DELETE(self, request):
        return self, self.render_DELETE_separate

    def render_DELETE_separate(self, request):
        return True

Advanced interface

Resources can be implemented also through a more advanced interface.

class AdvancedResource(Resource):
    def __init__(self, name="Advanced"):
        super(AdvancedResource, self).__init__(name)
        self.payload = "Advanced resource"

    def render_GET_advanced(self, request, response):
        response.payload = self.payload
        response.max_age = 20
        response.code = defines.Codes.CONTENT.number
        return self, response

    def render_POST_advanced(self, request, response):
        self.payload = request.payload
        from coapthon.messages.response import Response
        assert(isinstance(response, Response))
        response.payload = "Response changed through POST"
        response.code = defines.Codes.CREATED.number
        return self, response

    def render_PUT_advanced(self, request, response):
        self.payload = request.payload
        from coapthon.messages.response import Response
        assert(isinstance(response, Response))
        response.payload = "Response changed through PUT"
        response.code = defines.Codes.CHANGED.number
        return self, response

    def render_DELETE_advanced(self, request, response):
        response.payload = "Response deleted"
        response.code = defines.Codes.DELETED.number
        return True, response

Separate mode with advanced interface

class AdvancedResourceSeparate(Resource):
    def __init__(self, name="Advanced"):
        super(AdvancedResourceSeparate, self).__init__(name)
        self.payload = "Advanced resource"

    def render_GET_advanced(self, request, response):
        return self, response, self.render_GET_separate

    def render_POST_advanced(self, request, response):
        return self, response, self.render_POST_separate

    def render_PUT_advanced(self, request, response):

        return self, response, self.render_PUT_separate

    def render_DELETE_advanced(self, request, response):
        return self, response, self.render_DELETE_separate

    def render_GET_separate(self, request, response):
        time.sleep(5)
        response.payload = self.payload
        response.max_age = 20
        return self, response

    def render_POST_separate(self, request, response):
        self.payload = request.payload
        response.payload = "Response changed through POST"
        return self, response

    def render_PUT_separate(self, request, response):
        self.payload = request.payload
        response.payload = "Response changed through PUT"
        return self, response

    def render_DELETE_separate(self, request, response):
        response.payload = "Response deleted"
        return True, response

CoAP client

from coapthon.client.helperclient import HelperClient

host = "127.0.0.1"
port = 5683
path ="basic"

client = HelperClient(server=(host, port))
response = client.get(path)
print response.pretty_print()
client.stop()

CoRE Resource Directory

Resource Directory server

You can start a CoRE Resource Directory server using ResourceDirectory class as follows:

from coapthon.resource_directory.resourceDirectory import ResourceDirectory


def main():
    server = ResourceDirectory("127.0.0.1", 5683)
    try:
        server.listen(10)
    except KeyboardInterrupt:
        print "Server Shutdown"
        server.close()
        print "Exiting..."


if __name__ == '__main__':
    main()

Resource Directory client examples

def main():
    host = "127.0.0.1"
    port = 5683
    client = HelperClient(server=(host, port))

    # Test discover
    path = "/.well-known/core"
    response = client.get(path)
    print response.pretty_print()

    # Create a registration resource
    path = "rd?ep=node1&con=coap://local-proxy-old.example.com:5683&et=oic.d.sensor"
    ct = {'content_type': defines.Content_types["application/link-format"]}
    payload = '</sensors/temp>;ct=41;rt="temperature-c";if="sensor";anchor="coap://spurious.example.com:5683",' \
              '</sensors/light>;ct=41;rt="light-lux";if="sensor"'
    response = client.post(path, payload, None, None, **ct)
    location_path = response.location_path
    print response.pretty_print()

    # Resource lookup
    path = 'rd-lookup/res?if=sensor'
    response = client.get(path)
    print response.pretty_print()

    # Update a registration resource
    path = location_path + "?con=coaps://new.example.com:5684"
    response = client.post(path, '')
    print response.pretty_print()

    # Read endpoint links
    path = location_path
    response = client.get(path)
    print response.pretty_print()

    # Endpoint lookup
    path = 'rd-lookup/ep?et=oic.d.sensor'
    response = client.get(path)
    print response.pretty_print()

    # Delete a registration resource
    path = location_path
    response = client.delete(path)
    print response.pretty_print()

    client.stop()

Build the documentation

The documentation is based on the Sphinx framework. In order to build the documentation issue the following:

$ pip install Sphinx
$ cd CoAPthon/docs
$ make html

The documentation will be build in CoAPthon/docs/build/html. Let's start from index.html to have an overview of the library.