CoAPthon is a python library to the CoAP protocol aligned with the RFC
Python
Latest commit 0655a83 Mar 1, 2017 @Tanganelli release 4.0.2
Permalink
Failed to load latest commit information.
coapthon release 4.0.1 Mar 1, 2017
docs release 4.0.1 Mar 1, 2017
.coveragerc multicast testing Feb 28, 2017
.gitignore logging bug fix Dec 5, 2015
.travis.yml multicast testing Feb 28, 2017
LICENSE README and License Oct 26, 2015
README.md Installing CoAPthon through pip #54 Feb 28, 2017
coapclient.py clean code Dec 18, 2016
coapforwardproxy.py multicast testing Feb 28, 2017
coapping.py docs Dec 6, 2015
coapreverseproxy.py multicast testing Feb 28, 2017
coapserver.py multicast testing Feb 28, 2017
coverage_test.py new advanced optional interface for resource's methods Feb 27, 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
logging.conf add logging.conf Dec 16, 2016
lorem_impsum.txt client Oct 26, 2015
plugtest.py update for tests Feb 21, 2017
plugtest_coapserver.py clean code Dec 18, 2016
plugtest_resources.py clean code Dec 18, 2016
requirements.txt Why is flextls required?! Kick it. Jan 13, 2017
reverse_proxy_mapping.xml fix travis on coverage reverse proxy test Dec 15, 2016
setup.py release 4.0.2 Mar 1, 2017
test_secure.py release 4.0.1 Mar 1, 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 library to the CoAP protocol compliant with the RFC. Branch is available for the Twisted framework.

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

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()

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.