[Zope3-Users] XMLRPC Method with **kwargs
Jeremy Roberts
jerbear at incrediblepear.com
Fri Dec 14 09:01:54 EST 2007
Michael Howitz wrote:
> Am 14.12.2007 um 01:29 schrieb Jeremy Roberts:
>> Hello zope3 users!
>>
>> I'm using Zope-3.3.1, and I'm trying to expose a method via xmlrpc and
>> I'm having trouble supporting a variable number of kwargs. My use case
>> does not know ahead of time how many arguments will be passed to the
>> method, hence the use of **kwargs in the method signature.
>>
>> I get the error:
>> Unexpected Zope exception: TypeError: renderCode() takes at most 1
>> argument (2 given).
>
>
> Hi!
>
> I think this is because XML-RPC does not support (optional) keyword
> arguments, you only may use positional arguments. A solution for
> optional arguments can be a dictionary containing the optional arguments
> for your XML-RPC-View as the last parameter. But this parameter is not
> optional itself.
>
> So your view could look like:
>
> class ToolCodeXMLRPC(MethodPublisher):
> """An XMLRPC view for ToolCode objects."""
>
> def renderCode(self, data):
> return self.context.renderCode(**data)
>
>
Thanks a ton Michael.
This suggestion ultimately led to a solution.
First I changed my XMLRPC view method signature to expect a positional
dictionary per your suggestion.
This led to another problem: my XML was passing a <struct> representing
a dictionary of params which was being unmarshalled from XML to method
call by Zope as keyword arguments - this resulted in an "Unexpected
keyword argument: 'color'" error.
In other words, the XML below is converted into a method call like so:
renderCode(color='green', number='3')
<?xml version="1.0"?>
<methodCall>
<methodName>renderCode</methodName>
<params>
<param>
<value>
<struct>
<member><name>color</name><value><string>green</string></value></member>
<member><name>number</name><value><string>3</string></value></member>
</struct>
</value>
</param>
</params>
</methodCall>
The fix was to pack my data struct into another struct with an explicit
keyword:
<?xml version="1.0"?>
<methodCall>
<methodName>renderCode</methodName>
<params>
<param>
<value>
<struct>
<member><name>data</name><value>
<struct>
<member><name>color</name><value><string>fuscia</string></value></member>
<member><name>number</name><value><string>3</string></value></member>
</struct>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>
(Note the nested struct.) This is converted into a method call like so:
renderCode(data={color: 'fuscia', number: '3'})
This worked like a charm. Thanks for all the help o mighty list - for I
now declare this code to be totally awesome.
-Jer
PS: 'fuscia' simply CAN'T be the correct spelling.
More information about the Zope3-users
mailing list