iterable-subprocess
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 processstderr- 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)
Release files for iterable-subprocess 0.0.16
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| iterable_subprocess-0.0.16.tar.gz | 5.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| iterable_subprocess-0.0.16-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 10.6 kB
Release files / iterable_subprocess-0.0.16.tar.gz
| Download URL | iterable_subprocess-0.0.16.tar.gz |
|---|---|
| Size | 5.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6f8b1a5ae29f1e33d89805bfd28c7b9eea71a1f381b36932d4060ae4cb1cac83
|
|
BLAKE2b-256 checksum How to use checksums |
8315eb6f79183d803b9457a32cdce6c347ecf604838d154fd193372cdeb1a89a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/4.0.2 CPython/3.11.4
|
Release files / iterable_subprocess-0.0.16-py3-none-any.whl
| Download URL | iterable_subprocess-0.0.16-py3-none-any.whl |
|---|---|
| Size | 5.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
952561f8d7b013a637f2740a5bca59e95c238b5a42ac4765c85872ee51e316fd
|
|
BLAKE2b-256 checksum How to use checksums |
0d94822db29d5c9003a8b34462660403888c44457391bda3b3e1837e72d4c2ca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/4.0.2 CPython/3.11.4
|