Skip to main content
The SyftBox transport uses the traditional syft_core.Client to provide full RPC, encryption, and event handling capabilities for federated learning.

SyftCoreClient

Adapter that wraps syft_core.Client for use with Syft-Flwr.

Class Definition

from syft_flwr.client import SyftCoreClient
from syft_core import Client

class SyftCoreClient(SyftFlwrClient):
    """Adapter for syft_core.Client - the traditional SyftBox client.
    
    This adapter wraps syft_core.Client and provides full syft-rpc/syft-crypto/syft-event
    functionality through get_client().
    """
Source: src/syft_flwr/client/syft_core_client.py:9

Constructor

client
syft_core.Client
required
The underlying SyftBox client instance to wrap

Class Methods

load

@classmethod
def load(cls, filepath: Optional[str] = None) -> SyftCoreClient
Load a SyftCoreClient from a config file.
filepath
str
default:"~/.syftbox/config.json"
Path to the SyftBox client configuration file
return
SyftCoreClient
Initialized client instance
Example:
from syft_flwr.client import SyftCoreClient

# Load from default location
client = SyftCoreClient.load()

# Load from custom path
client = SyftCoreClient.load("/custom/path/config.json")

print(client.email)  # user@example.com
print(client.my_datasite)  # Path('/home/user/.syftbox/user@example.com')

Properties

email

@property
def email(self) -> str
Get the email address of the current user.
return
str
User’s email address (e.g., “user@example.com”)

config_path

@property
def config_path(self) -> Path
Get the path to the SyftBox configuration file.
return
Path
Path to the config file

my_datasite

@property
def my_datasite(self) -> Path
Get the path to the user’s datasite directory.
return
Path
Path to user’s datasite (e.g., ~/.syftbox/datasites/user@example.com/)

datasites

@property
def datasites(self) -> Path
Get the path to the datasites root directory.
return
Path
Path to datasites root (e.g., ~/.syftbox/datasites/)

Methods

app_data

def app_data(
    self,
    app_name: Optional[str] = None,
    datasite: Optional[str] = None,
) -> Path
Get the app data directory path for a specific app and datasite.
app_name
str
default:"None"
Name of the application (e.g., “flwr/my_fl_app”)
datasite
str
default:"self.email"
Email address of the datasite owner
return
Path
Path to app data directory
Example:
client = SyftCoreClient.load()

# Get app data for current user
app_path = client.app_data("flwr/diabetes_prediction")
# /home/user/.syftbox/datasites/user@example.com/app_data/flwr/diabetes_prediction

# Get app data for another datasite
other_path = client.app_data("flwr/diabetes_prediction", "other@example.com")
# /home/user/.syftbox/datasites/other@example.com/app_data/flwr/diabetes_prediction

get_client

def get_client(self) -> Client
Get the underlying syft_core.Client for RPC/crypto/event operations.
return
syft_core.Client
The wrapped native SyftBox client with full RPC/crypto/event stack
Example:
from syft_flwr.client import SyftCoreClient
from syft_core import Client as SyftCoreNativeClient

wrapper = SyftCoreClient.load()
native_client = wrapper.get_client()

# Type check for RPC path selection
if isinstance(native_client, SyftCoreNativeClient):
    # Use syft_rpc for message sending
    from syft_rpc import rpc
    future = rpc.send(
        url=rpc.make_url("recipient@example.com", app_name="flwr/app"),
        body=b"message",
        client=native_client,
        encrypt=True
    )

SyftRpc

RPC adapter that wraps syft_rpc for message sending with encryption support.

Class Definition

from syft_flwr.rpc import SyftRpc
from syft_core import Client

class SyftRpc(SyftFlwrRpc):
    """Adapter wrapping syft_rpc for traditional SyftBox.
    
    This adapter provides the full syft_rpc functionality including:
    - URL-based message routing
    - Futures database for response tracking
    - Optional encryption via syft_crypto
    """
Source: src/syft_flwr/rpc/syft_rpc.py:12

Constructor

client
syft_core.Client
required
The SyftBox client for message transport
app_name
str
required
Name of the FL application (e.g., “flwr/my_app”)

Methods

send

def send(
    self,
    to_email: str,
    app_name: str,
    endpoint: str,
    body: bytes,
    encrypt: bool = False,
) -> str
Send a message to a recipient using syft_rpc.
to_email
str
required
Recipient’s email address
app_name
str
required
Name of the FL application
endpoint
str
required
RPC endpoint (e.g., “messages”, “rpc/fit”)
body
bytes
required
Message body as bytes (serialized Flower message)
encrypt
bool
default:false
Whether to encrypt the message using syft_crypto (X3DH)
return
str
Future ID for tracking the response
Example:
from syft_flwr.rpc import SyftRpc
from syft_core import Client

client = Client.load()
rpc = SyftRpc(client=client, app_name="flwr/my_app")

# Send encrypted message
future_id = rpc.send(
    to_email="recipient@example.com",
    app_name="flwr/my_app",
    endpoint="messages",
    body=b"serialized_message_data",
    encrypt=True
)

print(f"Message sent, future_id: {future_id}")
# Message sent, future_id: 550e8400-e29b-41d4-a716-446655440000

get_response

def get_response(self, future_id: str) -> Optional[bytes]
Retrieve the response for a previously sent message.
future_id
str
required
The future ID returned by send()
return
Optional[bytes]
Response body as bytes, or None if not ready yet
Example:
import time

future_id = rpc.send(
    to_email="recipient@example.com",
    app_name="flwr/my_app",
    endpoint="messages",
    body=b"request_data",
    encrypt=True
)

# Poll for response
while True:
    response = rpc.get_response(future_id)
    if response is not None:
        print(f"Got response: {len(response)} bytes")
        break
    time.sleep(1)

delete_future

def delete_future(self, future_id: str) -> None
Delete a future after processing its response.
future_id
str
required
The future ID to delete from the futures database
Example:
response = rpc.get_response(future_id)
if response is not None:
    # Process response
    process_message(response)
    
    # Clean up
    rpc.delete_future(future_id)

SyftEvents

Event handler that wraps syft_event.SyftEvents for real-time message processing.

Class Definition

from syft_flwr.events import SyftEvents
from syft_core import Client

class SyftEvents(SyftFlwrEvents):
    """Adapter wrapping syft_event.SyftEvents for traditional SyftBox.
    
    This adapter provides the syft-extras stack (syft_rpc/syft_crypto/syft_event)
    for FL message handling when running with syft_core.Client.
    """
Source: src/syft_flwr/events/syft_events.py:16

Constructor

app_name
str
required
Name of the FL application
client
syft_core.Client
required
The SyftBox client instance
cleanup_expiry
str
default:"1d"
How long to keep processed messages before cleanup (e.g., “1d”, “12h”)
cleanup_interval
str
default:"1d"
How often to run cleanup (e.g., “1d”, “6h”)

Properties

client_email

@property
def client_email(self) -> str
return
str
Email address of the current client

app_dir

@property
def app_dir(self) -> Path
return
Path
Path to the app data directory

is_running

@property
def is_running(self) -> bool
return
bool
Whether the event loop is currently running

Methods

on_request

def on_request(
    self,
    endpoint: str,
    handler: Callable[[bytes], Optional[Union[str, bytes]]],
    auto_decrypt: bool = True,
    encrypt_reply: bool = False,
) -> None
Register a handler for incoming messages at an endpoint.
endpoint
str
required
The endpoint path (e.g., “/messages”, “/rpc/fit”)
handler
Callable[[bytes], Optional[Union[str, bytes]]]
required
Function that receives message bytes and returns response (str or bytes)
auto_decrypt
bool
default:true
Whether to automatically decrypt incoming encrypted messages
encrypt_reply
bool
default:false
Whether to encrypt the reply message
Example:
from syft_flwr.events import SyftEvents
from syft_core import Client

client = Client.load()
events = SyftEvents(
    app_name="flwr/my_app",
    client=client,
    cleanup_expiry="1d",
    cleanup_interval="1d"
)

def handle_message(body: bytes) -> bytes:
    """Process incoming FL message and return response."""
    print(f"Received message: {len(body)} bytes")
    
    # Deserialize and process message
    # ... FL logic here ...
    
    return b"response_data"

# Register handler with encryption
events.on_request(
    endpoint="/messages",
    handler=handle_message,
    auto_decrypt=True,
    encrypt_reply=True
)

print("Starting event loop...")
events.run_forever()

run_forever

def run_forever(self) -> None
Start the event loop and block until stopped. Uses watchdog file monitoring for real-time message detection. Example:
try:
    events.run_forever()
except KeyboardInterrupt:
    print("Shutting down...")
    events.stop()

stop

def stop(self) -> None
Signal the event loop to stop gracefully.

is_cleanup_running

def is_cleanup_running(self) -> bool
return
bool
Whether the cleanup service is currently running

See Also

Build docs developers (and LLMs) love