ClientApp¶
- class ClientApp(client_fn: Callable[[Context], Client] | None = None, mods: list[Callable[[Message, Context, Callable[[Message, Context], Message]], Message]] | None = None)[source]¶
Bases:
object
Flower ClientApp.
Examples
Assuming a typical
Client
implementation namedFlowerClient
, you can wrap it in aClientApp
as follows:class FlowerClient(NumPyClient): # ... def client_fn(context: Context): return FlowerClient().to_client() app = ClientApp(client_fn)
Methods
evaluate
([action, mods])Register an evaluate function with the
ClientApp
.lifespan
()Return a decorator that registers the lifespan fn with the client app.
query
([action, mods])Register a query function with the
ClientApp
.train
([action, mods])Register a train function with the
ClientApp
.- evaluate(action: str = 'default', *, mods: list[Callable[[Message, Context, Callable[[Message, Context], Message]], Message]] | None = None) Callable[[Callable[[Message, Context], Message]], Callable[[Message, Context], Message]] [source]¶
Register an evaluate function with the
ClientApp
.- Parameters:
action (str (default: "default")) – The action name used to route messages. Defaults to “default”.
mods (Optional[list[Mod]] (default: None)) – A list of function-specific modifiers.
- Returns:
A decorator that registers an evaluate function with the
ClientApp
.- Return type:
Callable[[ClientAppCallable], ClientAppCallable]
Examples
Registering an evaluate function:
app = ClientApp() @app.evaluate() def evaluate(message: Message, context: Context) -> Message: print("Executing default evaluate function") # Create and return an echo reply message return Message(message.content, reply_to=message)
Registering an evaluate function with a custom action name:
app = ClientApp() # Messages with `message_type="evaluate.custom_action"` will be # routed to this function. @app.evaluate("custom_action") def custom_action(message: Message, context: Context) -> Message: print("Executing evaluate function for custom action") return Message(message.content, reply_to=message)
Registering an evaluate function with a function-specific Flower Mod:
from flwr.client.mod import message_size_mod app = ClientApp() # Using the `mods` argument to apply a function-specific mod. @app.evaluate(mods=[message_size_mod]) def evaluate(message: Message, context: Context) -> Message: print("Executing evaluate function with message size mod") # Create and return an echo reply message return Message(message.content, reply_to=message)
- lifespan() Callable[[Callable[[Context], Iterator[None]]], Callable[[Context], Iterator[None]]] [source]¶
Return a decorator that registers the lifespan fn with the client app.
The decorated function should accept a Context object and use yield to define enter and exit behavior.
Examples
app = ClientApp() @app.lifespan() def lifespan(context: Context) -> None: # Perform initialization tasks before the app starts print("Initializing ClientApp") yield # ClientApp is running # Perform cleanup tasks after the app stops print("Cleaning up ClientApp")
- query(action: str = 'default', *, mods: list[Callable[[Message, Context, Callable[[Message, Context], Message]], Message]] | None = None) Callable[[Callable[[Message, Context], Message]], Callable[[Message, Context], Message]] [source]¶
Register a query function with the
ClientApp
.- Parameters:
action (str (default: "default")) – The action name used to route messages. Defaults to “default”.
mods (Optional[list[Mod]] (default: None)) – A list of function-specific modifiers.
- Returns:
A decorator that registers a query function with the
ClientApp
.- Return type:
Callable[[ClientAppCallable], ClientAppCallable]
Examples
Registering a query function:
app = ClientApp() @app.query() def query(message: Message, context: Context) -> Message: print("Executing default query function") # Create and return an echo reply message return Message(message.content, reply_to=message)
Registering a query function with a custom action name:
app = ClientApp() # Messages with `message_type="query.custom_action"` will be # routed to this function. @app.query("custom_action") def custom_action(message: Message, context: Context) -> Message: print("Executing query function for custom action") return Message(message.content, reply_to=message)
Registering a query function with a function-specific Flower Mod:
from flwr.client.mod import message_size_mod app = ClientApp() # Using the `mods` argument to apply a function-specific mod. @app.query(mods=[message_size_mod]) def query(message: Message, context: Context) -> Message: print("Executing query function with message size mod") # Create and return an echo reply message return Message(message.content, reply_to=message)
- train(action: str = 'default', *, mods: list[Callable[[Message, Context, Callable[[Message, Context], Message]], Message]] | None = None) Callable[[Callable[[Message, Context], Message]], Callable[[Message, Context], Message]] [source]¶
Register a train function with the
ClientApp
.- Parameters:
action (str (default: "default")) – The action name used to route messages. Defaults to “default”.
mods (Optional[list[Mod]] (default: None)) – A list of function-specific modifiers.
- Returns:
A decorator that registers a train function with the
ClientApp
.- Return type:
Callable[[ClientAppCallable], ClientAppCallable]
Examples
Registering a train function:
app = ClientApp() @app.train() def train(message: Message, context: Context) -> Message: print("Executing default train function") # Create and return an echo reply message return Message(message.content, reply_to=message)
Registering a train function with a custom action name:
app = ClientApp() # Messages with `message_type="train.custom_action"` will be # routed to this function. @app.train("custom_action") def custom_action(message: Message, context: Context) -> Message: print("Executing train function for custom action") return Message(message.content, reply_to=message)
Registering a train function with a function-specific Flower Mod:
from flwr.client.mod import message_size_mod app = ClientApp() # Using the `mods` argument to apply a function-specific mod. @app.train(mods=[message_size_mod]) def train(message: Message, context: Context) -> Message: print("Executing train function with message size mod") # Create and return an echo reply message return Message(message.content, reply_to=message)