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
@@ -104,7 +104,7 @@ class Array(google.protobuf.message.Message):
104
104
  def ClearField(self, field_name: typing_extensions.Literal["data",b"data","dtype",b"dtype","shape",b"shape","stype",b"stype"]) -> None: ...
105
105
  global___Array = Array
106
106
 
107
- class MetricsRecordValue(google.protobuf.message.Message):
107
+ class MetricRecordValue(google.protobuf.message.Message):
108
108
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
109
109
  DOUBLE_FIELD_NUMBER: builtins.int
110
110
  SINT64_FIELD_NUMBER: builtins.int
@@ -137,9 +137,9 @@ class MetricsRecordValue(google.protobuf.message.Message):
137
137
  def HasField(self, field_name: typing_extensions.Literal["double",b"double","double_list",b"double_list","sint64",b"sint64","sint_list",b"sint_list","uint64",b"uint64","uint_list",b"uint_list","value",b"value"]) -> builtins.bool: ...
138
138
  def ClearField(self, field_name: typing_extensions.Literal["double",b"double","double_list",b"double_list","sint64",b"sint64","sint_list",b"sint_list","uint64",b"uint64","uint_list",b"uint_list","value",b"value"]) -> None: ...
139
139
  def WhichOneof(self, oneof_group: typing_extensions.Literal["value",b"value"]) -> typing.Optional[typing_extensions.Literal["double","sint64","uint64","double_list","sint_list","uint_list"]]: ...
140
- global___MetricsRecordValue = MetricsRecordValue
140
+ global___MetricRecordValue = MetricRecordValue
141
141
 
142
- class ConfigsRecordValue(google.protobuf.message.Message):
142
+ class ConfigRecordValue(google.protobuf.message.Message):
143
143
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
144
144
  DOUBLE_FIELD_NUMBER: builtins.int
145
145
  SINT64_FIELD_NUMBER: builtins.int
@@ -193,9 +193,9 @@ class ConfigsRecordValue(google.protobuf.message.Message):
193
193
  def HasField(self, field_name: typing_extensions.Literal["bool",b"bool","bool_list",b"bool_list","bytes",b"bytes","bytes_list",b"bytes_list","double",b"double","double_list",b"double_list","sint64",b"sint64","sint_list",b"sint_list","string",b"string","string_list",b"string_list","uint64",b"uint64","uint_list",b"uint_list","value",b"value"]) -> builtins.bool: ...
194
194
  def ClearField(self, field_name: typing_extensions.Literal["bool",b"bool","bool_list",b"bool_list","bytes",b"bytes","bytes_list",b"bytes_list","double",b"double","double_list",b"double_list","sint64",b"sint64","sint_list",b"sint_list","string",b"string","string_list",b"string_list","uint64",b"uint64","uint_list",b"uint_list","value",b"value"]) -> None: ...
195
195
  def WhichOneof(self, oneof_group: typing_extensions.Literal["value",b"value"]) -> typing.Optional[typing_extensions.Literal["double","sint64","uint64","bool","string","bytes","double_list","sint_list","uint_list","bool_list","string_list","bytes_list"]]: ...
196
- global___ConfigsRecordValue = ConfigsRecordValue
196
+ global___ConfigRecordValue = ConfigRecordValue
197
197
 
198
- class ParametersRecord(google.protobuf.message.Message):
198
+ class ArrayRecord(google.protobuf.message.Message):
199
199
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
200
200
  DATA_KEYS_FIELD_NUMBER: builtins.int
201
201
  DATA_VALUES_FIELD_NUMBER: builtins.int
@@ -209,9 +209,9 @@ class ParametersRecord(google.protobuf.message.Message):
209
209
  data_values: typing.Optional[typing.Iterable[global___Array]] = ...,
210
210
  ) -> None: ...
211
211
  def ClearField(self, field_name: typing_extensions.Literal["data_keys",b"data_keys","data_values",b"data_values"]) -> None: ...
212
- global___ParametersRecord = ParametersRecord
212
+ global___ArrayRecord = ArrayRecord
213
213
 
214
- class MetricsRecord(google.protobuf.message.Message):
214
+ class MetricRecord(google.protobuf.message.Message):
215
215
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
216
216
  class DataEntry(google.protobuf.message.Message):
217
217
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
@@ -219,26 +219,26 @@ class MetricsRecord(google.protobuf.message.Message):
219
219
  VALUE_FIELD_NUMBER: builtins.int
220
220
  key: typing.Text
221
221
  @property
222
- def value(self) -> global___MetricsRecordValue: ...
222
+ def value(self) -> global___MetricRecordValue: ...
223
223
  def __init__(self,
224
224
  *,
225
225
  key: typing.Text = ...,
226
- value: typing.Optional[global___MetricsRecordValue] = ...,
226
+ value: typing.Optional[global___MetricRecordValue] = ...,
227
227
  ) -> None: ...
228
228
  def HasField(self, field_name: typing_extensions.Literal["value",b"value"]) -> builtins.bool: ...
229
229
  def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ...
230
230
 
231
231
  DATA_FIELD_NUMBER: builtins.int
232
232
  @property
233
- def data(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, global___MetricsRecordValue]: ...
233
+ def data(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, global___MetricRecordValue]: ...
234
234
  def __init__(self,
235
235
  *,
236
- data: typing.Optional[typing.Mapping[typing.Text, global___MetricsRecordValue]] = ...,
236
+ data: typing.Optional[typing.Mapping[typing.Text, global___MetricRecordValue]] = ...,
237
237
  ) -> None: ...
238
238
  def ClearField(self, field_name: typing_extensions.Literal["data",b"data"]) -> None: ...
239
- global___MetricsRecord = MetricsRecord
239
+ global___MetricRecord = MetricRecord
240
240
 
241
- class ConfigsRecord(google.protobuf.message.Message):
241
+ class ConfigRecord(google.protobuf.message.Message):
242
242
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
243
243
  class DataEntry(google.protobuf.message.Message):
244
244
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
@@ -246,38 +246,38 @@ class ConfigsRecord(google.protobuf.message.Message):
246
246
  VALUE_FIELD_NUMBER: builtins.int
247
247
  key: typing.Text
248
248
  @property
249
- def value(self) -> global___ConfigsRecordValue: ...
249
+ def value(self) -> global___ConfigRecordValue: ...
250
250
  def __init__(self,
251
251
  *,
252
252
  key: typing.Text = ...,
253
- value: typing.Optional[global___ConfigsRecordValue] = ...,
253
+ value: typing.Optional[global___ConfigRecordValue] = ...,
254
254
  ) -> None: ...
255
255
  def HasField(self, field_name: typing_extensions.Literal["value",b"value"]) -> builtins.bool: ...
256
256
  def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ...
257
257
 
258
258
  DATA_FIELD_NUMBER: builtins.int
259
259
  @property
260
- def data(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, global___ConfigsRecordValue]: ...
260
+ def data(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, global___ConfigRecordValue]: ...
261
261
  def __init__(self,
262
262
  *,
263
- data: typing.Optional[typing.Mapping[typing.Text, global___ConfigsRecordValue]] = ...,
263
+ data: typing.Optional[typing.Mapping[typing.Text, global___ConfigRecordValue]] = ...,
264
264
  ) -> None: ...
265
265
  def ClearField(self, field_name: typing_extensions.Literal["data",b"data"]) -> None: ...
266
- global___ConfigsRecord = ConfigsRecord
266
+ global___ConfigRecord = ConfigRecord
267
267
 
268
- class RecordSet(google.protobuf.message.Message):
268
+ class RecordDict(google.protobuf.message.Message):
269
269
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
270
- class ParametersEntry(google.protobuf.message.Message):
270
+ class ArraysEntry(google.protobuf.message.Message):
271
271
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
272
272
  KEY_FIELD_NUMBER: builtins.int
273
273
  VALUE_FIELD_NUMBER: builtins.int
274
274
  key: typing.Text
275
275
  @property
276
- def value(self) -> global___ParametersRecord: ...
276
+ def value(self) -> global___ArrayRecord: ...
277
277
  def __init__(self,
278
278
  *,
279
279
  key: typing.Text = ...,
280
- value: typing.Optional[global___ParametersRecord] = ...,
280
+ value: typing.Optional[global___ArrayRecord] = ...,
281
281
  ) -> None: ...
282
282
  def HasField(self, field_name: typing_extensions.Literal["value",b"value"]) -> builtins.bool: ...
283
283
  def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ...
@@ -288,11 +288,11 @@ class RecordSet(google.protobuf.message.Message):
288
288
  VALUE_FIELD_NUMBER: builtins.int
289
289
  key: typing.Text
290
290
  @property
291
- def value(self) -> global___MetricsRecord: ...
291
+ def value(self) -> global___MetricRecord: ...
292
292
  def __init__(self,
293
293
  *,
294
294
  key: typing.Text = ...,
295
- value: typing.Optional[global___MetricsRecord] = ...,
295
+ value: typing.Optional[global___MetricRecord] = ...,
296
296
  ) -> None: ...
297
297
  def HasField(self, field_name: typing_extensions.Literal["value",b"value"]) -> builtins.bool: ...
298
298
  def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ...
@@ -303,29 +303,29 @@ class RecordSet(google.protobuf.message.Message):
303
303
  VALUE_FIELD_NUMBER: builtins.int
304
304
  key: typing.Text
305
305
  @property
306
- def value(self) -> global___ConfigsRecord: ...
306
+ def value(self) -> global___ConfigRecord: ...
307
307
  def __init__(self,
308
308
  *,
309
309
  key: typing.Text = ...,
310
- value: typing.Optional[global___ConfigsRecord] = ...,
310
+ value: typing.Optional[global___ConfigRecord] = ...,
311
311
  ) -> None: ...
312
312
  def HasField(self, field_name: typing_extensions.Literal["value",b"value"]) -> builtins.bool: ...
313
313
  def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ...
314
314
 
315
- PARAMETERS_FIELD_NUMBER: builtins.int
315
+ ARRAYS_FIELD_NUMBER: builtins.int
316
316
  METRICS_FIELD_NUMBER: builtins.int
317
317
  CONFIGS_FIELD_NUMBER: builtins.int
318
318
  @property
319
- def parameters(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, global___ParametersRecord]: ...
319
+ def arrays(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, global___ArrayRecord]: ...
320
320
  @property
321
- def metrics(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, global___MetricsRecord]: ...
321
+ def metrics(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, global___MetricRecord]: ...
322
322
  @property
323
- def configs(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, global___ConfigsRecord]: ...
323
+ def configs(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, global___ConfigRecord]: ...
324
324
  def __init__(self,
325
325
  *,
326
- parameters: typing.Optional[typing.Mapping[typing.Text, global___ParametersRecord]] = ...,
327
- metrics: typing.Optional[typing.Mapping[typing.Text, global___MetricsRecord]] = ...,
328
- configs: typing.Optional[typing.Mapping[typing.Text, global___ConfigsRecord]] = ...,
326
+ arrays: typing.Optional[typing.Mapping[typing.Text, global___ArrayRecord]] = ...,
327
+ metrics: typing.Optional[typing.Mapping[typing.Text, global___MetricRecord]] = ...,
328
+ configs: typing.Optional[typing.Mapping[typing.Text, global___ConfigRecord]] = ...,
329
329
  ) -> None: ...
330
- def ClearField(self, field_name: typing_extensions.Literal["configs",b"configs","metrics",b"metrics","parameters",b"parameters"]) -> None: ...
331
- global___RecordSet = RecordSet
330
+ def ClearField(self, field_name: typing_extensions.Literal["arrays",b"arrays","configs",b"configs","metrics",b"metrics"]) -> None: ...
331
+ global___RecordDict = RecordDict
flwr/proto/run_pb2.py CHANGED
@@ -14,11 +14,11 @@ _sym_db = _symbol_database.Default()
14
14
 
15
15
  from flwr.proto import fab_pb2 as flwr_dot_proto_dot_fab__pb2
16
16
  from flwr.proto import node_pb2 as flwr_dot_proto_dot_node__pb2
17
- from flwr.proto import recordset_pb2 as flwr_dot_proto_dot_recordset__pb2
17
+ from flwr.proto import recorddict_pb2 as flwr_dot_proto_dot_recorddict__pb2
18
18
  from flwr.proto import transport_pb2 as flwr_dot_proto_dot_transport__pb2
19
19
 
20
20
 
21
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/run.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x1a\x66lwr/proto/recordset.proto\x1a\x1a\x66lwr/proto/transport.proto\"\xce\x02\n\x03Run\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x0e\n\x06\x66\x61\x62_id\x18\x02 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x03 \x01(\t\x12<\n\x0foverride_config\x18\x04 \x03(\x0b\x32#.flwr.proto.Run.OverrideConfigEntry\x12\x10\n\x08\x66\x61\x62_hash\x18\x05 \x01(\t\x12\x12\n\npending_at\x18\x06 \x01(\t\x12\x13\n\x0bstarting_at\x18\x07 \x01(\t\x12\x12\n\nrunning_at\x18\x08 \x01(\t\x12\x13\n\x0b\x66inished_at\x18\t \x01(\t\x12%\n\x06status\x18\n \x01(\x0b\x32\x15.flwr.proto.RunStatus\x1aI\n\x13OverrideConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"@\n\tRunStatus\x12\x0e\n\x06status\x18\x01 \x01(\t\x12\x12\n\nsub_status\x18\x02 \x01(\t\x12\x0f\n\x07\x64\x65tails\x18\x03 \x01(\t\"\xeb\x01\n\x10\x43reateRunRequest\x12\x0e\n\x06\x66\x61\x62_id\x18\x01 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x02 \x01(\t\x12I\n\x0foverride_config\x18\x03 \x03(\x0b\x32\x30.flwr.proto.CreateRunRequest.OverrideConfigEntry\x12\x1c\n\x03\x66\x61\x62\x18\x04 \x01(\x0b\x32\x0f.flwr.proto.Fab\x1aI\n\x13OverrideConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"#\n\x11\x43reateRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"?\n\rGetRunRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0e\n\x06run_id\x18\x02 \x01(\x04\".\n\x0eGetRunResponse\x12\x1c\n\x03run\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Run\"S\n\x16UpdateRunStatusRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12)\n\nrun_status\x18\x02 \x01(\x0b\x32\x15.flwr.proto.RunStatus\"\x19\n\x17UpdateRunStatusResponse\"F\n\x13GetRunStatusRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0f\n\x07run_ids\x18\x02 \x03(\x04\"\xb1\x01\n\x14GetRunStatusResponse\x12L\n\x0frun_status_dict\x18\x01 \x03(\x0b\x32\x33.flwr.proto.GetRunStatusResponse.RunStatusDictEntry\x1aK\n\x12RunStatusDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.flwr.proto.RunStatus:\x02\x38\x01\"-\n\x1bGetFederationOptionsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"U\n\x1cGetFederationOptionsResponse\x12\x35\n\x12\x66\x65\x64\x65ration_options\x18\x01 \x01(\x0b\x32\x19.flwr.proto.ConfigsRecordb\x06proto3')
21
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/run.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x1b\x66lwr/proto/recorddict.proto\x1a\x1a\x66lwr/proto/transport.proto\"\xce\x02\n\x03Run\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x0e\n\x06\x66\x61\x62_id\x18\x02 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x03 \x01(\t\x12<\n\x0foverride_config\x18\x04 \x03(\x0b\x32#.flwr.proto.Run.OverrideConfigEntry\x12\x10\n\x08\x66\x61\x62_hash\x18\x05 \x01(\t\x12\x12\n\npending_at\x18\x06 \x01(\t\x12\x13\n\x0bstarting_at\x18\x07 \x01(\t\x12\x12\n\nrunning_at\x18\x08 \x01(\t\x12\x13\n\x0b\x66inished_at\x18\t \x01(\t\x12%\n\x06status\x18\n \x01(\x0b\x32\x15.flwr.proto.RunStatus\x1aI\n\x13OverrideConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"@\n\tRunStatus\x12\x0e\n\x06status\x18\x01 \x01(\t\x12\x12\n\nsub_status\x18\x02 \x01(\t\x12\x0f\n\x07\x64\x65tails\x18\x03 \x01(\t\"\xeb\x01\n\x10\x43reateRunRequest\x12\x0e\n\x06\x66\x61\x62_id\x18\x01 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x02 \x01(\t\x12I\n\x0foverride_config\x18\x03 \x03(\x0b\x32\x30.flwr.proto.CreateRunRequest.OverrideConfigEntry\x12\x1c\n\x03\x66\x61\x62\x18\x04 \x01(\x0b\x32\x0f.flwr.proto.Fab\x1aI\n\x13OverrideConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"#\n\x11\x43reateRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"?\n\rGetRunRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0e\n\x06run_id\x18\x02 \x01(\x04\".\n\x0eGetRunResponse\x12\x1c\n\x03run\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Run\"S\n\x16UpdateRunStatusRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12)\n\nrun_status\x18\x02 \x01(\x0b\x32\x15.flwr.proto.RunStatus\"\x19\n\x17UpdateRunStatusResponse\"F\n\x13GetRunStatusRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0f\n\x07run_ids\x18\x02 \x03(\x04\"\xb1\x01\n\x14GetRunStatusResponse\x12L\n\x0frun_status_dict\x18\x01 \x03(\x0b\x32\x33.flwr.proto.GetRunStatusResponse.RunStatusDictEntry\x1aK\n\x12RunStatusDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.flwr.proto.RunStatus:\x02\x38\x01\"-\n\x1bGetFederationOptionsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"T\n\x1cGetFederationOptionsResponse\x12\x34\n\x12\x66\x65\x64\x65ration_options\x18\x01 \x01(\x0b\x32\x18.flwr.proto.ConfigRecordb\x06proto3')
22
22
 
23
23
  _globals = globals()
24
24
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -31,34 +31,34 @@ if _descriptor._USE_C_DESCRIPTORS == False:
31
31
  _globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_options = b'8\001'
32
32
  _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._options = None
33
33
  _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_options = b'8\001'
34
- _globals['_RUN']._serialized_start=138
35
- _globals['_RUN']._serialized_end=472
36
- _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_start=399
37
- _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_end=472
38
- _globals['_RUNSTATUS']._serialized_start=474
39
- _globals['_RUNSTATUS']._serialized_end=538
40
- _globals['_CREATERUNREQUEST']._serialized_start=541
41
- _globals['_CREATERUNREQUEST']._serialized_end=776
42
- _globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=399
43
- _globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=472
44
- _globals['_CREATERUNRESPONSE']._serialized_start=778
45
- _globals['_CREATERUNRESPONSE']._serialized_end=813
46
- _globals['_GETRUNREQUEST']._serialized_start=815
47
- _globals['_GETRUNREQUEST']._serialized_end=878
48
- _globals['_GETRUNRESPONSE']._serialized_start=880
49
- _globals['_GETRUNRESPONSE']._serialized_end=926
50
- _globals['_UPDATERUNSTATUSREQUEST']._serialized_start=928
51
- _globals['_UPDATERUNSTATUSREQUEST']._serialized_end=1011
52
- _globals['_UPDATERUNSTATUSRESPONSE']._serialized_start=1013
53
- _globals['_UPDATERUNSTATUSRESPONSE']._serialized_end=1038
54
- _globals['_GETRUNSTATUSREQUEST']._serialized_start=1040
55
- _globals['_GETRUNSTATUSREQUEST']._serialized_end=1110
56
- _globals['_GETRUNSTATUSRESPONSE']._serialized_start=1113
57
- _globals['_GETRUNSTATUSRESPONSE']._serialized_end=1290
58
- _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_start=1215
59
- _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_end=1290
60
- _globals['_GETFEDERATIONOPTIONSREQUEST']._serialized_start=1292
61
- _globals['_GETFEDERATIONOPTIONSREQUEST']._serialized_end=1337
62
- _globals['_GETFEDERATIONOPTIONSRESPONSE']._serialized_start=1339
34
+ _globals['_RUN']._serialized_start=139
35
+ _globals['_RUN']._serialized_end=473
36
+ _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_start=400
37
+ _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_end=473
38
+ _globals['_RUNSTATUS']._serialized_start=475
39
+ _globals['_RUNSTATUS']._serialized_end=539
40
+ _globals['_CREATERUNREQUEST']._serialized_start=542
41
+ _globals['_CREATERUNREQUEST']._serialized_end=777
42
+ _globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=400
43
+ _globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=473
44
+ _globals['_CREATERUNRESPONSE']._serialized_start=779
45
+ _globals['_CREATERUNRESPONSE']._serialized_end=814
46
+ _globals['_GETRUNREQUEST']._serialized_start=816
47
+ _globals['_GETRUNREQUEST']._serialized_end=879
48
+ _globals['_GETRUNRESPONSE']._serialized_start=881
49
+ _globals['_GETRUNRESPONSE']._serialized_end=927
50
+ _globals['_UPDATERUNSTATUSREQUEST']._serialized_start=929
51
+ _globals['_UPDATERUNSTATUSREQUEST']._serialized_end=1012
52
+ _globals['_UPDATERUNSTATUSRESPONSE']._serialized_start=1014
53
+ _globals['_UPDATERUNSTATUSRESPONSE']._serialized_end=1039
54
+ _globals['_GETRUNSTATUSREQUEST']._serialized_start=1041
55
+ _globals['_GETRUNSTATUSREQUEST']._serialized_end=1111
56
+ _globals['_GETRUNSTATUSRESPONSE']._serialized_start=1114
57
+ _globals['_GETRUNSTATUSRESPONSE']._serialized_end=1291
58
+ _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_start=1216
59
+ _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_end=1291
60
+ _globals['_GETFEDERATIONOPTIONSREQUEST']._serialized_start=1293
61
+ _globals['_GETFEDERATIONOPTIONSREQUEST']._serialized_end=1338
62
+ _globals['_GETFEDERATIONOPTIONSRESPONSE']._serialized_start=1340
63
63
  _globals['_GETFEDERATIONOPTIONSRESPONSE']._serialized_end=1424
64
64
  # @@protoc_insertion_point(module_scope)
flwr/proto/run_pb2.pyi CHANGED
@@ -5,7 +5,7 @@ isort:skip_file
5
5
  import builtins
6
6
  import flwr.proto.fab_pb2
7
7
  import flwr.proto.node_pb2
8
- import flwr.proto.recordset_pb2
8
+ import flwr.proto.recorddict_pb2
9
9
  import flwr.proto.transport_pb2
10
10
  import google.protobuf.descriptor
11
11
  import google.protobuf.internal.containers
@@ -258,10 +258,10 @@ class GetFederationOptionsResponse(google.protobuf.message.Message):
258
258
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
259
259
  FEDERATION_OPTIONS_FIELD_NUMBER: builtins.int
260
260
  @property
261
- def federation_options(self) -> flwr.proto.recordset_pb2.ConfigsRecord: ...
261
+ def federation_options(self) -> flwr.proto.recorddict_pb2.ConfigRecord: ...
262
262
  def __init__(self,
263
263
  *,
264
- federation_options: typing.Optional[flwr.proto.recordset_pb2.ConfigsRecord] = ...,
264
+ federation_options: typing.Optional[flwr.proto.recorddict_pb2.ConfigRecord] = ...,
265
265
  ) -> None: ...
266
266
  def HasField(self, field_name: typing_extensions.Literal["federation_options",b"federation_options"]) -> builtins.bool: ...
267
267
  def ClearField(self, field_name: typing_extensions.Literal["federation_options",b"federation_options"]) -> None: ...
flwr/server/__init__.py CHANGED
@@ -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.
@@ -21,7 +21,8 @@ from .app import start_server as start_server
21
21
  from .client_manager import ClientManager as ClientManager
22
22
  from .client_manager import SimpleClientManager as SimpleClientManager
23
23
  from .compat import LegacyContext as LegacyContext
24
- from .driver import Driver as Driver
24
+ from .grid import Driver as Driver
25
+ from .grid import Grid as Grid
25
26
  from .history import History as History
26
27
  from .server import Server as Server
27
28
  from .server_app import ServerApp as ServerApp
@@ -31,6 +32,7 @@ from .serverapp_components import ServerAppComponents as ServerAppComponents
31
32
  __all__ = [
32
33
  "ClientManager",
33
34
  "Driver",
35
+ "Grid",
34
36
  "History",
35
37
  "LegacyContext",
36
38
  "Server",
flwr/server/app.py CHANGED
@@ -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.
@@ -54,7 +54,9 @@ from flwr.common.constant import (
54
54
  TRANSPORT_TYPE_GRPC_ADAPTER,
55
55
  TRANSPORT_TYPE_GRPC_RERE,
56
56
  TRANSPORT_TYPE_REST,
57
+ EventLogWriterType,
57
58
  )
59
+ from flwr.common.event_log_plugin import EventLogWriterPlugin
58
60
  from flwr.common.exit import ExitCode, flwr_exit
59
61
  from flwr.common.exit_handlers import register_exit_handlers
60
62
  from flwr.common.grpc import generic_create_grpc_server
@@ -66,6 +68,7 @@ from flwr.proto.fleet_pb2_grpc import ( # pylint: disable=E0611
66
68
  add_FleetServicer_to_server,
67
69
  )
68
70
  from flwr.proto.grpcadapter_pb2_grpc import add_GrpcAdapterServicer_to_server
71
+ from flwr.server.fleet_event_log_interceptor import FleetEventLogInterceptor
69
72
  from flwr.server.serverapp.app import flwr_serverapp
70
73
  from flwr.simulation.app import flwr_simulation
71
74
  from flwr.superexec.app import load_executor
@@ -76,13 +79,13 @@ from .history import History
76
79
  from .server import Server, init_defaults, run_fl
77
80
  from .server_config import ServerConfig
78
81
  from .strategy import Strategy
79
- from .superlink.driver.serverappio_grpc import run_serverappio_api_grpc
80
82
  from .superlink.ffs.ffs_factory import FfsFactory
81
83
  from .superlink.fleet.grpc_adapter.grpc_adapter_servicer import GrpcAdapterServicer
82
84
  from .superlink.fleet.grpc_bidi.grpc_server import start_grpc_server
83
85
  from .superlink.fleet.grpc_rere.fleet_servicer import FleetServicer
84
86
  from .superlink.fleet.grpc_rere.server_interceptor import AuthenticateServerInterceptor
85
87
  from .superlink.linkstate import LinkStateFactory
88
+ from .superlink.serverappio.serverappio_grpc import run_serverappio_api_grpc
86
89
  from .superlink.simulation.simulationio_grpc import run_simulationio_api_grpc
87
90
 
88
91
  DATABASE = ":flwr-in-memory-state:"
@@ -94,6 +97,8 @@ try:
94
97
  add_ee_args_superlink,
95
98
  get_dashboard_server,
96
99
  get_exec_auth_plugins,
100
+ get_exec_event_log_writer_plugins,
101
+ get_fleet_event_log_writer_plugins,
97
102
  )
98
103
  except ImportError:
99
104
 
@@ -105,6 +110,18 @@ except ImportError:
105
110
  """Return all Exec API authentication plugins."""
106
111
  raise NotImplementedError("No authentication plugins are currently supported.")
107
112
 
113
+ def get_exec_event_log_writer_plugins() -> dict[str, type[EventLogWriterPlugin]]:
114
+ """Return all Exec API event log writer plugins."""
115
+ raise NotImplementedError(
116
+ "No event log writer plugins are currently supported."
117
+ )
118
+
119
+ def get_fleet_event_log_writer_plugins() -> dict[str, type[EventLogWriterPlugin]]:
120
+ """Return all Fleet API event log writer plugins."""
121
+ raise NotImplementedError(
122
+ "No event log writer plugins are currently supported."
123
+ )
124
+
108
125
 
109
126
  def start_server( # pylint: disable=too-many-arguments,too-many-locals
110
127
  *,
@@ -166,19 +183,19 @@ def start_server( # pylint: disable=too-many-arguments,too-many-locals
166
183
 
167
184
  Examples
168
185
  --------
169
- Starting an insecure server:
186
+ Starting an insecure server::
170
187
 
171
- >>> start_server()
188
+ start_server()
172
189
 
173
- Starting an SSL-enabled server:
190
+ Starting a TLS-enabled server::
174
191
 
175
- >>> start_server(
176
- >>> certificates=(
177
- >>> Path("/crts/root.pem").read_bytes(),
178
- >>> Path("/crts/localhost.crt").read_bytes(),
179
- >>> Path("/crts/localhost.key").read_bytes()
180
- >>> )
181
- >>> )
192
+ start_server(
193
+ certificates=(
194
+ Path("/crts/root.pem").read_bytes(),
195
+ Path("/crts/localhost.crt").read_bytes(),
196
+ Path("/crts/localhost.key").read_bytes()
197
+ )
198
+ )
182
199
  """
183
200
  msg = (
184
201
  "flwr.server.start_server() is deprecated."
@@ -276,9 +293,13 @@ def run_superlink() -> None:
276
293
  verify_tls_cert = not getattr(args, "disable_oidc_tls_cert_verification", None)
277
294
 
278
295
  auth_plugin: Optional[ExecAuthPlugin] = None
296
+ event_log_plugin: Optional[EventLogWriterPlugin] = None
279
297
  # Load the auth plugin if the args.user_auth_config is provided
280
298
  if cfg_path := getattr(args, "user_auth_config", None):
281
299
  auth_plugin = _try_obtain_exec_auth_plugin(Path(cfg_path), verify_tls_cert)
300
+ # Enable event logging if the args.enable_event_log is True
301
+ if args.enable_event_log:
302
+ event_log_plugin = _try_obtain_exec_event_log_writer_plugin()
282
303
 
283
304
  # Initialize StateFactory
284
305
  state_factory = LinkStateFactory(args.database)
@@ -298,6 +319,7 @@ def run_superlink() -> None:
298
319
  [args.executor_config] if args.executor_config else args.executor_config
299
320
  ),
300
321
  auth_plugin=auth_plugin,
322
+ event_log_plugin=event_log_plugin,
301
323
  )
302
324
  grpc_servers = [exec_server]
303
325
 
@@ -389,6 +411,11 @@ def run_superlink() -> None:
389
411
  log(DEBUG, "Automatic node authentication enabled")
390
412
 
391
413
  interceptors = [AuthenticateServerInterceptor(state_factory, auto_auth)]
414
+ if getattr(args, "enable_event_log", None):
415
+ fleet_log_plugin = _try_obtain_fleet_event_log_writer_plugin()
416
+ if fleet_log_plugin is not None:
417
+ interceptors.append(FleetEventLogInterceptor(fleet_log_plugin))
418
+ log(INFO, "Flower Fleet event logging enabled")
392
419
 
393
420
  fleet_server = _run_fleet_api_grpc_rere(
394
421
  address=fleet_address,
@@ -613,6 +640,34 @@ def _try_obtain_exec_auth_plugin(
613
640
  sys.exit("No authentication plugins are currently supported.")
614
641
 
615
642
 
643
+ def _try_obtain_exec_event_log_writer_plugin() -> Optional[EventLogWriterPlugin]:
644
+ """Return an instance of the event log writer plugin."""
645
+ try:
646
+ all_plugins: dict[str, type[EventLogWriterPlugin]] = (
647
+ get_exec_event_log_writer_plugins()
648
+ )
649
+ plugin_class = all_plugins[EventLogWriterType.STDOUT]
650
+ return plugin_class()
651
+ except KeyError:
652
+ sys.exit("No event log writer plugin is provided.")
653
+ except NotImplementedError:
654
+ sys.exit("No event log writer plugins are currently supported.")
655
+
656
+
657
+ def _try_obtain_fleet_event_log_writer_plugin() -> Optional[EventLogWriterPlugin]:
658
+ """Return an instance of the Fleet Servicer event log writer plugin."""
659
+ try:
660
+ all_plugins: dict[str, type[EventLogWriterPlugin]] = (
661
+ get_fleet_event_log_writer_plugins()
662
+ )
663
+ plugin_class = all_plugins[EventLogWriterType.STDOUT]
664
+ return plugin_class()
665
+ except KeyError:
666
+ sys.exit("No Fleet API event log writer plugin is provided.")
667
+ except NotImplementedError:
668
+ sys.exit("No Fleet API event log writer plugins are currently supported.")
669
+
670
+
616
671
  def _run_fleet_api_grpc_rere(
617
672
  address: str,
618
673
  state_factory: LinkStateFactory,
@@ -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 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,10 +15,10 @@
15
15
  """Flower ServerApp compatibility package."""
16
16
 
17
17
 
18
- from .app import start_driver as start_driver
18
+ from .app import start_grid as start_grid
19
19
  from .legacy_context import LegacyContext as LegacyContext
20
20
 
21
21
  __all__ = [
22
22
  "LegacyContext",
23
- "start_driver",
23
+ "start_grid",
24
24
  ]
flwr/server/compat/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.
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  # ==============================================================================
15
- """Flower driver app."""
15
+ """Flower grid app."""
16
16
 
17
17
 
18
18
  from logging import INFO
@@ -25,27 +25,27 @@ from flwr.server.server import Server, init_defaults, run_fl
25
25
  from flwr.server.server_config import ServerConfig
26
26
  from flwr.server.strategy import Strategy
27
27
 
28
- from ..driver import Driver
28
+ from ..grid import Grid
29
29
  from .app_utils import start_update_client_manager_thread
30
30
 
31
31
 
32
- def start_driver( # pylint: disable=too-many-arguments, too-many-locals
32
+ def start_grid( # pylint: disable=too-many-arguments, too-many-locals
33
33
  *,
34
- driver: Driver,
34
+ grid: Grid,
35
35
  server: Optional[Server] = None,
36
36
  config: Optional[ServerConfig] = None,
37
37
  strategy: Optional[Strategy] = None,
38
38
  client_manager: Optional[ClientManager] = None,
39
39
  ) -> History:
40
- """Start a Flower Driver API server.
40
+ """Start a Flower server.
41
41
 
42
42
  Parameters
43
43
  ----------
44
- driver : Driver
45
- The Driver object to use.
44
+ grid : Grid
45
+ The Grid object to use.
46
46
  server : Optional[flwr.server.Server] (default: None)
47
47
  A server implementation, either `flwr.server.Server` or a subclass
48
- thereof. If no instance is provided, then `start_driver` will create
48
+ thereof. If no instance is provided, then `start_grid` will create
49
49
  one.
50
50
  config : Optional[ServerConfig] (default: None)
51
51
  Currently supported values are `num_rounds` (int, default: 1) and
@@ -56,7 +56,7 @@ def start_driver( # pylint: disable=too-many-arguments, too-many-locals
56
56
  `start_server` will use `flwr.server.strategy.FedAvg`.
57
57
  client_manager : Optional[flwr.server.ClientManager] (default: None)
58
58
  An implementation of the class `flwr.server.ClientManager`. If no
59
- implementation is provided, then `start_driver` will use
59
+ implementation is provided, then `start_grid` will use
60
60
  `flwr.server.SimpleClientManager`.
61
61
 
62
62
  Returns
@@ -64,7 +64,7 @@ def start_driver( # pylint: disable=too-many-arguments, too-many-locals
64
64
  hist : flwr.server.history.History
65
65
  Object containing training and evaluation metrics.
66
66
  """
67
- # Initialize the Driver API server and config
67
+ # Initialize the server and config
68
68
  initialized_server, initialized_config = init_defaults(
69
69
  server=server,
70
70
  config=config,
@@ -80,7 +80,7 @@ def start_driver( # pylint: disable=too-many-arguments, too-many-locals
80
80
 
81
81
  # Start the thread updating nodes
82
82
  thread, f_stop, c_done = start_update_client_manager_thread(
83
- driver, initialized_server.client_manager()
83
+ grid, initialized_server.client_manager()
84
84
  )
85
85
 
86
86
  # Wait until the node registration done