読者です 読者をやめる 読者になる 読者になる

XML-RPCでPerlとPythonを結ぶ

Perl Python 問題発見と解決

ここのToDoがちょっと終わった。

僕が何をやりたいのかを説明すると

  • Perlで引っ張ってきたデータをRに処理させたい
  • でも、そのままじゃ処理させることができない
    • RSPerlとかあるけど、あんまり好きじゃない*1
    • バッチファイル処理させて、云々やってもいいけどかっこよくない*2
  • Pythonからならrpyがあるから触ることができる
  • じゃあ、PythonとPerlをつなげば、PerlとRをつなぐことができるな
  • 俺がつなぐことのできる技術はXML-RPCくらいか
  • じゃあ、XML-RPCで実装しますか

という流れ。以下コードとか。
http://www.linux.or.jp/JF/JFdocs/XML-RPC-HOWTO/xmlrpc-howto-perl.htmlのコードを拝借して、サーバー側を実装。

use Frontier::Daemon;

sub sumAndDifference {
    my ( $x, $y ) = @_;
    return { 'sum' => $x + $y, 'difference' => $x - $y };
}

# Call me as http://localhost:8080/RPC2
$methods = { 'sample.sumAndDifference' => \&sumAndDifference };
Frontier::Daemon->new( LocalPort => 3000, methods => $methods )
  or die "Couldn't start HTTP server: $!";

クライアント側をperlで書くとこう、って移したまんまですが。

use Frontier::Client;

# Make an object to represent the XML-RPC server.
$server_url = 'http://localhost:3000/RPC2';
$server = Frontier::Client->new( url => $server_url );

# Call the remote server and get our result.
$result     = $server->call( 'sample.sumAndDifference', 5, 3 );
$sum        = $result->{'sum'};
$difference = $result->{'difference'};

print "Sum: $sum, Difference: $difference\n";

で、pythonでクライアントを実装させるとこんな感じに。

import xmlrpclib

server_url='http://localhost:3000'
server=xmlrpclib.Server(server_url)
calc=server.sample.sumAndDifference(5,3)
for item in calc.iteritems():
    print item

実行させるとこんな感じ。辞書で返ってきますた。

localhost% python client.py
python client.py
('sum', 8)
('difference', 2)

pythonでサーバー側の実装も簡単ですね。わっふるわっふる。この辺参考にしますた。

import SimpleXMLRPCServer

class PliceString:
    def hello_world(self):
        return("hello world!")
        
ps = PliceString()
sv = SimpleXMLRPCServer.SimpleXMLRPCServer(('localhost', 8888))
sv.register_instance(ps)
sv.serve_forever()

*1:あんまり使ったことないけど、好きになれなかった記憶がある。

*2:何それwww