20.23. xmlrpclib — XML-RPCクライアントアクセス—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/2.7/library/xmlrpclib
移動先:案内検索

20.23。 xmlrpclib —XML-RPCクライアントアクセス

ノート

xmlrpclib モジュールは、Python3でxmlrpc.clientに名前が変更されました。 2to3 ツールは、ソースをPython 3に変換するときに、インポートを自動的に適応させます。


バージョン2.2の新機能。


ソースコード: :source: `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(Uniform Resource Indicator)であり、通常はサーバーのURLになります。 オプションの2番目の引数は、トランスポートファクトリインスタンスです。 デフォルトでは、https:URLの内部SafeTransportインスタンスであり、それ以外の場合は内部HTTP Transportインスタンスです。 オプションの3番目の引数はエンコーディングであり、デフォルトではUTF-8です。 オプションの4番目の引数はデバッグフラグです。

次のパラメータは、返されるプロキシインスタンスの使用を管理します。 allow_none がtrueの場合、Python定数NoneはXMLに変換されます。 デフォルトの動作では、NoneTypeErrorを発生させます。 これはXML-RPC仕様の一般的に使用される拡張機能ですが、すべてのクライアントとサーバーでサポートされているわけではありません。 説明については、 http://ontosys.com/xml-rpc/extensions.phpを参照してください。 use_datetime フラグを使用すると、日付/時刻の値を datetime.datetime オブジェクトとして表示できます。 これはデフォルトではfalseです。 datetime.datetime オブジェクトを呼び出しに渡すことができます。

HTTPトランスポートとHTTPSトランスポートはどちらも、HTTP基本認証のURL構文拡張機能http://user:pass@host:port/pathをサポートしています。 user:passの部分は、HTTPの「Authorization」ヘッダーとしてbase64でエンコードされ、XML-RPCメソッドを呼び出すときに接続プロセスの一部としてリモートサーバーに送信されます。 これを使用する必要があるのは、リモートサーバーで基本認証のユーザーとパスワードが必要な場合のみです。 HTTPS URLが提供されている場合、 contextssl.SSLContext であり、基盤となるHTTPS接続のSSL設定を構成します。

返されるインスタンスは、リモートサーバーで対応するRPC呼び出しを呼び出すために使用できるメソッドを持つプロキシオブジェクトです。 リモートサーバーがイントロスペクションAPIをサポートしている場合は、プロキシを使用して、サポートしているメソッド(サービス検出)をリモートサーバーに照会し、他のサーバー関連のメタデータをフェッチすることもできます。

適合性のあるタイプ(例: XMLを介してマーシャリングできる)、以下を含めます(特に明記されている場合を除き、同じPythonタイプとしてマーシャリングされません)。

XML-RPCタイプ

Pythonタイプ

boolean

bool

intまたはi4

int または long の範囲は、-2147483648〜2147483647です。

double

float

string

str または unicode

array

適合要素を含むlistまたはタプル。 配列はlistsとして返されます。

struct

dict 。 キーは文字列である必要があり、値は任意の適合タイプにすることができます。 ユーザー定義クラスのオブジェクトを渡すことができます。 __ dict __ 属性のみが送信されます。

dateTime.iso8601

DateTime または datetime.datetime 。 返されるタイプは、 use_datetime フラグの値によって異なります。

base64

Binary

nil

None定数。 合格は、 allow_none がtrueの場合にのみ許可されます。

これは、XML-RPCでサポートされているデータ型の完全なセットです。 メソッド呼び出しは、XML-RPCサーバーエラーの通知に使用される特別な Fault インスタンス、またはHTTP / HTTPSトランスポート層のエラーの通知に使用される ProtocolError を発生させる場合もあります。 FaultProtocolError はどちらも、Errorという基本クラスから派生しています。 Python 2.2以降では、組み込み型をサブクラス化できますが、xmlrpclibモジュールは現在、そのようなサブクラスのインスタンスをマーシャリングしないことに注意してください。

文字列を渡す場合、<>&などのXMLに固有の文字は自動的にエスケープされます。 ただし、ASCII値が0〜31の制御文字(もちろん、タブ、改行、キャリッジリターンを除く)など、XMLで許可されていない文字が文字列に含まれていないことを確認するのは呼び出し元の責任です。 これを怠ると、整形式のXMLではないXML-RPC要求が発生します。 XML-RPCを介して任意の文字列を渡す必要がある場合は、以下で説明する Binary ラッパークラスを使用してください。

Serverは、下位互換性のために ServerProxy のエイリアスとして保持されます。 新しいコードは ServerProxy を使用する必要があります。

バージョン2.5で変更: use_datetime フラグが追加されました。

バージョン2.6で変更: new-style class esのインスタンスは、 __ dict __ 属性があり、基本クラスがない場合に渡すことができます。特別な方法でマーシャルされました。

バージョン2.7.9で変更: context 引数を追加しました。

も参照してください

XML-RPC HOWTO
いくつかの言語でのXML-RPC操作とクライアントソフトウェアの適切な説明。 XML-RPCクライアント開発者が知る必要のあるほとんどすべてが含まれています。
XML-RPCイントロスペクション
イントロスペクション用のXML-RPCプロトコル拡張について説明します。
XML-RPC仕様
公式仕様。
非公式のXML-RPCエラッタ
Fredrik Lundhの「XML-RPC仕様の特定の詳細を明確にし、独自のXML-RPC実装を設計するときに使用する「ベストプラクティス」を示唆することを目的とした非公式の正誤表。」


20.23.1。 ServerProxyオブジェクト

ServerProxy インスタンスには、XML-RPCサーバーによって受け入れられた各リモートプロシージャコールに対応するメソッドがあります。 メソッドを呼び出すと、RPCが実行され、名前と引数の両方の署名によってディスパッチされます(例: 同じメソッド名が複数の引数シグネチャでオーバーロードされる可能性があります)。 RPCは値を返すことで終了します。値は、準拠タイプで返されたデータか、エラーを示す Fault または ProtocolError オブジェクトのいずれかです。

XMLイントロスペクションAPIをサポートするサーバーは、予約済みのsystem属性の下にグループ化されたいくつかの一般的なメソッドをサポートします。

ServerProxy.system.listMethods()
このメソッドは、XML-RPCサーバーでサポートされている(システム以外の)メソッドごとに1つずつ、文字列のリストを返します。
ServerProxy.system.methodSignature(name)

このメソッドは、XML-RPCサーバーによって実装されるメソッドの名前という1つのパラメーターを取ります。 このメソッドの可能な署名の配列を返します。 シグニチャは型の配列です。 これらのタイプの最初はメソッドの戻りタイプであり、残りはパラメーターです。

複数の署名があるため(つまり、 オーバーロード)が許可されている場合、このメソッドはシングルトンではなく署名のリストを返します。

シグニチャ自体は、メソッドで期待される最上位のパラメータに制限されています。 たとえば、メソッドが構造体の1つの配列をパラメーターとして予期し、文字列を返す場合、そのシグネチャは単に「文字列、配列」です。 3つの整数を期待して文字列を返す場合、その署名は「string、int、int、int」です。

メソッドにシグニチャが定義されていない場合は、配列以外の値が返されます。 Pythonでは、これは戻り値の型がリスト以外のものになることを意味します。

ServerProxy.system.methodHelp(name)
このメソッドは、XML-RPCサーバーによって実装されるメソッドの名前という1つのパラメーターを取ります。 そのメソッドの使用法を説明するドキュメント文字列を返します。 そのような文字列が使用できない場合は、空の文字列が返されます。 ドキュメント文字列には、HTMLマークアップが含まれる場合があります。


20.23.2。 ブールオブジェクト

このクラスは、任意のPython値から初期化できます。 返されるインスタンスは、その真理値のみに依存します。 __cmp__()__repr__()__int__()、および__nonzero__()メソッドを介してさまざまなPython演算子をサポートし、すべて明白な方法で実装されています。

また、次のメソッドがあり、主に非マーシャリングコードによる内部使用がサポートされています。

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

20.23.3。 DateTimeオブジェクト

class xmlrpclib.DateTime

このクラスは、エポックからの秒数、タイムタプル、ISO 8601の時刻/日付文字列、または datetime.datetime インスタンスで初期化できます。 これには次のメソッドがあり、主にマーシャリング/アンマーシャリングコードによる内部使用がサポートされています。

decode(string)

インスタンスの新しい時間値として文字列を受け入れます。

encode(out)

この DateTime アイテムのXML-RPCエンコーディングを out ストリームオブジェクトに書き込みます。

また、__cmp__()および__repr__()メソッドを介してPythonの特定の組み込み演算子をサポートします。

実用的な例を次に示します。 サーバーコード:

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

20.23.4。 バイナリオブジェクト

class xmlrpclib.Binary

このクラスは、文字列データ(NULを含む場合があります)から初期化できます。 Binary オブジェクトのコンテンツへのプライマリアクセスは、次の属性によって提供されます。

data

Binary インスタンスによってカプセル化されたバイナリデータ。 データは8ビット文字列として提供されます。

Binary オブジェクトには次のメソッドがあり、主にマーシャリング/アンマーシャリングコードによる内部使用がサポートされています。

decode(string)

base64文字列を受け入れ、インスタンスの新しいデータとしてデコードします。

encode(out)

このバイナリアイテムのXML-RPCbase64エンコーディングを out ストリームオブジェクトに書き込みます。

エンコードされたデータには、 RFC2045セクション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)

20.23.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

20.23.6。 ProtocolErrorオブジェクト

class xmlrpclib.ProtocolError

ProtocolError オブジェクトは、基盤となるトランスポート層のプロトコルエラーを記述します(URIで指定されたサーバーが存在しない場合の404'not found 'エラーなど)。 次の属性があります。

url

エラーをトリガーしたURIまたはURL。

errcode

エラーコード。

errmsg

エラーメッセージまたは診断文字列。

headers

エラーをトリガーしたHTTP / HTTPSリクエストのヘッダーを含む文字列。

次の例では、XMLRPCサーバーを指さないURIを提供することにより、意図的に ProtocolError を発生させます。

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

20.23.7。 MultiCallオブジェクト

バージョン2.4の新機能。


MultiCall オブジェクトは、リモートサーバーへの複数の呼び出しを単一の要求 1 にカプセル化する方法を提供します。

class xmlrpclib.MultiCall(server)
boxcarメソッド呼び出しに使用されるオブジェクトを作成します。 server が最終的な呼び出しのターゲットです。 結果オブジェクトを呼び出すことはできますが、すぐに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)

20.23.8。 便利な機能

xmlrpclib.boolean(value)
Python値をXML-RPCブール定数TrueまたはFalseのいずれかに変換します。
xmlrpclib.dumps(params[, methodname[, methodresponse[, encoding[, allow_none]]]])
params をXML-RPCリクエストに変換します。 または、 methodresponse がtrueの場合は応答に。 params は、引数のタプルまたは Fault 例外クラスのインスタンスのいずれかです。 methodresponse がtrueの場合、返される値は1つだけです。つまり、 params の長さは1でなければなりません。 encoding は、提供されている場合、生成されたXMLで使用するエンコーディングです。 デフォルトはUTF-8です。 Pythonの None 値は、標準のXML-RPCでは使用できません。 拡張機能を介して使用できるようにするには、 allow_none に真の値を指定します。
xmlrpclib.loads(data[, use_datetime])

XML-RPC要求または応答をPythonオブジェクト(params, methodname)に変換します。 params は引数のタプルです。 methodname は文字列、またはパケットにメソッド名が存在しない場合はNoneです。 XML-RPCパケットが障害状態を表す場合、この関数は Fault 例外を発生させます。 use_datetime フラグを使用すると、日付/時刻の値を datetime.datetime オブジェクトとして表示できます。 これはデフォルトではfalseです。

バージョン2.5で変更: use_datetime フラグが追加されました。


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

20.23.10。 クライアントとサーバーの使用例

SimpleXMLRPCServerの例を参照してください。

脚注

1
このアプローチは、 xmlrpc.com に関するディスカッションで最初に提示されました。