21.27. xmlrpc.server — 基本的 XML-RPC 服务器 — Python 文档
21.27. xmlrpc.server — 基本的 XML-RPC 服务器
源代码: :source:`Lib/xmlrpc/server.py`
xmlrpc.server 模块为用 Python 编写的 XML-RPC 服务器提供了一个基本的服务器框架。 服务器可以是独立的,使用 SimpleXMLRPCServer,或者嵌入在 CGI 环境中,使用 CGIXMLRPCRequestHandler。
- 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 为真(默认),请求将被记录; 将此参数设置为 false 将关闭日志记录。 allow_none 和 encoding 参数传递给 xmlrpc.client 并控制将从服务器返回的 XML-RPC 响应。 bind_and_activate参数控制
server_bind()
和server_activate()
是否被构造函数立即调用; 它默认为真。 将其设置为 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
- 创建一个新的请求处理程序实例。 此请求处理程序支持 [X30X] 请求并修改日志记录,以便支持 SimpleXMLRPCServer 构造函数参数的 logRequests 参数。
21.27.1。 SimpleXMLRPCServer 对象
SimpleXMLRPCServer 类基于 socketserver.TCPServer,提供了一种创建简单、独立的 XML-RPC 服务器的方法。
- SimpleXMLRPCServer.register_function(function, name=None)
- 注册一个可以响应 XML-RPC 请求的函数。 如果给出 name,它将是与 function 关联的方法名称,否则将使用
function.__name__
。 name 可以是普通字符串或 Unicode 字符串,并且可能包含 Python 标识符中不合法的字符,包括句点字符。
- 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 参数为真,并且实例没有
_dispatch()
方法,那么如果请求的方法名称包含句点,则单独搜索方法名称的每个组成部分,使用执行简单的分层搜索的效果。 然后使用请求中的参数调用从该搜索中找到的值,并将返回值传递回客户端。警告
启用 allow_dotted_names 选项允许入侵者访问您模块的全局变量,并可能允许入侵者在您的机器上执行任意代码。 仅在安全、封闭的网络上使用此选项。
- SimpleXMLRPCServer.register_introspection_functions()
- 注册 XML-RPC 内省函数
system.listMethods
、system.methodHelp
和system.methodSignature
。
- SimpleXMLRPCServer.register_multicall_functions()
- 注册 XML-RPC 多调用函数 system.multicall。
- SimpleXMLRPCRequestHandler.rpc_paths
- 一个属性值,它必须是一个元组,列出用于接收 XML-RPC 请求的 URL 的有效路径部分。 发布到其他路径的请求将导致 404“无此类页面”HTTP 错误。 如果此元组为空,则所有路径都将被视为有效。 默认值为
('/', '/RPC2')
。
21.27.1.1。 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('http://localhost: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())
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("http://localhost: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
21.27.2. CGIXMLRPCRequestHandler
CGIXMLRPCRequestHandler 类可用于处理发送到 Python CGI 脚本的 XML-RPC 请求。
- CGIXMLRPCRequestHandler.register_function(function, name=None)
- 注册一个可以响应 XML-RPC 请求的函数。 如果给出 name,它将是与函数关联的方法名称,否则将使用 function.__name__。 name 可以是普通字符串或 Unicode 字符串,并且可能包含 Python 标识符中不合法的字符,包括句点字符。
- CGIXMLRPCRequestHandler.register_instance(instance)
- 注册一个对象,该对象用于公开尚未使用 register_function() 注册的方法名称。 如果实例包含
_dispatch()
方法,则使用请求的方法名称和请求中的参数调用它; 返回值作为结果返回给客户端。 如果实例没有_dispatch()
方法,则搜索与请求的方法名称匹配的属性; 如果请求的方法名称包含句点,则单独搜索方法名称的每个组成部分,结果是执行简单的分层搜索。 然后使用请求中的参数调用从该搜索中找到的值,并将返回值传递回客户端。
- CGIXMLRPCRequestHandler.register_introspection_functions()
- 注册 XML-RPC 内省函数
system.listMethods
、system.methodHelp
和system.methodSignature
。
- CGIXMLRPCRequestHandler.register_multicall_functions()
- 注册 XML-RPC 多调用函数
system.multicall
。
- CGIXMLRPCRequestHandler.handle_request(request_text=None)
- 处理 XML-RPC 请求。 如果给出request_text,则应该是HTTP服务器提供的POST数据,否则会使用stdin的内容。
例子:
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()
21.27.3. 记录 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 参数得到遵守。
21.27.4. 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 文档中使用的描述。 此描述将在文档中显示为位于服务器名称下方的段落。
21.27.5。 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 文档中使用的描述。 此描述将在文档中显示为位于服务器名称下方的段落。