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

原始碼:Lib/xmlrpc/server.py


xmlrpc.server 模組為以 Python 撰寫的 XML-RPC 伺服器提供了基本的伺服器框架。伺服器可以是獨立執行的(使用SimpleXMLRPCServer),或嵌入在 CGI 環境中(使用CGIXMLRPCRequestHandler)。

警告

xmlrpc.server 模組對於惡意建構的資料並不安全。如果你需要剖析不受信任或未經驗證的資料,請參閱XML 安全性

可用性: not WASI.

此模組在 WebAssembly 平台上不起作用或無法使用。更多資訊請參閱WebAssembly 平台

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

建立一個新的伺服器實例。此類別提供了可被 XML-RPC 協定呼叫之函式的註冊方法。requestHandler 參數應該是請求處理器實例的工廠(factory);它預設為SimpleXMLRPCRequestHandleraddrrequestHandler 參數會傳遞給socketserver.TCPServer 建構函式。如果logRequests 為 true(預設值),請求會被記錄;將此參數設定為 false 將關閉記錄。allow_noneencoding 參數會傳遞給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 旗標。

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

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

在 3.3 版的變更:新增use_builtin_types 旗標。

classxmlrpc.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 自我檢查函式 (introspection functions)system.listMethodssystem.methodHelpsystem.methodSignature

SimpleXMLRPCServer.register_multicall_functions()

註冊 XML-RPC 多重呼叫函式 (multicall function) system.multicall。

SimpleXMLRPCRequestHandler.rpc_paths

一個屬性值,必須是一個元組,列出接收 XML-RPC 請求的 URL 的有效路徑部分。發布到其他路徑的請求將導致 404 "no such page" HTTP 錯誤。如果此元組為空,所有路徑都將被視為有效。預設值為('/','/RPC2')

SimpleXMLRPCServer 範例

伺服器程式碼:

fromxmlrpc.serverimportSimpleXMLRPCServerfromxmlrpc.serverimportSimpleXMLRPCRequestHandler# 限制為特定路徑。classRequestHandler(SimpleXMLRPCRequestHandler):rpc_paths=('/RPC2',)# 建立伺服器withSimpleXMLRPCServer(('localhost',8000),requestHandler=RequestHandler)asserver:server.register_introspection_functions()# 註冊 pow() 函式;這將使用 pow.__name__ 的值作為名稱,即 'pow'。server.register_function(pow)# 以不同的名稱註冊函式defadder_function(x,y):returnx+yserver.register_function(adder_function,'add')# 註冊一個實例;該實例的所有方法都會被發布為 XML-RPC 方法(在此例中僅 'mul')。classMyFuncs:defmul(self,x,y):returnx*yserver.register_instance(MyFuncs())# 執行伺服器的主迴圈server.serve_forever()

以下用戶端程式碼將呼叫前述伺服器提供的方法:

importxmlrpc.clients=xmlrpc.client.ServerProxy('http://localhost:8000')print(s.pow(2,3))# 回傳 2**3 = 8print(s.add(2,3))# 回傳 5print(s.mul(5,2))# 回傳 5*2 = 10# 印出可用方法列表print(s.system.listMethods())

register_function() 也可以用作裝飾器。前述的伺服器範例可以用裝飾器方式註冊函式:

fromxmlrpc.serverimportSimpleXMLRPCServerfromxmlrpc.serverimportSimpleXMLRPCRequestHandlerclassRequestHandler(SimpleXMLRPCRequestHandler):rpc_paths=('/RPC2',)withSimpleXMLRPCServer(('localhost',8000),requestHandler=RequestHandler)asserver:server.register_introspection_functions()# 註冊 pow() 函式;這將使用 pow.__name__ 的值作為名稱,即 'pow'。server.register_function(pow)# 使用 register_function 作為裝飾器以不同的名稱註冊函式。# *name* 只能作為關鍵字引數給定。@server.register_function(name='add')defadder_function(x,y):returnx+y# 以 function.__name__ 註冊函式。@server.register_functiondefmul(x,y):returnx*yserver.serve_forever()

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

警告

啟用allow_dotted_names 選項來允許入侵者存取你模組的全域變數,並可能允許入侵者在你的機器上執行任意程式碼。請在安全、封閉的網路中才使用此範例。

importdatetimeclassExampleService:defgetData(self):return'42'classcurrentTime:@staticmethoddefgetCurrentTime():returndatetime.datetime.now()withSimpleXMLRPCServer(("localhost",8000))asserver:server.register_function(pow)server.register_function(lambdax,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()exceptKeyboardInterrupt:print("\nKeyboard interrupt received, exiting.")sys.exit(0)

此 ExampleService 示範可以從命令列觸發:

python-mxmlrpc.server

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

server=ServerProxy("http://localhost:8000")try:print(server.currentTime.getCurrentTime())exceptErrorasv:print("ERROR",v)multi=MultiCall(server)multi.getData()multi.pow(2,9)multi.add(1,2)try:forresponseinmulti():print(response)exceptErrorasv:print("ERROR",v)

與示範 XMLRPC 伺服器互動的此用戶端可以如下呼叫:

python-mxmlrpc.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() 註冊的方法名稱。如果實例包含_dispatch() 方法,它會以請求的方法名稱和來自請求的參數來被呼叫;回傳值會作為結果回傳給用戶端。如果實例沒有_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 資料,否則將使用 stdin 的內容。

範例:

classMyFuncs:defmul(self,x,y):returnx*yhandler=CGIXMLRPCRequestHandler()handler.register_function(pow)handler.register_function(lambdax,y:x+y,'add')handler.register_introspection_functions()handler.register_instance(MyFuncs())handler.handle_request()

記錄 XMLRPC 伺服器

這些類別擴充了上述類別,來為 HTTP GET 請求於回應中提供 HTML 文件。伺服器可以是獨立執行的(使用DocXMLRPCServer),或嵌入在 CGI 環境中(使用DocCGIXMLRPCRequestHandler)。

classxmlrpc.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 旗標。

classxmlrpc.server.DocCGIXMLRPCRequestHandler

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

classxmlrpc.server.DocXMLRPCRequestHandler

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

DocXMLRPCServer 物件

DocXMLRPCServer 類別衍生自SimpleXMLRPCServer,並提供了建立自我記錄 (self-documenting) 的獨立 XML-RPC 伺服器的方式。HTTP POST 請求會被作為 XML-RPC 方法呼叫來處理。HTTP GET 請求會透過產生 pydoc 風格的 HTML 文件來處理。這允許伺服器提供自己的網頁文件。

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 文件來處理。這允許伺服器提供自己的網頁文件。

DocCGIXMLRPCRequestHandler.set_server_title(server_title)

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

DocCGIXMLRPCRequestHandler.set_server_name(server_name)

設定在產生的 HTML 文件中使用的名稱。此名稱將顯示在產生的文件頂部的 "h1" 元素內。

DocCGIXMLRPCRequestHandler.set_server_documentation(server_documentation)

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