# `xmlrpc.server` — Servidores básicos XML-RPC

Código fuente: Lib/xmlrpc/server.py

El módulo `xmlrpc.server` proporciona un marco de servidor básico para servidores XML-RPC escritos en Python. Los servidores pueden ser independientes, utilizando `SimpleXMLRPCServer`, o integrados en un entorno CGI, utilizando `CGIXMLRPCRequestHandler`.

Advertencia

El módulo `xmlrpc.server` no es seguro contra datos construidos maliciosamente. Si necesita analizar sintácticamente datos no confiables o no autentificados, consulte Vulnerabilidades XML.

class `xmlrpc.server.``SimpleXMLRPCServer`(addr, requestHandler=SimpleXMLRPCRequestHandler, logRequests=True, allow_none=False, encoding=None, bind_and_activate=True, use_builtin_types=False)

  Crea una nueva instancia de servidor. Esta clase proporciona métodos para el registro de funciones que pueden ser llamados por el protocolo XML-RPC. El parámetro requestHandler debe ser un generador para las instancias del controlador de solicitudes; el valor predeterminado es `SimpleXMLRPCRequestHandler`. Los parámetros addr y requestHandler se pasan al constructor `socketserver. TCPServer`. Si logRequests es verdadero (valor predeterminado), se registrarán las solicitudes; establecer este parámetro como falso desactivará el registro. Los parámetros allow_none y encoding se pasan a `xmlrpc.client` y controlan las respuestas XML-RPC que se devolverán desde el servidor. El parámetro bind_and_activate controla si `server_bind()` y `server_activate()` son llamados inmediatamente por el constructor; por defecto es verdadero. Establecerlo como false permite que el código manipule la variable de clase allow_reuse_address antes de enlazar la dirección. El parámetro use_builtin_types se pasa a la función `loads()` y controla qué tipos se procesan cuando se reciben valores de fecha y hora o datos binarios; el valor predeterminado es false.

  Distinto en la versión 3.3: Se ha añadido el indicador use_builtin_types.

class `xmlrpc.server.``CGIXMLRPCRequestHandler`(allow_none=False, encoding=None, use_builtin_types=False)

  Crea una nueva instancia para gestionar solicitudes XML-RPC en un entorno CGI. Los parámetros allow_none y encoding se pasan a `xmlrpc.client` y controlan las respuestas XML-RPC que se devolverán desde el servidor. El parámetro use_builtin_types se pasa a la función `loads()` y controla qué tipos se procesan cuando se reciben valores de fecha y hora o datos binarios; el valor predeterminado es falso.

  Distinto en la versión 3.3: Se ha añadido el indicador use_builtin_types.

class `xmlrpc.server.``SimpleXMLRPCRequestHandler`

  Crea una nueva instancia del controlador de solicitudes. Este controlador de solicitudes admite solicitudes `POST` y modifica el registro para que se respete el parámetro logRequests del parámetro constructor `SimpleXMLRPCServer`.

## Objetos SimpleXMLRPCServer

La clase `SimpleXMLRPCServer` se basa en `socketserver.TCPServer` y proporciona un medio para crear servidores XML-RPC simples e independientes.

`SimpleXMLRPCServer.``register_function`(function=None, name=None)

  Registra una función que pueda responder a solicitudes XML-RPC. Si se proporciona name, este será el nombre del método asociado con function, en otro caso se utilizará `function.__name__`. name es una cadena de texto, y puede contener caracteres no permitidos en los identificadores de Python, incluido el caracter de punto.

  Este método también se puede utilizar como decorador. Cuando se usa como decorador, name solo se puede dar como un argumento de palabra clave para registrar function bajo nombre. Si no se proporciona name, se usará `function.__name__`.

  Distinto en la versión 3.7: `register_function()` puede ser usado como decorador.

`SimpleXMLRPCServer.``register_instance`(instance, allow_dotted_names=False)

  Registre un objeto que se usa para exponer nombre de métodos que no se han registrado usando `register_function()`. Si instance contiene un método `_dispatch()`, este será llamado con el nombre del método solicitado y los parámetros de la solicitud. Su API es `def _dispatch(self, method, params)` (tenga en cuenta que params no representa una lista de argumentos variables). Si se invoca a una función subyacente para realizar su tarea, esa función es llamada como `func(*params)`, expandiendo la lista de parámetros. El valor de retorno de `_dispatch()` se retorna al cliente como resultado. Si instance no tiene un método `_dispatch()`, se busca un atributo que coincida con el nombre del método solicitado.

  Si el argumento opcional allow_dotted_names es verdadero y la instancia no tiene un método `_dispatch()`, entonces si el nombre solicitado contiene puntos, cada componente del nombre del método se busca individualmente, con el efecto con el efecto que produce una búsqueda jerárquica simple. El valor encontrado en esta búsqueda es entonces llamado con los parámetros de la solicitud y el valor de retorno se devuelve al cliente.

  Advertencia

  Habilitando la opción allow_dotted_names permite a los intrusos acceder a las variables globales de su módulo y puede permitir que los intrusos ejecuten código arbitrario en su máquina. Utilice esta opción únicamente en una red cerrada y segura.

`SimpleXMLRPCServer.``register_introspection_functions`()

  Registre las funciones de introspección XML-RPC `system.listMethods`, `system.methodHelp` y `system.methodSignature`.

`SimpleXMLRPCServer.``register_multicall_functions`()

  Registre la función de llamada múltiple XML-RPC system.multicall.

`SimpleXMLRPCRequestHandler.``rpc_paths`

  Un valor de atributo que debe ser una tupla que enumere porciones de rota válidas de la URL para recibir solicitudes XML-RPC. Las solicitudes publicadas en otras rutas darán como resultado un error HTTP 404 «no existe tal página». Si esta tupla está vacía, todas las rutas se considerarán válidas. El valor predeterminado es `('/', '/RPC2')`.

### Ejemplo de SimpleXMLRPCServer

Código del servidor:

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

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

    # Create server
    with SimpleXMLRPCServer(('localhost', 8000),
                            requestHandler=RequestHandler) as server:
        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()

El siguiente código de cliente llamará a los métodos disponibles por el servidor anterior:

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

`register_function()` también se puede utilizar como decorador. El ejemplo de servidor anterior puede registrar funciones a modo de decorador:

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

    class RequestHandler(SimpleXMLRPCRequestHandler):
        rpc_paths = ('/RPC2',)

    with SimpleXMLRPCServer(('localhost', 8000),
                            requestHandler=RequestHandler) as server:
        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, using
        # register_function as a decorator. *name* can only be given
        # as a keyword argument.
        @server.register_function(name='add')
        def adder_function(x, y):
            return x + y

        # Register a function under function.__name__.
        @server.register_function
        def mul(x, y):
            return x * y

        server.serve_forever()

El siguiente ejemplo incluido en el módulo `Lib/xmlrpc/server.py` muestra un servidor que permite nombres con puntos y registra una función de llamada múltiple.

Advertencia

Habilitar la opción allow_dotted_names permite a los intrusos acceder a las variables globales de su módulo y puede permitir que los intrusos ejecuten código arbitrario en su máquina. Utilice este ejemplo únicamente dentro de una red cerrada y segura.

    import datetime

    class ExampleService:
        def getData(self):
            return '42'

        class currentTime:
            @staticmethod
            def getCurrentTime():
                return datetime.datetime.now()

    with SimpleXMLRPCServer(("localhost", 8000)) as server:
        server.register_function(pow)
        server.register_function(lambda x,y: x+y, 'add')
        server.register_instance(ExampleService(), allow_dotted_names=True)
        server.register_multicall_functions()
        print('Serving XML-RPC on localhost port 8000')
        try:
            server.serve_forever()
        except KeyboardInterrupt:
            print("\nKeyboard interrupt received, exiting.")
            sys.exit(0)

Esta demostración de ExampleService se puede invocar desde la línea de comando:

    python -m xmlrpc.server

El cliente que interactúa con el servidor anterior está incluido en Lib/xmlrpc/client.py:

    server = ServerProxy("http://localhost:8000")

    try:
        print(server.currentTime.getCurrentTime())
    except Error as v:
        print("ERROR", v)

    multi = MultiCall(server)
    multi.getData()
    multi.pow(2,9)
    multi.add(1,2)
    try:
        for response in multi():
            print(response)
    except Error as v:
        print("ERROR", v)

Este cliente que interactúa con el servidor XMLRPC de demostración se puede invocar como:

    python -m xmlrpc.client

## CGIXMLRPCRequestHandler

La clase `CGIXMLRPCRequestHandler` se puede usar para manejar solicitudes XML-RPC enviadas a scripts Python CGI.

`CGIXMLRPCRequestHandler.``register_function`(function=None, name=None)

  Registra una función que pueda responder a solicitudes XML-RPC. Si se proporciona name, este será el nombre del método asociado con function, en otro caso se utilizará `function.__name__`. name es una cadena de texto, y puede contener caracteres no permitidos en los identificadores de Python, incluido el caracter de punto.

  Este método también se puede utilizar como decorador. Cuando se usa como decorador, name solo se puede dar como un argumento de palabra clave para registrar function bajo nombre. Si no se proporciona name, se usará `function.__name__`.

  Distinto en la versión 3.7: `register_function()` puede ser usado como decorador.

`CGIXMLRPCRequestHandler.``register_instance`(instance)

  Registra un objeto que se usa para exponer nombres de métodos que no se han registrado usando `register_function()`. Si la instancia contiene un método `_dispatch()`, se llama con el nombre del método solicitado y los parámetros de la solicitud; el valor de retorno se devuelve al cliente como resultado. Si la instancia no tiene un método `_dispatch()`, se busca un atributo que coincida con el nombre del método solicitado; si el nombre del método contiene púntos, cada componente del nombre del método se busca individualmente, con el efecto con el efecto que produce una búsqueda jerárquica simple. El valor encontrado en esta búsqueda es entonces llamado con los parámetros de la solicitud y el valor de retorno se devuelve al cliente.

`CGIXMLRPCRequestHandler.``register_introspection_functions`()

  Registra las funciones de introspección `system.listMethods`, `system.methodHelp` y `system.methodSignature`.

`CGIXMLRPCRequestHandler.``register_multicall_functions`()

  Registra la función de llamada múltiple XML-RPC `system.multicall`.

`CGIXMLRPCRequestHandler.``handle_request`(request_text=None)

  Maneja una solicitud XML-RPC. Si se proporciona request_text, deberían ser los datos POST proporcionados por el servidor HTTP, de lo contrario se utilizará el contenido de stdin.

Ejemplo:

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

## Documentando el servidor XMLRPC

Estas clases amplían las clases anteriores para proporcionar documentación HTML en respuesta a solicitudes HTTP GET. Los servidores pueden ser independientes, usando `DocXMLRPCServer`, o integrados en un entorno CGI, usando `DocCGIXMLRPCRequestHandler`.

class `xmlrpc.server.``DocXMLRPCServer`(addr, requestHandler=DocXMLRPCRequestHandler, logRequests=True, allow_none=False, encoding=None, bind_and_activate=True, use_builtin_types=True)

  Crea una nueva instancia de servidor. Todos los parámetros tienen el mismo significado que para `SimpleXMLRPCServer`; requestHandler tiene como valor predeterminado `DocXMLRPCRequestHandler`.

  Distinto en la versión 3.3: Se ha añadido el indicador use_builtin_types.

class `xmlrpc.server.``DocCGIXMLRPCRequestHandler`

  Crea una nueva instancia para manejar solicitudes XML-RPC en un entorno CGI.

class `xmlrpc.server.``DocXMLRPCRequestHandler`

  Crea una nueva instancia de controlador de solicitudes. Este controlador de solicitudes admite solicitudes XML-RPC POST, solicitudes GET de documentación y modifica el registro para que se respete el parámetro logRequests del parámetro constructor `DocXMLRPCServer`.

## Objetos DocXMLRPCServer

La clase `DocXMLRPCServer` se deriva de `SimpleXMLRPCServer` y proporciona un medio para crear servidores XML-RPC autónomos y autodocumentados. Las solicitudes HTTP POST se manejan como llamadas al método XML-RPC. Las solicitudes HTTP GET se manejan generando documentación HTML al estilo pydoc. Esto permite que un servidor proporcione su propia documentación basada en web.

`DocXMLRPCServer.``set_server_title`(server_title)

  Establezca el título utilizado en la documentación HTML generada. Este título se utilizará dentro del elemento HTML «title».

`DocXMLRPCServer.``set_server_name`(server_name)

  Establezca el nombre utilizado en la documentación HTML generada. Este nombre aparecerá en la parte superior de la documentación generada dentro de un elemento «h1».

`DocXMLRPCServer.``set_server_documentation`(server_documentation)

  Establezca la descripción utilizada en la documentación HTML generada. Esta descripción aparecerá como un párrafo, debajo del nombre del servidor, en la documentación.

## DocCGIXMLRPCRequestHandler

La clase `DocCGIXMLRPCRequestHandler` se deriva de `CGIXMLRPCRequestHandler` y proporciona un medio para crear scripts CGI XML-RPC autodocumentados. Las solicitudes HTTP POST se manejan como llamadas al método XML-RPC. Las solicitudes HTTP GET se manejan generando documentación HTML al estilo pydoc. Esto permite que un servidor proporcione su propia documentación basada en web.

`DocCGIXMLRPCRequestHandler.``set_server_title`(server_title)

  Establezca el título utilizado en la documentación HTML generada. Este título se utilizará dentro del elemento HTML «title».

`DocCGIXMLRPCRequestHandler.``set_server_name`(server_name)

  Establezca el nombre utilizado en la documentación HTML generada. Este nombre aparecerá en la parte superior de la documentación generada dentro de un elemento «h1».

`DocCGIXMLRPCRequestHandler.``set_server_documentation`(server_documentation)

  Establezca la descripción utilizada en la documentación HTML generada. Esta descripción aparecerá como un párrafo, debajo del nombre del servidor, en la documentación.