xmlrpc.client — XML-RPC-Client-Zugriff¶
Quellcode: Lib/xmlrpc/client.py
XML-RPC ist eine Remote Procedure Call-Methode, die XML über HTTP(S) als Transport verwendet. Damit kann ein Client Methoden mit Parametern bei einem entfernten Server aufrufen (der Server wird durch eine URI benannt) und strukturierte Daten zurückerhalten. Dieses Modul unterstützt das Schreiben von XML-RPC-Client-Code; es kümmert sich um alle Details der Übersetzung zwischen konformen Python-Objekten und XML im Netzwerk.
Warnung
Das Modul xmlrpc.client ist nicht gegen böswillig konstruierte Daten gesichert. Wenn Sie nicht vertrauenswürdige oder nicht authentifizierte Daten parsen müssen, siehe XML-Sicherheit.
Geändert in Version 3.5: Für HTTPS-URIs führt xmlrpc.client standardmäßig alle notwendigen Zertifikats- und Hostnamenprüfungen durch.
Verfügbarkeit: nicht WASI.
Dieses Modul funktioniert nicht oder ist nicht auf WebAssembly verfügbar. Weitere Informationen finden Sie unter WebAssembly-Plattformen.
- class xmlrpc.client.ServerProxy(uri, transport=None, encoding=None, verbose=False, allow_none=False, use_datetime=False, use_builtin_types=False, *, headers=(), context=None)¶
Eine Instanz von
ServerProxyist ein Objekt, das die Kommunikation mit einem entfernten XML-RPC-Server verwaltet. Das erforderliche erste Argument ist eine URI (Uniform Resource Indicator) und normalerweise die URL des Servers. Das optionale zweite Argument ist eine Transport-Factory-Instanz; standardmäßig ist dies eine interneSafeTransport-Instanz für https:-URLs und andernfalls eine interne HTTP-Transport-Instanz. Das optionale dritte Argument ist eine Kodierung, standardmäßig UTF-8. Das optionale vierte Argument ist ein Debugging-Flag.Die folgenden Parameter steuern die Verwendung der zurückgegebenen Proxy-Instanz. Wenn allow_none wahr ist, wird die Python-Konstante
Nonein XML übersetzt; das Standardverhalten ist, dassNoneeinenTypeErrorauslöst. Dies ist eine häufig verwendete Erweiterung der XML-RPC-Spezifikation, wird aber nicht von allen Clients und Servern unterstützt; siehe http://ontosys.com/xml-rpc/extensions.php für eine Beschreibung. Das Flag use_builtin_types kann verwendet werden, um Datums-/Zeitwerte alsdatetime.datetime-Objekte und Binärdaten alsbytes-Objekte darzustellen; dieses Flag ist standardmäßig falsch.datetime.datetime,bytesundbytearray-Objekte können an Aufrufe übergeben werden. Der Parameter headers ist eine optionale Sequenz von HTTP-Headern, die mit jeder Anfrage gesendet werden sollen, ausgedrückt als Sequenz von 2-Tupeln, die den Header-Namen und -Wert darstellen. (z. B.[('Header-Name', 'wert')]). Wenn eine HTTPS-URL angegeben wird, kann context einssl.SSLContextsein und konfiguriert die SSL-Einstellungen der zugrunde liegenden HTTPS-Verbindung. Das veraltete Flag use_datetime ist ähnlich wie use_builtin_types, aber es gilt nur für Datums-/Zeitwerte.Geändert in Version 3.3: Das Flag use_builtin_types wurde hinzugefügt.
Geändert in Version 3.8: Der Parameter headers wurde hinzugefügt.
Sowohl der HTTP- als auch der HTTPS-Transport unterstützen die URL-Syntaxerweiterung für HTTP Basic Authentication:
http://user:pass@host:port/path. Der Teiluser:passwird als HTTP-‚Authorization‘-Header base64-codiert und während des Verbindungsprozesses beim Aufruf einer XML-RPC-Methode an den entfernten Server gesendet. Sie müssen dies nur verwenden, wenn der entfernte Server einen Basic Authentication-Benutzer und ein Passwort benötigt.Die zurückgegebene Instanz ist ein Proxy-Objekt mit Methoden, die zum Aufrufen entsprechender RPC-Aufrufe auf dem entfernten Server verwendet werden können. Wenn der entfernte Server die Introspektions-API unterstützt, kann der Proxy auch verwendet werden, um den entfernten Server nach den unterstützten Methoden abzufragen (Service Discovery) und andere serverbezogene Metadaten abzurufen.
Typen, die konform sind (z. B. die durch XML gemarshallt werden können), umfassen die folgenden (und soweit nicht anders angegeben, werden sie als derselbe Python-Typ unmarhallt)
XML-RPC-Typ
Python Typ
booleanint,i1,i2,i4,i8oderbigintegerintim Bereich von -2147483648 bis 2147483647. Werte erhalten das Tag<int>.doubleoderfloatfloat. Werte erhalten das Tag<double>.stringarraylistodertuplemit konformen Elementen. Arrays werden alsListenzurückgegeben.structdict. Schlüssel müssen Strings sein, Werte können beliebige konforme Typen sein. Objekte benutzerdefinierter Klassen können übergeben werden; nur ihr__dict__-Attribut wird übertragen.dateTime.iso8601DateTimeoderdatetime.datetime. Der zurückgegebene Typ hängt von den Werten der Flags use_builtin_types und use_datetime ab.base64Binary,bytesoderbytearray. Der zurückgegebene Typ hängt vom Wert des Flags use_builtin_types ab.nilDie Konstante
None. Die Übergabe ist nur erlaubt, wenn allow_none wahr ist.bigdecimaldecimal.Decimal. Nur zurückgegebener Typ.Dies ist die vollständige Menge der von XML-RPC unterstützten Datentypen. Methodenaufrufe können auch eine spezielle
Fault-Instanz auslösen, die zur Signalgebung von XML-RPC-Serverfehlern verwendet wird, oderProtocolError, die zur Signalgebung eines Fehlers in der HTTP/HTTPS-Transportschicht verwendet wird. SowohlFaultals auchProtocolErrorleiten sich von einer Basisklasse namensErrorab. Beachten Sie, dass das xmlrpc-Client-Modul derzeit keine Instanzen von Unterklassen von eingebauten Typen marshallt.Beim Übergeben von Strings werden XML-spezifische Zeichen wie
<,>und&automatisch escaped. Es liegt jedoch in der Verantwortung des Aufrufers sicherzustellen, dass der String frei von Zeichen ist, die in XML nicht zulässig sind, wie z. B. Steuerzeichen mit ASCII-Werten zwischen 0 und 31 (außer Tabulator, Zeilenvorschub und Wagenrücklauf); andernfalls wird eine XML-RPC-Anfrage generiert, die kein wohlgeformtes XML ist. Wenn Sie beliebige Bytes über XML-RPC übergeben müssen, verwenden Sie die Klassenbytesoderbytearrayoder die unten beschriebene Wrapper-KlasseBinary.Serverwird aus Gründen der Abwärtskompatibilität als Alias fürServerProxybeibehalten. Neuer Code sollteServerProxyverwenden.Geändert in Version 3.5: Das Argument context wurde hinzugefügt.
Geändert in Version 3.6: Unterstützung für Typ-Tags mit Präfixen (z. B.
ex:nil) hinzugefügt. Unterstützung für das Unmarshalling zusätzlicher Typen, die von der Apache XML-RPC-Implementierung für Numeriken verwendet werden:i1,i2,i8,biginteger,floatundbigdecimal. Siehe https://ws.apache.org/xmlrpc/types.html für eine Beschreibung.
Siehe auch
- XML-RPC HOWTO
Eine gute Beschreibung der Funktionsweise von XML-RPC und Client-Software in mehreren Sprachen. Enthält so ziemlich alles, was ein XML-RPC-Client-Entwickler wissen muss.
- XML-RPC-Introspektion
Beschreibt die XML-RPC-Protokollerweiterung für Introspektion.
- XML-RPC-Spezifikation
Die offizielle Spezifikation.
ServerProxy-Objekte¶
Eine Instanz von ServerProxy hat eine Methode, die jedem vom XML-RPC-Server akzeptierten entfernten Prozeduraufruf entspricht. Der Aufruf der Methode führt einen RPC durch, der sowohl nach Name als auch nach Argument-Signatur aufgerufen wird (z. B. kann derselbe Methodenname mit mehreren Argument-Signaturen überladen werden). Der RPC endet mit der Rückgabe eines Wertes, der entweder zurückgegebene Daten in einem konformen Typ oder ein Fault- oder ProtocolError-Objekt sein kann, das einen Fehler signalisiert.
Server, die die XML-Introspektions-API unterstützen, unterstützen einige gängige Methoden, die unter dem reservierten Attribut system zusammengefasst sind
- ServerProxy.system.listMethods()¶
Diese Methode gibt eine Liste von Strings zurück, eine für jede (Nicht-System-)Methode, die vom XML-RPC-Server unterstützt wird.
- ServerProxy.system.methodSignature(name)¶
Diese Methode nimmt einen Parameter entgegen, den Namen einer vom XML-RPC-Server implementierten Methode. Sie gibt ein Array möglicher Signaturen für diese Methode zurück. Eine Signatur ist ein Array von Typen. Der erste dieser Typen ist der Rückgabetyp der Methode, die restlichen sind Parameter.
Da mehrere Signaturen (d. h. Überladung) zulässig sind, gibt diese Methode eine Liste von Signaturen anstelle eines einzelnen Werts zurück.
Signaturen selbst sind auf die Top-Level-Parameter beschränkt, die von einer Methode erwartet werden. Wenn eine Methode beispielsweise ein Array von Structs als Parameter erwartet und einen String zurückgibt, ist ihre Signatur einfach „string, array“. Wenn sie drei Integer erwartet und einen String zurückgibt, ist ihre Signatur „string, int, int, int“.
Wenn für die Methode keine Signatur definiert ist, wird ein Wert zurückgegeben, der kein Array ist. In Python bedeutet dies, dass der Typ des zurückgegebenen Werts etwas anderes als eine Liste ist.
- ServerProxy.system.methodHelp(name)¶
Diese Methode nimmt einen Parameter entgegen, den Namen einer vom XML-RPC-Server implementierten Methode. Sie gibt einen Dokumentationsstring zurück, der die Verwendung dieser Methode beschreibt. Wenn keine solche Zeichenkette verfügbar ist, wird eine leere Zeichenkette zurückgegeben. Der Dokumentationsstring kann HTML-Markup enthalten.
Geändert in Version 3.5: Instanzen von ServerProxy unterstützen das Protokoll des Kontextmanagers zum Schließen des zugrunde liegenden Transports.
Ein funktionierendes Beispiel folgt. Der Servercode
from xmlrpc.server import SimpleXMLRPCServer
def is_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()
Der Client-Code für den vorherigen Server
import xmlrpc.client
with xmlrpc.client.ServerProxy("https://:8000/") as proxy:
print("3 is even: %s" % str(proxy.is_even(3)))
print("100 is even: %s" % str(proxy.is_even(100)))
DateTime-Objekte¶
- class xmlrpc.client.DateTime¶
Diese Klasse kann mit Sekunden seit der Epoche, einem Zeit-Tupel, einem ISO 8601 Zeit-/Datumsstring oder einer Instanz von
datetime.datetimeinitialisiert werden. Sie hat die folgenden Methoden, die hauptsächlich für den internen Gebrauch durch den Marshalling-/Unmarshalling-Code unterstützt werden- decode(string)¶
Akzeptiert eine Zeichenkette als neuen Zeitwert der Instanz.
Es unterstützt auch bestimmte eingebaute Operatoren von Python durch Methoden wie
reichhaltige Vergleicheund__repr__().
Ein funktionierendes Beispiel folgt. Der Servercode
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()
Der Client-Code für den vorherigen Server
import xmlrpc.client
import datetime
proxy = xmlrpc.client.ServerProxy("https://: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äre Objekte¶
- class xmlrpc.client.Binary¶
Diese Klasse kann aus Byte-Daten (die auch NULs enthalten können) initialisiert werden. Der primäre Zugriff auf den Inhalt eines
Binary-Objekts erfolgt über ein Attribut- data¶
Die von der
Binary-Instanz umschlossenen Binärdaten. Die Daten werden alsbytes-Objekt bereitgestellt.
Binary-Objekte haben die folgenden Methoden, die hauptsächlich für den internen Gebrauch durch den Marshalling-/Unmarshalling-Code unterstützt werden- decode(bytes)¶
Akzeptiert ein base64-kodiertes
bytes-Objekt und dekodiert es als neue Daten der Instanz.
- encode(out)¶
Schreibt die XML-RPC-Base64-Kodierung dieses binären Elements in den Ausgabestrom out.
Die kodierten Daten enthalten Zeilenumbrüche alle 76 Zeichen gemäß RFC 2045 Abschnitt 6.8, was der De-facto-Standard für Base64 war, als die XML-RPC-Spezifikation geschrieben wurde.
Es unterstützt auch bestimmte eingebaute Operatoren von Python durch die Methoden
__eq__()und__ne__().
Beispiel für die Verwendung von Binärobjekten. Wir werden ein Bild über XMLRPC übertragen
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()
Der Client erhält das Bild und speichert es in einer Datei
import xmlrpc.client
proxy = xmlrpc.client.ServerProxy("https://:8000/")
with open("fetched_python_logo.jpg", "wb") as handle:
handle.write(proxy.python_logo().data)
Fault-Objekte¶
- class xmlrpc.client.Fault¶
Ein
Fault-Objekt kapselt den Inhalt eines XML-RPC-Fehlertags. Fault-Objekte haben die folgenden Attribute- faultCode¶
Eine Ganzzahl, die den Fehlertyp angibt.
- faultString¶
Ein String, der eine Diagnosemeldung enthält, die mit dem Fehler verbunden ist.
Im folgenden Beispiel werden wir absichtlich einen Fault verursachen, indem wir ein komplexes Typobjekt zurückgeben. Der Servercode
from xmlrpc.server import SimpleXMLRPCServer
# A marshalling error is going to occur because we're returning a
# complex number
def add(x, y):
return x+y+0j
server = SimpleXMLRPCServer(("localhost", 8000))
print("Listening on port 8000...")
server.register_function(add, 'add')
server.serve_forever()
Der Client-Code für den vorherigen Server
import xmlrpc.client
proxy = xmlrpc.client.ServerProxy("https://: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)
ProtocolError-Objekte¶
- class xmlrpc.client.ProtocolError¶
Ein
ProtocolError-Objekt beschreibt einen Protokollfehler in der zugrunde liegenden Transportschicht (wie z. B. ein 404 „nicht gefunden“-Fehler, wenn der durch die URI benannte Server nicht existiert). Es hat die folgenden Attribute- url¶
Die URI oder URL, die den Fehler ausgelöst hat.
- errcode¶
Der Fehlercode.
- errmsg¶
Die Fehlermeldung oder Diagnosezeichenkette.
- headers¶
Ein Dictionary, das die Header der HTTP/HTTPS-Anfrage enthält, die den Fehler ausgelöst hat.
Im folgenden Beispiel werden wir absichtlich einen ProtocolError verursachen, indem wir eine ungültige URI bereitstellen
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-Objekte¶
Das MultiCall-Objekt bietet eine Möglichkeit, mehrere Aufrufe an einen entfernten Server zu einer einzigen Anfrage zu kapseln [1].
- class xmlrpc.client.MultiCall(server)¶
Erstellt ein Objekt, das zum Boxen von Methodenaufrufen verwendet wird. server ist das endgültige Ziel des Aufrufs. Aufrufe können an das Ergebnisobjekt gerichtet werden, aber sie geben sofort
Nonezurück und speichern nur den Aufrufnamen und die Parameter imMultiCall-Objekt. Das Aufrufen des Objekts selbst bewirkt, dass alle gespeicherten Aufrufe als eine einzigesystem.multicall-Anfrage übertragen werden. Das Ergebnis dieses Aufrufs ist ein Generator; das Iterieren über diesen Generator liefert die einzelnen Ergebnisse.
Ein Anwendungsbeispiel dieser Klasse folgt. Der Servercode
from xmlrpc.server import SimpleXMLRPCServer
def add(x, y):
return x + y
def subtract(x, y):
return x - y
def multiply(x, y):
return x * y
def divide(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()
Der Client-Code für den vorherigen Server
import xmlrpc.client
proxy = xmlrpc.client.ServerProxy("https://: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))
Komfortfunktionen¶
- xmlrpc.client.dumps(params, methodname=None, methodresponse=None, encoding=None, allow_none=False)¶
Konvertiert params in eine XML-RPC-Anfrage oder in eine Antwort, wenn methodresponse wahr ist. params kann entweder ein Tupel von Argumenten oder eine Instanz der Klasse
Faultsein. Wenn methodresponse wahr ist, kann nur ein einzelner Wert zurückgegeben werden, was bedeutet, dass params die Länge 1 haben muss. encoding, falls angegeben, ist die zu verwendende Kodierung im generierten XML; der Standard ist UTF-8. PythonsNone-Wert kann in Standard-XML-RPC nicht verwendet werden; um ihn über eine Erweiterung verwenden zu können, geben Sie für allow_none einen wahren Wert an.
- xmlrpc.client.loads(data, use_datetime=False, use_builtin_types=False)¶
Konvertiert eine XML-RPC-Anfrage oder -Antwort in Python-Objekte, ein
(params, methodname). params ist ein Tupel von Argumenten; methodname ist ein String oderNone, wenn kein Methodenname im Paket vorhanden ist. Wenn das XML-RPC-Paket einen Fehlerzustand darstellt, löst diese Funktion eine AusnahmeFaultaus. Das Flag use_builtin_types kann verwendet werden, um Datums-/Zeitwerte alsdatetime.datetime-Objekte und Binärdaten alsbytes-Objekte darzustellen; dieses Flag ist standardmäßig falsch.Das veraltete Flag use_datetime ist ähnlich wie use_builtin_types, aber es gilt nur für Datums-/Zeitwerte.
Geändert in Version 3.3: Das Flag use_builtin_types wurde hinzugefügt.
Beispiel für die Client-Nutzung¶
# simple test program (from the XML-RPC specification)
from xmlrpc.client import ServerProxy, Error
# server = ServerProxy("https://:8000") # local server
with ServerProxy("http://betty.userland.com") as proxy:
print(proxy)
try:
print(proxy.examples.getStateName(41))
except Error as v:
print("ERROR", v)
Um über einen HTTP-Proxy auf einen XML-RPC-Server zuzugreifen, müssen Sie einen benutzerdefinierten Transport definieren. Das folgende Beispiel zeigt, wie
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))
Beispiel für Client- und Server-Nutzung¶
Siehe SimpleXMLRPCServer Beispiel.
Fußnoten