[Checkins] SVN: z3c.jsonrpc/trunk/ - implemented default skin for JSON-RPC like we have for browser request

Roger Ineichen roger at projekt01.ch
Mon Feb 23 22:45:04 EST 2009


Log message for revision 97191:
  - implemented default skin for JSON-RPC like we have for browser request
  - added tests for all JSON-RPC versions
  - prepare for release

Changed:
  U   z3c.jsonrpc/trunk/CHANGES.txt
  U   z3c.jsonrpc/trunk/setup.py
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/README.txt
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/ftesting.zcml
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/meta.zcml
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/publisher.py
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/testing.py
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.py
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.txt

-=-
Modified: z3c.jsonrpc/trunk/CHANGES.txt
===================================================================
--- z3c.jsonrpc/trunk/CHANGES.txt	2009-02-24 03:32:40 UTC (rev 97190)
+++ z3c.jsonrpc/trunk/CHANGES.txt	2009-02-24 03:45:04 UTC (rev 97191)
@@ -2,29 +2,33 @@
 CHANGES
 =======
 
-Version 0.5.2dev (unreleased)
------------------------------
+Version 0.5.2 (2009-02-24)
+--------------------------
 
- - support non positional arguments for all jsonrpc versions
-   There is now no distinction in handling method parameters for all supported
-   versions.
+- added tests for all JSON-RPC versions
 
-- for jsonrpc version 1.1 :
+- Feature: implemented defaultJSONRPCSkin directive
+
+- Feature: support non positional arguments for all jsonrpc versions. There is
+  now no distinction in handling method parameters for all supported versions.
+
+- Fix: for jsonrpc version 1.1 :
    - must not provide "error" property in case of success
    - must not provide "result" property in case of error
 
-- removed develop path for z3c.json from buildout.cfg
-- publisher checks for version id as a string not a float
+- Fix: removed develop path for z3c.json from buildout.cfg
 
-- Implemented JSON-RPC 2.0 specification. Use JSON-RPC 2.0 version as default.
-  Optional the version 1.0 and 1.1 can be set. See JSON-RPC 2.0 specification
-  for more information.
+- Fix: publisher checks for version id as a string not a float
 
-- Added initial version of JSON-RPC exceptions.
+- Feature: Implemented JSON-RPC 2.0 specification. Use JSON-RPC 2.0 version as
+  default. Optional the version 1.0 and 1.1 can be set. See JSON-RPC 2.0
+  specification for more information.
 
-- Added explicit test cleanup since some zope testing change left over a global 
-  adapter registry from old connections
+- Feature: Added initial version of JSON-RPC exceptions.
 
+- Added explicit test cleanup since some zope testing change left over a
+  global adapter registry from old connections
+
 - Removed unused dependency to z3c.layer in test setup
 
 - Removed unused dependency on z3c.i18n.

Modified: z3c.jsonrpc/trunk/setup.py
===================================================================
--- z3c.jsonrpc/trunk/setup.py	2009-02-24 03:32:40 UTC (rev 97190)
+++ z3c.jsonrpc/trunk/setup.py	2009-02-24 03:45:04 UTC (rev 97191)
@@ -25,7 +25,7 @@
 
 setup (
     name='z3c.jsonrpc',
-    version='0.5.2dev',
+    version='0.5.2',
     author = "Roger Ineichen and the Zope Community",
     author_email = "zope-dev at zope.org",
     description = "JSON RPC server and client implementation for Zope3",

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/README.txt
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/README.txt	2009-02-24 03:32:40 UTC (rev 97190)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/README.txt	2009-02-24 03:45:04 UTC (rev 97191)
@@ -62,7 +62,7 @@
 python, e.g. getMultiAdapter((context, request), name='myViewName'). This is
 explicitly done this way. If you'd like to use content form such browser pages
 in a JSON request/call, you can inherit your skin form IJSONRPCLayer and
-IBrowserRequest and register your views for this custom layer.
+IBrowserRequest and register your JSON-RPC views for this custom layer.
 
 
 JSON-RPC server
@@ -271,8 +271,8 @@
   >>> proxy.hello()
   u'Hello World'
 
-  >>> p2 = JSONRPCTestProxy(siteURL + '/container')
-  >>> p2.available()
+  >>> proxy2 = JSONRPCTestProxy(siteURL + '/container')
+  >>> proxy2.available()
   u'Hello World'
 
 Now let's make a remote procedure call with a argument:
@@ -280,16 +280,6 @@
   >>> proxy.greeting(u'Jessy')
   u'Hello Jessy'
 
-Note that this key word arguments are stored in the request.form. Important
-to know is that JSON-RPC does not support positional and named arguments in
-one method call. We are working on a solution for solve that restriction which
-hurts us as python developer.
-
-  >>> proxy.mixedparams('Hello', foo=u'FOO', bar=u'BAR')
-  Traceback (most recent call last):
-  ...
-  ValueError: Mixing positional and named parameters in one call is not possible
-
 Let's call named arguments:
 
   >>> proxy.kws(bar=u'BAR', foo=u'FOO')
@@ -307,6 +297,97 @@
   >>> proxy.jsonId
   u'my id'
 
+
+JSON-RPC Versions
+-----------------
+
+Let's test the different JSON-RPC versions starting with version 1.0:
+
+  >>> v1 = JSONRPCTestProxy(siteURL + '/container', jsonVersion='1.0')
+  >>> v1.available()
+  u'Hello World'
+
+  >>> v1.greeting(u'Jessy')
+  u'Hello Jessy'
+
+  >>> v1.kws(bar=u'BAR', foo=u'FOO')
+  u'None FOO BAR'
+
+  >>> v1 = JSONRPCTestProxy(siteURL + '/content', jsonId = u'my id',
+  ...     jsonVersion='1.0')
+  >>> v1.showId()
+  u'The json id is: my id'
+
+  >>> v1.jsonId
+  u'my id'
+
+Now test with JSON-RPC version 1.1:
+
+  >>> v11 = JSONRPCTestProxy(siteURL + '/container', jsonVersion='1.1')
+  >>> v11.available()
+  u'Hello World'
+
+  >>> v11.greeting(u'Jessy')
+  u'Hello Jessy'
+
+  >>> v11.kws(bar=u'BAR', foo=u'FOO')
+  u'None FOO BAR'
+
+  >>> v11 = JSONRPCTestProxy(siteURL + '/content', jsonId = u'my id',
+  ...     jsonVersion='1.1')
+  >>> v11.showId()
+  u'The json id is: my id'
+
+  >>> v11.jsonId
+  u'my id'
+
+Now test with JSON-RPC version 2.0:
+
+  >>> v2 = JSONRPCTestProxy(siteURL + '/container', jsonVersion='2.0')
+  >>> v2.available()
+  u'Hello World'
+
+  >>> v2.greeting(u'Jessy')
+  u'Hello Jessy'
+
+  >>> v2.kws(bar=u'BAR', foo=u'FOO')
+  u'None FOO BAR'
+
+  >>> v2 = JSONRPCTestProxy(siteURL + '/content', jsonId = u'my id',
+  ...     jsonVersion='2.0')
+  >>> v2.showId()
+  u'The json id is: my id'
+
+  >>> v2.jsonId
+  u'my id'
+
+
+Mixed parameters
+----------------
+
+Note the keyword arguments will get stored in the request.form. Important
+to know is that JSON-RPC does not support positional and named arguments in
+one method call.
+
+  >>> v1.mixedparams('Hello', foo=u'FOO', bar=u'BAR')
+  Traceback (most recent call last):
+  ...
+  ValueError: Mixing positional and named parameters in one call is not possible
+
+  >>> v11.mixedparams('Hello', foo=u'FOO', bar=u'BAR')
+  Traceback (most recent call last):
+  ...
+  ValueError: Mixing positional and named parameters in one call is not possible
+
+  >>> v2.mixedparams('Hello', foo=u'FOO', bar=u'BAR')
+  Traceback (most recent call last):
+  ...
+  ValueError: Mixing positional and named parameters in one call is not possible
+
+
+Error handling
+--------------
+
 See what happens if the server raises an Exception:
 
   >>> proxy.forceValueError()

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/ftesting.zcml
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/ftesting.zcml	2009-02-24 03:32:40 UTC (rev 97190)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/ftesting.zcml	2009-02-24 03:45:04 UTC (rev 97191)
@@ -1,8 +1,9 @@
-<configure xmlns="http://namespaces.zope.org/zope"
-           xmlns:meta="http://namespaces.zope.org/meta"
-           xmlns:browser="http://namespaces.zope.org/browser"
-           xmlns:z3c="http://namespaces.zope.org/z3c"
-           i18n_domain="zope">
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:meta="http://namespaces.zope.org/meta"
+    xmlns:browser="http://namespaces.zope.org/browser"
+    xmlns:z3c="http://namespaces.zope.org/z3c"
+    i18n_domain="zope">
 
   <include package="zope.i18n" file="meta.zcml" />
   <include package="zope.app.component" file="meta.zcml" />

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/meta.zcml
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/meta.zcml	2009-02-24 03:32:40 UTC (rev 97190)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/meta.zcml	2009-02-24 03:45:04 UTC (rev 97191)
@@ -3,11 +3,18 @@
     xmlns="http://namespaces.zope.org/zope">
     
   <meta:directive
-       namespace="http://namespaces.zope.org/z3c"
-       name="jsonrpc"
-       schema=".zcml.IJSONRPCDirective"
-       handler=".zcml.jsonrpc"
-       />
+      namespace="http://namespaces.zope.org/z3c"
+      name="jsonrpc"
+      schema=".zcml.IJSONRPCDirective"
+      handler=".zcml.jsonrpc"
+      />
+
+  <meta:directive
+      namespace="http://namespaces.zope.org/z3c"
+      name="defaultJSONRPCSkin"
+      schema=".zcml.IDefaultJSONRPCSkinDirective"
+      handler=".zcml.defaultJSONRPCSkin"
+      />
        
     <meta:provides feature="z3c.jsonrpc" />
 

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/publisher.py
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/publisher.py	2009-02-24 03:32:40 UTC (rev 97190)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/publisher.py	2009-02-24 03:45:04 UTC (rev 97191)
@@ -24,6 +24,7 @@
 import zope.component
 from zope.location.location import Location
 from zope.i18n.interfaces import IUserPreferredCharsets
+from zope.publisher.interfaces.browser import IDefaultSkin
 from zope.publisher.http import HTTPRequest
 from zope.publisher.http import HTTPResponse
 from zope.publisher.http import getCharsetUsingRequest
@@ -45,6 +46,14 @@
     return int(item[0])
 
 
+def setDefaultSkin(request):
+    """Sets the default skin for the JONS-RPC request."""
+    adapters = zope.component.getSiteManager().adapters
+    skin = adapters.lookup((zope.interface.providedBy(request),), IDefaultSkin, '')
+    if skin is not None:
+        zope.interface.directlyProvides(request, skin)
+
+
 class MethodPublisher(Location):
     """Base class for JSON-RPC views that publish methods
        like zope.app.publisher.xmlrpc.MethodPublisher
@@ -258,7 +267,27 @@
     def __getitem__(self, key):
         return self.get(key)
 
+    def retry(self):
+        """Set default JSONRPC skin if available."""
+        count = getattr(self, '_retry_count', 0)
+        self._retry_count = count + 1
 
+        request = self.__class__(
+            # Use the cache stream as the new input stream.
+            body_instream=self._body_instream.getCacheStream(),
+            environ=self._orig_env,
+            response=self.response.retry(),
+            )
+        # restore the default skin
+        if interfaces.IJSONRPCRequest.providedBy(self):
+            # only browser requests have skins
+            setDefaultSkin(request)
+
+        request.setPublication(self.publication)
+        request._retry_count = self._retry_count
+        return request
+
+
 class JSONRPCResponse(HTTPResponse):
     """JSON-RPC Response"""
 

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/testing.py
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/testing.py	2009-02-24 03:32:40 UTC (rev 97190)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/testing.py	2009-02-24 03:45:04 UTC (rev 97191)
@@ -30,9 +30,10 @@
 from z3c.json.proxy import JSONRPCProxy
 from z3c.json.transport import Transport
 from z3c.jsonrpc import layer
+from z3c.jsonrpc.publication import JSONRPCPublication
 from z3c.jsonrpc.publisher import JSONRPCRequest
 from z3c.jsonrpc.publisher import MethodPublisher
-from z3c.jsonrpc.publication import JSONRPCPublication
+from z3c.jsonrpc.publisher import JSON_RPC_VERSION
 
 
 ###############################################################################
@@ -78,8 +79,8 @@
             StringIO.StringIO(response.getBody()), sock=None)
 
 
-def JSONRPCTestProxy(uri, transport=None, encoding=None,
-                verbose=None, jsonId=None, handleErrors=True):
+def JSONRPCTestProxy(uri, transport=None, encoding=None, verbose=None,
+    jsonId=None, handleErrors=True, jsonVersion=JSON_RPC_VERSION):
     """A factory that creates a server proxy using the ZopeJSONRPCTestTransport 
     by default."""
     if verbose is None:
@@ -88,7 +89,7 @@
         transport = JSONRPCTestTransport()
     if isinstance(transport, JSONRPCTestTransport):
         transport.handleErrors = handleErrors
-    return JSONRPCProxy(uri, transport, encoding, verbose, jsonId)
+    return JSONRPCProxy(uri, transport, encoding, verbose, jsonId, jsonVersion)
 
 
 ###############################################################################

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.py
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.py	2009-02-24 03:32:40 UTC (rev 97190)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.py	2009-02-24 03:45:04 UTC (rev 97191)
@@ -17,10 +17,12 @@
 __docformat__ = "reStructuredText"
 
 import zope.interface
+import zope.component
 import zope.configuration.fields
 import zope.interface
 import zope.schema
 import zope.security.zcml
+from zope.publisher.interfaces.browser import IDefaultSkin
 
 from zope.interface import Interface
 from zope.security.checker import CheckerPublic, Checker
@@ -208,3 +210,29 @@
             callable = provideInterface,
             args = ('', for_)
             )
+
+
+class IDefaultJSONRPCSkinDirective(zope.interface.Interface):
+    """Sets the default JSON-RPC skin."""
+
+    name = zope.schema.TextLine(
+        title=u"Default skin name",
+        description=u"Default skin name",
+        required=True
+        )
+
+
+def setDefaultJSONRPCSkin(name, info=''):
+    """Set the default skin."""
+    skin = zope.component.getUtility(interfaces.IJSONRPCSkinType, name=name)
+    handler('registerAdapter', skin, (interfaces.IJSONRPCRequest,),
+        IDefaultSkin, '', info),
+
+
+def defaultJSONRPCSkin(_context, name):
+
+    _context.action(
+        discriminator = 'setDefaultJSONRPCSkin',
+        callable = setDefaultJSONRPCSkin,
+        args = (name, _context.info)
+        )

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.txt
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.txt	2009-02-24 03:32:40 UTC (rev 97190)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.txt	2009-02-24 03:45:04 UTC (rev 97191)
@@ -73,3 +73,25 @@
 
   >>> zope.component.queryMultiAdapter((b, request), name='hello') is None
   True
+
+
+setDefaultJSONRPCSkin
+---------------------
+
+  >>> from zope.interface import directlyProvides
+  >>> from zope.publisher.interfaces.browser import IDefaultSkin
+  >>> from z3c.jsonrpc import interfaces
+  >>> import z3c.jsonrpc.zcml
+
+  >>> class Skin: pass
+  >>> directlyProvides(Skin, interfaces.IJSONRPCSkinType)
+
+  >>> zope.component.provideUtility(Skin, interfaces.IJSONRPCSkinType,
+  ...     name='JSONRPC')
+  >>> z3c.jsonrpc.zcml.setDefaultJSONRPCSkin('JSONRPC')
+  >>> adapters = zope.component.getSiteManager().adapters
+
+Lookup the default skin for a request that has the
+
+  >>> adapters.lookup((interfaces.IJSONRPCRequest,), IDefaultSkin, '') is Skin
+  True



More information about the Checkins mailing list