More Related Content Similar to XML-RPC : Pythonが「電池付属」と呼ばれる理由 (20) XML-RPC : Pythonが「電池付属」と呼ばれる理由1. Copyright (c) 2014 Ransui Iso, All rights reserved.
XML-RPC
Pythonが電池付属と呼ばれる理由
2014-09-13
Python Conference JP 2014
Ransui Iso
Strategic Technology Group / X-Listing Co, Ltd.
2. Ransui Iso (磯 蘭水)
Work at X-Listing Co, Ltd.
http://www.xlisting.co.jp/
Pythonは1998年から使っています。E-Commerceエンジンやサーチエンジンの開
発、Zopeを用いたWebサイト開発、その他色々を経て、今はネット広告配信シス
テムについての研究開発をしています。最近はCommon Lispでシステム開発をし
ていますが、Pythonもヘビーに使っています。
Copyright (c) 2014 Ransui Iso, All rights reserved.
おまえ誰よ?
http://www.facebook.com/ransui
@ransui
4. Copyright (c) 2014 Ransui Iso, All rights reserved.
有名どころ
● Sun RPC
– NFSの基盤として開発された
– XDRという形式で情報をシリアライズする
● なんとPython標準モジュールにでXDRを取り扱える
– 現役で色々と使われている
● その他にも
– DCE/RPC
– OMG CORBA
– DCOM
5. ham
spam
egg
Copyright (c) 2014 Ransui Iso, All rights reserved.
そも、RPCとは?
● 言語が提供する「呼び出し規約」を拡張する
– 利用者はRPCをサポートする言語でプログラミングをす
るとき、ほとんどRPCの存在を意識する必要がない。
ham
spam
egg
Remote Local
この時ローカルから result = spam(args) という感じでリモート
のメソッドを呼び出せるということ
8. メッセージ形式がXMLなRPC
● 通信そのものはHTTPが使われることが多い
– HTTPのbody部分に呼び出しや戻り値についての情報を
XML形式で記述してメッセージとして交換する
– 当然のことながらXMLの冗長性のおかげでオーバーヘッ
ドが大きくてパフォーマンス的には不利
– バイナリプロトコルに対してHuman Readableだという
部分くらいしか利点が思いつかない……
Copyright (c) 2014 Ransui Iso, All rights reserved.
9. Copyright (c) 2014 Ransui Iso, All rights reserved.
PythonでのXML-RPC
● 標準ライブラリにある
– クライアント・サーバモデル
– xmlrpc.servsr サーバ側
– xmlrpc.client クライアント側
● PurePythonによる実装
– cPythonが動く環境であればまずどこでも使える
– 改造も簡単。色々できる。
10. class HelloServer(xmlrpc.server.SimpleXMLRPCServer):
Copyright (c) 2014 Ransui Iso, All rights reserved.
Hello World : Server側
● まずはサーバを準備
● SimpleXMLRPCServerを継承したクラスを作る
● このクラスは通信担当で公開メソッドとかに関与しない
import xmlrpc.server
import xmlrpc.server
class HelloServer(xmlrpc.server.SimpleXMLRPCServer):
allow_reuse_address = True
request_queue_size = 1024
allow_reuse_address = True
request_queue_size = 1024
def __init__(self, *args, **kw):
def __init__(self, *args, **kw):
super().__init__(*args, **kw)
super().__init__(*args, **kw)
11. class HelloRequestHandler(xmlrpc.server.SimpleXMLRPCRequestHandler):
return getattr(self, method_name)(*args)
Copyright (c) 2014 Ransui Iso, All rights reserved.
Hello World : Server側
● 公開する機能を準備する
● SimpleXMLRPCRequestHandlerを継承したクラスを作る
● このクラス内で「メソッド名」と「機能」の対応を作る
class HelloRequestHandler(xmlrpc.server.SimpleXMLRPCRequestHandler):
def __init__(self, *args, **kw):
def __init__(self, *args, **kw):
super().__init__(*args, **kw)
super().__init__(*args, **kw)
def _dispatch(self, method_name, args):
def _dispatch(self, method_name, args):
return getattr(self, method_name)(*args)
def greeting(self, name):
def greeting(self, name):
return "Hello, %s" % name
return "Hello, %s" % name
12. server = HelloServer(("127.0.0.1", 9999),
requestHandler=HelloRequestHandler,
logRequests=None,
allow_none=True)
Copyright (c) 2014 Ransui Iso, All rights reserved.
Hello World : Server側
● 組み合わせてサーバとして起動する
● サーバクラスとハンドラクラスのインスタンスを作成して組み
合わせる。その後、サーバインスタンスのループを開始。
def main():
def main():
server = HelloServer(("127.0.0.1", 9999),
requestHandler=HelloRequestHandler,
logRequests=None,
allow_none=True)
server.serve_forever()
server.serve_forever()
13. proxy = xmlrpc.client.ServerProxy("http://127.0.0.1:9999/",
Copyright (c) 2014 Ransui Iso, All rights reserved.
Hello World : Client側
● ServerProxyクラスを使うだけ
● サーバ側に比べてとっても簡単
import xmlrpc.client
import xmlrpc.client
def main():
def main():
proxy = xmlrpc.client.ServerProxy("http://127.0.0.1:9999/",
allow_none=True)
print(proxy.greeting("spam"))
allow_none=True)
print(proxy.greeting("spam"))
15. ServerとClient分離問題
ham
spam
egg
Copyright (c) 2014 Ransui Iso, All rights reserved.
● 見通しの悪さを改善する
– サーバもクライアントも1つのモジュールをimportする
– 下のような状態を維持しやすくする
ham
spam
egg
RequestHandler ServiceClient
16. Server Code Application Code
Copyright (c) 2014 Ransui Iso, All rights reserved.
もっと結合性を上げる
● Pythonの動的な性質をもっと使う
– MetaClassを使うなどして、サービスの定義を行うとと
自動的にStubが生成されるようにして、コードはそれを
継承して書くとかする
Client
RPC Library
Service Definition
Client Stub
Server
Server Stub
RPC Library
Metaclass
18. class HelloServer(Socketserver.ThreadingMixIn,
xmlrpc.server.SimpleXMLRPCServer):
Copyright (c) 2014 Ransui Iso, All rights reserved.
サーバのスレッド化
● 簡単にスレッド化ができる
– SimpleXMLRPCServerはSocketServerを利用して構築
されていることを利用する。
import xmlrpc.server
import socketserver
import xmlrpc.server
import socketserver
class HelloServer(Socketserver.ThreadingMixIn,
xmlrpc.server.SimpleXMLRPCServer):
allow_reuse_address = True
allow_reuse_address = True
request_queue_size = 1024
request_queue_size = 1024
def __init__(self, *args, **kw):
def __init__(self, *args, **kw):
super().__init__(*args, **kw)
super().__init__(*args, **kw)
19. return Binary(pickle.dumps(target_object, protocol=2))
return encode_to_binary(blahblah(decode_from_binay(args))
self.proxy.server_side_method(encode_to_binary(args))
Copyright (c) 2014 Ransui Iso, All rights reserved.
複雑なデータ
● インスタンスとかの送受信
– デコレータ化すればもっとかっこよくできる
import pickle
from xmlrpc.client import Binary
import pickle
from xmlrpc.client import Binary
def encode_to_binary(target_object):
def encode_to_binary(target_object):
return Binary(pickle.dumps(target_object, protocol=2))
def decode_from_binary(binary_image):
def decode_from_binary(binary_image):
return pickle.loads(binary_image.data)
return pickle.loads(binary_image.data)
def server_side_method(self, args):
def server_side_method(self, args):
return encode_to_binary(blahblah(decode_from_binay(args))
def client_side_method(self, args):
def client_side_method(self, args):
result = decode_from_binary(
result = decode_from_binary(
self.proxy.server_side_method(encode_to_binary(args))
21. Viewer
Search
Application
MonkeyPod ディレクトリ
Copyright (c) 2014 Ransui Iso, All rights reserved.
● データベースと検索に使用
MonkeypodTreeServer
Tree maintainer
Get Node
Get Review
etc.
SiteData
Data Manage
22. ● 広告配信のターゲティングルールの管理
Rule Builer
RuleEngine
Stats / Report
Application
Copyright (c) 2014 Ransui Iso, All rights reserved.
ターゲティングルール
Set Rule
RuleServer
Object Storage
Create New Rule
Get Rule
Storage File
Remove Rule
24. Copyright (c) 2014 Ransui Iso, All rights reserved.
使い所と注意
● ちょっとしたサービスが必要なときに
– とにかくPythonがインストールされていれば使える
– 変な設定ファイルとかサーバプロセスとかいらない
– サービス側のコードを書く際に、お作法とか無いので何
でもやり放題
● 気をつけたいところ
– pickleとか無節操に使うとPython縛りに
– 真の意味でパフォーマンスが必要なときは使っちゃダメ
25. Thank you for listening.
Happy Hacking with Python!
Copyright (c) 2014 Ransui Iso, All rights reserved.