xmlrpc.client — XML-RPC-klientåtkomst

Källkod: Lib/xmlrpc/client.py


XML-RPC är en Remote Procedure Call-metod som använder XML som skickas via HTTP(S) som transport. Med den kan en klient anropa metoder med parametrar på en fjärrserver (servern namnges av en URI) och få tillbaka strukturerade data. Den här modulen stöder skrivandet av XML-RPC-klientkod; den hanterar alla detaljer i översättningen mellan kompatibla Python-objekt och XML på kabeln.

Varning

Modulen xmlrpc.client är inte säker mot skadligt konstruerade data. Om du behöver analysera icke betrodda eller oautentiserade data, se XML-säkerhet.

Ändrad i version 3.5: För HTTPS URI:er utför xmlrpc.client nu alla nödvändiga certifikat- och värdnamnskontroller som standard.

Tillgänglighet: not WASI.

Den här modulen fungerar inte eller är inte tillgänglig på WebAssembly. Se WebAssembly-plattformar för mer information.

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

En instans av ServerProxy är ett objekt som hanterar kommunikationen med en XML-RPC-fjärrserver. Det obligatoriska första argumentet är en URI (Uniform Resource Indicator) som normalt är serverns URL. Det valfria andra argumentet är en transportfabriksinstans; som standard är det en intern SafeTransport-instans för https: URL:er och en intern HTTP Transport-instans i annat fall. Det valfria tredje argumentet är en kodning, som standard UTF-8. Det valfria fjärde argumentet är en felsökningsflagga.

Följande parametrar styr användningen av den returnerade proxyinstansen. Om allow_none är true kommer Python-konstanten None att översättas till XML; standardbeteendet är att None ger upphov till ett TypeError. Detta är en vanligt förekommande utvidgning av XML-RPC-specifikationen, men stöds inte av alla klienter och servrar; se http://ontosys.com/xml-rpc/extensions.php för en beskrivning. Flaggan use_builtin_types kan användas för att få datum/tidsvärden att presenteras som datetime.datetime-objekt och binära data att presenteras som bytes-objekt; denna flagga är false som standard. datetime.datetime-, bytes- och bytearray-objekt kan skickas till anrop. Parametern headers är en valfri sekvens av HTTP-rubriker som ska skickas med varje begäran, uttryckt som en sekvens av 2-tuples som representerar rubrikens namn och värde. (t.ex. [('Header-Name', 'value')]). Om en HTTPS-URL tillhandahålls kan context vara ssl.SSLContext och konfigurerar SSL-inställningarna för den underliggande HTTPS-anslutningen. Den obsoleta flaggan use_datetime liknar use_builtin_types men gäller endast datum-/tidsvärden.

Ändrad i version 3.3: Flaggan use_builtin_types har lagts till.

Ändrad i version 3.8: Parametern headers har lagts till.

Både HTTP- och HTTPS-transporterna stöder URL-syntaxtillägget för HTTP Basic Authentication: http://user:pass@host:port/path. Delen user:pass kommer att base64-kodas som en HTTP ”Authorization”-rubrik och skickas till fjärrservern som en del av anslutningsprocessen när en XML-RPC-metod anropas. Du behöver bara använda detta om fjärrservern kräver en användare och ett lösenord med Basic Authentication.

Den returnerade instansen är ett proxyobjekt med metoder som kan användas för att anropa motsvarande RPC-anrop på fjärrservern. Om fjärrservern stöder introspection API kan proxyn också användas för att fråga fjärrservern om de metoder den stöder (service discovery) och hämta andra serverassocierade metadata.

Typer som är konforma (dvs. som kan marshallas genom XML), inkluderar följande (och förutom där det anges, är de inte marshallade som samma Python-typ):

XML-RPC-typ

Python-typ

boolean

bool

int, i1, i2, i4, i8 eller biginteger

int i intervallet från -2147483648 till 2147483647. Värdena får taggen <int>.

double eller float

float. Värden får taggen <double>.

string

str

array

list eller tuple som innehåller överensstämmande element. Arrayer returneras som lists.

struct

dict. Nycklar måste vara strängar, värden kan vara vilken typ som helst. Objekt av användardefinierade klasser kan skickas in; endast deras __dict__-attribut överförs.

dateTime.iso8601

DateTime eller datetime.datetime. Returnerad typ beror på värdena för flaggorna use_builtin_types och use_datetime.

base64

Binary, bytes eller bytearray. Returnerad typ beror på värdet av flaggan use_builtin_types.

nil

Konstanten None. Överföring är tillåten endast om allow_none är true.

bigdecimal

decimal.Decimal. Endast returnerad typ.

Detta är den fullständiga uppsättning datatyper som stöds av XML-RPC. Metodanrop kan också ge upphov till en speciell Fault-instans, som används för att signalera XML-RPC-serverfel, eller ProtocolError som används för att signalera ett fel i HTTP/HTTPS-transportlagret. Både Fault och ProtocolError härstammar från en basklass som heter Error. Observera att xmlrpc-klientmodulen för närvarande inte marshalar instanser av underklasser av inbyggda typer.

När strängar skickas kommer tecken som är speciella för XML, t.ex. <, > och &, att escapas automatiskt. Det är dock anroparens ansvar att se till att strängen är fri från tecken som inte är tillåtna i XML, t.ex. kontrolltecken med ASCII-värden mellan 0 och 31 (förutom tab, newline och carriage return); om du inte gör detta kommer det att resultera i en XML-RPC-begäran som inte är välformad XML. Om du måste skicka godtyckliga bytes via XML-RPC, använd bytes eller bytearray klasserna eller Binary wrapper klassen som beskrivs nedan.

Server behålls som ett alias för ServerProxy för bakåtkompatibilitet. Ny kod bör använda ServerProxy.

Ändrad i version 3.5: Lagt till argumentet context.

Ändrad i version 3.6: Stöd för typtaggar med prefix har lagts till (t.ex. ex:nil). Lagt till stöd för unmarshalling av ytterligare typer som används av Apache XML-RPC-implementering för numeriska värden: i1, i2, i8, biginteger, float och bigdecimal. Se https://ws.apache.org/xmlrpc/types.html för en beskrivning.

Se även

XML-RPC HOWTO

En bra beskrivning av XML-RPC-operation och klientprogramvara på flera språk. Innehåller i stort sett allt som en XML-RPC-klientutvecklare behöver veta.

XML-RPC Introspektion

Beskriver XML-RPC-protokolltillägget för introspektion.

XML-RPC-specifikation

Den officiella specifikationen.

ServerProxy-objekt

En ServerProxy-instans har en metod som motsvarar varje fjärrproceduranrop som accepteras av XML-RPC-servern. När metoden anropas utförs ett RPC-anrop, som skickas med både namn och argumentsignatur (t.ex. kan samma metodnamn överbelastas med flera argumentsignaturer). RPC avslutas med att ett värde returneras, vilket kan vara antingen returnerade data i en överensstämmande typ eller ett Fault- eller ProtocolError-objekt som indikerar ett fel.

Servrar som stöder XML introspection API stöder några vanliga metoder som grupperas under det reserverade attributet system:

ServerProxy.system.listMethods()

Denna metod returnerar en lista med strängar, en för varje (icke-system) metod som stöds av XML-RPC-servern.

ServerProxy.system.methodSignature(name)

Denna metod tar emot en parameter, namnet på en metod som implementeras av XML-RPC-servern. Den returnerar en array av möjliga signaturer för denna metod. En signatur är en array av typer. Den första av dessa typer är metodens returtyp, resten är parametrar.

Eftersom flera signaturer (dvs. överbelastning) är tillåtna returnerar denna metod en lista med signaturer i stället för en singleton.

Själva signaturerna är begränsade till de parametrar på högsta nivå som förväntas av en metod. Om en metod t.ex. förväntar sig en array av structs som parameter och returnerar en sträng, är dess signatur helt enkelt ”string, array”. Om den förväntar sig tre heltal och returnerar en sträng är signaturen ”string, int, int, int”.

Om ingen signatur har definierats för metoden returneras ett värde som inte är en array. I Python betyder det att typen av det returnerade värdet kommer att vara något annat än list.

ServerProxy.system.methodHelp(name)

Denna metod tar en parameter, namnet på en metod som implementeras av XML-RPC-servern. Den returnerar en dokumentationssträng som beskriver användningen av den metoden. Om ingen sådan sträng finns tillgänglig returneras en tom sträng. Dokumentationssträngen kan innehålla HTML-markup.

Ändrad i version 3.5: Instanser av ServerProxy stöder context manager-protokollet för att stänga den underliggande transporten.

Här följer ett fungerande exempel. Serverkoden:

from xmlrpc.server import SimpleXMLRPCServer

def is_even(n):
    return n % 2 == 0

server = SimpleXMLRPCServer(("localhost", 8000))
print("Lyssnar på port 8000...")
server.register_function(is_even, "is_even")
server.serve_forever()

Klientkoden för den föregående servern:

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

class xmlrpc.client.DateTime

Klassen kan initialiseras med sekunder sedan epoken, en tidstupel, en ISO 8601 tid/datum-sträng eller en datetime.datetime-instans. Den har följande metoder, som huvudsakligen stöds för internt bruk av marshalling/unmarshalling-koden:

decode(string)

Acceptera en sträng som instansens nya tidsvärde.

encode(out)

Skriv XML-RPC-kodningen av detta DateTime-objekt till out-strömobjektet.

Den stöder också vissa av Pythons inbyggda operatorer genom metoderna rich comparison och __repr__().

Här följer ett fungerande exempel. Serverkoden:

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

Klientkoden för den föregående servern:

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

Binära objekt

class xmlrpc.client.Binary

Denna klass kan initialiseras från bytesdata (som kan innehålla NUL). Den primära tillgången till innehållet i ett Binary-objekt ges av ett attribut:

data

De binära data som inkapslas av Binary-instansen. Data tillhandahålls som ett bytes-objekt.

Binary-objekt har följande metoder, som huvudsakligen stöds för internt bruk av marshalling/unmarshalling-koden:

decode(bytes)

Acceptera ett base64 bytes-objekt och avkoda det som instansens nya data.

encode(out)

Skriv XML-RPC-bas 64-kodningen av detta binära objekt till out-strömobjektet.

De kodade data kommer att ha nya rader var 76:e tecken enligt RFC 2045 section 6.8, som var de facto-standarden för base64-specifikationen när XML-RPC-specifikationen skrevs.

Den stöder också vissa av Pythons inbyggda operatorer genom metoderna __eq__() och __ne__().

Exempel på användning av de binära objekten. Vi kommer att överföra en bild via 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()

Klienten hämtar bilden och sparar den i en fil:

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)

Felobjekt

class xmlrpc.client.Fault

Ett Fault-objekt kapslar in innehållet i en XML-RPC fault-tagg. Fault-objekt har följande attribut:

faultCode

Ett int som anger feltypen.

faultString

En sträng som innehåller ett diagnostiskt meddelande som är kopplat till felet.

I följande exempel ska vi avsiktligt orsaka ett Fault genom att returnera ett objekt av komplex typ. Serverkoden:

from xmlrpc.server import SimpleXMLRPCServer

# Ett marshalling-fel kommer att uppstå eftersom vi returnerar ett
# komplext tal
def add(x, y):
    returnerar x+y+0j

server = SimpleXMLRPCServer(("localhost", 8000))
print("Lyssnar på port 8000...")
server.register_function(add, 'add')

server.serve_forever()

Klientkoden för den föregående servern:

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)

ProtokollFel Objekt

class xmlrpc.client.ProtocolError

Ett ProtocolError-objekt beskriver ett protokollfel i det underliggande transportlagret (t.ex. ett 404 ”not found”-fel om servern som anges av URI:n inte existerar). Det har följande attribut:

url

Den URI eller URL som utlöste felet.

errcode

Felkoden.

errmsg

Felmeddelandet eller diagnossträngen.

headers

En dict som innehåller rubrikerna för den HTTP/HTTPS-begäran som utlöste felet.

I följande exempel kommer vi avsiktligt att orsaka ett ProtocolError genom att ange en ogiltig 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-objekt

Objektet MultiCall ger möjlighet att kapsla in flera anrop till en fjärrserver i en enda begäran [1].

class xmlrpc.client.MultiCall(server)

Skapa ett objekt som används för att boxcar-metodanrop. server är det slutliga målet för anropet. Anrop kan göras till resultatobjektet, men de kommer omedelbart att returnera None, och bara lagra anropets namn och parametrar i MultiCall-objektet. Anrop av själva objektet gör att alla lagrade anrop överförs som en enda system.multicall-begäran. Resultatet av detta anrop är en generator; genom att iterera över denna generator erhålls de enskilda resultaten.

Här följer ett exempel på användning av denna klass. Serverkoden:

from xmlrpc.server import SimpleXMLRPCServer

def add(x, y):
    return x + y

def subtract(x, y):
    returnerar x - y

def multiply(x, y):
    returnerar x * y

def divide(x, y):
    returnerar x // y

# En enkel server med enkla aritmetiska funktioner
server = SimpleXMLRPCServer(("localhost", 8000))
print("Lyssnar på port 8000...")
server.register_multicall_functions()
server.register_function(add, 'add')
server.register_function(subtract, 'subtrahera')
server.register_funktion(multiplicera, 'multiply')
server.register_function(divide, 'dividera')
server.serve_forever()

Klientkoden för den föregående servern:

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

Bekväma funktioner

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

Konverterar params till en XML-RPC-begäran eller till ett svar om methodresponse är sant. params kan vara antingen en tupel av argument eller en instans av undantagsklassen Fault. Om methodresponse är true kan endast ett enda värde returneras, vilket innebär att params måste ha längden 1. encoding, om det anges, är den kodning som ska användas i den XML som genereras; standard är UTF-8. Pythons None-värde kan inte användas i standard XML-RPC; för att tillåta att det används via ett tillägg, ange ett true-värde för allow_none.

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

Konverterar en XML-RPC-begäran eller ett svar till Python-objekt, en (params, methodname). params är en tupel av argument; methodname är en sträng, eller None om inget metodnamn finns i paketet. Om XML-RPC-paketet representerar ett feltillstånd, kommer denna funktion att ge upphov till ett Fault undantag. Flaggan use_builtin_types kan användas för att få datum/tidsvärden att presenteras som datetime.datetime-objekt och binära data att presenteras som bytes-objekt; denna flagga är falsk som standard.

Den föråldrade flaggan use_datetime liknar use_builtin_types men gäller bara för datum-/tidsvärden.

Ändrad i version 3.3: Flaggan use_builtin_types har lagts till.

Exempel på klientanvändning

# enkelt testprogram (från XML-RPC-specifikationen)
from xmlrpc.client import ServerProxy, Fel

# server = ServerProxy("http://localhost:8000") # lokal server
med ServerProxy("http://betty.userland.com") som proxy:

    print(proxy)

    försök:
        print(proxy.examples.getStateName(41))
    except Error as v:
        print("ERROR", v)

Om du vill komma åt en XML-RPC-server via en HTTP-proxy måste du definiera en anpassad transport. Följande exempel visar hur:

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

Exempel på användning av klient och server

Se Exempel på SimpleXMLRPCServer.

Fotnoter