Metadata-Version: 1.1
Name: QooxdooCherrypyJsonRpc
Version: 0.6.0
Summary: Qooxdoo-specific CherryPy-based JSON-RPC server
Home-page: https://bitbucket.org/saaj/qooxdoo-cherrypy-json-rpc
Author: saaj
Author-email: mail@saaj.me
License: LGPL-2.1+
Description: .. image:: https://bitbucket-badges.atlassian.io/badge/saaj/qooxdoo-cherrypy-json-rpc.svg?ref=default
          :target: https://bitbucket.org/saaj/qooxdoo-cherrypy-json-rpc/addon/pipelines/home
        .. image:: https://codecov.io/bb/saaj/qooxdoo-cherrypy-json-rpc/branch/default/graph/badge.svg
          :target: https://codecov.io/bb/saaj/qooxdoo-cherrypy-json-rpc/branch/default
        .. image:: https://badge.fury.io/py/QooxdooCherrypyJsonRpc.png
           :target: https://pypi.python.org/pypi/QooxdooCherrypyJsonRpc
        
        ***********************************************
        Qooxdoo-specific CherryPy-based JSON-RPC server
        ***********************************************
        
        Overview
        ========
        *Python* RPC-server for a `Qooxdoo <http://qooxdoo.org>`_ application. Implemented on top of
        `CherryPy <http://cherrypy.org>`_. Supports file upload and download. Controller code example:
        
        .. sourcecode:: python
        
           import cherrypy
           import qxcpjsonrpc as rpc
        
           class Service:
        
             _server = rpc.Server()
             '''Server instance can be shared between threads'''
        
             @cherrypy.expose
             def index(self, *args, **kwargs):
               return self._server.run()
        
        Alternatively ``rpc.ServerTool`` can used in *CherryPy* configuration as follows (or
        `any of other ways <http://cherrypy.readthedocs.org/en/3.2.6/concepts/tools.html>`_ to
        activate a *CherryPy* tool because of its great flexibility):
        
        .. sourcecode:: python
        
          import cherrypy
          import qxcpjsonrpc as rpc
        
          config = {
            '/service' : {
              'tools.jsonrpc.on' : True
            }
          }
        
          cherrypy.tools.jsonrpc = rpc.ServerTool()
        
          cherrypy.tree.mount(None, config = config)
        
        
        Service code example:
        
        .. sourcecode:: python
        
           import qxcpjsonrpc as rpc
        
           class Test(rpc.Service):
        
             @rpc.public
             def add(self, x, y):
               return x + y
        
        *Qooxdoo* code example:
        
        .. sourcecode:: javascript
        
           var rpc = new qx.io.remote.Rpc();
           rpc.setServiceName('modulename.Test');
           rpc.setUrl('http://127.0.0.1:8080/service');
           rpc.addListener("completed", function(event)
           {
             console.log(event.getData());
           });
           rpc.callAsyncListeners(this, 'add', 5, 7);
        
        
        Serialisation
        =============
        Serialisation is provided by ``json`` package. However it doesn't work out-of-the-box for some
        practically important types.
        
        No special deserialisation but ``json.loads`` is performed. Additional parsing is intended to be
        in user code.
        
        
        Date
        ----
        
        Dates are serialised to `UTC <http://en.wikipedia.org/wiki/Coordinated_Universal_Time>`_
        `ISO 8601 <http://www.w3.org/TR/NOTE-datetime>`_ strings, close to what *Javascript*
        ``JSON.stringify(new Date())`` produces. ``datetime.datetime`` objects look like
        ``'2012-03-17T19:09:12.217000Z'``, ``datetime.date`` like ``'2012-03-17T00:00:00Z'``.
        
        As far as I know, there's no reliable and cross-browser way to parse *ISO 8601* strings using
        *Javascript* ``Date`` object. The following code can help (usually I put it to
        ``Date.fromISOString``, as a counterpart to ``Date.prototype.toISOString``), which converts
        *ISO 8601* to cross-browser representation ``'2011/10/09 07:06:05 +0000'`` and passes it
        to ``Date`` constructor.
        
        .. sourcecode:: javascript
        
          function fromISOString(value)
          {
            if(!value)
            {
              return null;
            }
        
            return new Date(value
              .split(".")[0]
              .split("Z")[0]
              .split("-").join("/")
              .replace("T", " ")
              + " +0000"
            );
          }
        
        For dealing with *ISO 8601* strings in service user code there's a helper, which can be used
        as follows.
        Note that ``datetime.datetime`` objects it produces are timezone-aware. Timezone is *UTC*.
        
        .. sourcecode:: python
        
          import qxcpjsonrpc as rpc
        
          rpc.fromJsonDate('2012-03-17T19:09:12.217Z')
        
        Decimal
        -------
        
        Serialised as strings.
        
        
        Access control
        ==============
        By default all methods are protected and need to be explicitly marked with ``rpc.access`` decorator
        to become accessible. The decorator expects a callable that returns a ``bool``. It is possible to
        use the decorator multiple times.
        
        The package doesn't use manual service bookkeeping, rather than doing imports programmatically
        through ``importlib``. In case you operate modules that have import side-effects, which are
        in general a good idea to eliminate, you can subclass ``rpc.ServiceLocator`` and pass it (class)
        to initializer of ``rpc.Server`` or ``rpc.ServerTool``. This way arbitrary method lookup can be
        implemented.
        
        .. sourcecode:: python
        
          import qxcpjsonrpc as rpc
        
          def isAdmin(method, request):
            '''Access is granted only to administrator'''
            return cherrypy.request.login == 'admin'
        
          class Restricted(rpc.Service):
        
             @rpc.access(isAdmin)
             def entertainme(self):
               return '1/0 === Infinity'
        
        
        Protocol
        ========
        Below are some examples of typical payloads.
        
        GET
        ---
        It's usually a case of source mode *Qooxdoo* application under development. Especially when the
        application is loaded from *file://* and requires *JSONP* communication to circumvent
        Same Origin Policy.
        
        Request's query parameters, like in
        ``http://localhost/service?_ScriptTransport_id=...&nocache=...&_ScriptTransport_data=...``:
        
        .. sourcecode:: javascript
        
          // _ScriptTransport_data
          {
            "id"          : 5,
            "service"     : "modulename.Test",
            "method"      : "anotherMethod",
            "params"      : ["JavaScript", {"is": ["doable with Qooxdoo"]}],
            "server_data" : {"token": "a58666196537fdf3e5bf63cd740928gf"}
          }
        
          // _ScriptTransport_id
          5
        
          // nocache
          1297107012377
        
        Response:
        
        .. sourcecode:: javascript
        
          qx.io.remote.transport.Script._requestFinished(
            5, // id
            {
              "id"    : 5,
              "error" : {
                "origin"  : 2,
                "message" : "[ApplicationError] Wild statement!",
                "code"    : 0
              },
              "result" : null
            }
          );
        
        
        POST
        ----
        It's usually a case of built and deployed *Qooxdoo* application.
        
        Request to ``http://localhost/service?nocache=1234500999666``:
        
        .. sourcecode:: javascript
        
          {
            "id"          : 12,
            "service"     : "modulename.Test",
            "method"      : "anotherMethod",
            "params"      : ["Python", true, {"ly": ["rocks"]}],
            "server_data" : {"token": "a58666196537fdf3e5bf63cd740928gf"}
          }
        
        Response:
        
        .. sourcecode:: javascript
        
          {
            "id"     : 12,
            "error"  : null,
            "result" : {"arbitrary": {"here": ["a", 5, " well"]}}
          }
        
        
        Examples
        ========
        For examples look in
        `test suite <https://bitbucket.org/saaj/qooxdoo-cherrypy-json-rpc/src/default/qxcpjsonrpc/test/>`_.
        More examples could be found in `this <https://bitbucket.org/saaj/cherrypy-webapp-skeleton>`_
        project.
        
Keywords: qooxdoo cherrypy javascript python rpc
Platform: Any
Classifier: Topic :: Communications
Classifier: Topic :: Software Development :: Libraries
Classifier: Framework :: CherryPy
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Intended Audience :: Developers
