[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