ソースコード探訪:turbogears.toolbox.shell.WebConsole¶
turbogears.toolbox.shell.WebConsole クラスのコードを読む。 Web画面上でPython対話コンソール(InteractiveShell)を実現するためのサーバー側実装コードは100行無かった!こんなに短いとは‥‥。全ては code.InteractiveConsole クラスのお力か。
で、このコードを発展させて、自分でソケットを開いてリモート対話シェルを作ってみる。
import sys
import StringIO
from code import InteractiveConsole
import socket
def init_ps():
try:
sys.ps1
except AttributeError:
sys.ps1 = '>>> '
try:
sys.ps2
except AttributeError:
sys.ps2 = '... '
class RemoteConsole(object):
"""Remote Python interpreter"""
def __init__(self):
self.console = None
init_ps()
def process_request(self, line):
more, output = self._process_request(line)
return dict(more=more, output=output)
def _process_request(self, line):
myout = StringIO.StringIO()
try:
sys.stdout = myout
sys.stderr = myout
more = self.console.push(line)
finally:
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
output = myout.getvalue()
return ( more, output.rstrip() )
def new_console(self):
locs = dict(__name__='RemoteConsole',
__doc__=None,
reload_console=self.new_console,
)
self.console = InteractiveConsole(locals=locs)
def connect(self):
if not self.console:
self.new_console()
def disconnect(self):
if self.console:
self.console = None
def server():
rc = RemoteConsole()
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('',10000))
s.listen(1)
conn,addr=s.accept()
rc.connect()
while 1:
data = conn.recv(1000000)
#print 'r',len(data)
ret = rc.process_request(data)
ret = unicode(ret)
#print 's',len(ret)
conn.send(ret)
def client():
init_ps()
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('localhost',10000))
more = False
while 1:
data = raw_input(more and sys.ps2 or sys.ps1)
if len(data) == 0:
data = '\n'
s.send(data)
ret = s.recv(1000000)
ret = eval(ret)
output = ret.get('output')
more = ret.get('more', False)
if output:
print output
if __name__ == '__main__':
if len(sys.argv) == 1:
print 'Run as server'
server()
else:
print 'Run as client'
client()
ちょー適当だけど、とりあえず動くだけなら出来た。97行。
このコードをtestconsole.pyとして保存して実行してみる。
見た目分かりづらいけど、ネットワーク越しにPython対話シェルもどきが動いている。この先にあるのは、パクり元のWebConsoleのネットワーク版。
Pythonで書かれたサーバーにモニタリング用ポートを開けて、好きなタイミングでサーバー稼働中のPythonプロセスで対話シェルを操作できるようになる‥‥といいなあ。モデルの状態を見たり、メモリ利用状態の調査をしたり色々できるんじゃなかろうか。