flwr-nightly 1.26.0.dev20260113__tar.gz → 1.26.0.dev20260115__tar.gz
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_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/PKG-INFO +1 -1
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/app.py +9 -1
- flwr_nightly-1.26.0.dev20260115/py/flwr/cli/config/__init__.py +21 -0
- flwr_nightly-1.26.0.dev20260115/py/flwr/cli/config/ls.py +104 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/constant.py +67 -0
- flwr_nightly-1.26.0.dev20260115/py/flwr/cli/flower_config.py +422 -0
- {flwr_nightly-1.26.0.dev20260113/py/flwr/supercore → flwr_nightly-1.26.0.dev20260115/py/flwr/cli}/typing.py +51 -2
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/utils.py +0 -215
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/grpc_rere/node_auth_server_interceptor.py +13 -12
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/linkstate/in_memory_linkstate.py +0 -9
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/linkstate/linkstate.py +0 -20
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/linkstate/sqlite_linkstate.py +0 -23
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/constant.py +0 -62
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/servicer/control/control_servicer.py +2 -1
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/pyproject.toml +1 -1
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/README.md +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/app/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/app/error.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/app/exception.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/app/message_type.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/app/metadata.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/app/user_config.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/app_cmd/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/app_cmd/publish.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/app_cmd/review.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/auth_plugin/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/auth_plugin/auth_plugin.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/auth_plugin/noop_auth_plugin.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/auth_plugin/oidc_cli_plugin.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/build.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/cli_account_auth_interceptor.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/config_utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/example.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/federation/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/federation/ls.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/install.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/log.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/login/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/login/login.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/ls.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/new/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/new/new.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/pull.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/run/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/run/run.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/run_utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/stop.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/supernode/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/supernode/ls.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/supernode/register.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/cli/supernode/unregister.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/client.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/dpfedavg_numpy_client.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/grpc_adapter_client/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/grpc_adapter_client/connection.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/grpc_rere_client/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/grpc_rere_client/connection.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/grpc_rere_client/grpc_adapter.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/grpc_rere_client/node_auth_client_interceptor.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/message_handler/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/message_handler/message_handler.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/mod/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/mod/centraldp_mods.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/mod/comms_mods.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/mod/localdp_mod.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/mod/utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/numpy_client.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/rest_client/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/rest_client/connection.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/run_info_store.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/client/typing.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/clientapp/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/clientapp/client_app.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/clientapp/mod/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/clientapp/mod/centraldp_mods.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/clientapp/mod/localdp_mod.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/clientapp/typing.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/clientapp/utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/args.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/config.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/constant.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/context.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/differential_privacy.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/differential_privacy_constants.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/dp.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/event_log_plugin/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/event_log_plugin/event_log_plugin.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/exit/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/exit/exit.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/exit/exit_code.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/exit/exit_handler.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/exit/signal_handler.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/inflatable.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/inflatable_protobuf_utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/inflatable_utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/logger.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/message.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/object_ref.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/parameter.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/record/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/record/array.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/record/arraychunk.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/record/arrayrecord.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/record/configrecord.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/record/conversion_utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/record/metricrecord.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/record/recorddict.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/record/typeddict.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/recorddict_compat.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/retry_invoker.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/secure_aggregation/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/secure_aggregation/quantization.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/serde.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/serde_utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/telemetry.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/common/typing.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/compat/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/compat/client/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/compat/client/app.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/compat/client/grpc_client/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/compat/client/grpc_client/connection.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/compat/common/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/compat/common/constant.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/compat/server/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/compat/server/app.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/compat/simulation/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/appio_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/appio_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/appio_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/appio_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/clientappio_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/clientappio_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/clientappio_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/clientappio_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/control_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/control_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/control_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/control_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/error_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/error_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/error_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/error_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/fab_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/fab_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/fab_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/fab_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/federation_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/federation_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/federation_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/federation_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/fleet_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/fleet_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/fleet_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/grpcadapter_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/grpcadapter_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/grpcadapter_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/grpcadapter_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/heartbeat_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/heartbeat_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/heartbeat_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/heartbeat_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/log_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/log_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/log_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/log_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/message_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/message_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/message_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/message_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/node_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/node_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/node_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/node_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/recorddict_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/recorddict_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/recorddict_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/recorddict_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/run_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/run_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/run_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/run_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/serverappio_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/serverappio_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/serverappio_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/serverappio_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/simulationio_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/simulationio_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/simulationio_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/simulationio_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/transport_pb2.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/transport_pb2.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/transport_pb2_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/py.typed +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/app.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/client_manager.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/client_proxy.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/compat/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/compat/app.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/compat/app_utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/compat/grid_client_proxy.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/compat/legacy_context.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/criterion.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/fleet_event_log_interceptor.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/grid/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/grid/grid.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/grid/grpc_grid.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/grid/inmemory_grid.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/history.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/run_serverapp.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/server.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/server_app.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/server_config.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/serverapp/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/serverapp/app.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/serverapp_components.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/aggregate.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/bulyan.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/fedadagrad.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/fedadam.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/fedavg.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/fedavg_android.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/fedavgm.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/fedmedian.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/fedopt.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/fedprox.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/fedyogi.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/krum.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/qfedavg.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/strategy/strategy.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/message_handler/message_handler.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/fleet/vce/vce_api.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/linkstate/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/linkstate/linkstate_factory.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/linkstate/utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/serverappio/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/serverappio/serverappio_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/serverappio/serverappio_servicer.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/simulation/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/simulation/simulationio_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/simulation/simulationio_servicer.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/superlink/utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/typing.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/utils/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/utils/tensorboard.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/utils/validator.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/workflow/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/workflow/constant.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/workflow/default_workflows.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/exception.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/bulyan.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/dp_adaptive_clipping.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/dp_fixed_clipping.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/fedadagrad.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/fedadam.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/fedavg.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/fedavgm.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/fedmedian.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/fedopt.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/fedprox.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/fedtrimmedavg.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/fedxgb_bagging.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/fedxgb_cyclic.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/fedyogi.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/krum.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/multikrum.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/qfedavg.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/result.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/strategy.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/serverapp/strategy/strategy_utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/simulation/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/simulation/app.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/simulation/legacy_app.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/simulation/ray_transport/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/simulation/ray_transport/utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/simulation/run_simulation.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/simulation/simulationio_connection.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/address.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/app_utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/cli/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/cli/flower_superexec.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/corestate/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/corestate/corestate.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/corestate/in_memory_corestate.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/corestate/sqlite_corestate.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/date.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/ffs/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/ffs/disk_ffs.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/ffs/ffs.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/ffs/ffs_factory.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/grpc_health/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/grpc_health/health_server.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/grpc_health/simple_health_servicer.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/heartbeat.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/license_plugin/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/license_plugin/license_plugin.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/object_store/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/object_store/in_memory_object_store.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/object_store/object_store.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/object_store/object_store_factory.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/object_store/sqlite_object_store.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/primitives/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/primitives/asymmetric.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/primitives/asymmetric_ed25519.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/sqlite_mixin.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/superexec/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/superexec/plugin/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/superexec/plugin/base_exec_plugin.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/superexec/plugin/clientapp_exec_plugin.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/superexec/plugin/exec_plugin.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/superexec/plugin/serverapp_exec_plugin.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/superexec/plugin/simulation_exec_plugin.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/superexec/run_superexec.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/utils.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supercore/version.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/artifact_provider/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/artifact_provider/artifact_provider.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/auth_plugin/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/auth_plugin/auth_plugin.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/auth_plugin/noop_auth_plugin.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/federation/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/federation/federation_manager.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/federation/noop_federation_manager.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/servicer/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/servicer/control/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/servicer/control/control_account_auth_interceptor.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/servicer/control/control_event_log_interceptor.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/servicer/control/control_grpc.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/superlink/servicer/control/control_license_interceptor.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supernode/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supernode/cli/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supernode/cli/flower_supernode.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supernode/cli/flwr_clientapp.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supernode/nodestate/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supernode/nodestate/in_memory_nodestate.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supernode/nodestate/nodestate.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supernode/nodestate/nodestate_factory.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supernode/runtime/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supernode/runtime/run_clientapp.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supernode/servicer/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supernode/servicer/clientappio/__init__.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supernode/servicer/clientappio/clientappio_servicer.py +0 -0
- {flwr_nightly-1.26.0.dev20260113 → flwr_nightly-1.26.0.dev20260115}/py/flwr/supernode/start_client_internal.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: flwr-nightly
|
|
3
|
-
Version: 1.26.0.
|
|
3
|
+
Version: 1.26.0.dev20260115
|
|
4
4
|
Summary: Flower: A Friendly Federated AI Framework
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Keywords: Artificial Intelligence,Federated AI,Federated Analytics,Federated Evaluation,Federated Learning,Flower,Machine Learning
|
|
@@ -22,7 +22,9 @@ from flwr.supercore.version import package_version
|
|
|
22
22
|
from .app_cmd import publish as app_publish
|
|
23
23
|
from .app_cmd import review as app_review
|
|
24
24
|
from .build import build
|
|
25
|
+
from .config import ls as config_list
|
|
25
26
|
from .federation import ls as federation_list
|
|
27
|
+
from .flower_config import init_flwr_config
|
|
26
28
|
from .install import install
|
|
27
29
|
from .log import log
|
|
28
30
|
from .login import login
|
|
@@ -34,7 +36,6 @@ from .stop import stop
|
|
|
34
36
|
from .supernode import ls as supernode_list
|
|
35
37
|
from .supernode import register as supernode_register
|
|
36
38
|
from .supernode import unregister as supernode_unregister
|
|
37
|
-
from .utils import init_flwr_config
|
|
38
39
|
|
|
39
40
|
app = typer.Typer(
|
|
40
41
|
help=typer.style(
|
|
@@ -81,6 +82,13 @@ federation_app.command("list")(federation_list)
|
|
|
81
82
|
federation_app.command(hidden=True)(federation_list)
|
|
82
83
|
app.add_typer(federation_app, name="federation")
|
|
83
84
|
|
|
85
|
+
# Create config command group
|
|
86
|
+
config_app = typer.Typer(help="Manage Configuration")
|
|
87
|
+
config_app.command("list")(config_list)
|
|
88
|
+
# Hide "ls" command (left as alias)
|
|
89
|
+
config_app.command(hidden=True)(config_list)
|
|
90
|
+
app.add_typer(config_app, name="config")
|
|
91
|
+
|
|
84
92
|
typer_click_object = get_command(app)
|
|
85
93
|
|
|
86
94
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Copyright 2026 Flower Labs GmbH. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
# ==============================================================================
|
|
15
|
+
"""Flower command line interface `config` command."""
|
|
16
|
+
|
|
17
|
+
from .ls import ls as ls
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"ls",
|
|
21
|
+
]
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Copyright 2026 Flower Labs GmbH. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
# ==============================================================================
|
|
15
|
+
"""Flower command line interface `config list` command."""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
import io
|
|
19
|
+
import json
|
|
20
|
+
from typing import Annotated
|
|
21
|
+
|
|
22
|
+
import typer
|
|
23
|
+
from rich.console import Console
|
|
24
|
+
|
|
25
|
+
from flwr.common.constant import CliOutputFormat
|
|
26
|
+
from flwr.common.logger import print_json_error, redirect_output, restore_output
|
|
27
|
+
|
|
28
|
+
from ..constant import SuperLinkConnectionTomlKey
|
|
29
|
+
from ..flower_config import read_flower_config
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def ls(
|
|
33
|
+
output_format: Annotated[
|
|
34
|
+
str,
|
|
35
|
+
typer.Option(
|
|
36
|
+
"--format",
|
|
37
|
+
case_sensitive=False,
|
|
38
|
+
help="Format output using 'default' view or 'json'",
|
|
39
|
+
),
|
|
40
|
+
] = CliOutputFormat.DEFAULT,
|
|
41
|
+
) -> None:
|
|
42
|
+
"""List all SuperLink connections."""
|
|
43
|
+
suppress_output = output_format == CliOutputFormat.JSON
|
|
44
|
+
captured_output = io.StringIO()
|
|
45
|
+
config_path = None
|
|
46
|
+
|
|
47
|
+
if suppress_output:
|
|
48
|
+
redirect_output(captured_output)
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
# Load Flower Config
|
|
52
|
+
config, config_path = read_flower_config()
|
|
53
|
+
|
|
54
|
+
# Get `superlink` tables
|
|
55
|
+
superlink_connections = config.get(SuperLinkConnectionTomlKey.SUPERLINK, {})
|
|
56
|
+
|
|
57
|
+
# Get default, then pop from dict
|
|
58
|
+
default = superlink_connections.pop(SuperLinkConnectionTomlKey.DEFAULT, None)
|
|
59
|
+
|
|
60
|
+
connection_names = list(superlink_connections.keys())
|
|
61
|
+
restore_output()
|
|
62
|
+
if output_format == CliOutputFormat.JSON:
|
|
63
|
+
conn = {
|
|
64
|
+
SuperLinkConnectionTomlKey.SUPERLINK: connection_names,
|
|
65
|
+
SuperLinkConnectionTomlKey.DEFAULT: default,
|
|
66
|
+
}
|
|
67
|
+
Console().print_json(json.dumps(conn))
|
|
68
|
+
else:
|
|
69
|
+
typer.secho("SuperLink connections:", fg=typer.colors.BLUE)
|
|
70
|
+
# List SuperLink connections and highlight default
|
|
71
|
+
for k in connection_names:
|
|
72
|
+
typer.secho(f" {k}", fg=typer.colors.GREEN, nl=False)
|
|
73
|
+
if k == default:
|
|
74
|
+
typer.secho(
|
|
75
|
+
f" ({SuperLinkConnectionTomlKey.DEFAULT})",
|
|
76
|
+
fg=typer.colors.WHITE,
|
|
77
|
+
nl=False,
|
|
78
|
+
)
|
|
79
|
+
typer.echo()
|
|
80
|
+
except typer.Exit as err:
|
|
81
|
+
# log the error if json format requested
|
|
82
|
+
# else do nothing since it will be logged by typer
|
|
83
|
+
if suppress_output:
|
|
84
|
+
restore_output()
|
|
85
|
+
e_message = captured_output.getvalue()
|
|
86
|
+
print_json_error(e_message, err)
|
|
87
|
+
|
|
88
|
+
except Exception as err: # pylint: disable=broad-except
|
|
89
|
+
if suppress_output:
|
|
90
|
+
restore_output()
|
|
91
|
+
e_message = captured_output.getvalue()
|
|
92
|
+
print_json_error(e_message, err)
|
|
93
|
+
else:
|
|
94
|
+
typer.secho(
|
|
95
|
+
f"❌ An unexpected error occurred while listing the SuperLink "
|
|
96
|
+
f"connections in the Flower configuration file ({config_path}): {err}",
|
|
97
|
+
fg=typer.colors.RED,
|
|
98
|
+
err=True,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
finally:
|
|
102
|
+
if suppress_output:
|
|
103
|
+
restore_output()
|
|
104
|
+
captured_output.close()
|
|
@@ -42,3 +42,70 @@ FEDERATION_CONFIG_HELP_MESSAGE = CONFIG_HELP_MESSAGE.format(
|
|
|
42
42
|
"[tool.flwr.federations.<YOUR-FEDERATION>]",
|
|
43
43
|
"",
|
|
44
44
|
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# Default simulation backend name
|
|
48
|
+
DEFAULT_SIMULATION_BACKEND_NAME = "ray"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class SuperLinkConnectionTomlKey:
|
|
52
|
+
"""TOML keys for SuperLink connection configuration."""
|
|
53
|
+
|
|
54
|
+
SUPERLINK = "superlink"
|
|
55
|
+
DEFAULT = "default"
|
|
56
|
+
ADDRESS = "address"
|
|
57
|
+
ROOT_CERTIFICATES = "root-certificates"
|
|
58
|
+
INSECURE = "insecure"
|
|
59
|
+
ENABLE_ACCOUNT_AUTH = "enable-account-auth"
|
|
60
|
+
FEDERATION = "federation"
|
|
61
|
+
OPTIONS = "options"
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class SuperLinkSimulationOptionsTomlKey:
|
|
65
|
+
"""TOML keys for SuperLinkSimulationOptions."""
|
|
66
|
+
|
|
67
|
+
NUM_SUPERNODES = "num-supernodes"
|
|
68
|
+
BACKEND = "backend"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class SimulationClientResourcesTomlKey:
|
|
72
|
+
"""TOML keys for SimulationClientResources."""
|
|
73
|
+
|
|
74
|
+
NUM_CPUS = "num-cpus"
|
|
75
|
+
NUM_GPUS = "num-gpus"
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class SimulationInitArgsTomlKey:
|
|
79
|
+
"""TOML keys for SimulationInitArgs."""
|
|
80
|
+
|
|
81
|
+
NUM_CPUS = "num-cpus"
|
|
82
|
+
NUM_GPUS = "num-gpus"
|
|
83
|
+
LOGGING_LEVEL = "logging-level"
|
|
84
|
+
LOG_TO_DRIVE = "log-to-drive"
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class SimulationBackendConfigTomlKey:
|
|
88
|
+
"""TOML keys for SimulationBackendConfig."""
|
|
89
|
+
|
|
90
|
+
CLIENT_RESOURCES = "client-resources"
|
|
91
|
+
INIT_ARGS = "init-args"
|
|
92
|
+
NAME = "name"
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# CLI connection configuration file name
|
|
96
|
+
FLOWER_CONFIG_FILE = "config.toml"
|
|
97
|
+
|
|
98
|
+
# The default configuration for the Flower config file
|
|
99
|
+
DEFAULT_FLOWER_CONFIG_TOML = """[superlink]
|
|
100
|
+
default = "local"
|
|
101
|
+
|
|
102
|
+
[superlink.supergrid]
|
|
103
|
+
address = "supergrid.flower.ai"
|
|
104
|
+
enable-account-auth = true
|
|
105
|
+
federation = "YOUR-FEDERATION-HERE"
|
|
106
|
+
|
|
107
|
+
[superlink.local]
|
|
108
|
+
options.num-supernodes = 10
|
|
109
|
+
options.backend.client-resources.num-cpus = 1
|
|
110
|
+
options.backend.client-resources.num-gpus = 0
|
|
111
|
+
"""
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
# Copyright 2026 Flower Labs GmbH. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
# ==============================================================================
|
|
15
|
+
"""Flower command line interface configuration utils."""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
import re
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import Any, cast
|
|
21
|
+
|
|
22
|
+
import tomli
|
|
23
|
+
import tomli_w
|
|
24
|
+
import typer
|
|
25
|
+
|
|
26
|
+
from flwr.cli.constant import (
|
|
27
|
+
DEFAULT_FLOWER_CONFIG_TOML,
|
|
28
|
+
DEFAULT_SIMULATION_BACKEND_NAME,
|
|
29
|
+
FLOWER_CONFIG_FILE,
|
|
30
|
+
SimulationBackendConfigTomlKey,
|
|
31
|
+
SimulationClientResourcesTomlKey,
|
|
32
|
+
SimulationInitArgsTomlKey,
|
|
33
|
+
SuperLinkConnectionTomlKey,
|
|
34
|
+
SuperLinkSimulationOptionsTomlKey,
|
|
35
|
+
)
|
|
36
|
+
from flwr.cli.typing import (
|
|
37
|
+
SimulationBackendConfig,
|
|
38
|
+
SimulationClientResources,
|
|
39
|
+
SimulationInitArgs,
|
|
40
|
+
SuperLinkConnection,
|
|
41
|
+
SuperLinkSimulationOptions,
|
|
42
|
+
)
|
|
43
|
+
from flwr.common.config import flatten_dict
|
|
44
|
+
from flwr.supercore.utils import get_flwr_home
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _parse_simulation_options(options: dict[str, Any]) -> SuperLinkSimulationOptions:
|
|
48
|
+
"""Parse simulation options from a dictionary in a SuperLink connection."""
|
|
49
|
+
num_supernodes = options.get(SuperLinkSimulationOptionsTomlKey.NUM_SUPERNODES)
|
|
50
|
+
# Validation handled in SuperLinkSimulationOptions.__post_init__
|
|
51
|
+
|
|
52
|
+
backend_dict = options.get(SuperLinkSimulationOptionsTomlKey.BACKEND)
|
|
53
|
+
simulation_backend: SimulationBackendConfig | None = None
|
|
54
|
+
|
|
55
|
+
if isinstance(backend_dict, dict):
|
|
56
|
+
# Parse client resources
|
|
57
|
+
client_resources_dict = backend_dict.get(
|
|
58
|
+
SimulationBackendConfigTomlKey.CLIENT_RESOURCES
|
|
59
|
+
)
|
|
60
|
+
client_resources: SimulationClientResources | None = None
|
|
61
|
+
if isinstance(client_resources_dict, dict):
|
|
62
|
+
client_resources = SimulationClientResources(
|
|
63
|
+
num_cpus=client_resources_dict.get(
|
|
64
|
+
SimulationClientResourcesTomlKey.NUM_CPUS
|
|
65
|
+
),
|
|
66
|
+
num_gpus=client_resources_dict.get(
|
|
67
|
+
SimulationClientResourcesTomlKey.NUM_GPUS
|
|
68
|
+
),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# Parse init args
|
|
72
|
+
init_args_dict = backend_dict.get(SimulationBackendConfigTomlKey.INIT_ARGS)
|
|
73
|
+
init_args: SimulationInitArgs | None = None
|
|
74
|
+
if isinstance(init_args_dict, dict):
|
|
75
|
+
init_args = SimulationInitArgs(
|
|
76
|
+
num_cpus=init_args_dict.get(SimulationInitArgsTomlKey.NUM_CPUS),
|
|
77
|
+
num_gpus=init_args_dict.get(SimulationInitArgsTomlKey.NUM_GPUS),
|
|
78
|
+
logging_level=init_args_dict.get(
|
|
79
|
+
SimulationInitArgsTomlKey.LOGGING_LEVEL
|
|
80
|
+
),
|
|
81
|
+
log_to_drive=init_args_dict.get(SimulationInitArgsTomlKey.LOG_TO_DRIVE),
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
simulation_backend = SimulationBackendConfig(
|
|
85
|
+
name=backend_dict.get(
|
|
86
|
+
SimulationBackendConfigTomlKey.NAME, DEFAULT_SIMULATION_BACKEND_NAME
|
|
87
|
+
),
|
|
88
|
+
client_resources=client_resources,
|
|
89
|
+
init_args=init_args,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# Note: validation happens in SuperLinkSimulationOptions.__post_init__
|
|
93
|
+
return SuperLinkSimulationOptions(
|
|
94
|
+
num_supernodes=cast(int, num_supernodes),
|
|
95
|
+
backend=simulation_backend,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _serialize_simulation_options(
|
|
100
|
+
options: SuperLinkSimulationOptions,
|
|
101
|
+
) -> dict[str, Any]:
|
|
102
|
+
"""Convert SuperLinkSimulationOptions to a dictionary for TOML serialization."""
|
|
103
|
+
options_dict: dict[str, Any] = {
|
|
104
|
+
SuperLinkSimulationOptionsTomlKey.NUM_SUPERNODES: options.num_supernodes
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if options.backend is not None:
|
|
108
|
+
backend = options.backend
|
|
109
|
+
|
|
110
|
+
# Serialize client resources
|
|
111
|
+
c_res_dict: dict[str, Any] = {}
|
|
112
|
+
if backend.client_resources is not None:
|
|
113
|
+
client_res = backend.client_resources
|
|
114
|
+
c_res_dict = {
|
|
115
|
+
SimulationClientResourcesTomlKey.NUM_CPUS: client_res.num_cpus,
|
|
116
|
+
SimulationClientResourcesTomlKey.NUM_GPUS: client_res.num_gpus,
|
|
117
|
+
}
|
|
118
|
+
# Remove None values
|
|
119
|
+
c_res_dict = {k: v for k, v in c_res_dict.items() if v is not None}
|
|
120
|
+
|
|
121
|
+
# Serialize init args
|
|
122
|
+
init_args_dict: dict[str, Any] = {}
|
|
123
|
+
if backend.init_args is not None:
|
|
124
|
+
init_args = backend.init_args
|
|
125
|
+
init_args_dict = {
|
|
126
|
+
SimulationInitArgsTomlKey.NUM_CPUS: init_args.num_cpus,
|
|
127
|
+
SimulationInitArgsTomlKey.NUM_GPUS: init_args.num_gpus,
|
|
128
|
+
SimulationInitArgsTomlKey.LOGGING_LEVEL: init_args.logging_level,
|
|
129
|
+
SimulationInitArgsTomlKey.LOG_TO_DRIVE: init_args.log_to_drive,
|
|
130
|
+
}
|
|
131
|
+
# Remove None values
|
|
132
|
+
init_args_dict = {k: v for k, v in init_args_dict.items() if v is not None}
|
|
133
|
+
|
|
134
|
+
backend_dict = {
|
|
135
|
+
SimulationBackendConfigTomlKey.NAME: backend.name,
|
|
136
|
+
SimulationBackendConfigTomlKey.CLIENT_RESOURCES: c_res_dict,
|
|
137
|
+
SimulationBackendConfigTomlKey.INIT_ARGS: init_args_dict,
|
|
138
|
+
}
|
|
139
|
+
# Remove empty dicts
|
|
140
|
+
backend_dict = {k: v for k, v in backend_dict.items() if v}
|
|
141
|
+
|
|
142
|
+
options_dict[SuperLinkSimulationOptionsTomlKey.BACKEND] = backend_dict
|
|
143
|
+
|
|
144
|
+
return options_dict
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def init_flwr_config() -> None:
|
|
148
|
+
"""Initialize the Flower configuration file."""
|
|
149
|
+
config_path = get_flwr_home() / FLOWER_CONFIG_FILE
|
|
150
|
+
|
|
151
|
+
if not config_path.exists():
|
|
152
|
+
# Create parent directory if it doesn't exist
|
|
153
|
+
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
154
|
+
# Write Flower config file
|
|
155
|
+
config_path.write_text(DEFAULT_FLOWER_CONFIG_TOML, encoding="utf-8")
|
|
156
|
+
|
|
157
|
+
typer.secho(
|
|
158
|
+
f"\nFlower configuration not found. Created default configuration"
|
|
159
|
+
f" at {config_path}\n",
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def parse_superlink_connection(
|
|
164
|
+
conn_dict: dict[str, Any], name: str
|
|
165
|
+
) -> SuperLinkConnection:
|
|
166
|
+
"""Parse SuperLink connection configuration from a TOML dictionary.
|
|
167
|
+
|
|
168
|
+
Parameters
|
|
169
|
+
----------
|
|
170
|
+
conn_dict : dict[str, Any]
|
|
171
|
+
The TOML configuration dictionary for the connection.
|
|
172
|
+
name : str
|
|
173
|
+
The name of the connection.
|
|
174
|
+
|
|
175
|
+
Returns
|
|
176
|
+
-------
|
|
177
|
+
SuperLinkConnection
|
|
178
|
+
The parsed SuperLink connection configuration.
|
|
179
|
+
"""
|
|
180
|
+
simulation_options: SuperLinkSimulationOptions | None = None
|
|
181
|
+
if SuperLinkConnectionTomlKey.OPTIONS in conn_dict:
|
|
182
|
+
options = conn_dict[SuperLinkConnectionTomlKey.OPTIONS]
|
|
183
|
+
if isinstance(options, dict):
|
|
184
|
+
simulation_options = _parse_simulation_options(options)
|
|
185
|
+
else:
|
|
186
|
+
raise ValueError(
|
|
187
|
+
f"Invalid value for key '{SuperLinkConnectionTomlKey.OPTIONS}': "
|
|
188
|
+
f"expected dict, but got {type(options).__name__}."
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
# Build and return SuperLinkConnection
|
|
192
|
+
return SuperLinkConnection(
|
|
193
|
+
name=name,
|
|
194
|
+
address=conn_dict.get(SuperLinkConnectionTomlKey.ADDRESS),
|
|
195
|
+
root_certificates=conn_dict.get(SuperLinkConnectionTomlKey.ROOT_CERTIFICATES),
|
|
196
|
+
insecure=conn_dict.get(SuperLinkConnectionTomlKey.INSECURE),
|
|
197
|
+
enable_account_auth=conn_dict.get(
|
|
198
|
+
SuperLinkConnectionTomlKey.ENABLE_ACCOUNT_AUTH
|
|
199
|
+
),
|
|
200
|
+
federation=conn_dict.get(SuperLinkConnectionTomlKey.FEDERATION),
|
|
201
|
+
options=simulation_options,
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def serialize_superlink_connection(connection: SuperLinkConnection) -> dict[str, Any]:
|
|
206
|
+
"""Convert SuperLinkConnection to a dictionary for TOML serialization.
|
|
207
|
+
|
|
208
|
+
Parameters
|
|
209
|
+
----------
|
|
210
|
+
connection : SuperLinkConnection
|
|
211
|
+
The SuperLink connection to serialize.
|
|
212
|
+
|
|
213
|
+
Returns
|
|
214
|
+
-------
|
|
215
|
+
dict[str, Any]
|
|
216
|
+
Dictionary representation suitable for TOML serialization.
|
|
217
|
+
"""
|
|
218
|
+
conn_dict: dict[str, Any] = {
|
|
219
|
+
SuperLinkConnectionTomlKey.ADDRESS: connection.address,
|
|
220
|
+
SuperLinkConnectionTomlKey.ROOT_CERTIFICATES: connection.root_certificates,
|
|
221
|
+
SuperLinkConnectionTomlKey.INSECURE: connection.insecure,
|
|
222
|
+
SuperLinkConnectionTomlKey.ENABLE_ACCOUNT_AUTH: connection.enable_account_auth,
|
|
223
|
+
SuperLinkConnectionTomlKey.FEDERATION: connection.federation,
|
|
224
|
+
}
|
|
225
|
+
# Remove None values
|
|
226
|
+
conn_dict = {k: v for k, v in conn_dict.items() if v is not None}
|
|
227
|
+
|
|
228
|
+
if connection.options is not None:
|
|
229
|
+
options_dict = _serialize_simulation_options(connection.options)
|
|
230
|
+
conn_dict[SuperLinkConnectionTomlKey.OPTIONS] = options_dict
|
|
231
|
+
|
|
232
|
+
return conn_dict
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def read_superlink_connection(
|
|
236
|
+
connection_name: str | None = None,
|
|
237
|
+
) -> SuperLinkConnection | None:
|
|
238
|
+
"""Read a SuperLink connection from the Flower configuration file.
|
|
239
|
+
|
|
240
|
+
Parameters
|
|
241
|
+
----------
|
|
242
|
+
connection_name : str | None
|
|
243
|
+
The name of the SuperLink connection to load. If None, the default connection
|
|
244
|
+
will be loaded.
|
|
245
|
+
|
|
246
|
+
Returns
|
|
247
|
+
-------
|
|
248
|
+
SuperLinkConnection | None
|
|
249
|
+
The SuperLink connection, or None if the config file is missing or the
|
|
250
|
+
requested connection (or default) cannot be found.
|
|
251
|
+
|
|
252
|
+
Raises
|
|
253
|
+
------
|
|
254
|
+
typer.Exit
|
|
255
|
+
Raised if the configuration file is corrupted, or if the requested
|
|
256
|
+
connection (or default) cannot be found.
|
|
257
|
+
"""
|
|
258
|
+
toml_dict, config_path = read_flower_config()
|
|
259
|
+
|
|
260
|
+
try:
|
|
261
|
+
superlink_config = toml_dict.get(SuperLinkConnectionTomlKey.SUPERLINK, {})
|
|
262
|
+
|
|
263
|
+
# Load the default SuperLink connection when not provided
|
|
264
|
+
if connection_name is None:
|
|
265
|
+
connection_name = superlink_config.get(SuperLinkConnectionTomlKey.DEFAULT)
|
|
266
|
+
|
|
267
|
+
# Exit when no connection name is available
|
|
268
|
+
if connection_name is None:
|
|
269
|
+
typer.secho(
|
|
270
|
+
"❌ No SuperLink connection set. A SuperLink connection needs to be "
|
|
271
|
+
"provided or one must be set as default in the Flower "
|
|
272
|
+
f"configuration file ({config_path}). Specify a default SuperLink "
|
|
273
|
+
"connection by adding: \n\n[superlink]\ndefault = 'connection_name'\n\n"
|
|
274
|
+
f"to the Flower configuration file ({config_path}).",
|
|
275
|
+
fg=typer.colors.RED,
|
|
276
|
+
err=True,
|
|
277
|
+
)
|
|
278
|
+
raise typer.Exit(code=1)
|
|
279
|
+
|
|
280
|
+
# Try to find the connection with the given name
|
|
281
|
+
if connection_name not in superlink_config:
|
|
282
|
+
typer.secho(
|
|
283
|
+
f"❌ SuperLink connection '{connection_name}' not found in the "
|
|
284
|
+
f"Flower configuration file ({config_path}).",
|
|
285
|
+
fg=typer.colors.RED,
|
|
286
|
+
err=True,
|
|
287
|
+
)
|
|
288
|
+
# If default was used, show a specific error message
|
|
289
|
+
if connection_name == superlink_config.get(
|
|
290
|
+
SuperLinkConnectionTomlKey.DEFAULT
|
|
291
|
+
):
|
|
292
|
+
typer.secho(
|
|
293
|
+
f"Please check that the default connection '{connection_name}' "
|
|
294
|
+
"is defined in the [superlink] section.",
|
|
295
|
+
fg=typer.colors.RED,
|
|
296
|
+
err=True,
|
|
297
|
+
)
|
|
298
|
+
raise typer.Exit(code=1)
|
|
299
|
+
|
|
300
|
+
conn_dict = superlink_config[connection_name]
|
|
301
|
+
return parse_superlink_connection(conn_dict, connection_name)
|
|
302
|
+
|
|
303
|
+
except ValueError as err:
|
|
304
|
+
typer.secho(
|
|
305
|
+
f"❌ Failed to parse the Flower configuration file ({config_path}). "
|
|
306
|
+
f"{err}",
|
|
307
|
+
fg=typer.colors.RED,
|
|
308
|
+
err=True,
|
|
309
|
+
)
|
|
310
|
+
raise typer.Exit(code=1) from err
|
|
311
|
+
except Exception as err:
|
|
312
|
+
typer.secho(
|
|
313
|
+
f"❌ An unexpected error occurred while reading the Flower configuration "
|
|
314
|
+
f"file ({config_path}). {err}",
|
|
315
|
+
fg=typer.colors.RED,
|
|
316
|
+
err=True,
|
|
317
|
+
)
|
|
318
|
+
raise typer.Exit(code=1) from err
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def write_superlink_connection(connection: SuperLinkConnection) -> None:
|
|
322
|
+
"""Write a SuperLink connection to the Flower configuration file.
|
|
323
|
+
|
|
324
|
+
Parameters
|
|
325
|
+
----------
|
|
326
|
+
connection : SuperLinkConnection
|
|
327
|
+
The SuperLink connection to write to the configuration file.
|
|
328
|
+
|
|
329
|
+
Raises
|
|
330
|
+
------
|
|
331
|
+
typer.Exit
|
|
332
|
+
Raised if the configuration file cannot be read or written.
|
|
333
|
+
"""
|
|
334
|
+
toml_dict, _ = read_flower_config()
|
|
335
|
+
|
|
336
|
+
# Ensure superlink section exists
|
|
337
|
+
if SuperLinkConnectionTomlKey.SUPERLINK not in toml_dict:
|
|
338
|
+
toml_dict[SuperLinkConnectionTomlKey.SUPERLINK] = {}
|
|
339
|
+
|
|
340
|
+
superlink_config = toml_dict[SuperLinkConnectionTomlKey.SUPERLINK]
|
|
341
|
+
|
|
342
|
+
# Serialize connection and flatten nested dicts using dotted keys
|
|
343
|
+
conn_dict = serialize_superlink_connection(connection)
|
|
344
|
+
|
|
345
|
+
# Add/update the connection
|
|
346
|
+
superlink_config[connection.name] = conn_dict
|
|
347
|
+
|
|
348
|
+
# Flatten SuperLink connections
|
|
349
|
+
for name in list(superlink_config.keys()):
|
|
350
|
+
if isinstance(superlink_config[name], dict):
|
|
351
|
+
superlink_config[name] = flatten_dict(superlink_config[name])
|
|
352
|
+
|
|
353
|
+
# Write back to file
|
|
354
|
+
write_flower_config(toml_dict)
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
def read_flower_config() -> tuple[dict[str, Any], Path]:
|
|
358
|
+
"""Read the Flower configuration file.
|
|
359
|
+
|
|
360
|
+
Returns
|
|
361
|
+
-------
|
|
362
|
+
tuple[dict[str, Any], Path]
|
|
363
|
+
A tuple containing the TOML configuration dictionary and the path to the
|
|
364
|
+
configuration file.
|
|
365
|
+
|
|
366
|
+
Raises
|
|
367
|
+
------
|
|
368
|
+
typer.Exit
|
|
369
|
+
Raised if the configuration file is corrupted.
|
|
370
|
+
"""
|
|
371
|
+
init_flwr_config()
|
|
372
|
+
|
|
373
|
+
config_path = get_flwr_home() / FLOWER_CONFIG_FILE
|
|
374
|
+
|
|
375
|
+
try:
|
|
376
|
+
with config_path.open("rb") as file:
|
|
377
|
+
return tomli.load(file), config_path
|
|
378
|
+
|
|
379
|
+
except tomli.TOMLDecodeError as err:
|
|
380
|
+
typer.secho(
|
|
381
|
+
f"❌ Failed to read the Flower configuration file ({config_path}). "
|
|
382
|
+
"Please ensure it is valid TOML.",
|
|
383
|
+
fg=typer.colors.RED,
|
|
384
|
+
err=True,
|
|
385
|
+
)
|
|
386
|
+
raise typer.Exit(code=1) from err
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
# This function may be subject to change once we introduce more configuration
|
|
390
|
+
def write_flower_config(toml_dict: dict[str, Any]) -> Path:
|
|
391
|
+
"""Write the Flower configuration file.
|
|
392
|
+
|
|
393
|
+
Parameters
|
|
394
|
+
----------
|
|
395
|
+
toml_dict : dict[str, Any]
|
|
396
|
+
The TOML configuration dictionary to write to the file.
|
|
397
|
+
|
|
398
|
+
Returns
|
|
399
|
+
-------
|
|
400
|
+
Path
|
|
401
|
+
The path to the configuration file.
|
|
402
|
+
"""
|
|
403
|
+
config_path = get_flwr_home() / FLOWER_CONFIG_FILE
|
|
404
|
+
|
|
405
|
+
# Get the standard TOML text
|
|
406
|
+
toml_content = tomli_w.dumps(toml_dict)
|
|
407
|
+
|
|
408
|
+
# Remove double quotes around multi-dot keys
|
|
409
|
+
# All keys must be [A-Za-z0-9_-]+ except dots
|
|
410
|
+
lines = toml_content.splitlines(keepends=True)
|
|
411
|
+
pattern = re.compile(r'^"([^"]+\.[^"]+)"\s*=')
|
|
412
|
+
for i, line in enumerate(lines):
|
|
413
|
+
if match := pattern.match(line):
|
|
414
|
+
key = match.group(1)
|
|
415
|
+
lines[i] = line.replace(f'"{key}"', key)
|
|
416
|
+
|
|
417
|
+
toml_content = "".join(lines)
|
|
418
|
+
|
|
419
|
+
with config_path.open("w") as file:
|
|
420
|
+
file.write(toml_content)
|
|
421
|
+
|
|
422
|
+
return config_path
|