Skip to main content

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

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)

Source distribution for shtoobz 0.1.1
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)

Table of built distributions (wheels) for shtoobz 0.1.1
File Interpreter ABI Platform Actions
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.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page