python-json-socket (jsocket)
Simple JSON-over-TCP sockets for Python. This library provides:
- JsonClient/JsonServer: length‑prefixed JSON message framing over TCP
- ThreadedServer: a single-connection server running in its own thread
- ServerFactory/ServerFactoryThread: a per‑connection worker model for multiple clients
It aims to be small, predictable, and easy to integrate in tests or small services.
Install
pip install jsocket
Requires Python 3.8+.
Quickstart
Echo server with ThreadedServer and a client:
import time
import jsocket
class Echo(jsocket.ThreadedServer):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.timeout = 2.0 # sets both accept and recv timeouts
# Return a dict to send a response back to the client
def _process_message(self, obj):
if isinstance(obj, dict) and 'echo' in obj:
return obj
return None
# Bind to an ephemeral port (port=0)
server = Echo(address='127.0.0.1', port=0)
_, port = server.socket.getsockname()
server.start()
client = jsocket.JsonClient(address='127.0.0.1', port=port)
assert client.connect() is True
payload = {"echo": "hello"}
client.send_obj(payload)
assert client.read_obj() == payload
client.close()
server.stop()
server.join()
Per‑connection workers with ServerFactory:
import jsocket
class Worker(jsocket.ServerFactoryThread):
def __init__(self):
super().__init__()
self.timeout = 2.0 # sets recv timeout for this worker
def _process_message(self, obj):
if isinstance(obj, dict) and 'message' in obj:
return {"reply": f"got: {obj['message']}"}
server = jsocket.ServerFactory(Worker, address='127.0.0.1', port=5489)
server.start()
# Connect one or more clients; one Worker is spawned per connection
API Highlights
-
JsonClient:
connect()returns True on successsend_obj(dict)sends a JSON objectread_obj()blocks until a full message is received; raisessocket.timeoutorRuntimeError("socket connection broken")timeoutsets both accept and recv timeoutsaccept_timeoutcontrols the server's accept timeoutrecv_timeoutcontrols the connection read timeout
-
ThreadedServer:
- Subclass and implement
_process_message(self, obj) -> Optional[dict] - Return a dict to send a response; return
Noneto send nothing start(),stop(),join()manage the server threadsend_obj(dict)sends to the currently connected client
- Subclass and implement
-
ServerFactory / ServerFactoryThread:
ServerFactoryThreadis a worker that handles one client connectionServerFactoryaccepts connections and spawns a worker per client
Examples and Tests
- Examples: see
examples/example_servers.pyandscripts/smoke_test.py - Pytest: end-to-end and listener tests under
tests/- Run:
pytest -q
- Run:
Behavior-Driven Tests (Behave)
-
Steps live under
features/steps/and environment hooks infeatures/environment.py. -
To run Behave scenarios, add one or more
.featurefiles underfeatures/and run:pip install -r requirements-dev.txtPYTHONPATH=. behave -f progress2
-
A minimal example feature:
Feature: Echo round-trip Scenario: client/server echo Given I start the server And I connect the client When the client sends the object {"echo": "hi"} Then the client sees a message {"echo": "hi"}
Notes
- Breaking change: version 2.0.0 uses a new framing header (magic + length + CRC32). v1 clients are incompatible.
- Message framing uses a 12‑byte header: 4‑byte magic, 4‑byte big‑endian length, and 4‑byte CRC32 of the payload, followed by a JSON payload encoded as UTF‑8.
max_message_sizedefaults to 10MB; set.max_message_sizeto adjust or set toNoneto disable.- On disconnect, reads raise
RuntimeError("socket connection broken")so callers can distinguish cleanly from timeouts. - Binding with
port=0lets the OS choose an ephemeral port; find it withserver.socket.getsockname().
Links
- PyPI: https://pypi.org/project/jsocket/
- License: see
LICENSE
Metadata
Release files for jsocket 2.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jsocket-2.0.3.tar.gz | 38.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jsocket-2.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 55.9 kB
Release files / jsocket-2.0.3.tar.gz
| Download URL | jsocket-2.0.3.tar.gz |
|---|---|
| Size | 38.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fd2fd78958a1d2e0c02d6bc7a27d36fa2a7b6430e1f9acebf85cf1bd818fff89
|
|
BLAKE2b-256 checksum How to use checksums |
55e1210a6e543ca371c2681d36097dc21a014b09b61991b9bc27aec6178d96d3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|
Release files / jsocket-2.0.3-py3-none-any.whl
| Download URL | jsocket-2.0.3-py3-none-any.whl |
|---|---|
| Size | 17.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fc652bc0d686f1ffce7e7e2b99625dc38b28d15f4358520a3a56956c69a03c48
|
|
BLAKE2b-256 checksum How to use checksums |
dfab46d5ca141f114b1c6c44be36ba7ae85bfdbf53d0834d394835424822cecd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|