Skip to main content

Intuitive API to safely start and communicate with processes in Python

Project description

Subrun

Intuitive API to safely start and communicate with processes in Python.

This project is part of the Pyrustic Open Ecosystem.

Installation . Demo . Latest . Documentation

Table of contents

Overview

Python comes with the subprocess module that allows to spawn new processes. In a unified module, subprocess provides enhancements over previous functions for the same task.

Based on the subprocess module, Subrun is a library that makes convenience and security a priority for spawning new processes. With Subrun, commands are provided as strings (or as a sequence of strings) that are safely executed without involving the system shell and a consistent NamedTuple is returned to give you useful information about what just happened (success boolean, return codes from each process of a pipeline, boolean timeout_expired, et cetera).

The library is made up of two categories of functions:

  • Three functions that synthesize the operations you will need to perform: run, ghostrun, and capture.
  • Three base functions that helped build the previous functions: create, wait, and communicate.

These functions, originally designed to spawn one process at a time, are mirrored in subrun.pipeline, a module dedicated to the pipeline mechanism.

Operations

Let's take a look at run, ghostrun, and capture, three convenience functions that attempt to synthesize use cases into three eponymous operations.

Run

Use the run function to spawn a new process that a user can interact with from the command line. This function returns a NamedTuple with useful information (e.g., the return code, et cetera).

import subrun

command = "python -m this"
subrun.run(command)  # returns a NamedTuple

Note: Subrun recognizes the python command and replaces it with the fully-qualified path of the executable binary for the current Python interpreter.

The run function also accepts these keywords-arguments: input, cwd, stdin, stdout, stderr, and timeout.

Example

hello.py: Simple program that asks for your name and gender, then greets you.

# hello.py
name = input()
gender = input()
msg = "Hello {} ! You are a {} !".format(name, gender)
print(msg)

script.py: Simple script that uses subrun to run hello.py and programmatically send it an arbitrary name and gender.

# script.py
import subrun

command = "python -m hello"
subrun.run(command, input="Alex\nMale")
# note that you can also set the 'cwd' parameter 
# (current working directory)

# also, in this specific example,
# if you don't set the 'input' programmatically,
# it will be prompted to the user

command line: Let's run script.py !

$ python -m script
Hello Alex ! You are a Male !

Ghostrun

Use the ghostrun function to run a command without any feedback. Ghostrun is like the run function with one twist: stderr and stdout are redirected to devnull. This function returns a NamedTuple with useful information (e.g., the return code of the process, the success boolean, et cetera).

script.py: This script uses subrun to ghostrun the command "python -m this".

# script.py
import subrun

command = "python -m this"
subrun.ghostrun(command)  # returns a NamedTuple instance

command line: Let's run script.py !

$ python -m script
$

Capture

Use the capture function to run and capture the output of a command. This function returns a NamedTuple instance with useful information (e.g., the return code of the process, the stdout data, the stderr data, et cetera).

# script.py
import subrun

command = "python -m this"
info = subrun.capture(command)  # returns a NamedTuple instance

# info.output contains the Zen Of Python as encoded bytes

Base functions

The run, ghostrun, and capture functions use three base functions:

  • create: Run a command and return a process object.
  • wait: Wait for a process to terminate.
  • communicate: Interact with a process.

The run and ghostrun functions use create and wait base functions. The capture function use create and communicate base functions.

Example

import subrun

# === Create and Wait ===
# Command
command = "python -m this"
# Create the process with the command
process = subrun.create(command)
# Wait the process to end
info = subrun.wait(process)

# === Create and Communicate ===
# Command
command = "python -m hello"
# Create the process with the command
process = subrun.create(command)
# Capture the output of the process
info = subrun.communicate(process, input="Alex\nMale")

Pipeline

The subrun.pipeline module reproduces the same API as in subrun with a twist: you must provide more than one command which will be chained and executed.

Example

The run, ghostrun, and capture functions are defined in the subrun.pipeline module to process a pipeline of commands:

from subrun import pipeline

command1 = "python -m hello"
command2 = "program arg1 arg2"
command3 = "/path/to/program --arg data"

# === Run ===
# Run three commands pipeline. A NamedTuple instance is returned
pipeline.run(command1, command2, command3, input="Alex\nMale")

# === Ghostrun ===
# Ghostrun three commands pipeline. A NamedTuple instance is returned
pipeline.ghostrun(command1, command2, command3)

# === Capture ===
# Capture three commands pipeline. A NamedTuple instance is returned
info = pipeline.capture(command1, command2, command3)

The create, wait, and communicate base functions are also defined in the subrun.pipeline module to process a pipeline of commands:

from subrun import pipeline

command1 = "python -m hello"
command2 = "program arg1 arg2"
command3 = "/path/to/program --arg data"

# === Create and Wait ===
# Create a generator so that you can iterate over created processes
generator = pipeline.create(command1, command2, command3)
# Wait the process to end
pipeline.wait(generator)

# === Create and Communicate ===
# Create a generator so that you can iterate over created processes
generator = pipeline.create(command1, command2, command3)
# Capture the output of the process
pipeline.communicate(generator)

Related project

Backstage is a language-agnostic command-line tool that allows the developer to define, coordinate and use the various resources at his disposal to create and manage a software project.

Backstage uses Subrun extensively.

Discover Backstage !

Installation

Subrun is cross platform and versions under 1.0.0 will be considered Beta at best. It is built on Ubuntu with Python 3.8 and should work on Python 3.5 or newer.

For the first time

$ pip install subrun

Upgrade

$ pip install subrun --upgrade --upgrade-strategy eager

Demo

A demo is available to play with as a Github Gist. Feel free to give a feedback in the comments section.

Play with the Demo.




Back to top

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

subrun-0.0.8.tar.gz (10.9 kB view hashes)

Uploaded Source

Built Distribution

subrun-0.0.8-py3-none-any.whl (10.5 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page