pyisolate
Run Python extensions in isolated virtual environments with seamless inter-process communication.
pyisolate enables you to run Python extensions with conflicting dependencies in the same application by automatically creating isolated environments for each extension. Extensions communicate with the host process through a transparent JSON-RPC system, making the isolation invisible to your code while keeping the host environment dependency-free.
Requirements
- Python 3.10+
- The
uvCLI available on yourPATH - PyTorch is optional and only required for tensor-sharing features (
share_torch=True)
Key Benefits
- Dependency Isolation: Run extensions with incompatible dependencies (e.g., numpy 1.x and 2.x) in the same application
- Zero-Copy PyTorch Tensor Sharing: Share PyTorch tensors between processes without serialization overhead
- Multiple Environment Backends: Use
uvby default or a conda/pixi environment for conda-native dependencies - Bubblewrap Sandboxing: Deny-by-default filesystem isolation on Linux with GPU passthrough
- Transparent Communication: Call async methods across process boundaries as if they were local
- Fast: Uses
uvfor blazing-fast virtual environment creation
Installation
pip install pyisolate
For development:
pip install pyisolate[dev]
Quick Start
Basic Usage
Create an extension that runs in an isolated environment:
# extensions/my_extension/__init__.py
from pyisolate import ExtensionBase
class MyExtension(ExtensionBase):
def on_module_loaded(self, module):
self.module = module
async def process_data(self, data):
# This runs in an isolated process with its own dependencies
import numpy as np # This could be numpy 2.x
return np.array(data).mean()
Load and use the extension from your main application:
# main.py
import pyisolate
import asyncio
async def main():
config = pyisolate.ExtensionManagerConfig(
venv_root_path="./venvs"
)
manager = pyisolate.ExtensionManager(pyisolate.ExtensionBase, config)
extension = manager.load_extension(
pyisolate.ExtensionConfig(
name="data_processor",
module_path="./extensions/my_extension",
isolated=True,
dependencies=["numpy>=2.0.0"]
)
)
result = await extension.process_data([1, 2, 3, 4, 5])
print(f"Mean: {result}") # Mean: 3.0
await extension.stop()
asyncio.run(main())
PyTorch Tensor Sharing
Share PyTorch tensors between processes without serialization:
extension = manager.load_extension(
pyisolate.ExtensionConfig(
name="ml_processor",
module_path="./extensions/ml_extension",
share_torch=True, # Enable zero-copy tensor sharing
share_cuda_ipc=True, # CUDA IPC for GPU tensors (Linux)
)
)
# Large tensor is shared via /dev/shm, not serialized
large_tensor = torch.randn(1000, 1000)
mean = await extension.process_tensor(large_tensor)
Shared State with Singletons
Share state across all extensions using ProxiedSingleton:
from pyisolate import ProxiedSingleton
class DatabaseAPI(ProxiedSingleton):
def __init__(self):
self.data = {}
def get(self, key):
return self.data.get(key)
def set(self, key, value):
self.data[key] = value
# In any extension — returns proxy to host's real instance
db = DatabaseAPI()
await db.set("result", result)
Execution Models
pyisolate provides two execution models:
host-coupled(default): Child process shares the host's torch runtime and can use zero-copy tensor transfer via/dev/shmand CUDA IPC.sealed_worker: Fully isolated child with its own interpreter. No hostsys.pathreconstruction, JSON-RPC tensor transport only.
And two environment backends:
uv(default): Fast pip-compatible virtual environments.conda: pixi-backed conda environments for packages that need conda-forge.
# Sealed worker with conda environment
config = pyisolate.ExtensionConfig(
name="weather_processor",
module_path="./extensions/weather",
isolated=True,
execution_model="sealed_worker",
package_manager="conda",
share_torch=False,
conda_channels=["conda-forge"],
conda_dependencies=["eccodes", "cfgrib"],
dependencies=["xarray", "cfgrib"],
)
Implementing an Adapter
Applications integrate via the IsolationAdapter protocol:
from pyisolate.interfaces import IsolationAdapter
class MyAppAdapter(IsolationAdapter):
@property
def identifier(self) -> str:
return "myapp"
def get_path_config(self, module_path: str) -> dict:
return {
"preferred_root": "/path/to/myapp",
"additional_paths": ["/path/to/myapp/extensions"],
}
def register_serializers(self, registry) -> None:
registry.register(
"MyCustomType",
serializer=lambda obj: {"data": obj.data},
deserializer=lambda d: MyCustomType(d["data"]),
)
def provide_rpc_services(self) -> list:
return [MyRegistry, MyProgressReporter]
Architecture
┌─────────────────────┐ RPC ┌─────────────┐
│ Host Process │◄────────────►│ Extension A │
│ │ │ (venv A) │
│ ┌──────────────┐ │ └─────────────┘
│ │ Shared │ │ RPC ┌─────────────┐
│ │ Singletons │ │◄────────────►│ Extension B │
│ └──────────────┘ │ │ (venv B) │
└─────────────────────┘ └─────────────┘
Features
Core
- Automatic virtual environment management
- Bidirectional JSON-RPC over Unix Domain Sockets (no pickle)
- Full async/await support
- Lifecycle hooks:
before_module_loaded(),on_module_loaded(),stop() - Error propagation across process boundaries
Advanced
- Bubblewrap sandbox with deny-by-default filesystem (Linux)
- CUDA wheel resolution for custom GPU package builds
- Zero-copy tensor transfer via CUDA IPC and
/dev/shm - Performance tracing (
PYISOLATE_TRACE_FILE) - Multi-distro sandbox detection (RHEL, Ubuntu, Arch, SELinux)
Environment Variables
| Variable | Description |
|---|---|
PYISOLATE_CHILD |
Set to "1" in isolated child processes |
PYISOLATE_DEBUG_RPC |
"1" for verbose RPC message logging |
PYISOLATE_TRACE_FILE |
Path for structured performance trace output |
PYISOLATE_ENABLE_CUDA_IPC |
"1" to enable CUDA IPC tensor transport |
PYISOLATE_PATH_DEBUG |
"1" for detailed sys.path logging during child init |
Development
# Setup development environment
uv venv && source .venv/bin/activate
uv pip install -e ".[dev,test]"
pre-commit install
# Run tests
pytest
# Run linting
ruff check pyisolate tests
# Run benchmarks
python benchmarks/simple_benchmark.py
Use Cases
pyisolate is designed for:
- Plugin Systems: When plugins may require conflicting dependencies
- ML Pipelines: Different models requiring different library versions
- Microservices in a Box: Multiple services with different dependencies in one app
- Legacy Code Integration: Wrapping legacy code with specific dependency requirements
License
pyisolate is licensed under the MIT License. See LICENSE for details.
Metadata
Release files for pyisolate 0.10.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pyisolate-0.10.2.tar.gz | 160.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyisolate-0.10.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 251.6 kB
Release files / pyisolate-0.10.2.tar.gz
| Download URL | pyisolate-0.10.2.tar.gz |
|---|---|
| Size | 160.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c5803c0350ed773d1bcfed9cfb414b7b04a932c141e4a851d633d98a349f3b48
|
|
BLAKE2b-256 checksum How to use checksums |
5470a749f8aa1e13db2bc39b1d75967fa60fdf103f6432a9662e760b8ffc23b8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Apr 12, 2026.
Transparency logRelease files / pyisolate-0.10.2-py3-none-any.whl
| Download URL | pyisolate-0.10.2-py3-none-any.whl |
|---|---|
| Size | 91.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b8471926f34625dee8acd8d037f3b1475847acd38983951cd27957987cf8514d
|
|
BLAKE2b-256 checksum How to use checksums |
92b1d76bda411b8ca87cc1dfea1da696996352fae8acbc7a8bea9a5eb4b388a9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Apr 12, 2026.
Transparency log