Skip to main content

Python context manager to communicate with a subprocess using iterables of bytes rather Python's built-in subprocess module

Project description

iterable-subprocess

PyPI package Test suite Code coverage

Python context manager to communicate with a subprocess using iterables. This offers a higher level interface to subprocesses than Python's built-in subprocess module, and is particularly helpful when data won't fit in memory and has to be streamed.

This also allows an external subprocess to be naturally placed in a chain of iterables as part of a data processing pipeline.

Installation

pip install iterable-subprocess

Usage

A single context manager iterable_subprocess is exposed. The first parameter is the args argument passed to the Popen Constructor, and the second is an iterable whose items must be bytes instances and are sent to the subprocess's standard input.

Returned from the function is an iterable whose items are bytes instances of the process's standard output.

from iterable_subprocess import iterable_subprocess

# In a real case could be a generator function that reads from the filesystem or the network
iterable_of_bytes = (
    b'first\n',
    b'second\n',
    b'third\n',
)

with iterable_subprocess(['cat'], iterable_of_bytes) as output:
    for chunk in output:
        print(chunk)

Exceptions

Python's subprocess.Popen is used to start the process, and any exceptions it raises are propagated without transformation. For example, if the subprocess can't be found, then a FileNotFoundError is raised.

If the process starts, but exits with a non-zero return code, then an iterable_subprocess.IterableSubprocessError exception will be raised with two members:

  • returncode - the return code of the process
  • stderr - the final 65536 bytes of the standard error of the process

However, if the process starts, but an exception is raised from inside the context or from the source iterable, then this exception is propagated, even if the process subsequently exits with a non-zero return code.

Example: unzip the first file of a ZIP archive while downloading

It's possible to download the bytes of a ZIP file in Python, and unzip by passing the bytes to funzip, as in the following example.

import httpx
from iterable_subprocess import iterable_subprocess

with \
        httpx.stream('GET', 'https://www.example.com/my.zip') as r, \
        iterable_subprocess(['funzip'], r.iter_bytes()) as unzipped_chunks:

    for chunk in unzipped_chunks:
        print(chunk)

Note that it's also possible to stream unzip files without resorting to another process using stream-unzip.

Example: download file using curl and process in Python

You would usually download directly from Python, but as an example, you can download using the curl executable and process its output in Python.

from iterable_subprocess import iterable_subprocess

url = 'https://data.api.trade.gov.uk/v1/datasets/uk-tariff-2021-01-01/versions/v3.0.212/tables/measures-on-declarable-commodities/data?format=csv'
with iterable_subprocess(['curl', '--no-progress-meter', '--fail-with-body', url], ()) as output:
    for chunk in output:
        print(chunk)

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

iterable_subprocess-0.0.16.tar.gz (5.4 kB view details)

Uploaded Source

Built Distribution

iterable_subprocess-0.0.16-py3-none-any.whl (5.2 kB view details)

Uploaded Python 3

File details

Details for the file iterable_subprocess-0.0.16.tar.gz.

File metadata

  • Download URL: iterable_subprocess-0.0.16.tar.gz
  • Upload date:
  • Size: 5.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.4

File hashes

Hashes for iterable_subprocess-0.0.16.tar.gz
Algorithm Hash digest
SHA256 6f8b1a5ae29f1e33d89805bfd28c7b9eea71a1f381b36932d4060ae4cb1cac83
MD5 601208269eeee9b42cc9c720571fef42
BLAKE2b-256 8315eb6f79183d803b9457a32cdce6c347ecf604838d154fd193372cdeb1a89a

See more details on using hashes here.

File details

Details for the file iterable_subprocess-0.0.16-py3-none-any.whl.

File metadata

File hashes

Hashes for iterable_subprocess-0.0.16-py3-none-any.whl
Algorithm Hash digest
SHA256 952561f8d7b013a637f2740a5bca59e95c238b5a42ac4765c85872ee51e316fd
MD5 4a6a71bf32a4ede112710aa5fe9ffe91
BLAKE2b-256 0d94822db29d5c9003a8b34462660403888c44457391bda3b3e1837e72d4c2ca

See more details on using hashes here.

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