:mod:`xmlrpc.server` --- Basic XML-RPC servers
==============================================

.. module:: xmlrpc.server
   :synopsis: Basic XML-RPC server implementations.
.. moduleauthor:: Brian Quinlan <brianq@activestate.com>
.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>

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

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

The :mod:`xmlrpc.server` module provides a basic server framework for XML-RPC
servers written in Python.  Servers can either be free standing, using
:class:`SimpleXMLRPCServer`, or embedded in a CGI environment, using
:class:`CGIXMLRPCRequestHandler`.


.. class:: SimpleXMLRPCServer(addr, requestHandler=SimpleXMLRPCRequestHandler,\
               logRequests=True, allow_none=False, encoding=None,\
               bind_and_activate=True, use_builtin_types=False)

   Create a new server instance.  This class provides methods for registration of
   functions that can be called by the XML-RPC protocol.  The *requestHandler*
   parameter should be a factory for request handler instances; it defaults to
   :class:`SimpleXMLRPCRequestHandler`.  The *addr* and *requestHandler* parameters
   are passed to the :class:`socketserver.TCPServer` constructor.  If *logRequests*
   is true (the default), requests will be logged; setting this parameter to false
   will turn off logging.   The *allow_none* and *encoding* parameters are passed
   on to :mod:`xmlrpc.client` and control the XML-RPC responses that will be returned
   from the server. The *bind_and_activate* parameter controls whether
   :meth:`server_bind` and :meth:`server_activate` are called immediately by the
   constructor; it defaults to true. Setting it to false allows code to manipulate
   the *allow_reuse_address* class variable before the address is bound.
   The *use_builtin_types* parameter is passed to the
   :func:`~xmlrpc.client.loads` function and controls which types are processed
   when date/times values or binary data are received; it defaults to false.

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


.. class:: CGIXMLRPCRequestHandler(allow_none=False, encoding=None,\
               use_builtin_types=False)

   Create a new instance to handle XML-RPC requests in a CGI environment.  The
   *allow_none* and *encoding* parameters are passed on to :mod:`xmlrpc.client`
   and control the XML-RPC responses that will be returned from the server.
   The *use_builtin_types* parameter is passed to the
   :func:`~xmlrpc.client.loads` function and controls which types are processed
   when date/times values or binary data are received; it defaults to false.

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


.. class:: SimpleXMLRPCRequestHandler()

   Create a new request handler instance.  This request handler supports ``POST``
   requests and modifies logging so that the *logRequests* parameter to the
   :class:`SimpleXMLRPCServer` constructor parameter is honored.


.. _simple-xmlrpc-servers:

SimpleXMLRPCServer Objects
--------------------------

The :class:`SimpleXMLRPCServer` class is based on
:class:`socketserver.TCPServer` and provides a means of creating simple, stand
alone XML-RPC servers.


.. method:: SimpleXMLRPCServer.register_function(function, name=None)

   Register a function that can respond to XML-RPC requests.  If *name* is given,
   it will be the method name associated with *function*, otherwise
   ``function.__name__`` will be used.  *name* can be either a normal or Unicode
   string, and may contain characters not legal in Python identifiers, including
   the period character.


.. method:: SimpleXMLRPCServer.register_instance(instance, allow_dotted_names=False)

   Register an object which is used to expose method names which have not been
   registered using :meth:`register_function`.  If *instance* contains a
   :meth:`_dispatch` method, it is called with the requested method name and the
   parameters from the request.  Its API is ``def _dispatch(self, method, params)``
   (note that *params* does not represent a variable argument list).  If it calls
   an underlying function to perform its task, that function is called as
   ``func(*params)``, expanding the parameter list. The return value from
   :meth:`_dispatch` is returned to the client as the result.  If *instance* does
   not have a :meth:`_dispatch` method, it is searched for an attribute matching
   the name of the requested method.

   If the optional *allow_dotted_names* argument is true and the instance does not
   have a :meth:`_dispatch` method, then if the requested method name contains
   periods, each component of the method name is searched for individually, with
   the effect that a simple hierarchical search is performed.  The value found from
   this search is then called with the parameters from the request, and the return
   value is passed back to the client.

   .. warning::

      Enabling the *allow_dotted_names* option allows intruders to access your
      module's global variables and may allow intruders to execute arbitrary code on
      your machine.  Only use this option on a secure, closed network.


.. method:: SimpleXMLRPCServer.register_introspection_functions()

   Registers the XML-RPC introspection functions ``system.listMethods``,
   ``system.methodHelp`` and ``system.methodSignature``.


.. method:: SimpleXMLRPCServer.register_multicall_functions()

   Registers the XML-RPC multicall function system.multicall.


.. attribute:: SimpleXMLRPCRequestHandler.rpc_paths

   An attribute value that must be a tuple listing valid path portions of the URL
   for receiving XML-RPC requests.  Requests posted to other paths will result in a
   404 "no such page" HTTP error.  If this tuple is empty, all paths will be
   considered valid. The default value is ``('/', '/RPC2')``.


.. _simplexmlrpcserver-example:

SimpleXMLRPCServer Example
^^^^^^^^^^^^^^^^^^^^^^^^^^
Server code::

   from xmlrpc.server import SimpleXMLRPCServer
   from xmlrpc.server import SimpleXMLRPCRequestHandler

   # Restrict to a particular path.
   class RequestHandler(SimpleXMLRPCRequestHandler):
       rpc_paths = ('/RPC2',)

   # Create server
   server = SimpleXMLRPCServer(("localhost", 8000),
                               requestHandler=RequestHandler)
   server.register_introspection_functions()

   # Register pow() function; this will use the value of
   # pow.__name__ as the name, which is just 'pow'.
   server.register_function(pow)

   # Register a function under a different name
   def adder_function(x,y):
       return x + y
   server.register_function(adder_function, 'add')

   # Register an instance; all the methods of the instance are
   # published as XML-RPC methods (in this case, just 'mul').
   class MyFuncs:
       def mul(self, x, y):
           return x * y

   server.register_instance(MyFuncs())

   # Run the server's main loop
   server.serve_forever()

The following client code will call the methods made available by the preceding
server::

   import xmlrpc.client

   s = xmlrpc.client.ServerProxy('http://localhost:8000')
   print(s.pow(2,3))  # Returns 2**3 = 8
   print(s.add(2,3))  # Returns 5
   print(s.mul(5,2))  # Returns 5*2 = 10

   # Print list of available methods
   print(s.system.listMethods())


CGIXMLRPCRequestHandler
-----------------------

The :class:`CGIXMLRPCRequestHandler` class can be used to  handle XML-RPC
requests sent to Python CGI scripts.


.. method:: CGIXMLRPCRequestHandler.register_function(function, name=None)

   Register a function that can respond to XML-RPC requests. If  *name* is given,
   it will be the method name associated with  function, otherwise
   *function.__name__* will be used. *name* can be either a normal or Unicode
   string, and may contain  characters not legal in Python identifiers, including
   the period character.


.. method:: CGIXMLRPCRequestHandler.register_instance(instance)

   Register an object which is used to expose method names  which have not been
   registered using :meth:`register_function`. If  instance contains a
   :meth:`_dispatch` method, it is called with the  requested method name and the
   parameters from the  request; the return value is returned to the client as the
   result. If instance does not have a :meth:`_dispatch` method, it is searched
   for an attribute matching the name of the requested method; if  the requested
   method name contains periods, each  component of the method name is searched for
   individually,  with the effect that a simple hierarchical search is performed.
   The value found from this search is then called with the  parameters from the
   request, and the return value is passed  back to the client.


.. method:: CGIXMLRPCRequestHandler.register_introspection_functions()

   Register the XML-RPC introspection functions  ``system.listMethods``,
   ``system.methodHelp`` and  ``system.methodSignature``.


.. method:: CGIXMLRPCRequestHandler.register_multicall_functions()

   Register the XML-RPC multicall function ``system.multicall``.


.. method:: CGIXMLRPCRequestHandler.handle_request(request_text=None)

   Handle a XML-RPC request. If *request_text* is given, it  should be the POST
   data provided by the HTTP server,  otherwise the contents of stdin will be used.

Example::

   class MyFuncs:
       def mul(self, x, y):
           return x * y


   handler = CGIXMLRPCRequestHandler()
   handler.register_function(pow)
   handler.register_function(lambda x,y: x+y, 'add')
   handler.register_introspection_functions()
   handler.register_instance(MyFuncs())
   handler.handle_request()


Documenting XMLRPC server
-------------------------

These classes extend the above classes to serve HTML documentation in response
to HTTP GET requests.  Servers can either be free standing, using
:class:`DocXMLRPCServer`, or embedded in a CGI environment, using
:class:`DocCGIXMLRPCRequestHandler`.


.. class:: DocXMLRPCServer(addr, requestHandler=DocXMLRPCRequestHandler,\
               logRequests=True, allow_none=False, encoding=None,\
               bind_and_activate=True, use_builtin_types=True)

   Create a new server instance. All parameters have the same meaning as for
   :class:`SimpleXMLRPCServer`; *requestHandler* defaults to
   :class:`DocXMLRPCRequestHandler`.

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


.. class:: DocCGIXMLRPCRequestHandler()

   Create a new instance to handle XML-RPC requests in a CGI environment.


.. class:: DocXMLRPCRequestHandler()

   Create a new request handler instance. This request handler supports XML-RPC
   POST requests, documentation GET requests, and modifies logging so that the
   *logRequests* parameter to the :class:`DocXMLRPCServer` constructor parameter is
   honored.


.. _doc-xmlrpc-servers:

DocXMLRPCServer Objects
-----------------------

The :class:`DocXMLRPCServer` class is derived from :class:`SimpleXMLRPCServer`
and provides a means of creating self-documenting, stand alone XML-RPC
servers. HTTP POST requests are handled as XML-RPC method calls. HTTP GET
requests are handled by generating pydoc-style HTML documentation. This allows a
server to provide its own web-based documentation.


.. method:: DocXMLRPCServer.set_server_title(server_title)

   Set the title used in the generated HTML documentation. This title will be used
   inside the HTML "title" element.


.. method:: DocXMLRPCServer.set_server_name(server_name)

   Set the name used in the generated HTML documentation. This name will appear at
   the top of the generated documentation inside a "h1" element.


.. method:: DocXMLRPCServer.set_server_documentation(server_documentation)

   Set the description used in the generated HTML documentation. This description
   will appear as a paragraph, below the server name, in the documentation.


DocCGIXMLRPCRequestHandler
--------------------------

The :class:`DocCGIXMLRPCRequestHandler` class is derived from
:class:`CGIXMLRPCRequestHandler` and provides a means of creating
self-documenting, XML-RPC CGI scripts. HTTP POST requests are handled as XML-RPC
method calls. HTTP GET requests are handled by generating pydoc-style HTML
documentation. This allows a server to provide its own web-based documentation.


.. method:: DocCGIXMLRPCRequestHandler.set_server_title(server_title)

   Set the title used in the generated HTML documentation. This title will be used
   inside the HTML "title" element.


.. method:: DocCGIXMLRPCRequestHandler.set_server_name(server_name)

   Set the name used in the generated HTML documentation. This name will appear at
   the top of the generated documentation inside a "h1" element.


.. method:: DocCGIXMLRPCRequestHandler.set_server_documentation(server_documentation)

   Set the description used in the generated HTML documentation. This description
   will appear as a paragraph, below the server name, in the documentation.
