xmlrpc.server --- 基本的な XML-RPC サーバー

ソースコード: Lib/xmlrpc/server.py


xmlrpc.server モジュールは、Python で記述する XML-RPC サーバーの基本的なフレームワークを提供します。 SimpleXMLRPCServer を使うと独立したサーバーを作成でき、CGIXMLRPCRequestHandler を使うと CGI 環境に組み込めます。

警告

xmlrpc.server モジュールは、悪意を持って作成されたデータに対して安全ではありません。 信頼できないデータや認証されていないデータを解析する必要がある場合は、XML のセキュリティ を参照してください。

利用可能な環境: not WASI.

このモジュールは WebAssembly では動作しないか、利用不可です。詳しくは、WebAssembly プラットフォーム を見てください。

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 が真の場合 (デフォルト)、 リクエストはログに記録されます。 この引数を偽にするとはログは記録されません。 引数 allow_none と encoding は xmlrpc.client に渡され、サーバーが返す XML-RPC 応答を制御します。 bind_and_activate 引数はコンストラクタが直ちに server_bind() と server_activate() を呼ぶかどうかを制御します。デフォルトでは真です。 この引数に False を設定することで、アドレスを束縛する前に allow_reuse_address クラス変数を操作することが出来ます。 use_builtin_types 引数は loads() 関数に渡されます。 この引数は日付/時刻の値やバイナリデータを受け取ったときにどの型が処理されるかを制御します。デフォルトでは偽です。

バージョン 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() 関数に渡されます。 この引数は日付/時刻の値やバイナリデータを受け取ったときにどの型が処理されるかを制御します。デフォルトは偽です。

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

class xmlrpc.server.SimpleXMLRPCRequestHandler

リクエストハンドラーインスタンスを新たに作成します。このリクエストハンドラーは POST リクエストをサポートし、 SimpleXMLRPCServer コンストラクターの引数 logRequests に従ってログ出力を行います。

SimpleXMLRPCServer オブジェクト

SimpleXMLRPCServer クラスは socketserver.TCPServer のサブクラスで、基本的なスタンドアロンの XML-RPC サーバーを作成する手段を提供します。

SimpleXMLRPCServer.register_function(function=None, name=None)

XML-RPC リクエストに応答可能な関数を登録します。引数 name が与えられた場合は、それが関数 function に関連付けられたメソッド名となります。そうでない場合は、 function.__name__ の値が用いられます。引数 name は文字列で、例えばピリオド "." のようなPythonで識別子として正しくない文字を含んでいても構いません。

このメソッドはデコレーターとしても使用することができます。デコレーターとして使用するときは、 name は関数を name で登録するキーワード引数としてのみ渡すことができます。 name が与えられていないときは、 function.__name__ が使用されます。

バージョン 3.7 で変更: register_function() はデコレーターとして使用できます。

SimpleXMLRPCServer.register_instance(instance, allow_dotted_names=False)

オブジェクトを登録します。 オブジェクトは register_function() を使用して登録されていないメソッド名を公開するのに使われます。 instance に _dispatch() メソッドがあった場合、リクエストされたメソッド名と引数で _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') です。

SimpleXMLRPCServer の例

サーバーのコード:

from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler

# 特定のパスに制限する
class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/RPC2',)

# サーバーを作成する
with SimpleXMLRPCServer(('localhost', 8000),
                        requestHandler=RequestHandler) as server:
    server.register_introspection_functions()

    # pow() 関数を登録する。
    # 名前には pow.__name__ の値、つまり 'pow' が使われる。
    server.register_function(pow)

    # 別の名前で関数を登録する
    def adder_function(x, y):
        return x + y
    server.register_function(adder_function, 'add')

    # インスタンスを登録する。
    # そのすべてのメソッド (この場合は 'mul' だけ) が XML-RPC メソッドとして公開される。
    class MyFuncs:
        def mul(self, x, y):
            return x * y

    server.register_instance(MyFuncs())

    # サーバーのメインループを実行する
    server.serve_forever()

以下のクライアントコードは上のサーバーで使えるようになったメソッドを呼び出します:

import xmlrpc.client

s = xmlrpc.client.ServerProxy('http://localhost:8000')
print(s.pow(2,3))  # 2**3 = 8 を返す
print(s.add(2,3))  # 5 を返す
print(s.mul(5,2))  # 5*2 = 10 を返す

# 利用可能なメソッドの一覧を表示する
print(s.system.listMethods())

register_function() はデコレーターとしても使えます。 先ほどのサーバーの例では、デコレーターを使って関数を登録することもできます。

from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler

class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/RPC2',)

with SimpleXMLRPCServer(('localhost', 8000),
                        requestHandler=RequestHandler) as server:
    server.register_introspection_functions()

    # pow() 関数を登録する。
    # 名前には pow.__name__ の値、つまり 'pow' が使われる。
    server.register_function(pow)

    # register_function をデコレーターとして使い、別の名前で関数を登録する。
    # *name* はキーワード引数としてのみ指定できる。
    @server.register_function(name='add')
    def adder_function(x, y):
        return x + y

    # function.__name__ という名前で関数を登録する。
    @server.register_function
    def mul(x, y):
        return x * y

    server.serve_forever()

Lib/xmlrpc/server.py モジュール内にある以下の例はドット付名前を許容し複数呼び出し関数を登録するサーバです。

警告

allow_dotted_names オプションを有効にすると、侵入者がモジュールのグローバル変数にアクセスできるようになり、マシン上で任意のコードを実行される可能性があります。 この例は安全な閉じたネットワーク内でのみ使ってください。

import datetime as dt

class ExampleService:
    def getData(self):
        return '42'

    class currentTime:
        @staticmethod
        def getCurrentTime():
            return dt.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

CGIXMLRPCRequestHandler

CGIXMLRPCRequestHandler クラスは、Python の CGI スクリプトに送られた XML-RPC リクエストを処理するときに使用できます。

CGIXMLRPCRequestHandler.register_function(function=None, name=None)

XML-RPC リクエストに応答可能な関数を登録します。引数 name が与えられた場合は、それが関数 function に関連付けられたメソッド名となります。そうでない場合は、 function.__name__ の値が用いられます。引数 name は文字列で、例えばピリオド "." のようなPythonで識別子として正しくない文字を含んでいても構いません。

このメソッドはデコレーターとしても使用することができます。デコレーターとして使用するときは、 name は関数を name で登録するキーワード引数としてのみ渡すことができます。 name が与えられていないときは、 function.__name__ が使用されます。

バージョン 3.7 で変更: register_function() はデコレーターとして使用できます。

CGIXMLRPCRequestHandler.register_instance(instance)

オブジェクトを登録します。 オブジェクトは register_function() を使用して登録されていないメソッド名を公開するのに使われます。 instance に _dispatch() メソッドがあった場合、リクエストされたメソッド名と引数で _dispatch() を呼び出します。 返り値は結果としてクライアントに返されます。 instance に _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 データでなければなりません。 そうでない場合、標準入力の内容が使われます。

以下はプログラム例です:

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

XMLRPC サーバの文書化

これらのクラスは上記のクラスを拡張し、HTTP GET リクエストに対して HTML ドキュメントを返します。 DocXMLRPCServer を使うと独立したサーバーを作成でき、DocCGIXMLRPCRequestHandler を使うと CGI 環境に組み込めます。

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環境で XMR-RPC リクエストを処理するインスタンスを新たに生成します。

class xmlrpc.server.DocXMLRPCRequestHandler

リクエスト・ハンドラのインスタンスを新たに生成します。このリクエスト・ハンドラは XML-RPC POST 要求とドキュメントの GET 要求をサポートし、 DocXMLRPCServer コンストラクタに与えられた引数 logRequests を優先するためにロギングを変更します。

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 文書内で使用される説明を設定します。この説明は文書中のサーバ名の下にパラグラフとして出力されます。

DocCGIXMLRPCRequestHandler

DocCGIXMLRPCRequestHandler は CGIXMLRPCRequestHandler の派生クラスで、自己文書化する XML-RPC CGI スクリプトの作成手段を提供します。 HTTP POST リクエストは XML-RCP メソッドの呼び出しとして処理されます。 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 文書内で使用される説明を設定します。この説明は文書中のサーバ名の下にパラグラフとして出力されます。