osrf_pycommon.process_utils.async_execute_process_asyncio package
Submodules
Module contents
- async osrf_pycommon.process_utils.async_execute_process_asyncio.async_execute_process(protocol_class, cmd=None, cwd=None, env=None, shell=False, emulate_tty=False, stderr_to_stdout=True)
Coroutine to execute a subprocess and yield the output back asynchronously.
This function is meant to be used with the Python
asyncio
module, which is available in Python 3.5 or greater.Here is an example of how to use this function:
import asyncio from osrf_pycommon.process_utils import async_execute_process from osrf_pycommon.process_utils import AsyncSubprocessProtocol from osrf_pycommon.process_utils import get_loop async def setup(): transport, protocol = await async_execute_process( AsyncSubprocessProtocol, ['ls', '/usr']) returncode = await protocol.complete return returncode retcode = get_loop().run_until_complete(setup()) get_loop().close()
Tthe first argument is the default
AsyncSubprocessProtocol
protocol class, which simply prints output from stdout to stdout and output from stderr to stderr.If you want to capture and do something with the output or write to the stdin, then you need to subclass from the
AsyncSubprocessProtocol
class, and override theon_stdout_received
,on_stderr_received
, andon_process_exited
functions.See the documentation for the
AsyncSubprocessProtocol
class for more details, but here is an example which uses asyncio from Python 3.5:import asyncio from osrf_pycommon.process_utils import async_execute_process from osrf_pycommon.process_utils import AsyncSubprocessProtocol from osrf_pycommon.process_utils import get_loop class MyProtocol(AsyncSubprocessProtocol): def __init__(self, file_name, **kwargs): self.fh = open(file_name, 'w') AsyncSubprocessProtocol.__init__(self, **kwargs) def on_stdout_received(self, data): # Data has line endings intact, but is bytes in Python 3 self.fh.write(data.decode('utf-8')) def on_stderr_received(self, data): self.fh.write(data.decode('utf-8')) def on_process_exited(self, returncode): self.fh.write("Exited with return code: {0}".format(returncode)) self.fh.close() async def log_command_to_file(cmd, file_name): def create_protocol(**kwargs): return MyProtocol(file_name, **kwargs) transport, protocol = await async_execute_process( create_protocol, cmd) returncode = await protocol.complete return returncode get_loop().run_until_complete( log_command_to_file(['ls', '/'], '/tmp/out.txt')) get_loop().close()
See the
subprocess.Popen
class for more details on some of the parameters to this function likecwd
,env
, andshell
.See the
osrf_pycommon.process_utils.execute_process()
function for more details on theemulate_tty
parameter.- Parameters:
protocol_class (
AsyncSubprocessProtocol
or a subclass) – Protocol class which handles subprocess callbackscmd (list) – list of arguments where the executable is the first item
cwd (str) – directory in which to run the command
env (dict) – a dictionary of environment variable names to values
shell (bool) – if True, the
cmd
variable is interpreted by a the shellemulate_tty (bool) – if True, pty’s are passed to the subprocess for stdout and stderr, see
osrf_pycommon.process_utils.execute_process()
.stderr_to_stdout (bool) – if True, stderr is directed to stdout, so they are not captured separately.
- osrf_pycommon.process_utils.async_execute_process_asyncio.get_loop()
This function will return the proper event loop for the subprocess async calls.
On Unix this just returns
asyncio.get_event_loop()
, but on Windows it will set and return aasyncio.ProactorEventLoop
instead.