flwr 1.23.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 +19 -0
- 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/auth_plugin.py +4 -5
- flwr/cli/auth_plugin/noop_auth_plugin.py +54 -11
- flwr/cli/auth_plugin/oidc_cli_plugin.py +32 -9
- flwr/cli/build.py +60 -18
- flwr/cli/cli_account_auth_interceptor.py +24 -7
- 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 +52 -9
- flwr/cli/login/login.py +7 -4
- flwr/cli/ls.py +170 -130
- flwr/cli/new/new.py +33 -50
- 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 +10 -5
- flwr/cli/run/run.py +77 -30
- flwr/cli/run_utils.py +130 -0
- flwr/cli/stop.py +25 -7
- flwr/cli/supernode/ls.py +16 -8
- flwr/cli/supernode/register.py +9 -4
- flwr/cli/supernode/unregister.py +5 -3
- flwr/cli/utils.py +376 -16
- flwr/client/__init__.py +1 -1
- flwr/client/dpfedavg_numpy_client.py +4 -1
- flwr/client/grpc_adapter_client/connection.py +6 -7
- flwr/client/grpc_rere_client/connection.py +10 -11
- flwr/client/grpc_rere_client/grpc_adapter.py +6 -2
- flwr/client/grpc_rere_client/node_auth_client_interceptor.py +2 -1
- flwr/client/message_handler/message_handler.py +2 -2
- flwr/client/mod/secure_aggregation/secaggplus_mod.py +3 -3
- flwr/client/numpy_client.py +1 -1
- flwr/client/rest_client/connection.py +12 -14
- flwr/client/run_info_store.py +4 -5
- flwr/client/typing.py +1 -1
- flwr/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/clientapp/utils.py +3 -3
- flwr/common/address.py +1 -2
- flwr/common/args.py +3 -4
- flwr/common/config.py +13 -16
- flwr/common/constant.py +5 -2
- 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 +19 -0
- 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 +38 -21
- flwr/common/logger.py +19 -19
- flwr/common/message.py +4 -4
- flwr/common/object_ref.py +7 -7
- flwr/common/record/array.py +3 -3
- flwr/common/record/arrayrecord.py +18 -30
- 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/ndarrays_arithmetic.py +3 -3
- flwr/common/serde.py +5 -4
- flwr/common/serde_utils.py +2 -2
- flwr/common/telemetry.py +9 -5
- flwr/common/typing.py +52 -37
- flwr/compat/client/app.py +38 -37
- flwr/compat/client/grpc_client/connection.py +11 -11
- 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 +71 -52
- flwr/proto/control_pb2.pyi +277 -111
- flwr/proto/control_pb2_grpc.py +249 -40
- flwr/proto/control_pb2_grpc.pyi +185 -52
- 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 +14 -4
- flwr/proto/fab_pb2.pyi +59 -31
- 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 +14 -4
- flwr/proto/fleet_pb2.pyi +137 -61
- flwr/proto/fleet_pb2_grpc.py +189 -48
- flwr/proto/fleet_pb2_grpc.pyi +175 -61
- 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 +15 -5
- flwr/proto/node_pb2.pyi +50 -25
- 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 +38 -17
- 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 +2 -1
- 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 +4 -4
- flwr/server/superlink/fleet/grpc_rere/node_auth_server_interceptor.py +3 -2
- flwr/server/superlink/fleet/message_handler/message_handler.py +34 -28
- flwr/server/superlink/fleet/rest_rere/rest_api.py +2 -2
- flwr/server/superlink/fleet/vce/backend/backend.py +1 -1
- flwr/server/superlink/fleet/vce/backend/raybackend.py +5 -5
- flwr/server/superlink/fleet/vce/vce_api.py +15 -9
- flwr/server/superlink/linkstate/in_memory_linkstate.py +115 -150
- flwr/server/superlink/linkstate/linkstate.py +59 -43
- flwr/server/superlink/linkstate/linkstate_factory.py +22 -5
- flwr/server/superlink/linkstate/sqlite_linkstate.py +447 -438
- flwr/server/superlink/linkstate/utils.py +6 -6
- flwr/server/superlink/serverappio/serverappio_grpc.py +1 -2
- flwr/server/superlink/serverappio/serverappio_servicer.py +26 -21
- flwr/server/superlink/simulation/simulationio_grpc.py +1 -2
- flwr/server/superlink/simulation/simulationio_servicer.py +18 -13
- flwr/server/superlink/utils.py +4 -6
- flwr/server/typing.py +1 -1
- flwr/server/utils/tensorboard.py +15 -8
- 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 +8 -8
- 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 +10 -11
- flwr/simulation/ray_transport/ray_client_proxy.py +11 -12
- flwr/simulation/run_simulation.py +43 -43
- flwr/simulation/simulationio_connection.py +4 -4
- flwr/supercore/cli/flower_superexec.py +3 -4
- flwr/supercore/constant.py +31 -1
- 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 -2
- flwr/supercore/object_store/object_store.py +1 -2
- flwr/supercore/object_store/object_store_factory.py +1 -2
- flwr/supercore/object_store/sqlite_object_store.py +8 -7
- flwr/supercore/primitives/asymmetric.py +1 -1
- flwr/supercore/primitives/asymmetric_ed25519.py +11 -1
- flwr/supercore/sqlite_mixin.py +37 -34
- 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/superlink/artifact_provider/artifact_provider.py +1 -2
- flwr/superlink/auth_plugin/auth_plugin.py +6 -9
- flwr/superlink/auth_plugin/noop_auth_plugin.py +6 -9
- 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_account_auth_interceptor.py +22 -13
- flwr/superlink/servicer/control/control_event_log_interceptor.py +7 -7
- flwr/superlink/servicer/control/control_grpc.py +5 -6
- flwr/superlink/servicer/control/control_license_interceptor.py +3 -3
- flwr/superlink/servicer/control/control_servicer.py +102 -18
- flwr/supernode/cli/flower_supernode.py +58 -3
- 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 +41 -22
- flwr/supernode/servicer/clientappio/clientappio_servicer.py +40 -10
- flwr/supernode/start_client_internal.py +158 -42
- {flwr-1.23.0.dist-info → flwr-1.24.0.dist-info}/METADATA +8 -8
- flwr-1.24.0.dist-info/RECORD +454 -0
- flwr/supercore/object_store/utils.py +0 -43
- flwr-1.23.0.dist-info/RECORD +0 -439
- {flwr-1.23.0.dist-info → flwr-1.24.0.dist-info}/WHEEL +0 -0
- {flwr-1.23.0.dist-info → flwr-1.24.0.dist-info}/entry_points.txt +0 -0
|
@@ -19,7 +19,6 @@ from collections.abc import Iterator
|
|
|
19
19
|
from dataclasses import dataclass
|
|
20
20
|
from enum import Enum
|
|
21
21
|
from threading import Condition
|
|
22
|
-
from typing import Optional
|
|
23
22
|
|
|
24
23
|
from flwr.proto.transport_pb2 import ( # pylint: disable=E0611
|
|
25
24
|
ClientMessage,
|
|
@@ -32,7 +31,7 @@ class InsWrapper:
|
|
|
32
31
|
"""Instruction wrapper class for a single server message."""
|
|
33
32
|
|
|
34
33
|
server_message: ServerMessage
|
|
35
|
-
timeout:
|
|
34
|
+
timeout: float | None
|
|
36
35
|
|
|
37
36
|
|
|
38
37
|
@dataclass
|
|
@@ -70,8 +69,8 @@ class GrpcBridge:
|
|
|
70
69
|
# pylint: disable=unsubscriptable-object
|
|
71
70
|
self._cv = Condition() # cv stands for condition variable
|
|
72
71
|
self._status = Status.AWAITING_INS_WRAPPER
|
|
73
|
-
self._ins_wrapper:
|
|
74
|
-
self._res_wrapper:
|
|
72
|
+
self._ins_wrapper: InsWrapper | None = None
|
|
73
|
+
self._res_wrapper: ResWrapper | None = None
|
|
75
74
|
|
|
76
75
|
def _is_closed(self) -> bool:
|
|
77
76
|
"""Return True if closed and False otherwise."""
|
|
@@ -15,8 +15,6 @@
|
|
|
15
15
|
"""Flower ClientProxy implementation using gRPC bidirectional streaming."""
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
from typing import Optional
|
|
19
|
-
|
|
20
18
|
from flwr import common
|
|
21
19
|
from flwr.common import serde
|
|
22
20
|
from flwr.proto.transport_pb2 import ( # pylint: disable=E0611
|
|
@@ -45,8 +43,8 @@ class GrpcClientProxy(ClientProxy):
|
|
|
45
43
|
def get_properties(
|
|
46
44
|
self,
|
|
47
45
|
ins: common.GetPropertiesIns,
|
|
48
|
-
timeout:
|
|
49
|
-
group_id:
|
|
46
|
+
timeout: float | None,
|
|
47
|
+
group_id: int | None,
|
|
50
48
|
) -> common.GetPropertiesRes:
|
|
51
49
|
"""Request client's set of internal properties."""
|
|
52
50
|
get_properties_msg = serde.get_properties_ins_to_proto(ins)
|
|
@@ -65,8 +63,8 @@ class GrpcClientProxy(ClientProxy):
|
|
|
65
63
|
def get_parameters(
|
|
66
64
|
self,
|
|
67
65
|
ins: common.GetParametersIns,
|
|
68
|
-
timeout:
|
|
69
|
-
group_id:
|
|
66
|
+
timeout: float | None,
|
|
67
|
+
group_id: int | None,
|
|
70
68
|
) -> common.GetParametersRes:
|
|
71
69
|
"""Return the current local model parameters."""
|
|
72
70
|
get_parameters_msg = serde.get_parameters_ins_to_proto(ins)
|
|
@@ -85,8 +83,8 @@ class GrpcClientProxy(ClientProxy):
|
|
|
85
83
|
def fit(
|
|
86
84
|
self,
|
|
87
85
|
ins: common.FitIns,
|
|
88
|
-
timeout:
|
|
89
|
-
group_id:
|
|
86
|
+
timeout: float | None,
|
|
87
|
+
group_id: int | None,
|
|
90
88
|
) -> common.FitRes:
|
|
91
89
|
"""Refine the provided parameters using the locally held dataset."""
|
|
92
90
|
fit_ins_msg = serde.fit_ins_to_proto(ins)
|
|
@@ -104,8 +102,8 @@ class GrpcClientProxy(ClientProxy):
|
|
|
104
102
|
def evaluate(
|
|
105
103
|
self,
|
|
106
104
|
ins: common.EvaluateIns,
|
|
107
|
-
timeout:
|
|
108
|
-
group_id:
|
|
105
|
+
timeout: float | None,
|
|
106
|
+
group_id: int | None,
|
|
109
107
|
) -> common.EvaluateRes:
|
|
110
108
|
"""Evaluate the provided parameters using the locally held dataset."""
|
|
111
109
|
evaluate_msg = serde.evaluate_ins_to_proto(ins)
|
|
@@ -122,8 +120,8 @@ class GrpcClientProxy(ClientProxy):
|
|
|
122
120
|
def reconnect(
|
|
123
121
|
self,
|
|
124
122
|
ins: common.ReconnectIns,
|
|
125
|
-
timeout:
|
|
126
|
-
group_id:
|
|
123
|
+
timeout: float | None,
|
|
124
|
+
group_id: int | None,
|
|
127
125
|
) -> common.DisconnectRes:
|
|
128
126
|
"""Disconnect and (optionally) reconnect later."""
|
|
129
127
|
reconnect_ins_msg = serde.reconnect_ins_to_proto(ins)
|
|
@@ -15,8 +15,6 @@
|
|
|
15
15
|
"""Implements utility function to create a gRPC server."""
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
from typing import Optional
|
|
19
|
-
|
|
20
18
|
import grpc
|
|
21
19
|
|
|
22
20
|
from flwr.common import GRPC_MAX_MESSAGE_LENGTH
|
|
@@ -36,7 +34,7 @@ def start_grpc_server( # pylint: disable=too-many-arguments,R0917
|
|
|
36
34
|
max_concurrent_workers: int = 1000,
|
|
37
35
|
max_message_length: int = GRPC_MAX_MESSAGE_LENGTH,
|
|
38
36
|
keepalive_time_ms: int = 210000,
|
|
39
|
-
certificates:
|
|
37
|
+
certificates: tuple[bytes, bytes, bytes] | None = None,
|
|
40
38
|
) -> grpc.Server:
|
|
41
39
|
"""Create and start a gRPC server running FlowerServiceServicer.
|
|
42
40
|
|
|
@@ -249,8 +249,8 @@ class FleetServicer(fleet_pb2_grpc.FleetServicer):
|
|
|
249
249
|
state=self.state_factory.state(),
|
|
250
250
|
store=self.objectstore_factory.store(),
|
|
251
251
|
)
|
|
252
|
-
except InvalidRunStatusException as e:
|
|
253
|
-
abort_grpc_context(e
|
|
252
|
+
except (InvalidRunStatusException, ValueError) as e:
|
|
253
|
+
abort_grpc_context(str(e), context)
|
|
254
254
|
|
|
255
255
|
return res
|
|
256
256
|
|
|
@@ -266,8 +266,8 @@ class FleetServicer(fleet_pb2_grpc.FleetServicer):
|
|
|
266
266
|
state=self.state_factory.state(),
|
|
267
267
|
store=self.objectstore_factory.store(),
|
|
268
268
|
)
|
|
269
|
-
except InvalidRunStatusException as e:
|
|
270
|
-
abort_grpc_context(e
|
|
269
|
+
except (InvalidRunStatusException, ValueError) as e:
|
|
270
|
+
abort_grpc_context(str(e), context)
|
|
271
271
|
|
|
272
272
|
return res
|
|
273
273
|
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
import datetime
|
|
19
|
-
from
|
|
19
|
+
from collections.abc import Callable
|
|
20
|
+
from typing import Any, cast
|
|
20
21
|
|
|
21
22
|
import grpc
|
|
22
23
|
from google.protobuf.message import Message as GrpcMessage
|
|
@@ -117,7 +118,7 @@ class NodeAuthServerInterceptor(grpc.ServerInterceptor): # type: ignore
|
|
|
117
118
|
# than the `intercept_service` function.
|
|
118
119
|
|
|
119
120
|
# Retrieve the public key
|
|
120
|
-
if isinstance(request, (RegisterNodeFleetRequest
|
|
121
|
+
if isinstance(request, (RegisterNodeFleetRequest | ActivateNodeRequest)):
|
|
121
122
|
actual_public_key = request.public_key
|
|
122
123
|
else:
|
|
123
124
|
if hasattr(request, "node"):
|
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
"""Fleet API message handlers."""
|
|
16
16
|
|
|
17
17
|
from logging import ERROR
|
|
18
|
-
from typing import Optional
|
|
19
18
|
|
|
20
19
|
from flwr.common import Message, log
|
|
21
20
|
from flwr.common.constant import (
|
|
22
21
|
HEARTBEAT_MAX_INTERVAL,
|
|
23
22
|
HEARTBEAT_MIN_INTERVAL,
|
|
23
|
+
NOOP_ACCOUNT_NAME,
|
|
24
24
|
NOOP_FLWR_AID,
|
|
25
25
|
Status,
|
|
26
26
|
)
|
|
@@ -29,9 +29,9 @@ from flwr.common.serde import (
|
|
|
29
29
|
fab_to_proto,
|
|
30
30
|
message_from_proto,
|
|
31
31
|
message_to_proto,
|
|
32
|
-
|
|
32
|
+
run_to_proto,
|
|
33
33
|
)
|
|
34
|
-
from flwr.common.typing import Fab, InvalidRunStatusException
|
|
34
|
+
from flwr.common.typing import Fab, InvalidRunStatusException, Run
|
|
35
35
|
from flwr.proto.fab_pb2 import GetFabRequest, GetFabResponse # pylint: disable=E0611
|
|
36
36
|
from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
|
|
37
37
|
ActivateNodeRequest,
|
|
@@ -60,16 +60,11 @@ from flwr.proto.message_pb2 import ( # pylint: disable=E0611
|
|
|
60
60
|
PushObjectRequest,
|
|
61
61
|
PushObjectResponse,
|
|
62
62
|
)
|
|
63
|
-
from flwr.proto.run_pb2 import
|
|
64
|
-
GetRunRequest,
|
|
65
|
-
GetRunResponse,
|
|
66
|
-
Run,
|
|
67
|
-
)
|
|
63
|
+
from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611
|
|
68
64
|
from flwr.server.superlink.linkstate import LinkState
|
|
69
65
|
from flwr.server.superlink.utils import check_abort
|
|
70
66
|
from flwr.supercore.ffs import Ffs
|
|
71
67
|
from flwr.supercore.object_store import NoObjectInStoreError, ObjectStore
|
|
72
|
-
from flwr.supercore.object_store.utils import store_mapping_and_register_objects
|
|
73
68
|
|
|
74
69
|
|
|
75
70
|
class InvalidHeartbeatIntervalError(Exception):
|
|
@@ -81,7 +76,7 @@ def register_node(
|
|
|
81
76
|
state: LinkState,
|
|
82
77
|
) -> RegisterNodeFleetResponse:
|
|
83
78
|
"""Register a node (Fleet API only)."""
|
|
84
|
-
node_id = state.create_node(NOOP_FLWR_AID, request.public_key, 0)
|
|
79
|
+
node_id = state.create_node(NOOP_FLWR_AID, NOOP_ACCOUNT_NAME, request.public_key, 0)
|
|
85
80
|
return RegisterNodeFleetResponse(node_id=node_id)
|
|
86
81
|
|
|
87
82
|
|
|
@@ -173,10 +168,11 @@ def push_messages(
|
|
|
173
168
|
"""Push Messages handler."""
|
|
174
169
|
# Convert Message from proto
|
|
175
170
|
msg = message_from_proto(message_proto=request.messages_list[0])
|
|
171
|
+
run_id = msg.metadata.run_id
|
|
176
172
|
|
|
177
173
|
# Abort if the run is not running
|
|
178
174
|
abort_msg = check_abort(
|
|
179
|
-
|
|
175
|
+
run_id,
|
|
180
176
|
[Status.PENDING, Status.STARTING, Status.FINISHED],
|
|
181
177
|
state,
|
|
182
178
|
store,
|
|
@@ -184,11 +180,12 @@ def push_messages(
|
|
|
184
180
|
if abort_msg:
|
|
185
181
|
raise InvalidRunStatusException(abort_msg)
|
|
186
182
|
|
|
187
|
-
# Store Message in State
|
|
188
|
-
message_id: Optional[str] = state.store_message_res(message=msg)
|
|
189
|
-
|
|
190
183
|
# Store Message object to descendants mapping and preregister objects
|
|
191
|
-
objects_to_push =
|
|
184
|
+
objects_to_push: set[str] = set()
|
|
185
|
+
for object_tree in request.message_object_trees:
|
|
186
|
+
objects_to_push |= set(store.preregister(run_id, object_tree))
|
|
187
|
+
# Store Message in State
|
|
188
|
+
message_id: str | None = state.store_message_res(message=msg)
|
|
192
189
|
|
|
193
190
|
# Build response
|
|
194
191
|
response = PushMessagesResponse(
|
|
@@ -203,10 +200,8 @@ def get_run(
|
|
|
203
200
|
request: GetRunRequest, state: LinkState, store: ObjectStore
|
|
204
201
|
) -> GetRunResponse:
|
|
205
202
|
"""Get run information."""
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if run is None:
|
|
209
|
-
return GetRunResponse()
|
|
203
|
+
# Validate that the requesting SuperNode is part of the federation
|
|
204
|
+
run = _validate_node_in_federation(state, request.node.node_id, request.run_id)
|
|
210
205
|
|
|
211
206
|
# Abort if the run is not running
|
|
212
207
|
abort_msg = check_abort(
|
|
@@ -218,21 +213,16 @@ def get_run(
|
|
|
218
213
|
if abort_msg:
|
|
219
214
|
raise InvalidRunStatusException(abort_msg)
|
|
220
215
|
|
|
221
|
-
return GetRunResponse(
|
|
222
|
-
run=Run(
|
|
223
|
-
run_id=run.run_id,
|
|
224
|
-
fab_id=run.fab_id,
|
|
225
|
-
fab_version=run.fab_version,
|
|
226
|
-
override_config=user_config_to_proto(run.override_config),
|
|
227
|
-
fab_hash=run.fab_hash,
|
|
228
|
-
)
|
|
229
|
-
)
|
|
216
|
+
return GetRunResponse(run=run_to_proto(run))
|
|
230
217
|
|
|
231
218
|
|
|
232
219
|
def get_fab(
|
|
233
220
|
request: GetFabRequest, ffs: Ffs, state: LinkState, store: ObjectStore
|
|
234
221
|
) -> GetFabResponse:
|
|
235
222
|
"""Get FAB."""
|
|
223
|
+
# Validate that the requesting SuperNode is part of the federation
|
|
224
|
+
_validate_node_in_federation(state, request.node.node_id, request.run_id)
|
|
225
|
+
|
|
236
226
|
# Abort if the run is not running
|
|
237
227
|
abort_msg = check_abort(
|
|
238
228
|
request.run_id,
|
|
@@ -329,3 +319,19 @@ def _validate_heartbeat_interval(interval: float) -> None:
|
|
|
329
319
|
f"Heartbeat interval {interval} is out of bounds "
|
|
330
320
|
f"[{HEARTBEAT_MIN_INTERVAL}, {HEARTBEAT_MAX_INTERVAL}]."
|
|
331
321
|
)
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def _validate_node_in_federation(
|
|
325
|
+
state: LinkState,
|
|
326
|
+
node_id: int,
|
|
327
|
+
run_id: int,
|
|
328
|
+
) -> Run:
|
|
329
|
+
"""Raise if the requesting SuperNode is not part of the federation the run belongs
|
|
330
|
+
to."""
|
|
331
|
+
run = state.get_run(run_id)
|
|
332
|
+
if not run:
|
|
333
|
+
raise ValueError(f"Run ID not found: {run_id}")
|
|
334
|
+
|
|
335
|
+
if not state.federation_manager.has_node(node_id, run.federation):
|
|
336
|
+
raise ValueError(f"SuperNode is not part of the federation '{run.federation}'.")
|
|
337
|
+
return run
|
|
@@ -17,8 +17,8 @@
|
|
|
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
|
|
|
@@ -16,8 +16,8 @@
|
|
|
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
|
|
|
@@ -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)
|
|
@@ -20,11 +20,11 @@ import secrets
|
|
|
20
20
|
import threading
|
|
21
21
|
import time
|
|
22
22
|
import traceback
|
|
23
|
+
from collections.abc import Callable
|
|
23
24
|
from concurrent.futures import ThreadPoolExecutor
|
|
24
25
|
from logging import DEBUG, ERROR, INFO, WARN
|
|
25
26
|
from pathlib import Path
|
|
26
27
|
from queue import Empty, Queue
|
|
27
|
-
from typing import Callable, Optional
|
|
28
28
|
from uuid import uuid4
|
|
29
29
|
|
|
30
30
|
from flwr.app.error import Error
|
|
@@ -34,6 +34,7 @@ from flwr.clientapp.utils import get_load_client_app_fn
|
|
|
34
34
|
from flwr.common import Message
|
|
35
35
|
from flwr.common.constant import (
|
|
36
36
|
HEARTBEAT_INTERVAL_INF,
|
|
37
|
+
NOOP_ACCOUNT_NAME,
|
|
37
38
|
NOOP_FLWR_AID,
|
|
38
39
|
NUM_PARTITIONS_KEY,
|
|
39
40
|
PARTITION_ID_KEY,
|
|
@@ -43,6 +44,8 @@ from flwr.common.logger import log
|
|
|
43
44
|
from flwr.common.typing import Run
|
|
44
45
|
from flwr.server.superlink.linkstate import LinkState, LinkStateFactory
|
|
45
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
|
|
46
49
|
|
|
47
50
|
from .backend import Backend, error_messages_backends, supported_backends
|
|
48
51
|
|
|
@@ -61,6 +64,7 @@ def _register_nodes(
|
|
|
61
64
|
# use NOOP_FLWR_AID as owner_aid and
|
|
62
65
|
# use random bytes as public key
|
|
63
66
|
NOOP_FLWR_AID,
|
|
67
|
+
NOOP_ACCOUNT_NAME,
|
|
64
68
|
secrets.token_bytes(32),
|
|
65
69
|
heartbeat_interval=HEARTBEAT_INTERVAL_INF,
|
|
66
70
|
)
|
|
@@ -75,7 +79,7 @@ def _register_nodes(
|
|
|
75
79
|
def _register_node_info_stores(
|
|
76
80
|
nodes_mapping: NodeToPartitionMapping,
|
|
77
81
|
run: Run,
|
|
78
|
-
app_dir:
|
|
82
|
+
app_dir: str | None = None,
|
|
79
83
|
) -> dict[int, DeprecatedRunInfoStore]:
|
|
80
84
|
"""Create DeprecatedRunInfoStore objects and register the context for the run."""
|
|
81
85
|
node_info_store: dict[int, DeprecatedRunInfoStore] = {}
|
|
@@ -270,12 +274,12 @@ def start_vce(
|
|
|
270
274
|
is_app: bool,
|
|
271
275
|
f_stop: threading.Event,
|
|
272
276
|
run: Run,
|
|
273
|
-
flwr_dir:
|
|
274
|
-
client_app:
|
|
275
|
-
client_app_attr:
|
|
276
|
-
num_supernodes:
|
|
277
|
-
state_factory:
|
|
278
|
-
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,
|
|
279
283
|
) -> None:
|
|
280
284
|
"""Start Fleet API with the Simulation Engine."""
|
|
281
285
|
nodes_mapping = {}
|
|
@@ -313,7 +317,9 @@ def start_vce(
|
|
|
313
317
|
if not state_factory:
|
|
314
318
|
log(INFO, "A StateFactory was not supplied to the SimulationEngine.")
|
|
315
319
|
# Create an empty in-memory state factory
|
|
316
|
-
state_factory = LinkStateFactory(
|
|
320
|
+
state_factory = LinkStateFactory(
|
|
321
|
+
FLWR_IN_MEMORY_DB_NAME, NoOpFederationManager(), ObjectStoreFactory()
|
|
322
|
+
)
|
|
317
323
|
log(INFO, "Created new %s.", state_factory.__class__.__name__)
|
|
318
324
|
|
|
319
325
|
if num_supernodes:
|