Execute Python code from different virtual environments as regular functions. Supports multiple Python versions, async/await, generators, and more.
Project description
MultiEnvEmployer
Execute Python code from different virtual environments as regular functions.
Run functions from isolated environments with different Python versions and conflicting dependencies without import conflicts or version issues.
Features
- ✅ Isolated Execution - Run code in separate virtual environments
- ✅ Transparent API - Call remote functions as if they were local
- ✅ Multiple Python Versions - Support for Python 3.5+ modules
- ✅ Stateful & Stateless - Choose between persistent or one-shot execution
- ✅ Print Interception - Capture stdout from remote processes
- ✅ Generators - Full support for generator functions
- ✅ Async Functions - Automatic handling of async/await
- ✅ Result Caching - Optional caching for expensive operations
- ✅ Large Data Streaming - Automatic chunking for big results
- ✅ Timeout Control - Flexible timeout modes (none, absolute, progress)
- ✅ Error Handling - Remote exceptions as local exceptions
- ✅ Process Management - Fine-grained control over worker processes
Installation
pip install multi-env-employer
Quick Start
from pathlib import Path
from MultiEnvEmployer import Employer, RemoteModule
# Initialize employer with target environment
emp = Employer(
project_dir=Path("path/to/modules"),
venv_path=Path("path/to/venv")
)
# Connect to remote module
module = RemoteModule(emp, "my_module")
# Call functions as if they were local
result = module.add(2, 3)
print(result) # 5
# Use context manager for automatic cleanup
with Employer("path/to/modules", "path/to/venv") as emp:
module = RemoteModule(emp, "my_module")
result = module.process_data([1, 2, 3])
Basic Usage
Stateless Execution (default)
New process per function call:
module = RemoteModule(emp, "my_module", stateful=False)
module.func1() # Process A
module.func2() # Process B
Stateful Execution
Single process for all calls:
module = RemoteModule(emp, "my_module", stateful=True)
module.set_value(10) # Process A
module.get_value() # Process A (same process)
Print Interception
module = RemoteModule(emp, "my_module", print_output="terminal")
module.my_function() # Prints are captured and displayed
Generators
for value in module.stream_numbers(5):
print(value) # 0, 1, 2, 3, 4
Async Functions
result = module.async_operation(10) # Called synchronously
Result Caching
module = RemoteModule(emp, "my_module", caching=True)
result1 = module.expensive_function(x=10) # Executes
result2 = module.expensive_function(x=10) # From cache
Timeout Control
from MultiEnvEmployer import TimeoutPolicy
# No timeout
module = RemoteModule(emp, "my_module",
timeout=TimeoutPolicy(seconds=60, mode="none"))
# Absolute timeout (hard limit)
module = RemoteModule(emp, "my_module",
timeout=TimeoutPolicy(seconds=30, mode="absolute"))
# Progress timeout (resets on activity)
module = RemoteModule(emp, "my_module",
timeout=TimeoutPolicy(seconds=10, mode="progress"))
Error Handling
from MultiEnvEmployer import errors
try:
result = module.failing_function()
except errors.RemoteExecutionError as e:
print(f"Remote error: {e.error_type}")
print(f"Message: {e.error_message}")
print(f"Traceback:\n{e.remote_traceback}")
except errors.RemoteTimeoutError as e:
print(f"Timeout after {e.timeout_seconds}s")
except errors.WrongArgumentsError as e:
print(f"Invalid arguments: {e.details}")
Advanced Features
Large Data Streaming
Large return values are automatically streamed in chunks:
result = module.get_large_list() # Automatically chunked if > 1 MB
Process Management
# Close specific module
emp.close(module)
# Close specific function (stateless)
emp.close("module_name.function_name")
# Close all processes
emp.close()
Custom Configuration
emp = Employer(
project_dir=Path("modules"),
venv_path=Path("venv"),
cache_path=Path("cache"),
pickle_protocol=4,
stream_threshold=1024 * 1024, # 1 MB
chunk_size=512 * 1024 # 512 KB
)
Requirements
- Python 3.8+ (for the library itself)
- Python 3.5+ (for remote modules)
- Virtual environment with target Python version
Security Warning
⚠️ CRITICAL: This library uses pickle for inter-process communication. Never use with untrusted data sources.
- Pickle can execute arbitrary code during deserialization
- Only use MultiEnvEmployer with code and data you control
- Not suitable for processing user-supplied data or external inputs
Use Cases
- Legacy Code Integration - Run old Python 2.7 code from Python 3.x
- Dependency Isolation - Use conflicting library versions in one project
- Version Testing - Test code across multiple Python versions
- Resource Isolation - Isolate memory-intensive operations
- Sandboxing - Run untrusted code in separate processes
Documentation
Full documentation: GitHub Repository
License
MIT License - see LICENSE
Contact
- GitHub Issues: https://github.com/REYIL/MultiEnvEmployer/issues
- Telegram: @REYIL_DEV
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 multi_env_employer-1.1.0.tar.gz.
File metadata
- Download URL: multi_env_employer-1.1.0.tar.gz
- Upload date:
- Size: 17.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c60f4f3fc2a4b3f7d96b0190ddaf9627aa130bb802a92811c797452057c61fca
|
|
| MD5 |
154c08af6db99628d69c7f2e0dc23e94
|
|
| BLAKE2b-256 |
bc428fb429af0625564556422cfff68a3c91f2365bfd96711fac62dc6e2ebc7b
|
File details
Details for the file multi_env_employer-1.1.0-py3-none-any.whl.
File metadata
- Download URL: multi_env_employer-1.1.0-py3-none-any.whl
- Upload date:
- Size: 21.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b738f862085fae23e997487d3ea63f4f89bc4c9399e7a4cc46eea0555594b42a
|
|
| MD5 |
aefe0634ef5400a75f0374a3256299de
|
|
| BLAKE2b-256 |
bdb89d4d149696abaade4aeecfb21266692cd95b155a628a5729d87f8f37b38e
|