: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>

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

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

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

XML-RPC is a Remote Procedure Call method that uses XML passed via HTTP(S) 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`.

.. versionchanged:: 3.5

   For HTTPS URIs, :mod:`xmlrpc.client` now performs all the necessary
   certificate and hostname checks by default.

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

   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.

   The following parameters govern the use of the returned proxy instance.
   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
   <https://web.archive.org/web/20130120074804/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`, :class:`bytes` and :class:`bytearray` objects
   may be passed to calls.
   The *headers* parameter is an optional sequence of HTTP headers to send with
   each request, expressed as a sequence of 2-tuples representing the header
   name and value. (e.g. `[('Header-Name', 'value')]`).
   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.

.. versionchanged:: 3.8
    The *headers* parameter was added.

   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. If an HTTPS URL is provided, *context* may
   be :class:`ssl.SSLContext` and configures the SSL settings of the underlying
   HTTPS connection.

   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.

   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):

   .. tabularcolumns:: |l|L|

   +----------------------+-------------------------------------------------------+
   | XML-RPC type         | Python type                                           |
   +======================+=======================================================+
   | ``boolean``          | :class:`bool`                                         |
   +----------------------+-------------------------------------------------------+
   | ``int``, ``i1``,     | :class:`int` in range from -2147483648 to 2147483647. |
   | ``i2``,  ``i4``,     | Values get the ``<int>`` tag.                         |
   | ``i8`` or            |                                                       |
   | ``biginteger``       |                                                       |
   +----------------------+-------------------------------------------------------+
   | ``double`` or        | :class:`float`.  Values get the ``<double>`` tag.     |
   | ``float``            |                                                       |
   +----------------------+-------------------------------------------------------+
   | ``string``           | :class:`str`                                          |
   +----------------------+-------------------------------------------------------+
   | ``array``            | :class:`list` or :class:`tuple` containing            |
   |                      | conformable elements.  Arrays are returned as         |
   |                      | :class:`lists <list>`.                                |
   +----------------------+-------------------------------------------------------+
   | ``struct``           | :class:`dict`.  Keys must be strings, values may be   |
   |                      | any conformable type.  Objects of user-defined        |
   |                      | classes can be passed in; only their                  |
   |                      | :attr:`~object.__dict__` attribute is transmitted.    |
   +----------------------+-------------------------------------------------------+
   | ``dateTime.iso8601`` | :class:`DateTime` or :class:`datetime.datetime`.      |
   |                      | Returned type depends on values of                    |
   |                      | *use_builtin_types* and *use_datetime* flags.         |
   +----------------------+-------------------------------------------------------+
   | ``base64``           | :class:`Binary`, :class:`bytes` or                    |
   |                      | :class:`bytearray`.  Returned type depends on the     |
   |                      | value of the *use_builtin_types* flag.                |
   +----------------------+-------------------------------------------------------+
   | ``nil``              | The ``None`` constant.  Passing is allowed only if    |
   |                      | *allow_none* is true.                                 |
   +----------------------+-------------------------------------------------------+
   | ``bigdecimal``       | :class:`decimal.Decimal`.  Returned type only.        |
   +----------------------+-------------------------------------------------------+

   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 :class:`bytes` or :class:`bytearray` classes 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`.

   .. versionchanged:: 3.5
      Added the *context* argument.

   .. versionchanged:: 3.6
      Added support of type tags with prefixes (e.g. ``ex:nil``).
      Added support of unmarshalling additional types used by Apache XML-RPC
      implementation for numerics: ``i1``, ``i2``, ``i8``, ``biginteger``,
      ``float`` and ``bigdecimal``.
      See http://ws.apache.org/xmlrpc/types.html for a description.


.. 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://xmlrpc.scripting.com/spec.html>`_
      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:`~ServerProxy.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.

.. versionchanged:: 3.5

   Instances of :class:`ServerProxy` support the :term:`context manager` protocol
   for closing the underlying transport.


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

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

.. _datetime-objects:

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

.. class:: DateTime

   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:: decode(string)

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


   .. method:: 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
--------------

.. class:: Binary

   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:: 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:: decode(bytes)

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


   .. method:: 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:`RFC 2045 section 6.8 <2045#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
-------------

.. class:: Fault

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


   .. attribute:: faultCode

      A string indicating the fault type.


   .. attribute:: 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
---------------------

.. class:: ProtocolError

   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:: url

      The URI or URL that triggered the error.


   .. attribute:: errcode

      The error code.


   .. attribute:: errmsg

      The error message or diagnostic string.


   .. attribute:: 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 a 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
   with ServerProxy("http://betty.userland.com") as proxy:

       print(proxy)

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

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

   import http.client
   import xmlrpc.client

   class ProxiedTransport(xmlrpc.client.Transport):

       def set_proxy(self, host, port=None, headers=None):
           self.proxy = host, port
           self.proxy_headers = headers

       def make_connection(self, host):
           connection = http.client.HTTPConnection(*self.proxy)
           connection.set_tunnel(host, headers=self.proxy_headers)
           self._connection = host, connection
           return connection

   transport = ProxiedTransport()
   transport.set_proxy('proxy-server', 8080)
   server = xmlrpc.client.ServerProxy('http://betty.userland.com', transport=transport)
   print(server.examples.getStateName(41))


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

See :ref:`simplexmlrpcserver-example`.


.. rubric:: Footnotes

.. [#] This approach has been first presented in `a discussion on xmlrpc.com
   <https://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)
