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

提供:Dev Guides
< PythonPython/docs/3.8/library/xmlrpc.client
移動先:案内検索

xmlrpc.client —XML-RPCクライアントアクセス

ソースコード: :source: `Lib / xmlrpc / client.py`



XML-RPCは、HTTP(S)を介して渡されたXMLをトランスポートとして使用するリモートプロシージャコールメソッドです。 これにより、クライアントはリモートサーバー(サーバーはURIによって名前が付けられます)上のパラメーターを使用してメソッドを呼び出し、構造化データを取得できます。 このモジュールは、XML-RPCクライアントコードの記述をサポートします。 適合PythonオブジェクトとXML間の変換のすべての詳細をネットワーク上で処理します。

警告

xmlrpc.client モジュールは、悪意を持って構築されたデータに対して安全ではありません。 信頼できないデータまたは認証されていないデータを解析する必要がある場合は、 XMLの脆弱性を参照してください。


バージョン3.5で変更: HTTPS URIの場合、 xmlrpc.client は、デフォルトで必要なすべての証明書とホスト名のチェックを実行するようになりました。


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番目の引数は、トランスポートファクトリインスタンスです。 デフォルトでは、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_builtin_types フラグを使用すると、日付/時刻の値を datetime.datetime オブジェクトとして表示し、バイナリデータを bytes オブジェクトとして表示できます。 このフラグはデフォルトでfalseです。 datetime.datetimebytes 、および bytearray オブジェクトを呼び出しに渡すことができます。 headers パラメーターは、各リクエストで送信するHTTPヘッダーのオプションのシーケンスであり、ヘッダーの名前と値を表す2タプルのシーケンスとして表されます。 (例えば [( 'ヘッダー名'、 '値')] )。 廃止された use_datetime フラグは、 use_builtin_types に似ていますが、日付/時刻の値にのみ適用されます。

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


バージョン3.8で変更: headers パラメーターが追加されました。

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
inti1i2i4i8、またはbiginteger int の範囲は-2147483648から2147483647です。 値は<int>タグを取得します。
doubleまたはfloat フロート。 値は<double>タグを取得します。
string str
array 適合要素を含む list または tuple 。 配列はリストとして返されます。
struct dict 。 キーは文字列である必要があり、値は任意の適合タイプにすることができます。 ユーザー定義クラスのオブジェクトを渡すことができます。 __ dict __ 属性のみが送信されます。
dateTime.iso8601 DateTime または datetime.datetime 。 返される型は、 use_builtin_types および use_datetime フラグの値によって異なります。
base64 バイナリバイトまたはバイトアレイ。 返されるタイプは、 use_builtin_types フラグの値によって異なります。
nil None定数。 合格は、 allow_none がtrueの場合にのみ許可されます。
bigdecimal decimal.Decimal 。 返されたタイプのみ。

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

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

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

バージョン3.5で変更: context 引数が追加されました。


バージョン3.6で変更:プレフィックス付きのタイプタグのサポートが追加されました(例: ex:nil)。 数値のApacheXML-RPC実装で使用されるアンマーシャリング追加タイプのサポートが追加されました:i1i2i8bigintegerfloatおよびbigdecimal。 説明については、 http://ws.apache.org/xmlrpc/types.htmlを参照してください。


も参照してください

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


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マークアップが含まれる場合があります。

バージョン3.5で変更: ServerProxy のインスタンスは、基になるトランスポートを閉じるためのコンテキストマネージャープロトコルをサポートします。


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

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)

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

encode(out)

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

また、豊富な比較と__repr__()メソッドを通じて、Pythonの特定の組み込み演算子をサポートします。

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

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

バイナリオブジェクト

class xmlrpc.client.Binary

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

data

Binary インスタンスによってカプセル化されたバイナリデータ。 データは bytes オブジェクトとして提供されます。

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

decode(bytes)

base64 bytes オブジェクトを受け入れ、インスタンスの新しいデータとしてデコードします。

encode(out)

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

エンコードされたデータには、 RFC2045セクション6.8 に従って、76文字ごとに改行が含まれます。これは、XML-RPC仕様が作成されたときの事実上の標準base64仕様でした。

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

バイナリオブジェクトの使用例。 XMLRPCを介して画像を転送します。

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)

障害オブジェクト

class xmlrpc.client.Fault

Fault オブジェクトは、XML-RPC障害タグのコンテンツをカプセル化します。 障害オブジェクトには、次の属性があります。

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リクエストのヘッダーを含むdict。

次の例では、無効な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 が最終的な呼び出しのターゲットです。 結果オブジェクトを呼び出すことはできますが、すぐに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 がtrueの場合は応答に。 params は、引数のタプルまたは Fault 例外クラスのインスタンスのいずれかです。 methodresponse がtrueの場合、返される値は1つだけです。つまり、 params の長さは1でなければなりません。 encoding は、提供されている場合、生成されたXMLで使用するエンコーディングです。 デフォルトはUTF-8です。 Pythonの None 値は、標準のXML-RPCでは使用できません。 拡張機能を介して使用できるようにするには、 allow_none に真の値を指定します。
xmlrpc.client.loads(data, use_datetime=False, use_builtin_types=False)

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

廃止された use_datetime フラグは、 use_builtin_types に似ていますが、日付/時刻の値にのみ適用されます。

バージョン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)

HTTPプロキシを介してXML-RPCサーバーにアクセスするには、カスタムトランスポートを定義する必要があります。 次の例は、その方法を示しています。

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の例を参照してください。

脚注

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