flwr-nightly 1.19.0.dev20250510__tar.gz → 1.19.0.dev20250512__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.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/PKG-INFO +2 -1
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/build.py +82 -57
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/model.baseline.py.tpl +1 -1
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.baseline.py.tpl +2 -3
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +13 -16
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/run/run.py +8 -12
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/constant.py +1 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/linkstate/in_memory_linkstate.py +84 -4
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/linkstate/linkstate.py +23 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/linkstate/sqlite_linkstate.py +98 -8
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/pyproject.toml +2 -1
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/README.md +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/auth_plugin/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/auth_plugin/oidc_cli_plugin.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/cli_user_auth_interceptor.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/config_utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/constant.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/example.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/install.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/log.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/login/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/login/login.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/ls.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/new.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/.gitignore.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/LICENSE.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/README.baseline.md.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/README.flowertune.md.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/README.md.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/__init__.baseline.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.baseline.py.tpl +1 -1
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.huggingface.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.jax.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.mlx.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.sklearn.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/dataset.baseline.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.huggingface.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.jax.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.mlx.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.sklearn.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/strategy.baseline.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/task.huggingface.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/task.jax.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/task.mlx.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/task.numpy.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/task.sklearn.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/utils.baseline.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/run/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/stop.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/client.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/client_app.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/clientapp/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/clientapp/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/clientapp/clientappio_servicer.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/clientapp/utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/dpfedavg_numpy_client.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_adapter_client/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_adapter_client/connection.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_client/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_client/connection.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_rere_client/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_rere_client/client_interceptor.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_rere_client/connection.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_rere_client/grpc_adapter.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/message_handler/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/message_handler/message_handler.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/centraldp_mods.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/comms_mods.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/localdp_mod.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/nodestate/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/nodestate/in_memory_nodestate.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/nodestate/nodestate.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/nodestate/nodestate_factory.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/numpy_client.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/rest_client/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/rest_client/connection.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/run_info_store.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/supernode/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/supernode/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/typing.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/address.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/args.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/auth_plugin/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/auth_plugin/auth_plugin.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/config.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/context.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/date.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/differential_privacy.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/differential_privacy_constants.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/dp.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/event_log_plugin/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/event_log_plugin/event_log_plugin.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/exit/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/exit/exit.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/exit/exit_code.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/exit_handlers.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/heartbeat.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/inflatable.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/logger.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/message.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/object_ref.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/parameter.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/pyproject.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/array.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/arrayrecord.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/configrecord.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/conversion_utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/metricrecord.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/recorddict.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/typeddict.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/recorddict_compat.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/retry_invoker.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/quantization.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/serde.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/serde_utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/telemetry.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/typing.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/version.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/clientappio_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/clientappio_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/clientappio_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/clientappio_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/error_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/error_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/error_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/error_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/exec_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/exec_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/exec_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/exec_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fab_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fab_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fab_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fab_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fleet_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fleet_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fleet_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/grpcadapter_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/grpcadapter_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/grpcadapter_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/grpcadapter_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/heartbeat_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/heartbeat_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/heartbeat_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/heartbeat_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/log_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/log_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/log_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/log_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/message_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/message_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/message_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/message_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/node_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/node_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/node_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/node_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/recorddict_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/recorddict_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/recorddict_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/recorddict_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/run_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/run_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/run_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/run_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/serverappio_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/serverappio_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/serverappio_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/serverappio_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/simulationio_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/simulationio_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/simulationio_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/simulationio_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/transport_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/transport_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/transport_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/py.typed +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/client_manager.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/client_proxy.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/compat/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/compat/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/compat/app_utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/compat/grid_client_proxy.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/compat/legacy_context.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/criterion.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/fleet_event_log_interceptor.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/grid/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/grid/grid.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/grid/grpc_grid.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/grid/inmemory_grid.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/history.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/run_serverapp.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/server.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/server_app.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/server_config.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/serverapp/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/serverapp/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/serverapp_components.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/aggregate.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/bulyan.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedadagrad.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedadam.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedavg.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedavg_android.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedavgm.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedmedian.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedopt.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedprox.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedyogi.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/krum.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/qfedavg.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/strategy.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/ffs/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/ffs/disk_ffs.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/ffs/ffs.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/ffs/ffs_factory.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/message_handler/message_handler.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/vce/vce_api.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/linkstate/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/linkstate/linkstate_factory.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/linkstate/utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/serverappio/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/serverappio/serverappio_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/serverappio/serverappio_servicer.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/simulation/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/simulation/simulationio_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/simulation/simulationio_servicer.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/typing.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/utils/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/utils/tensorboard.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/utils/validator.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/workflow/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/workflow/constant.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/workflow/default_workflows.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/legacy_app.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/ray_transport/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/ray_transport/utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/run_simulation.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/simulationio_connection.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/deployment.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/exec_event_log_interceptor.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/exec_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/exec_servicer.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/exec_user_auth_interceptor.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/executor.py +0 -0
- {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/simulation.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: flwr-nightly
|
3
|
-
Version: 1.19.0.
|
3
|
+
Version: 1.19.0.dev20250512
|
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
|
@@ -31,6 +31,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
31
31
|
Classifier: Typing :: Typed
|
32
32
|
Provides-Extra: rest
|
33
33
|
Provides-Extra: simulation
|
34
|
+
Requires-Dist: click (<8.2.0)
|
34
35
|
Requires-Dist: cryptography (>=44.0.1,<45.0.0)
|
35
36
|
Requires-Dist: grpcio (>=1.62.3,<2.0.0,!=1.65.0)
|
36
37
|
Requires-Dist: iterators (>=0.0.2,<0.0.3)
|
@@ -16,10 +16,8 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
import hashlib
|
19
|
-
import os
|
20
|
-
import shutil
|
21
|
-
import tempfile
|
22
19
|
import zipfile
|
20
|
+
from io import BytesIO
|
23
21
|
from pathlib import Path
|
24
22
|
from typing import Annotated, Any, Optional, Union
|
25
23
|
|
@@ -29,6 +27,7 @@ import typer
|
|
29
27
|
|
30
28
|
from flwr.common.constant import FAB_ALLOWED_EXTENSIONS, FAB_DATE, FAB_HASH_TRUNCATION
|
31
29
|
|
30
|
+
from .config_utils import load as load_toml
|
32
31
|
from .config_utils import load_and_validate
|
33
32
|
from .utils import is_valid_project_name
|
34
33
|
|
@@ -43,11 +42,11 @@ def write_to_zip(
|
|
43
42
|
return zipfile_obj
|
44
43
|
|
45
44
|
|
46
|
-
def get_fab_filename(
|
45
|
+
def get_fab_filename(config: dict[str, Any], fab_hash: str) -> str:
|
47
46
|
"""Get the FAB filename based on the given config and FAB hash."""
|
48
|
-
publisher =
|
49
|
-
name =
|
50
|
-
version =
|
47
|
+
publisher = config["tool"]["flwr"]["app"]["publisher"]
|
48
|
+
name = config["project"]["name"]
|
49
|
+
version = config["project"]["version"].replace(".", "-")
|
51
50
|
fab_hash_truncated = fab_hash[:FAB_HASH_TRUNCATION]
|
52
51
|
return f"{publisher}.{name}.{version}.{fab_hash_truncated}.fab"
|
53
52
|
|
@@ -89,8 +88,8 @@ def build(
|
|
89
88
|
)
|
90
89
|
raise typer.Exit(code=1)
|
91
90
|
|
92
|
-
|
93
|
-
if
|
91
|
+
config, errors, warnings = load_and_validate(app / "pyproject.toml")
|
92
|
+
if config is None:
|
94
93
|
typer.secho(
|
95
94
|
"Project configuration could not be loaded.\npyproject.toml is invalid:\n"
|
96
95
|
+ "\n".join([f"- {line}" for line in errors]),
|
@@ -107,70 +106,96 @@ def build(
|
|
107
106
|
bold=True,
|
108
107
|
)
|
109
108
|
|
110
|
-
#
|
111
|
-
|
109
|
+
# Build FAB
|
110
|
+
fab_bytes, fab_hash, _ = build_fab(app)
|
112
111
|
|
113
|
-
|
112
|
+
# Get the name of the zip file
|
113
|
+
fab_filename = get_fab_filename(config, fab_hash)
|
114
|
+
|
115
|
+
# Write the FAB
|
116
|
+
Path(fab_filename).write_bytes(fab_bytes)
|
117
|
+
|
118
|
+
typer.secho(
|
119
|
+
f"🎊 Successfully built {fab_filename}", fg=typer.colors.GREEN, bold=True
|
120
|
+
)
|
121
|
+
|
122
|
+
return fab_filename, fab_hash
|
114
123
|
|
115
|
-
# Remove the 'federations' field from 'tool.flwr' if it exists
|
116
|
-
if (
|
117
|
-
"tool" in conf
|
118
|
-
and "flwr" in conf["tool"]
|
119
|
-
and "federations" in conf["tool"]["flwr"]
|
120
|
-
):
|
121
|
-
del conf["tool"]["flwr"]["federations"]
|
122
124
|
|
123
|
-
|
125
|
+
def build_fab(app: Path) -> tuple[bytes, str, dict[str, Any]]:
|
126
|
+
"""Build a FAB in memory and return the bytes, hash, and config.
|
124
127
|
|
125
|
-
|
126
|
-
|
128
|
+
This function assumes that the provided path points to a valid Flower app and
|
129
|
+
bundles it into a FAB without performing additional validation.
|
127
130
|
|
128
|
-
|
129
|
-
|
131
|
+
Parameters
|
132
|
+
----------
|
133
|
+
app : Path
|
134
|
+
Path to the Flower app to bundle into a FAB.
|
130
135
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
136
|
+
Returns
|
137
|
+
-------
|
138
|
+
tuple[bytes, str, dict[str, Any]]
|
139
|
+
A tuple containing:
|
140
|
+
- the FAB as bytes
|
141
|
+
- the SHA256 hash of the FAB
|
142
|
+
- the project configuration (with the 'federations' field removed)
|
143
|
+
"""
|
144
|
+
app = app.resolve()
|
145
|
+
|
146
|
+
# Load the pyproject.toml file
|
147
|
+
config = load_toml(app / "pyproject.toml")
|
148
|
+
if config is None:
|
149
|
+
raise ValueError("Project configuration could not be loaded.")
|
140
150
|
|
141
|
-
|
151
|
+
# Remove the 'federations' field if it exists
|
152
|
+
if (
|
153
|
+
"tool" in config
|
154
|
+
and "flwr" in config["tool"]
|
155
|
+
and "federations" in config["tool"]["flwr"]
|
156
|
+
):
|
157
|
+
del config["tool"]["flwr"]["federations"]
|
142
158
|
|
143
|
-
|
144
|
-
|
145
|
-
with open(file_path, "rb") as f:
|
146
|
-
file_contents = f.read()
|
159
|
+
# Load .gitignore rules if present
|
160
|
+
ignore_spec = _load_gitignore(app)
|
147
161
|
|
148
|
-
|
149
|
-
|
162
|
+
# Search for all files in the app directory
|
163
|
+
all_files = [
|
164
|
+
f
|
165
|
+
for f in app.rglob("*")
|
166
|
+
if not ignore_spec.match_file(f)
|
167
|
+
and f.suffix in FAB_ALLOWED_EXTENSIONS
|
168
|
+
and f.name != "pyproject.toml" # Exclude the original pyproject.toml
|
169
|
+
]
|
170
|
+
all_files.sort()
|
171
|
+
|
172
|
+
# Create a zip file in memory
|
173
|
+
list_file_content = ""
|
150
174
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
175
|
+
fab_buffer = BytesIO()
|
176
|
+
with zipfile.ZipFile(fab_buffer, "w", zipfile.ZIP_DEFLATED) as fab_file:
|
177
|
+
# Add pyproject.toml
|
178
|
+
write_to_zip(fab_file, "pyproject.toml", tomli_w.dumps(config))
|
155
179
|
|
156
|
-
|
157
|
-
|
180
|
+
for file_path in all_files:
|
181
|
+
# Read the file content manually
|
182
|
+
file_contents = file_path.read_bytes()
|
158
183
|
|
159
|
-
|
160
|
-
|
161
|
-
fab_hash = hashlib.sha256(content).hexdigest()
|
184
|
+
archive_path = str(file_path.relative_to(app))
|
185
|
+
write_to_zip(fab_file, archive_path, file_contents)
|
162
186
|
|
163
|
-
|
164
|
-
|
187
|
+
# Calculate file info
|
188
|
+
sha256_hash = hashlib.sha256(file_contents).hexdigest()
|
189
|
+
file_size_bits = len(file_contents) * 8 # size in bits
|
190
|
+
list_file_content += f"{archive_path},{sha256_hash},{file_size_bits}\n"
|
165
191
|
|
166
|
-
|
167
|
-
|
192
|
+
# Add CONTENT and CONTENT.jwt to the zip file
|
193
|
+
write_to_zip(fab_file, ".info/CONTENT", list_file_content)
|
168
194
|
|
169
|
-
|
170
|
-
|
171
|
-
)
|
195
|
+
fab_bytes = fab_buffer.getvalue()
|
196
|
+
fab_hash = hashlib.sha256(fab_bytes).hexdigest()
|
172
197
|
|
173
|
-
return
|
198
|
+
return fab_bytes, fab_hash, config
|
174
199
|
|
175
200
|
|
176
201
|
def _load_gitignore(app: Path) -> pathspec.PathSpec:
|
@@ -76,5 +76,5 @@ def get_weights(net):
|
|
76
76
|
def set_weights(net, parameters):
|
77
77
|
"""Apply parameters to an existing model."""
|
78
78
|
params_dict = zip(net.state_dict().keys(), parameters)
|
79
|
-
state_dict = OrderedDict({k: torch.
|
79
|
+
state_dict = OrderedDict({k: torch.from_numpy(v) for k, v in params_dict})
|
80
80
|
net.load_state_dict(state_dict, strict=True)
|
@@ -1,15 +1,14 @@
|
|
1
1
|
"""$project_name: A Flower Baseline."""
|
2
2
|
|
3
|
-
from typing import List, Tuple
|
4
|
-
|
5
3
|
from flwr.common import Context, Metrics, ndarrays_to_parameters
|
6
4
|
from flwr.server import ServerApp, ServerAppComponents, ServerConfig
|
7
5
|
from flwr.server.strategy import FedAvg
|
6
|
+
|
8
7
|
from $import_name.model import Net, get_weights
|
9
8
|
|
10
9
|
|
11
10
|
# Define metric aggregation function
|
12
|
-
def weighted_average(metrics:
|
11
|
+
def weighted_average(metrics: list[tuple[int, Metrics]]) -> Metrics:
|
13
12
|
"""Do weighted average of accuracy metric."""
|
14
13
|
# Multiply accuracy of each client by number of examples used
|
15
14
|
accuracies = [num_examples * float(m["accuracy"]) for num_examples, m in metrics]
|
@@ -10,8 +10,8 @@ license = "Apache-2.0"
|
|
10
10
|
dependencies = [
|
11
11
|
"flwr[simulation]>=1.19.0",
|
12
12
|
"flwr-datasets[vision]>=0.5.0",
|
13
|
-
"torch==2.
|
14
|
-
"torchvision==0.
|
13
|
+
"torch==2.6.0",
|
14
|
+
"torchvision==0.21.0",
|
15
15
|
]
|
16
16
|
|
17
17
|
[tool.hatch.metadata]
|
@@ -23,28 +23,23 @@ dev = [
|
|
23
23
|
"black==24.2.0",
|
24
24
|
"docformatter==1.7.5",
|
25
25
|
"mypy==1.8.0",
|
26
|
-
"pylint==3.
|
27
|
-
"
|
28
|
-
"pytest==6.2.4",
|
26
|
+
"pylint==3.3.1",
|
27
|
+
"pytest==7.4.4",
|
29
28
|
"pytest-watch==4.2.0",
|
30
|
-
"ruff==0.
|
29
|
+
"ruff==0.4.5",
|
31
30
|
"types-requests==2.31.0.20240125",
|
32
31
|
]
|
33
32
|
|
34
33
|
[tool.isort]
|
35
34
|
profile = "black"
|
36
|
-
known_first_party = ["flwr"]
|
37
35
|
|
38
36
|
[tool.black]
|
39
37
|
line-length = 88
|
40
|
-
target-version = ["
|
38
|
+
target-version = ["py310", "py311", "py312"]
|
41
39
|
|
42
40
|
[tool.pytest.ini_options]
|
43
41
|
minversion = "6.2"
|
44
42
|
addopts = "-qq"
|
45
|
-
testpaths = [
|
46
|
-
"flwr_baselines",
|
47
|
-
]
|
48
43
|
|
49
44
|
[tool.mypy]
|
50
45
|
ignore_missing_imports = true
|
@@ -82,11 +77,8 @@ wrap-summaries = 88
|
|
82
77
|
wrap-descriptions = 88
|
83
78
|
|
84
79
|
[tool.ruff]
|
85
|
-
target-version = "
|
80
|
+
target-version = "py310"
|
86
81
|
line-length = 88
|
87
|
-
select = ["D", "E", "F", "W", "B", "ISC", "C4"]
|
88
|
-
fixable = ["D", "E", "F", "W", "B", "ISC", "C4"]
|
89
|
-
ignore = ["B024", "B027"]
|
90
82
|
exclude = [
|
91
83
|
".bzr",
|
92
84
|
".direnv",
|
@@ -111,7 +103,12 @@ exclude = [
|
|
111
103
|
"proto",
|
112
104
|
]
|
113
105
|
|
114
|
-
[tool.ruff.
|
106
|
+
[tool.ruff.lint]
|
107
|
+
select = ["D", "E", "F", "W", "B", "ISC", "C4", "UP"]
|
108
|
+
fixable = ["D", "E", "F", "W", "B", "ISC", "C4", "UP"]
|
109
|
+
ignore = ["B024", "B027", "D205", "D209"]
|
110
|
+
|
111
|
+
[tool.ruff.lint.pydocstyle]
|
115
112
|
convention = "numpy"
|
116
113
|
|
117
114
|
[tool.hatch.build.targets.wheel]
|
@@ -24,9 +24,8 @@ from typing import Annotated, Any, Optional
|
|
24
24
|
import typer
|
25
25
|
from rich.console import Console
|
26
26
|
|
27
|
-
from flwr.cli.build import
|
27
|
+
from flwr.cli.build import build_fab, get_fab_filename
|
28
28
|
from flwr.cli.config_utils import (
|
29
|
-
get_fab_metadata,
|
30
29
|
load_and_validate,
|
31
30
|
process_loaded_project_config,
|
32
31
|
validate_federation_in_project_config,
|
@@ -34,6 +33,7 @@ from flwr.cli.config_utils import (
|
|
34
33
|
from flwr.cli.constant import FEDERATION_CONFIG_HELP_MESSAGE
|
35
34
|
from flwr.common.config import (
|
36
35
|
flatten_dict,
|
36
|
+
get_metadata_from_config,
|
37
37
|
parse_config_args,
|
38
38
|
user_config_to_configrecord,
|
39
39
|
)
|
@@ -158,18 +158,14 @@ def _run_with_exec_api(
|
|
158
158
|
channel = init_channel(app, federation_config, auth_plugin)
|
159
159
|
stub = ExecStub(channel)
|
160
160
|
|
161
|
-
|
162
|
-
|
163
|
-
fab_id, fab_version = get_fab_metadata(Path(fab_path))
|
161
|
+
fab_bytes, fab_hash, config = build_fab(app)
|
162
|
+
fab_id, fab_version = get_metadata_from_config(config)
|
164
163
|
|
165
|
-
|
166
|
-
Path(fab_path).unlink()
|
167
|
-
|
168
|
-
fab = Fab(fab_hash, content)
|
164
|
+
fab = Fab(fab_hash, fab_bytes)
|
169
165
|
|
170
166
|
# Construct a `ConfigRecord` out of a flattened `UserConfig`
|
171
|
-
|
172
|
-
c_record = user_config_to_configrecord(
|
167
|
+
fed_config = flatten_dict(federation_config.get("options", {}))
|
168
|
+
c_record = user_config_to_configrecord(fed_config)
|
173
169
|
|
174
170
|
req = StartRunRequest(
|
175
171
|
fab=fab_to_proto(fab),
|
@@ -194,7 +190,7 @@ def _run_with_exec_api(
|
|
194
190
|
"fab-name": fab_id.rsplit("/", maxsplit=1)[-1],
|
195
191
|
"fab-version": fab_version,
|
196
192
|
"fab-hash": fab_hash[:8],
|
197
|
-
"fab-filename":
|
193
|
+
"fab-filename": get_fab_filename(config, fab_hash),
|
198
194
|
}
|
199
195
|
)
|
200
196
|
restore_output()
|
@@ -25,12 +25,15 @@ from uuid import UUID, uuid4
|
|
25
25
|
|
26
26
|
from flwr.common import Context, Message, log, now
|
27
27
|
from flwr.common.constant import (
|
28
|
+
HEARTBEAT_MAX_INTERVAL,
|
28
29
|
HEARTBEAT_PATIENCE,
|
29
30
|
MESSAGE_TTL_TOLERANCE,
|
30
31
|
NODE_ID_NUM_BYTES,
|
32
|
+
RUN_FAILURE_DETAILS_NO_HEARTBEAT,
|
31
33
|
RUN_ID_NUM_BYTES,
|
32
34
|
SUPERLINK_NODE_ID,
|
33
35
|
Status,
|
36
|
+
SubStatus,
|
34
37
|
)
|
35
38
|
from flwr.common.record import ConfigRecord
|
36
39
|
from flwr.common.typing import Run, RunStatus, UserConfig
|
@@ -52,8 +55,11 @@ class RunRecord: # pylint: disable=R0902
|
|
52
55
|
"""The record of a specific run, including its status and timestamps."""
|
53
56
|
|
54
57
|
run: Run
|
58
|
+
active_until: float = 0.0
|
59
|
+
heartbeat_interval: float = 0.0
|
55
60
|
logs: list[tuple[float, str]] = field(default_factory=list)
|
56
61
|
log_lock: threading.Lock = field(default_factory=threading.Lock)
|
62
|
+
lock: threading.RLock = field(default_factory=threading.RLock)
|
57
63
|
|
58
64
|
|
59
65
|
class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
|
@@ -461,8 +467,29 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
|
|
461
467
|
with self.lock:
|
462
468
|
return set(self.run_ids.keys())
|
463
469
|
|
470
|
+
def _check_and_tag_inactive_run(self, run_ids: set[int]) -> None:
|
471
|
+
"""Check if any runs are no longer active.
|
472
|
+
|
473
|
+
Marks runs with status 'starting' or 'running' as failed
|
474
|
+
if they have not sent a heartbeat before `active_until`.
|
475
|
+
"""
|
476
|
+
current = now()
|
477
|
+
for record in [self.run_ids[run_id] for run_id in run_ids]:
|
478
|
+
with record.lock:
|
479
|
+
if record.run.status.status in (Status.STARTING, Status.RUNNING):
|
480
|
+
if record.active_until < current.timestamp():
|
481
|
+
record.run.status = RunStatus(
|
482
|
+
status=Status.FINISHED,
|
483
|
+
sub_status=SubStatus.FAILED,
|
484
|
+
details=RUN_FAILURE_DETAILS_NO_HEARTBEAT,
|
485
|
+
)
|
486
|
+
record.run.finished_at = now().isoformat()
|
487
|
+
|
464
488
|
def get_run(self, run_id: int) -> Optional[Run]:
|
465
489
|
"""Retrieve information about the run with the specified `run_id`."""
|
490
|
+
# Check if runs are still active
|
491
|
+
self._check_and_tag_inactive_run(run_ids={run_id})
|
492
|
+
|
466
493
|
with self.lock:
|
467
494
|
if run_id not in self.run_ids:
|
468
495
|
log(ERROR, "`run_id` is invalid")
|
@@ -471,6 +498,9 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
|
|
471
498
|
|
472
499
|
def get_run_status(self, run_ids: set[int]) -> dict[int, RunStatus]:
|
473
500
|
"""Retrieve the statuses for the specified runs."""
|
501
|
+
# Check if runs are still active
|
502
|
+
self._check_and_tag_inactive_run(run_ids=run_ids)
|
503
|
+
|
474
504
|
with self.lock:
|
475
505
|
return {
|
476
506
|
run_id: self.run_ids[run_id].run.status
|
@@ -480,12 +510,16 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
|
|
480
510
|
|
481
511
|
def update_run_status(self, run_id: int, new_status: RunStatus) -> bool:
|
482
512
|
"""Update the status of the run with the specified `run_id`."""
|
513
|
+
# Check if runs are still active
|
514
|
+
self._check_and_tag_inactive_run(run_ids={run_id})
|
515
|
+
|
483
516
|
with self.lock:
|
484
517
|
# Check if the run_id exists
|
485
518
|
if run_id not in self.run_ids:
|
486
519
|
log(ERROR, "`run_id` is invalid")
|
487
520
|
return False
|
488
521
|
|
522
|
+
with self.run_ids[run_id].lock:
|
489
523
|
# Check if the status transition is valid
|
490
524
|
current_status = self.run_ids[run_id].run.status
|
491
525
|
if not is_valid_transition(current_status, new_status):
|
@@ -507,14 +541,23 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
|
|
507
541
|
)
|
508
542
|
return False
|
509
543
|
|
510
|
-
#
|
544
|
+
# Initialize heartbeat_interval and active_until
|
545
|
+
# when switching to starting or running
|
546
|
+
current = now()
|
511
547
|
run_record = self.run_ids[run_id]
|
548
|
+
if new_status.status in (Status.STARTING, Status.RUNNING):
|
549
|
+
run_record.heartbeat_interval = HEARTBEAT_MAX_INTERVAL
|
550
|
+
run_record.active_until = (
|
551
|
+
current.timestamp() + run_record.heartbeat_interval
|
552
|
+
)
|
553
|
+
|
554
|
+
# Update the run status
|
512
555
|
if new_status.status == Status.STARTING:
|
513
|
-
run_record.run.starting_at =
|
556
|
+
run_record.run.starting_at = current.isoformat()
|
514
557
|
elif new_status.status == Status.RUNNING:
|
515
|
-
run_record.run.running_at =
|
558
|
+
run_record.run.running_at = current.isoformat()
|
516
559
|
elif new_status.status == Status.FINISHED:
|
517
|
-
run_record.run.finished_at =
|
560
|
+
run_record.run.finished_at = current.isoformat()
|
518
561
|
run_record.run.status = new_status
|
519
562
|
return True
|
520
563
|
|
@@ -558,6 +601,43 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
|
|
558
601
|
return True
|
559
602
|
return False
|
560
603
|
|
604
|
+
def acknowledge_app_heartbeat(self, run_id: int, heartbeat_interval: float) -> bool:
|
605
|
+
"""Acknowledge a heartbeat received from a ServerApp for a given run.
|
606
|
+
|
607
|
+
A run with status `"running"` is considered alive as long as it sends heartbeats
|
608
|
+
within the tolerated interval: HEARTBEAT_PATIENCE × heartbeat_interval.
|
609
|
+
HEARTBEAT_PATIENCE = N allows for N-1 missed heartbeat before the run is
|
610
|
+
marked as `"completed:failed"`.
|
611
|
+
"""
|
612
|
+
with self.lock:
|
613
|
+
# Search for the run
|
614
|
+
record = self.run_ids.get(run_id)
|
615
|
+
|
616
|
+
# Check if the run_id exists
|
617
|
+
if record is None:
|
618
|
+
log(ERROR, "`run_id` is invalid")
|
619
|
+
return False
|
620
|
+
|
621
|
+
with record.lock:
|
622
|
+
# Check if runs are still active
|
623
|
+
self._check_and_tag_inactive_run(run_ids={run_id})
|
624
|
+
|
625
|
+
# Check if the run is of status "running"/"starting"
|
626
|
+
current_status = record.run.status
|
627
|
+
if current_status.status not in (Status.RUNNING, Status.STARTING):
|
628
|
+
log(
|
629
|
+
ERROR,
|
630
|
+
'Cannot acknowledge heartbeat for run with status "%s"',
|
631
|
+
current_status.status,
|
632
|
+
)
|
633
|
+
return False
|
634
|
+
|
635
|
+
# Update the `active_until` and `heartbeat_interval` for the given run
|
636
|
+
current = now().timestamp()
|
637
|
+
record.active_until = current + HEARTBEAT_PATIENCE * heartbeat_interval
|
638
|
+
record.heartbeat_interval = heartbeat_interval
|
639
|
+
return True
|
640
|
+
|
561
641
|
def get_serverapp_context(self, run_id: int) -> Optional[Context]:
|
562
642
|
"""Get the context for the specified `run_id`."""
|
563
643
|
return self.contexts.get(run_id)
|
@@ -292,6 +292,29 @@ class LinkState(abc.ABC): # pylint: disable=R0904
|
|
292
292
|
True if the heartbeat is successfully acknowledged; otherwise, False.
|
293
293
|
"""
|
294
294
|
|
295
|
+
@abc.abstractmethod
|
296
|
+
def acknowledge_app_heartbeat(self, run_id: int, heartbeat_interval: float) -> bool:
|
297
|
+
"""Acknowledge a heartbeat received from a ServerApp for a given run.
|
298
|
+
|
299
|
+
A run with status `"running"` is considered alive as long as it sends heartbeats
|
300
|
+
within the tolerated interval: HEARTBEAT_PATIENCE × heartbeat_interval.
|
301
|
+
HEARTBEAT_PATIENCE = N allows for N-1 missed heartbeat before the run is
|
302
|
+
marked as `"completed:failed"`.
|
303
|
+
|
304
|
+
Parameters
|
305
|
+
----------
|
306
|
+
run_id : int
|
307
|
+
The `run_id` from which the heartbeat was received.
|
308
|
+
heartbeat_interval : float
|
309
|
+
The interval (in seconds) from the current timestamp within which the next
|
310
|
+
heartbeat from the ServerApp for this run must be received.
|
311
|
+
|
312
|
+
Returns
|
313
|
+
-------
|
314
|
+
is_acknowledged : bool
|
315
|
+
True if the heartbeat is successfully acknowledged; otherwise, False.
|
316
|
+
"""
|
317
|
+
|
295
318
|
@abc.abstractmethod
|
296
319
|
def get_serverapp_context(self, run_id: int) -> Optional[Context]:
|
297
320
|
"""Get the context for the specified `run_id`.
|