xmlrpc.server — 基本 XML-RPC 伺服器

原始碼: Lib/xmlrpc/server.py


xmlrpc.server 模組為用 Python 編寫的 XML-RPC 伺服器提供了一個基本的伺服器框架。伺服器可以是獨立的,使用 SimpleXMLRPCServer;也可以嵌入到 CGI 環境中,使用 CGIXMLRPCRequestHandler

警告

xmlrpc.server 模組對惡意構造的資料不安全。如果您需要解析不可信或未經身份驗證的資料,請參閱 XML 安全

可用性:非 WASI。

此模組在 WebAssembly 上不起作用或不可用。有關更多資訊,請參閱 WebAssembly 平臺

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

建立一個新的伺服器例項。此類提供了用於註冊可透過 XML-RPC 協議呼叫的函式的方法。*requestHandler* 引數應該是一個請求處理程式例項的工廠;它預設為 SimpleXMLRPCRequestHandler。*addr* 和 *requestHandler* 引數傳遞給 socketserver.TCPServer 建構函式。如果 *logRequests* 為 true(預設值),則會記錄請求;將此引數設定為 false 將關閉日誌記錄。*allow_none* 和 *encoding* 引數傳遞給 xmlrpc.client 並控制將從伺服器返回的 XML-RPC 響應。*bind_and_activate* 引數控制建構函式是否立即呼叫 server_bind()server_activate();它預設為 true。將其設定為 false 允許程式碼在繫結地址之前操作 *allow_reuse_address* 類變數。*use_builtin_types* 引數傳遞給 loads() 函式,並控制在接收日期/時間值或二進位制資料時處理哪些型別;它預設為 false。

3.3 版本發生變更: 添加了 *use_builtin_types* 標誌。

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

建立一個新例項以在 CGI 環境中處理 XML-RPC 請求。*allow_none* 和 *encoding* 引數傳遞給 xmlrpc.client 並控制將從伺服器返回的 XML-RPC 響應。*use_builtin_types* 引數傳遞給 loads() 函式,並控制在接收日期/時間值或二進位制資料時處理哪些型別;它預設為 false。

3.3 版本發生變更: 添加了 *use_builtin_types* 標誌。

class xmlrpc.server.SimpleXMLRPCRequestHandler

建立一個新的請求處理程式例項。此請求處理程式支援 POST 請求,並修改日誌記錄,以便遵守 SimpleXMLRPCServer 建構函式引數的 *logRequests* 引數。

SimpleXMLRPCServer 物件

SimpleXMLRPCServer 類基於 socketserver.TCPServer,並提供了一種建立簡單、獨立的 XML-RPC 伺服器的方法。

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

註冊一個可以響應 XML-RPC 請求的函式。如果給定 *name*,它將是與 *function* 關聯的方法名,否則將使用 function.__name__。*name* 是一個字串,可能包含 Python 識別符號中不合法的字元,包括句點字元。

此方法也可以用作裝飾器。當用作裝飾器時,*name* 只能作為關鍵字引數給定,用於在 *name* 下注冊 *function*。如果沒有給出 *name*,將使用 function.__name__

3.7 版本發生變更: register_function() 可以用作裝飾器。

SimpleXMLRPCServer.register_instance(instance, allow_dotted_names=False)

註冊一個物件,該物件用於公開未使用 register_function() 註冊的方法名。如果 *instance* 包含一個 _dispatch() 方法,則使用請求的方法名和請求中的引數呼叫它。其 API 是 def _dispatch(self, method, params)(請注意,*params* 不表示可變引數列表)。如果它呼叫底層函式來執行其任務,則該函式以 func(*params) 的形式呼叫,展開引數列表。_dispatch() 的返回值作為結果返回給客戶端。如果 *instance* 沒有 _dispatch() 方法,則會搜尋與請求方法名匹配的屬性。

如果可選的 *allow_dotted_names* 引數為 true 且例項沒有 _dispatch() 方法,則如果請求的方法名包含句點,則會單獨搜尋方法名的每個元件,從而執行簡單的分層搜尋。然後使用請求中的引數呼叫此搜尋找到的值,並將返回值傳回給客戶端。

警告

啟用 *allow_dotted_names* 選項允許入侵者訪問您模組的全域性變數,並可能允許入侵者在您的機器上執行任意程式碼。僅在安全、封閉的網路上使用此選項。

SimpleXMLRPCServer.register_introspection_functions()

註冊 XML-RPC 內省函式 system.listMethodssystem.methodHelpsystem.methodSignature

SimpleXMLRPCServer.register_multicall_functions()

註冊 XML-RPC 多呼叫函式 system.multicall。

SimpleXMLRPCRequestHandler.rpc_paths

一個屬性值,它必須是一個元組,列出用於接收 XML-RPC 請求的 URL 的有效路徑部分。釋出到其他路徑的請求將導致 404“無此頁面”HTTP 錯誤。如果此元組為空,則所有路徑都將被視為有效。預設值為 ('/', '/RPC2')

SimpleXMLRPCServer 示例

伺服器程式碼

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

以下客戶端程式碼將呼叫前面伺服器提供的方法

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() 也可以用作裝飾器。前面的伺服器示例可以以裝飾器方式註冊函式

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

Lib/xmlrpc/server.py 模組中包含的以下示例顯示了一個允許使用點分名稱並註冊多呼叫函式的伺服器。

警告

啟用 *allow_dotted_names* 選項允許入侵者訪問您模組的全域性變數,並可能允許入侵者在您的機器上執行任意程式碼。僅在安全、封閉的網路中才使用此示例。

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)

此 ExampleService 演示可以從命令列呼叫

python -m xmlrpc.server

與上述伺服器互動的客戶端包含在 Lib/xmlrpc/client.py

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)

與演示 XMLRPC 伺服器互動的客戶端可以這樣呼叫

python -m xmlrpc.client

CGIXMLRPCRequestHandler

CGIXMLRPCRequestHandler 類可用於處理傳送到 Python CGI 指令碼的 XML-RPC 請求。

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

註冊一個可以響應 XML-RPC 請求的函式。如果給定 *name*,它將是與 *function* 關聯的方法名,否則將使用 function.__name__。*name* 是一個字串,可能包含 Python 識別符號中不合法的字元,包括句點字元。

此方法也可以用作裝飾器。當用作裝飾器時,*name* 只能作為關鍵字引數給定,用於在 *name* 下注冊 *function*。如果沒有給出 *name*,將使用 function.__name__

3.7 版本發生變更: register_function() 可以用作裝飾器。

CGIXMLRPCRequestHandler.register_instance(instance)

註冊一個物件,該物件用於公開未使用 register_function() 註冊的方法名。如果 *instance* 包含一個 _dispatch() 方法,則使用請求的方法名和請求中的引數呼叫它;返回值作為結果返回給客戶端。如果 *instance* 沒有 _dispatch() 方法,則會搜尋與請求方法名匹配的屬性;如果請求的方法名包含句點,則會單獨搜尋方法名的每個元件,從而執行簡單的分層搜尋。然後使用請求中的引數呼叫此搜尋找到的值,並將返回值傳回給客戶端。

CGIXMLRPCRequestHandler.register_introspection_functions()

註冊 XML-RPC 內省函式 system.listMethodssystem.methodHelpsystem.methodSignature

CGIXMLRPCRequestHandler.register_multicall_functions()

註冊 XML-RPC 多呼叫函式 system.multicall

CGIXMLRPCRequestHandler.handle_request(request_text=None)

處理 XML-RPC 請求。如果給出 *request_text*,它應該是 HTTP 伺服器提供的 POST 資料,否則將使用標準輸入的內容。

示例

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

文件化 XMLRPC 伺服器

這些類擴充套件了上述類,以響應 HTTP GET 請求提供 HTML 文件。伺服器可以是獨立的,使用 DocXMLRPCServer;也可以嵌入到 CGI 環境中,使用 DocCGIXMLRPCRequestHandler

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

建立一個新的伺服器例項。所有引數的含義與 SimpleXMLRPCServer 相同;*requestHandler* 預設為 DocXMLRPCRequestHandler

3.3 版本發生變更: 添加了 *use_builtin_types* 標誌。

class xmlrpc.server.DocCGIXMLRPCRequestHandler

建立一個新例項以在 CGI 環境中處理 XML-RPC 請求。

class xmlrpc.server.DocXMLRPCRequestHandler

建立一個新的請求處理程式例項。此請求處理程式支援 XML-RPC POST 請求、文件 GET 請求,並修改日誌記錄,以便遵守 DocXMLRPCServer 建構函式引數的 *logRequests* 引數。

DocXMLRPCServer 物件

DocXMLRPCServer 類派生自 SimpleXMLRPCServer,並提供了一種建立自文件化、獨立 XML-RPC 伺服器的方法。HTTP POST 請求被處理為 XML-RPC 方法呼叫。HTTP GET 請求透過生成 pydoc 風格的 HTML 文件來處理。這允許伺服器提供自己的基於 Web 的文件。

DocXMLRPCServer.set_server_title(server_title)

設定在生成的 HTML 文件中使用的標題。此標題將用於 HTML“title”元素內。

DocXMLRPCServer.set_server_name(server_name)

設定在生成的 HTML 文件中使用的名稱。此名稱將顯示在生成的文件頂部,位於“h1”元素內。

DocXMLRPCServer.set_server_documentation(server_documentation)

設定在生成的 HTML 文件中使用的描述。此描述將作為一段文字,顯示在伺服器名稱下方。

DocCGIXMLRPCRequestHandler

DocCGIXMLRPCRequestHandler 類派生自 CGIXMLRPCRequestHandler,並提供了一種建立自文件化 XML-RPC CGI 指令碼的方法。HTTP POST 請求被處理為 XML-RPC 方法呼叫。HTTP GET 請求透過生成 pydoc 風格的 HTML 文件來處理。這允許伺服器提供自己的基於 Web 的文件。

DocCGIXMLRPCRequestHandler.set_server_title(server_title)

設定在生成的 HTML 文件中使用的標題。此標題將用於 HTML“title”元素內。

DocCGIXMLRPCRequestHandler.set_server_name(server_name)

設定在生成的 HTML 文件中使用的名稱。此名稱將顯示在生成的文件頂部,位於“h1”元素內。

DocCGIXMLRPCRequestHandler.set_server_documentation(server_documentation)

設定在生成的 HTML 文件中使用的描述。此描述將作為一段文字,顯示在伺服器名稱下方。