RPyC -- Remote Python Call
RPyC is a transparent, symmetric Python library for remote procedure calls,
clustering, and distributed computing. Object-proxying makes remote objects
behave like local ones.
Use the Read tool to load referenced files identified as relevant for full details.
Install: pip install rpyc
Default ports: Classic 18812, SSL 18821, Registry 18811
Python: CPython 3.8+ (rpyc 6.x Requires-Python >=3.8; no Python 2<->3 crossing)
Dependencies: plumbum is unconditional (rpyc 6.x declares Requires-Dist: plumbum, no
extra, no marker), so pip install rpyc always installs it; pywin32 is optional, needed only
for PipeStream on Windows
Repository: https://github.com/tomerfiliba-org/rpyc
When to Use
- Remote testing -- run tests centrally, operations happen on remote machines
- Administration -- control heterogeneous machines from one place using Python
- Remote hardware -- access
ctypes, /dev files, drivers on remote machines transparently
- Parallel execution -- overcome GIL by distributing work across RPyC processes
- Distributed computation -- platform-agnostic foundation for clustering
- Remote services -- implement secure RPC services without heavyweight frameworks
- Monkey-patching -- replace local modules with remote ones to cross network boundaries
When NOT to Use
- Need a REST/HTTP API (use Flask, FastAPI)
- Need language-agnostic RPC (use gRPC, Thrift)
- Need message queuing (use Celery, RabbitMQ)
- Untrusted clients over the Internet without SSL/SSH wrapping
Which File Do I Need?
Reference files (distilled, code-rich summaries):
| I need to... |
Read |
Classic mode -- rpyc.classic.connect(), conn.modules, conn.teleport(), tutorials 1/2/4 |
classic-and-tutorials.md |
Services -- rpyc.Service, exposed_, ThreadedServer, rpyc.discover(), tutorial 3 |
services-and-servers.md |
Async -- rpyc.async_(), AsyncResult, rpyc.timed(), BgServingThread, tutorial 5 |
async-and-events.md |
Security -- SSLAuthenticator, rpyc.ssl_connect(), restricted(), DeployedServer |
security-and-connections.md |
API -- rpyc.connect(), Connection, Service, Netref, factory functions, classpartial() |
api-reference.md |
| Demos -- echo, chat, filemon, sharing, async_client, boilerplate patterns |
demos-and-patterns.md |
Config -- protocol_config, rpyc_classic.py, rpyc_registry.py, Wireshark debugging |
config-and-cli.md |
Try distilled references (above) first. Use upstream docs below only when more detail is needed.
Original upstream docs (for additional detail beyond the reference files):
| Topic |
Key API / search terms |
Read |
| About RPyC |
related projects, contributors, logo, project history |
docs/about.md |
| Theory of operation |
boxing by-value/by-reference, netref proxying, address space unification, symmetry |
docs/theory.md |
| Classic mode |
rpyc.classic.connect(), conn.modules, conn.execute(), conn.builtins, rpyc_classic.py |
docs/classic.md |
| Services |
rpyc.Service, exposed_ prefix, @rpyc.exposed, @rpyc.service, conn.root, on_connect(), on_disconnect(), ALIASES, VoidService |
docs/services.md |
| Servers & registry |
ThreadedServer, ForkingServer, ClassicService, rpyc_classic.py flags (-m, -p, --register), rpyc_registry.py |
docs/servers.md |
| Async & background |
rpyc.async_(), AsyncResult (.ready, .value, .wait(), .set_expiry(), .add_callback()), rpyc.timed(), BgServingThread |
docs/async.md |
| Security model |
restricted(), allow_public_attrs, _rpyc_getattr, _rpyc_setattr, _rpyc_delattr, capability-based security |
docs/security.md |
| SSL/TLS |
SSLAuthenticator, rpyc.ssl_connect(), keyfile, certfile, certificate/key setup |
docs/secure-connection.md |
| Zero-deploy (SSH) |
DeployedServer, MultiServerDeployment, SshMachine, .classic_connect(), .classic_connect_all(), plumbum |
docs/zerodeploy.md |
| How-to recipes |
redirected_stdio(), rpyc.classic.pm(), stdio redirection, tunneling over bridges, monkey-patching |
docs/howto.md |
| Advanced debugging |
pyenv multi-version testing, Docker testing, Wireshark capture, rpyc_classic.py --host |
docs/advanced-debugging.md |
| Tutorial 1: Classic |
rpyc.classic.connect(), conn.modules, conn.builtins, conn.namespace, conn.teleport(), conn.eval(), conn.execute() |
tutorial/tut1.md |
| Tutorial 2: Netrefs |
netref, isinstance(), exception propagation, import_custom_exceptions, OneShotServer, protocol_config= |
tutorial/tut2.md |
| Tutorial 3: Services |
rpyc.Service, ThreadedServer, OneShotServer, rpyc.discover(), rpyc.list_services(), rpyc.connect_by_service(), classpartial |
tutorial/tut3.md |
| Tutorial 4: Callbacks |
callbacks as first-class objects, passing local functions to remote, symmetric protocol |
tutorial/tut4.md |
| Tutorial 5: Async |
rpyc.async_(), AsyncResult (.error), BgServingThread, conn.poll_all(), conn.serve, event producer/consumer |
tutorial/tut5.md |
| Use cases |
remote testing, administration, hardware access, GIL workaround, distributed computation, clustering |
docs/usecases.md |
| Release process |
hatch build, hatch publish, git tagging, PyPI, semantic versioning, CHANGELOG |
docs/rpyc-release-process.md |
| Per-module API |
STUBS ONLY - each api/*.md is a one-line pointer to the source, not API detail. For signatures use python -c "import rpyc; help(rpyc.core.protocol)" on the installed package. |
api/ |
Quick Reference
Connect (Classic Mode)
import rpyc
conn = rpyc.classic.connect("hostname") # port 18812
conn.modules.os.listdir("/tmp") # remote module access
conn.builtins.open("/etc/hostname").read() # remote builtins
Create a Service
import rpyc
from rpyc.utils.server import ThreadedServer
class MyService(rpyc.Service):
def on_connect(self, conn): pass
def on_disconnect(self, conn): pass
def exposed_add(self, a, b):
return a + b
ThreadedServer(MyService, port=18861).start()
Connect to a Service
conn = rpyc.connect("hostname", 18861)
conn.root.add(3, 4) # => 7
For async, timed calls, BgServingThread examples see async-and-events.md.
For SSL, zero-deploy, service discovery examples see security-and-connections.md and services-and-servers.md.
Common Mistakes
| Mistake |
Fix |
rpyc.async_(conn.root.fn)(args) -- weak-ref lost |
Store wrapper: afn = rpyc.async_(conn.root.fn); afn(args) |
| Expecting async execution order |
No order guarantee for multiple async requests |
allow_all_attrs on public server |
Use allow_exposed_attrs (default) + capability-based access |
No BgServingThread when using callbacks |
Server callbacks won't process unless client serves requests |
Overriding __init__ on Service class |
Use on_connect(self, conn) instead |
| Passing class instance vs class to ThreadedServer |
ThreadedServer(MyService) = per-connection; ThreadedServer(MyService()) = shared |
Exposing objects with sys references |
Attacker can traverse to sys.modules; use restricted() wrapper |
| Cross-Python-version connections (2<->3) |
Not supported; 3.x<->3.y works if shared types/modules used |
| Not closing connections (resource leak) |
Use with rpyc.connect(...) as conn: or try/finally with conn.close() |
Key Concepts
Transparent (remote objects behave local) | Symmetric (both ends serve requests) | Boxing (immutables by value, rest by reference as netrefs) | Capability-based security (pass specific objects, not broad access)
1---2name: coding-python-rpyc3description: Use when building transparent remote procedure calls, distributed computing, or remote object proxying in Python with RPyC. Use when asked about rpyc.connect, rpyc.Service, netref proxies, async_(), BgServingThread, SSLAuthenticator, DeployedServer, or rpyc_classic.py.4---56# RPyC -- Remote Python Call78RPyC is a transparent, symmetric Python library for remote procedure calls,9clustering, and distributed computing. Object-proxying makes remote objects10behave like local ones.1112Use the Read tool to load referenced files identified as relevant for full details.1314**Install:** `pip install rpyc`15**Default ports:** Classic `18812`, SSL `18821`, Registry `18811`16**Python:** CPython 3.8+ (rpyc 6.x `Requires-Python >=3.8`; no Python 2<->3 crossing)17**Dependencies:** `plumbum` is unconditional (rpyc 6.x declares `Requires-Dist: plumbum`, no18extra, no marker), so `pip install rpyc` always installs it; `pywin32` is optional, needed only19for `PipeStream` on Windows20**Repository:** https://github.com/tomerfiliba-org/rpyc2122## When to Use2324- Remote testing -- run tests centrally, operations happen on remote machines25- Administration -- control heterogeneous machines from one place using Python26- Remote hardware -- access `ctypes`, `/dev` files, drivers on remote machines transparently27- Parallel execution -- overcome GIL by distributing work across RPyC processes28- Distributed computation -- platform-agnostic foundation for clustering29- Remote services -- implement secure RPC services without heavyweight frameworks30- Monkey-patching -- replace local modules with remote ones to cross network boundaries3132## When NOT to Use3334- Need a REST/HTTP API (use Flask, FastAPI)35- Need language-agnostic RPC (use gRPC, Thrift)36- Need message queuing (use Celery, RabbitMQ)37- Untrusted clients over the Internet without SSL/SSH wrapping3839---4041## Which File Do I Need?4243**Reference files** (distilled, code-rich summaries):4445| I need to... | Read |46|-------------------------------------------------------------------------------------------------|-------------------------------|47| Classic mode -- `rpyc.classic.connect()`, `conn.modules`, `conn.teleport()`, tutorials 1/2/4 | `classic-and-tutorials.md` |48| Services -- `rpyc.Service`, `exposed_`, `ThreadedServer`, `rpyc.discover()`, tutorial 3 | `services-and-servers.md` |49| Async -- `rpyc.async_()`, `AsyncResult`, `rpyc.timed()`, `BgServingThread`, tutorial 5 | `async-and-events.md` |50| Security -- `SSLAuthenticator`, `rpyc.ssl_connect()`, `restricted()`, `DeployedServer` | `security-and-connections.md` |51| API -- `rpyc.connect()`, `Connection`, `Service`, `Netref`, factory functions, `classpartial()` | `api-reference.md` |52| Demos -- echo, chat, filemon, sharing, async_client, boilerplate patterns | `demos-and-patterns.md` |53| Config -- `protocol_config`, `rpyc_classic.py`, `rpyc_registry.py`, Wireshark debugging | `config-and-cli.md` |5455Try distilled references (above) first. Use upstream docs below only when more detail is needed.5657**Original upstream docs** (for additional detail beyond the reference files):5859| Topic | Key API / search terms | Read |60|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------|61| About RPyC | related projects, contributors, logo, project history | `docs/about.md` |62| Theory of operation | boxing by-value/by-reference, netref proxying, address space unification, symmetry | `docs/theory.md` |63| Classic mode | `rpyc.classic.connect()`, `conn.modules`, `conn.execute()`, `conn.builtins`, `rpyc_classic.py` | `docs/classic.md` |64| Services | `rpyc.Service`, `exposed_` prefix, `@rpyc.exposed`, `@rpyc.service`, `conn.root`, `on_connect()`, `on_disconnect()`, `ALIASES`, `VoidService` | `docs/services.md` |65| Servers & registry | `ThreadedServer`, `ForkingServer`, `ClassicService`, `rpyc_classic.py` flags (`-m`, `-p`, `--register`), `rpyc_registry.py` | `docs/servers.md` |66| Async & background | `rpyc.async_()`, `AsyncResult` (`.ready`, `.value`, `.wait()`, `.set_expiry()`, `.add_callback()`), `rpyc.timed()`, `BgServingThread` | `docs/async.md` |67| Security model | `restricted()`, `allow_public_attrs`, `_rpyc_getattr`, `_rpyc_setattr`, `_rpyc_delattr`, capability-based security | `docs/security.md` |68| SSL/TLS | `SSLAuthenticator`, `rpyc.ssl_connect()`, `keyfile`, `certfile`, certificate/key setup | `docs/secure-connection.md` |69| Zero-deploy (SSH) | `DeployedServer`, `MultiServerDeployment`, `SshMachine`, `.classic_connect()`, `.classic_connect_all()`, plumbum | `docs/zerodeploy.md` |70| How-to recipes | `redirected_stdio()`, `rpyc.classic.pm()`, stdio redirection, tunneling over bridges, monkey-patching | `docs/howto.md` |71| Advanced debugging | pyenv multi-version testing, Docker testing, Wireshark capture, `rpyc_classic.py --host` | `docs/advanced-debugging.md` |72| Tutorial 1: Classic | `rpyc.classic.connect()`, `conn.modules`, `conn.builtins`, `conn.namespace`, `conn.teleport()`, `conn.eval()`, `conn.execute()` | `tutorial/tut1.md` |73| Tutorial 2: Netrefs | netref, `isinstance()`, exception propagation, `import_custom_exceptions`, `OneShotServer`, `protocol_config=` | `tutorial/tut2.md` |74| Tutorial 3: Services | `rpyc.Service`, `ThreadedServer`, `OneShotServer`, `rpyc.discover()`, `rpyc.list_services()`, `rpyc.connect_by_service()`, `classpartial` | `tutorial/tut3.md` |75| Tutorial 4: Callbacks | callbacks as first-class objects, passing local functions to remote, symmetric protocol | `tutorial/tut4.md` |76| Tutorial 5: Async | `rpyc.async_()`, `AsyncResult` (`.error`), `BgServingThread`, `conn.poll_all()`, `conn.serve`, event producer/consumer | `tutorial/tut5.md` |77| Use cases | remote testing, administration, hardware access, GIL workaround, distributed computation, clustering | `docs/usecases.md` |78| Release process | `hatch build`, `hatch publish`, git tagging, PyPI, semantic versioning, CHANGELOG | `docs/rpyc-release-process.md` |79| Per-module API | STUBS ONLY - each `api/*.md` is a one-line pointer to the source, not API detail. For signatures use `python -c "import rpyc; help(rpyc.core.protocol)"` on the installed package. | `api/` |8081---8283## Quick Reference8485### Connect (Classic Mode)8687```python88import rpyc89conn = rpyc.classic.connect("hostname") # port 1881290conn.modules.os.listdir("/tmp") # remote module access91conn.builtins.open("/etc/hostname").read() # remote builtins92```9394### Create a Service9596```python97import rpyc98from rpyc.utils.server import ThreadedServer99100class MyService(rpyc.Service):101 def on_connect(self, conn): pass102 def on_disconnect(self, conn): pass103 def exposed_add(self, a, b):104 return a + b105106ThreadedServer(MyService, port=18861).start()107```108109### Connect to a Service110111```python112conn = rpyc.connect("hostname", 18861)113conn.root.add(3, 4) # => 7114```115116For async, timed calls, BgServingThread examples see `async-and-events.md`.117For SSL, zero-deploy, service discovery examples see `security-and-connections.md` and `services-and-servers.md`.118119---120121## Common Mistakes122123| Mistake | Fix |124|----------------------------------------------------|--------------------------------------------------------------------------------------|125| `rpyc.async_(conn.root.fn)(args)` -- weak-ref lost | Store wrapper: `afn = rpyc.async_(conn.root.fn); afn(args)` |126| Expecting async execution order | No order guarantee for multiple async requests |127| `allow_all_attrs` on public server | Use `allow_exposed_attrs` (default) + capability-based access |128| No `BgServingThread` when using callbacks | Server callbacks won't process unless client serves requests |129| Overriding `__init__` on Service class | Use `on_connect(self, conn)` instead |130| Passing class instance vs class to ThreadedServer | `ThreadedServer(MyService)` = per-connection; `ThreadedServer(MyService())` = shared |131| Exposing objects with `sys` references | Attacker can traverse to `sys.modules`; use `restricted()` wrapper |132| Cross-Python-version connections (2<->3) | Not supported; 3.x<->3.y works if shared types/modules used |133| Not closing connections (resource leak) | Use `with rpyc.connect(...) as conn:` or try/finally with `conn.close()` |134135---136137## Key Concepts138139**Transparent** (remote objects behave local) | **Symmetric** (both ends serve requests) | **Boxing** (immutables by value, rest by reference as netrefs) | **Capability-based security** (pass specific objects, not broad access)