flwr-nightly 1.23.0.dev20250930__py3-none-any.whl → 1.26.0.dev20260121__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 +17 -6
- flwr/app/__init__.py +4 -1
- flwr/app/error.py +2 -2
- flwr/app/exception.py +3 -3
- flwr/app/message_type.py +29 -0
- flwr/app/metadata.py +5 -2
- flwr/app/user_config.py +19 -0
- flwr/cli/app.py +62 -9
- flwr/cli/{new/templates/app/code → app_cmd}/__init__.py +9 -1
- flwr/cli/app_cmd/publish.py +285 -0
- flwr/cli/app_cmd/review.py +262 -0
- flwr/cli/auth_plugin/__init__.py +13 -6
- flwr/cli/auth_plugin/auth_plugin.py +26 -15
- flwr/cli/auth_plugin/noop_auth_plugin.py +101 -0
- flwr/cli/auth_plugin/oidc_cli_plugin.py +52 -32
- flwr/cli/build.py +166 -53
- flwr/cli/{cli_user_auth_interceptor.py → cli_account_auth_interceptor.py} +27 -10
- flwr/cli/config/__init__.py +21 -0
- flwr/cli/config/ls.py +104 -0
- flwr/cli/config_migration.py +300 -0
- flwr/cli/config_utils.py +154 -13
- flwr/cli/constant.py +67 -0
- flwr/cli/{new/templates/app/code/flwr_tune → federation}/__init__.py +8 -1
- flwr/cli/federation/ls.py +361 -0
- flwr/cli/flower_config.py +447 -0
- flwr/cli/install.py +91 -13
- flwr/cli/log.py +65 -36
- flwr/cli/login/login.py +41 -27
- flwr/cli/ls.py +232 -158
- flwr/cli/new/new.py +188 -244
- flwr/cli/pull.py +25 -34
- flwr/cli/run/run.py +106 -74
- flwr/cli/run_utils.py +148 -0
- flwr/cli/stop.py +46 -37
- flwr/cli/supernode/__init__.py +25 -0
- flwr/cli/supernode/ls.py +273 -0
- flwr/cli/supernode/register.py +190 -0
- flwr/cli/supernode/unregister.py +140 -0
- flwr/cli/typing.py +211 -0
- flwr/cli/utils.py +428 -80
- flwr/client/__init__.py +2 -1
- flwr/client/dpfedavg_numpy_client.py +4 -1
- flwr/client/grpc_adapter_client/connection.py +14 -17
- flwr/client/grpc_rere_client/connection.py +73 -43
- flwr/client/grpc_rere_client/grpc_adapter.py +35 -15
- flwr/client/grpc_rere_client/{client_interceptor.py → node_auth_client_interceptor.py} +5 -7
- flwr/client/message_handler/message_handler.py +4 -3
- flwr/client/mod/centraldp_mods.py +1 -1
- flwr/client/mod/localdp_mod.py +1 -1
- flwr/client/mod/secure_aggregation/secaggplus_mod.py +11 -9
- flwr/client/numpy_client.py +1 -1
- flwr/client/rest_client/connection.py +99 -54
- flwr/client/run_info_store.py +6 -6
- flwr/client/typing.py +1 -1
- flwr/clientapp/__init__.py +1 -2
- flwr/{client → clientapp}/client_app.py +11 -11
- 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/__init__.py +3 -2
- flwr/common/args.py +3 -4
- flwr/common/config.py +15 -17
- flwr/common/constant.py +56 -28
- flwr/common/context.py +2 -1
- flwr/common/differential_privacy.py +3 -4
- flwr/common/event_log_plugin/event_log_plugin.py +3 -4
- flwr/common/exit/exit.py +16 -3
- 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 +8 -7
- 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 +5 -5
- 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 +8 -5
- flwr/common/serde.py +22 -11
- flwr/common/serde_utils.py +2 -2
- flwr/common/telemetry.py +10 -6
- flwr/common/typing.py +65 -44
- flwr/compat/client/app.py +45 -47
- flwr/compat/client/grpc_client/connection.py +15 -14
- flwr/compat/common/constant.py +29 -0
- flwr/compat/server/app.py +6 -7
- 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 +190 -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 +158 -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 +175 -128
- 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 +12 -13
- 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 +12 -10
- 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 +20 -9
- 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 -50
- flwr/server/superlink/fleet/message_handler/message_handler.py +141 -51
- 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/__init__.py +2 -0
- flwr/server/superlink/linkstate/in_memory_linkstate.py +293 -208
- flwr/server/superlink/linkstate/linkstate.py +176 -64
- flwr/server/superlink/linkstate/linkstate_factory.py +24 -6
- flwr/server/superlink/linkstate/sql_linkstate.py +221 -0
- flwr/server/superlink/linkstate/sqlite_linkstate.py +743 -648
- flwr/server/superlink/linkstate/utils.py +11 -62
- 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 +7 -6
- flwr/server/workflow/secure_aggregation/secagg_workflow.py +2 -4
- flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +13 -11
- 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 +10 -11
- 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 +10 -10
- 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 +14 -19
- flwr/simulation/run_simulation.py +46 -44
- flwr/simulation/simulationio_connection.py +4 -4
- flwr/{common → supercore}/address.py +1 -37
- flwr/supercore/cli/flower_superexec.py +3 -4
- flwr/supercore/constant.py +69 -0
- flwr/supercore/corestate/corestate.py +24 -3
- flwr/supercore/corestate/in_memory_corestate.py +138 -0
- flwr/supercore/corestate/sql_corestate.py +153 -0
- flwr/supercore/corestate/sqlite_corestate.py +157 -0
- flwr/supercore/credential_store/__init__.py +33 -0
- flwr/supercore/credential_store/credential_store.py +34 -0
- flwr/supercore/credential_store/file_credential_store.py +76 -0
- flwr/{common → supercore}/date.py +0 -11
- 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/{cli/new/templates/app → supercore/primitives}/__init__.py +1 -1
- flwr/supercore/primitives/asymmetric.py +117 -0
- flwr/supercore/primitives/asymmetric_ed25519.py +175 -0
- flwr/supercore/sql_mixin.py +292 -0
- flwr/supercore/sqlite_mixin.py +156 -0
- flwr/{client/clientapp → supercore/state}/__init__.py +2 -2
- flwr/supercore/state/schema/README.md +125 -0
- flwr/{cli/new/templates → supercore/state/schema}/__init__.py +2 -2
- flwr/supercore/state/schema/corestate_tables.py +36 -0
- flwr/supercore/state/schema/linkstate_tables.py +152 -0
- flwr/supercore/state/schema/objectstore_tables.py +90 -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 +224 -0
- flwr/superlink/artifact_provider/artifact_provider.py +1 -2
- flwr/superlink/auth_plugin/__init__.py +5 -2
- flwr/superlink/auth_plugin/auth_plugin.py +20 -19
- 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 +20 -17
- flwr/superlink/servicer/control/control_license_interceptor.py +3 -3
- flwr/superlink/servicer/control/control_servicer.py +328 -68
- flwr/supernode/cli/flower_supernode.py +74 -26
- flwr/supernode/nodestate/in_memory_nodestate.py +121 -49
- flwr/supernode/nodestate/nodestate.py +52 -8
- flwr/supernode/nodestate/nodestate_factory.py +7 -4
- flwr/supernode/runtime/run_clientapp.py +43 -24
- flwr/supernode/servicer/clientappio/clientappio_servicer.py +48 -10
- flwr/supernode/start_client_internal.py +185 -57
- {flwr_nightly-1.23.0.dev20250930.dist-info → flwr_nightly-1.26.0.dev20260121.dist-info}/METADATA +10 -11
- flwr_nightly-1.26.0.dev20260121.dist-info/RECORD +411 -0
- flwr/cli/new/templates/app/.gitignore.tpl +0 -163
- flwr/cli/new/templates/app/LICENSE.tpl +0 -202
- flwr/cli/new/templates/app/README.baseline.md.tpl +0 -127
- flwr/cli/new/templates/app/README.flowertune.md.tpl +0 -68
- flwr/cli/new/templates/app/README.md.tpl +0 -37
- flwr/cli/new/templates/app/code/__init__.baseline.py.tpl +0 -1
- flwr/cli/new/templates/app/code/__init__.py.tpl +0 -1
- flwr/cli/new/templates/app/code/__init__.pytorch_legacy_api.py.tpl +0 -1
- flwr/cli/new/templates/app/code/client.baseline.py.tpl +0 -75
- flwr/cli/new/templates/app/code/client.huggingface.py.tpl +0 -93
- flwr/cli/new/templates/app/code/client.jax.py.tpl +0 -71
- flwr/cli/new/templates/app/code/client.mlx.py.tpl +0 -102
- flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -46
- flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -80
- flwr/cli/new/templates/app/code/client.pytorch_legacy_api.py.tpl +0 -55
- flwr/cli/new/templates/app/code/client.sklearn.py.tpl +0 -108
- flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -82
- flwr/cli/new/templates/app/code/client.xgboost.py.tpl +0 -110
- flwr/cli/new/templates/app/code/dataset.baseline.py.tpl +0 -36
- flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +0 -92
- flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +0 -87
- flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +0 -56
- flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +0 -73
- flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +0 -78
- flwr/cli/new/templates/app/code/model.baseline.py.tpl +0 -66
- flwr/cli/new/templates/app/code/server.baseline.py.tpl +0 -43
- flwr/cli/new/templates/app/code/server.huggingface.py.tpl +0 -42
- flwr/cli/new/templates/app/code/server.jax.py.tpl +0 -39
- flwr/cli/new/templates/app/code/server.mlx.py.tpl +0 -41
- flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -38
- flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -41
- flwr/cli/new/templates/app/code/server.pytorch_legacy_api.py.tpl +0 -31
- flwr/cli/new/templates/app/code/server.sklearn.py.tpl +0 -44
- flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -38
- flwr/cli/new/templates/app/code/server.xgboost.py.tpl +0 -56
- flwr/cli/new/templates/app/code/strategy.baseline.py.tpl +0 -1
- flwr/cli/new/templates/app/code/task.huggingface.py.tpl +0 -98
- flwr/cli/new/templates/app/code/task.jax.py.tpl +0 -57
- flwr/cli/new/templates/app/code/task.mlx.py.tpl +0 -102
- flwr/cli/new/templates/app/code/task.numpy.py.tpl +0 -7
- flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -98
- flwr/cli/new/templates/app/code/task.pytorch_legacy_api.py.tpl +0 -111
- flwr/cli/new/templates/app/code/task.sklearn.py.tpl +0 -67
- flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +0 -52
- flwr/cli/new/templates/app/code/task.xgboost.py.tpl +0 -67
- flwr/cli/new/templates/app/code/utils.baseline.py.tpl +0 -1
- flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +0 -146
- flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +0 -80
- flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +0 -65
- flwr/cli/new/templates/app/pyproject.jax.toml.tpl +0 -52
- flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +0 -56
- flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +0 -49
- flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +0 -53
- flwr/cli/new/templates/app/pyproject.pytorch_legacy_api.toml.tpl +0 -53
- flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +0 -52
- flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +0 -53
- flwr/cli/new/templates/app/pyproject.xgboost.toml.tpl +0 -61
- flwr/common/pyproject.py +0 -42
- flwr/supercore/object_store/utils.py +0 -43
- flwr_nightly-1.23.0.dev20250930.dist-info/RECORD +0 -429
- /flwr/{common → supercore}/version.py +0 -0
- {flwr_nightly-1.23.0.dev20250930.dist-info → flwr_nightly-1.26.0.dev20260121.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.23.0.dev20250930.dist-info → flwr_nightly-1.26.0.dev20260121.dist-info}/entry_points.txt +0 -0
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
"""Contextmanager for a REST request-response channel to the Flower server."""
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
from collections.abc import Iterator
|
|
18
|
+
from collections.abc import Callable, Iterator
|
|
19
19
|
from contextlib import contextmanager
|
|
20
20
|
from logging import ERROR, WARN
|
|
21
|
-
from typing import
|
|
21
|
+
from typing import TypeVar
|
|
22
22
|
|
|
23
23
|
from cryptography.hazmat.primitives.asymmetric import ec
|
|
24
24
|
from google.protobuf.message import Message as GrpcMessage
|
|
@@ -27,7 +27,6 @@ from requests.exceptions import ConnectionError as RequestsConnectionError
|
|
|
27
27
|
from flwr.common import GRPC_MAX_MESSAGE_LENGTH
|
|
28
28
|
from flwr.common.constant import HEARTBEAT_DEFAULT_INTERVAL
|
|
29
29
|
from flwr.common.exit import ExitCode, flwr_exit
|
|
30
|
-
from flwr.common.heartbeat import HeartbeatSender
|
|
31
30
|
from flwr.common.inflatable_protobuf_utils import (
|
|
32
31
|
make_confirm_message_received_fn_protobuf,
|
|
33
32
|
make_pull_object_fn_protobuf,
|
|
@@ -36,18 +35,27 @@ from flwr.common.inflatable_protobuf_utils import (
|
|
|
36
35
|
from flwr.common.logger import log
|
|
37
36
|
from flwr.common.message import Message, remove_content_from_message
|
|
38
37
|
from flwr.common.retry_invoker import RetryInvoker
|
|
39
|
-
from flwr.common.serde import
|
|
38
|
+
from flwr.common.serde import (
|
|
39
|
+
fab_from_proto,
|
|
40
|
+
message_from_proto,
|
|
41
|
+
message_to_proto,
|
|
42
|
+
run_from_proto,
|
|
43
|
+
)
|
|
40
44
|
from flwr.common.typing import Fab, Run
|
|
41
45
|
from flwr.proto.fab_pb2 import GetFabRequest, GetFabResponse # pylint: disable=E0611
|
|
42
46
|
from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
ActivateNodeRequest,
|
|
48
|
+
ActivateNodeResponse,
|
|
49
|
+
DeactivateNodeRequest,
|
|
50
|
+
DeactivateNodeResponse,
|
|
47
51
|
PullMessagesRequest,
|
|
48
52
|
PullMessagesResponse,
|
|
49
53
|
PushMessagesRequest,
|
|
50
54
|
PushMessagesResponse,
|
|
55
|
+
RegisterNodeFleetRequest,
|
|
56
|
+
RegisterNodeFleetResponse,
|
|
57
|
+
UnregisterNodeFleetRequest,
|
|
58
|
+
UnregisterNodeFleetResponse,
|
|
51
59
|
)
|
|
52
60
|
from flwr.proto.heartbeat_pb2 import ( # pylint: disable=E0611
|
|
53
61
|
SendNodeHeartbeatRequest,
|
|
@@ -64,6 +72,8 @@ from flwr.proto.message_pb2 import ( # pylint: disable=E0611
|
|
|
64
72
|
)
|
|
65
73
|
from flwr.proto.node_pb2 import Node # pylint: disable=E0611
|
|
66
74
|
from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611
|
|
75
|
+
from flwr.supercore.heartbeat import HeartbeatSender
|
|
76
|
+
from flwr.supercore.primitives.asymmetric import generate_key_pairs, public_key_to_bytes
|
|
67
77
|
|
|
68
78
|
try:
|
|
69
79
|
import requests
|
|
@@ -71,8 +81,10 @@ except ModuleNotFoundError:
|
|
|
71
81
|
flwr_exit(ExitCode.COMMON_MISSING_EXTRA_REST)
|
|
72
82
|
|
|
73
83
|
|
|
74
|
-
|
|
75
|
-
|
|
84
|
+
PATH_REGISTER_NODE: str = "/api/v0/fleet/register-node"
|
|
85
|
+
PATH_ACTIVATE_NODE: str = "/api/v0/fleet/activate-node"
|
|
86
|
+
PATH_DEACTIVATE_NODE: str = "/api/v0/fleet/deactivate-node"
|
|
87
|
+
PATH_UNREGISTER_NODE: str = "/api/v0/fleet/unregister-node"
|
|
76
88
|
PATH_PULL_MESSAGES: str = "/api/v0/fleet/pull-messages"
|
|
77
89
|
PATH_PUSH_MESSAGES: str = "/api/v0/fleet/push-messages"
|
|
78
90
|
PATH_PULL_OBJECT: str = "/api/v0/fleet/pull-object"
|
|
@@ -91,18 +103,15 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
|
91
103
|
insecure: bool, # pylint: disable=unused-argument
|
|
92
104
|
retry_invoker: RetryInvoker,
|
|
93
105
|
max_message_length: int = GRPC_MAX_MESSAGE_LENGTH, # pylint: disable=W0613
|
|
94
|
-
root_certificates:
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
tuple[ec.EllipticCurvePrivateKey, ec.EllipticCurvePublicKey]
|
|
99
|
-
] = None,
|
|
106
|
+
root_certificates: bytes | str | None = None, # pylint: disable=unused-argument
|
|
107
|
+
authentication_keys: (
|
|
108
|
+
tuple[ec.EllipticCurvePrivateKey, ec.EllipticCurvePublicKey] | None
|
|
109
|
+
) = None,
|
|
100
110
|
) -> Iterator[
|
|
101
111
|
tuple[
|
|
102
|
-
|
|
103
|
-
Callable[[Message, ObjectTree]
|
|
104
|
-
Callable[[],
|
|
105
|
-
Callable[[], None],
|
|
112
|
+
int,
|
|
113
|
+
Callable[[], tuple[Message, ObjectTree] | None],
|
|
114
|
+
Callable[[Message, ObjectTree, float], set[str]],
|
|
106
115
|
Callable[[int], Run],
|
|
107
116
|
Callable[[str, int], Fab],
|
|
108
117
|
Callable[[int, str], bytes],
|
|
@@ -134,15 +143,15 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
|
134
143
|
connection using the certificates will be established to an SSL-enabled
|
|
135
144
|
Flower server. Bytes won't work for the REST API.
|
|
136
145
|
authentication_keys : Optional[Tuple[PrivateKey, PublicKey]] (default: None)
|
|
137
|
-
|
|
146
|
+
SuperNode authentication is not supported for this transport type.
|
|
138
147
|
|
|
139
148
|
Returns
|
|
140
149
|
-------
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
150
|
+
node_id : int
|
|
151
|
+
receive : Callable[[], Optional[tuple[Message, ObjectTree]]]
|
|
152
|
+
send : Callable[[Message, ObjectTree, float], set[str]]
|
|
153
|
+
get_run : Callable[[int], Run]
|
|
154
|
+
get_fab : Callable[[str, int], Fab]
|
|
146
155
|
pull_object : Callable[[str], bytes]
|
|
147
156
|
push_object : Callable[[str, bytes], None]
|
|
148
157
|
confirm_message_received : Callable[[str], None]
|
|
@@ -161,7 +170,7 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
|
161
170
|
# Otherwise any server can fake its identity
|
|
162
171
|
# Please refer to:
|
|
163
172
|
# https://requests.readthedocs.io/en/latest/user/advanced/#ssl-cert-verification
|
|
164
|
-
verify:
|
|
173
|
+
verify: bool | str = True
|
|
165
174
|
if isinstance(root_certificates, str):
|
|
166
175
|
verify = root_certificates
|
|
167
176
|
elif isinstance(root_certificates, bytes):
|
|
@@ -171,21 +180,28 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
|
171
180
|
"must be provided as a string path to the client.",
|
|
172
181
|
)
|
|
173
182
|
if authentication_keys is not None:
|
|
174
|
-
log(ERROR, "
|
|
183
|
+
log(ERROR, "SuperNode authentication is not supported for this transport type.")
|
|
184
|
+
|
|
185
|
+
# REST does NOT support node authentication
|
|
186
|
+
self_registered = False
|
|
187
|
+
if authentication_keys is None:
|
|
188
|
+
self_registered = True
|
|
189
|
+
authentication_keys = generate_key_pairs()
|
|
190
|
+
node_pk = public_key_to_bytes(authentication_keys[1])
|
|
175
191
|
|
|
176
192
|
# Shared variables for inner functions
|
|
177
|
-
node:
|
|
193
|
+
node: Node | None = None
|
|
178
194
|
|
|
179
195
|
# Remove should_giveup from RetryInvoker as REST does not support gRPC status codes
|
|
180
196
|
retry_invoker.should_giveup = None
|
|
181
197
|
|
|
182
198
|
###########################################################################
|
|
183
|
-
#
|
|
199
|
+
# SuperNode functions
|
|
184
200
|
###########################################################################
|
|
185
201
|
|
|
186
202
|
def _request(
|
|
187
203
|
req: GrpcMessage, res_type: type[T], api_path: str, retry: bool = True
|
|
188
|
-
) ->
|
|
204
|
+
) -> T | None:
|
|
189
205
|
# Serialize the request
|
|
190
206
|
req_bytes = req.SerializeToString()
|
|
191
207
|
|
|
@@ -290,23 +306,35 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
|
290
306
|
|
|
291
307
|
heartbeat_sender = HeartbeatSender(send_node_heartbeat)
|
|
292
308
|
|
|
293
|
-
def
|
|
294
|
-
"""
|
|
295
|
-
req =
|
|
309
|
+
def register_node() -> None:
|
|
310
|
+
"""Register node with SuperLink."""
|
|
311
|
+
req = RegisterNodeFleetRequest(public_key=node_pk)
|
|
296
312
|
|
|
297
313
|
# Send the request
|
|
298
|
-
res = _request(req,
|
|
314
|
+
res = _request(req, RegisterNodeFleetResponse, PATH_REGISTER_NODE)
|
|
299
315
|
if res is None:
|
|
300
|
-
|
|
316
|
+
raise RuntimeError("Failed to register node")
|
|
317
|
+
|
|
318
|
+
def activate_node() -> int:
|
|
319
|
+
"""Activate node and start heartbeat."""
|
|
320
|
+
req = ActivateNodeRequest(
|
|
321
|
+
public_key=node_pk,
|
|
322
|
+
heartbeat_interval=HEARTBEAT_DEFAULT_INTERVAL,
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
# Send the request
|
|
326
|
+
res = _request(req, ActivateNodeResponse, PATH_ACTIVATE_NODE)
|
|
327
|
+
if res is None:
|
|
328
|
+
raise RuntimeError("Failed to activate node")
|
|
301
329
|
|
|
302
330
|
# Remember the node and start the heartbeat sender
|
|
303
331
|
nonlocal node
|
|
304
|
-
node = res.
|
|
332
|
+
node = Node(node_id=res.node_id)
|
|
305
333
|
heartbeat_sender.start()
|
|
306
334
|
return node.node_id
|
|
307
335
|
|
|
308
|
-
def
|
|
309
|
-
"""
|
|
336
|
+
def deactivate_node() -> None:
|
|
337
|
+
"""Deactivate node and stop heartbeat."""
|
|
310
338
|
nonlocal node
|
|
311
339
|
if node is None:
|
|
312
340
|
raise RuntimeError("Node instance missing")
|
|
@@ -314,18 +342,32 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
|
314
342
|
# Stop the heartbeat sender
|
|
315
343
|
heartbeat_sender.stop()
|
|
316
344
|
|
|
317
|
-
# Send
|
|
318
|
-
req =
|
|
345
|
+
# Send DeactivateNode request
|
|
346
|
+
req = DeactivateNodeRequest(node_id=node.node_id)
|
|
347
|
+
|
|
348
|
+
# Send the request
|
|
349
|
+
res = _request(req, DeactivateNodeResponse, PATH_DEACTIVATE_NODE)
|
|
350
|
+
if res is None:
|
|
351
|
+
raise RuntimeError("Failed to deactivate node")
|
|
352
|
+
|
|
353
|
+
def unregister_node() -> None:
|
|
354
|
+
"""Unregister node from SuperLink."""
|
|
355
|
+
nonlocal node
|
|
356
|
+
if node is None:
|
|
357
|
+
raise RuntimeError("Node instance missing")
|
|
358
|
+
|
|
359
|
+
# Send UnregisterNode request
|
|
360
|
+
req = UnregisterNodeFleetRequest(node_id=node.node_id)
|
|
319
361
|
|
|
320
362
|
# Send the request
|
|
321
|
-
res = _request(req,
|
|
363
|
+
res = _request(req, UnregisterNodeFleetResponse, PATH_UNREGISTER_NODE)
|
|
322
364
|
if res is None:
|
|
323
|
-
|
|
365
|
+
raise RuntimeError("Failed to unregister node")
|
|
324
366
|
|
|
325
367
|
# Cleanup
|
|
326
368
|
node = None
|
|
327
369
|
|
|
328
|
-
def receive() ->
|
|
370
|
+
def receive() -> tuple[Message, ObjectTree] | None:
|
|
329
371
|
"""Pull a message with its ObjectTree from SuperLink."""
|
|
330
372
|
# Get Node
|
|
331
373
|
if node is None:
|
|
@@ -351,12 +393,13 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
|
351
393
|
# Return the Message and its object tree
|
|
352
394
|
return in_message, object_tree
|
|
353
395
|
|
|
354
|
-
def send(
|
|
396
|
+
def send(
|
|
397
|
+
message: Message, object_tree: ObjectTree, clientapp_runtime: float
|
|
398
|
+
) -> set[str]:
|
|
355
399
|
"""Send the message with its ObjectTree to SuperLink."""
|
|
356
400
|
# Get Node
|
|
357
401
|
if node is None:
|
|
358
402
|
raise RuntimeError("Node instance missing")
|
|
359
|
-
|
|
360
403
|
# Remove the content from the message if it has
|
|
361
404
|
if message.has_content():
|
|
362
405
|
message = remove_content_from_message(message)
|
|
@@ -366,6 +409,7 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
|
366
409
|
node=node,
|
|
367
410
|
messages_list=[message_to_proto(message)],
|
|
368
411
|
message_object_trees=[object_tree],
|
|
412
|
+
clientapp_runtime_list=[clientapp_runtime],
|
|
369
413
|
)
|
|
370
414
|
res = _request(req, PushMessagesResponse, PATH_PUSH_MESSAGES)
|
|
371
415
|
if res is None:
|
|
@@ -392,12 +436,9 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
|
392
436
|
# Send the request
|
|
393
437
|
res = _request(req, GetFabResponse, PATH_GET_FAB)
|
|
394
438
|
if res is None:
|
|
395
|
-
return Fab("", b"")
|
|
439
|
+
return Fab("", b"", {})
|
|
396
440
|
|
|
397
|
-
return
|
|
398
|
-
res.fab.hash_str,
|
|
399
|
-
res.fab.content,
|
|
400
|
-
)
|
|
441
|
+
return fab_from_proto(res.fab)
|
|
401
442
|
|
|
402
443
|
def pull_object(run_id: int, object_id: str) -> bytes:
|
|
403
444
|
"""Pull the object from the SuperLink."""
|
|
@@ -439,12 +480,14 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
|
439
480
|
fn(object_id)
|
|
440
481
|
|
|
441
482
|
try:
|
|
483
|
+
if self_registered:
|
|
484
|
+
register_node()
|
|
485
|
+
node_id = activate_node()
|
|
442
486
|
# Yield methods
|
|
443
487
|
yield (
|
|
488
|
+
node_id,
|
|
444
489
|
receive,
|
|
445
490
|
send,
|
|
446
|
-
create_node,
|
|
447
|
-
delete_node,
|
|
448
491
|
get_run,
|
|
449
492
|
get_fab,
|
|
450
493
|
pull_object,
|
|
@@ -459,6 +502,8 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
|
459
502
|
if node is not None:
|
|
460
503
|
# Disable retrying
|
|
461
504
|
retry_invoker.max_tries = 1
|
|
462
|
-
|
|
505
|
+
deactivate_node()
|
|
506
|
+
if self_registered:
|
|
507
|
+
unregister_node()
|
|
463
508
|
except RequestsConnectionError:
|
|
464
509
|
pass
|
flwr/client/run_info_store.py
CHANGED
|
@@ -17,15 +17,15 @@
|
|
|
17
17
|
|
|
18
18
|
from dataclasses import dataclass
|
|
19
19
|
from pathlib import Path
|
|
20
|
-
from typing import Optional
|
|
21
20
|
|
|
21
|
+
from flwr.app.user_config import UserConfig
|
|
22
22
|
from flwr.common import Context, RecordDict
|
|
23
23
|
from flwr.common.config import (
|
|
24
24
|
get_fused_config,
|
|
25
25
|
get_fused_config_from_dir,
|
|
26
26
|
get_fused_config_from_fab,
|
|
27
27
|
)
|
|
28
|
-
from flwr.common.typing import Fab, Run
|
|
28
|
+
from flwr.common.typing import Fab, Run
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
@dataclass()
|
|
@@ -52,10 +52,10 @@ class DeprecatedRunInfoStore:
|
|
|
52
52
|
def register_context(
|
|
53
53
|
self,
|
|
54
54
|
run_id: int,
|
|
55
|
-
run:
|
|
56
|
-
flwr_path:
|
|
57
|
-
app_dir:
|
|
58
|
-
fab:
|
|
55
|
+
run: Run | None = None,
|
|
56
|
+
flwr_path: Path | None = None,
|
|
57
|
+
app_dir: str | None = None,
|
|
58
|
+
fab: Fab | None = None,
|
|
59
59
|
) -> None:
|
|
60
60
|
"""Register new run context for this node."""
|
|
61
61
|
if run_id not in self.run_infos:
|
flwr/client/typing.py
CHANGED
flwr/clientapp/__init__.py
CHANGED
|
@@ -16,10 +16,10 @@
|
|
|
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
|
|
|
22
|
+
from flwr.app.message_type import MessageType
|
|
23
23
|
from flwr.app.metadata import validate_message_type
|
|
24
24
|
from flwr.client.client import Client
|
|
25
25
|
from flwr.client.message_handler.message_handler import (
|
|
@@ -27,7 +27,7 @@ from flwr.client.message_handler.message_handler import (
|
|
|
27
27
|
)
|
|
28
28
|
from flwr.client.mod.utils import make_ffn
|
|
29
29
|
from flwr.client.typing import ClientFnExt, Mod
|
|
30
|
-
from flwr.common import Context, Message
|
|
30
|
+
from flwr.common import Context, Message
|
|
31
31
|
from flwr.common.logger import warn_deprecated_feature
|
|
32
32
|
|
|
33
33
|
from .typing import ClientAppCallable
|
|
@@ -109,14 +109,14 @@ class ClientApp:
|
|
|
109
109
|
|
|
110
110
|
def __init__(
|
|
111
111
|
self,
|
|
112
|
-
client_fn:
|
|
113
|
-
mods:
|
|
112
|
+
client_fn: ClientFnExt | None = None, # Only for backward compatibility
|
|
113
|
+
mods: list[Mod] | None = None,
|
|
114
114
|
) -> None:
|
|
115
115
|
self._mods: list[Mod] = mods if mods is not None else []
|
|
116
116
|
self._registered_funcs: dict[str, ClientAppCallable] = {}
|
|
117
117
|
|
|
118
118
|
# Create wrapper function for `handle`
|
|
119
|
-
self._call:
|
|
119
|
+
self._call: ClientAppCallable | None = None
|
|
120
120
|
if client_fn is not None:
|
|
121
121
|
|
|
122
122
|
client_fn = _inspect_maybe_adapt_client_fn_signature(client_fn)
|
|
@@ -163,7 +163,7 @@ class ClientApp:
|
|
|
163
163
|
raise ValueError(f"No {category} function registered with name '{action}'")
|
|
164
164
|
|
|
165
165
|
def train(
|
|
166
|
-
self, action: str = DEFAULT_ACTION, *, mods:
|
|
166
|
+
self, action: str = DEFAULT_ACTION, *, mods: list[Mod] | None = None
|
|
167
167
|
) -> Callable[[ClientAppCallable], ClientAppCallable]:
|
|
168
168
|
"""Register a train function with the ``ClientApp``.
|
|
169
169
|
|
|
@@ -218,7 +218,7 @@ class ClientApp:
|
|
|
218
218
|
return _get_decorator(self, MessageType.TRAIN, action, mods)
|
|
219
219
|
|
|
220
220
|
def evaluate(
|
|
221
|
-
self, action: str = DEFAULT_ACTION, *, mods:
|
|
221
|
+
self, action: str = DEFAULT_ACTION, *, mods: list[Mod] | None = None
|
|
222
222
|
) -> Callable[[ClientAppCallable], ClientAppCallable]:
|
|
223
223
|
"""Register an evaluate function with the ``ClientApp``.
|
|
224
224
|
|
|
@@ -273,7 +273,7 @@ class ClientApp:
|
|
|
273
273
|
return _get_decorator(self, MessageType.EVALUATE, action, mods)
|
|
274
274
|
|
|
275
275
|
def query(
|
|
276
|
-
self, action: str = DEFAULT_ACTION, *, mods:
|
|
276
|
+
self, action: str = DEFAULT_ACTION, *, mods: list[Mod] | None = None
|
|
277
277
|
) -> Callable[[ClientAppCallable], ClientAppCallable]:
|
|
278
278
|
"""Register a query function with the ``ClientApp``.
|
|
279
279
|
|
|
@@ -355,7 +355,7 @@ class ClientApp:
|
|
|
355
355
|
"""
|
|
356
356
|
|
|
357
357
|
def lifespan_decorator(
|
|
358
|
-
lifespan_fn: Callable[[Context], Iterator[None]]
|
|
358
|
+
lifespan_fn: Callable[[Context], Iterator[None]],
|
|
359
359
|
) -> Callable[[Context], Iterator[None]]:
|
|
360
360
|
"""Register the lifespan fn with the ServerApp object."""
|
|
361
361
|
|
|
@@ -398,7 +398,7 @@ class LoadClientAppError(Exception):
|
|
|
398
398
|
|
|
399
399
|
|
|
400
400
|
def _get_decorator(
|
|
401
|
-
app: ClientApp, category: str, action: str, mods:
|
|
401
|
+
app: ClientApp, category: str, action: str, mods: list[Mod] | None
|
|
402
402
|
) -> Callable[[ClientAppCallable], ClientAppCallable]:
|
|
403
403
|
"""Get the decorator for the given category and action."""
|
|
404
404
|
# pylint: disable=protected-access
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
"""Clipping modifiers for central DP with client-side clipping."""
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
from collections import OrderedDict
|
|
19
18
|
from logging import ERROR, INFO
|
|
20
19
|
from typing import cast
|
|
21
20
|
|
|
@@ -105,14 +104,14 @@ def fixedclipping_mod(
|
|
|
105
104
|
)
|
|
106
105
|
# Replace outgoing ArrayRecord's Array while preserving their keys
|
|
107
106
|
out_msg.content.array_records[new_array_record_key] = ArrayRecord(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
107
|
+
{
|
|
108
|
+
k: Array(v)
|
|
109
|
+
for k, v in zip(
|
|
110
|
+
client_to_server_arrecord.keys(),
|
|
111
|
+
client_to_server_ndarrays,
|
|
112
|
+
strict=True,
|
|
113
|
+
)
|
|
114
|
+
}
|
|
116
115
|
)
|
|
117
116
|
return out_msg
|
|
118
117
|
|
|
@@ -192,14 +191,14 @@ def adaptiveclipping_mod(
|
|
|
192
191
|
)
|
|
193
192
|
# Replace outgoing ArrayRecord's Array while preserving their keys
|
|
194
193
|
out_msg.content.array_records[new_array_record_key] = ArrayRecord(
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
194
|
+
{
|
|
195
|
+
k: Array(v)
|
|
196
|
+
for k, v in zip(
|
|
197
|
+
client_to_server_arrecord.keys(),
|
|
198
|
+
client_to_server_ndarrays,
|
|
199
|
+
strict=True,
|
|
200
|
+
)
|
|
201
|
+
}
|
|
203
202
|
)
|
|
204
203
|
# Add to the MetricRecords the norm bit (recall reply messages only contain
|
|
205
204
|
# one MetricRecord)
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
"""Local DP modifier."""
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
from collections import OrderedDict
|
|
19
18
|
from logging import INFO
|
|
20
19
|
|
|
21
20
|
import numpy as np
|
|
@@ -157,13 +156,13 @@ class LocalDpMod:
|
|
|
157
156
|
|
|
158
157
|
# Replace outgoing ArrayRecord's Array while preserving their keys
|
|
159
158
|
out_msg.content[new_array_record_key] = ArrayRecord(
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
159
|
+
{
|
|
160
|
+
k: Array(v)
|
|
161
|
+
for k, v in zip(
|
|
162
|
+
client_to_server_arrecord.keys(),
|
|
163
|
+
client_to_server_ndarrays,
|
|
164
|
+
strict=True,
|
|
165
|
+
)
|
|
166
|
+
}
|
|
168
167
|
)
|
|
169
168
|
return out_msg
|
flwr/clientapp/typing.py
CHANGED
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
"""Flower ClientApp loading utils."""
|
|
16
16
|
|
|
17
17
|
|
|
18
|
+
from collections.abc import Callable
|
|
18
19
|
from logging import DEBUG
|
|
19
20
|
from pathlib import Path
|
|
20
|
-
from typing import Callable, Optional
|
|
21
21
|
|
|
22
|
-
from flwr.
|
|
22
|
+
from flwr.clientapp.client_app import ClientApp, LoadClientAppError
|
|
23
23
|
from flwr.common.config import (
|
|
24
24
|
get_flwr_dir,
|
|
25
25
|
get_metadata_from_config,
|
|
@@ -32,9 +32,9 @@ from flwr.common.object_ref import load_app, validate
|
|
|
32
32
|
|
|
33
33
|
def get_load_client_app_fn(
|
|
34
34
|
default_app_ref: str,
|
|
35
|
-
app_path:
|
|
35
|
+
app_path: str | None,
|
|
36
36
|
multi_app: bool,
|
|
37
|
-
flwr_dir:
|
|
37
|
+
flwr_dir: str | None = None,
|
|
38
38
|
) -> Callable[[str, str, str], ClientApp]:
|
|
39
39
|
"""Get the load_client_app_fn function.
|
|
40
40
|
|
flwr/common/__init__.py
CHANGED
|
@@ -15,12 +15,13 @@
|
|
|
15
15
|
"""Common components shared between server and client."""
|
|
16
16
|
|
|
17
17
|
|
|
18
|
+
from flwr.app.message_type import MessageType as MessageType
|
|
19
|
+
|
|
18
20
|
from ..app.error import Error as Error
|
|
19
21
|
from ..app.metadata import Metadata as Metadata
|
|
20
|
-
from .
|
|
22
|
+
from ..supercore.date import now as now
|
|
21
23
|
from .constant import MessageTypeLegacy as MessageTypeLegacy
|
|
22
24
|
from .context import Context as Context
|
|
23
|
-
from .date import now as now
|
|
24
25
|
from .grpc import GRPC_MAX_MESSAGE_LENGTH
|
|
25
26
|
from .logger import configure as configure
|
|
26
27
|
from .logger import log as log
|
flwr/common/args.py
CHANGED
|
@@ -20,7 +20,6 @@ import sys
|
|
|
20
20
|
from logging import DEBUG, ERROR, INFO, WARN
|
|
21
21
|
from os.path import isfile
|
|
22
22
|
from pathlib import Path
|
|
23
|
-
from typing import Optional, Union
|
|
24
23
|
|
|
25
24
|
from flwr.common.constant import TRANSPORT_TYPE_REST
|
|
26
25
|
from flwr.common.logger import log
|
|
@@ -70,9 +69,9 @@ def add_args_flwr_app_common(parser: argparse.ArgumentParser) -> None:
|
|
|
70
69
|
def try_obtain_root_certificates(
|
|
71
70
|
args: argparse.Namespace,
|
|
72
71
|
grpc_server_address: str,
|
|
73
|
-
) ->
|
|
72
|
+
) -> bytes | str | None:
|
|
74
73
|
"""Validate and return the root certificates."""
|
|
75
|
-
root_cert_path:
|
|
74
|
+
root_cert_path: str | None = args.root_certificates
|
|
76
75
|
if args.insecure:
|
|
77
76
|
if root_cert_path is not None:
|
|
78
77
|
sys.exit(
|
|
@@ -111,7 +110,7 @@ def try_obtain_root_certificates(
|
|
|
111
110
|
|
|
112
111
|
def try_obtain_server_certificates(
|
|
113
112
|
args: argparse.Namespace,
|
|
114
|
-
) ->
|
|
113
|
+
) -> tuple[bytes, bytes, bytes] | None:
|
|
115
114
|
"""Validate and return the CA cert, server cert, and server private key."""
|
|
116
115
|
if args.insecure:
|
|
117
116
|
log(
|