Stdlib-only local IPC — Unix sockets, FIFOs, JSON-line protocol.
Project description
┌─────────────────┐ ╔═════════════════╗
│ codechu — ipc │═════>║ your daemon ║
│ client │ JSON ║ handler(req) ║
│ request() │<═════║ → response ║
└─────────────────┘ line ╚═════════════════╝
unix socket · fifo · json-line · pidfile
Local IPC the boring way — Unix sockets, FIFOs, one JSON object per line.
codechu-ipc
Stdlib-only local IPC for Linux daemons and sidecars: Unix domain sockets, named pipes (FIFOs), JSON-line framing, server lifecycle helpers. No third-party dependencies. Python 3.10+.
Linux is the primary target; BSD/macOS are best-effort (anything
POSIX-y with AF_UNIX and mkfifo should work).
Install
pip install codechu-ipc
API at a glance
from codechu_ipc import UnixServer, UnixClient, FifoChannel, pidfile
# --- Server side ------------------------------------------------------
def handler(req: dict) -> dict:
return {"echo": req}
with UnixServer("/run/codechu/myapp/control.sock", handler):
... # serve until the context exits
# --- Client side ------------------------------------------------------
client = UnixClient("/run/codechu/myapp/control.sock")
response = client.request({"cmd": "status"}) # → {"echo": ...}
client.notify({"cmd": "shutdown"}) # fire-and-forget
# --- FIFO -------------------------------------------------------------
ch = FifoChannel("/run/codechu/myapp/events.fifo")
ch.send({"event": "rescan-done"}) # non-blocking
msg = ch.recv() # blocks for next
# --- Lifecycle --------------------------------------------------------
with pidfile("/run/codechu/myapp/daemon.pid"):
serve_forever()
Why JSON-line?
- One object per line. Trivial to parse from any language, any shell pipeline, any log viewer.
- No length prefixes, no schemas. Easy to inspect with
nc -Uorsocatwhile debugging. - Backpressure is the OS's problem. The kernel's socket buffers do the queuing; this library stays a thin wrapper.
If you need binary framing, multiplexing, or RPC semantics, you want gRPC, not this.
UnixServer(path, handler, *, mode=0o600, backlog=16)
- Background accept-loop thread; one worker thread per connection.
- Default socket permissions: owner-only (0o600). Override with
mode=. - Auto-cleans stale socket files from a crashed previous run; refuses
to overwrite a live socket (raises
FileExistsError). - Handler returning
Nonemeans "this was a notification, send no response". Anything else is encoded back as one JSON line. - Handler exceptions are caught and returned to the client as
{"error": "...", "type": "..."}— the server keeps serving. - Context manager:
with UnixServer(...) as srv: ...callsstart()/stop()for you.
UnixClient(path, *, timeout=5.0, retries=3, retry_backoff=0.5)
request(payload)— send a JSON line, read one back.notify(payload)— send a JSON line, close. No response read.- Retries on
ConnectionRefusedError/FileNotFoundError, with exponential backoff (0.5s, 1.0s, 2.0s, ...). Useful for the short window between "daemon is starting" and "daemon is ready".
JsonLineProtocol
The framing helper, exposed so you can build your own transport on top of it.
data = JsonLineProtocol.encode({"hello": "world"}) # → b'{"hello":"world"}\n'
with open("/var/log/myapp.jsonl", "rb") as f:
for obj in JsonLineProtocol.decode_stream(f):
print(obj)
FifoChannel(path, *, mode=0o600)
- Auto-creates the FIFO with
mkfifoif missing. send()opens write-side non-blocking — raisesBrokenPipeErrorif no reader is attached, so you don't deadlock.recv()opens read-side blocking and yields one decoded message.- FIFOs are unidirectional; for request/response use
UnixServer.
pidfile(path)
Context manager that:
- Creates the parent directory.
- Opens the pidfile and acquires an exclusive
flock. - If another process holds the lock, raises
BlockingIOErrorimmediately — perfect for "don't start twice" guards. - Writes the current PID, releases the lock, removes the file on exit (including exceptions).
try:
with pidfile("/run/codechu/myapp/daemon.pid"):
run()
except BlockingIOError:
sys.exit("already running")
Design
- Pure stdlib.
socket,threading,fcntl,os,json— no more. The whole library is five small modules. - Linux-first. AF_UNIX,
mkfifo,flock— all POSIX, but Linux is the platform we run CI on. BSD/macOS work in practice. - No magic. No global registry, no event loop, no decorators. You start the server, you stop the server.
- Crash-safe. Stale socket files are detected on startup; pidfiles are removed on exit; handler exceptions don't kill the server.
Tests
pip install -e ".[dev]"
pytest -q
ruff check src tests
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file codechu_ipc-0.1.0.tar.gz.
File metadata
- Download URL: codechu_ipc-0.1.0.tar.gz
- Upload date:
- Size: 14.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d096574ad8bd4e7aa7f94bb0da730469dce1fceea9d723b798a75aac90f7aafb
|
|
| MD5 |
577d1de97a8dcc1e6f3e6b700dcd82bd
|
|
| BLAKE2b-256 |
52bd91755225e5eb117af87561056a74c6e6d972bdfafbbce7510f7f46602b0a
|
Provenance
The following attestation bundles were made for codechu_ipc-0.1.0.tar.gz:
Publisher:
release.yml on codechu/ipc-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
codechu_ipc-0.1.0.tar.gz -
Subject digest:
d096574ad8bd4e7aa7f94bb0da730469dce1fceea9d723b798a75aac90f7aafb - Sigstore transparency entry: 1582372276
- Sigstore integration time:
-
Permalink:
codechu/ipc-py@a25781445d00ee1b1f5be1b48e6a4e379be5f7fa -
Branch / Tag:
refs/heads/main - Owner: https://github.com/codechu
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a25781445d00ee1b1f5be1b48e6a4e379be5f7fa -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file codechu_ipc-0.1.0-py3-none-any.whl.
File metadata
- Download URL: codechu_ipc-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
51bf24965f44ece25ea3a3498754e6b7baaf5bfb1918f702fcfb1448677894bd
|
|
| MD5 |
3e242499753bc00d3330ff3412f15925
|
|
| BLAKE2b-256 |
7463c079bdf6380fdaff77c355caa6b953249e5cc264a072536cf64fc1215aeb
|
Provenance
The following attestation bundles were made for codechu_ipc-0.1.0-py3-none-any.whl:
Publisher:
release.yml on codechu/ipc-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
codechu_ipc-0.1.0-py3-none-any.whl -
Subject digest:
51bf24965f44ece25ea3a3498754e6b7baaf5bfb1918f702fcfb1448677894bd - Sigstore transparency entry: 1582372383
- Sigstore integration time:
-
Permalink:
codechu/ipc-py@a25781445d00ee1b1f5be1b48e6a4e379be5f7fa -
Branch / Tag:
refs/heads/main - Owner: https://github.com/codechu
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a25781445d00ee1b1f5be1b48e6a4e379be5f7fa -
Trigger Event:
workflow_dispatch
-
Statement type: