[Python-ideas] Improving xmlrpc introspection

Guido van Rossum guido at python.org
Wed Jun 18 16:42:21 CEST 2014


Since this is an internet client+server, can you please also consider
security as part of your design? Perhaps it's not always a good idea to
have that much introspectability on a web interface.


On Wed, Jun 18, 2014 at 3:23 AM, Claudiu Popa <pcmanticore at gmail.com> wrote:

> Hello.
>
> This idea proposes enhancing the xmlrpc library by adding a couple
> of introspectable servers and proxies. For instance, here's an output of
> using the current idioms.
>
> >>> proxy = ServerProxy('http://localhost:8000')
> >>> dir(proxy)
> ['_ServerProxy__allow_none', '_ServerProxy__close',
> '_ServerProxy__encoding', '_ServerProxy__handler',
> '_ServerProxy__host', '_ServerProxy__request',
> '_ServerProxy__transport', '_ServerProxy__verbose', '__call__',
> '__class__', '__delattr__', '__dict__', '__dir__', '__doc__',
> '__enter__', '__eq__', '__exit__', '__format__', '__ge__',
> '__getattr__'
> , '__getattribute__', '__gt__', '__hash__', '__init__', '__le__',
> '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
> '__reduce_ex__', '__repr__', '__setattr__',
> '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>
>
> Nothing useful in dir. The following works only if the server enables
> introspection:
>
> >>> proxy.system.listMethods()
> ['mul', 'pow', 'system.listMethods', 'system.methodHelp',
> 'system.methodSignature']
>
> Now, let's see what mul does:
>
> >>> proxy.mul
> <xmlrpc.client._Method object at 0x02AFB690>
> >>> help(proxy.mul)
> Help on _Method in module xmlrpc.client object:
>
> class _Method(builtins.object)
>  |  Methods defined here:
>  |
>  |  __call__(self, *args)
>  |
>  |  __getattr__(self, name)
>  |
>  |  __init__(self, send, name)
>  |      # some magic to bind an XML-RPC method to an RPC server.
>  |      # supports "nested" methods (e.g. examples.getStateName)
>  |
>  |  ----------------------------------------------------------------------
>  |  Data descriptors defined here:
>  |
>  |  __dict__
>  |      dictionary for instance variables (if defined)
>  |
>  |  __weakref__
>  |      list of weak references to the object (if defined)
>
>
>
> Nothing useful for us. Neither methodHelp, nor methodSignature are very
> useful:
>
> >>> proxy.system.methodHelp('mul')
> 'multiplication'
> >>> proxy.system.methodSignature('mul')
> 'signatures not supported'
>
>
> We can find out something about that method by calling it.
>
> >>> proxy.mul(1, 2, 3)
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "D:\Projects\cpython\lib\xmlrpc\client.py", line 1091, in __call__
>     return self.__send(self.__name, args)
>   File "D:\Projects\cpython\lib\xmlrpc\client.py", line 1421, in __request
>     verbose=self.__verbose
>   File "D:\Projects\cpython\lib\xmlrpc\client.py", line 1133, in request
>     return self.single_request(host, handler, request_body, verbose)
>   File "D:\Projects\cpython\lib\xmlrpc\client.py", line 1149, in
> single_request
>     return self.parse_response(resp)
>   File "D:\Projects\cpython\lib\xmlrpc\client.py", line 1320, in
> parse_response
>     return u.close()
>   File "D:\Projects\cpython\lib\xmlrpc\client.py", line 658, in close
>     raise Fault(**self._stack[0])
> xmlrpc.client.Fault: <Fault 1: "<class 'TypeError'>:mul() takes 3
> positional arguments but 4 were given">
>
>
> So, only after calling a method, one can find meaningful informations
> about it.
> My idea behaves like this:
>
> >>> from xmlrpc.client import MagicProxy # not a very good name, but it
> does some magic behind
> >>> proxy = MagicProxy('http://localhost:8000')
> >>> dir(proxy)
> ['_ServerProxy__allow_none', '_ServerProxy__close',
> '_ServerProxy__encoding', '_ServerProxy__handler',
> '_ServerProxy__host', '_ServerProxy__request', '_ServerProxy__trans
> ', '_ServerProxy__verbose', '__call__', '__class__', '__delattr__',
> '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__',
> '__format__', '__ge__',
> '__getattr__', '__getattribute__', '__gt__', '__hash__', '__init__',
> '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
> '__reduce_ex__', '__repr__', '__setattr__',
> '__sizeof__', '__str__', '__subclasshook__', '__weakref__',
> '_collect_methods', '_original_mul', '_original_pow', 'mul', 'pow']
> >>> proxy.mul
> <function mul at 0x035AD5D8>
> >>> proxy.pow
> <function pow at 0x035AD638>
> >>> help(proxy.mul)
> Help on function mul in module xmlrpc.client:
>
> mul(x:1, y) -> 2
>     multiplication
>
> >>> help(proxy.pow)
> Help on function pow in module xmlrpc.client:
>
> pow(*args, **kwargs)
>     pow(x, y[, z]) -> number
>
>     With two arguments, equivalent to x**y.  With three arguments,
>     equivalent to (x**y) % z, but may be more efficient (e.g. for ints).
>
> >>> proxy.mul(1)
> Traceback (most recent call last):
>   File "<console>", line 1, in <module>
> TypeError: mul() missing 1 required positional argument: 'y'
> >>> proxy.mul(1, 2, 3)
> Traceback (most recent call last):
>   File "<console>", line 1, in <module>
> TypeError: mul() takes 2 positional arguments but 3 were given
> >>> proxy.mul(1, 2)
> 2
> >>> import inspect
> >>> inspect.signature(proxy.mul)
> <Signature at 0x35d4b98 "(x:1, y) -> 2">
> >>>
>
> As we can  see, the registered methods can be introspected and calling
> one with the wrong number of arguments will not trigger a request to
> the server, but will fail right in the user's code.
> As a problem, it will work only for servers written in Python. For
> others will fallback to the current idiom.
> Would something like this be useful as an addition to the stdlib's
> xmlrpc module?
> If someone wants to test it, here's a rough patch against tip:
> https://gist.github.com/PCManticore/cf82ab421d4dc5c7f6ff.
>
> Thanks!
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>



-- 
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140618/5b045ce7/attachment-0001.html>


More information about the Python-ideas mailing list