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

.. include:: ../includes/wasm-notavail.rst

.. 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 https://ws.apache.org/xmlrpc/types.html for a description.


.. seealso::

   `XML-RPC HOWTO <https://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 <https://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.

.. _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

      An int 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)
