xmlrpc.client --- XML-RPC クライアントアクセス¶
ソースコード: Lib/xmlrpc/client.py
XML-RPCはXMLを利用した遠隔手続き呼び出し(Remote Procedure Call)の一種で、HTTP(S)をトランスポートとして使用します。XML- RPCでは、クライアントはリモートサーバ(URIで指定されたサーバ)上のメソッドをパラメータを指定して呼び出し、構造化されたデータを取得します。このモジュールは、XML-RPCクライアントの開発をサポートしており、Pythonオブジェクトに適合する転送用XMLの変換の全てを行います。
警告
The xmlrpc.client module is not secure against maliciously
constructed data. If you need to parse untrusted or unauthenticated data,
see XML security.
バージョン 3.5 で変更: HTTPS URI の場合、 xmlrpc.client は必要な証明書検証とホスト名チェックを全てデフォルトで行います。
Availability: not WASI.
このモジュールは WebAssembly では動作しないか、利用不可です。詳しくは、WebAssembly プラットフォーム を見てください。
- class xmlrpc.client.ServerProxy(uri, transport=None, encoding=None, verbose=False, allow_none=False, use_datetime=False, use_builtin_types=False, *, headers=(), context=None)¶
ServerProxyは、リモートのXML-RPCサーバとの通信を管理するオブジェクトです。最初のパラメータはURI(Uniform Resource Indicator)で、通常はサーバのURLを指定します。2番目のパラメータにはトランスポート・ファクトリを指定する事ができます。トランスポート・ファクトリを省略した場合、URLが https: ならモジュール内部のSafeTransportインスタンスを使用し、それ以外の場合にはモジュール内部のTransportインスタンスを使用します。オプションの 3 番目の引数はエンコード方法で、デフォルトでは UTF-8 です。オプションの 4 番目の引数はデバッグフラグです。The following parameters govern the use of the returned proxy instance. If allow_none is true, the Python constant
Nonewill be translated into XML; the default behaviour is forNoneto raise aTypeError. This is a commonly used extension to the XML-RPC specification, but isn't supported by all clients and servers; see http://ontosys.com/xml-rpc/extensions.php for a description. The use_builtin_types flag can be used to cause date/time values to be presented asdatetime.datetimeobjects and binary data to be presented asbytesobjects; this flag is false by default.datetime.datetime,bytesandbytearrayobjects may be passed to calls. The headers parameter is an optional sequence of HTTP headers to send with each request, expressed as a sequence of 2-tuples representing the header name and value. (e.g.[('Header-Name', 'value')]). If an HTTPS URL is provided, context may bessl.SSLContextand configures the SSL settings of the underlying HTTPS connection. The obsolete use_datetime flag is similar to use_builtin_types but it applies only to date/time values.バージョン 3.3 で変更: use_builtin_types フラグが追加されました。
バージョン 3.8 で変更: headers 引数が追加されました。
HTTP及びHTTPS通信の両方で、
http://user:pass@host:port/pathのようなHTTP基本認証のための拡張URL構文をサポートしています。user:passはbase64でエンコードしてHTTPの'Authorization 'ヘッダとなり、XML-RPCメソッド呼び出し時に接続処理の一部としてリモートサーバに送信されます。リモートサーバが基本認証を要求する場合のみ、この機能を利用する必要があります。生成されるインスタンスはリモートサーバへのプロクシオブジェクトで、RPC呼び出しを行う為のメソッドを持ちます。リモートサーバがイントロスペクション APIをサポートしている場合は、リモートサーバのサポートするメソッドを検索 (サービス検索)やサーバのメタデータの取得なども行えます。
以下の型をXMLに変換(XMLを通じてマーシャルする)する事ができます (特別な指定がない限り、逆変換でも同じ型として変換されます):
XML-RPC の型
Python の型
booleanint,i1,i2,i4,i8またはbigintegerintin range from -2147483648 to 2147483647. Values get the<int>tag.doubleまたはfloatfloat. Values get the<double>tag.stringarraystructdict。キーは文字列のみ。全ての値は変換可能でなくてはならない。ユーザー定義型を渡すこともできます。__dict__の属性のみ転送されます。dateTime.iso8601DateTimeまたはdatetime.datetime。返される型は use_builtin_types および use_datetime の値に依ります。base64Binary、bytesまたはbytearray。返される型は use_builtin_types フラグの値に依ります。nilNone定数。 allow_none が真の場合にのみ渡すことが出来ます。bigdecimaldecimal.Decimal. Returned type only.上記のXML-RPCでサポートする全データ型を使用することができます。メソッド呼び出し時、XML- RPCサーバエラーが発生すると
Faultインスタンスを送出し、HTTP/HTTPSトランスポート層でエラーが発生した場合にはProtocolErrorを送出します。ErrorをベースとするFaultとProtocolErrorの両方が発生します。現在のところxmlrpclibでは組み込み型のサブクラスのインスタンスをマーシャルすることはできません。文字列を渡す場合、
<,>,&などのXMLで特殊な意味を持つ文字は自動的にエスケープされます。しかし、ASCII値0〜31の制御文字(もちろん、タブ'TAB',改行'LF',リターン'CR'は除く)などのXMLで使用することのできない文字を使用することはできず、使用するとそのXML-RPCリクエストはwell-formedなXMLとはなりません。そのようなバイト列を渡す必要がある場合は、bytes,bytearrayクラスまたは後述のBinaryラッパークラスを使用してください。Serverは、後方互換性の為にServerProxyの別名として残されています。新しいコードではServerProxyを使用してください。バージョン 3.5 で変更: context 引数が追加されました。
バージョン 3.6 で変更: Added support of type tags with prefixes (e.g.
ex:nil). Added support of unmarshalling additional types used by Apache XML-RPC implementation for numerics:i1,i2,i8,biginteger,floatandbigdecimal. See https://ws.apache.org/xmlrpc/types.html for a description.
参考
- XML-RPC HOWTO
数種類のプログラミング言語で記述された XML-RPCの操作とクライアントソフトウェアの素晴らしい説明が掲載されています。 XML- RPCクライアントの開発者が知っておくべきことがほとんど全て記載されています。
- XML-RPC Introspection
インストロペクションをサポートする、 XML-RPC プロトコルの拡張を解説しています。
- XML-RPC Specification
公式の仕様
ServerProxy オブジェクト¶
ServerProxy インスタンスの各メソッドはそれぞれXML-RPCサーバの遠隔手続き呼び出しに対応しており、メソッドが呼び出されると名前と引数をシグネチャとしてRPCを実行します(同じ名前のメソッドでも、異なる引数シグネチャによってオーバロードされます)。RPC実行後、変換された値を返すか、または Fault オブジェクトもしくは ProtocolError オブジェクトでエラーを通知します。
予約属性 system から、XMLイントロスペクションAPIの一般的なメソッドを利用する事ができます:
- ServerProxy.system.listMethods()¶
XML-RPCサーバがサポートするメソッド名(system以外)を格納する文字列のリストを返します。
- ServerProxy.system.methodSignature(name)¶
XML-RPCサーバで実装されているメソッドの名前を指定し、利用可能なシグネチャの配列を取得します。シグネチャは型のリストで、先頭の型は戻り値の型を示し、以降はパラメータの型を示します。
XML-RPCでは複数のシグネチャ(オーバロード)を使用することができるので、単独のシグネチャではなく、シグネチャのリストを返します。
シグネチャは、メソッドが使用する最上位のパラメータにのみ適用されます。例えばあるメソッドのパラメータが構造体の配列で戻り値が文字列の場合、シグネチャは単に"string, array" となります。パラメータが三つの整数で戻り値が文字列の場合は"string, int, int, int"となります。
メソッドにシグネチャが定義されていない場合、配列以外の値が返ります。 Pythonでは、この値はlist以外の値となります。
- ServerProxy.system.methodHelp(name)¶
XML-RPCサーバで実装されているメソッドの名前を指定し、そのメソッドを解説する文書文字列を取得します。文書文字列を取得できない場合は空文字列を返します。文書文字列にはHTMLマークアップが含まれます。
バージョン 3.5 で変更: Instances of ServerProxy support the context manager protocol
for closing the underlying transport.
以下は、動作する例です。サーバ側のコード:
from xmlrpc.server 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 xmlrpc.client
with xmlrpc.client.ServerProxy("http://localhost:8000/") as proxy:
print("3 is even: %s" % str(proxy.is_even(3)))
print("100 is even: %s" % str(proxy.is_even(100)))
DateTime オブジェクト¶
- class xmlrpc.client.DateTime¶
このクラスは、エポックからの秒数、タプルで表現された時刻、ISO 8601形式の時間/日付文字列、
datetime.datetime, のインスタンスのいずれかで初期化することができます。このクラスには以下のメソッドがあり、主にコードをマーシャル/アンマーシャルするための内部処理を行います:- decode(string)¶
文字列をインスタンスの新しい時間を示す値として指定します。
It also supports certain of Python's built-in operators through
rich comparisonand__repr__()methods.
以下は、動作する例です。サーバ側のコード:
import datetime
from xmlrpc.server import SimpleXMLRPCServer
import xmlrpc.client
def today():
today = datetime.datetime.today()
return xmlrpc.client.DateTime(today)
server = SimpleXMLRPCServer(("localhost", 8000))
print("Listening on port 8000...")
server.register_function(today, "today")
server.serve_forever()
上記のサーバーに対するクライアントコード:
import xmlrpc.client
import datetime
proxy = xmlrpc.client.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"))
Binary オブジェクト¶
- class xmlrpc.client.Binary¶
このクラスは、バイト列データ(NULを含む)で初期化することができます。
Binaryの内容は、属性で参照します:Binaryオブジェクトは以下のメソッドを持ち、主に内部的にマーシャル/アンマーシャル時に使用されます:- encode(out)¶
バイナリ値をbase64でエンコードし、出力ストリームオブジェクト out に出力します。
エンコードされたデータは、 RFC 2045 section 6.8 にある通り、76文字ごとに改行されます。これは、XMC-RPC仕様が作成された時のデ・ファクト・スタンダードのbase64です。
It also supports certain of Python's built-in operators through
__eq__()and__ne__()methods.
バイナリオブジェクトの使用例です。 XML-RPCごしに画像を転送します。
from xmlrpc.server import SimpleXMLRPCServer
import xmlrpc.client
def python_logo():
with open("python_logo.jpg", "rb") as handle:
return xmlrpc.client.Binary(handle.read())
server = SimpleXMLRPCServer(("localhost", 8000))
print("Listening on port 8000...")
server.register_function(python_logo, 'python_logo')
server.serve_forever()
クライアントは画像を取得して、ファイルに保存します。
import xmlrpc.client
proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
with open("fetched_python_logo.jpg", "wb") as handle:
handle.write(proxy.python_logo().data)
Fault オブジェクト¶
- class xmlrpc.client.Fault¶
Faultオブジェクトは、XML-RPCのfaultタグの内容をカプセル化しており、以下の属性を持ちます:- faultCode¶
失敗のタイプを示す整数。
- faultString¶
失敗の診断メッセージを含む文字列。
以下のサンプルでは、複素数型のオブジェクトを返そうとして、故意に Fault を起こしています。
from xmlrpc.server 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 xmlrpc.client
proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
try:
proxy.add(2, 5)
except xmlrpc.client.Fault as err:
print("A fault occurred")
print("Fault code: %d" % err.faultCode)
print("Fault string: %s" % err.faultString)
ProtocolError オブジェクト¶
- class xmlrpc.client.ProtocolError¶
ProtocolErrorオブジェクトはトランスポート層で発生したエラー(URI で指定したサーバが見つからなかった場合に発生する404 'not found'など)の内容を示し、以下の属性を持ちます:- url¶
エラーの原因となったURIまたはURL。
- errcode¶
エラーコード。
- errmsg¶
エラーメッセージまたは診断文字列。
- headers¶
エラーの原因となったHTTP/HTTPSリクエストを含む辞書。
次の例では、不適切な URI を利用して、故意に ProtocolError を発生させています:
import xmlrpc.client
# create a ServerProxy with a URI that doesn't respond to XMLRPC requests
proxy = xmlrpc.client.ServerProxy("http://google.com/")
try:
proxy.some_method()
except xmlrpc.client.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)
MultiCall オブジェクト¶
MultiCall オブジェクトは遠隔のサーバに対する複数の呼び出しをひとつのリクエストにカプセル化する方法を提供します [1]。
- class xmlrpc.client.MultiCall(server)¶
巨大な (boxcar) メソッド呼び出しに使えるオブジェクトを作成します。 server には最終的に呼び出しを行う対象を指定します。作成した MultiCall オブジェクトを使って呼び出しを行うと、即座に
Noneを返し、呼び出したい手続き名とパラメタをMultiCallオブジェクトに保存するだけに留まります。オブジェクト自体を呼び出すと、それまでに保存しておいたすべての呼び出しを単一のsystem.multicallリクエストの形で伝送します。呼び出し結果は ジェネレータ になります。このジェネレータにわたってイテレーションを行うと、個々の呼び出し結果を返します。
以下は、このクラスの使用例です。サーバ側のコード:
from xmlrpc.server 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 xmlrpc.client
proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
multicall = xmlrpc.client.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))
補助関数¶
- xmlrpc.client.dumps(params, methodname=None, methodresponse=None, encoding=None, allow_none=False)¶
params を XML-RPC リクエストの形式に変換します。 methodresponse が真の場合、XML-RPC レスポンスの形式に変換します。 params に指定できるのは、引数からなるタプルか
Fault例外クラスのインスタンスです。 methodresponse が真の場合、単一の値だけを返します。従って、 params の長さも 1 でなければなりません。 encoding を指定した場合、生成される XML のエンコード方式になります。デフォルトは UTF-8 です。 Python のNoneは標準の XML-RPC には利用できません。Noneを使えるようにするには、 allow_none を真にして、拡張機能つきにしてください。
- xmlrpc.client.loads(data, use_datetime=False, use_builtin_types=False)¶
XML-RPC リクエストまたはレスポンスを
(params, methodname)の形式をとる Python オブジェクトにします。 params は引数のタプルです。 methodname は文字列で、パケット中にメソッド名がない場合にはNoneになります。例外条件を示す XML-RPC パケットの場合には、Fault例外を送出します。 use_builtin_types フラグはdatetime.datetimeのオブジェクトとして日付/時刻を、bytesのオブジェクトとしてバイナリデータを表現する時に使用し、デフォルトでは false に設定されています。非推奨となった use_datetime フラグは use_builtin_types に似ていますが date/time 値にのみ適用されます。
バージョン 3.3 で変更: use_builtin_types フラグが追加されました。
クライアントのサンプル¶
# simple test program (from the XML-RPC specification)
from xmlrpc.client import ServerProxy, Error
# server = ServerProxy("http://localhost:8000") # local server
with ServerProxy("http://betty.userland.com") as proxy:
print(proxy)
try:
print(proxy.examples.getStateName(41))
except Error as v:
print("ERROR", v)
XML-RPC サーバに HTTP プロキシを経由して接続する場合、カスタムトランスポートを定義する必要があります。以下に例を示します:
import http.client
import xmlrpc.client
class ProxiedTransport(xmlrpc.client.Transport):
def set_proxy(self, host, port=None, headers=None):
self.proxy = host, port
self.proxy_headers = headers
def make_connection(self, host):
connection = http.client.HTTPConnection(*self.proxy)
connection.set_tunnel(host, headers=self.proxy_headers)
self._connection = host, connection
return connection
transport = ProxiedTransport()
transport.set_proxy('proxy-server', 8080)
server = xmlrpc.client.ServerProxy('http://betty.userland.com', transport=transport)
print(server.examples.getStateName(41))
クライアントとサーバーの利用例¶
SimpleXMLRPCServer の例 を参照してください。
脚注