flwr 1.17.0__py3-none-any.whl → 1.19.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 +1 -1
- flwr/app/__init__.py +15 -0
- flwr/app/error.py +68 -0
- flwr/app/metadata.py +223 -0
- flwr/cli/__init__.py +1 -1
- flwr/cli/app.py +21 -2
- flwr/cli/build.py +83 -58
- flwr/cli/cli_user_auth_interceptor.py +1 -1
- flwr/cli/config_utils.py +53 -17
- flwr/cli/example.py +1 -1
- flwr/cli/install.py +1 -1
- flwr/cli/log.py +4 -4
- flwr/cli/login/__init__.py +1 -1
- flwr/cli/login/login.py +15 -8
- flwr/cli/ls.py +16 -37
- flwr/cli/new/__init__.py +1 -1
- flwr/cli/new/new.py +4 -4
- flwr/cli/new/templates/__init__.py +1 -1
- flwr/cli/new/templates/app/__init__.py +1 -1
- flwr/cli/new/templates/app/code/__init__.py +1 -1
- flwr/cli/new/templates/app/code/client.baseline.py.tpl +1 -1
- flwr/cli/new/templates/app/code/flwr_tune/__init__.py +1 -1
- flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +4 -4
- flwr/cli/new/templates/app/code/model.baseline.py.tpl +1 -1
- flwr/cli/new/templates/app/code/server.baseline.py.tpl +2 -3
- flwr/cli/new/templates/app/code/task.sklearn.py.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +14 -17
- flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +4 -4
- 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 +1 -1
- flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +1 -1
- flwr/cli/run/__init__.py +1 -1
- flwr/cli/run/run.py +11 -19
- flwr/cli/stop.py +3 -3
- flwr/cli/utils.py +42 -17
- flwr/client/__init__.py +3 -3
- flwr/client/client.py +1 -1
- flwr/client/client_app.py +140 -138
- flwr/client/clientapp/__init__.py +1 -8
- flwr/client/clientapp/utils.py +1 -1
- flwr/client/dpfedavg_numpy_client.py +1 -1
- flwr/client/grpc_adapter_client/__init__.py +1 -1
- flwr/client/grpc_adapter_client/connection.py +5 -5
- flwr/client/grpc_rere_client/__init__.py +1 -1
- flwr/client/grpc_rere_client/client_interceptor.py +1 -1
- flwr/client/grpc_rere_client/connection.py +131 -61
- flwr/client/grpc_rere_client/grpc_adapter.py +35 -7
- flwr/client/message_handler/__init__.py +1 -1
- flwr/client/message_handler/message_handler.py +2 -2
- flwr/client/mod/__init__.py +1 -1
- flwr/client/mod/centraldp_mods.py +1 -1
- flwr/client/mod/comms_mods.py +39 -20
- flwr/client/mod/localdp_mod.py +6 -6
- flwr/client/mod/secure_aggregation/__init__.py +1 -1
- flwr/client/mod/secure_aggregation/secagg_mod.py +1 -1
- flwr/client/mod/secure_aggregation/secaggplus_mod.py +1 -1
- flwr/client/mod/utils.py +1 -1
- flwr/client/numpy_client.py +1 -1
- flwr/client/rest_client/__init__.py +1 -1
- flwr/client/rest_client/connection.py +174 -68
- flwr/client/run_info_store.py +1 -1
- flwr/client/typing.py +1 -1
- flwr/clientapp/__init__.py +15 -0
- flwr/common/__init__.py +3 -3
- flwr/common/address.py +1 -1
- flwr/common/args.py +1 -1
- flwr/common/auth_plugin/__init__.py +3 -1
- flwr/common/auth_plugin/auth_plugin.py +30 -4
- flwr/common/config.py +1 -1
- flwr/common/constant.py +37 -8
- flwr/common/context.py +1 -1
- flwr/common/date.py +1 -1
- flwr/common/differential_privacy.py +1 -1
- flwr/common/differential_privacy_constants.py +1 -1
- flwr/common/dp.py +1 -1
- flwr/common/event_log_plugin/event_log_plugin.py +3 -3
- flwr/common/exit/exit.py +6 -6
- flwr/common/exit_handlers.py +31 -1
- flwr/common/grpc.py +1 -1
- flwr/common/heartbeat.py +165 -0
- flwr/common/inflatable.py +290 -0
- flwr/common/inflatable_grpc_utils.py +99 -0
- flwr/common/inflatable_rest_utils.py +99 -0
- flwr/common/inflatable_utils.py +341 -0
- flwr/common/logger.py +1 -1
- flwr/common/message.py +137 -252
- flwr/common/object_ref.py +1 -1
- flwr/common/parameter.py +1 -1
- flwr/common/pyproject.py +1 -1
- flwr/common/record/__init__.py +3 -2
- flwr/common/record/array.py +323 -0
- flwr/common/record/arrayrecord.py +121 -243
- flwr/common/record/configrecord.py +71 -16
- flwr/common/record/conversion_utils.py +2 -2
- flwr/common/record/metricrecord.py +71 -20
- flwr/common/record/recorddict.py +207 -90
- flwr/common/record/typeddict.py +1 -1
- flwr/common/recorddict_compat.py +2 -2
- flwr/common/retry_invoker.py +15 -11
- flwr/common/secure_aggregation/__init__.py +1 -1
- flwr/common/secure_aggregation/crypto/__init__.py +1 -1
- flwr/common/secure_aggregation/crypto/shamir.py +52 -30
- flwr/common/secure_aggregation/crypto/symmetric_encryption.py +1 -1
- flwr/common/secure_aggregation/ndarrays_arithmetic.py +1 -1
- flwr/common/secure_aggregation/quantization.py +1 -1
- flwr/common/secure_aggregation/secaggplus_constants.py +1 -1
- flwr/common/secure_aggregation/secaggplus_utils.py +1 -1
- flwr/common/serde.py +60 -184
- flwr/common/serde_utils.py +175 -0
- flwr/common/telemetry.py +2 -2
- flwr/common/typing.py +6 -4
- flwr/common/version.py +1 -1
- flwr/compat/__init__.py +15 -0
- flwr/compat/client/__init__.py +15 -0
- flwr/{client → compat/client}/app.py +71 -211
- flwr/{client → compat/client}/grpc_client/__init__.py +1 -1
- flwr/{client → compat/client}/grpc_client/connection.py +13 -13
- flwr/compat/common/__init__.py +15 -0
- flwr/compat/server/__init__.py +15 -0
- flwr/compat/server/app.py +174 -0
- flwr/compat/simulation/__init__.py +15 -0
- flwr/proto/__init__.py +1 -1
- flwr/proto/fleet_pb2.py +32 -27
- flwr/proto/fleet_pb2.pyi +49 -35
- flwr/proto/fleet_pb2_grpc.py +117 -13
- flwr/proto/fleet_pb2_grpc.pyi +47 -6
- flwr/proto/heartbeat_pb2.py +33 -0
- flwr/proto/heartbeat_pb2.pyi +66 -0
- flwr/proto/heartbeat_pb2_grpc.py +4 -0
- flwr/proto/heartbeat_pb2_grpc.pyi +4 -0
- flwr/proto/message_pb2.py +28 -11
- flwr/proto/message_pb2.pyi +125 -0
- flwr/proto/recorddict_pb2.py +16 -28
- flwr/proto/recorddict_pb2.pyi +46 -64
- flwr/proto/run_pb2.py +24 -32
- flwr/proto/run_pb2.pyi +4 -52
- flwr/proto/serverappio_pb2.py +32 -23
- flwr/proto/serverappio_pb2.pyi +45 -3
- flwr/proto/serverappio_pb2_grpc.py +138 -34
- flwr/proto/serverappio_pb2_grpc.pyi +54 -13
- flwr/proto/simulationio_pb2.py +12 -11
- flwr/proto/simulationio_pb2_grpc.py +35 -0
- flwr/proto/simulationio_pb2_grpc.pyi +14 -0
- flwr/server/__init__.py +2 -2
- flwr/server/app.py +69 -187
- flwr/server/client_manager.py +1 -1
- flwr/server/client_proxy.py +1 -1
- flwr/server/compat/__init__.py +1 -1
- flwr/server/compat/app.py +1 -1
- flwr/server/compat/app_utils.py +51 -29
- flwr/server/compat/legacy_context.py +1 -1
- flwr/server/criterion.py +1 -1
- flwr/server/fleet_event_log_interceptor.py +2 -2
- flwr/server/grid/grid.py +3 -3
- flwr/server/grid/grpc_grid.py +104 -34
- flwr/server/grid/inmemory_grid.py +5 -4
- flwr/server/history.py +1 -1
- flwr/server/run_serverapp.py +1 -1
- flwr/server/server.py +1 -1
- flwr/server/server_app.py +65 -58
- flwr/server/server_config.py +1 -1
- flwr/server/serverapp/__init__.py +1 -1
- flwr/server/serverapp/app.py +19 -1
- flwr/server/serverapp_components.py +1 -1
- flwr/server/strategy/__init__.py +1 -1
- flwr/server/strategy/aggregate.py +1 -1
- flwr/server/strategy/bulyan.py +2 -2
- flwr/server/strategy/dp_adaptive_clipping.py +17 -17
- flwr/server/strategy/dp_fixed_clipping.py +17 -17
- flwr/server/strategy/dpfedavg_adaptive.py +1 -1
- flwr/server/strategy/dpfedavg_fixed.py +1 -1
- flwr/server/strategy/fault_tolerant_fedavg.py +1 -1
- flwr/server/strategy/fedadagrad.py +1 -1
- flwr/server/strategy/fedadam.py +1 -1
- flwr/server/strategy/fedavg.py +1 -1
- flwr/server/strategy/fedavg_android.py +1 -1
- flwr/server/strategy/fedavgm.py +1 -1
- flwr/server/strategy/fedmedian.py +1 -1
- flwr/server/strategy/fedopt.py +1 -1
- flwr/server/strategy/fedprox.py +1 -1
- flwr/server/strategy/fedtrimmedavg.py +1 -1
- flwr/server/strategy/fedxgb_bagging.py +1 -1
- flwr/server/strategy/fedxgb_cyclic.py +1 -1
- flwr/server/strategy/fedxgb_nn_avg.py +3 -2
- flwr/server/strategy/fedyogi.py +1 -1
- flwr/server/strategy/krum.py +1 -1
- flwr/server/strategy/qfedavg.py +1 -1
- flwr/server/strategy/strategy.py +1 -1
- flwr/server/superlink/__init__.py +1 -1
- flwr/server/superlink/ffs/__init__.py +3 -1
- flwr/server/superlink/ffs/disk_ffs.py +1 -1
- flwr/server/superlink/ffs/ffs.py +1 -1
- flwr/server/superlink/ffs/ffs_factory.py +1 -1
- flwr/server/superlink/fleet/__init__.py +1 -1
- flwr/server/superlink/fleet/grpc_adapter/__init__.py +1 -1
- flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +14 -4
- flwr/server/superlink/fleet/grpc_bidi/__init__.py +1 -1
- flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +1 -1
- flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +1 -1
- flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +1 -1
- flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +13 -13
- flwr/server/superlink/fleet/grpc_rere/__init__.py +1 -1
- flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +102 -8
- flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +1 -1
- flwr/server/superlink/fleet/message_handler/__init__.py +1 -1
- flwr/server/superlink/fleet/message_handler/message_handler.py +136 -19
- flwr/server/superlink/fleet/rest_rere/__init__.py +1 -1
- flwr/server/superlink/fleet/rest_rere/rest_api.py +73 -12
- flwr/server/superlink/fleet/vce/__init__.py +1 -1
- flwr/server/superlink/fleet/vce/backend/__init__.py +1 -1
- flwr/server/superlink/fleet/vce/backend/backend.py +1 -1
- flwr/server/superlink/fleet/vce/backend/raybackend.py +1 -1
- flwr/server/superlink/fleet/vce/vce_api.py +7 -4
- flwr/server/superlink/linkstate/__init__.py +1 -1
- flwr/server/superlink/linkstate/in_memory_linkstate.py +139 -44
- flwr/server/superlink/linkstate/linkstate.py +54 -21
- flwr/server/superlink/linkstate/linkstate_factory.py +1 -1
- flwr/server/superlink/linkstate/sqlite_linkstate.py +150 -56
- flwr/server/superlink/linkstate/utils.py +34 -30
- flwr/server/superlink/serverappio/serverappio_grpc.py +3 -0
- flwr/server/superlink/serverappio/serverappio_servicer.py +211 -57
- flwr/server/superlink/simulation/__init__.py +1 -1
- flwr/server/superlink/simulation/simulationio_grpc.py +1 -1
- flwr/server/superlink/simulation/simulationio_servicer.py +26 -2
- flwr/server/superlink/utils.py +45 -3
- flwr/server/typing.py +1 -1
- flwr/server/utils/__init__.py +1 -1
- flwr/server/utils/tensorboard.py +1 -1
- flwr/server/utils/validator.py +3 -3
- flwr/server/workflow/__init__.py +1 -1
- flwr/server/workflow/constant.py +1 -1
- flwr/server/workflow/default_workflows.py +1 -1
- flwr/server/workflow/secure_aggregation/__init__.py +1 -1
- flwr/server/workflow/secure_aggregation/secagg_workflow.py +1 -1
- flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +1 -1
- flwr/serverapp/__init__.py +15 -0
- flwr/simulation/__init__.py +1 -1
- flwr/simulation/app.py +18 -1
- flwr/simulation/legacy_app.py +1 -1
- flwr/simulation/ray_transport/__init__.py +1 -1
- flwr/simulation/ray_transport/ray_actor.py +1 -1
- flwr/simulation/ray_transport/ray_client_proxy.py +1 -1
- flwr/simulation/ray_transport/utils.py +1 -1
- flwr/simulation/run_simulation.py +2 -2
- flwr/simulation/simulationio_connection.py +1 -1
- flwr/supercore/__init__.py +15 -0
- flwr/supercore/object_store/__init__.py +24 -0
- flwr/supercore/object_store/in_memory_object_store.py +229 -0
- flwr/supercore/object_store/object_store.py +192 -0
- flwr/supercore/object_store/object_store_factory.py +44 -0
- flwr/superexec/__init__.py +1 -1
- flwr/superexec/app.py +1 -1
- flwr/superexec/deployment.py +7 -3
- flwr/superexec/exec_event_log_interceptor.py +4 -4
- flwr/superexec/exec_grpc.py +8 -4
- flwr/superexec/exec_servicer.py +126 -24
- flwr/superexec/exec_user_auth_interceptor.py +38 -9
- flwr/superexec/executor.py +5 -1
- flwr/superexec/simulation.py +8 -2
- flwr/superlink/__init__.py +15 -0
- flwr/{client/supernode → supernode}/__init__.py +1 -8
- flwr/{client/nodestate/nodestate.py → supernode/cli/__init__.py} +8 -15
- flwr/{client/supernode/app.py → supernode/cli/flower_supernode.py} +4 -13
- flwr/supernode/cli/flwr_clientapp.py +81 -0
- flwr/{client → supernode}/nodestate/__init__.py +1 -1
- flwr/supernode/nodestate/in_memory_nodestate.py +190 -0
- flwr/supernode/nodestate/nodestate.py +212 -0
- flwr/{client → supernode}/nodestate/nodestate_factory.py +1 -1
- flwr/supernode/runtime/__init__.py +15 -0
- flwr/{client/clientapp/app.py → supernode/runtime/run_clientapp.py} +26 -57
- flwr/supernode/servicer/__init__.py +15 -0
- flwr/supernode/servicer/clientappio/__init__.py +24 -0
- flwr/{client/clientapp → supernode/servicer/clientappio}/clientappio_servicer.py +1 -1
- flwr/supernode/start_client_internal.py +491 -0
- {flwr-1.17.0.dist-info → flwr-1.19.0.dist-info}/METADATA +6 -5
- flwr-1.19.0.dist-info/RECORD +365 -0
- {flwr-1.17.0.dist-info → flwr-1.19.0.dist-info}/WHEEL +1 -1
- {flwr-1.17.0.dist-info → flwr-1.19.0.dist-info}/entry_points.txt +2 -2
- flwr/client/heartbeat.py +0 -74
- flwr/client/nodestate/in_memory_nodestate.py +0 -38
- flwr-1.17.0.dist-info/LICENSE +0 -202
- flwr-1.17.0.dist-info/RECORD +0 -333
flwr/server/strategy/fedadam.py
CHANGED
flwr/server/strategy/fedavg.py
CHANGED
flwr/server/strategy/fedavgm.py
CHANGED
flwr/server/strategy/fedopt.py
CHANGED
flwr/server/strategy/fedprox.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2025 Flower Labs GmbH. All Rights Reserved.
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -44,7 +44,8 @@ class FedXgbNnAvg(FedAvg):
|
|
|
44
44
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
45
45
|
"""Federated XGBoost [Ma et al., 2023] strategy.
|
|
46
46
|
|
|
47
|
-
Implementation based on
|
|
47
|
+
Implementation based on
|
|
48
|
+
https://arxiv.org/abs/2304.07537.
|
|
48
49
|
"""
|
|
49
50
|
super().__init__(*args, **kwargs)
|
|
50
51
|
warn_deprecated_feature("`FedXgbNnAvg` strategy")
|
flwr/server/strategy/fedyogi.py
CHANGED
flwr/server/strategy/krum.py
CHANGED
flwr/server/strategy/qfedavg.py
CHANGED
flwr/server/strategy/strategy.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2025 Flower Labs GmbH. All Rights Reserved.
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -17,8 +17,10 @@
|
|
|
17
17
|
|
|
18
18
|
from .disk_ffs import DiskFfs as DiskFfs
|
|
19
19
|
from .ffs import Ffs as Ffs
|
|
20
|
+
from .ffs_factory import FfsFactory as FfsFactory
|
|
20
21
|
|
|
21
22
|
__all__ = [
|
|
22
23
|
"DiskFfs",
|
|
23
24
|
"Ffs",
|
|
25
|
+
"FfsFactory",
|
|
24
26
|
]
|
flwr/server/superlink/ffs/ffs.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2025 Flower Labs GmbH. All Rights Reserved.
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -35,11 +35,15 @@ from flwr.proto.fab_pb2 import GetFabRequest # pylint: disable=E0611
|
|
|
35
35
|
from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
|
|
36
36
|
CreateNodeRequest,
|
|
37
37
|
DeleteNodeRequest,
|
|
38
|
-
PingRequest,
|
|
39
38
|
PullMessagesRequest,
|
|
40
39
|
PushMessagesRequest,
|
|
41
40
|
)
|
|
42
41
|
from flwr.proto.grpcadapter_pb2 import MessageContainer # pylint: disable=E0611
|
|
42
|
+
from flwr.proto.heartbeat_pb2 import SendNodeHeartbeatRequest # pylint: disable=E0611
|
|
43
|
+
from flwr.proto.message_pb2 import ( # pylint: disable=E0611
|
|
44
|
+
PullObjectRequest,
|
|
45
|
+
PushObjectRequest,
|
|
46
|
+
)
|
|
43
47
|
from flwr.proto.run_pb2 import GetRunRequest # pylint: disable=E0611
|
|
44
48
|
|
|
45
49
|
from ..grpc_rere.fleet_servicer import FleetServicer
|
|
@@ -81,8 +85,10 @@ class GrpcAdapterServicer(grpcadapter_pb2_grpc.GrpcAdapterServicer, FleetService
|
|
|
81
85
|
return _handle(request, context, CreateNodeRequest, self.CreateNode)
|
|
82
86
|
if request.grpc_message_name == DeleteNodeRequest.__qualname__:
|
|
83
87
|
return _handle(request, context, DeleteNodeRequest, self.DeleteNode)
|
|
84
|
-
if request.grpc_message_name ==
|
|
85
|
-
return _handle(
|
|
88
|
+
if request.grpc_message_name == SendNodeHeartbeatRequest.__qualname__:
|
|
89
|
+
return _handle(
|
|
90
|
+
request, context, SendNodeHeartbeatRequest, self.SendNodeHeartbeat
|
|
91
|
+
)
|
|
86
92
|
if request.grpc_message_name == GetRunRequest.__qualname__:
|
|
87
93
|
return _handle(request, context, GetRunRequest, self.GetRun)
|
|
88
94
|
if request.grpc_message_name == GetFabRequest.__qualname__:
|
|
@@ -91,4 +97,8 @@ class GrpcAdapterServicer(grpcadapter_pb2_grpc.GrpcAdapterServicer, FleetService
|
|
|
91
97
|
return _handle(request, context, PullMessagesRequest, self.PullMessages)
|
|
92
98
|
if request.grpc_message_name == PushMessagesRequest.__qualname__:
|
|
93
99
|
return _handle(request, context, PushMessagesRequest, self.PushMessages)
|
|
100
|
+
if request.grpc_message_name == PushObjectRequest.__qualname__:
|
|
101
|
+
return _handle(request, context, PushObjectRequest, self.PushObject)
|
|
102
|
+
if request.grpc_message_name == PullObjectRequest.__qualname__:
|
|
103
|
+
return _handle(request, context, PullObjectRequest, self.PullObject)
|
|
94
104
|
raise ValueError(f"Invalid grpc_message_name: {request.grpc_message_name}")
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2025 Flower Labs GmbH. All Rights Reserved.
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -96,18 +96,18 @@ def start_grpc_server( # pylint: disable=too-many-arguments,R0917
|
|
|
96
96
|
|
|
97
97
|
Examples
|
|
98
98
|
--------
|
|
99
|
-
Starting a
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
99
|
+
Starting a TLS-enabled server::
|
|
100
|
+
|
|
101
|
+
from pathlib import Path
|
|
102
|
+
start_grpc_server(
|
|
103
|
+
client_manager=ClientManager(),
|
|
104
|
+
server_address="localhost:8080",
|
|
105
|
+
certificates=(
|
|
106
|
+
Path("/crts/root.pem").read_bytes(),
|
|
107
|
+
Path("/crts/localhost.crt").read_bytes(),
|
|
108
|
+
Path("/crts/localhost.key").read_bytes(),
|
|
109
|
+
),
|
|
110
|
+
)
|
|
111
111
|
"""
|
|
112
112
|
servicer = FlowerServiceServicer(client_manager)
|
|
113
113
|
add_servicer_to_server_fn = add_FlowerServiceServicer_to_server
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2025 Flower Labs GmbH. All Rights Reserved.
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -20,6 +20,7 @@ from logging import DEBUG, INFO
|
|
|
20
20
|
import grpc
|
|
21
21
|
from google.protobuf.json_format import MessageToDict
|
|
22
22
|
|
|
23
|
+
from flwr.common.inflatable import UnexpectedObjectContentError
|
|
23
24
|
from flwr.common.logger import log
|
|
24
25
|
from flwr.common.typing import InvalidRunStatusException
|
|
25
26
|
from flwr.proto import fleet_pb2_grpc # pylint: disable=E0611
|
|
@@ -29,34 +30,53 @@ from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
|
|
|
29
30
|
CreateNodeResponse,
|
|
30
31
|
DeleteNodeRequest,
|
|
31
32
|
DeleteNodeResponse,
|
|
32
|
-
PingRequest,
|
|
33
|
-
PingResponse,
|
|
34
33
|
PullMessagesRequest,
|
|
35
34
|
PullMessagesResponse,
|
|
36
35
|
PushMessagesRequest,
|
|
37
36
|
PushMessagesResponse,
|
|
38
37
|
)
|
|
38
|
+
from flwr.proto.heartbeat_pb2 import ( # pylint: disable=E0611
|
|
39
|
+
SendNodeHeartbeatRequest,
|
|
40
|
+
SendNodeHeartbeatResponse,
|
|
41
|
+
)
|
|
42
|
+
from flwr.proto.message_pb2 import ( # pylint: disable=E0611
|
|
43
|
+
ConfirmMessageReceivedRequest,
|
|
44
|
+
ConfirmMessageReceivedResponse,
|
|
45
|
+
PullObjectRequest,
|
|
46
|
+
PullObjectResponse,
|
|
47
|
+
PushObjectRequest,
|
|
48
|
+
PushObjectResponse,
|
|
49
|
+
)
|
|
39
50
|
from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611
|
|
40
51
|
from flwr.server.superlink.ffs.ffs_factory import FfsFactory
|
|
41
52
|
from flwr.server.superlink.fleet.message_handler import message_handler
|
|
42
53
|
from flwr.server.superlink.linkstate import LinkStateFactory
|
|
43
54
|
from flwr.server.superlink.utils import abort_grpc_context
|
|
55
|
+
from flwr.supercore.object_store import ObjectStoreFactory
|
|
44
56
|
|
|
45
57
|
|
|
46
58
|
class FleetServicer(fleet_pb2_grpc.FleetServicer):
|
|
47
59
|
"""Fleet API servicer."""
|
|
48
60
|
|
|
49
61
|
def __init__(
|
|
50
|
-
self,
|
|
62
|
+
self,
|
|
63
|
+
state_factory: LinkStateFactory,
|
|
64
|
+
ffs_factory: FfsFactory,
|
|
65
|
+
objectstore_factory: ObjectStoreFactory,
|
|
51
66
|
) -> None:
|
|
52
67
|
self.state_factory = state_factory
|
|
53
68
|
self.ffs_factory = ffs_factory
|
|
69
|
+
self.objectstore_factory = objectstore_factory
|
|
54
70
|
|
|
55
71
|
def CreateNode(
|
|
56
72
|
self, request: CreateNodeRequest, context: grpc.ServicerContext
|
|
57
73
|
) -> CreateNodeResponse:
|
|
58
74
|
"""."""
|
|
59
|
-
log(
|
|
75
|
+
log(
|
|
76
|
+
INFO,
|
|
77
|
+
"[Fleet.CreateNode] Request heartbeat_interval=%s",
|
|
78
|
+
request.heartbeat_interval,
|
|
79
|
+
)
|
|
60
80
|
log(DEBUG, "[Fleet.CreateNode] Request: %s", MessageToDict(request))
|
|
61
81
|
response = message_handler.create_node(
|
|
62
82
|
request=request,
|
|
@@ -77,10 +97,12 @@ class FleetServicer(fleet_pb2_grpc.FleetServicer):
|
|
|
77
97
|
state=self.state_factory.state(),
|
|
78
98
|
)
|
|
79
99
|
|
|
80
|
-
def
|
|
100
|
+
def SendNodeHeartbeat(
|
|
101
|
+
self, request: SendNodeHeartbeatRequest, context: grpc.ServicerContext
|
|
102
|
+
) -> SendNodeHeartbeatResponse:
|
|
81
103
|
"""."""
|
|
82
|
-
log(DEBUG, "[Fleet.
|
|
83
|
-
return message_handler.
|
|
104
|
+
log(DEBUG, "[Fleet.SendNodeHeartbeat] Request: %s", MessageToDict(request))
|
|
105
|
+
return message_handler.send_node_heartbeat(
|
|
84
106
|
request=request,
|
|
85
107
|
state=self.state_factory.state(),
|
|
86
108
|
)
|
|
@@ -94,6 +116,7 @@ class FleetServicer(fleet_pb2_grpc.FleetServicer):
|
|
|
94
116
|
return message_handler.pull_messages(
|
|
95
117
|
request=request,
|
|
96
118
|
state=self.state_factory.state(),
|
|
119
|
+
store=self.objectstore_factory.store(),
|
|
97
120
|
)
|
|
98
121
|
|
|
99
122
|
def PushMessages(
|
|
@@ -113,6 +136,7 @@ class FleetServicer(fleet_pb2_grpc.FleetServicer):
|
|
|
113
136
|
res = message_handler.push_messages(
|
|
114
137
|
request=request,
|
|
115
138
|
state=self.state_factory.state(),
|
|
139
|
+
store=self.objectstore_factory.store(),
|
|
116
140
|
)
|
|
117
141
|
except InvalidRunStatusException as e:
|
|
118
142
|
abort_grpc_context(e.message, context)
|
|
@@ -129,6 +153,7 @@ class FleetServicer(fleet_pb2_grpc.FleetServicer):
|
|
|
129
153
|
res = message_handler.get_run(
|
|
130
154
|
request=request,
|
|
131
155
|
state=self.state_factory.state(),
|
|
156
|
+
store=self.objectstore_factory.store(),
|
|
132
157
|
)
|
|
133
158
|
except InvalidRunStatusException as e:
|
|
134
159
|
abort_grpc_context(e.message, context)
|
|
@@ -145,6 +170,75 @@ class FleetServicer(fleet_pb2_grpc.FleetServicer):
|
|
|
145
170
|
request=request,
|
|
146
171
|
ffs=self.ffs_factory.ffs(),
|
|
147
172
|
state=self.state_factory.state(),
|
|
173
|
+
store=self.objectstore_factory.store(),
|
|
174
|
+
)
|
|
175
|
+
except InvalidRunStatusException as e:
|
|
176
|
+
abort_grpc_context(e.message, context)
|
|
177
|
+
|
|
178
|
+
return res
|
|
179
|
+
|
|
180
|
+
def PushObject(
|
|
181
|
+
self, request: PushObjectRequest, context: grpc.ServicerContext
|
|
182
|
+
) -> PushObjectResponse:
|
|
183
|
+
"""Push an object to the ObjectStore."""
|
|
184
|
+
log(
|
|
185
|
+
DEBUG,
|
|
186
|
+
"[ServerAppIoServicer.PushObject] Push Object with object_id=%s",
|
|
187
|
+
request.object_id,
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
try:
|
|
191
|
+
# Insert in Store
|
|
192
|
+
res = message_handler.push_object(
|
|
193
|
+
request=request,
|
|
194
|
+
state=self.state_factory.state(),
|
|
195
|
+
store=self.objectstore_factory.store(),
|
|
196
|
+
)
|
|
197
|
+
except InvalidRunStatusException as e:
|
|
198
|
+
abort_grpc_context(e.message, context)
|
|
199
|
+
except UnexpectedObjectContentError as e:
|
|
200
|
+
# Object content is not valid
|
|
201
|
+
context.abort(grpc.StatusCode.FAILED_PRECONDITION, str(e))
|
|
202
|
+
|
|
203
|
+
return res
|
|
204
|
+
|
|
205
|
+
def PullObject(
|
|
206
|
+
self, request: PullObjectRequest, context: grpc.ServicerContext
|
|
207
|
+
) -> PullObjectResponse:
|
|
208
|
+
"""Pull an object from the ObjectStore."""
|
|
209
|
+
log(
|
|
210
|
+
DEBUG,
|
|
211
|
+
"[ServerAppIoServicer.PullObject] Pull Object with object_id=%s",
|
|
212
|
+
request.object_id,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
try:
|
|
216
|
+
# Fetch from store
|
|
217
|
+
res = message_handler.pull_object(
|
|
218
|
+
request=request,
|
|
219
|
+
state=self.state_factory.state(),
|
|
220
|
+
store=self.objectstore_factory.store(),
|
|
221
|
+
)
|
|
222
|
+
except InvalidRunStatusException as e:
|
|
223
|
+
abort_grpc_context(e.message, context)
|
|
224
|
+
|
|
225
|
+
return res
|
|
226
|
+
|
|
227
|
+
def ConfirmMessageReceived(
|
|
228
|
+
self, request: ConfirmMessageReceivedRequest, context: grpc.ServicerContext
|
|
229
|
+
) -> ConfirmMessageReceivedResponse:
|
|
230
|
+
"""Confirm message received."""
|
|
231
|
+
log(
|
|
232
|
+
DEBUG,
|
|
233
|
+
"[Fleet.ConfirmMessageReceived] Message with ID '%s' has been received",
|
|
234
|
+
request.message_object_id,
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
try:
|
|
238
|
+
res = message_handler.confirm_message_received(
|
|
239
|
+
request=request,
|
|
240
|
+
state=self.state_factory.state(),
|
|
241
|
+
store=self.objectstore_factory.store(),
|
|
148
242
|
)
|
|
149
243
|
except InvalidRunStatusException as e:
|
|
150
244
|
abort_grpc_context(e.message, context)
|