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.