[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-API] Typing in XML-RPC
Here's an example implementation to further illustrate my point. Regards, Anthony Liguori Anthony Liguori wrote: One of the first things I noticed is that the spec defines some extended types. This is a bit challenging in XML-RPC. It's unclear to me how 64 bit integer is represented (since XML-RPC only defines 32 bit integers). Also, defining void to an empty string is understandable but requires some special casing that really shouldn't be necessary.Here's what I propose:As a convention, we never use <struct>'s on the wire to directly represent structures. By convention, structs always appear as:<struct><member><name>kind</name><value><string>[typename]</string></value></member><member><name>value</name><value>[typevalue]</value></member> </struct>Where typename is the string representation of the type and typevalue is the type-specific value.Some common types would be:struct - use this to represent actual structs. typevalue is the normal encoding of a struct long - 64 bit representation of struct. typevalue is the string representationvoid - use to represent None. typevalue is ignored.What's nice about this sort of consistent approach is that we can write a marshalling/unmarshalling wrapper for Python that automagically does this conversion. Furthermore, if we did decide to support objects (as the current spec does), we could automagically marshal/unmarshal these over the wire.The general idea here is that this is an extensible typing system for XML-RPC.Another thing to consider is having a type of exception. I like exception based APIs (i'll say that for another email) however the format of the standard XML-RPC exception leaves a lot to be desired.Thoughts? Regards, Anthony Liguori _______________________________________________ xen-api mailing list xen-api@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-api import xmlrpclib import SimpleXMLRPCServer from types import DictType, NoneType class Marshaller(xmlrpclib.Marshaller): def dump_struct(self, value, write, escape=xmlrpclib.escape): write("""<value><struct> <member> <name>type</name> <value>struct</value> </member> <member> <name>value</name> """) self.__dump_struct(self, value, write, escape) write('</member></struct></value>\n') def __init__(self, encoding=None, allow_none=0): xmlrpclib.Marshaller.__init__(self, encoding, allow_none) self.__dump_struct = self.dispatch[DictType] self.dispatch[DictType] = Marshaller.dump_struct class Unmarshaller(xmlrpclib.Unmarshaller): dispatch_ext = {} def ext_struct(self, value): return value dispatch_ext['struct'] = ext_struct def end_struct(self, data): self.__end_struct(self, data) if self._on: a = self._stack[-1] if self.dispatch_ext.has_key(a['type']): a = self.dispatch_ext[a['type']](self, a['value']) self._stack[-1] = a self._on = not self._on def __init__(self, *args): xmlrpclib.Unmarshaller.__init__(self) self.__end_struct = self.dispatch["struct"] self.dispatch["struct"] = Unmarshaller.end_struct self._on = False xmlrpclib.FastMarshaller = Marshaller xmlrpclib.FastParser = xmlrpclib.ExpatParser xmlrpclib.FastUnmarshaller = Unmarshaller a = xmlrpclib.ServerProxy("http://localhost:8001/RPC2") print a.ident({'z': 'z', 'foo': {'poo': 'foo'}, 'doo': {'da': 'qe'}, 'a': 'b'}) _______________________________________________ xen-api mailing list xen-api@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-api
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |