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.
- flwr/__init__.py +16 -5
- flwr/app/error.py +2 -2
- flwr/app/exception.py +3 -3
- flwr/cli/app.py +34 -1
- flwr/cli/app_cmd/__init__.py +23 -0
- flwr/cli/app_cmd/publish.py +285 -0
- flwr/cli/app_cmd/review.py +252 -0
- flwr/cli/auth_plugin/__init__.py +15 -6
- flwr/cli/auth_plugin/auth_plugin.py +94 -0
- flwr/cli/auth_plugin/noop_auth_plugin.py +101 -0
- flwr/cli/auth_plugin/oidc_cli_plugin.py +46 -32
- flwr/cli/build.py +166 -53
- flwr/cli/{cli_user_auth_interceptor.py → cli_account_auth_interceptor.py} +29 -11
- flwr/cli/config_utils.py +101 -13
- flwr/cli/federation/__init__.py +24 -0
- flwr/cli/federation/ls.py +140 -0
- flwr/cli/federation/show.py +317 -0
- flwr/cli/install.py +91 -13
- flwr/cli/log.py +54 -11
- flwr/cli/login/login.py +41 -27
- flwr/cli/ls.py +177 -133
- flwr/cli/new/new.py +175 -40
- flwr/cli/new/templates/app/code/task.pytorch.py.tpl +1 -0
- flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.jax.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +3 -3
- flwr/cli/new/templates/app/pyproject.pytorch_legacy_api.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +2 -2
- flwr/cli/new/templates/app/pyproject.xgboost.toml.tpl +1 -1
- flwr/cli/pull.py +12 -7
- flwr/cli/run/run.py +82 -31
- flwr/cli/run_utils.py +130 -0
- flwr/cli/stop.py +27 -9
- flwr/cli/supernode/__init__.py +25 -0
- flwr/cli/supernode/ls.py +268 -0
- flwr/cli/supernode/register.py +190 -0
- flwr/cli/supernode/unregister.py +140 -0
- flwr/cli/utils.py +464 -81
- flwr/client/__init__.py +2 -1
- flwr/client/dpfedavg_numpy_client.py +4 -1
- flwr/client/grpc_adapter_client/connection.py +12 -15
- flwr/client/grpc_rere_client/connection.py +68 -41
- flwr/client/grpc_rere_client/grpc_adapter.py +34 -14
- flwr/client/grpc_rere_client/{client_interceptor.py → node_auth_client_interceptor.py} +5 -7
- flwr/client/message_handler/message_handler.py +2 -2
- flwr/client/mod/secure_aggregation/secaggplus_mod.py +10 -8
- flwr/client/numpy_client.py +1 -1
- flwr/client/rest_client/connection.py +94 -51
- flwr/client/run_info_store.py +4 -5
- flwr/client/typing.py +1 -1
- flwr/clientapp/__init__.py +1 -2
- flwr/{client → clientapp}/client_app.py +9 -10
- flwr/clientapp/mod/centraldp_mods.py +16 -17
- flwr/clientapp/mod/localdp_mod.py +8 -9
- flwr/clientapp/typing.py +1 -1
- flwr/{client/clientapp → clientapp}/utils.py +4 -4
- flwr/common/address.py +1 -2
- flwr/common/args.py +3 -4
- flwr/common/config.py +13 -16
- flwr/common/constant.py +56 -13
- flwr/common/differential_privacy.py +3 -4
- flwr/common/event_log_plugin/event_log_plugin.py +3 -4
- flwr/common/exit/exit.py +15 -2
- flwr/common/exit/exit_code.py +39 -10
- flwr/common/exit/exit_handler.py +6 -2
- flwr/common/exit/signal_handler.py +5 -5
- flwr/common/grpc.py +6 -6
- flwr/common/inflatable_protobuf_utils.py +1 -1
- flwr/common/inflatable_utils.py +48 -31
- flwr/common/logger.py +19 -19
- flwr/common/message.py +4 -4
- flwr/common/object_ref.py +7 -7
- flwr/common/record/array.py +6 -6
- flwr/common/record/arrayrecord.py +18 -21
- flwr/common/record/configrecord.py +3 -3
- flwr/common/record/recorddict.py +5 -5
- flwr/common/record/typeddict.py +9 -2
- flwr/common/recorddict_compat.py +7 -10
- flwr/common/retry_invoker.py +20 -20
- flwr/common/secure_aggregation/crypto/symmetric_encryption.py +1 -89
- flwr/common/secure_aggregation/ndarrays_arithmetic.py +3 -3
- flwr/common/serde.py +9 -6
- flwr/common/serde_utils.py +2 -2
- flwr/common/telemetry.py +9 -5
- flwr/common/typing.py +59 -43
- flwr/compat/client/app.py +39 -38
- flwr/compat/client/grpc_client/connection.py +13 -13
- flwr/compat/server/app.py +5 -6
- flwr/proto/appio_pb2.py +13 -3
- flwr/proto/appio_pb2.pyi +134 -65
- flwr/proto/appio_pb2_grpc.py +20 -0
- flwr/proto/appio_pb2_grpc.pyi +27 -0
- flwr/proto/clientappio_pb2.py +17 -7
- flwr/proto/clientappio_pb2.pyi +15 -0
- flwr/proto/clientappio_pb2_grpc.py +206 -40
- flwr/proto/clientappio_pb2_grpc.pyi +168 -53
- flwr/proto/control_pb2.py +72 -40
- flwr/proto/control_pb2.pyi +319 -87
- flwr/proto/control_pb2_grpc.py +339 -28
- flwr/proto/control_pb2_grpc.pyi +209 -37
- flwr/proto/error_pb2.py +13 -3
- flwr/proto/error_pb2.pyi +24 -6
- flwr/proto/error_pb2_grpc.py +20 -0
- flwr/proto/error_pb2_grpc.pyi +27 -0
- flwr/proto/fab_pb2.py +24 -10
- flwr/proto/fab_pb2.pyi +68 -20
- flwr/proto/fab_pb2_grpc.py +20 -0
- flwr/proto/fab_pb2_grpc.pyi +27 -0
- flwr/proto/federation_pb2.py +38 -0
- flwr/proto/federation_pb2.pyi +56 -0
- flwr/proto/federation_pb2_grpc.py +24 -0
- flwr/proto/federation_pb2_grpc.pyi +31 -0
- flwr/proto/fleet_pb2.py +45 -27
- flwr/proto/fleet_pb2.pyi +186 -70
- flwr/proto/fleet_pb2_grpc.py +277 -66
- flwr/proto/fleet_pb2_grpc.pyi +201 -55
- flwr/proto/grpcadapter_pb2.py +14 -4
- flwr/proto/grpcadapter_pb2.pyi +38 -16
- flwr/proto/grpcadapter_pb2_grpc.py +35 -4
- flwr/proto/grpcadapter_pb2_grpc.pyi +38 -7
- flwr/proto/heartbeat_pb2.py +17 -7
- flwr/proto/heartbeat_pb2.pyi +51 -22
- flwr/proto/heartbeat_pb2_grpc.py +20 -0
- flwr/proto/heartbeat_pb2_grpc.pyi +27 -0
- flwr/proto/log_pb2.py +13 -3
- flwr/proto/log_pb2.pyi +34 -11
- flwr/proto/log_pb2_grpc.py +20 -0
- flwr/proto/log_pb2_grpc.pyi +27 -0
- flwr/proto/message_pb2.py +15 -5
- flwr/proto/message_pb2.pyi +154 -86
- flwr/proto/message_pb2_grpc.py +20 -0
- flwr/proto/message_pb2_grpc.pyi +27 -0
- flwr/proto/node_pb2.py +16 -4
- flwr/proto/node_pb2.pyi +77 -4
- flwr/proto/node_pb2_grpc.py +20 -0
- flwr/proto/node_pb2_grpc.pyi +27 -0
- flwr/proto/recorddict_pb2.py +13 -3
- flwr/proto/recorddict_pb2.pyi +184 -107
- flwr/proto/recorddict_pb2_grpc.py +20 -0
- flwr/proto/recorddict_pb2_grpc.pyi +27 -0
- flwr/proto/run_pb2.py +40 -31
- flwr/proto/run_pb2.pyi +149 -84
- flwr/proto/run_pb2_grpc.py +20 -0
- flwr/proto/run_pb2_grpc.pyi +27 -0
- flwr/proto/serverappio_pb2.py +13 -3
- flwr/proto/serverappio_pb2.pyi +32 -8
- flwr/proto/serverappio_pb2_grpc.py +246 -65
- flwr/proto/serverappio_pb2_grpc.pyi +221 -85
- flwr/proto/simulationio_pb2.py +16 -8
- flwr/proto/simulationio_pb2.pyi +15 -0
- flwr/proto/simulationio_pb2_grpc.py +162 -41
- flwr/proto/simulationio_pb2_grpc.pyi +149 -55
- flwr/proto/transport_pb2.py +20 -10
- flwr/proto/transport_pb2.pyi +249 -160
- flwr/proto/transport_pb2_grpc.py +35 -4
- flwr/proto/transport_pb2_grpc.pyi +38 -8
- flwr/server/app.py +173 -127
- flwr/server/client_manager.py +4 -5
- flwr/server/client_proxy.py +10 -11
- flwr/server/compat/app.py +4 -5
- flwr/server/compat/app_utils.py +2 -1
- flwr/server/compat/grid_client_proxy.py +10 -12
- flwr/server/compat/legacy_context.py +3 -4
- flwr/server/fleet_event_log_interceptor.py +2 -1
- flwr/server/grid/grid.py +2 -3
- flwr/server/grid/grpc_grid.py +10 -8
- flwr/server/grid/inmemory_grid.py +4 -4
- flwr/server/run_serverapp.py +2 -3
- flwr/server/server.py +34 -39
- flwr/server/server_app.py +7 -8
- flwr/server/server_config.py +1 -2
- flwr/server/serverapp/app.py +34 -28
- flwr/server/serverapp_components.py +4 -5
- flwr/server/strategy/aggregate.py +9 -8
- flwr/server/strategy/bulyan.py +13 -11
- flwr/server/strategy/dp_adaptive_clipping.py +16 -20
- flwr/server/strategy/dp_fixed_clipping.py +12 -17
- flwr/server/strategy/dpfedavg_adaptive.py +3 -4
- flwr/server/strategy/dpfedavg_fixed.py +6 -10
- flwr/server/strategy/fault_tolerant_fedavg.py +14 -13
- flwr/server/strategy/fedadagrad.py +18 -14
- flwr/server/strategy/fedadam.py +16 -14
- flwr/server/strategy/fedavg.py +16 -17
- flwr/server/strategy/fedavg_android.py +15 -15
- flwr/server/strategy/fedavgm.py +21 -18
- flwr/server/strategy/fedmedian.py +2 -3
- flwr/server/strategy/fedopt.py +11 -10
- flwr/server/strategy/fedprox.py +10 -9
- flwr/server/strategy/fedtrimmedavg.py +12 -11
- flwr/server/strategy/fedxgb_bagging.py +13 -11
- flwr/server/strategy/fedxgb_cyclic.py +6 -6
- flwr/server/strategy/fedxgb_nn_avg.py +4 -4
- flwr/server/strategy/fedyogi.py +16 -14
- flwr/server/strategy/krum.py +12 -11
- flwr/server/strategy/qfedavg.py +16 -15
- flwr/server/strategy/strategy.py +6 -9
- flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +19 -8
- flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +1 -2
- flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +3 -4
- flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +10 -12
- flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +1 -3
- flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +136 -42
- flwr/server/superlink/fleet/grpc_rere/{server_interceptor.py → node_auth_server_interceptor.py} +28 -51
- flwr/server/superlink/fleet/message_handler/message_handler.py +100 -49
- flwr/server/superlink/fleet/rest_rere/rest_api.py +54 -33
- flwr/server/superlink/fleet/vce/backend/backend.py +2 -2
- flwr/server/superlink/fleet/vce/backend/raybackend.py +6 -6
- flwr/server/superlink/fleet/vce/vce_api.py +32 -13
- flwr/server/superlink/linkstate/in_memory_linkstate.py +266 -207
- flwr/server/superlink/linkstate/linkstate.py +161 -62
- flwr/server/superlink/linkstate/linkstate_factory.py +24 -6
- flwr/server/superlink/linkstate/sqlite_linkstate.py +698 -638
- flwr/server/superlink/linkstate/utils.py +9 -60
- flwr/server/superlink/serverappio/serverappio_grpc.py +1 -2
- flwr/server/superlink/serverappio/serverappio_servicer.py +28 -23
- flwr/server/superlink/simulation/simulationio_grpc.py +1 -2
- flwr/server/superlink/simulation/simulationio_servicer.py +19 -14
- flwr/server/superlink/utils.py +4 -6
- flwr/server/typing.py +1 -1
- flwr/server/utils/tensorboard.py +15 -8
- flwr/server/utils/validator.py +2 -3
- flwr/server/workflow/default_workflows.py +5 -5
- flwr/server/workflow/secure_aggregation/secagg_workflow.py +2 -4
- flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +12 -10
- flwr/serverapp/strategy/bulyan.py +16 -15
- flwr/serverapp/strategy/dp_adaptive_clipping.py +12 -11
- flwr/serverapp/strategy/dp_fixed_clipping.py +11 -14
- flwr/serverapp/strategy/fedadagrad.py +10 -11
- flwr/serverapp/strategy/fedadam.py +10 -11
- flwr/serverapp/strategy/fedavg.py +9 -10
- flwr/serverapp/strategy/fedavgm.py +17 -16
- flwr/serverapp/strategy/fedmedian.py +2 -2
- flwr/serverapp/strategy/fedopt.py +10 -11
- flwr/serverapp/strategy/fedprox.py +7 -8
- flwr/serverapp/strategy/fedtrimmedavg.py +9 -9
- flwr/serverapp/strategy/fedxgb_bagging.py +3 -3
- flwr/serverapp/strategy/fedxgb_cyclic.py +9 -9
- flwr/serverapp/strategy/fedyogi.py +9 -11
- flwr/serverapp/strategy/krum.py +7 -7
- flwr/serverapp/strategy/multikrum.py +9 -9
- flwr/serverapp/strategy/qfedavg.py +17 -16
- flwr/serverapp/strategy/strategy.py +6 -9
- flwr/serverapp/strategy/strategy_utils.py +7 -8
- flwr/simulation/app.py +46 -42
- flwr/simulation/legacy_app.py +12 -12
- flwr/simulation/ray_transport/ray_actor.py +11 -12
- flwr/simulation/ray_transport/ray_client_proxy.py +12 -13
- flwr/simulation/run_simulation.py +44 -43
- flwr/simulation/simulationio_connection.py +4 -4
- flwr/supercore/cli/flower_superexec.py +3 -4
- flwr/supercore/constant.py +52 -0
- flwr/supercore/corestate/corestate.py +24 -3
- flwr/supercore/corestate/in_memory_corestate.py +138 -0
- flwr/supercore/corestate/sqlite_corestate.py +157 -0
- flwr/supercore/ffs/disk_ffs.py +1 -2
- flwr/supercore/ffs/ffs.py +1 -2
- flwr/supercore/ffs/ffs_factory.py +1 -2
- flwr/{common → supercore}/heartbeat.py +20 -25
- flwr/supercore/object_store/in_memory_object_store.py +1 -6
- flwr/supercore/object_store/object_store.py +1 -2
- flwr/supercore/object_store/object_store_factory.py +27 -8
- flwr/supercore/object_store/sqlite_object_store.py +253 -0
- flwr/{client/clientapp → supercore/primitives}/__init__.py +1 -1
- flwr/supercore/primitives/asymmetric.py +117 -0
- flwr/supercore/primitives/asymmetric_ed25519.py +175 -0
- flwr/supercore/sqlite_mixin.py +159 -0
- flwr/supercore/superexec/plugin/base_exec_plugin.py +1 -2
- flwr/supercore/superexec/plugin/exec_plugin.py +3 -3
- flwr/supercore/superexec/run_superexec.py +9 -13
- flwr/supercore/utils.py +20 -0
- flwr/superlink/artifact_provider/artifact_provider.py +1 -2
- flwr/{common → superlink}/auth_plugin/__init__.py +6 -6
- flwr/superlink/auth_plugin/auth_plugin.py +88 -0
- flwr/superlink/auth_plugin/noop_auth_plugin.py +84 -0
- flwr/superlink/federation/__init__.py +24 -0
- flwr/superlink/federation/federation_manager.py +64 -0
- flwr/superlink/federation/noop_federation_manager.py +71 -0
- flwr/superlink/servicer/control/{control_user_auth_interceptor.py → control_account_auth_interceptor.py} +41 -32
- flwr/superlink/servicer/control/control_event_log_interceptor.py +7 -7
- flwr/superlink/servicer/control/control_grpc.py +18 -17
- flwr/superlink/servicer/control/control_license_interceptor.py +3 -3
- flwr/superlink/servicer/control/control_servicer.py +239 -63
- flwr/supernode/cli/flower_supernode.py +74 -26
- flwr/supernode/nodestate/in_memory_nodestate.py +60 -49
- flwr/supernode/nodestate/nodestate.py +7 -8
- flwr/supernode/nodestate/nodestate_factory.py +7 -4
- flwr/supernode/runtime/run_clientapp.py +43 -24
- flwr/supernode/servicer/clientappio/clientappio_servicer.py +40 -10
- flwr/supernode/start_client_internal.py +175 -51
- {flwr-1.22.0.dist-info → flwr-1.24.0.dist-info}/METADATA +8 -8
- flwr-1.24.0.dist-info/RECORD +454 -0
- flwr/common/auth_plugin/auth_plugin.py +0 -149
- flwr/supercore/object_store/utils.py +0 -43
- flwr-1.22.0.dist-info/RECORD +0 -428
- {flwr-1.22.0.dist-info → flwr-1.24.0.dist-info}/WHEEL +0 -0
- {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
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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(
|
|
100
|
-
async def
|
|
101
|
-
|
|
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.
|
|
130
|
+
return message_handler.activate_node(request=request, state=state)
|
|
107
131
|
|
|
108
132
|
|
|
109
|
-
@rest_request_response(
|
|
110
|
-
async def
|
|
111
|
-
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
19
|
+
from collections.abc import Callable
|
|
20
20
|
|
|
21
|
-
from flwr.
|
|
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.
|
|
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,
|
|
36
|
-
ActorArgsDict = dict[str,
|
|
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:
|
|
60
|
+
self.pool: BasicActorPool | None = None
|
|
61
61
|
|
|
62
|
-
self.app_fn:
|
|
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
|
-
|
|
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(
|
|
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:
|
|
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:
|
|
261
|
-
client_app:
|
|
262
|
-
client_app_attr:
|
|
263
|
-
num_supernodes:
|
|
264
|
-
state_factory:
|
|
265
|
-
existing_nodes_mapping:
|
|
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(
|
|
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:
|