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

XML-RPC es un método de llamada a procedimiento remoto que utiliza XML pasado a través de HTTP (S) como transporte. Con él, un cliente puede llamar a métodos con parámetros en un servidor remoto (el servidor es nombrado por un URI) y recuperar datos estructurados. Este módulo admite la escritura de código de cliente XML-RPC; maneja todos los detalles de la traducción entre objetos Python compatibles y XML en el cable.

Advertencia

los xmlrpc.client módulo no es seguro contra datos construidos maliciosamente. Si necesita analizar datos que no son de confianza o no autenticados, consulte Vulnerabilidades XML.

Modificado en la versión 3.5: Para HTTPS URI, xmlrpc.client ahora realiza todas las comprobaciones necesarias de certificados y nombres de host de forma predeterminada.

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

A ServerProxy instancia es un objeto que gestiona la comunicación con un servidor XML-RPC remoto. El primer argumento requerido es un URI (Uniform Resource Indicator) y normalmente será la URL del servidor. El segundo argumento opcional es una instancia de fábrica de transporte; por defecto es un interno SafeTransport instancia para https: URL y un HTTP interno Transport instancia de lo contrario. El tercer argumento opcional es una codificación, por defecto UTF-8. El cuarto argumento opcional es un indicador de depuración.

Los siguientes parámetros rigen el uso de la instancia de proxy devuelta. Si allow_none es cierto, la constante de Python None se traducirá a XML; el comportamiento predeterminado es para None para levantar un TypeError. Esta es una extensión de uso común para la especificación XML-RPC, pero no todos los clientes y servidores la admiten; ver http://ontosys.com/xml-rpc/extensions.php para una descripción. los use_builtin_types La bandera se puede usar para hacer que los valores de fecha / hora se presenten como datetime.datetime objetos y datos binarios que se presentarán como bytes objetos; esta bandera es falsa por defecto. datetime.datetime, bytes y bytearray los objetos se pueden pasar a las llamadas. los encabezados El parámetro es una secuencia opcional de encabezados HTTP para enviar con cada solicitud, expresada como una secuencia de 2 tuplas que representan el nombre y el valor del encabezado. (p.ej [(‘Header-Name’, ‘value’)]). Lo obsoleto use_datetime bandera es similar a use_builtin_types pero se aplica solo a los valores de fecha / hora.

Modificado en la versión 3.3: los use_builtin_types se agregó la bandera.

Modificado en la versión 3.8: los encabezados se agregó el parámetro.

Tanto los transportes HTTP como HTTPS admiten la extensión de sintaxis de URL para la autenticación básica HTTP: http://user:[email protected]:port/path. los user:pass La porción se codificará en base64 como un encabezado de ‘Autorización’ HTTP y se enviará al servidor remoto como parte del proceso de conexión al invocar un método XML-RPC. Solo necesita usar esto si el servidor remoto requiere un usuario y una contraseña de autenticación básica. Si se proporciona una URL HTTPS, contexto quizás ssl.SSLContext y configura la configuración SSL de la conexión HTTPS subyacente.

La instancia devuelta es un objeto proxy con métodos que se pueden utilizar para invocar las llamadas RPC correspondientes en el servidor remoto. Si el servidor remoto admite la API de introspección, el proxy también se puede utilizar para consultar al servidor remoto los métodos que admite (descubrimiento de servicios) y obtener otros metadatos asociados al servidor.

Los tipos que son conformes (por ejemplo, que se pueden clasificar a través de XML) incluyen lo siguiente (y, excepto donde se indique, no se clasifican como el mismo tipo de Python):

Tipo XML-RPC

Tipo de Python

boolean

bool

int, i1, i2, i4, i8 o biginteger

int en el rango de -2147483648 a 2147483647. Los valores obtienen el etiqueta.

double o float

float. Los valores obtienen el etiqueta.

string

str

array

list o tuple que contiene elementos conformables. Las matrices se devuelven como lists.

struct

dict. Las claves deben ser cadenas, los valores pueden ser de cualquier tipo conforme. Se pueden pasar objetos de clases definidas por el usuario; solo su __dict__ se transmite el atributo.

dateTime.iso8601

DateTime o datetime.datetime. El tipo devuelto depende de los valores de use_builtin_types y use_datetime banderas.

base64

Binary, bytes o bytearray. El tipo devuelto depende del valor del use_builtin_types bandera.

nil

los None constante. Solo se permite pasar si allow_none es verdad.

bigdecimal

decimal.Decimal. Solo tipo devuelto.

Este es el conjunto completo de tipos de datos admitidos por XML-RPC. Las llamadas a métodos también pueden generar una Fault instancia, utilizada para señalar errores del servidor XML-RPC, o ProtocolError utilizado para señalar un error en la capa de transporte HTTP / HTTPS. Ambos Fault y ProtocolError derivar de una clase base llamada Error. Tenga en cuenta que el módulo de cliente xmlrpc actualmente no clasifica instancias de subclases de tipos integrados.

Al pasar cadenas, los caracteres especiales de XML como <, >, y & se escapará automáticamente. Sin embargo, es responsabilidad de la persona que llama asegurarse de que la cadena no contenga caracteres que no estén permitidos en XML, como los caracteres de control con valores ASCII entre 0 y 31 (excepto, por supuesto, tabulación, nueva línea y retorno de carro); Si no lo hace, se generará una solicitud XML-RPC que no tiene un formato XML correcto. Si tiene que pasar bytes arbitrarios a través de XML-RPC, use bytes o bytearray clases o el Binary clase contenedora que se describe a continuación.

Server se conserva como un alias para ServerProxy para compatibilidad con versiones anteriores. Se debe usar un nuevo código ServerProxy.

Modificado en la versión 3.5: Agregó el contexto argumento.

Modificado en la versión 3.6: Se agregó soporte de etiquetas de tipo con prefijos (p. Ej. ex:nil). Se agregó soporte para deshacer los tipos adicionales utilizados por la implementación de Apache XML-RPC para números: i1, i2, i8, biginteger, float y bigdecimal. Ver http://ws.apache.org/xmlrpc/types.html para una descripción.

Ver también

CÓMO XML-RPC

Una buena descripción del funcionamiento de XML-RPC y del software de cliente en varios idiomas. Contiene prácticamente todo lo que un desarrollador de cliente XML-RPC necesita saber.

Introspección XML-RPC

Describe la extensión del protocolo XML-RPC para la introspección.

Especificación XML-RPC

La especificación oficial.

Erratas XML-RPC no oficiales

Las "erratas no oficiales de Fredrik Lundh, destinadas a aclarar ciertos detalles en la especificación XML-RPC, así como también dar pistas sobre las 'mejores prácticas' para usar al diseñar sus propias implementaciones XML-RPC".

Objetos ServerProxy

A ServerProxy La instancia tiene un método correspondiente a cada llamada de procedimiento remoto aceptada por el servidor XML-RPC. Llamar al método realiza un RPC, enviado por nombre y firma de argumento (por ejemplo, el mismo nombre de método puede sobrecargarse con múltiples firmas de argumento). El RPC finaliza devolviendo un valor, que puede ser datos devueltos en un tipo conforme o un Fault o ProtocolError objeto que indica un error.

Los servidores que admiten la API de introspección XML admiten algunos métodos comunes agrupados bajo el reservado system atributo:

ServerProxy.system.listMethods()

Este método devuelve una lista de cadenas, una para cada método (que no es del sistema) admitido por el servidor XML-RPC.

ServerProxy.system.methodSignature(name)

Este método toma un parámetro, el nombre de un método implementado por el servidor XML-RPC. Devuelve una matriz de posibles firmas para este método. Una firma es una variedad de tipos. El primero de estos tipos es el tipo de retorno del método, el resto son parámetros.

Debido a que se permiten múltiples firmas (es decir, sobrecarga), este método devuelve una lista de firmas en lugar de un singleton.

Las propias firmas están restringidas a los parámetros de nivel superior esperados por un método. Por ejemplo, si un método espera una matriz de estructuras como parámetro y devuelve una cadena, su firma es simplemente "cadena, matriz". Si espera tres enteros y devuelve una cadena, su firma es "cadena, int, int, int".

Si no se define una firma para el método, se devuelve un valor que no es una matriz. En Python, esto significa que el tipo de valor devuelto será diferente a list.

ServerProxy.system.methodHelp(name)

Este método toma un parámetro, el nombre de un método implementado por el servidor XML-RPC. Devuelve una cadena de documentación que describe el uso de ese método. Si no hay tal cadena disponible, se devuelve una cadena vacía. La cadena de documentación puede contener marcado HTML.

Modificado en la versión 3.5: Instancias de ServerProxy apoyen el administrador de contexto protocolo para cerrar el transporte subyacente.

A continuación se muestra un ejemplo práctico. El código del servidor:

from xmlrpc.server import SimpleXMLRPCServer

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

El código de cliente para el servidor anterior:

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

Objetos de fecha y hora

class xmlrpc.client.DateTime

Esta clase se puede inicializar con segundos desde la época, una tupla de tiempo, una cadena de fecha / hora ISO 8601 o una datetime.datetime ejemplo. Tiene los siguientes métodos, soportados principalmente para uso interno por el código de clasificación / eliminación de clasificación:

decode(string)

Acepte una cadena como el nuevo valor de tiempo de la instancia.

encode(out)

Escriba la codificación XML-RPC de este DateTime artículo al fuera objeto de flujo.

También es compatible con algunos de los operadores integrados de Python a través de una rica comparación y __repr__() métodos.

A continuación se muestra un ejemplo práctico. El código del servidor:

import datetime
from xmlrpc.server import SimpleXMLRPCServer
import xmlrpc.client

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

El código de cliente para el servidor anterior:

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

Objetos binarios

class xmlrpc.client.Binary

Esta clase puede inicializarse a partir de datos de bytes (que pueden incluir NUL). El acceso principal al contenido de un Binary El objeto es proporcionado por un atributo:

data

Los datos binarios encapsulados por el Binary ejemplo. Los datos se proporcionan como bytes objeto.

Binary Los objetos tienen los siguientes métodos, soportados principalmente para uso interno por el código de clasificación / eliminación:

decode(bytes)

Aceptar una base64 bytes objeto y decodificarlo como los nuevos datos de la instancia.

encode(out)

Escriba la codificación XML-RPC base 64 de este elemento binario en el fuera objeto de flujo.

Los datos codificados tendrán nuevas líneas cada 76 caracteres según RFC 2045 sección 6.8, cuales era la especificación base64 estándar de facto cuando se escribió la especificación XML-RPC.

También es compatible con algunos de los operadores integrados de Python a través de __eq__() y __ne__() métodos.

Ejemplo de uso de los objetos binarios. Vamos a transferir una imagen a través de XMLRPC:

from xmlrpc.server import SimpleXMLRPCServer
import xmlrpc.client

defpython_logo():withopen("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()

El cliente obtiene la imagen y la guarda en un archivo:

import xmlrpc.client

proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")withopen("fetched_python_logo.jpg","wb")as handle:
    handle.write(proxy.python_logo().data)

Objetos de falla

class xmlrpc.client.Fault

A Fault El objeto encapsula el contenido de una etiqueta de error XML-RPC. Los objetos de error tienen los siguientes atributos:

faultCode

Una cadena que indica el tipo de falla.

faultString

Una cadena que contiene un mensaje de diagnóstico asociado con la falla.

En el siguiente ejemplo vamos a causar intencionalmente un Fault devolviendo un objeto de tipo complejo. El código del servidor:

from xmlrpc.server import SimpleXMLRPCServer

# A marshalling error is going to occur because we're returning a# complex numberdefadd(x, y):return x+y+0j

server = SimpleXMLRPCServer(("localhost",8000))print("Listening on port 8000...")
server.register_function(add,'add')

server.serve_forever()

El código de cliente para el servidor anterior:

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)

Objetos ProtocolError

class xmlrpc.client.ProtocolError

A ProtocolError El objeto describe un error de protocolo en la capa de transporte subyacente (como un error 404 'no encontrado' si el servidor nombrado por el URI no existe). Tiene los siguientes atributos:

url

El URI o URL que desencadenó el error.

errcode

El código de error.

errmsg

El mensaje de error o la cadena de diagnóstico.

headers

Un dictado que contiene los encabezados de la solicitud HTTP / HTTPS que desencadenó el error.

En el siguiente ejemplo vamos a causar intencionalmente un ProtocolError proporcionando un URI no válido:

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)

Objetos MultiCall

los MultiCall El objeto proporciona una forma de encapsular varias llamadas a un servidor remoto en una sola solicitud 1.

class xmlrpc.client.MultiCall(server)

Cree un objeto utilizado para las llamadas al método boxcar. servidor es el objetivo final de la llamada. Se pueden realizar llamadas al objeto de resultado, pero volverán inmediatamente None, y solo almacena el nombre y los parámetros de la llamada en el MultiCall objeto. Llamar al objeto en sí hace que todas las llamadas almacenadas se transmitan como una sola system.multicall solicitud. El resultado de esta llamada es un generador; iterar sobre este generador produce los resultados individuales.

A continuación, se muestra un ejemplo de uso de esta clase. El código del servidor:

from xmlrpc.server import SimpleXMLRPCServer

defadd(x, y):return x + y

defsubtract(x, y):return x - y

defmultiply(x, y):return x * y

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

El código de cliente para el servidor anterior:

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

Funciones de conveniencia

xmlrpc.client.dumps(params, methodname=None, methodresponse=None, encoding=None, allow_none=False)

Convertir params en una solicitud XML-RPC. o en una respuesta si método respuesta es verdad. params puede ser una tupla de argumentos o una instancia del Fault clase de excepción. Si método respuesta es verdadero, solo se puede devolver un valor, lo que significa que params debe tener una longitud de 1. codificacion, si se proporciona, es la codificación que se utilizará en el XML generado; el predeterminado es UTF-8. Python None el valor no se puede utilizar en XML-RPC estándar; para permitir su uso a través de una extensión, proporcione un valor real para allow_none.

xmlrpc.client.loads(data, use_datetime=False, use_builtin_types=False)

Convierta una solicitud o respuesta XML-RPC en objetos Python, un (params,
methodname)
. params es una tupla de argumento; nombre del método es una cadena, o None si no hay un nombre de método presente en el paquete. Si el paquete XML-RPC representa una condición de falla, esta función generará un Fault excepción. los use_builtin_types La bandera se puede usar para hacer que los valores de fecha / hora se presenten como datetime.datetime objetos y datos binarios que se presentarán como bytes objetos; esta bandera es falsa por defecto.

Lo obsoleto use_datetime bandera es similar a use_builtin_types pero se aplica solo a los valores de fecha / hora.

Modificado en la versión 3.3: los use_builtin_types se agregó la bandera.

Ejemplo de uso del cliente

# simple test program (from the XML-RPC specification)from xmlrpc.client import ServerProxy, Error

# server = ServerProxy("http://localhost:8000") # local serverwith ServerProxy("http://betty.userland.com")as proxy:print(proxy)try:print(proxy.examples.getStateName(41))except Error as v:print("ERROR", v)

Para acceder a un servidor XML-RPC a través de un proxy HTTP, debe definir un transporte personalizado. El siguiente ejemplo muestra cómo:

import http.client
import xmlrpc.client

classProxiedTransport(xmlrpc.client.Transport):defset_proxy(self, host, port=None, headers=None):
        self.proxy = host, port
        self.proxy_headers = headers

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

Ejemplo de uso de cliente y servidor

Ver Ejemplo de SimpleXMLRPCServer.

Notas al pie

1

Este enfoque se ha presentado por primera vez en una discusión sobre xmlrpc.com.