shtoobz
Talk to a child process or a TCP socket through the same Python API. A shtoob handles bytes, buffering, prompts, and timeouts so your client code can stay the same when you switch transports.
Python 3.11+ · Windows and Linux · No runtime dependencies
Install
In an existing uv project:
uv add shtoobz
Or install into your Python environment with python -m pip install shtoobz.
This is a Python library; there is no shtoobz command to launch.
Try a process
Save this as hello.py. It launches a Python child, sends a line, and reads the
child's response. It runs on both Windows and Linux without an external server.
import sys
from shtoobz import ProcessShtoob
with ProcessShtoob(
[
sys.executable, "-u", "-c",
"print(input().upper(), flush=True)",
],
timeout=5,
) as shtoob:
shtoob.sendline(b"hello")
reply = shtoob.recvline()
print(reply.decode().rstrip("\r\n"))
Run uv run python hello.py from your project, or python hello.py if you used
pip. You should see:
HELLO
The with block closes the shtoob and cleans up the child. Python's -u option
keeps the child's output unbuffered so responses arrive promptly.
Switch transports
For an application that exposes the same byte protocol over stdin/stdout and
TCP, switch the connection by changing LOCAL. The example below expects your
application to print Name: , accept a name, and reply with a newline-terminated
message. Replace the executable path or host and port with your own target.
from shtoobz import ProcessShtoob, SocketShtoob
LOCAL = True
shtoob = (
ProcessShtoob(
["./example", "--stdio"], timeout=5,
)
if LOCAL
else SocketShtoob("127.0.0.1", 9000, timeout=5)
)
with shtoob:
shtoob.sendlineafter(
b"Name: ", b"Alice", max_bytes=4096,
)
print(shtoob.recvline(max_bytes=4096))
On Windows, use your executable's path, for example r".\example.exe".
Both endpoints must speak the same protocol; shtoobz does not translate between
a CLI menu and a different network protocol.
To keep connection setup out of your client, accept the shared Shtoob type:
from shtoobz import Shtoob
class Client:
def __init__(self, shtoob: Shtoob):
self.shtoob = shtoob
def request(self, payload: bytes) -> bytes:
self.shtoob.sendline(payload)
return self.shtoob.recvline(max_bytes=4096)
Choose a read
| You need | Use |
|---|---|
| Up to a number of bytes | recv(n) |
| Exactly a number of bytes | recvn(n) |
| A prompt or delimiter | recvuntil(b"> ") |
| One line, including its newline | recvline() |
| Everything until the peer closes its output | recvall() |
| Output until an idle gap | recv_available() |
| A stream of lines or chunks | iterlines() or iterchunks() |
Payloads and delimiters are bytes. Encode text before sending and decode it
after reading. Reads retain bytes beyond a delimiter for the next call.
Set a finite timeout when you want a stalled read to fail. The default waits
indefinitely. A timeout preserves partial input so you can continue the same
read. Writes are blocking and have no timeout.
recv(n) may return fewer than n bytes; recvn(n) waits for the exact count.
recvline() raises ShtoobEOF if the peer closes before a newline arrives.
Use iterlines() when an unterminated final line should be returned.
The API reference covers errors and recovery, response limits, prompt helpers, buffering, streaming, traffic logging, and transport options.
Supported use
shtoobz supports redirected process pipes and IPv4/IPv6 TCP connections. Use it for programs that accept bytes on stdin and write responses to stdout, or expose the same protocol through a socket. A child must flush its output promptly.
PTY/ConPTY terminal emulation, interactive terminal forwarding, async APIs, TLS, server listeners, and process-tree management are outside the current scope. Closing a process shtoob terminates and reaps its direct child, not descendants.
More documentation
- API reference: method behavior, timeout and EOF rules, examples, and lifecycle.
- Development and releases: work on the package, run checks, and publish with GitLab.
- Issues: report a problem or request a feature.
Licensed under the MIT License. Copyright 2026 Jeremy Dunn.
Metadata
Release files for shtoobz 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| shtoobz-0.1.1.tar.gz | 45.4 kB | Without provenance | Details for shtoobz-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| shtoobz-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for shtoobz-0.1.1-py3-none-any.whl |
Total release size: 57.6 kB
Release files / shtoobz-0.1.1.tar.gz
| Download URL | shtoobz-0.1.1.tar.gz |
|---|---|
| Size | 45.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
61cbf57e2365757ea47b59d850584d4f9cc473c6478199428d64d5447b1c5926
|
|
BLAKE2b-256 checksum How to use checksums |
fe8f7c69ccaf25111f420ef884eb2d2264cbbdbe4ac6e76b903ac14746144a9c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / shtoobz-0.1.1-py3-none-any.whl
| Download URL | shtoobz-0.1.1-py3-none-any.whl |
|---|---|
| Size | 12.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c78db680b34766417ef6c59d39c3222be8e8dad128538d345882c9bfb38393ba
|
|
BLAKE2b-256 checksum How to use checksums |
340bdfdf615bd795f53c5eb3b1300d4d677e25ff8fd3aec9be7f6362a7d841e5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for shtoobz 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.