Source code for emit.multilang

'class to communicate with other languages over stdin/out'
import json
import logging
import shlex
from subprocess import Popen, PIPE


[docs]class ShellNode(object): '''\ callable object to wrap communication to a node in another language to use this, subclass ``ShellNode``, providing "command". Decorate it however you feel like. Messages will be passed in on lines in msgpack format. This class expects similar output: msgpack messages separated by a newline. ''' def __init__(self): self.logger = logging.getLogger('%s.%s' % ( self.__class__.__module__, self.__class__.__name__ )) self.logger.debug('initialized %s', self.__class__.__name__) @property def __name__(self): 'fix for being able to use functools.wraps on a class' return self.__class__.__name__
[docs] def __call__(self, msg): 'call the command specified, processing output' process = Popen( self.get_command(), stdout=PIPE, stderr=PIPE, stdin=PIPE, cwd=self.get_cwd() ) msg_json = msg.as_json() try: stdout, stderr = process.communicate(bytes(msg_json, 'UTF-8')) except TypeError: # python 2.7.2 stdout, stderr = process.communicate(msg_json) if stderr: self.logger.error('Error calling "%s": %s', self.command, stderr) raise RuntimeError(stderr) messages = stdout.decode('UTF-8').strip().split('\n') self.logger.debug('subprocess returned %d messages', len(messages)) for message in messages: yield self.deserialize(message)
[docs] def get_command(self): 'get the command as a list' return shlex.split(self.command)
[docs] def get_cwd(self): 'get directory to change to before running the command' try: return self.cwd except AttributeError: self.logger.debug('no cwd specified, returning None') return None
[docs] def deserialize(self, msg): 'deserialize output to a Python object' self.logger.debug('deserializing %s', msg) return json.loads(msg)

Project Versions

This Page