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 named FlowerClient, you can wrap it in a ClientApp 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)