flwr 1.22.0__py3-none-any.whl → 1.24.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 (301) hide show
  1. flwr/__init__.py +16 -5
  2. flwr/app/error.py +2 -2
  3. flwr/app/exception.py +3 -3
  4. flwr/cli/app.py +34 -1
  5. flwr/cli/app_cmd/__init__.py +23 -0
  6. flwr/cli/app_cmd/publish.py +285 -0
  7. flwr/cli/app_cmd/review.py +252 -0
  8. flwr/cli/auth_plugin/__init__.py +15 -6
  9. flwr/cli/auth_plugin/auth_plugin.py +94 -0
  10. flwr/cli/auth_plugin/noop_auth_plugin.py +101 -0
  11. flwr/cli/auth_plugin/oidc_cli_plugin.py +46 -32
  12. flwr/cli/build.py +166 -53
  13. flwr/cli/{cli_user_auth_interceptor.py → cli_account_auth_interceptor.py} +29 -11
  14. flwr/cli/config_utils.py +101 -13
  15. flwr/cli/federation/__init__.py +24 -0
  16. flwr/cli/federation/ls.py +140 -0
  17. flwr/cli/federation/show.py +317 -0
  18. flwr/cli/install.py +91 -13
  19. flwr/cli/log.py +54 -11
  20. flwr/cli/login/login.py +41 -27
  21. flwr/cli/ls.py +177 -133
  22. flwr/cli/new/new.py +175 -40
  23. flwr/cli/new/templates/app/code/task.pytorch.py.tpl +1 -0
  24. flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +1 -1
  25. flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +1 -1
  26. flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +1 -1
  27. flwr/cli/new/templates/app/pyproject.jax.toml.tpl +1 -1
  28. flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +1 -1
  29. flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +1 -1
  30. flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +3 -3
  31. flwr/cli/new/templates/app/pyproject.pytorch_legacy_api.toml.tpl +1 -1
  32. flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +1 -1
  33. flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +2 -2
  34. flwr/cli/new/templates/app/pyproject.xgboost.toml.tpl +1 -1
  35. flwr/cli/pull.py +12 -7
  36. flwr/cli/run/run.py +82 -31
  37. flwr/cli/run_utils.py +130 -0
  38. flwr/cli/stop.py +27 -9
  39. flwr/cli/supernode/__init__.py +25 -0
  40. flwr/cli/supernode/ls.py +268 -0
  41. flwr/cli/supernode/register.py +190 -0
  42. flwr/cli/supernode/unregister.py +140 -0
  43. flwr/cli/utils.py +464 -81
  44. flwr/client/__init__.py +2 -1
  45. flwr/client/dpfedavg_numpy_client.py +4 -1
  46. flwr/client/grpc_adapter_client/connection.py +12 -15
  47. flwr/client/grpc_rere_client/connection.py +68 -41
  48. flwr/client/grpc_rere_client/grpc_adapter.py +34 -14
  49. flwr/client/grpc_rere_client/{client_interceptor.py → node_auth_client_interceptor.py} +5 -7
  50. flwr/client/message_handler/message_handler.py +2 -2
  51. flwr/client/mod/secure_aggregation/secaggplus_mod.py +10 -8
  52. flwr/client/numpy_client.py +1 -1
  53. flwr/client/rest_client/connection.py +94 -51
  54. flwr/client/run_info_store.py +4 -5
  55. flwr/client/typing.py +1 -1
  56. flwr/clientapp/__init__.py +1 -2
  57. flwr/{client → clientapp}/client_app.py +9 -10
  58. flwr/clientapp/mod/centraldp_mods.py +16 -17
  59. flwr/clientapp/mod/localdp_mod.py +8 -9
  60. flwr/clientapp/typing.py +1 -1
  61. flwr/{client/clientapp → clientapp}/utils.py +4 -4
  62. flwr/common/address.py +1 -2
  63. flwr/common/args.py +3 -4
  64. flwr/common/config.py +13 -16
  65. flwr/common/constant.py +56 -13
  66. flwr/common/differential_privacy.py +3 -4
  67. flwr/common/event_log_plugin/event_log_plugin.py +3 -4
  68. flwr/common/exit/exit.py +15 -2
  69. flwr/common/exit/exit_code.py +39 -10
  70. flwr/common/exit/exit_handler.py +6 -2
  71. flwr/common/exit/signal_handler.py +5 -5
  72. flwr/common/grpc.py +6 -6
  73. flwr/common/inflatable_protobuf_utils.py +1 -1
  74. flwr/common/inflatable_utils.py +48 -31
  75. flwr/common/logger.py +19 -19
  76. flwr/common/message.py +4 -4
  77. flwr/common/object_ref.py +7 -7
  78. flwr/common/record/array.py +6 -6
  79. flwr/common/record/arrayrecord.py +18 -21
  80. flwr/common/record/configrecord.py +3 -3
  81. flwr/common/record/recorddict.py +5 -5
  82. flwr/common/record/typeddict.py +9 -2
  83. flwr/common/recorddict_compat.py +7 -10
  84. flwr/common/retry_invoker.py +20 -20
  85. flwr/common/secure_aggregation/crypto/symmetric_encryption.py +1 -89
  86. flwr/common/secure_aggregation/ndarrays_arithmetic.py +3 -3
  87. flwr/common/serde.py +9 -6
  88. flwr/common/serde_utils.py +2 -2
  89. flwr/common/telemetry.py +9 -5
  90. flwr/common/typing.py +59 -43
  91. flwr/compat/client/app.py +39 -38
  92. flwr/compat/client/grpc_client/connection.py +13 -13
  93. flwr/compat/server/app.py +5 -6
  94. flwr/proto/appio_pb2.py +13 -3
  95. flwr/proto/appio_pb2.pyi +134 -65
  96. flwr/proto/appio_pb2_grpc.py +20 -0
  97. flwr/proto/appio_pb2_grpc.pyi +27 -0
  98. flwr/proto/clientappio_pb2.py +17 -7
  99. flwr/proto/clientappio_pb2.pyi +15 -0
  100. flwr/proto/clientappio_pb2_grpc.py +206 -40
  101. flwr/proto/clientappio_pb2_grpc.pyi +168 -53
  102. flwr/proto/control_pb2.py +72 -40
  103. flwr/proto/control_pb2.pyi +319 -87
  104. flwr/proto/control_pb2_grpc.py +339 -28
  105. flwr/proto/control_pb2_grpc.pyi +209 -37
  106. flwr/proto/error_pb2.py +13 -3
  107. flwr/proto/error_pb2.pyi +24 -6
  108. flwr/proto/error_pb2_grpc.py +20 -0
  109. flwr/proto/error_pb2_grpc.pyi +27 -0
  110. flwr/proto/fab_pb2.py +24 -10
  111. flwr/proto/fab_pb2.pyi +68 -20
  112. flwr/proto/fab_pb2_grpc.py +20 -0
  113. flwr/proto/fab_pb2_grpc.pyi +27 -0
  114. flwr/proto/federation_pb2.py +38 -0
  115. flwr/proto/federation_pb2.pyi +56 -0
  116. flwr/proto/federation_pb2_grpc.py +24 -0
  117. flwr/proto/federation_pb2_grpc.pyi +31 -0
  118. flwr/proto/fleet_pb2.py +45 -27
  119. flwr/proto/fleet_pb2.pyi +186 -70
  120. flwr/proto/fleet_pb2_grpc.py +277 -66
  121. flwr/proto/fleet_pb2_grpc.pyi +201 -55
  122. flwr/proto/grpcadapter_pb2.py +14 -4
  123. flwr/proto/grpcadapter_pb2.pyi +38 -16
  124. flwr/proto/grpcadapter_pb2_grpc.py +35 -4
  125. flwr/proto/grpcadapter_pb2_grpc.pyi +38 -7
  126. flwr/proto/heartbeat_pb2.py +17 -7
  127. flwr/proto/heartbeat_pb2.pyi +51 -22
  128. flwr/proto/heartbeat_pb2_grpc.py +20 -0
  129. flwr/proto/heartbeat_pb2_grpc.pyi +27 -0
  130. flwr/proto/log_pb2.py +13 -3
  131. flwr/proto/log_pb2.pyi +34 -11
  132. flwr/proto/log_pb2_grpc.py +20 -0
  133. flwr/proto/log_pb2_grpc.pyi +27 -0
  134. flwr/proto/message_pb2.py +15 -5
  135. flwr/proto/message_pb2.pyi +154 -86
  136. flwr/proto/message_pb2_grpc.py +20 -0
  137. flwr/proto/message_pb2_grpc.pyi +27 -0
  138. flwr/proto/node_pb2.py +16 -4
  139. flwr/proto/node_pb2.pyi +77 -4
  140. flwr/proto/node_pb2_grpc.py +20 -0
  141. flwr/proto/node_pb2_grpc.pyi +27 -0
  142. flwr/proto/recorddict_pb2.py +13 -3
  143. flwr/proto/recorddict_pb2.pyi +184 -107
  144. flwr/proto/recorddict_pb2_grpc.py +20 -0
  145. flwr/proto/recorddict_pb2_grpc.pyi +27 -0
  146. flwr/proto/run_pb2.py +40 -31
  147. flwr/proto/run_pb2.pyi +149 -84
  148. flwr/proto/run_pb2_grpc.py +20 -0
  149. flwr/proto/run_pb2_grpc.pyi +27 -0
  150. flwr/proto/serverappio_pb2.py +13 -3
  151. flwr/proto/serverappio_pb2.pyi +32 -8
  152. flwr/proto/serverappio_pb2_grpc.py +246 -65
  153. flwr/proto/serverappio_pb2_grpc.pyi +221 -85
  154. flwr/proto/simulationio_pb2.py +16 -8
  155. flwr/proto/simulationio_pb2.pyi +15 -0
  156. flwr/proto/simulationio_pb2_grpc.py +162 -41
  157. flwr/proto/simulationio_pb2_grpc.pyi +149 -55
  158. flwr/proto/transport_pb2.py +20 -10
  159. flwr/proto/transport_pb2.pyi +249 -160
  160. flwr/proto/transport_pb2_grpc.py +35 -4
  161. flwr/proto/transport_pb2_grpc.pyi +38 -8
  162. flwr/server/app.py +173 -127
  163. flwr/server/client_manager.py +4 -5
  164. flwr/server/client_proxy.py +10 -11
  165. flwr/server/compat/app.py +4 -5
  166. flwr/server/compat/app_utils.py +2 -1
  167. flwr/server/compat/grid_client_proxy.py +10 -12
  168. flwr/server/compat/legacy_context.py +3 -4
  169. flwr/server/fleet_event_log_interceptor.py +2 -1
  170. flwr/server/grid/grid.py +2 -3
  171. flwr/server/grid/grpc_grid.py +10 -8
  172. flwr/server/grid/inmemory_grid.py +4 -4
  173. flwr/server/run_serverapp.py +2 -3
  174. flwr/server/server.py +34 -39
  175. flwr/server/server_app.py +7 -8
  176. flwr/server/server_config.py +1 -2
  177. flwr/server/serverapp/app.py +34 -28
  178. flwr/server/serverapp_components.py +4 -5
  179. flwr/server/strategy/aggregate.py +9 -8
  180. flwr/server/strategy/bulyan.py +13 -11
  181. flwr/server/strategy/dp_adaptive_clipping.py +16 -20
  182. flwr/server/strategy/dp_fixed_clipping.py +12 -17
  183. flwr/server/strategy/dpfedavg_adaptive.py +3 -4
  184. flwr/server/strategy/dpfedavg_fixed.py +6 -10
  185. flwr/server/strategy/fault_tolerant_fedavg.py +14 -13
  186. flwr/server/strategy/fedadagrad.py +18 -14
  187. flwr/server/strategy/fedadam.py +16 -14
  188. flwr/server/strategy/fedavg.py +16 -17
  189. flwr/server/strategy/fedavg_android.py +15 -15
  190. flwr/server/strategy/fedavgm.py +21 -18
  191. flwr/server/strategy/fedmedian.py +2 -3
  192. flwr/server/strategy/fedopt.py +11 -10
  193. flwr/server/strategy/fedprox.py +10 -9
  194. flwr/server/strategy/fedtrimmedavg.py +12 -11
  195. flwr/server/strategy/fedxgb_bagging.py +13 -11
  196. flwr/server/strategy/fedxgb_cyclic.py +6 -6
  197. flwr/server/strategy/fedxgb_nn_avg.py +4 -4
  198. flwr/server/strategy/fedyogi.py +16 -14
  199. flwr/server/strategy/krum.py +12 -11
  200. flwr/server/strategy/qfedavg.py +16 -15
  201. flwr/server/strategy/strategy.py +6 -9
  202. flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +19 -8
  203. flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +1 -2
  204. flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +3 -4
  205. flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +10 -12
  206. flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +1 -3
  207. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +136 -42
  208. flwr/server/superlink/fleet/grpc_rere/{server_interceptor.py → node_auth_server_interceptor.py} +28 -51
  209. flwr/server/superlink/fleet/message_handler/message_handler.py +100 -49
  210. flwr/server/superlink/fleet/rest_rere/rest_api.py +54 -33
  211. flwr/server/superlink/fleet/vce/backend/backend.py +2 -2
  212. flwr/server/superlink/fleet/vce/backend/raybackend.py +6 -6
  213. flwr/server/superlink/fleet/vce/vce_api.py +32 -13
  214. flwr/server/superlink/linkstate/in_memory_linkstate.py +266 -207
  215. flwr/server/superlink/linkstate/linkstate.py +161 -62
  216. flwr/server/superlink/linkstate/linkstate_factory.py +24 -6
  217. flwr/server/superlink/linkstate/sqlite_linkstate.py +698 -638
  218. flwr/server/superlink/linkstate/utils.py +9 -60
  219. flwr/server/superlink/serverappio/serverappio_grpc.py +1 -2
  220. flwr/server/superlink/serverappio/serverappio_servicer.py +28 -23
  221. flwr/server/superlink/simulation/simulationio_grpc.py +1 -2
  222. flwr/server/superlink/simulation/simulationio_servicer.py +19 -14
  223. flwr/server/superlink/utils.py +4 -6
  224. flwr/server/typing.py +1 -1
  225. flwr/server/utils/tensorboard.py +15 -8
  226. flwr/server/utils/validator.py +2 -3
  227. flwr/server/workflow/default_workflows.py +5 -5
  228. flwr/server/workflow/secure_aggregation/secagg_workflow.py +2 -4
  229. flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +12 -10
  230. flwr/serverapp/strategy/bulyan.py +16 -15
  231. flwr/serverapp/strategy/dp_adaptive_clipping.py +12 -11
  232. flwr/serverapp/strategy/dp_fixed_clipping.py +11 -14
  233. flwr/serverapp/strategy/fedadagrad.py +10 -11
  234. flwr/serverapp/strategy/fedadam.py +10 -11
  235. flwr/serverapp/strategy/fedavg.py +9 -10
  236. flwr/serverapp/strategy/fedavgm.py +17 -16
  237. flwr/serverapp/strategy/fedmedian.py +2 -2
  238. flwr/serverapp/strategy/fedopt.py +10 -11
  239. flwr/serverapp/strategy/fedprox.py +7 -8
  240. flwr/serverapp/strategy/fedtrimmedavg.py +9 -9
  241. flwr/serverapp/strategy/fedxgb_bagging.py +3 -3
  242. flwr/serverapp/strategy/fedxgb_cyclic.py +9 -9
  243. flwr/serverapp/strategy/fedyogi.py +9 -11
  244. flwr/serverapp/strategy/krum.py +7 -7
  245. flwr/serverapp/strategy/multikrum.py +9 -9
  246. flwr/serverapp/strategy/qfedavg.py +17 -16
  247. flwr/serverapp/strategy/strategy.py +6 -9
  248. flwr/serverapp/strategy/strategy_utils.py +7 -8
  249. flwr/simulation/app.py +46 -42
  250. flwr/simulation/legacy_app.py +12 -12
  251. flwr/simulation/ray_transport/ray_actor.py +11 -12
  252. flwr/simulation/ray_transport/ray_client_proxy.py +12 -13
  253. flwr/simulation/run_simulation.py +44 -43
  254. flwr/simulation/simulationio_connection.py +4 -4
  255. flwr/supercore/cli/flower_superexec.py +3 -4
  256. flwr/supercore/constant.py +52 -0
  257. flwr/supercore/corestate/corestate.py +24 -3
  258. flwr/supercore/corestate/in_memory_corestate.py +138 -0
  259. flwr/supercore/corestate/sqlite_corestate.py +157 -0
  260. flwr/supercore/ffs/disk_ffs.py +1 -2
  261. flwr/supercore/ffs/ffs.py +1 -2
  262. flwr/supercore/ffs/ffs_factory.py +1 -2
  263. flwr/{common → supercore}/heartbeat.py +20 -25
  264. flwr/supercore/object_store/in_memory_object_store.py +1 -6
  265. flwr/supercore/object_store/object_store.py +1 -2
  266. flwr/supercore/object_store/object_store_factory.py +27 -8
  267. flwr/supercore/object_store/sqlite_object_store.py +253 -0
  268. flwr/{client/clientapp → supercore/primitives}/__init__.py +1 -1
  269. flwr/supercore/primitives/asymmetric.py +117 -0
  270. flwr/supercore/primitives/asymmetric_ed25519.py +175 -0
  271. flwr/supercore/sqlite_mixin.py +159 -0
  272. flwr/supercore/superexec/plugin/base_exec_plugin.py +1 -2
  273. flwr/supercore/superexec/plugin/exec_plugin.py +3 -3
  274. flwr/supercore/superexec/run_superexec.py +9 -13
  275. flwr/supercore/utils.py +20 -0
  276. flwr/superlink/artifact_provider/artifact_provider.py +1 -2
  277. flwr/{common → superlink}/auth_plugin/__init__.py +6 -6
  278. flwr/superlink/auth_plugin/auth_plugin.py +88 -0
  279. flwr/superlink/auth_plugin/noop_auth_plugin.py +84 -0
  280. flwr/superlink/federation/__init__.py +24 -0
  281. flwr/superlink/federation/federation_manager.py +64 -0
  282. flwr/superlink/federation/noop_federation_manager.py +71 -0
  283. flwr/superlink/servicer/control/{control_user_auth_interceptor.py → control_account_auth_interceptor.py} +41 -32
  284. flwr/superlink/servicer/control/control_event_log_interceptor.py +7 -7
  285. flwr/superlink/servicer/control/control_grpc.py +18 -17
  286. flwr/superlink/servicer/control/control_license_interceptor.py +3 -3
  287. flwr/superlink/servicer/control/control_servicer.py +239 -63
  288. flwr/supernode/cli/flower_supernode.py +74 -26
  289. flwr/supernode/nodestate/in_memory_nodestate.py +60 -49
  290. flwr/supernode/nodestate/nodestate.py +7 -8
  291. flwr/supernode/nodestate/nodestate_factory.py +7 -4
  292. flwr/supernode/runtime/run_clientapp.py +43 -24
  293. flwr/supernode/servicer/clientappio/clientappio_servicer.py +40 -10
  294. flwr/supernode/start_client_internal.py +175 -51
  295. {flwr-1.22.0.dist-info → flwr-1.24.0.dist-info}/METADATA +8 -8
  296. flwr-1.24.0.dist-info/RECORD +454 -0
  297. flwr/common/auth_plugin/auth_plugin.py +0 -149
  298. flwr/supercore/object_store/utils.py +0 -43
  299. flwr-1.22.0.dist-info/RECORD +0 -428
  300. {flwr-1.22.0.dist-info → flwr-1.24.0.dist-info}/WHEEL +0 -0
  301. {flwr-1.22.0.dist-info → flwr-1.24.0.dist-info}/entry_points.txt +0 -0
@@ -17,22 +17,26 @@
17
17
 
18
18
  from __future__ import annotations
19
19
 
20
- from collections.abc import Awaitable
21
- from typing import Callable, TypeVar, cast
20
+ from collections.abc import Awaitable, Callable
21
+ from typing import TypeVar, cast
22
22
 
23
23
  from google.protobuf.message import Message as GrpcMessage
24
24
 
25
25
  from flwr.common.exit import ExitCode, flwr_exit
26
26
  from flwr.proto.fab_pb2 import GetFabRequest, GetFabResponse # pylint: disable=E0611
27
27
  from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
28
- CreateNodeRequest,
29
- CreateNodeResponse,
30
- DeleteNodeRequest,
31
- DeleteNodeResponse,
28
+ ActivateNodeRequest,
29
+ ActivateNodeResponse,
30
+ DeactivateNodeRequest,
31
+ DeactivateNodeResponse,
32
32
  PullMessagesRequest,
33
33
  PullMessagesResponse,
34
34
  PushMessagesRequest,
35
35
  PushMessagesResponse,
36
+ RegisterNodeFleetRequest,
37
+ RegisterNodeFleetResponse,
38
+ UnregisterNodeFleetRequest,
39
+ UnregisterNodeFleetResponse,
36
40
  )
37
41
  from flwr.proto.heartbeat_pb2 import ( # pylint: disable=E0611
38
42
  SendNodeHeartbeatRequest,
@@ -69,6 +73,8 @@ GrpcResponse = TypeVar("GrpcResponse", bound=GrpcMessage)
69
73
  GrpcAsyncFunction = Callable[[GrpcRequest], Awaitable[GrpcResponse]]
70
74
  RestEndPoint = Callable[[Request], Awaitable[Response]]
71
75
 
76
+ routes = []
77
+
72
78
 
73
79
  def rest_request_response(
74
80
  grpc_request_type: type[GrpcRequest],
@@ -76,6 +82,7 @@ def rest_request_response(
76
82
  """Convert an async gRPC-based function into a RESTful HTTP endpoint."""
77
83
 
78
84
  def decorator(func: GrpcAsyncFunction[GrpcRequest, GrpcResponse]) -> RestEndPoint:
85
+
79
86
  async def wrapper(request: Request) -> Response:
80
87
  _check_headers(request.headers)
81
88
 
@@ -91,33 +98,64 @@ def rest_request_response(
91
98
  headers={"Content-Type": "application/protobuf"},
92
99
  )
93
100
 
101
+ # Register route
102
+ path = f"/api/v0/fleet/{func.__name__.replace('_', '-')}"
103
+ routes.append(Route(path, wrapper, methods=["POST"]))
94
104
  return wrapper
95
105
 
96
106
  return decorator
97
107
 
98
108
 
99
- @rest_request_response(CreateNodeRequest)
100
- async def create_node(request: CreateNodeRequest) -> CreateNodeResponse:
101
- """Create Node."""
109
+ @rest_request_response(RegisterNodeFleetRequest)
110
+ async def register_node(
111
+ request: RegisterNodeFleetRequest,
112
+ ) -> RegisterNodeFleetResponse:
113
+ """Register a node (Fleet API only)."""
114
+ # Get state from app
115
+ state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
116
+
117
+ # Handle message
118
+ return message_handler.register_node(request=request, state=state)
119
+
120
+
121
+ @rest_request_response(ActivateNodeRequest)
122
+ async def activate_node(
123
+ request: ActivateNodeRequest,
124
+ ) -> ActivateNodeResponse:
125
+ """Activate a node."""
102
126
  # Get state from app
103
127
  state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
104
128
 
105
129
  # Handle message
106
- return message_handler.create_node(request=request, state=state)
130
+ return message_handler.activate_node(request=request, state=state)
107
131
 
108
132
 
109
- @rest_request_response(DeleteNodeRequest)
110
- async def delete_node(request: DeleteNodeRequest) -> DeleteNodeResponse:
111
- """Delete Node Id."""
133
+ @rest_request_response(DeactivateNodeRequest)
134
+ async def deactivate_node(
135
+ request: DeactivateNodeRequest,
136
+ ) -> DeactivateNodeResponse:
137
+ """Deactivate a node."""
112
138
  # Get state from app
113
139
  state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
114
140
 
115
141
  # Handle message
116
- return message_handler.delete_node(request=request, state=state)
142
+ return message_handler.deactivate_node(request=request, state=state)
143
+
144
+
145
+ @rest_request_response(UnregisterNodeFleetRequest)
146
+ async def unregister_node(
147
+ request: UnregisterNodeFleetRequest,
148
+ ) -> UnregisterNodeFleetResponse:
149
+ """Unregister a node (Fleet API only)."""
150
+ # Get state from app
151
+ state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
152
+
153
+ # Handle message
154
+ return message_handler.unregister_node(request=request, state=state)
117
155
 
118
156
 
119
157
  @rest_request_response(PullMessagesRequest)
120
- async def pull_message(request: PullMessagesRequest) -> PullMessagesResponse:
158
+ async def pull_messages(request: PullMessagesRequest) -> PullMessagesResponse:
121
159
  """Pull PullMessages."""
122
160
  # Get state from app
123
161
  state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
@@ -128,7 +166,7 @@ async def pull_message(request: PullMessagesRequest) -> PullMessagesResponse:
128
166
 
129
167
 
130
168
  @rest_request_response(PushMessagesRequest)
131
- async def push_message(request: PushMessagesRequest) -> PushMessagesResponse:
169
+ async def push_messages(request: PushMessagesRequest) -> PushMessagesResponse:
132
170
  """Pull PushMessages."""
133
171
  # Get state from app
134
172
  state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
@@ -212,23 +250,6 @@ async def confirm_message_received(
212
250
  )
213
251
 
214
252
 
215
- routes = [
216
- Route("/api/v0/fleet/create-node", create_node, methods=["POST"]),
217
- Route("/api/v0/fleet/delete-node", delete_node, methods=["POST"]),
218
- Route("/api/v0/fleet/pull-messages", pull_message, methods=["POST"]),
219
- Route("/api/v0/fleet/push-messages", push_message, methods=["POST"]),
220
- Route("/api/v0/fleet/pull-object", pull_object, methods=["POST"]),
221
- Route("/api/v0/fleet/push-object", push_object, methods=["POST"]),
222
- Route("/api/v0/fleet/send-node-heartbeat", send_node_heartbeat, methods=["POST"]),
223
- Route("/api/v0/fleet/get-run", get_run, methods=["POST"]),
224
- Route("/api/v0/fleet/get-fab", get_fab, methods=["POST"]),
225
- Route(
226
- "/api/v0/fleet/confirm-message-received",
227
- confirm_message_received,
228
- methods=["POST"],
229
- ),
230
- ]
231
-
232
253
  app: Starlette = Starlette(
233
254
  debug=False,
234
255
  routes=routes,
@@ -16,9 +16,9 @@
16
16
 
17
17
 
18
18
  from abc import ABC, abstractmethod
19
- from typing import Callable
19
+ from collections.abc import Callable
20
20
 
21
- from flwr.client.client_app import ClientApp
21
+ from flwr.clientapp.client_app import ClientApp
22
22
  from flwr.common.context import Context
23
23
  from flwr.common.message import Message
24
24
  from flwr.common.typing import ConfigRecordValues
@@ -16,12 +16,12 @@
16
16
 
17
17
 
18
18
  import sys
19
+ from collections.abc import Callable
19
20
  from logging import DEBUG, ERROR
20
- from typing import Callable, Optional, Union
21
21
 
22
22
  import ray
23
23
 
24
- from flwr.client.client_app import ClientApp
24
+ from flwr.clientapp.client_app import ClientApp
25
25
  from flwr.common.constant import PARTITION_ID_KEY
26
26
  from flwr.common.context import Context
27
27
  from flwr.common.logger import log
@@ -32,8 +32,8 @@ from flwr.simulation.ray_transport.utils import enable_tf_gpu_growth
32
32
 
33
33
  from .backend import Backend, BackendConfig
34
34
 
35
- ClientResourcesDict = dict[str, Union[int, float]]
36
- ActorArgsDict = dict[str, Union[int, float, Callable[[], None]]]
35
+ ClientResourcesDict = dict[str, int | float]
36
+ ActorArgsDict = dict[str, int | float | Callable[[], None]]
37
37
 
38
38
 
39
39
  class RayBackend(Backend):
@@ -57,9 +57,9 @@ class RayBackend(Backend):
57
57
 
58
58
  # Valide actor resources
59
59
  self.actor_kwargs = self._validate_actor_arguments(config=backend_config)
60
- self.pool: Optional[BasicActorPool] = None
60
+ self.pool: BasicActorPool | None = None
61
61
 
62
- self.app_fn: Optional[Callable[[], ClientApp]] = None
62
+ self.app_fn: Callable[[], ClientApp] | None = None
63
63
 
64
64
  def _validate_client_resources(self, config: BackendConfig) -> ClientResourcesDict:
65
65
  client_resources_config = config.get(self.client_resources_key)
@@ -16,23 +16,26 @@
16
16
 
17
17
 
18
18
  import json
19
+ import secrets
19
20
  import threading
20
21
  import time
21
22
  import traceback
23
+ from collections.abc import Callable
22
24
  from concurrent.futures import ThreadPoolExecutor
23
25
  from logging import DEBUG, ERROR, INFO, WARN
24
26
  from pathlib import Path
25
27
  from queue import Empty, Queue
26
- from typing import Callable, Optional
27
28
  from uuid import uuid4
28
29
 
29
30
  from flwr.app.error import Error
30
- from flwr.client.client_app import ClientApp, ClientAppException, LoadClientAppError
31
- from flwr.client.clientapp.utils import get_load_client_app_fn
32
31
  from flwr.client.run_info_store import DeprecatedRunInfoStore
32
+ from flwr.clientapp.client_app import ClientApp, ClientAppException, LoadClientAppError
33
+ from flwr.clientapp.utils import get_load_client_app_fn
33
34
  from flwr.common import Message
34
35
  from flwr.common.constant import (
35
- HEARTBEAT_MAX_INTERVAL,
36
+ HEARTBEAT_INTERVAL_INF,
37
+ NOOP_ACCOUNT_NAME,
38
+ NOOP_FLWR_AID,
36
39
  NUM_PARTITIONS_KEY,
37
40
  PARTITION_ID_KEY,
38
41
  ErrorCode,
@@ -40,6 +43,9 @@ from flwr.common.constant import (
40
43
  from flwr.common.logger import log
41
44
  from flwr.common.typing import Run
42
45
  from flwr.server.superlink.linkstate import LinkState, LinkStateFactory
46
+ from flwr.supercore.constant import FLWR_IN_MEMORY_DB_NAME
47
+ from flwr.supercore.object_store import ObjectStoreFactory
48
+ from flwr.superlink.federation import NoOpFederationManager
43
49
 
44
50
  from .backend import Backend, error_messages_backends, supported_backends
45
51
 
@@ -53,7 +59,18 @@ def _register_nodes(
53
59
  nodes_mapping: NodeToPartitionMapping = {}
54
60
  state = state_factory.state()
55
61
  for i in range(num_nodes):
56
- node_id = state.create_node(heartbeat_interval=HEARTBEAT_MAX_INTERVAL)
62
+ node_id = state.create_node(
63
+ # No node authentication in simulation;
64
+ # use NOOP_FLWR_AID as owner_aid and
65
+ # use random bytes as public key
66
+ NOOP_FLWR_AID,
67
+ NOOP_ACCOUNT_NAME,
68
+ secrets.token_bytes(32),
69
+ heartbeat_interval=HEARTBEAT_INTERVAL_INF,
70
+ )
71
+ state.acknowledge_node_heartbeat(
72
+ node_id=node_id, heartbeat_interval=HEARTBEAT_INTERVAL_INF
73
+ )
57
74
  nodes_mapping[node_id] = i
58
75
  log(DEBUG, "Registered %i nodes", len(nodes_mapping))
59
76
  return nodes_mapping
@@ -62,7 +79,7 @@ def _register_nodes(
62
79
  def _register_node_info_stores(
63
80
  nodes_mapping: NodeToPartitionMapping,
64
81
  run: Run,
65
- app_dir: Optional[str] = None,
82
+ app_dir: str | None = None,
66
83
  ) -> dict[int, DeprecatedRunInfoStore]:
67
84
  """Create DeprecatedRunInfoStore objects and register the context for the run."""
68
85
  node_info_store: dict[int, DeprecatedRunInfoStore] = {}
@@ -257,12 +274,12 @@ def start_vce(
257
274
  is_app: bool,
258
275
  f_stop: threading.Event,
259
276
  run: Run,
260
- flwr_dir: Optional[str] = None,
261
- client_app: Optional[ClientApp] = None,
262
- client_app_attr: Optional[str] = None,
263
- num_supernodes: Optional[int] = None,
264
- state_factory: Optional[LinkStateFactory] = None,
265
- existing_nodes_mapping: Optional[NodeToPartitionMapping] = None,
277
+ flwr_dir: str | None = None,
278
+ client_app: ClientApp | None = None,
279
+ client_app_attr: str | None = None,
280
+ num_supernodes: int | None = None,
281
+ state_factory: LinkStateFactory | None = None,
282
+ existing_nodes_mapping: NodeToPartitionMapping | None = None,
266
283
  ) -> None:
267
284
  """Start Fleet API with the Simulation Engine."""
268
285
  nodes_mapping = {}
@@ -300,7 +317,9 @@ def start_vce(
300
317
  if not state_factory:
301
318
  log(INFO, "A StateFactory was not supplied to the SimulationEngine.")
302
319
  # Create an empty in-memory state factory
303
- state_factory = LinkStateFactory(":flwr-in-memory-state:")
320
+ state_factory = LinkStateFactory(
321
+ FLWR_IN_MEMORY_DB_NAME, NoOpFederationManager(), ObjectStoreFactory()
322
+ )
304
323
  log(INFO, "Created new %s.", state_factory.__class__.__name__)
305
324
 
306
325
  if num_supernodes: