bare-rpc-python
RPC over any byte transport for Python. The Python counterpart of bare-rpc, and wire compatible with it. Built on compact-encoding-python.
pip install bare-rpc
hrpc-python generates typed clients and servers on top of it. Use it directly for the raw transport.
Wire codec
Encode and decode frames without the runtime:
import bare_rpc as rpc
frame = rpc.encode_request(1, 42, data=b"hi") # -> bytes
msg = rpc.decode_frame(frame) # -> RequestMessage(id=1, command=42, ...)
RPC runtime
RPC runs a session over a Transport: Any object with an async read(), returning b"" once it has ended, an async write(data), and close(). A Sidecar from bare-sidecar-python is one:
import asyncio
from bare_rpc import RPC
from bare_sidecar import spawn
async def main():
sidecar = await spawn("app.js")
async with RPC(sidecar) as rpc:
print(await rpc.request(1, b"ping"))
await rpc.event(2, b"note")
asyncio.run(main())
Where app.js serves the requests with bare-rpc:
const RPC = require("bare-rpc");
new RPC(Bare.IPC, (req) => req.reply("pong"));
For a socket or any other asyncio stream, wrap its reader and writer in a StreamTransport:
import asyncio
from bare_rpc import RPC, StreamTransport
async def main():
reader, writer = await asyncio.open_connection("localhost", 8080)
async with RPC(StreamTransport(reader, writer)) as rpc:
print(await rpc.request(1, b"ping"))
The session closes once the transport ends, and closing it closes the transport. Pass on_request and on_event to answer requests and receive events from the peer:
async def on_request(req):
await req.reply(b"pong")
rpc = RPC(transport, on_request=on_request)
Command routing
CommandRouter sends each request and event to the handler registered for its command. Pass its dispatch_request and dispatch_event to RPC:
router = rpc.CommandRouter()
async def ping(req):
return b"pong"
router.on_request(5, ping)
router.on_event(3, lambda event: print(event.data))
server = rpc.RPC(
transport,
on_request=router.dispatch_request,
on_event=router.dispatch_event,
)
Streams and backpressure
All three streaming shapes are implemented, with backpressure.
Incoming streams are read with async for, or a chunk at a time with await stream.read(), which returns None once the peer has ended the stream.
Response stream (server streams back, client reads):
async def on_request(req):
out = await req.create_response_stream()
await out.write(b"chunk-1")
await out.write(b"chunk-2")
await out.end()
incoming = await client.request_with_response_stream(command=5, data=b"go")
async for chunk in incoming:
...
Request stream (client streams up, server reads, then replies):
async def on_request(req):
async for chunk in req.request_stream:
...
await req.reply(b"done")
out, reply = await client.stream_request(command=6)
await out.write(b"chunk-1")
await out.end()
result = await reply # -> b"done"
Duplex (both directions):
out, incoming = await client.create_bidirectional_stream(command=7)
await out.write(b"ping")
await out.end()
async for chunk in incoming:
...
License
Apache-2.0
Metadata
Release files for bare-rpc 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 |
|---|---|---|---|---|
| bare_rpc-0.1.1.tar.gz | 24.8 kB | With provenance | Details for bare_rpc-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| bare_rpc-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for bare_rpc-0.1.1-py3-none-any.whl |
Total release size: 42.7 kB
Release files / bare_rpc-0.1.1.tar.gz
| Download URL | bare_rpc-0.1.1.tar.gz |
|---|---|
| Size | 24.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5810b719eb84dc46802f965caafc76b6da8c5646ec712d9d775c8aa47a5389bd
|
|
BLAKE2b-256 checksum How to use checksums |
430409807425839b88985176353ec8bd680b17e57c0fcd5b7603951c7a37bf5e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.
Transparency logRelease files / bare_rpc-0.1.1-py3-none-any.whl
| Download URL | bare_rpc-0.1.1-py3-none-any.whl |
|---|---|
| Size | 17.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
425658ed5a69d0b3fbf4dbe587000ac9cc2652321c59c293bf9654e15cabc270
|
|
BLAKE2b-256 checksum How to use checksums |
4607a9aa6b3febd773237dfedd45c25e0766ed436a8ef95518759826f55dd1c2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.
Transparency logSecurity for bare-rpc 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.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for bare_rpc-0.1.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.
Transparency logA 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.