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
flwr/server/client_proxy.py
CHANGED
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
from abc import ABC, abstractmethod
|
|
19
|
-
from typing import Optional
|
|
20
19
|
|
|
21
20
|
from flwr.common import (
|
|
22
21
|
DisconnectRes,
|
|
@@ -46,8 +45,8 @@ class ClientProxy(ABC):
|
|
|
46
45
|
def get_properties(
|
|
47
46
|
self,
|
|
48
47
|
ins: GetPropertiesIns,
|
|
49
|
-
timeout:
|
|
50
|
-
group_id:
|
|
48
|
+
timeout: float | None,
|
|
49
|
+
group_id: int | None,
|
|
51
50
|
) -> GetPropertiesRes:
|
|
52
51
|
"""Return the client's properties."""
|
|
53
52
|
|
|
@@ -55,8 +54,8 @@ class ClientProxy(ABC):
|
|
|
55
54
|
def get_parameters(
|
|
56
55
|
self,
|
|
57
56
|
ins: GetParametersIns,
|
|
58
|
-
timeout:
|
|
59
|
-
group_id:
|
|
57
|
+
timeout: float | None,
|
|
58
|
+
group_id: int | None,
|
|
60
59
|
) -> GetParametersRes:
|
|
61
60
|
"""Return the current local model parameters."""
|
|
62
61
|
|
|
@@ -64,8 +63,8 @@ class ClientProxy(ABC):
|
|
|
64
63
|
def fit(
|
|
65
64
|
self,
|
|
66
65
|
ins: FitIns,
|
|
67
|
-
timeout:
|
|
68
|
-
group_id:
|
|
66
|
+
timeout: float | None,
|
|
67
|
+
group_id: int | None,
|
|
69
68
|
) -> FitRes:
|
|
70
69
|
"""Refine the provided parameters using the locally held dataset."""
|
|
71
70
|
|
|
@@ -73,8 +72,8 @@ class ClientProxy(ABC):
|
|
|
73
72
|
def evaluate(
|
|
74
73
|
self,
|
|
75
74
|
ins: EvaluateIns,
|
|
76
|
-
timeout:
|
|
77
|
-
group_id:
|
|
75
|
+
timeout: float | None,
|
|
76
|
+
group_id: int | None,
|
|
78
77
|
) -> EvaluateRes:
|
|
79
78
|
"""Evaluate the provided parameters using the locally held dataset."""
|
|
80
79
|
|
|
@@ -82,7 +81,7 @@ class ClientProxy(ABC):
|
|
|
82
81
|
def reconnect(
|
|
83
82
|
self,
|
|
84
83
|
ins: ReconnectIns,
|
|
85
|
-
timeout:
|
|
86
|
-
group_id:
|
|
84
|
+
timeout: float | None,
|
|
85
|
+
group_id: int | None,
|
|
87
86
|
) -> DisconnectRes:
|
|
88
87
|
"""Disconnect and (optionally) reconnect later."""
|
flwr/server/compat/app.py
CHANGED
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
from logging import INFO
|
|
19
|
-
from typing import Optional
|
|
20
19
|
|
|
21
20
|
from flwr.common.logger import log
|
|
22
21
|
from flwr.server.client_manager import ClientManager
|
|
@@ -32,10 +31,10 @@ from .app_utils import start_update_client_manager_thread
|
|
|
32
31
|
def start_grid( # pylint: disable=too-many-arguments, too-many-locals
|
|
33
32
|
*,
|
|
34
33
|
grid: Grid,
|
|
35
|
-
server:
|
|
36
|
-
config:
|
|
37
|
-
strategy:
|
|
38
|
-
client_manager:
|
|
34
|
+
server: Server | None = None,
|
|
35
|
+
config: ServerConfig | None = None,
|
|
36
|
+
strategy: Strategy | None = None,
|
|
37
|
+
client_manager: ClientManager | None = None,
|
|
39
38
|
) -> History:
|
|
40
39
|
"""Start a Flower server.
|
|
41
40
|
|
flwr/server/compat/app_utils.py
CHANGED
|
@@ -15,8 +15,6 @@
|
|
|
15
15
|
"""Flower ClientProxy implementation using Grid."""
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
from typing import Optional
|
|
19
|
-
|
|
20
18
|
from flwr import common
|
|
21
19
|
from flwr.common import Message, MessageType, MessageTypeLegacy, RecordDict
|
|
22
20
|
from flwr.common import recorddict_compat as compat
|
|
@@ -37,8 +35,8 @@ class GridClientProxy(ClientProxy):
|
|
|
37
35
|
def get_properties(
|
|
38
36
|
self,
|
|
39
37
|
ins: common.GetPropertiesIns,
|
|
40
|
-
timeout:
|
|
41
|
-
group_id:
|
|
38
|
+
timeout: float | None,
|
|
39
|
+
group_id: int | None,
|
|
42
40
|
) -> common.GetPropertiesRes:
|
|
43
41
|
"""Return client's properties."""
|
|
44
42
|
# Ins to RecordDict
|
|
@@ -53,8 +51,8 @@ class GridClientProxy(ClientProxy):
|
|
|
53
51
|
def get_parameters(
|
|
54
52
|
self,
|
|
55
53
|
ins: common.GetParametersIns,
|
|
56
|
-
timeout:
|
|
57
|
-
group_id:
|
|
54
|
+
timeout: float | None,
|
|
55
|
+
group_id: int | None,
|
|
58
56
|
) -> common.GetParametersRes:
|
|
59
57
|
"""Return the current local model parameters."""
|
|
60
58
|
# Ins to RecordDict
|
|
@@ -67,7 +65,7 @@ class GridClientProxy(ClientProxy):
|
|
|
67
65
|
return compat.recorddict_to_getparametersres(in_recorddict, False)
|
|
68
66
|
|
|
69
67
|
def fit(
|
|
70
|
-
self, ins: common.FitIns, timeout:
|
|
68
|
+
self, ins: common.FitIns, timeout: float | None, group_id: int | None
|
|
71
69
|
) -> common.FitRes:
|
|
72
70
|
"""Train model parameters on the locally held dataset."""
|
|
73
71
|
# Ins to RecordDict
|
|
@@ -80,7 +78,7 @@ class GridClientProxy(ClientProxy):
|
|
|
80
78
|
return compat.recorddict_to_fitres(in_recorddict, keep_input=False)
|
|
81
79
|
|
|
82
80
|
def evaluate(
|
|
83
|
-
self, ins: common.EvaluateIns, timeout:
|
|
81
|
+
self, ins: common.EvaluateIns, timeout: float | None, group_id: int | None
|
|
84
82
|
) -> common.EvaluateRes:
|
|
85
83
|
"""Evaluate model parameters on the locally held dataset."""
|
|
86
84
|
# Ins to RecordDict
|
|
@@ -95,8 +93,8 @@ class GridClientProxy(ClientProxy):
|
|
|
95
93
|
def reconnect(
|
|
96
94
|
self,
|
|
97
95
|
ins: common.ReconnectIns,
|
|
98
|
-
timeout:
|
|
99
|
-
group_id:
|
|
96
|
+
timeout: float | None,
|
|
97
|
+
group_id: int | None,
|
|
100
98
|
) -> common.DisconnectRes:
|
|
101
99
|
"""Disconnect and (optionally) reconnect later."""
|
|
102
100
|
return common.DisconnectRes(reason="") # Nothing to do here (yet)
|
|
@@ -105,8 +103,8 @@ class GridClientProxy(ClientProxy):
|
|
|
105
103
|
self,
|
|
106
104
|
recorddict: RecordDict,
|
|
107
105
|
message_type: str,
|
|
108
|
-
timeout:
|
|
109
|
-
group_id:
|
|
106
|
+
timeout: float | None,
|
|
107
|
+
group_id: int | None,
|
|
110
108
|
) -> RecordDict:
|
|
111
109
|
|
|
112
110
|
# Create message
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
from dataclasses import dataclass
|
|
19
|
-
from typing import Optional
|
|
20
19
|
|
|
21
20
|
from flwr.common import Context
|
|
22
21
|
|
|
@@ -38,9 +37,9 @@ class LegacyContext(Context):
|
|
|
38
37
|
def __init__( # pylint: disable=too-many-arguments
|
|
39
38
|
self,
|
|
40
39
|
context: Context,
|
|
41
|
-
config:
|
|
42
|
-
strategy:
|
|
43
|
-
client_manager:
|
|
40
|
+
config: ServerConfig | None = None,
|
|
41
|
+
strategy: Strategy | None = None,
|
|
42
|
+
client_manager: ClientManager | None = None,
|
|
44
43
|
) -> None:
|
|
45
44
|
if config is None:
|
|
46
45
|
config = ServerConfig()
|
flwr/server/grid/grid.py
CHANGED
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
|
|
18
18
|
from abc import ABC, abstractmethod
|
|
19
19
|
from collections.abc import Iterable
|
|
20
|
-
from typing import Optional
|
|
21
20
|
|
|
22
21
|
from flwr.common import Message, RecordDict
|
|
23
22
|
from flwr.common.typing import Run
|
|
@@ -52,7 +51,7 @@ class Grid(ABC):
|
|
|
52
51
|
message_type: str,
|
|
53
52
|
dst_node_id: int,
|
|
54
53
|
group_id: str,
|
|
55
|
-
ttl:
|
|
54
|
+
ttl: float | None = None,
|
|
56
55
|
) -> Message:
|
|
57
56
|
"""Create a new message with specified parameters.
|
|
58
57
|
|
|
@@ -130,7 +129,7 @@ class Grid(ABC):
|
|
|
130
129
|
self,
|
|
131
130
|
messages: Iterable[Message],
|
|
132
131
|
*,
|
|
133
|
-
timeout:
|
|
132
|
+
timeout: float | None = None,
|
|
134
133
|
) -> Iterable[Message]:
|
|
135
134
|
"""Push messages to specified node IDs and pull the reply messages.
|
|
136
135
|
|
flwr/server/grid/grpc_grid.py
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import time
|
|
19
19
|
from collections.abc import Iterable
|
|
20
20
|
from logging import DEBUG, ERROR, WARNING
|
|
21
|
-
from typing import
|
|
21
|
+
from typing import cast
|
|
22
22
|
|
|
23
23
|
import grpc
|
|
24
24
|
|
|
@@ -119,13 +119,13 @@ class GrpcGrid(Grid):
|
|
|
119
119
|
def __init__( # pylint: disable=too-many-arguments
|
|
120
120
|
self,
|
|
121
121
|
serverappio_service_address: str = SERVERAPPIO_API_DEFAULT_CLIENT_ADDRESS,
|
|
122
|
-
root_certificates:
|
|
122
|
+
root_certificates: bytes | None = None,
|
|
123
123
|
) -> None:
|
|
124
124
|
self._addr = serverappio_service_address
|
|
125
125
|
self._cert = root_certificates
|
|
126
|
-
self._run:
|
|
127
|
-
self._grpc_stub:
|
|
128
|
-
self._channel:
|
|
126
|
+
self._run: Run | None = None
|
|
127
|
+
self._grpc_stub: ServerAppIoStub | None = None
|
|
128
|
+
self._channel: grpc.Channel | None = None
|
|
129
129
|
self.node = Node(node_id=SUPERLINK_NODE_ID)
|
|
130
130
|
self._retry_invoker = _make_simple_grpc_retry_invoker()
|
|
131
131
|
super().__init__()
|
|
@@ -200,7 +200,7 @@ class GrpcGrid(Grid):
|
|
|
200
200
|
message_type: str,
|
|
201
201
|
dst_node_id: int,
|
|
202
202
|
group_id: str,
|
|
203
|
-
ttl:
|
|
203
|
+
ttl: float | None = None,
|
|
204
204
|
) -> Message:
|
|
205
205
|
"""Create a new message with specified parameters.
|
|
206
206
|
|
|
@@ -313,7 +313,9 @@ class GrpcGrid(Grid):
|
|
|
313
313
|
)
|
|
314
314
|
# Pull Messages from store
|
|
315
315
|
inflated_msgs: list[Message] = []
|
|
316
|
-
for msg_proto, msg_tree in zip(
|
|
316
|
+
for msg_proto, msg_tree in zip(
|
|
317
|
+
res.messages_list, res.message_object_trees, strict=True
|
|
318
|
+
):
|
|
317
319
|
msg_id = msg_proto.metadata.message_id
|
|
318
320
|
try:
|
|
319
321
|
all_object_contents = pull_objects(
|
|
@@ -376,7 +378,7 @@ class GrpcGrid(Grid):
|
|
|
376
378
|
self,
|
|
377
379
|
messages: Iterable[Message],
|
|
378
380
|
*,
|
|
379
|
-
timeout:
|
|
381
|
+
timeout: float | None = None,
|
|
380
382
|
) -> Iterable[Message]:
|
|
381
383
|
"""Push messages to specified node IDs and pull the reply messages.
|
|
382
384
|
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import time
|
|
19
19
|
from collections.abc import Iterable
|
|
20
|
-
from typing import
|
|
20
|
+
from typing import cast
|
|
21
21
|
from uuid import uuid4
|
|
22
22
|
|
|
23
23
|
from flwr.common import Message, RecordDict
|
|
@@ -48,7 +48,7 @@ class InMemoryGrid(Grid):
|
|
|
48
48
|
state_factory: LinkStateFactory,
|
|
49
49
|
pull_interval: float = 0.1,
|
|
50
50
|
) -> None:
|
|
51
|
-
self._run:
|
|
51
|
+
self._run: Run | None = None
|
|
52
52
|
self.state = state_factory.state()
|
|
53
53
|
self.pull_interval = pull_interval
|
|
54
54
|
self.node = Node(node_id=SUPERLINK_NODE_ID)
|
|
@@ -81,7 +81,7 @@ class InMemoryGrid(Grid):
|
|
|
81
81
|
message_type: str,
|
|
82
82
|
dst_node_id: int,
|
|
83
83
|
group_id: str,
|
|
84
|
-
ttl:
|
|
84
|
+
ttl: float | None = None,
|
|
85
85
|
) -> Message:
|
|
86
86
|
"""Create a new message with specified parameters.
|
|
87
87
|
|
|
@@ -143,7 +143,7 @@ class InMemoryGrid(Grid):
|
|
|
143
143
|
self,
|
|
144
144
|
messages: Iterable[Message],
|
|
145
145
|
*,
|
|
146
|
-
timeout:
|
|
146
|
+
timeout: float | None = None,
|
|
147
147
|
) -> Iterable[Message]:
|
|
148
148
|
"""Push messages to specified node IDs and pull the reply messages.
|
|
149
149
|
|
flwr/server/run_serverapp.py
CHANGED
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
from logging import DEBUG
|
|
19
|
-
from typing import Optional
|
|
20
19
|
|
|
21
20
|
from flwr.common import Context
|
|
22
21
|
from flwr.common.logger import log
|
|
@@ -30,8 +29,8 @@ def run(
|
|
|
30
29
|
grid: Grid,
|
|
31
30
|
context: Context,
|
|
32
31
|
server_app_dir: str,
|
|
33
|
-
server_app_attr:
|
|
34
|
-
loaded_server_app:
|
|
32
|
+
server_app_attr: str | None = None,
|
|
33
|
+
loaded_server_app: ServerApp | None = None,
|
|
35
34
|
) -> Context:
|
|
36
35
|
"""Run ServerApp with a given Grid."""
|
|
37
36
|
if not (server_app_attr is None) ^ (loaded_server_app is None):
|
flwr/server/server.py
CHANGED
|
@@ -19,7 +19,6 @@ import concurrent.futures
|
|
|
19
19
|
import io
|
|
20
20
|
import timeit
|
|
21
21
|
from logging import INFO, WARN
|
|
22
|
-
from typing import Optional, Union
|
|
23
22
|
|
|
24
23
|
from flwr.common import (
|
|
25
24
|
Code,
|
|
@@ -43,15 +42,15 @@ from .server_config import ServerConfig
|
|
|
43
42
|
|
|
44
43
|
FitResultsAndFailures = tuple[
|
|
45
44
|
list[tuple[ClientProxy, FitRes]],
|
|
46
|
-
list[
|
|
45
|
+
list[tuple[ClientProxy, FitRes] | BaseException],
|
|
47
46
|
]
|
|
48
47
|
EvaluateResultsAndFailures = tuple[
|
|
49
48
|
list[tuple[ClientProxy, EvaluateRes]],
|
|
50
|
-
list[
|
|
49
|
+
list[tuple[ClientProxy, EvaluateRes] | BaseException],
|
|
51
50
|
]
|
|
52
51
|
ReconnectResultsAndFailures = tuple[
|
|
53
52
|
list[tuple[ClientProxy, DisconnectRes]],
|
|
54
|
-
list[
|
|
53
|
+
list[tuple[ClientProxy, DisconnectRes] | BaseException],
|
|
55
54
|
]
|
|
56
55
|
|
|
57
56
|
|
|
@@ -62,16 +61,16 @@ class Server:
|
|
|
62
61
|
self,
|
|
63
62
|
*,
|
|
64
63
|
client_manager: ClientManager,
|
|
65
|
-
strategy:
|
|
64
|
+
strategy: Strategy | None = None,
|
|
66
65
|
) -> None:
|
|
67
66
|
self._client_manager: ClientManager = client_manager
|
|
68
67
|
self.parameters: Parameters = Parameters(
|
|
69
68
|
tensors=[], tensor_type="numpy.ndarray"
|
|
70
69
|
)
|
|
71
70
|
self.strategy: Strategy = strategy if strategy is not None else FedAvg()
|
|
72
|
-
self.max_workers:
|
|
71
|
+
self.max_workers: int | None = None
|
|
73
72
|
|
|
74
|
-
def set_max_workers(self, max_workers:
|
|
73
|
+
def set_max_workers(self, max_workers: int | None) -> None:
|
|
75
74
|
"""Set the max_workers used by ThreadPoolExecutor."""
|
|
76
75
|
self.max_workers = max_workers
|
|
77
76
|
|
|
@@ -84,7 +83,7 @@ class Server:
|
|
|
84
83
|
return self._client_manager
|
|
85
84
|
|
|
86
85
|
# pylint: disable=too-many-locals
|
|
87
|
-
def fit(self, num_rounds: int, timeout:
|
|
86
|
+
def fit(self, num_rounds: int, timeout: float | None) -> tuple[History, float]:
|
|
88
87
|
"""Run federated averaging for a number of rounds."""
|
|
89
88
|
history = History()
|
|
90
89
|
|
|
@@ -161,10 +160,8 @@ class Server:
|
|
|
161
160
|
def evaluate_round(
|
|
162
161
|
self,
|
|
163
162
|
server_round: int,
|
|
164
|
-
timeout:
|
|
165
|
-
) ->
|
|
166
|
-
tuple[Optional[float], dict[str, Scalar], EvaluateResultsAndFailures]
|
|
167
|
-
]:
|
|
163
|
+
timeout: float | None,
|
|
164
|
+
) -> tuple[float | None, dict[str, Scalar], EvaluateResultsAndFailures] | None:
|
|
168
165
|
"""Validate current global model on a number of clients."""
|
|
169
166
|
# Get clients and their respective instructions from strategy
|
|
170
167
|
client_instructions = self.strategy.configure_evaluate(
|
|
@@ -198,7 +195,7 @@ class Server:
|
|
|
198
195
|
|
|
199
196
|
# Aggregate the evaluation results
|
|
200
197
|
aggregated_result: tuple[
|
|
201
|
-
|
|
198
|
+
float | None,
|
|
202
199
|
dict[str, Scalar],
|
|
203
200
|
] = self.strategy.aggregate_evaluate(server_round, results, failures)
|
|
204
201
|
|
|
@@ -208,10 +205,8 @@ class Server:
|
|
|
208
205
|
def fit_round(
|
|
209
206
|
self,
|
|
210
207
|
server_round: int,
|
|
211
|
-
timeout:
|
|
212
|
-
) ->
|
|
213
|
-
tuple[Optional[Parameters], dict[str, Scalar], FitResultsAndFailures]
|
|
214
|
-
]:
|
|
208
|
+
timeout: float | None,
|
|
209
|
+
) -> tuple[Parameters | None, dict[str, Scalar], FitResultsAndFailures] | None:
|
|
215
210
|
"""Perform a single round of federated averaging."""
|
|
216
211
|
# Get clients and their respective instructions from strategy
|
|
217
212
|
client_instructions = self.strategy.configure_fit(
|
|
@@ -246,14 +241,14 @@ class Server:
|
|
|
246
241
|
|
|
247
242
|
# Aggregate training results
|
|
248
243
|
aggregated_result: tuple[
|
|
249
|
-
|
|
244
|
+
Parameters | None,
|
|
250
245
|
dict[str, Scalar],
|
|
251
246
|
] = self.strategy.aggregate_fit(server_round, results, failures)
|
|
252
247
|
|
|
253
248
|
parameters_aggregated, metrics_aggregated = aggregated_result
|
|
254
249
|
return parameters_aggregated, metrics_aggregated, (results, failures)
|
|
255
250
|
|
|
256
|
-
def disconnect_all_clients(self, timeout:
|
|
251
|
+
def disconnect_all_clients(self, timeout: float | None) -> None:
|
|
257
252
|
"""Send shutdown signal to all clients."""
|
|
258
253
|
all_clients = self._client_manager.all()
|
|
259
254
|
clients = [all_clients[k] for k in all_clients.keys()]
|
|
@@ -266,11 +261,11 @@ class Server:
|
|
|
266
261
|
)
|
|
267
262
|
|
|
268
263
|
def _get_initial_parameters(
|
|
269
|
-
self, server_round: int, timeout:
|
|
264
|
+
self, server_round: int, timeout: float | None
|
|
270
265
|
) -> Parameters:
|
|
271
266
|
"""Get initial parameters from one of the available clients."""
|
|
272
267
|
# Server-side parameter initialization
|
|
273
|
-
parameters:
|
|
268
|
+
parameters: Parameters | None = self.strategy.initialize_parameters(
|
|
274
269
|
client_manager=self._client_manager
|
|
275
270
|
)
|
|
276
271
|
if parameters is not None:
|
|
@@ -297,8 +292,8 @@ class Server:
|
|
|
297
292
|
|
|
298
293
|
def reconnect_clients(
|
|
299
294
|
client_instructions: list[tuple[ClientProxy, ReconnectIns]],
|
|
300
|
-
max_workers:
|
|
301
|
-
timeout:
|
|
295
|
+
max_workers: int | None,
|
|
296
|
+
timeout: float | None,
|
|
302
297
|
) -> ReconnectResultsAndFailures:
|
|
303
298
|
"""Instruct clients to disconnect and never reconnect."""
|
|
304
299
|
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
@@ -313,7 +308,7 @@ def reconnect_clients(
|
|
|
313
308
|
|
|
314
309
|
# Gather results
|
|
315
310
|
results: list[tuple[ClientProxy, DisconnectRes]] = []
|
|
316
|
-
failures: list[
|
|
311
|
+
failures: list[tuple[ClientProxy, DisconnectRes] | BaseException] = []
|
|
317
312
|
for future in finished_fs:
|
|
318
313
|
failure = future.exception()
|
|
319
314
|
if failure is not None:
|
|
@@ -327,7 +322,7 @@ def reconnect_clients(
|
|
|
327
322
|
def reconnect_client(
|
|
328
323
|
client: ClientProxy,
|
|
329
324
|
reconnect: ReconnectIns,
|
|
330
|
-
timeout:
|
|
325
|
+
timeout: float | None,
|
|
331
326
|
) -> tuple[ClientProxy, DisconnectRes]:
|
|
332
327
|
"""Instruct client to disconnect and (optionally) reconnect later."""
|
|
333
328
|
disconnect = client.reconnect(
|
|
@@ -340,8 +335,8 @@ def reconnect_client(
|
|
|
340
335
|
|
|
341
336
|
def fit_clients(
|
|
342
337
|
client_instructions: list[tuple[ClientProxy, FitIns]],
|
|
343
|
-
max_workers:
|
|
344
|
-
timeout:
|
|
338
|
+
max_workers: int | None,
|
|
339
|
+
timeout: float | None,
|
|
345
340
|
group_id: int,
|
|
346
341
|
) -> FitResultsAndFailures:
|
|
347
342
|
"""Refine parameters concurrently on all selected clients."""
|
|
@@ -357,7 +352,7 @@ def fit_clients(
|
|
|
357
352
|
|
|
358
353
|
# Gather results
|
|
359
354
|
results: list[tuple[ClientProxy, FitRes]] = []
|
|
360
|
-
failures: list[
|
|
355
|
+
failures: list[tuple[ClientProxy, FitRes] | BaseException] = []
|
|
361
356
|
for future in finished_fs:
|
|
362
357
|
_handle_finished_future_after_fit(
|
|
363
358
|
future=future, results=results, failures=failures
|
|
@@ -366,7 +361,7 @@ def fit_clients(
|
|
|
366
361
|
|
|
367
362
|
|
|
368
363
|
def fit_client(
|
|
369
|
-
client: ClientProxy, ins: FitIns, timeout:
|
|
364
|
+
client: ClientProxy, ins: FitIns, timeout: float | None, group_id: int
|
|
370
365
|
) -> tuple[ClientProxy, FitRes]:
|
|
371
366
|
"""Refine parameters on a single client."""
|
|
372
367
|
fit_res = client.fit(ins, timeout=timeout, group_id=group_id)
|
|
@@ -376,7 +371,7 @@ def fit_client(
|
|
|
376
371
|
def _handle_finished_future_after_fit(
|
|
377
372
|
future: concurrent.futures.Future, # type: ignore
|
|
378
373
|
results: list[tuple[ClientProxy, FitRes]],
|
|
379
|
-
failures: list[
|
|
374
|
+
failures: list[tuple[ClientProxy, FitRes] | BaseException],
|
|
380
375
|
) -> None:
|
|
381
376
|
"""Convert finished future into either a result or a failure."""
|
|
382
377
|
# Check if there was an exception
|
|
@@ -400,8 +395,8 @@ def _handle_finished_future_after_fit(
|
|
|
400
395
|
|
|
401
396
|
def evaluate_clients(
|
|
402
397
|
client_instructions: list[tuple[ClientProxy, EvaluateIns]],
|
|
403
|
-
max_workers:
|
|
404
|
-
timeout:
|
|
398
|
+
max_workers: int | None,
|
|
399
|
+
timeout: float | None,
|
|
405
400
|
group_id: int,
|
|
406
401
|
) -> EvaluateResultsAndFailures:
|
|
407
402
|
"""Evaluate parameters concurrently on all selected clients."""
|
|
@@ -417,7 +412,7 @@ def evaluate_clients(
|
|
|
417
412
|
|
|
418
413
|
# Gather results
|
|
419
414
|
results: list[tuple[ClientProxy, EvaluateRes]] = []
|
|
420
|
-
failures: list[
|
|
415
|
+
failures: list[tuple[ClientProxy, EvaluateRes] | BaseException] = []
|
|
421
416
|
for future in finished_fs:
|
|
422
417
|
_handle_finished_future_after_evaluate(
|
|
423
418
|
future=future, results=results, failures=failures
|
|
@@ -428,7 +423,7 @@ def evaluate_clients(
|
|
|
428
423
|
def evaluate_client(
|
|
429
424
|
client: ClientProxy,
|
|
430
425
|
ins: EvaluateIns,
|
|
431
|
-
timeout:
|
|
426
|
+
timeout: float | None,
|
|
432
427
|
group_id: int,
|
|
433
428
|
) -> tuple[ClientProxy, EvaluateRes]:
|
|
434
429
|
"""Evaluate parameters on a single client."""
|
|
@@ -439,7 +434,7 @@ def evaluate_client(
|
|
|
439
434
|
def _handle_finished_future_after_evaluate(
|
|
440
435
|
future: concurrent.futures.Future, # type: ignore
|
|
441
436
|
results: list[tuple[ClientProxy, EvaluateRes]],
|
|
442
|
-
failures: list[
|
|
437
|
+
failures: list[tuple[ClientProxy, EvaluateRes] | BaseException],
|
|
443
438
|
) -> None:
|
|
444
439
|
"""Convert finished future into either a result or a failure."""
|
|
445
440
|
# Check if there was an exception
|
|
@@ -462,10 +457,10 @@ def _handle_finished_future_after_evaluate(
|
|
|
462
457
|
|
|
463
458
|
|
|
464
459
|
def init_defaults(
|
|
465
|
-
server:
|
|
466
|
-
config:
|
|
467
|
-
strategy:
|
|
468
|
-
client_manager:
|
|
460
|
+
server: Server | None,
|
|
461
|
+
config: ServerConfig | None,
|
|
462
|
+
strategy: Strategy | None,
|
|
463
|
+
client_manager: ClientManager | None,
|
|
469
464
|
) -> tuple[Server, ServerConfig]:
|
|
470
465
|
"""Create server instance if none was given."""
|
|
471
466
|
if server is None:
|
flwr/server/server_app.py
CHANGED
|
@@ -16,9 +16,8 @@
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
import inspect
|
|
19
|
-
from collections.abc import Iterator
|
|
19
|
+
from collections.abc import Callable, Iterator
|
|
20
20
|
from contextlib import contextmanager
|
|
21
|
-
from typing import Callable, Optional
|
|
22
21
|
|
|
23
22
|
from flwr.common import Context
|
|
24
23
|
from flwr.common.logger import warn_deprecated_feature_with_example
|
|
@@ -118,11 +117,11 @@ class ServerApp: # pylint: disable=too-many-instance-attributes
|
|
|
118
117
|
# pylint: disable=too-many-arguments,too-many-positional-arguments
|
|
119
118
|
def __init__(
|
|
120
119
|
self,
|
|
121
|
-
server:
|
|
122
|
-
config:
|
|
123
|
-
strategy:
|
|
124
|
-
client_manager:
|
|
125
|
-
server_fn:
|
|
120
|
+
server: Server | None = None,
|
|
121
|
+
config: ServerConfig | None = None,
|
|
122
|
+
strategy: Strategy | None = None,
|
|
123
|
+
client_manager: ClientManager | None = None,
|
|
124
|
+
server_fn: ServerFn | None = None,
|
|
126
125
|
) -> None:
|
|
127
126
|
if any([server, config, strategy, client_manager]):
|
|
128
127
|
warn_deprecated_feature_with_example(
|
|
@@ -148,7 +147,7 @@ class ServerApp: # pylint: disable=too-many-instance-attributes
|
|
|
148
147
|
self._strategy = strategy
|
|
149
148
|
self._client_manager = client_manager
|
|
150
149
|
self._server_fn = server_fn
|
|
151
|
-
self._main:
|
|
150
|
+
self._main: ServerAppCallable | None = None
|
|
152
151
|
self._lifespan = _empty_lifespan
|
|
153
152
|
|
|
154
153
|
def __call__(self, grid: Grid, context: Context) -> None:
|
flwr/server/server_config.py
CHANGED
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
from dataclasses import dataclass
|
|
19
|
-
from typing import Optional
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
@dataclass
|
|
@@ -28,7 +27,7 @@ class ServerConfig:
|
|
|
28
27
|
"""
|
|
29
28
|
|
|
30
29
|
num_rounds: int = 1
|
|
31
|
-
round_timeout:
|
|
30
|
+
round_timeout: float | None = None
|
|
32
31
|
|
|
33
32
|
def __repr__(self) -> str:
|
|
34
33
|
"""Return the string representation of the ServerConfig."""
|