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
flwr/cli/stop.py
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import io
|
|
19
19
|
import json
|
|
20
20
|
from pathlib import Path
|
|
21
|
-
from typing import Annotated
|
|
21
|
+
from typing import Annotated
|
|
22
22
|
|
|
23
23
|
import typer
|
|
24
24
|
from rich.console import Console
|
|
@@ -51,11 +51,11 @@ def stop( # pylint: disable=R0914
|
|
|
51
51
|
typer.Argument(help="Path of the Flower project"),
|
|
52
52
|
] = Path("."),
|
|
53
53
|
federation: Annotated[
|
|
54
|
-
|
|
54
|
+
str | None,
|
|
55
55
|
typer.Argument(help="Name of the federation"),
|
|
56
56
|
] = None,
|
|
57
57
|
federation_config_overrides: Annotated[
|
|
58
|
-
|
|
58
|
+
list[str] | None,
|
|
59
59
|
typer.Option(
|
|
60
60
|
"--federation-config",
|
|
61
61
|
help=FEDERATION_CONFIG_HELP_MESSAGE,
|
|
@@ -70,7 +70,11 @@ def stop( # pylint: disable=R0914
|
|
|
70
70
|
),
|
|
71
71
|
] = CliOutputFormat.DEFAULT,
|
|
72
72
|
) -> None:
|
|
73
|
-
"""Stop a run.
|
|
73
|
+
"""Stop a Flower run.
|
|
74
|
+
|
|
75
|
+
This command stops a running Flower App execution by sending a stop request to the
|
|
76
|
+
SuperLink via the Control API.
|
|
77
|
+
"""
|
|
74
78
|
suppress_output = output_format == CliOutputFormat.JSON
|
|
75
79
|
captured_output = io.StringIO()
|
|
76
80
|
try:
|
|
@@ -81,7 +85,7 @@ def stop( # pylint: disable=R0914
|
|
|
81
85
|
typer.secho("Loading project configuration... ", fg=typer.colors.BLUE)
|
|
82
86
|
|
|
83
87
|
pyproject_path = app / FAB_CONFIG_FILE if app else None
|
|
84
|
-
config, errors, warnings = load_and_validate(
|
|
88
|
+
config, errors, warnings = load_and_validate(pyproject_path, check_module=False)
|
|
85
89
|
config = process_loaded_project_config(config, errors, warnings)
|
|
86
90
|
federation, federation_config = validate_federation_in_project_config(
|
|
87
91
|
federation, config, federation_config_overrides
|
|
@@ -101,6 +105,7 @@ def stop( # pylint: disable=R0914
|
|
|
101
105
|
f"❌ {err}",
|
|
102
106
|
fg=typer.colors.RED,
|
|
103
107
|
bold=True,
|
|
108
|
+
err=True,
|
|
104
109
|
)
|
|
105
110
|
raise typer.Exit(code=1) from err
|
|
106
111
|
finally:
|
|
@@ -116,6 +121,7 @@ def stop( # pylint: disable=R0914
|
|
|
116
121
|
f"{err}",
|
|
117
122
|
fg=typer.colors.RED,
|
|
118
123
|
bold=True,
|
|
124
|
+
err=True,
|
|
119
125
|
)
|
|
120
126
|
finally:
|
|
121
127
|
if suppress_output:
|
|
@@ -124,7 +130,17 @@ def stop( # pylint: disable=R0914
|
|
|
124
130
|
|
|
125
131
|
|
|
126
132
|
def _stop_run(stub: ControlStub, run_id: int, output_format: str) -> None:
|
|
127
|
-
"""Stop a run.
|
|
133
|
+
"""Stop a run and display the result.
|
|
134
|
+
|
|
135
|
+
Parameters
|
|
136
|
+
----------
|
|
137
|
+
stub : ControlStub
|
|
138
|
+
The gRPC stub for Control API communication.
|
|
139
|
+
run_id : int
|
|
140
|
+
The unique identifier of the run to stop.
|
|
141
|
+
output_format : str
|
|
142
|
+
Output format ('default' or 'json').
|
|
143
|
+
"""
|
|
128
144
|
with flwr_cli_grpc_exc_handler():
|
|
129
145
|
response: StopRunResponse = stub.StopRun(request=StopRunRequest(run_id=run_id))
|
|
130
146
|
if response.success:
|
|
@@ -139,4 +155,6 @@ def _stop_run(stub: ControlStub, run_id: int, output_format: str) -> None:
|
|
|
139
155
|
restore_output()
|
|
140
156
|
Console().print_json(run_output)
|
|
141
157
|
else:
|
|
142
|
-
typer.secho(
|
|
158
|
+
typer.secho(
|
|
159
|
+
f"❌ Run {run_id} couldn't be stopped.", fg=typer.colors.RED, err=True
|
|
160
|
+
)
|
flwr/cli/supernode/ls.py
CHANGED
|
@@ -19,7 +19,7 @@ import io
|
|
|
19
19
|
import json
|
|
20
20
|
from datetime import datetime, timedelta
|
|
21
21
|
from pathlib import Path
|
|
22
|
-
from typing import Annotated,
|
|
22
|
+
from typing import Annotated, cast
|
|
23
23
|
|
|
24
24
|
import typer
|
|
25
25
|
from rich.console import Console
|
|
@@ -32,7 +32,7 @@ from flwr.cli.config_utils import (
|
|
|
32
32
|
process_loaded_project_config,
|
|
33
33
|
validate_federation_in_project_config,
|
|
34
34
|
)
|
|
35
|
-
from flwr.common.constant import FAB_CONFIG_FILE,
|
|
35
|
+
from flwr.common.constant import FAB_CONFIG_FILE, NOOP_ACCOUNT_NAME, CliOutputFormat
|
|
36
36
|
from flwr.common.date import format_timedelta, isoformat8601_utc
|
|
37
37
|
from flwr.common.logger import print_json_error, redirect_output, restore_output
|
|
38
38
|
from flwr.proto.control_pb2 import ( # pylint: disable=E0611
|
|
@@ -44,7 +44,7 @@ from flwr.proto.node_pb2 import NodeInfo # pylint: disable=E0611
|
|
|
44
44
|
|
|
45
45
|
from ..utils import flwr_cli_grpc_exc_handler, init_channel, load_cli_auth_plugin
|
|
46
46
|
|
|
47
|
-
_NodeListType = tuple[int, str, str, str, str, str, str, str]
|
|
47
|
+
_NodeListType = tuple[int, str, str, str, str, str, str, str, str]
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
def ls( # pylint: disable=R0914, R0913, R0917
|
|
@@ -54,7 +54,7 @@ def ls( # pylint: disable=R0914, R0913, R0917
|
|
|
54
54
|
typer.Argument(help="Path of the Flower project"),
|
|
55
55
|
] = Path("."),
|
|
56
56
|
federation: Annotated[
|
|
57
|
-
|
|
57
|
+
str | None,
|
|
58
58
|
typer.Argument(help="Name of the federation"),
|
|
59
59
|
] = None,
|
|
60
60
|
output_format: Annotated[
|
|
@@ -86,7 +86,7 @@ def ls( # pylint: disable=R0914, R0913, R0917
|
|
|
86
86
|
typer.secho("Loading project configuration... ", fg=typer.colors.BLUE)
|
|
87
87
|
|
|
88
88
|
pyproject_path = app / FAB_CONFIG_FILE if app else None
|
|
89
|
-
config, errors, warnings = load_and_validate(
|
|
89
|
+
config, errors, warnings = load_and_validate(pyproject_path, check_module=False)
|
|
90
90
|
config = process_loaded_project_config(config, errors, warnings)
|
|
91
91
|
federation, federation_config = validate_federation_in_project_config(
|
|
92
92
|
federation, config
|
|
@@ -138,7 +138,7 @@ def _format_nodes(
|
|
|
138
138
|
) -> list[_NodeListType]:
|
|
139
139
|
"""Format node information for display."""
|
|
140
140
|
|
|
141
|
-
def _format_datetime(dt_str:
|
|
141
|
+
def _format_datetime(dt_str: str | None) -> str:
|
|
142
142
|
dt = datetime.fromisoformat(dt_str) if dt_str else None
|
|
143
143
|
return isoformat8601_utc(dt).replace("T", " ") if dt else "N/A"
|
|
144
144
|
|
|
@@ -160,6 +160,7 @@ def _format_nodes(
|
|
|
160
160
|
(
|
|
161
161
|
node.node_id,
|
|
162
162
|
node.owner_aid,
|
|
163
|
+
node.owner_name,
|
|
163
164
|
node.status,
|
|
164
165
|
_format_datetime(node.registered_at),
|
|
165
166
|
_format_datetime(node.last_activated_at),
|
|
@@ -188,7 +189,8 @@ def _to_table(nodes_info: list[_NodeListType], verbose: bool) -> Table:
|
|
|
188
189
|
for row in nodes_info:
|
|
189
190
|
(
|
|
190
191
|
node_id,
|
|
191
|
-
|
|
192
|
+
_,
|
|
193
|
+
owner_name,
|
|
192
194
|
status,
|
|
193
195
|
_,
|
|
194
196
|
last_activated_at,
|
|
@@ -216,7 +218,11 @@ def _to_table(nodes_info: list[_NodeListType], verbose: bool) -> Table:
|
|
|
216
218
|
|
|
217
219
|
formatted_row = (
|
|
218
220
|
f"[bold]{node_id}[/bold]",
|
|
219
|
-
|
|
221
|
+
(
|
|
222
|
+
f"{owner_name}"
|
|
223
|
+
if owner_name != NOOP_ACCOUNT_NAME
|
|
224
|
+
else f"[dim]{owner_name}[/dim]"
|
|
225
|
+
),
|
|
220
226
|
f"[{status_style}]{status}",
|
|
221
227
|
f"[cyan]{elapse_activated}[/cyan]" if status == "online" else "",
|
|
222
228
|
time_at,
|
|
@@ -233,6 +239,7 @@ def _to_json(nodes_info: list[_NodeListType], verbose: bool) -> str:
|
|
|
233
239
|
(
|
|
234
240
|
node_id,
|
|
235
241
|
owner_aid,
|
|
242
|
+
owner_name,
|
|
236
243
|
status,
|
|
237
244
|
created_at,
|
|
238
245
|
activated_at,
|
|
@@ -248,6 +255,7 @@ def _to_json(nodes_info: list[_NodeListType], verbose: bool) -> str:
|
|
|
248
255
|
{
|
|
249
256
|
"node-id": node_id,
|
|
250
257
|
"owner-aid": owner_aid,
|
|
258
|
+
"owner-name": owner_name,
|
|
251
259
|
"status": status,
|
|
252
260
|
"created-at": created_at,
|
|
253
261
|
"online-at": activated_at,
|
flwr/cli/supernode/register.py
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import io
|
|
19
19
|
import json
|
|
20
20
|
from pathlib import Path
|
|
21
|
-
from typing import Annotated
|
|
21
|
+
from typing import Annotated
|
|
22
22
|
|
|
23
23
|
import typer
|
|
24
24
|
from cryptography.exceptions import UnsupportedAlgorithm
|
|
@@ -57,7 +57,7 @@ def register( # pylint: disable=R0914
|
|
|
57
57
|
typer.Argument(help="Path of the Flower project"),
|
|
58
58
|
] = Path("."),
|
|
59
59
|
federation: Annotated[
|
|
60
|
-
|
|
60
|
+
str | None,
|
|
61
61
|
typer.Argument(help="Name of the federation"),
|
|
62
62
|
] = None,
|
|
63
63
|
output_format: Annotated[
|
|
@@ -85,7 +85,7 @@ def register( # pylint: disable=R0914
|
|
|
85
85
|
typer.secho("Loading project configuration... ", fg=typer.colors.BLUE)
|
|
86
86
|
|
|
87
87
|
pyproject_path = app / FAB_CONFIG_FILE if app else None
|
|
88
|
-
config, errors, warnings = load_and_validate(
|
|
88
|
+
config, errors, warnings = load_and_validate(pyproject_path, check_module=False)
|
|
89
89
|
config = process_loaded_project_config(config, errors, warnings)
|
|
90
90
|
federation, federation_config = validate_federation_in_project_config(
|
|
91
91
|
federation, config
|
|
@@ -107,6 +107,7 @@ def register( # pylint: disable=R0914
|
|
|
107
107
|
f"❌ {err}",
|
|
108
108
|
fg=typer.colors.RED,
|
|
109
109
|
bold=True,
|
|
110
|
+
err=True,
|
|
110
111
|
)
|
|
111
112
|
raise typer.Exit(code=1) from err
|
|
112
113
|
finally:
|
|
@@ -123,6 +124,7 @@ def register( # pylint: disable=R0914
|
|
|
123
124
|
f"{err}",
|
|
124
125
|
fg=typer.colors.RED,
|
|
125
126
|
bold=True,
|
|
127
|
+
err=True,
|
|
126
128
|
)
|
|
127
129
|
finally:
|
|
128
130
|
if suppress_output:
|
|
@@ -151,7 +153,9 @@ def _register_node(stub: ControlStub, public_key: bytes, output_format: str) ->
|
|
|
151
153
|
restore_output()
|
|
152
154
|
Console().print_json(run_output)
|
|
153
155
|
else:
|
|
154
|
-
typer.secho(
|
|
156
|
+
typer.secho(
|
|
157
|
+
"❌ SuperNode couldn't be registered.", fg=typer.colors.RED, err=True
|
|
158
|
+
)
|
|
155
159
|
|
|
156
160
|
|
|
157
161
|
def try_load_public_key(public_key_path: Path) -> bytes:
|
|
@@ -161,6 +165,7 @@ def try_load_public_key(public_key_path: Path) -> bytes:
|
|
|
161
165
|
f"❌ Public key file '{public_key_path}' does not exist.",
|
|
162
166
|
fg=typer.colors.RED,
|
|
163
167
|
bold=True,
|
|
168
|
+
err=True,
|
|
164
169
|
)
|
|
165
170
|
raise typer.Exit(code=1)
|
|
166
171
|
|
flwr/cli/supernode/unregister.py
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import io
|
|
19
19
|
import json
|
|
20
20
|
from pathlib import Path
|
|
21
|
-
from typing import Annotated
|
|
21
|
+
from typing import Annotated
|
|
22
22
|
|
|
23
23
|
import typer
|
|
24
24
|
from rich.console import Console
|
|
@@ -49,7 +49,7 @@ def unregister( # pylint: disable=R0914
|
|
|
49
49
|
typer.Argument(help="Path of the Flower project"),
|
|
50
50
|
] = Path("."),
|
|
51
51
|
federation: Annotated[
|
|
52
|
-
|
|
52
|
+
str | None,
|
|
53
53
|
typer.Argument(help="Name of the federation"),
|
|
54
54
|
] = None,
|
|
55
55
|
output_format: Annotated[
|
|
@@ -73,7 +73,7 @@ def unregister( # pylint: disable=R0914
|
|
|
73
73
|
typer.secho("Loading project configuration... ", fg=typer.colors.BLUE)
|
|
74
74
|
|
|
75
75
|
pyproject_path = app / FAB_CONFIG_FILE if app else None
|
|
76
|
-
config, errors, warnings = load_and_validate(
|
|
76
|
+
config, errors, warnings = load_and_validate(pyproject_path, check_module=False)
|
|
77
77
|
config = process_loaded_project_config(config, errors, warnings)
|
|
78
78
|
federation, federation_config = validate_federation_in_project_config(
|
|
79
79
|
federation, config
|
|
@@ -93,6 +93,7 @@ def unregister( # pylint: disable=R0914
|
|
|
93
93
|
f"❌ {err}",
|
|
94
94
|
fg=typer.colors.RED,
|
|
95
95
|
bold=True,
|
|
96
|
+
err=True,
|
|
96
97
|
)
|
|
97
98
|
raise typer.Exit(code=1) from err
|
|
98
99
|
finally:
|
|
@@ -109,6 +110,7 @@ def unregister( # pylint: disable=R0914
|
|
|
109
110
|
f"{err}",
|
|
110
111
|
fg=typer.colors.RED,
|
|
111
112
|
bold=True,
|
|
113
|
+
err=True,
|
|
112
114
|
)
|
|
113
115
|
finally:
|
|
114
116
|
if suppress_output:
|