Skip to content

Instantly share code, notes, and snippets.

@maedoc
Last active August 29, 2015 13:56
Show Gist options
  • Select an option

  • Save maedoc/9095289 to your computer and use it in GitHub Desktop.

Select an option

Save maedoc/9095289 to your computer and use it in GitHub Desktop.
control Python REPL over HTTP
import os
import sys
import atexit
import tempfile
import traceback
from urlparse import urlparse, parse_qs
import BaseHTTPServer
try:
from cStringIO import StringIO
except:
from StringIO import StringIO
import numpy
exec_temp_files = []
class HREPL(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
pr = urlparse(self.path)
qd = parse_qs(pr.query, keep_blank_values=True, strict_parsing=True)
target = getattr(self, 'do_' + '_'.join(pr.path[1:].split('/')), None)
if target is None:
return self.send_response(404)
self.send_response(200)
self.end_headers()
self.wfile.write(target(**qd))
def do_ex(self, message=[], **kwds):
src = message[0]
print src
print repr(src)
out, err = sys.stdout, sys.stderr
sio = StringIO()
sys.stdout = sys.stderr = sio
try:
try:
print repr(eval(src, globals()))
except SyntaxError:
# TODO have Vim send us file & line numbers instead of using a temp file
f = tempfile.NamedTemporaryFile(suffix='.py', delete=False)
exec_temp_files.append(f)
f.write(src)
f.close()
execfile(f.name, globals())
except Exception as e:
print e
traceback.print_exc(e)
sys.stdout, sys.stderr = out, err
output = sio.getvalue()
print 'output = ', repr(output)
return output
def do_complete(self, message=[], **kwds):
name = message[0]
if '.' in name:
parts = name.split('.')
base, name = '.'.join(parts[:-1]), parts[-1]
try:
keys = dir(eval(base, globals()))
except Exception as e:
print 'completion failed', e
return ''
base += '.'
else:
base = ''
keys = globals().keys()
return ','.join('%s%s' % (base, k) for k in keys if k.startswith(name))
def do_describe(self, message=[], **kwds):
name = message[0]
g = globals()
if name == 'whos':
return '\n'.join('%-30s %s' % (k, type(g[k]))
for k in sorted(g.keys())
if not k.startswith('_'))
if name not in g:
return ''
obj = g[name]
if isinstance(obj, numpy.ndarray):
return '%s %r' % (obj.dtype.name, obj.shape)
else:
return repr(obj)[:80]
@atexit.register
def close_temp_files():
for f in exec_temp_files:
try:
os.unlink(f.name)
except Exception as e:
print e
def main(address='127.0.0.1', port=8080, protocol='HTTP/1.0'):
HREPL.protocol_version = protocol
httpd = BaseHTTPServer.HTTPServer((address, port), HREPL)
sa = httpd.socket.getsockname()
print 'HREPL on ', sa[0], 'port', sa[1]
httpd.serve_forever()
#TODO consider threaded so can launch from ipy console?
if __name__ == '__main__':
main()
@maedoc
Copy link
Author

maedoc commented Feb 19, 2014

works in coordination with some Vim functions in ftplugin/python.vim

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment