xmlrpclib
xmlrpclib — XML-RPC client access
注意
该xmlrpclib
模块已被重命名为xmlrpc.client
Python 3. 当将源代码转换为Python 3时,2to3工具将自动适应导入。
2.2版本中的新功能。
源代码:
Lib / xmlrpclib.py
XML-RPC是一种远程过程调用方法,它使用通过HTTP(S)传递的XML作为传输。通过它,客户端可以使用远程服务器上的参数调用方法(服务器通过URI命名)并获取结构化数据。该模块支持编写XML-RPC客户端代码; 它处理所有在线上一致的Python对象和XML之间的转换细节。
警告
该xmlrpclib
模块对恶意构建的数据不安全。如果您需要解析不可信或未经身份验证的数据,请参阅XML漏洞。
在版本2.7.9中更改:对于HTTPS URI,xmlrpclib
现在默认执行所有必需的证书和主机名检查。
class xmlrpclib.ServerProxy(uri[, transport[, encoding[, verbose[, allow_none[, use_datetime[, context]]]]]])
甲ServerProxy
实例是管理与远程XML-RPC服务器的通信的对象。所需的第一个参数是一个URI(统一资源指示符),通常是服务器的URL。可选的第二个参数是一个传输工厂实例; 默认情况下它是SafeTransport
https:URL的内部Transport
实例,否则是内部HTTP 实例。可选的第三个参数是一个编码,默认为UTF-8。可选的第四个参数是一个调试标志。
以下参数控制使用返回的代理实例。如果allow_none
为true,则Python常量None
将被转换为XML; 默认行为是为了None
引发一个TypeError
。这是XML-RPC规范的常用扩展,但并不受所有客户端和服务器的支持; 有关说明,请参阅http://ontosys.com/xml-rpc/extensions.php。所述use_datetime
标志可用于引起日期/时间值被表示为datetime.datetime
对象; 这在默认情况下是错误的。datetime.datetime
对象可能会传递给调用。
HTTP和HTTPS传输都支持HTTP基本认证的URL语法扩展:http://user:pass@host:port/path
。该user:pass
部分将被base64编码为HTTP'授权'标头,并在调用XML-RPC方法时作为连接过程的一部分发送到远程服务器。如果远程服务器需要基本身份验证用户和密码,则只需使用它。如果提供了HTTPS URL,上下文
可以ssl.SSLContext
并配置基础HTTPS连接的SSL设置。
返回的实例是一个代理对象,其中的方法可用于在远程服务器上调用相应的RPC调用。如果远程服务器支持introspection API,则该代理还可用于向远程服务器查询其支持的方法(服务发现)并获取其他服务器关联的元数据。
可以整合的类型(例如,可以通过XML进行编组)的类型包括以下内容(除非另有说明,否则它们被解组为相同的Python类型):
XML-RPC类型 | Python类型 |
---|---|
布尔 | 布尔 |
int或i4 | int或长范围从-2147483648到2147483647。 |
双 | 浮动 |
串 | str或unicode |
排列 | 包含可整合元素的列表或元组。数组返回为列表。 |
结构 | 字典。键必须是字符串,值可以是任何适合的类型。用户定义的类的对象可以传入; 只传输__dict__属性。 |
dateTime.iso8601 | DateTime或datetime.datetime。返回的类型取决于use_datetime标志的值。 |
BASE64 | 二进制 |
零 | 无常数。仅当allow_none为真时才允许传递。 |
这是XML-RPC支持的全套数据类型。方法调用还可能引发一个特殊的Fault
实例,用于发送XML-RPC服务器错误,或ProtocolError
用于在HTTP / HTTPS传输层中发出错误信号。双方Fault
并ProtocolError
从被称为基类派生Error
。请注意,即使从Python 2.2开始,您可以创建内置类型的子类,但xmlrpclib模块当前不会编组这些子类的实例。
传递字符串时,XML等特殊字符(例如<,>)&将被自动转义。但是,调用者有责任确保该字符串不含XML中不允许使用的字符,例如ASCII值介于0和31之间的控制字符(当然除了tab,newline和回车); 如果不这样做将导致XML-RPC请求不是格式良好的XML。如果您必须通过XML-RPC传递任意字符串,请使用Binary下面描述的包装类。
Server
被保留作为ServerProxy
向后兼容的别名。新的代码应该使用ServerProxy
。
在版本2.5中更改:添加了use_datetime
标志。
在版本2.6中进行了更改:如果具有___dict___属性并且没有以特殊方式编组的基类,则可以传入新样式类的实例。
在版本2.7.9中更改:添加了上下文
参数。
1. ServerProxy对象
甲ServerProxy
实例具有对应于由XML-RPC服务器接受每个远程过程调用的方法。调用该方法将执行由名称和参数签名调度的RPC(例如,可以使用多个参数签名重载相同的方法名称)。该RPC完成通过返回一个值,在符合的类型或它们可以是返回的数据Fault
或ProtocolError
对象指示错误。
支持XML内省API的服务器支持在保留system
属性下分组的一些常用方法:
ServerProxy.system.listMethods()
此方法返回一个字符串列表,XML-RPC服务器支持的每个(非系统)方法都有一个字符串列表。
ServerProxy.system.methodSignature(name)
此方法接受一个参数,即由XML-RPC服务器实现的方法的名称。它为此方法返回一组可能的签名。签名是一个类型数组。这些类型中的第一个是方法的返回类型,其余的是参数。
由于允许多个签名(即重载),因此此方法返回签名列表而不是单例。
签名本身仅限于方法所期望的顶级参数。例如,如果一个方法需要一个结构数组作为参数,并且它返回一个字符串,那么它的签名就是“string,array”。如果期望三个整数并返回一个字符串,则其签名是“string,int,int,int”。
如果没有为该方法定义签名,则返回一个非数组值。在Python中,这意味着返回值的类型将不是列表。
ServerProxy.system.methodHelp(name)
此方法接受一个参数,即由XML-RPC服务器实现的方法的名称。它返回一个描述该方法用法的文档字符串。如果没有这样的字符串可用,则返回空字符串。文档字符串可能包含HTML标记。
2.布尔对象
这个类可以从任何Python值初始化; 返回的实例仅取决于其真值。它支持通过各种Python的运营商__cmp__()
,__repr__()
,__int__()
,和__nonzero__()
方法,都在明显的方式来实现。
它还有以下方法,主要用于解组代码的内部使用:
Boolean.encode(out)
将此布尔项的XML-RPC编码写入输出流对象。
下面是一个工作示例。服务器代码:
import xmlrpclib
from SimpleXMLRPCServer 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()
上述服务器的客户端代码:
import xmlrpclib
proxy = xmlrpclib.ServerProxy("http://localhost:8000/")
print "3 is even: %s" % str(proxy.is_even(3))
print "100 is even: %s" % str(proxy.is_even(100))
3.日期时间对象
class xmlrpclib.DateTime
这个类可以在历元以来的秒数,时间元组,ISO 8601时间/日期字符串或datetime.datetime
实例中初始化。它具有以下方法,主要用于编组/解编码的内部使用:
decode(string)
接受一个字符串作为实例的新时间值。
encode(out)
将此DateTime
项目的XML-RPC编码写入输出
流对象。
它还支持某些Python的内置操作符__cmp__()
和__repr__()
方法。
下面是一个工作示例。服务器代码:
import datetime
from SimpleXMLRPCServer import SimpleXMLRPCServer
import xmlrpclib
def today():
today = datetime.datetime.today()
return xmlrpclib.DateTime(today)
server = SimpleXMLRPCServer(("localhost", 8000))
print "Listening on port 8000..."
server.register_function(today, "today")
server.serve_forever()
上述服务器的客户端代码:
import xmlrpclib
import datetime
proxy = xmlrpclib.ServerProxy("http://localhost: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")
4.二进制对象
class xmlrpclib.Binary
这个类可以从字符串数据(可能包括NULs)初始化。Binary
对象内容的主要访问由一个属性提供:
data
由Binary
实例封装的二进制数据。数据以8位字符串的形式提供。
Binary
对象具有以下方法,主要用于编组/解编码的内部使用:
decode(string)
接受base64字符串并将其解码为实例的新数据。
encode(out)
将此二进制项的XML-RPC base 64编码写入输出
流对象。
按照RFC 2045第6.8节的规定,编码后的数据每隔76个字符就会换行,这在编写XML-RPC规范时是事实上的标准base64规范。
它还通过一种__cmp__()
方法支持某些Python的内置操作符。
二进制对象的示例用法。我们将通过XMLRPC传输图像:
from SimpleXMLRPCServer import SimpleXMLRPCServer
import xmlrpclib
def python_logo():
with open("python_logo.jpg", "rb") as handle:
return xmlrpclib.Binary(handle.read())
server = SimpleXMLRPCServer(("localhost", 8000))
print "Listening on port 8000..."
server.register_function(python_logo, 'python_logo')
server.serve_forever()
客户端获取图像并将其保存到文件中:
import xmlrpclib
proxy = xmlrpclib.ServerProxy("http://localhost:8000/")
with open("fetched_python_logo.jpg", "wb") as handle:
handle.write(proxy.python_logo().data)
5.故障对象
class xmlrpclib.Fault
一个Fault
对象封装了XML-RPC错误标签的内容。故障对象具有以下属性:
faultCode
指示故障类型的字符串。
faultString
包含与故障关联的诊断消息的字符串。
在下面的例子中,我们将Fault
通过返回一个复杂的类型对象来故意造成一个。服务器代码:
from SimpleXMLRPCServer 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()
上述服务器的客户端代码:
import xmlrpclib
proxy = xmlrpclib.ServerProxy("http://localhost:8000/")
try:
proxy.add(2, 5)
except xmlrpclib.Fault as err:
print "A fault occurred"
print "Fault code: %d" % err.faultCode
print "Fault string: %s" % err.faultString
6. ProtocolError对象
class xmlrpclib.ProtocolError
甲ProtocolError
对象描述底层传输层中的协议错误(例如404“未找到”错误,如果由URI指定的服务器不存在)。它具有以下属性:
url
触发错误的URI或URL。
errcode
错误代码。
errmsg
错误消息或诊断字符串。
headers
包含触发错误的HTTP / HTTPS请求标头的字符串。
在下面的例子中,我们将ProtocolError
通过提供一个不指向XMLRPC服务器的URI 来故意引起:
import xmlrpclib
# create a ServerProxy with a URI that doesn't respond to XMLRPC requests
proxy = xmlrpclib.ServerProxy("http://www.google.com/")
try:
proxy.some_method()
except xmlrpclib.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
7. MultiCall对象
2.4版本中的新功能。
该MultiCall
对象提供了一种将多个调用封装到远程服务器到单个请求的方法[1]。
class xmlrpclib.MultiCall(server)
创建一个用于boxcar方法调用的对象。服务器
是呼叫的最终目标。可以对结果对象进行调用,但它们会立即返回None
,并只将MultiCall
对象名称和参数存储在对象中。调用对象本身会导致所有存储的调用都作为单个system.multicall
请求传输。这个调用的结果是一个发生器 ; 遍历这个生成器会产生单独的结果。
这个类的用法示例如下。服务器代码
from SimpleXMLRPCServer 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()
上述服务器的客户端代码:
import xmlrpclib
proxy = xmlrpclib.ServerProxy("http://localhost:8000/")
multicall = xmlrpclib.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)
8.便利功能
xmlrpclib.boolean(value)
将任何Python值转换为其中一个XML-RPC布尔常量True
或False
。
xmlrpclib.dumps(params[, methodname[, methodresponse[, encoding[, allow_none]]]])
将params
转换为XML-RPC请求。或者如果方法
响应为真,则将其
转换为响应。参数
可以是参数
的元组或Fault
异常类的实例。如果methodresponse
为true,则只能返回一个值,这意味着params
的长度必须为1. 编码
(如果提供)是在生成的XML中使用的编码
; 默认是UTF-8。Python的None
值不能用于标准的XML-RPC; 允许通过扩展来使用它,为allow_none
提供一个真正的值。
xmlrpclib.loads(data[, use_datetime])
将XML-RPC请求或响应转换为Python对象,a (params, methodname)
。params
是一个论元; methodname
是一个字符串,或者None
如果数据包中没有方法名称。如果XML-RPC数据包代表故障条件,则此函数将引发Fault
异常。所述use_datetime
标志可用于引起日期/时间值被表示为datetime.datetime
对象; 这在默认情况下是错误的。
在版本2.5中更改:添加了use_datetime
标志。
9.客户使用示例
# simple test program (from the XML-RPC specification)
from xmlrpclib import ServerProxy, Error
# server = ServerProxy("http://localhost:8000") # local server
server = ServerProxy("http://betty.userland.com")
print server
try:
print server.examples.getStateName(41)
except Error as v:
print "ERROR", v
要通过HTTP代理访问XML-RPC服务器,您需要定义一个自定义传输。以下示例显示了如何:
import xmlrpclib, httplib
class ProxiedTransport(xmlrpclib.Transport):
def set_proxy(self, proxy):
self.proxy = proxy
def make_connection(self, host):
self.realhost = host
h = httplib.HTTPConnection(self.proxy)
return h
def send_request(self, connection, handler, request_body):
connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))
def send_host(self, connection, host):
connection.putheader('Host', self.realhost)
p = ProxiedTransport()
p.set_proxy('proxy-server:8080')
server = xmlrpclib.ServerProxy('http://time.xmlrpc.com/RPC2', transport=p)
print server.currentTime.getCurrentTime()
10.客户端和服务器使用示例
请参阅SimpleXMLRPCServer示例。
注
1 | 这种方法首先在关于xmlrpc.com的讨论中提出。 |
---|