Call Python functions across processes as easily as local function calls - Simple RPC and IPC for Python
Project description
remotefunc
Call Python functions across different processes as easily as local functions.
An ultra-simple, zero-configuration RPC (Remote Procedure Call) library that makes inter-process communication (IPC) in Python feel like magic. No complex setup, no message queues, no serialization headaches - just pure Python functions that work across process boundaries.
Quick Start
Server Process (daemon.py)
from remotefunc import shared
import time
# Your shared data
items = []
# Make any function callable from other processes
@shared
def push_new_item(item: dict) -> int:
items.append(item)
return len(items)
@shared
def get_items() -> list:
return items
# more code that keeps this process running
Client Process (controller.py)
from daemon import push_new_item, get_items
# Call remote functions exactly like local functions!
new_id = push_new_item({'x': 10, 'y': 20})
print(f'New item pushed, id: {new_id}') # Output: New item pushed, id: 1
all_items = get_items()
print(f'All items: {all_items}') # Output: All items: [{'x': 10, 'y': 20}]
That's it! No server setup, no configuration files, no complicated API calls.
Installation
pip install remotefunc
Or install from source:
git clone https://github.com/mortasen/remotefunc.git
cd remotefunc
pip install -e .
What is this library perfect for?
- ๐ Sharing data between Python processes without files or databases
- ๐ฎ Building daemon/controller architectures with minimal boilerplate
- ๐ Distributed Python applications that need simple process communication
- ๐ ๏ธ Microservices in Python without the complexity of gRPC or REST frameworks
- ๐ก Inter-process communication (IPC) made simple and Pythonic
- ๐ Remote procedure calls (RPC) without learning new protocols
Why remotefunc?
The Problem: You have two Python processes that need to share data or call each other's functions. Traditional solutions are complicated:
- Files? Slow and error-prone
- Databases? Overkill for simple communication
- Sockets? Too low-level
- Message queues (RabbitMQ, Redis)? Too heavy
- multiprocessing.Queue? Only works with parent/child processes
- REST APIs? Too much boilerplate
The Solution: With remotefunc, just add one decorator and import functions normally. That's it.
Features
โจ Zero Configuration - Server starts automatically, no setup required
๐ฏ Transparent RPC - Remote calls look identical to local calls
๐ Type Safe - Full support for type hints and IDE autocomplete
โก Fast - HTTP-based with smart JSON/pickle serialization
๐ Great Debugging - Remote exceptions include full tracebacks
๐ชถ Lightweight - No external dependencies, pure Python
๐ Stateful - Share data structures across processes easily
๐ฆ Works Everywhere - Any Python 3.7+ on Windows, macOS, Linux
Use Cases
1. Daemon + Controller Pattern
Perfect for background services controlled by CLI tools:
# daemon.py - runs continuously
@shared
def start_task(name): ...
@shared
def get_status(): ...
# cli.py - user commands
from daemon import start_task, get_status
start_task("backup")
print(get_status())
2. Multi-Process Data Sharing
Share state between independent Python processes:
# data_server.py
cache = {}
@shared
def set(key, value):
cache[key] = value
@shared
def get(key):
return cache.get(key)
# Any other process can now access the shared cache
from data_server import set, get
set("user_123", {"name": "Alice"})
3. Distributed Task Processing
Coordinate work across multiple Python processes:
# coordinator.py
jobs = []
@shared
def submit_job(task):
jobs.append(task)
return len(jobs)
# worker.py
from coordinator import submit_job
submit_job({"type": "process_video", "file": "video.mp4"})
4. Real-time Monitoring
Monitor long-running processes from separate scripts:
# long_process.py
progress = 0
@shared
def get_progress():
return progress
# monitor.py
from long_process import get_progress
while True:
print(f"Progress: {get_progress()}%")
time.sleep(1)
How It Works
- Decorator Registration:
@sharedregisters your function and starts an HTTP server (first time only) - Smart Detection: When imported from another process, creates a remote proxy
- HTTP Communication: Client makes POST request โ Server executes function โ Returns result
- Transparent Errors: Exceptions are serialized and re-raised on the client side
โโโโโโโโโโโโโโโโโโโ HTTP POST โโโโโโโโโโโโโโโโโโโ
โ Client Process โ โโโโโโโโโโโโโโโโโโโโโโโโ> โ Server Process โ
โ โ โ โ
โ from daemon โ {"function": "push", โ @shared โ
โ import func โ "args": [item]} โ def push(): โ
โ โ โ items.add โ
โ func(item) โ <โโโโโโโโโโโโโโโโโโโโโโโโ โ return len โ
โ โ {"result": 1} โ โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
API Reference
@shared
Make any function callable from other processes.
from remotefunc import shared
@shared
def my_function(x: int, y: int) -> int:
"""Full type hints and docstrings work perfectly"""
return x + y
configure(host=None, port=None)
Configure global settings for remote calls.
from remotefunc import configure
# Call this in the client process before importing shared functions
configure(host='192.168.1.10', port=8080)
get_server_port()
Get the current server port (default: 5555).
from remotefunc import get_server_port
print(f"Server running on port {get_server_port()}")
shutdown_server()
Gracefully shutdown the server.
from remotefunc import shutdown_server
shutdown_server()
Advanced Usage
Custom Port
from remotefunc.server import start_server
start_server(port=8080) # Start before decorating functions
@shared
def my_function():
pass
Error Handling
Remote exceptions are propagated with full context:
from daemon import risky_function
from remotefunc.client import RemoteCallError
try:
result = risky_function()
except RemoteCallError as e:
print(f"Remote call failed: {e}")
# Full traceback from the server process is included!
Complex Data Types
Works with JSON-serializable data and falls back to pickle:
@shared
def process_data(data: dict, callback: callable = None):
# Dicts, lists, primitives โ JSON (fast)
# Complex objects โ pickle (automatic)
return result
Comparison with Alternatives
| Solution | Setup Complexity | Use Case | remotefunc Equivalent |
|---|---|---|---|
| Files/JSON | Low | Slow data sharing | โ Just use @shared |
| Sockets | High | Custom protocols | โ Just use @shared |
| multiprocessing.Queue | Medium | Parent-child only | โ Works with any processes |
| Redis/RabbitMQ | Very High | Production scale | โ Use those for production |
| REST API (Flask) | High | HTTP services | โ But with zero boilerplate |
| gRPC | Very High | Performance critical | โ Use gRPC for that |
| XML-RPC | Medium | Legacy systems | โ Modern Python approach |
FAQ
Q: How do two processes discover each other?
A: The server automatically starts on localhost:5555. Client imports create proxies that connect to this address.
Q: What if the server process isn't running?
A: You'll get a clear RemoteCallError indicating connection failure.
Q: Can I use this in production?
A: It's great for internal tools, daemons, and development. For production microservices, consider gRPC or proper REST APIs with authentication.
Q: Does it work with threading/asyncio?
A: Yes! The server is multi-threaded and can handle concurrent requests. Async functions need to be wrapped with asyncio.run().
Security Warning โ ๏ธ
remotefunc uses pickle as a fallback serialization mechanism for complex Python objects.
NEVER use this library across untrusted networks or to communicate with untrusted clients.
An attacker who can send data to the remotefunc server (default port 5555) can execute arbitrary code on your machine. This library is designed for localhost communication or within a strictly secured, trusted private network.
Examples
See the examples/ directory:
daemon.py- Full-featured server with multiple shared functionscontroller.py- Client demonstrating all remote call patterns
Contributing
Contributions welcome! Please open an issue or PR on GitHub.
License
MIT License - see LICENSE.md file for details.
Keywords for Search
python ipc python rpc inter process communication python share data between python processes python process communication python remote function call python daemon controller python distributed call function in another process python python multiprocessing communication python process synchronization
Made with โค๏ธ for developers who want IPC/RPC to "just work"
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 remotefunc-0.1.0.tar.gz.
File metadata
- Download URL: remotefunc-0.1.0.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
678663489f9bd24c3e0c934fa8a2712e3b13e12f09dbb59c724386ef5d376e7e
|
|
| MD5 |
9ab27690bdb4e4c9b117de706971ab14
|
|
| BLAKE2b-256 |
dda05788e11e725494494099730ecd6841ae19b7851020542109e577e9847950
|
File details
Details for the file remotefunc-0.1.0-py3-none-any.whl.
File metadata
- Download URL: remotefunc-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9773c9544cda54b21fac9ccb27131420aaff8daa80525d4f05f9859b67cc594c
|
|
| MD5 |
54ca96a9ae533044118c59d07b34ef30
|
|
| BLAKE2b-256 |
6d8dacb0acb1e0d10c7c5247e4ac4d4b79452a08cc9e3c2e8febde4734b7a147
|