Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

SLIM Python Bindings (UniFFI)

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.

Overview

These Python bindings are generated from the agntcy-slim-bindings-ffi crate using UniFFI, providing a native Python interface that wraps the high-performance Rust implementation.

Key Features

  • 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 for app identity; Basic, JWT, SPIRE, and OIDC for the gRPC transport
  • slimrpc Support: Protocol Buffers RPC over SLIM - see SLIMRPC.md for details

Architecture

The Python bindings are built using Maturin, which automatically generates Python bindings from the Rust UniFFI adapter:

slim-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

Prerequisites

  • Rust toolchain (1.70+)
  • Python (3.10+)
  • uv (Python package manager): https://docs.astral.sh/uv/
  • Task (optional, for convenient build commands)

Installation

Development Build

cd python
task python:bindings:build

This will:

  1. Install all dependencies
  2. Compile the Rust UniFFI adapter
  3. Generate Python bindings using Maturin
  4. Install the package in development mode

Creating Distribution Packages

Build Wheels for Multiple Python Versions

To create distributable wheel packages for Python 3.10, 3.11, 3.12, 3.13 and 3.14:

task python:bindings:packaging

Or directly with Maturin:

uv run maturin build --release -i 3.10 3.11 3.12 3.13

Maturin automatically:

  1. Compiles the Rust UniFFI adapter library
  2. Generates Python bindings from UniFFI scaffolding
  3. Bundles the native library into platform-specific wheels
  4. Creates wheels for each specified Python version

The resulting wheels are self-contained and ready for distribution.

Custom Build Options

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-gnu

Output Structure

After 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.

Installing from Wheel

Users can install the wheel package directly:

pip install slim_uniffi_bindings-0.7.0-cp310-*.whl

The native library is automatically included in the wheel and will be loaded at runtime.

Examples

Examples are a separate project in the examples/ directory.

See examples/README.md for detailed instructions.

Quick Start with Examples

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 2

Quick Start

Simple Example

import 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 simple

Point-to-Point Communication

Terminal 1 - Receiver (Alice):

cd examples
task p2p:alice

Terminal 2 - Sender (Bob):

cd examples
task p2p:bob

Group Communication

Terminal 1 - Participant (Alice):

cd examples
task group:participant:alice

Terminal 2 - Participant (Bob):

cd examples
task group:participant:bob

Terminal 3 - Moderator:

cd examples
task group:moderator

For more details, see examples/README.md.

Transport Authentication (gRPC connection)

Separate from the app identity set at create_app_* time, the gRPC connection to a SLIM node can carry its own credentials via ClientConfig.auth (and ServerConfig.auth when hosting). Supported modes are BASIC, STATIC_JWT, JWT, SPIRE, and OIDC.

OIDC, client side (client-credentials flow):

import datetime
import slim_bindings

oidc = slim_bindings.OidcConfig(
    issuer_url="https://auth.example.com",
    client_id="my-client",
    client_secret="s3cr3t",
    audience=None,
    refresh_token=None,
    refresh_token_file=None,
    access_token_file=None,
    scope="openid profile",
    timeout=datetime.timedelta(seconds=30),
    jwks_ttl=None,
    claim_cache_ttl=None,
    policy=None,
)

base = slim_bindings.new_insecure_client_config("http://127.0.0.1:46357")
client_config = slim_bindings.ClientConfig(
    **{**vars(base), "auth": slim_bindings.ClientAuthenticationConfig.OIDC(config=oidc)}
)
conn_id = await service.connect_async(client_config)

For the refresh-token flow set refresh_token (or refresh_token_file, which is rewritten in place as tokens rotate) instead of client_secret.

Server side, verifying incoming JWTs against the issuer's JWKS endpoint, optionally restricting access by claim:

oidc = slim_bindings.OidcConfig(
    issuer_url="https://auth.example.com",
    client_id=None,
    client_secret=None,
    audience="slim",                                   # required for verification
    refresh_token=None,
    refresh_token_file=None,
    access_token_file=None,
    scope=None,
    timeout=None,
    jwks_ttl=datetime.timedelta(hours=1),
    claim_cache_ttl=datetime.timedelta(minutes=1),
    policy=slim_bindings.OidcPolicyConfig.CEL(expression='"admin" in claims.groups'),
)

base = slim_bindings.new_insecure_server_config("127.0.0.1:46357")
server_config = slim_bindings.ServerConfig(
    **{**vars(base), "auth": slim_bindings.ServerAuthenticationConfig.OIDC(config=oidc)}
)

policy accepts OidcPolicyConfig.CEL(expression=...), OidcPolicyConfig.REGO(text=...) (which must define package slim.auth with default allow = false), or OidcPolicyConfig.REGO_FILE(path=...). Client-only fields (scope, timeout) and server-only fields (jwks_ttl, claim_cache_ttl, policy) are ignored by the other side.

From a config file — the examples read SLIM_CLIENT_CONFIG (or --slim-config <path>), which covers every auth mode plus TLS material and backoff without any code change:

{
  "endpoint": "http://127.0.0.1:46357",
  "tls": { "insecure": true },
  "auth": {
    "type": "oidc",
    "issuer_url": "https://auth.example.com",
    "client_id": "my-client",
    "client_secret": "s3cr3t",
    "audience": "slim",
    "policy": { "cel": "\"admin\" in claims.groups" }
  }
}

The schema matches data-plane/core/config/src/grpc/schema/client-config.schema.json in the slim repo. To load one yourself, call slim_bindings.new_config_from_json(json_text).

API Overview

Application Creation

# 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()

Server Operations

# 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)

Session Management

# 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)

Messaging

# 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)

Group Operations

# Invite participant to group
session.invite(participant_name)

# Remove participant
session.remove(participant_name)

Examples

Examples Directory Structure

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

Running Examples

All examples require a running SLIM server. Start the Go server:

cd go
task example:server

Then 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 3

Testing

Unit Tests

task test
# or
python -m pytest tests/unit_test.py -v

Integration Tests

Integration 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 -s

Development

Available Tasks

task                           # 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 artifacts

Project Structure

  • slim_uniffi_bindings/ - Python package (bindings generated by Maturin)
  • examples/ - Example applications
  • tests/ - Unit and integration tests
  • Taskfile.yaml - Build automation
  • pyproject.toml - Package configuration (Maturin build system)

Comparison with Go Bindings

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

API Reference

Core Types

  • Name: Application/service identifier with components and optional ID
  • SessionConfig: Configuration for creating sessions
  • TlsConfig: TLS settings for secure connections
  • ServerConfig: Server endpoint and TLS configuration
  • ClientConfig: Client endpoint and TLS configuration
  • MessageContext: Message metadata (source, destination, type, metadata)
  • ReceivedMessage: Received message with context and payload

Main Classes

  • BindingsAdapter: Main app interface for session management
  • BindingsSessionContext: Session interface for messaging
  • FfiCompletionHandle: Completion handle for delivery confirmation

Session Types

  • PointToPoint: Direct one-to-one communication
  • Group: One-to-many multicast communication

Troubleshooting

ImportError: Cannot find slim_uniffi_bindings

Make sure you've built the package:

task build
# or
uv run maturin develop

Connection Refused

Ensure the SLIM server is running:

cd ../go && task example:server

Build Errors

If you encounter build errors, try cleaning and rebuilding:

task clean
uv run maturin develop

Contributing

When contributing to the Python bindings:

  1. Maintain API consistency with Go bindings
  2. Follow Python naming conventions (snake_case)
  3. Add tests for new functionality
  4. Update examples if adding features
  5. Keep documentation up to date

License

Apache-2.0 - See LICENSE.md for details

See Also

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

slim_bindings-2.1.1rc2-py3-none-win_arm64.whl (19.4 MB view details)

Uploaded Python 3Windows ARM64

slim_bindings-2.1.1rc2-py3-none-win_amd64.whl (20.8 MB view details)

Uploaded Python 3Windows x86-64

slim_bindings-2.1.1rc2-py3-none-musllinux_1_2_x86_64.whl (23.3 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

slim_bindings-2.1.1rc2-py3-none-musllinux_1_2_aarch64.whl (22.6 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

slim_bindings-2.1.1rc2-py3-none-manylinux_2_28_x86_64.whl (23.3 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ x86-64

slim_bindings-2.1.1rc2-py3-none-manylinux_2_28_aarch64.whl (22.6 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ ARM64

slim_bindings-2.1.1rc2-py3-none-macosx_11_0_arm64.whl (21.5 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

slim_bindings-2.1.1rc2-py3-none-macosx_10_12_x86_64.whl (22.3 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file slim_bindings-2.1.1rc2-py3-none-win_arm64.whl.

File metadata

File hashes

Hashes for slim_bindings-2.1.1rc2-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 9b7585e7b55337c5c5cfd30cd28912f7c2847c8f66685f359c0985ea77bd8279
MD5 c934abcbe6c7da5c62de946a6f6bd17a
BLAKE2b-256 b4e5fe6fe0be969c99787a4142663475f7e1b4d2736bc469ad0c39462fb41b9d

See more details on using hashes here.

Provenance

The following attestation bundles were made for slim_bindings-2.1.1rc2-py3-none-win_arm64.whl:

Publisher: release-bindings.yaml on agntcy/slim-bindings

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file slim_bindings-2.1.1rc2-py3-none-win_amd64.whl.

File metadata

File hashes

Hashes for slim_bindings-2.1.1rc2-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 9b88dc83aa60333e5d436fe91d68597d5b2cb7510f7e456ed024710206835713
MD5 6f2c9ec04df029e28268a007a9266f91
BLAKE2b-256 71bb33ba29a1b3f8c334f680e1a84842b05ae63936f6b7026cc089d944a63222

See more details on using hashes here.

Provenance

The following attestation bundles were made for slim_bindings-2.1.1rc2-py3-none-win_amd64.whl:

Publisher: release-bindings.yaml on agntcy/slim-bindings

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file slim_bindings-2.1.1rc2-py3-none-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for slim_bindings-2.1.1rc2-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 beeedd4cd8a23e303c8b6f7564b951eeab6737d7fc4c021150fca8e37704fb3d
MD5 fac703901a5d2a62b2399ddd03f76c48
BLAKE2b-256 b5641cd651728ca8ca0dfc65b97a3b160e904d3a9dc537eb593501a3ab16f762

See more details on using hashes here.

Provenance

The following attestation bundles were made for slim_bindings-2.1.1rc2-py3-none-musllinux_1_2_x86_64.whl:

Publisher: release-bindings.yaml on agntcy/slim-bindings

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file slim_bindings-2.1.1rc2-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for slim_bindings-2.1.1rc2-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 cff9de5d534dabe8ab2013344f89afe1ba57c351c36dd0bcb63f01fb7198b9dc
MD5 e74e36e80fd806b62c2869b518729415
BLAKE2b-256 235354ab0d3410a64d62f7f7abd6d88f3221c8d680d21497cb416224cb35bb32

See more details on using hashes here.

Provenance

The following attestation bundles were made for slim_bindings-2.1.1rc2-py3-none-musllinux_1_2_aarch64.whl:

Publisher: release-bindings.yaml on agntcy/slim-bindings

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file slim_bindings-2.1.1rc2-py3-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for slim_bindings-2.1.1rc2-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 62df2e9ab54b596cbe7c1b4f9777d87f7dc47887ff0d55c489a211cfa27f4cbb
MD5 1026936fea247d403512854df0f16f68
BLAKE2b-256 0a1d1a992c4625ed6aa41a5987abefb0d2a39052bcafa819a96a9cec41c9cce8

See more details on using hashes here.

Provenance

The following attestation bundles were made for slim_bindings-2.1.1rc2-py3-none-manylinux_2_28_x86_64.whl:

Publisher: release-bindings.yaml on agntcy/slim-bindings

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file slim_bindings-2.1.1rc2-py3-none-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for slim_bindings-2.1.1rc2-py3-none-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 5a793a5340be8781a87db74beaf57d7c0818c77715132cd7cc55f0a45f8833db
MD5 d30669bb4df4676d3d6dc65cbe390282
BLAKE2b-256 630d7528b4e2087daf5a572bf7a07704948e29a3ef43e73e15d9862a785ae125

See more details on using hashes here.

Provenance

The following attestation bundles were made for slim_bindings-2.1.1rc2-py3-none-manylinux_2_28_aarch64.whl:

Publisher: release-bindings.yaml on agntcy/slim-bindings

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file slim_bindings-2.1.1rc2-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for slim_bindings-2.1.1rc2-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4a0ae7268ca8aabd1c6d690d5719a1e70d7b723968748be87e969487b8b1c1c7
MD5 2d315701ac2821842a64169728b11918
BLAKE2b-256 b9c930c39455312b2fe9f797aa759e614a9404d1032fcbfe48b580af2730deb4

See more details on using hashes here.

Provenance

The following attestation bundles were made for slim_bindings-2.1.1rc2-py3-none-macosx_11_0_arm64.whl:

Publisher: release-bindings.yaml on agntcy/slim-bindings

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file slim_bindings-2.1.1rc2-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for slim_bindings-2.1.1rc2-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 5c5ddff44d7ec8a3d6630a84830600a9573d0bdb5d07b910e9d453e6b9334fcc
MD5 76c6a4f72c6baa9deefe03c3eb1d1e45
BLAKE2b-256 026a1058b0c18eedaae6951eca376a346616490a7858fc089f515b3f31ee62b1

See more details on using hashes here.

Provenance

The following attestation bundles were made for slim_bindings-2.1.1rc2-py3-none-macosx_10_12_x86_64.whl:

Publisher: release-bindings.yaml on agntcy/slim-bindings

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

2.1.1rc2 This release

8 files

2.1.0

8 files

2.0.0

8 files

1.4.1

8 files

1.4.0

8 files

1.3.0

8 files

1.2.0

8 files

1.1.1

8 files

1.1.0

8 files

1.0.1

8 files

1.0.0

8 files

0.7.1

21 files

0.7.0

21 files

0.6.3

26 files

0.6.2

26 files

0.6.1

26 files

0.6.0

26 files

0.5.0

26 files

0.4.1

21 files

0.4.0

26 files

0.3.6

26 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page