Python bindings for SLIM (Secure Low-Latency Interactive Messaging) using UniFFI.
This provides a Python interface to the SLIM data plane, enabling secure, low-latency messaging with support for point-to-point and group (multicast) communication patterns.
These Python bindings are generated from the agntcy-slim-bindings crate
using UniFFI, providing a native
Python interface that wraps the high-performance Rust implementation.
- Point-to-Point Messaging: Direct communication between two endpoints
- Group Messaging: Multicast communication with multiple participants
- Secure by Default: Support for TLS, mTLS, and various authentication methods
- MLS Encryption: End-to-end encryption for sessions
- Delivery Confirmation: Optional completion handles for reliable messaging
- Flexible Authentication: Shared secrets, JWT, SPIRE integration
- slimrpc Support: Protocol Buffers RPC over SLIM - see SLIMRPC.md for details
The Python bindings are built using Maturin, which automatically generates Python bindings from the Rust UniFFI adapter:
data-plane/bindings/
├── rust/ # Rust UniFFI bindings (shared by Go, Python, etc.)
│ ├── src/
│ │ ├── app.rs
│ │ ├── build_info.rs
│ │ ├── client_config.rs
│ │ ├── common_config.rs
│ │ ├── completion_handle.rs
│ │ ├── config.rs
│ │ ├── errors.rs
│ │ ├── identity.rs
│ │ ├── identity_config.rs
│ │ ├── init_config.rs
│ │ ├── lib.rs
│ │ ├── message_context.rs
│ │ ├── name.rs
│ │ ├── server_config.rs
│ │ ├── service.rs
│ │ └── session.rs
│ └── Cargo.toml
├── go/ # Go-specific bindings and examples
└── python/ # Python-specific bindings and examples (this directory)
├── examples/ # Example applications
├── tests/ # Unit and integration tests
└── Taskfile.yaml # Build and development tasks
- Rust toolchain (1.70+)
- Python (3.10+)
- uv (Python package manager): https://docs.astral.sh/uv/
- Task (optional, for convenient build commands)
cd data-plane/bindings/python
task python:bindings:buildThis will:
- Install all dependencies
- Compile the Rust UniFFI adapter
- Generate Python bindings using Maturin
- Install the package in development mode
To create distributable wheel packages for Python 3.10, 3.11, 3.12, 3.13 and 3.14:
task python:bindings:packagingOr directly with Maturin:
uv run maturin build --release -i 3.10 3.11 3.12 3.13Maturin automatically:
- Compiles the Rust UniFFI adapter library
- Generates Python bindings from UniFFI scaffolding
- Bundles the native library into platform-specific wheels
- Creates wheels for each specified Python version
The resulting wheels are self-contained and ready for distribution.
You can customize the build with the following variables:
# Build for a specific target architecture
task python:bindings:packaging TARGET=aarch64-apple-darwin
# Build in debug mode (default is release)
task python:bindings:packaging PROFILE=debug
# Cross-compile for Linux on macOS
task python:bindings:packaging TARGET=x86_64-unknown-linux-gnuAfter running the packaging task, you'll find:
dist/
├── slim_uniffi_bindings-0.7.0-cp310-*.whl # Python 3.10 wheel
├── slim_uniffi_bindings-0.7.0-cp311-*.whl # Python 3.11 wheel
├── slim_uniffi_bindings-0.7.0-cp312-*.whl # Python 3.12 wheel
└── slim_uniffi_bindings-0.7.0-cp313-*.whl # Python 3.13 wheel
Note: The native library is automatically bundled inside each wheel.
Users can install the wheel package directly:
pip install slim_uniffi_bindings-0.7.0-cp310-*.whlThe native library is automatically included in the wheel and will be loaded at runtime.
Examples are a separate project in the examples/ directory.
See examples/README.md for detailed instructions.
cd examples
# View available examples
task
# Run simple example
task simple
# Run point-to-point examples
task p2p:alice # Terminal 1
task p2p:bob # Terminal 2import slim_uniffi_bindings as slim
# Initialize crypto provider
slim.initialize_crypto_provider()
# Get version
print(f"SLIM Version: {slim.get_version()}")
# Create an app with shared secret authentication
app_name = {
'components': ['org', 'example', 'app'],
'id': None
}
app = slim.create_app_with_secret(app_name, "my-secret")
print(f"App ID: {app.id()}")
print(f"App Name: {'/'.join(app.name().components)}")Run the simple example:
cd examples
task simpleTerminal 1 - Receiver (Alice):
cd examples
task p2p:aliceTerminal 2 - Sender (Bob):
cd examples
task p2p:bobTerminal 1 - Participant (Alice):
cd examples
task group:participant:aliceTerminal 2 - Participant (Bob):
cd examples
task group:participant:bobTerminal 3 - Moderator:
cd examples
task group:moderatorFor more details, see examples/README.md.
# Create app with shared secret
app = slim.create_app_with_secret(app_name, shared_secret)
# Get app information
app_id = app.id()
app_name = app.name()# Connect to server
client_config = {
'endpoint': 'http://localhost:46357',
'tls': {'insecure': True, ...}
}
conn_id = app.connect(client_config)
# Run server
server_config = {
'endpoint': '127.0.0.1:46357',
'tls': {'insecure': True, ...}
}
app.run_server(server_config)
# Disconnect
app.disconnect(conn_id)# Create session
session_config = {
'session_type': 'PointToPoint', # or 'Group'
'enable_mls': False,
'max_retries': 3,
'interval_ms': 100,
'initiator': True,
'metadata': {}
}
session = app.create_session(session_config, destination_name)
# Listen for incoming session
session = app.listen_for_session(timeout_ms=30000)
# Delete session
app.delete_session(session)# Send message (fire-and-forget)
session.publish(data, "text/plain", metadata)
# Send with delivery confirmation
completion = session.publish_with_completion(data, "text/plain", metadata)
completion.wait() # Block until delivered
# Receive message
msg = session.get_message(timeout_ms=5000)
print(f"Payload: {msg.payload}")
print(f"From: {msg.context.source_name}")
print(f"Type: {msg.context.payload_type}")
# Reply to message
session.publish_to(msg.context, reply_data, "text/plain", None)# Invite participant to group
session.invite(participant_name)
# Remove participant
session.remove(participant_name)examples/
├── common/
│ └── common.py # Shared utilities
├── simple/
│ └── main.py # Basic functionality demo
├── point_to_point/
│ └── main.py # P2P messaging
└── group/
└── main.py # Group/multicast messaging
All examples require a running SLIM server. Start the Go server:
cd data-plane/bindings/go
task example:serverThen run Python examples:
# Simple example
task example
# Point-to-point
task example:p2p:alice # Terminal 1
task example:p2p:bob # Terminal 2
# Group messaging
task example:group:participant:alice # Terminal 1
task example:group:participant:bob # Terminal 2
task example:group:moderator # Terminal 3task test
# or
python -m pytest tests/unit_test.py -vIntegration tests require a running SLIM server:
# Terminal 1: Start server
cd ../go && task example:server
# Terminal 2: Run integration tests
SLIM_INTEGRATION_TEST=1 python -m pytest tests/integration_test.py -v -stask # Show help
task build # Build package with Maturin
task test # Run tests
task python:bindings:packaging # Build wheels for multiple Python versions
task clean # Clean build artifactsslim_uniffi_bindings/- Python package (bindings generated by Maturin)examples/- Example applicationstests/- Unit and integration testsTaskfile.yaml- Build automationpyproject.toml- Package configuration (Maturin build system)
Both Python and Go bindings use the same UniFFI adapter, ensuring API consistency:
| Feature | Python | Go |
|---|---|---|
| Binding Generation | uniffi-bindgen | uniffi-bindgen-go |
| API Style | Pythonic (snake_case) | Idiomatic Go (PascalCase) |
| Error Handling | Exceptions | Error returns |
| Async Support | Sync wrapper over async Rust | Sync wrapper over async Rust |
| Examples | ✅ | ✅ |
| Tests | ✅ | ✅ |
Name: Application/service identifier with components and optional IDSessionConfig: Configuration for creating sessionsTlsConfig: TLS settings for secure connectionsServerConfig: Server endpoint and TLS configurationClientConfig: Client endpoint and TLS configurationMessageContext: Message metadata (source, destination, type, metadata)ReceivedMessage: Received message with context and payload
BindingsAdapter: Main app interface for session managementBindingsSessionContext: Session interface for messagingFfiCompletionHandle: Completion handle for delivery confirmation
PointToPoint: Direct one-to-one communicationGroup: One-to-many multicast communication
Make sure you've built the package:
task build
# or
uv run maturin developEnsure the SLIM server is running:
cd ../go && task example:serverIf you encounter build errors, try cleaning and rebuilding:
task clean
uv run maturin developWhen contributing to the Python bindings:
- Maintain API consistency with Go bindings
- Follow Python naming conventions (snake_case)
- Add tests for new functionality
- Update examples if adding features
- Keep documentation up to date
Apache-2.0 - See LICENSE.md for details
- slimrpc Documentation - Protocol Buffers RPC over SLIM
- Go Bindings
- UniFFI Adapter
- SLIM Documentation