• Save
XML-RPC : Pythonが「電池付属」と呼ばれる理由
Upcoming SlideShare
Loading in...5
×
 

XML-RPC : Pythonが「電池付属」と呼ばれる理由

on

  • 238 views

PyConJP 2014 のセッションでお話した時に使用したスライドです。

PyConJP 2014 のセッションでお話した時に使用したスライドです。

Statistics

Views

Total Views
238
Views on SlideShare
213
Embed Views
25

Actions

Likes
1
Downloads
0
Comments
0

1 Embed 25

https://twitter.com 25

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

XML-RPC : Pythonが「電池付属」と呼ばれる理由 XML-RPC : Pythonが「電池付属」と呼ばれる理由 Presentation Transcript

  • 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.
  • 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
  • Remote Procedure Call Copyright (c) 2014 Ransui Iso, All rights reserved. 昔からあるんです
  • Copyright (c) 2014 Ransui Iso, All rights reserved. 有名どころ ● Sun RPC – NFSの基盤として開発された – XDRという形式で情報をシリアライズする ● なんとPython標準モジュールにでXDRを取り扱える – 現役で色々と使われている ● その他にも – DCE/RPC – OMG CORBA – DCOM
  • ham spam egg Copyright (c) 2014 Ransui Iso, All rights reserved. そも、RPCとは? ● 言語が提供する「呼び出し規約」を拡張する – 利用者はRPCをサポートする言語でプログラミングをす るとき、ほとんどRPCの存在を意識する必要がない。 ham spam egg Remote Local この時ローカルから result = spam(args) という感じでリモート のメソッドを呼び出せるということ
  • – インタフェースの定義からStubライブラリを作成しそれ を利用することでリモート呼び出しの詳細を隠蔽する Server Code Application Code Client もうすこし細かく見てみる ● 魔法は存在しないのでタネがある RPC Library Copyright (c) 2014 Ransui Iso, All rights reserved. IDL Client Stub Server Server Stub RPC Library IDL Compiler
  • Copyright (c) 2014 Ransui Iso, All rights reserved. XML-RPC
  • メッセージ形式がXMLなRPC ● 通信そのものはHTTPが使われることが多い – HTTPのbody部分に呼び出しや戻り値についての情報を XML形式で記述してメッセージとして交換する – 当然のことながらXMLの冗長性のおかげでオーバーヘッ ドが大きくてパフォーマンス的には不利 – バイナリプロトコルに対してHuman Readableだという 部分くらいしか利点が思いつかない…… Copyright (c) 2014 Ransui Iso, All rights reserved.
  • Copyright (c) 2014 Ransui Iso, All rights reserved. PythonでのXML-RPC ● 標準ライブラリにある – クライアント・サーバモデル – xmlrpc.servsr サーバ側 – xmlrpc.client クライアント側 ● PurePythonによる実装 – cPythonが動く環境であればまずどこでも使える – 改造も簡単。色々できる。
  • 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)
  • 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
  • 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()
  • 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"))
  • もう少し使いやすく 日々の道具として使うための工夫 Copyright (c) 2014 Ransui Iso, All rights reserved.
  • ServerとClient分離問題 ham spam egg Copyright (c) 2014 Ransui Iso, All rights reserved. ● 見通しの悪さを改善する – サーバもクライアントも1つのモジュールをimportする – 下のような状態を維持しやすくする ham spam egg RequestHandler ServiceClient
  • 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
  • 使いこなし Copyright (c) 2014 Ransui Iso, All rights reserved.
  • 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)
  • 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))
  • Copyright (c) 2014 Ransui Iso, All rights reserved. 事例 弊社では使いまくってます
  • Viewer Search Application MonkeyPod ディレクトリ Copyright (c) 2014 Ransui Iso, All rights reserved. ● データベースと検索に使用 MonkeypodTreeServer Tree maintainer Get Node Get Review etc. SiteData Data Manage
  • ● 広告配信のターゲティングルールの管理 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
  • Copyright (c) 2014 Ransui Iso, All rights reserved. まとめ
  • Copyright (c) 2014 Ransui Iso, All rights reserved. 使い所と注意 ● ちょっとしたサービスが必要なときに – とにかくPythonがインストールされていれば使える – 変な設定ファイルとかサーバプロセスとかいらない – サービス側のコードを書く際に、お作法とか無いので何 でもやり放題 ● 気をつけたいところ – pickleとか無節操に使うとPython縛りに – 真の意味でパフォーマンスが必要なときは使っちゃダメ
  • Thank you for listening. Happy Hacking with Python! Copyright (c) 2014 Ransui Iso, All rights reserved.