:mod:`xmlrpc.client` --- XML-RPC client access
==============================================

.. module:: xmlrpc.client
   :synopsis: XML-RPC client access.
.. moduleauthor:: Fredrik Lundh <fredrik@pythonware.com>
.. sectionauthor:: Eric S. Raymond <esr@snark.thyrsus.com>


.. XXX Not everything is documented yet.  It might be good to describe
   Marshaller, Unmarshaller, getparser and Transport.

**Source code:** :source:`Lib/xmlrpc/client.py`

--------------

XML-RPC is a Remote Procedure Call method that uses XML passed via HTTP as a
transport.  With it, a client can call methods with parameters on a remote
server (the server is named by a URI) and get back structured data.  This module
supports writing XML-RPC client code; it handles all the details of translating
between conformable Python objects and XML on the wire.


.. warning::

   The :mod:`xmlrpc.client` module is not secure against maliciously
   constructed data.  If you need to parse untrusted or unauthenticated data see
   :ref:`xml-vulnerabilities`.


.. class:: ServerProxy(uri, transport=None, encoding=None, verbose=False, \
                       allow_none=False, use_datetime=False, \
                       use_builtin_types=False)

   .. versionchanged:: 3.3
      The *use_builtin_types* flag was added.

   A :class:`ServerProxy` instance is an object that manages communication with a
   remote XML-RPC server.  The required first argument is a URI (Uniform Resource
   Indicator), and will normally be the URL of the server.  The optional second
   argument is a transport factory instance; by default it is an internal
   :class:`SafeTransport` instance for https: URLs and an internal HTTP
   :class:`Transport` instance otherwise.  The optional third argument is an
   encoding, by default UTF-8. The optional fourth argument is a debugging flag.
   If *allow_none* is true,  the Python constant ``None`` will be translated into
   XML; the default behaviour is for ``None`` to raise a :exc:`TypeError`. This is
   a commonly-used extension to the XML-RPC specification, but isn't supported by
   all clients and servers; see http://ontosys.com/xml-rpc/extensions.php for a
   description.  The *use_builtin_types* flag can be used to cause date/time values
   to be presented as :class:`datetime.datetime` objects and binary data to be
   presented as :class:`bytes` objects; this flag is false by default.
   :class:`datetime.datetime` and :class:`bytes` objects may be passed to calls.

   The obsolete *use_datetime* flag is similar to *use_builtin_types* but it
   applies only to date/time values.

   Both the HTTP and HTTPS transports support the URL syntax extension for HTTP
   Basic Authentication: ``http://user:pass@host:port/path``.  The  ``user:pass``
   portion will be base64-encoded as an HTTP 'Authorization' header, and sent to
   the remote server as part of the connection process when invoking an XML-RPC
   method.  You only need to use this if the remote server requires a Basic
   Authentication user and password.

   The returned instance is a proxy object with methods that can be used to invoke
   corresponding RPC calls on the remote server.  If the remote server supports the
   introspection API, the proxy can also be used to query the remote server for the
   methods it supports (service discovery) and fetch other server-associated
   metadata.

   :class:`ServerProxy` instance methods take Python basic types and objects as
   arguments and return Python basic types and classes.  Types that are conformable
   (e.g. that can be marshalled through XML), include the following (and except
   where noted, they are unmarshalled as the same Python type):

   +---------------------------------+---------------------------------------------+
   | Name                            | Meaning                                     |
   +=================================+=============================================+
   | :const:`boolean`                | The :const:`True` and :const:`False`        |
   |                                 | constants                                   |
   +---------------------------------+---------------------------------------------+
   | :const:`integers`               | Pass in directly                            |
   +---------------------------------+---------------------------------------------+
   | :const:`floating-point numbers` | Pass in directly                            |
   +---------------------------------+---------------------------------------------+
   | :const:`strings`                | Pass in directly                            |
   +---------------------------------+---------------------------------------------+
   | :const:`arrays`                 | Any Python sequence type containing         |
   |                                 | conformable elements. Arrays are returned   |
   |                                 | as lists                                    |
   +---------------------------------+---------------------------------------------+
   | :const:`structures`             | A Python dictionary. Keys must be strings,  |
   |                                 | values may be any conformable type. Objects |
   |                                 | of user-defined classes can be passed in;   |
   |                                 | only their *__dict__* attribute is          |
   |                                 | transmitted.                                |
   +---------------------------------+---------------------------------------------+
   | :const:`dates`                  | In seconds since the epoch.  Pass in an     |
   |                                 | instance of the :class:`DateTime` class or  |
   |                                 | a :class:`datetime.datetime` instance.      |
   +---------------------------------+---------------------------------------------+
   | :const:`binary data`            | Pass in an instance of the :class:`Binary`  |
   |                                 | wrapper class or a :class:`bytes` instance. |
   +---------------------------------+---------------------------------------------+

   This is the full set of data types supported by XML-RPC.  Method calls may also
   raise a special :exc:`Fault` instance, used to signal XML-RPC server errors, or
   :exc:`ProtocolError` used to signal an error in the HTTP/HTTPS transport layer.
   Both :exc:`Fault` and :exc:`ProtocolError` derive from a base class called
   :exc:`Error`.  Note that the xmlrpc client module currently does not marshal
   instances of subclasses of built-in types.

   When passing strings, characters special to XML such as ``<``, ``>``, and ``&``
   will be automatically escaped.  However, it's the caller's responsibility to
   ensure that the string is free of characters that aren't allowed in XML, such as
   the control characters with ASCII values between 0 and 31 (except, of course,
   tab, newline and carriage return); failing to do this will result in an XML-RPC
   request that isn't well-formed XML.  If you have to pass arbitrary bytes
   via XML-RPC, use the :class:`bytes` class or the class:`Binary` wrapper class
   described below.

   :class:`Server` is retained as an alias for :class:`ServerProxy` for backwards
   compatibility.  New code should use :class:`ServerProxy`.


.. seealso::

   `XML-RPC HOWTO <http://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html>`_
      A good description of XML-RPC operation and client software in several languages.
      Contains pretty much everything an XML-RPC client developer needs to know.

   `XML-RPC Introspection <http://xmlrpc-c.sourceforge.net/introspection.html>`_
      Describes the XML-RPC protocol extension for introspection.

   `XML-RPC Specification <http://www.xmlrpc.com/spec>`_
      The official specification.

   `Unofficial XML-RPC Errata <http://effbot.org/zone/xmlrpc-errata.htm>`_
      Fredrik Lundh's "unofficial errata, intended to clarify certain
      details in the XML-RPC specification, as well as hint at
      'best practices' to use when designing your own XML-RPC
      implementations."

.. _serverproxy-objects:

ServerProxy Objects
-------------------

A :class:`ServerProxy` instance has a method corresponding to each remote
procedure call accepted by the XML-RPC server.  Calling the method performs an
RPC, dispatched by both name and argument signature (e.g. the same method name
can be overloaded with multiple argument signatures).  The RPC finishes by
returning a value, which may be either returned data in a conformant type or a
:class:`Fault` or :class:`ProtocolError` object indicating an error.

Servers that support the XML introspection API support some common methods
grouped under the reserved :attr:`system` attribute:


.. method:: ServerProxy.system.listMethods()

   This method returns a list of strings, one for each (non-system) method
   supported by the XML-RPC server.


.. method:: ServerProxy.system.methodSignature(name)

   This method takes one parameter, the name of a method implemented by the XML-RPC
   server. It returns an array of possible signatures for this method. A signature
   is an array of types. The first of these types is the return type of the method,
   the rest are parameters.

   Because multiple signatures (ie. overloading) is permitted, this method returns
   a list of signatures rather than a singleton.

   Signatures themselves are restricted to the top level parameters expected by a
   method. For instance if a method expects one array of structs as a parameter,
   and it returns a string, its signature is simply "string, array". If it expects
   three integers and returns a string, its signature is "string, int, int, int".

   If no signature is defined for the method, a non-array value is returned. In
   Python this means that the type of the returned  value will be something other
   than list.


.. method:: ServerProxy.system.methodHelp(name)

   This method takes one parameter, the name of a method implemented by the XML-RPC
   server.  It returns a documentation string describing the use of that method. If
   no such string is available, an empty string is returned. The documentation
   string may contain HTML markup.


A working example follows. The server code::

   from xmlrpc.server import SimpleXMLRPCServer

   def is_even(n):
       return n%2 == 0

   server = SimpleXMLRPCServer(("localhost", 8000))
   print("Listening on port 8000...")
   server.register_function(is_even, "is_even")
   server.serve_forever()

The client code for the preceding server::

   import xmlrpc.client

   proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
   print("3 is even: %s" % str(proxy.is_even(3)))
   print("100 is even: %s" % str(proxy.is_even(100)))

.. _datetime-objects:

DateTime Objects
----------------

This class may be initialized with seconds since the epoch, a time
tuple, an ISO 8601 time/date string, or a :class:`datetime.datetime`
instance.  It has the following methods, supported mainly for internal
use by the marshalling/unmarshalling code:


.. method:: DateTime.decode(string)

   Accept a string as the instance's new time value.


.. method:: DateTime.encode(out)

   Write the XML-RPC encoding of this :class:`DateTime` item to the *out* stream
   object.

It also supports certain of Python's built-in operators through rich comparison
and :meth:`__repr__` methods.

A working example follows. The server code::

   import datetime
   from xmlrpc.server import SimpleXMLRPCServer
   import xmlrpc.client

   def today():
       today = datetime.datetime.today()
       return xmlrpc.client.DateTime(today)

   server = SimpleXMLRPCServer(("localhost", 8000))
   print("Listening on port 8000...")
   server.register_function(today, "today")
   server.serve_forever()

The client code for the preceding server::

   import xmlrpc.client
   import datetime

   proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")

   today = proxy.today()
   # convert the ISO8601 string to a datetime object
   converted = datetime.datetime.strptime(today.value, "%Y%m%dT%H:%M:%S")
   print("Today: %s" % converted.strftime("%d.%m.%Y, %H:%M"))

.. _binary-objects:

Binary Objects
--------------

This class may be initialized from bytes data (which may include NULs). The
primary access to the content of a :class:`Binary` object is provided by an
attribute:


.. attribute:: Binary.data

   The binary data encapsulated by the :class:`Binary` instance.  The data is
   provided as a :class:`bytes` object.

:class:`Binary` objects have the following methods, supported mainly for
internal use by the marshalling/unmarshalling code:


.. method:: Binary.decode(bytes)

   Accept a base64 :class:`bytes` object and decode it as the instance's new data.


.. method:: Binary.encode(out)

   Write the XML-RPC base 64 encoding of this binary item to the out stream object.

   The encoded data will have newlines every 76 characters as per
   `RFC 2045 section 6.8 <http://tools.ietf.org/html/rfc2045#section-6.8>`_,
   which was the de facto standard base64 specification when the
   XML-RPC spec was written.

It also supports certain of Python's built-in operators through :meth:`__eq__`
and :meth:`__ne__` methods.

Example usage of the binary objects.  We're going to transfer an image over
XMLRPC::

   from xmlrpc.server import SimpleXMLRPCServer
   import xmlrpc.client

   def python_logo():
       with open("python_logo.jpg", "rb") as handle:
           return xmlrpc.client.Binary(handle.read())

   server = SimpleXMLRPCServer(("localhost", 8000))
   print("Listening on port 8000...")
   server.register_function(python_logo, 'python_logo')

   server.serve_forever()

The client gets the image and saves it to a file::

   import xmlrpc.client

   proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
   with open("fetched_python_logo.jpg", "wb") as handle:
       handle.write(proxy.python_logo().data)

.. _fault-objects:

Fault Objects
-------------

A :class:`Fault` object encapsulates the content of an XML-RPC fault tag. Fault
objects have the following attributes:


.. attribute:: Fault.faultCode

   A string indicating the fault type.


.. attribute:: Fault.faultString

   A string containing a diagnostic message associated with the fault.

In the following example we're going to intentionally cause a :exc:`Fault` by
returning a complex type object.  The server code::

   from xmlrpc.server import SimpleXMLRPCServer

   # A marshalling error is going to occur because we're returning a
   # complex number
   def add(x,y):
       return x+y+0j

   server = SimpleXMLRPCServer(("localhost", 8000))
   print("Listening on port 8000...")
   server.register_function(add, 'add')

   server.serve_forever()

The client code for the preceding server::

   import xmlrpc.client

   proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
   try:
       proxy.add(2, 5)
   except xmlrpc.client.Fault as err:
       print("A fault occurred")
       print("Fault code: %d" % err.faultCode)
       print("Fault string: %s" % err.faultString)



.. _protocol-error-objects:

ProtocolError Objects
---------------------

A :class:`ProtocolError` object describes a protocol error in the underlying
transport layer (such as a 404 'not found' error if the server named by the URI
does not exist).  It has the following attributes:


.. attribute:: ProtocolError.url

   The URI or URL that triggered the error.


.. attribute:: ProtocolError.errcode

   The error code.


.. attribute:: ProtocolError.errmsg

   The error message or diagnostic string.


.. attribute:: ProtocolError.headers

   A dict containing the headers of the HTTP/HTTPS request that triggered the
   error.

In the following example we're going to intentionally cause a :exc:`ProtocolError`
by providing an invalid URI::

   import xmlrpc.client

   # create a ServerProxy with an URI that doesn't respond to XMLRPC requests
   proxy = xmlrpc.client.ServerProxy("http://google.com/")

   try:
       proxy.some_method()
   except xmlrpc.client.ProtocolError as err:
       print("A protocol error occurred")
       print("URL: %s" % err.url)
       print("HTTP/HTTPS headers: %s" % err.headers)
       print("Error code: %d" % err.errcode)
       print("Error message: %s" % err.errmsg)

MultiCall Objects
-----------------

The :class:`MultiCall` object provides a way to encapsulate multiple calls to a
remote server into a single request [#]_.


.. class:: MultiCall(server)

   Create an object used to boxcar method calls. *server* is the eventual target of
   the call. Calls can be made to the result object, but they will immediately
   return ``None``, and only store the call name and parameters in the
   :class:`MultiCall` object. Calling the object itself causes all stored calls to
   be transmitted as a single ``system.multicall`` request. The result of this call
   is a :term:`generator`; iterating over this generator yields the individual
   results.

A usage example of this class follows.  The server code ::

   from xmlrpc.server import SimpleXMLRPCServer

   def add(x,y):
       return x+y

   def subtract(x, y):
       return x-y

   def multiply(x, y):
       return x*y

   def divide(x, y):
       return x/y

   # A simple server with simple arithmetic functions
   server = SimpleXMLRPCServer(("localhost", 8000))
   print("Listening on port 8000...")
   server.register_multicall_functions()
   server.register_function(add, 'add')
   server.register_function(subtract, 'subtract')
   server.register_function(multiply, 'multiply')
   server.register_function(divide, 'divide')
   server.serve_forever()

The client code for the preceding server::

   import xmlrpc.client

   proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
   multicall = xmlrpc.client.MultiCall(proxy)
   multicall.add(7,3)
   multicall.subtract(7,3)
   multicall.multiply(7,3)
   multicall.divide(7,3)
   result = multicall()

   print("7+3=%d, 7-3=%d, 7*3=%d, 7/3=%d" % tuple(result))


Convenience Functions
---------------------

.. function:: dumps(params, methodname=None, methodresponse=None, encoding=None, allow_none=False)

   Convert *params* into an XML-RPC request. or into a response if *methodresponse*
   is true. *params* can be either a tuple of arguments or an instance of the
   :exc:`Fault` exception class.  If *methodresponse* is true, only a single value
   can be returned, meaning that *params* must be of length 1. *encoding*, if
   supplied, is the encoding to use in the generated XML; the default is UTF-8.
   Python's :const:`None` value cannot be used in standard XML-RPC; to allow using
   it via an extension,  provide a true value for *allow_none*.


.. function:: loads(data, use_datetime=False, use_builtin_types=False)

   Convert an XML-RPC request or response into Python objects, a ``(params,
   methodname)``.  *params* is a tuple of argument; *methodname* is a string, or
   ``None`` if no method name is present in the packet. If the XML-RPC packet
   represents a fault condition, this function will raise a :exc:`Fault` exception.
   The *use_builtin_types* flag can be used to cause date/time values to be
   presented as :class:`datetime.datetime` objects and binary data to be
   presented as :class:`bytes` objects; this flag is false by default.

   The obsolete *use_datetime* flag is similar to *use_builtin_types* but it
   applies only to date/time values.

   .. versionchanged:: 3.3
      The *use_builtin_types* flag was added.


.. _xmlrpc-client-example:

Example of Client Usage
-----------------------

::

   # simple test program (from the XML-RPC specification)
   from xmlrpc.client import ServerProxy, Error

   # server = ServerProxy("http://localhost:8000") # local server
   server = ServerProxy("http://betty.userland.com")

   print(server)

   try:
       print(server.examples.getStateName(41))
   except Error as v:
       print("ERROR", v)

To access an XML-RPC server through a proxy, you need to define  a custom
transport.  The following example shows how:

.. Example taken from http://lowlife.jp/nobonobo/wiki/xmlrpcwithproxy.html

::

   import xmlrpc.client, http.client

   class ProxiedTransport(xmlrpc.client.Transport):
       def set_proxy(self, proxy):
           self.proxy = proxy
       def make_connection(self, host):
           self.realhost = host
           h = http.client.HTTP(self.proxy)
           return h
       def send_request(self, connection, handler, request_body):
           connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))
       def send_host(self, connection, host):
           connection.putheader('Host', self.realhost)

   p = ProxiedTransport()
   p.set_proxy('proxy-server:8080')
   server = xmlrpc.client.Server('http://time.xmlrpc.com/RPC2', transport=p)
   print(server.currentTime.getCurrentTime())


Example of Client and Server Usage
----------------------------------

See :ref:`simplexmlrpcserver-example`.


.. rubric:: Footnotes

.. [#] This approach has been first presented in `a discussion on xmlrpc.com
   <http://web.archive.org/web/20060624230303/http://www.xmlrpc.com/discuss/msgReader$1208?mode=topic>`_.
.. the link now points to webarchive since the one at
.. http://www.xmlrpc.com/discuss/msgReader%241208 is broken (and webadmin
.. doesn't reply)
