flwr 1.16.0__py3-none-any.whl → 1.18.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. flwr/__init__.py +1 -1
  2. flwr/cli/__init__.py +1 -1
  3. flwr/cli/app.py +21 -2
  4. flwr/cli/build.py +1 -1
  5. flwr/cli/cli_user_auth_interceptor.py +1 -1
  6. flwr/cli/config_utils.py +53 -17
  7. flwr/cli/example.py +1 -1
  8. flwr/cli/install.py +1 -1
  9. flwr/cli/log.py +1 -1
  10. flwr/cli/login/__init__.py +1 -1
  11. flwr/cli/login/login.py +12 -1
  12. flwr/cli/ls.py +1 -1
  13. flwr/cli/new/__init__.py +1 -1
  14. flwr/cli/new/new.py +4 -4
  15. flwr/cli/new/templates/__init__.py +1 -1
  16. flwr/cli/new/templates/app/__init__.py +1 -1
  17. flwr/cli/new/templates/app/code/__init__.py +1 -1
  18. flwr/cli/new/templates/app/code/flwr_tune/__init__.py +1 -1
  19. flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +5 -5
  20. flwr/cli/new/templates/app/code/task.sklearn.py.tpl +1 -1
  21. flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +1 -1
  22. flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +4 -4
  23. flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +1 -1
  24. flwr/cli/new/templates/app/pyproject.jax.toml.tpl +1 -1
  25. flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +1 -1
  26. flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +1 -1
  27. flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +1 -1
  28. flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +1 -1
  29. flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +1 -1
  30. flwr/cli/run/__init__.py +1 -1
  31. flwr/cli/run/run.py +6 -10
  32. flwr/cli/stop.py +1 -1
  33. flwr/cli/utils.py +11 -12
  34. flwr/client/__init__.py +1 -1
  35. flwr/client/app.py +58 -56
  36. flwr/client/client.py +1 -1
  37. flwr/client/client_app.py +231 -166
  38. flwr/client/clientapp/__init__.py +1 -1
  39. flwr/client/clientapp/app.py +3 -3
  40. flwr/client/clientapp/clientappio_servicer.py +1 -1
  41. flwr/client/clientapp/utils.py +1 -1
  42. flwr/client/dpfedavg_numpy_client.py +1 -1
  43. flwr/client/grpc_adapter_client/__init__.py +1 -1
  44. flwr/client/grpc_adapter_client/connection.py +1 -1
  45. flwr/client/grpc_client/__init__.py +1 -1
  46. flwr/client/grpc_client/connection.py +37 -34
  47. flwr/client/grpc_rere_client/__init__.py +1 -1
  48. flwr/client/grpc_rere_client/client_interceptor.py +1 -1
  49. flwr/client/grpc_rere_client/connection.py +1 -1
  50. flwr/client/grpc_rere_client/grpc_adapter.py +1 -1
  51. flwr/client/heartbeat.py +1 -1
  52. flwr/client/message_handler/__init__.py +1 -1
  53. flwr/client/message_handler/message_handler.py +28 -28
  54. flwr/client/mod/__init__.py +3 -3
  55. flwr/client/mod/centraldp_mods.py +8 -8
  56. flwr/client/mod/comms_mods.py +17 -23
  57. flwr/client/mod/localdp_mod.py +10 -10
  58. flwr/client/mod/secure_aggregation/__init__.py +1 -1
  59. flwr/client/mod/secure_aggregation/secagg_mod.py +1 -1
  60. flwr/client/mod/secure_aggregation/secaggplus_mod.py +32 -32
  61. flwr/client/mod/utils.py +1 -1
  62. flwr/client/nodestate/__init__.py +1 -1
  63. flwr/client/nodestate/in_memory_nodestate.py +1 -1
  64. flwr/client/nodestate/nodestate.py +1 -1
  65. flwr/client/nodestate/nodestate_factory.py +1 -1
  66. flwr/client/numpy_client.py +1 -1
  67. flwr/client/rest_client/__init__.py +1 -1
  68. flwr/client/rest_client/connection.py +1 -1
  69. flwr/client/run_info_store.py +3 -3
  70. flwr/client/supernode/__init__.py +1 -1
  71. flwr/client/supernode/app.py +1 -1
  72. flwr/client/typing.py +1 -1
  73. flwr/common/__init__.py +13 -5
  74. flwr/common/address.py +1 -1
  75. flwr/common/args.py +1 -1
  76. flwr/common/auth_plugin/__init__.py +1 -1
  77. flwr/common/auth_plugin/auth_plugin.py +1 -1
  78. flwr/common/config.py +5 -5
  79. flwr/common/constant.py +7 -7
  80. flwr/common/context.py +5 -5
  81. flwr/common/date.py +1 -1
  82. flwr/common/differential_privacy.py +1 -1
  83. flwr/common/differential_privacy_constants.py +1 -1
  84. flwr/common/dp.py +1 -1
  85. flwr/common/event_log_plugin/event_log_plugin.py +3 -3
  86. flwr/common/exit/exit.py +6 -6
  87. flwr/common/exit_handlers.py +1 -1
  88. flwr/common/grpc.py +1 -1
  89. flwr/common/logger.py +3 -3
  90. flwr/common/message.py +344 -102
  91. flwr/common/object_ref.py +1 -1
  92. flwr/common/parameter.py +1 -1
  93. flwr/common/pyproject.py +1 -1
  94. flwr/common/record/__init__.py +9 -5
  95. flwr/common/record/arrayrecord.py +626 -0
  96. flwr/common/record/{configsrecord.py → configrecord.py} +83 -37
  97. flwr/common/record/conversion_utils.py +2 -2
  98. flwr/common/record/{metricsrecord.py → metricrecord.py} +90 -44
  99. flwr/common/record/recorddict.py +337 -0
  100. flwr/common/record/typeddict.py +1 -1
  101. flwr/common/recorddict_compat.py +410 -0
  102. flwr/common/retry_invoker.py +10 -10
  103. flwr/common/secure_aggregation/__init__.py +1 -1
  104. flwr/common/secure_aggregation/crypto/__init__.py +1 -1
  105. flwr/common/secure_aggregation/crypto/shamir.py +52 -30
  106. flwr/common/secure_aggregation/crypto/symmetric_encryption.py +1 -1
  107. flwr/common/secure_aggregation/ndarrays_arithmetic.py +1 -1
  108. flwr/common/secure_aggregation/quantization.py +1 -1
  109. flwr/common/secure_aggregation/secaggplus_constants.py +2 -2
  110. flwr/common/secure_aggregation/secaggplus_utils.py +1 -1
  111. flwr/common/serde.py +67 -72
  112. flwr/common/telemetry.py +2 -2
  113. flwr/common/typing.py +9 -9
  114. flwr/common/version.py +1 -1
  115. flwr/proto/__init__.py +1 -1
  116. flwr/proto/exec_pb2.py +3 -3
  117. flwr/proto/exec_pb2.pyi +3 -3
  118. flwr/proto/message_pb2.py +12 -12
  119. flwr/proto/message_pb2.pyi +9 -9
  120. flwr/proto/recorddict_pb2.py +70 -0
  121. flwr/proto/{recordset_pb2.pyi → recorddict_pb2.pyi} +35 -35
  122. flwr/proto/run_pb2.py +31 -31
  123. flwr/proto/run_pb2.pyi +3 -3
  124. flwr/server/__init__.py +4 -2
  125. flwr/server/app.py +67 -12
  126. flwr/server/client_manager.py +1 -1
  127. flwr/server/client_proxy.py +1 -1
  128. flwr/server/compat/__init__.py +3 -3
  129. flwr/server/compat/app.py +12 -12
  130. flwr/server/compat/app_utils.py +17 -17
  131. flwr/server/compat/{driver_client_proxy.py → grid_client_proxy.py} +39 -39
  132. flwr/server/compat/legacy_context.py +1 -1
  133. flwr/server/criterion.py +1 -1
  134. flwr/server/fleet_event_log_interceptor.py +94 -0
  135. flwr/server/{driver → grid}/__init__.py +8 -7
  136. flwr/server/{driver/driver.py → grid/grid.py} +48 -19
  137. flwr/server/{driver/grpc_driver.py → grid/grpc_grid.py} +87 -64
  138. flwr/server/{driver/inmemory_driver.py → grid/inmemory_grid.py} +24 -34
  139. flwr/server/history.py +1 -1
  140. flwr/server/run_serverapp.py +5 -5
  141. flwr/server/server.py +1 -1
  142. flwr/server/server_app.py +98 -71
  143. flwr/server/server_config.py +1 -1
  144. flwr/server/serverapp/__init__.py +1 -1
  145. flwr/server/serverapp/app.py +11 -11
  146. flwr/server/serverapp_components.py +1 -1
  147. flwr/server/strategy/__init__.py +1 -1
  148. flwr/server/strategy/aggregate.py +1 -1
  149. flwr/server/strategy/bulyan.py +2 -2
  150. flwr/server/strategy/dp_adaptive_clipping.py +17 -17
  151. flwr/server/strategy/dp_fixed_clipping.py +17 -17
  152. flwr/server/strategy/dpfedavg_adaptive.py +1 -1
  153. flwr/server/strategy/dpfedavg_fixed.py +1 -1
  154. flwr/server/strategy/fault_tolerant_fedavg.py +1 -1
  155. flwr/server/strategy/fedadagrad.py +1 -1
  156. flwr/server/strategy/fedadam.py +1 -1
  157. flwr/server/strategy/fedavg.py +1 -1
  158. flwr/server/strategy/fedavg_android.py +1 -1
  159. flwr/server/strategy/fedavgm.py +1 -1
  160. flwr/server/strategy/fedmedian.py +1 -1
  161. flwr/server/strategy/fedopt.py +1 -1
  162. flwr/server/strategy/fedprox.py +1 -1
  163. flwr/server/strategy/fedtrimmedavg.py +1 -1
  164. flwr/server/strategy/fedxgb_bagging.py +1 -1
  165. flwr/server/strategy/fedxgb_cyclic.py +1 -1
  166. flwr/server/strategy/fedxgb_nn_avg.py +3 -2
  167. flwr/server/strategy/fedyogi.py +1 -1
  168. flwr/server/strategy/krum.py +1 -1
  169. flwr/server/strategy/qfedavg.py +1 -1
  170. flwr/server/strategy/strategy.py +1 -1
  171. flwr/server/superlink/__init__.py +1 -1
  172. flwr/server/superlink/ffs/__init__.py +1 -1
  173. flwr/server/superlink/ffs/disk_ffs.py +1 -1
  174. flwr/server/superlink/ffs/ffs.py +1 -1
  175. flwr/server/superlink/ffs/ffs_factory.py +1 -1
  176. flwr/server/superlink/fleet/__init__.py +1 -1
  177. flwr/server/superlink/fleet/grpc_adapter/__init__.py +1 -1
  178. flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +1 -1
  179. flwr/server/superlink/fleet/grpc_bidi/__init__.py +1 -1
  180. flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +1 -1
  181. flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +1 -1
  182. flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +1 -1
  183. flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +13 -13
  184. flwr/server/superlink/fleet/grpc_rere/__init__.py +1 -1
  185. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +1 -1
  186. flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +1 -1
  187. flwr/server/superlink/fleet/message_handler/__init__.py +1 -1
  188. flwr/server/superlink/fleet/message_handler/message_handler.py +1 -1
  189. flwr/server/superlink/fleet/rest_rere/__init__.py +1 -1
  190. flwr/server/superlink/fleet/rest_rere/rest_api.py +1 -1
  191. flwr/server/superlink/fleet/vce/__init__.py +1 -1
  192. flwr/server/superlink/fleet/vce/backend/__init__.py +1 -1
  193. flwr/server/superlink/fleet/vce/backend/backend.py +3 -3
  194. flwr/server/superlink/fleet/vce/backend/raybackend.py +3 -3
  195. flwr/server/superlink/fleet/vce/vce_api.py +2 -4
  196. flwr/server/superlink/linkstate/__init__.py +1 -1
  197. flwr/server/superlink/linkstate/in_memory_linkstate.py +34 -9
  198. flwr/server/superlink/linkstate/linkstate.py +5 -5
  199. flwr/server/superlink/linkstate/linkstate_factory.py +1 -1
  200. flwr/server/superlink/linkstate/sqlite_linkstate.py +62 -28
  201. flwr/server/superlink/linkstate/utils.py +94 -28
  202. flwr/server/superlink/{driver → serverappio}/__init__.py +1 -1
  203. flwr/server/superlink/{driver → serverappio}/serverappio_grpc.py +1 -1
  204. flwr/server/superlink/{driver → serverappio}/serverappio_servicer.py +4 -4
  205. flwr/server/superlink/simulation/__init__.py +1 -1
  206. flwr/server/superlink/simulation/simulationio_grpc.py +1 -1
  207. flwr/server/superlink/simulation/simulationio_servicer.py +3 -3
  208. flwr/server/superlink/utils.py +1 -1
  209. flwr/server/typing.py +4 -4
  210. flwr/server/utils/__init__.py +1 -1
  211. flwr/server/utils/tensorboard.py +1 -1
  212. flwr/server/utils/validator.py +5 -5
  213. flwr/server/workflow/__init__.py +1 -1
  214. flwr/server/workflow/constant.py +1 -1
  215. flwr/server/workflow/default_workflows.py +49 -58
  216. flwr/server/workflow/secure_aggregation/__init__.py +1 -1
  217. flwr/server/workflow/secure_aggregation/secagg_workflow.py +1 -1
  218. flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +49 -51
  219. flwr/simulation/__init__.py +1 -1
  220. flwr/simulation/app.py +3 -3
  221. flwr/simulation/legacy_app.py +1 -1
  222. flwr/simulation/ray_transport/__init__.py +1 -1
  223. flwr/simulation/ray_transport/ray_actor.py +5 -3
  224. flwr/simulation/ray_transport/ray_client_proxy.py +35 -33
  225. flwr/simulation/ray_transport/utils.py +1 -1
  226. flwr/simulation/run_simulation.py +17 -17
  227. flwr/simulation/simulationio_connection.py +1 -1
  228. flwr/superexec/__init__.py +1 -1
  229. flwr/superexec/app.py +1 -1
  230. flwr/superexec/deployment.py +5 -5
  231. flwr/superexec/exec_event_log_interceptor.py +135 -0
  232. flwr/superexec/exec_grpc.py +11 -5
  233. flwr/superexec/exec_servicer.py +3 -3
  234. flwr/superexec/exec_user_auth_interceptor.py +19 -3
  235. flwr/superexec/executor.py +4 -4
  236. flwr/superexec/simulation.py +4 -4
  237. {flwr-1.16.0.dist-info → flwr-1.18.0.dist-info}/METADATA +3 -3
  238. flwr-1.18.0.dist-info/RECORD +332 -0
  239. flwr/common/record/parametersrecord.py +0 -339
  240. flwr/common/record/recordset.py +0 -209
  241. flwr/common/recordset_compat.py +0 -418
  242. flwr/proto/recordset_pb2.py +0 -70
  243. flwr-1.16.0.dist-info/LICENSE +0 -202
  244. flwr-1.16.0.dist-info/RECORD +0 -331
  245. /flwr/proto/{recordset_pb2_grpc.py → recorddict_pb2_grpc.py} +0 -0
  246. /flwr/proto/{recordset_pb2_grpc.pyi → recorddict_pb2_grpc.pyi} +0 -0
  247. {flwr-1.16.0.dist-info → flwr-1.18.0.dist-info}/WHEEL +0 -0
  248. {flwr-1.16.0.dist-info → flwr-1.18.0.dist-info}/entry_points.txt +0 -0
flwr/server/server_app.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -15,20 +15,18 @@
15
15
  """Flower ServerApp."""
16
16
 
17
17
 
18
+ import inspect
18
19
  from collections.abc import Iterator
19
20
  from contextlib import contextmanager
20
21
  from typing import Callable, Optional
21
22
 
22
23
  from flwr.common import Context
23
- from flwr.common.logger import (
24
- warn_deprecated_feature_with_example,
25
- warn_preview_feature,
26
- )
24
+ from flwr.common.logger import warn_deprecated_feature_with_example
27
25
  from flwr.server.strategy import Strategy
28
26
 
29
27
  from .client_manager import ClientManager
30
- from .compat import start_driver
31
- from .driver import Driver
28
+ from .compat import start_grid
29
+ from .grid import Driver, Grid
32
30
  from .server import Server
33
31
  from .server_config import ServerConfig
34
32
  from .typing import ServerAppCallable, ServerFn
@@ -46,6 +44,45 @@ SERVER_FN_USAGE_EXAMPLE = """
46
44
  app = ServerApp(server_fn=server_fn)
47
45
  """
48
46
 
47
+ GRID_USAGE_EXAMPLE = """
48
+ app = ServerApp()
49
+
50
+ @app.main()
51
+ def main(grid: Grid, context: Context) -> None:
52
+ # Your existing ServerApp code ...
53
+ """
54
+
55
+ BOTH_MAIN_FN_SERVER_FN_PROVIDED_ERROR_MSG = (
56
+ "Use either a custom main function or a `Strategy`, but not both."
57
+ """
58
+
59
+ Use the `ServerApp` with an existing `Strategy`:
60
+
61
+ server_config = ServerConfig(num_rounds=3)
62
+ strategy = FedAvg()
63
+
64
+ app = ServerApp(
65
+ server_config=server_config,
66
+ strategy=strategy,
67
+ )
68
+
69
+ Use the `ServerApp` with a custom main function:
70
+
71
+ app = ServerApp()
72
+
73
+ @app.main()
74
+ def main(grid: Grid, context: Context) -> None:
75
+ print("ServerApp running")
76
+ """
77
+ )
78
+
79
+ DRIVER_DEPRECATION_MSG = """
80
+ The `Driver` class is deprecated, it will be removed in a future release.
81
+ """
82
+ DRIVER_EXAMPLE_MSG = """
83
+ Instead, use `Grid` in the signature of your `ServerApp`. For example:
84
+ """
85
+
49
86
 
50
87
  @contextmanager
51
88
  def _empty_lifespan(_: Context) -> Iterator[None]:
@@ -57,25 +94,25 @@ class ServerApp: # pylint: disable=too-many-instance-attributes
57
94
 
58
95
  Examples
59
96
  --------
60
- Use the `ServerApp` with an existing `Strategy`:
61
-
62
- >>> def server_fn(context: Context):
63
- >>> server_config = ServerConfig(num_rounds=3)
64
- >>> strategy = FedAvg()
65
- >>> return ServerAppComponents(
66
- >>> strategy=strategy,
67
- >>> server_config=server_config,
68
- >>> )
69
- >>>
70
- >>> app = ServerApp(server_fn=server_fn)
71
-
72
- Use the `ServerApp` with a custom main function:
73
-
74
- >>> app = ServerApp()
75
- >>>
76
- >>> @app.main()
77
- >>> def main(driver: Driver, context: Context) -> None:
78
- >>> print("ServerApp running")
97
+ Use the ``ServerApp`` with an existing ``Strategy``::
98
+
99
+ def server_fn(context: Context):
100
+ server_config = ServerConfig(num_rounds=3)
101
+ strategy = FedAvg()
102
+ return ServerAppComponents(
103
+ strategy=strategy,
104
+ server_config=server_config,
105
+ )
106
+
107
+ app = ServerApp(server_fn=server_fn)
108
+
109
+ Use the ``ServerApp`` with a custom main function::
110
+
111
+ app = ServerApp()
112
+
113
+ @app.main()
114
+ def main(grid: Grid, context: Context) -> None:
115
+ print("ServerApp running")
79
116
  """
80
117
 
81
118
  # pylint: disable=too-many-arguments,too-many-positional-arguments
@@ -114,7 +151,7 @@ class ServerApp: # pylint: disable=too-many-instance-attributes
114
151
  self._main: Optional[ServerAppCallable] = None
115
152
  self._lifespan = _empty_lifespan
116
153
 
117
- def __call__(self, driver: Driver, context: Context) -> None:
154
+ def __call__(self, grid: Grid, context: Context) -> None:
118
155
  """Execute `ServerApp`."""
119
156
  with self._lifespan(context):
120
157
  # Compatibility mode
@@ -126,58 +163,47 @@ class ServerApp: # pylint: disable=too-many-instance-attributes
126
163
  self._config = components.config
127
164
  self._strategy = components.strategy
128
165
  self._client_manager = components.client_manager
129
- start_driver(
166
+ start_grid(
130
167
  server=self._server,
131
168
  config=self._config,
132
169
  strategy=self._strategy,
133
170
  client_manager=self._client_manager,
134
- driver=driver,
171
+ grid=grid,
135
172
  )
136
173
  return
137
174
 
138
175
  # New execution mode
139
- self._main(driver, context)
176
+ self._main(grid, context)
140
177
 
141
178
  def main(self) -> Callable[[ServerAppCallable], ServerAppCallable]:
142
179
  """Return a decorator that registers the main fn with the server app.
143
180
 
144
181
  Examples
145
182
  --------
146
- >>> app = ServerApp()
147
- >>>
148
- >>> @app.main()
149
- >>> def main(driver: Driver, context: Context) -> None:
150
- >>> print("ServerApp running")
183
+ ::
184
+
185
+ app = ServerApp()
186
+
187
+ @app.main()
188
+ def main(grid: Grid, context: Context) -> None:
189
+ print("ServerApp running")
151
190
  """
152
191
 
153
192
  def main_decorator(main_fn: ServerAppCallable) -> ServerAppCallable:
154
193
  """Register the main fn with the ServerApp object."""
155
194
  if self._server or self._config or self._strategy or self._client_manager:
156
- raise ValueError(
157
- """Use either a custom main function or a `Strategy`, but not both.
158
-
159
- Use the `ServerApp` with an existing `Strategy`:
160
-
161
- >>> server_config = ServerConfig(num_rounds=3)
162
- >>> strategy = FedAvg()
163
- >>>
164
- >>> app = ServerApp(
165
- >>> server_config=server_config,
166
- >>> strategy=strategy,
167
- >>> )
168
-
169
- Use the `ServerApp` with a custom main function:
170
-
171
- >>> app = ServerApp()
172
- >>>
173
- >>> @app.main()
174
- >>> def main(driver: Driver, context: Context) -> None:
175
- >>> print("ServerApp running")
176
- """,
195
+ raise ValueError(BOTH_MAIN_FN_SERVER_FN_PROVIDED_ERROR_MSG)
196
+
197
+ sig = inspect.signature(main_fn)
198
+ param = list(sig.parameters.values())[0]
199
+ # Check if parameter name or the annotation should be updated
200
+ if param.name == "driver" or param.annotation is Driver:
201
+ warn_deprecated_feature_with_example(
202
+ deprecation_message=DRIVER_DEPRECATION_MSG,
203
+ example_message=DRIVER_EXAMPLE_MSG,
204
+ code_example=GRID_USAGE_EXAMPLE,
177
205
  )
178
206
 
179
- warn_preview_feature("ServerApp-register-main-function")
180
-
181
207
  # Register provided function with the ServerApp object
182
208
  self._main = main_fn
183
209
 
@@ -198,24 +224,25 @@ class ServerApp: # pylint: disable=too-many-instance-attributes
198
224
 
199
225
  Examples
200
226
  --------
201
- >>> app = ServerApp()
202
- >>>
203
- >>> @app.lifespan()
204
- >>> def lifespan(context: Context) -> None:
205
- >>> # Perform initialization tasks before the app starts
206
- >>> print("Initializing ServerApp")
207
- >>>
208
- >>> yield # ServerApp is running
209
- >>>
210
- >>> # Perform cleanup tasks after the app stops
211
- >>> print("Cleaning up ServerApp")
227
+ ::
228
+
229
+ app = ServerApp()
230
+
231
+ @app.lifespan()
232
+ def lifespan(context: Context) -> None:
233
+ # Perform initialization tasks before the app starts
234
+ print("Initializing ServerApp")
235
+
236
+ yield # ServerApp is running
237
+
238
+ # Perform cleanup tasks after the app stops
239
+ print("Cleaning up ServerApp")
212
240
  """
213
241
 
214
242
  def lifespan_decorator(
215
- lifespan_fn: Callable[[Context], Iterator[None]]
243
+ lifespan_fn: Callable[[Context], Iterator[None]],
216
244
  ) -> Callable[[Context], Iterator[None]]:
217
245
  """Register the lifespan fn with the ServerApp object."""
218
- warn_preview_feature("ServerApp-register-lifespan-function")
219
246
 
220
247
  @contextmanager
221
248
  def decorated_lifespan(context: Context) -> Iterator[None]:
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -60,7 +60,7 @@ from flwr.proto.serverappio_pb2 import ( # pylint: disable=E0611
60
60
  PullServerAppInputsResponse,
61
61
  PushServerAppOutputsRequest,
62
62
  )
63
- from flwr.server.driver.grpc_driver import GrpcDriver
63
+ from flwr.server.grid.grpc_grid import GrpcGrid
64
64
  from flwr.server.run_serverapp import run as run_
65
65
 
66
66
 
@@ -106,7 +106,7 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915
106
106
  certificates: Optional[bytes] = None,
107
107
  ) -> None:
108
108
  """Run Flower ServerApp process."""
109
- driver = GrpcDriver(
109
+ grid = GrpcGrid(
110
110
  serverappio_service_address=serverappio_api_address,
111
111
  root_certificates=certificates,
112
112
  )
@@ -123,7 +123,7 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915
123
123
  # Pull ServerAppInputs from LinkState
124
124
  req = PullServerAppInputsRequest()
125
125
  log(DEBUG, "[flwr-serverapp] Pull ServerAppInputs")
126
- res: PullServerAppInputsResponse = driver._stub.PullServerAppInputs(req)
126
+ res: PullServerAppInputsResponse = grid._stub.PullServerAppInputs(req)
127
127
  if not res.HasField("run"):
128
128
  sleep(3)
129
129
  run_status = None
@@ -135,14 +135,14 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915
135
135
 
136
136
  hash_run_id = get_sha256_hash(run.run_id)
137
137
 
138
- driver.set_run(run.run_id)
138
+ grid.set_run(run.run_id)
139
139
 
140
140
  # Start log uploader for this run
141
141
  log_uploader = start_log_uploader(
142
142
  log_queue=log_queue,
143
143
  node_id=0,
144
144
  run_id=run.run_id,
145
- stub=driver._stub,
145
+ stub=grid._stub,
146
146
  )
147
147
 
148
148
  log(DEBUG, "[flwr-serverapp] Start FAB installation.")
@@ -173,7 +173,7 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915
173
173
 
174
174
  # Change status to Running
175
175
  run_status_proto = run_status_to_proto(RunStatus(Status.RUNNING, "", ""))
176
- driver._stub.UpdateRunStatus(
176
+ grid._stub.UpdateRunStatus(
177
177
  UpdateRunStatusRequest(run_id=run.run_id, run_status=run_status_proto)
178
178
  )
179
179
 
@@ -182,9 +182,9 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915
182
182
  event_details={"run-id-hash": hash_run_id},
183
183
  )
184
184
 
185
- # Load and run the ServerApp with the Driver
185
+ # Load and run the ServerApp with the Grid
186
186
  updated_context = run_(
187
- driver=driver,
187
+ grid=grid,
188
188
  server_app_dir=app_path,
189
189
  server_app_attr=server_app_attr,
190
190
  context=context,
@@ -196,7 +196,7 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915
196
196
  out_req = PushServerAppOutputsRequest(
197
197
  run_id=run.run_id, context=context_proto
198
198
  )
199
- _ = driver._stub.PushServerAppOutputs(out_req)
199
+ _ = grid._stub.PushServerAppOutputs(out_req)
200
200
 
201
201
  run_status = RunStatus(Status.FINISHED, SubStatus.COMPLETED, "")
202
202
  except RunNotRunningException:
@@ -221,7 +221,7 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915
221
221
  # Update run status
222
222
  if run_status:
223
223
  run_status_proto = run_status_to_proto(run_status)
224
- driver._stub.UpdateRunStatus(
224
+ grid._stub.UpdateRunStatus(
225
225
  UpdateRunStatusRequest(
226
226
  run_id=run.run_id, run_status=run_status_proto
227
227
  )
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@ from .aggregate import aggregate_bulyan, aggregate_krum
37
37
  from .fedavg import FedAvg
38
38
 
39
39
 
40
- # flake8: noqa: E501
40
+ # noqa: E501
41
41
  # pylint: disable=line-too-long
42
42
  class Bulyan(FedAvg):
43
43
  """Bulyan strategy.
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -77,15 +77,15 @@ class DifferentialPrivacyServerSideAdaptiveClipping(Strategy):
77
77
 
78
78
  Examples
79
79
  --------
80
- Create a strategy:
80
+ Create a strategy::
81
81
 
82
- >>> strategy = fl.server.strategy.FedAvg( ... )
82
+ strategy = fl.server.strategy.FedAvg( ... )
83
83
 
84
- Wrap the strategy with the DifferentialPrivacyServerSideAdaptiveClipping wrapper
84
+ Wrap the strategy with the DifferentialPrivacyServerSideAdaptiveClipping wrapper::
85
85
 
86
- >>> dp_strategy = DifferentialPrivacyServerSideAdaptiveClipping(
87
- >>> strategy, cfg.noise_multiplier, cfg.num_sampled_clients, ...
88
- >>> )
86
+ dp_strategy = DifferentialPrivacyServerSideAdaptiveClipping(
87
+ strategy, cfg.noise_multiplier, cfg.num_sampled_clients, ...
88
+ )
89
89
  """
90
90
 
91
91
  # pylint: disable=too-many-arguments,too-many-instance-attributes,too-many-positional-arguments
@@ -290,21 +290,21 @@ class DifferentialPrivacyClientSideAdaptiveClipping(Strategy):
290
290
 
291
291
  Examples
292
292
  --------
293
- Create a strategy:
293
+ Create a strategy::
294
294
 
295
- >>> strategy = fl.server.strategy.FedAvg(...)
295
+ strategy = fl.server.strategy.FedAvg(...)
296
296
 
297
- Wrap the strategy with the `DifferentialPrivacyClientSideAdaptiveClipping` wrapper:
297
+ Wrap the strategy with the `DifferentialPrivacyClientSideAdaptiveClipping` wrapper::
298
298
 
299
- >>> dp_strategy = DifferentialPrivacyClientSideAdaptiveClipping(
300
- >>> strategy, cfg.noise_multiplier, cfg.num_sampled_clients
301
- >>> )
299
+ dp_strategy = DifferentialPrivacyClientSideAdaptiveClipping(
300
+ strategy, cfg.noise_multiplier, cfg.num_sampled_clients
301
+ )
302
302
 
303
- On the client, add the `adaptiveclipping_mod` to the client-side mods:
303
+ On the client, add the `adaptiveclipping_mod` to the client-side mods::
304
304
 
305
- >>> app = fl.client.ClientApp(
306
- >>> client_fn=client_fn, mods=[adaptiveclipping_mod]
307
- >>> )
305
+ app = fl.client.ClientApp(
306
+ client_fn=client_fn, mods=[adaptiveclipping_mod]
307
+ )
308
308
  """
309
309
 
310
310
  # pylint: disable=too-many-arguments,too-many-instance-attributes,too-many-positional-arguments
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -64,15 +64,15 @@ class DifferentialPrivacyServerSideFixedClipping(Strategy):
64
64
 
65
65
  Examples
66
66
  --------
67
- Create a strategy:
67
+ Create a strategy::
68
68
 
69
- >>> strategy = fl.server.strategy.FedAvg( ... )
69
+ strategy = fl.server.strategy.FedAvg( ... )
70
70
 
71
- Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping wrapper
71
+ Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping wrapper::
72
72
 
73
- >>> dp_strategy = DifferentialPrivacyServerSideFixedClipping(
74
- >>> strategy, cfg.noise_multiplier, cfg.clipping_norm, cfg.num_sampled_clients
75
- >>> )
73
+ dp_strategy = DifferentialPrivacyServerSideFixedClipping(
74
+ strategy, cfg.noise_multiplier, cfg.clipping_norm, cfg.num_sampled_clients
75
+ )
76
76
  """
77
77
 
78
78
  # pylint: disable=too-many-arguments,too-many-instance-attributes
@@ -228,21 +228,21 @@ class DifferentialPrivacyClientSideFixedClipping(Strategy):
228
228
 
229
229
  Examples
230
230
  --------
231
- Create a strategy:
231
+ Create a strategy::
232
232
 
233
- >>> strategy = fl.server.strategy.FedAvg(...)
233
+ strategy = fl.server.strategy.FedAvg(...)
234
234
 
235
- Wrap the strategy with the `DifferentialPrivacyClientSideFixedClipping` wrapper:
235
+ Wrap the strategy with the `DifferentialPrivacyClientSideFixedClipping` wrapper::
236
236
 
237
- >>> dp_strategy = DifferentialPrivacyClientSideFixedClipping(
238
- >>> strategy, cfg.noise_multiplier, cfg.clipping_norm, cfg.num_sampled_clients
239
- >>> )
237
+ dp_strategy = DifferentialPrivacyClientSideFixedClipping(
238
+ strategy, cfg.noise_multiplier, cfg.clipping_norm, cfg.num_sampled_clients
239
+ )
240
240
 
241
- On the client, add the `fixedclipping_mod` to the client-side mods:
241
+ On the client, add the `fixedclipping_mod` to the client-side mods::
242
242
 
243
- >>> app = fl.client.ClientApp(
244
- >>> client_fn=client_fn, mods=[fixedclipping_mod]
245
- >>> )
243
+ app = fl.client.ClientApp(
244
+ client_fn=client_fn, mods=[fixedclipping_mod]
245
+ )
246
246
  """
247
247
 
248
248
  # pylint: disable=too-many-arguments,too-many-instance-attributes
@@ -1,4 +1,4 @@
1
- # Copyright 2022 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2022 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2021 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2021 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2021 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2022 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2022 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2021 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -44,7 +44,8 @@ class FedXgbNnAvg(FedAvg):
44
44
  def __init__(self, *args: Any, **kwargs: Any) -> None:
45
45
  """Federated XGBoost [Ma et al., 2023] strategy.
46
46
 
47
- Implementation based on https://arxiv.org/abs/2304.07537.
47
+ Implementation based on
48
+ https://arxiv.org/abs/2304.07537.
48
49
  """
49
50
  super().__init__(*args, **kwargs)
50
51
  warn_deprecated_feature("`FedXgbNnAvg` strategy")
@@ -1,4 +1,4 @@
1
- # Copyright 2021 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2022 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2021 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.