xmlrpc.server — Einfache XML-RPC-Server

Quellcode: Lib/xmlrpc/server.py


Das Modul xmlrpc.server stellt ein grundlegendes Server-Framework für in Python geschriebene XML-RPC-Server bereit. Server können entweder eigenständig sein und SimpleXMLRPCServer verwenden oder in eine CGI-Umgebung eingebettet sein und CGIXMLRPCRequestHandler verwenden.

Warnung

Das Modul xmlrpc.server ist nicht sicher gegen böswillig konstruierte Daten. Wenn Sie nicht vertrauenswürdige oder nicht authentifizierte Daten parsen müssen, siehe XML-Sicherheit.

Verfügbarkeit: nicht WASI.

Dieses Modul funktioniert nicht oder ist nicht auf WebAssembly verfügbar. Weitere Informationen finden Sie unter WebAssembly-Plattformen.

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

Erstellt eine neue Serverinstanz. Diese Klasse stellt Methoden zur Registrierung von Funktionen bereit, die per XML-RPC-Protokoll aufgerufen werden können. Der Parameter requestHandler sollte eine Factory für Request-Handler-Instanzen sein; standardmäßig ist es SimpleXMLRPCRequestHandler. Die Parameter addr und requestHandler werden an den Konstruktor von socketserver.TCPServer übergeben. Wenn logRequests wahr ist (standardmäßig), werden Anfragen protokolliert; wenn dieser Parameter auf falsch gesetzt wird, wird die Protokollierung deaktiviert. Die Parameter allow_none und encoding werden an xmlrpc.client übergeben und steuern die vom Server zurückgegebenen XML-RPC-Antworten. Der Parameter bind_and_activate steuert, ob server_bind() und server_activate() sofort vom Konstruktor aufgerufen werden; er ist standardmäßig wahr. Wenn er auf falsch gesetzt wird, kann der Code die Klassenvariable allow_reuse_address manipulieren, bevor die Adresse gebunden wird. Der Parameter use_builtin_types wird an die Funktion loads() übergeben und steuert, welche Typen bei Datum/Zeit-Werten oder Binärdaten verarbeitet werden; er ist standardmäßig falsch.

Geändert in Version 3.3: Das Flag use_builtin_types wurde hinzugefügt.

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

Erstellt eine neue Instanz zur Verarbeitung von XML-RPC-Anfragen in einer CGI-Umgebung. Die Parameter allow_none und encoding werden an xmlrpc.client übergeben und steuern die vom Server zurückgegebenen XML-RPC-Antworten. Der Parameter use_builtin_types wird an die Funktion loads() übergeben und steuert, welche Typen bei Datum/Zeit-Werten oder Binärdaten verarbeitet werden; er ist standardmäßig falsch.

Geändert in Version 3.3: Das Flag use_builtin_types wurde hinzugefügt.

class xmlrpc.server.SimpleXMLRPCRequestHandler

Erstellt eine neue Request-Handler-Instanz. Dieser Request-Handler unterstützt POST-Anfragen und passt die Protokollierung an, sodass der Konstruktorparameter logRequests des SimpleXMLRPCServer berücksichtigt wird.

SimpleXMLRPCServer-Objekte

Die Klasse SimpleXMLRPCServer basiert auf socketserver.TCPServer und bietet eine Möglichkeit, einfache, eigenständige XML-RPC-Server zu erstellen.

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

Registriert eine Funktion, die auf XML-RPC-Anfragen antworten kann. Wenn name angegeben ist, ist dies der Methodenname, der mit function verknüpft ist, andernfalls wird function.__name__ verwendet. name ist eine Zeichenkette und kann Zeichen enthalten, die in Python-Bezeichnern nicht zulässig sind, einschließlich des Punktzeichens.

Diese Methode kann auch als Dekorator verwendet werden. Als Dekorator kann name nur als Schlüsselwortargument angegeben werden, um function unter name zu registrieren. Wenn kein name angegeben ist, wird function.__name__ verwendet.

Geändert in Version 3.7: register_function() kann als Dekorator verwendet werden.

SimpleXMLRPCServer.register_instance(instance, allow_dotted_names=False)

Registriert ein Objekt, das verwendet wird, um Methodennamen verfügbar zu machen, die nicht mit register_function() registriert wurden. Wenn instance eine _dispatch()-Methode enthält, wird diese mit dem angeforderten Methodennamen und den Parametern der Anfrage aufgerufen. Ihre API lautet def _dispatch(self, method, params) (beachten Sie, dass params keine variable Argumentliste darstellt). Wenn sie eine zugrunde liegende Funktion aufruft, um ihre Aufgabe zu erfüllen, wird diese Funktion als func(*params) aufgerufen, wobei die Parameterliste erweitert wird. Der Rückgabewert von _dispatch() wird dem Client als Ergebnis zurückgegeben. Wenn instance keine _dispatch()-Methode hat, wird nach einem Attribut gesucht, das dem Namen der angeforderten Methode entspricht.

Wenn das optionale Argument allow_dotted_names wahr ist und die Instanz keine _dispatch()-Methode hat, werden bei der angeforderten Methode, die Punkte enthält, jede Komponente des Methodennamens einzeln gesucht, mit dem Effekt, dass eine einfache hierarchische Suche durchgeführt wird. Der aus dieser Suche gefundene Wert wird dann mit den Parametern der Anfrage aufgerufen, und der Rückgabewert wird an den Client zurückgegeben.

Warnung

Die Aktivierung der Option allow_dotted_names erlaubt es Angreifern, auf die globalen Variablen Ihres Moduls zuzugreifen und möglicherweise beliebigen Code auf Ihrer Maschine auszuführen. Verwenden Sie diese Option nur in einem sicheren, geschlossenen Netzwerk.

SimpleXMLRPCServer.register_introspection_functions()

Registriert die XML-RPC-Introspektionsfunktionen system.listMethods, system.methodHelp und system.methodSignature.

SimpleXMLRPCServer.register_multicall_functions()

Registriert die XML-RPC-Multicall-Funktion system.multicall.

SimpleXMLRPCRequestHandler.rpc_paths

Ein Attributwert, der ein Tupel von gültigen Pfadkomponenten der URL für den Empfang von XML-RPC-Anfragen sein muss. Anfragen, die an andere Pfade gesendet werden, führen zu einem 404-HTTP-Fehler „Seite nicht gefunden“. Wenn dieses Tupel leer ist, werden alle Pfade als gültig betrachtet. Der Standardwert ist ('/', '/RPC2').

Beispiel für SimpleXMLRPCServer

Servercode

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

Der folgende Client-Code ruft die durch den vorherigen Server verfügbaren Methoden auf

import xmlrpc.client

s = xmlrpc.client.ServerProxy('https://: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() kann auch als Dekorator verwendet werden. Das vorherige Serverbeispiel kann Funktionen im Dekorator-Stil registrieren

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

Das folgende Beispiel, das im Modul Lib/xmlrpc/server.py enthalten ist, zeigt einen Server, der Punktnamen zulässt und eine Multicall-Funktion registriert.

Warnung

Die Aktivierung der Option allow_dotted_names erlaubt es Angreifern, auf die globalen Variablen Ihres Moduls zuzugreifen und möglicherweise beliebigen Code auf Ihrer Maschine auszuführen. Verwenden Sie dieses Beispiel nur in einem sicheren, geschlossenen Netzwerk.

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)

Diese ExampleService-Demo kann über die Kommandozeile aufgerufen werden

python -m xmlrpc.server

Der Client, der mit dem obigen Server interagiert, ist in Lib/xmlrpc/client.py enthalten

server = ServerProxy("https://: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)

Dieser Client, der mit dem Demo-XMLRPC-Server interagiert, kann aufgerufen werden als

python -m xmlrpc.client

CGIXMLRPCRequestHandler

Die Klasse CGIXMLRPCRequestHandler kann verwendet werden, um XML-RPC-Anfragen zu verarbeiten, die an Python-CGI-Skripte gesendet werden.

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

Registriert eine Funktion, die auf XML-RPC-Anfragen antworten kann. Wenn name angegeben ist, ist dies der Methodenname, der mit function verknüpft ist, andernfalls wird function.__name__ verwendet. name ist eine Zeichenkette und kann Zeichen enthalten, die in Python-Bezeichnern nicht zulässig sind, einschließlich des Punktzeichens.

Diese Methode kann auch als Dekorator verwendet werden. Als Dekorator kann name nur als Schlüsselwortargument angegeben werden, um function unter name zu registrieren. Wenn kein name angegeben ist, wird function.__name__ verwendet.

Geändert in Version 3.7: register_function() kann als Dekorator verwendet werden.

CGIXMLRPCRequestHandler.register_instance(instance)

Registriert ein Objekt, das verwendet wird, um Methodennamen verfügbar zu machen, die nicht mit register_function() registriert wurden. Wenn instance eine _dispatch()-Methode enthält, wird diese mit dem angeforderten Methodennamen und den Parametern der Anfrage aufgerufen; der Rückgabewert wird dem Client als Ergebnis zurückgegeben. Wenn instance keine _dispatch()-Methode hat, wird nach einem Attribut gesucht, das dem Namen der angeforderten Methode entspricht; wenn der angeforderte Methodennamen Punkte enthält, wird jede Komponente des Methodennamens einzeln gesucht, mit dem Effekt, dass eine einfache hierarchische Suche durchgeführt wird. Der aus dieser Suche gefundene Wert wird dann mit den Parametern der Anfrage aufgerufen, und der Rückgabewert wird an den Client zurückgegeben.

CGIXMLRPCRequestHandler.register_introspection_functions()

Registriert die XML-RPC-Introspektionsfunktionen system.listMethods, system.methodHelp und system.methodSignature.

CGIXMLRPCRequestHandler.register_multicall_functions()

Registriert die XML-RPC-Multicall-Funktion system.multicall.

CGIXMLRPCRequestHandler.handle_request(request_text=None)

Verarbeitet eine XML-RPC-Anfrage. Wenn request_text angegeben ist, sollten es die POST-Daten des HTTP-Servers sein, andernfalls werden die Inhalte von stdin verwendet.

Beispiel

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

Dokumentation von XMLRPC-Servern

Diese Klassen erweitern die obigen Klassen, um HTML-Dokumentation als Antwort auf HTTP-GET-Anfragen zu liefern. Server können entweder eigenständig sein und DocXMLRPCServer verwenden oder in eine CGI-Umgebung eingebettet sein und DocCGIXMLRPCRequestHandler verwenden.

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

Erstellt eine neue Serverinstanz. Alle Parameter haben die gleiche Bedeutung wie bei SimpleXMLRPCServer; requestHandler ist standardmäßig DocXMLRPCRequestHandler.

Geändert in Version 3.3: Das Flag use_builtin_types wurde hinzugefügt.

class xmlrpc.server.DocCGIXMLRPCRequestHandler

Erstellt eine neue Instanz zur Verarbeitung von XML-RPC-Anfragen in einer CGI-Umgebung.

class xmlrpc.server.DocXMLRPCRequestHandler

Erstellt eine neue Request-Handler-Instanz. Dieser Request-Handler unterstützt XML-RPC POST-Anfragen, Dokumentations-GET-Anfragen und passt die Protokollierung an, sodass der Konstruktorparameter logRequests des DocXMLRPCServer berücksichtigt wird.

DocXMLRPCServer-Objekte

Die Klasse DocXMLRPCServer leitet sich von SimpleXMLRPCServer ab und bietet eine Möglichkeit, selbstdokumentierende, eigenständige XML-RPC-Server zu erstellen. HTTP-POST-Anfragen werden als XML-RPC-Methodenaufrufe verarbeitet. HTTP-GET-Anfragen werden durch die Generierung von pydoc-ähnlicher HTML-Dokumentation verarbeitet. Dies ermöglicht es einem Server, seine eigene webbasierte Dokumentation bereitzustellen.

DocXMLRPCServer.set_server_title(server_title)

Legt den Titel fest, der in der generierten HTML-Dokumentation verwendet wird. Dieser Titel wird innerhalb des HTML-„title“-Elements verwendet.

DocXMLRPCServer.set_server_name(server_name)

Legt den Namen fest, der in der generierten HTML-Dokumentation verwendet wird. Dieser Name wird oben in der generierten Dokumentation in einem „h1“-Element angezeigt.

DocXMLRPCServer.set_server_documentation(server_documentation)

Legt die Beschreibung fest, die in der generierten HTML-Dokumentation verwendet wird. Diese Beschreibung wird als Absatz unterhalb des Servernamens in der Dokumentation angezeigt.

DocCGIXMLRPCRequestHandler

Die Klasse DocCGIXMLRPCRequestHandler leitet sich von CGIXMLRPCRequestHandler ab und bietet eine Möglichkeit, selbstdokumentierende XML-RPC-CGI-Skripte zu erstellen. HTTP-POST-Anfragen werden als XML-RPC-Methodenaufrufe verarbeitet. HTTP-GET-Anfragen werden durch die Generierung von pydoc-ähnlicher HTML-Dokumentation verarbeitet. Dies ermöglicht es einem Server, seine eigene webbasierte Dokumentation bereitzustellen.

DocCGIXMLRPCRequestHandler.set_server_title(server_title)

Legt den Titel fest, der in der generierten HTML-Dokumentation verwendet wird. Dieser Titel wird innerhalb des HTML-„title“-Elements verwendet.

DocCGIXMLRPCRequestHandler.set_server_name(server_name)

Legt den Namen fest, der in der generierten HTML-Dokumentation verwendet wird. Dieser Name wird oben in der generierten Dokumentation in einem „h1“-Element angezeigt.

DocCGIXMLRPCRequestHandler.set_server_documentation(server_documentation)

Legt die Beschreibung fest, die in der generierten HTML-Dokumentation verwendet wird. Diese Beschreibung wird als Absatz unterhalb des Servernamens in der Dokumentation angezeigt.