flwr-nightly 1.19.0.dev20250606__tar.gz → 1.19.0.dev20250607__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.dev20250606 → flwr_nightly-1.19.0.dev20250607}/PKG-INFO +1 -1
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/grpc_rere_client/connection.py +26 -24
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/constant.py +11 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/inflatable.py +31 -15
- flwr_nightly-1.19.0.dev20250607/py/flwr/common/inflatable_grpc_utils.py +362 -0
- flwr_nightly-1.19.0.dev20250607/py/flwr/common/inflatable_utils.py +75 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/message.py +2 -2
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/grid/grpc_grid.py +23 -15
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/serverappio/serverappio_servicer.py +2 -2
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supernode/nodestate/in_memory_nodestate.py +41 -1
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supernode/nodestate/nodestate.py +55 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/pyproject.toml +1 -1
- flwr_nightly-1.19.0.dev20250606/py/flwr/common/inflatable_grpc_utils.py +0 -227
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/README.md +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/app/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/app/error.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/app/metadata.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/auth_plugin/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/auth_plugin/oidc_cli_plugin.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/build.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/cli_user_auth_interceptor.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/config_utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/constant.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/example.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/install.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/log.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/login/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/login/login.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/ls.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/new.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/.gitignore.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/LICENSE.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/README.baseline.md.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/README.flowertune.md.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/README.md.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/__init__.baseline.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/client.baseline.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/client.huggingface.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/client.jax.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/client.mlx.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/client.sklearn.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/dataset.baseline.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/model.baseline.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/server.baseline.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/server.huggingface.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/server.jax.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/server.mlx.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/server.sklearn.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/strategy.baseline.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/task.huggingface.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/task.jax.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/task.mlx.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/task.numpy.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/task.sklearn.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/code/utils.baseline.py.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/run/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/run/run.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/stop.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/cli/utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/client.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/client_app.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/clientapp/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/clientapp/utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/dpfedavg_numpy_client.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/grpc_adapter_client/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/grpc_adapter_client/connection.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/grpc_rere_client/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/grpc_rere_client/client_interceptor.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/grpc_rere_client/grpc_adapter.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/message_handler/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/message_handler/message_handler.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/mod/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/mod/centraldp_mods.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/mod/comms_mods.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/mod/localdp_mod.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/mod/utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/numpy_client.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/rest_client/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/rest_client/connection.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/run_info_store.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/client/typing.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/clientapp/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/address.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/args.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/auth_plugin/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/auth_plugin/auth_plugin.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/config.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/context.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/date.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/differential_privacy.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/differential_privacy_constants.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/dp.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/event_log_plugin/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/event_log_plugin/event_log_plugin.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/exit/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/exit/exit.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/exit/exit_code.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/exit_handlers.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/heartbeat.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/logger.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/object_ref.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/parameter.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/pyproject.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/record/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/record/array.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/record/arrayrecord.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/record/configrecord.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/record/conversion_utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/record/metricrecord.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/record/recorddict.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/record/typeddict.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/recorddict_compat.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/retry_invoker.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/secure_aggregation/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/secure_aggregation/quantization.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/serde.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/serde_utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/telemetry.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/typing.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/version.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/compat/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/compat/client/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/compat/client/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/compat/client/grpc_client/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/compat/client/grpc_client/connection.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/compat/common/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/compat/server/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/compat/server/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/compat/simulation/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/clientappio_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/clientappio_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/clientappio_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/clientappio_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/error_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/error_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/error_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/error_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/exec_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/exec_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/exec_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/exec_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/fab_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/fab_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/fab_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/fab_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/fleet_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/fleet_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/fleet_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/grpcadapter_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/grpcadapter_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/grpcadapter_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/grpcadapter_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/heartbeat_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/heartbeat_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/heartbeat_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/heartbeat_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/log_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/log_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/log_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/log_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/message_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/message_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/message_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/message_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/node_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/node_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/node_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/node_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/recorddict_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/recorddict_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/recorddict_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/recorddict_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/run_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/run_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/run_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/run_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/serverappio_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/serverappio_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/serverappio_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/serverappio_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/simulationio_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/simulationio_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/simulationio_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/simulationio_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/transport_pb2.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/transport_pb2.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/transport_pb2_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/py.typed +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/client_manager.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/client_proxy.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/compat/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/compat/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/compat/app_utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/compat/grid_client_proxy.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/compat/legacy_context.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/criterion.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/fleet_event_log_interceptor.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/grid/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/grid/grid.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/grid/inmemory_grid.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/history.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/run_serverapp.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/server.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/server_app.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/server_config.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/serverapp/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/serverapp/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/serverapp_components.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/aggregate.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/bulyan.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/fedadagrad.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/fedadam.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/fedavg.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/fedavg_android.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/fedavgm.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/fedmedian.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/fedopt.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/fedprox.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/fedyogi.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/krum.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/qfedavg.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/strategy/strategy.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/ffs/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/ffs/disk_ffs.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/ffs/ffs.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/ffs/ffs_factory.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/message_handler/message_handler.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/fleet/vce/vce_api.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/linkstate/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/linkstate/in_memory_linkstate.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/linkstate/linkstate.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/linkstate/linkstate_factory.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/linkstate/sqlite_linkstate.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/linkstate/utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/serverappio/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/serverappio/serverappio_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/simulation/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/simulation/simulationio_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/simulation/simulationio_servicer.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/superlink/utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/typing.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/utils/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/utils/tensorboard.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/utils/validator.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/workflow/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/workflow/constant.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/workflow/default_workflows.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/serverapp/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/simulation/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/simulation/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/simulation/legacy_app.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/simulation/ray_transport/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/simulation/ray_transport/utils.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/simulation/run_simulation.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/simulation/simulationio_connection.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supercore/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supercore/object_store/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supercore/object_store/in_memory_object_store.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supercore/object_store/object_store.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supercore/object_store/object_store_factory.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/superexec/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/superexec/app.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/superexec/deployment.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/superexec/exec_event_log_interceptor.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/superexec/exec_grpc.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/superexec/exec_servicer.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/superexec/exec_user_auth_interceptor.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/superexec/executor.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/superexec/simulation.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/superlink/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supernode/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supernode/cli/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supernode/cli/flower_supernode.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supernode/cli/flwr_clientapp.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supernode/nodestate/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supernode/nodestate/nodestate_factory.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supernode/runtime/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supernode/runtime/run_clientapp.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supernode/servicer/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supernode/servicer/clientappio/__init__.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/supernode/servicer/clientappio/clientappio_servicer.py +0 -0
- {flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/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.19.0.
|
3
|
+
Version: 1.19.0.dev20250607
|
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
|
@@ -30,18 +30,16 @@ from flwr.common import GRPC_MAX_MESSAGE_LENGTH
|
|
30
30
|
from flwr.common.constant import HEARTBEAT_CALL_TIMEOUT, HEARTBEAT_DEFAULT_INTERVAL
|
31
31
|
from flwr.common.grpc import create_channel, on_channel_state_change
|
32
32
|
from flwr.common.heartbeat import HeartbeatSender
|
33
|
+
from flwr.common.inflatable import get_all_nested_objects
|
33
34
|
from flwr.common.inflatable_grpc_utils import (
|
35
|
+
inflate_object_from_contents,
|
34
36
|
make_pull_object_fn_grpc,
|
35
37
|
make_push_object_fn_grpc,
|
36
|
-
|
37
|
-
|
38
|
+
pull_objects,
|
39
|
+
push_objects,
|
38
40
|
)
|
39
41
|
from flwr.common.logger import log
|
40
|
-
from flwr.common.message import
|
41
|
-
Message,
|
42
|
-
get_message_to_descendant_id_mapping,
|
43
|
-
remove_content_from_message,
|
44
|
-
)
|
42
|
+
from flwr.common.message import Message, remove_content_from_message
|
45
43
|
from flwr.common.retry_invoker import RetryInvoker, _wrap_stub
|
46
44
|
from flwr.common.secure_aggregation.crypto.symmetric_encryption import (
|
47
45
|
generate_key_pairs,
|
@@ -62,6 +60,7 @@ from flwr.proto.heartbeat_pb2 import ( # pylint: disable=E0611
|
|
62
60
|
SendNodeHeartbeatRequest,
|
63
61
|
SendNodeHeartbeatResponse,
|
64
62
|
)
|
63
|
+
from flwr.proto.message_pb2 import ObjectIDs # pylint: disable=E0611
|
65
64
|
from flwr.proto.node_pb2 import Node # pylint: disable=E0611
|
66
65
|
from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611
|
67
66
|
|
@@ -267,23 +266,21 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
267
266
|
in_message: Optional[Message] = None
|
268
267
|
|
269
268
|
if message_proto:
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
run_id=message_proto.metadata.run_id,
|
278
|
-
),
|
269
|
+
msg_id = message_proto.metadata.message_id
|
270
|
+
all_object_contents = pull_objects(
|
271
|
+
list(response.objects_to_pull[msg_id].object_ids) + [msg_id],
|
272
|
+
pull_object_fn=make_pull_object_fn_grpc(
|
273
|
+
pull_object_grpc=stub.PullObject,
|
274
|
+
node=node,
|
275
|
+
run_id=message_proto.metadata.run_id,
|
279
276
|
),
|
280
277
|
)
|
281
|
-
|
282
|
-
|
278
|
+
in_message = cast(
|
279
|
+
Message, inflate_object_from_contents(msg_id, all_object_contents)
|
280
|
+
)
|
283
281
|
# The deflated message doesn't contain the message_id (its own object_id)
|
284
282
|
# Inject
|
285
|
-
|
286
|
-
in_message.metadata._message_id = message_proto.metadata.message_id # type: ignore
|
283
|
+
in_message.metadata.__dict__["_message_id"] = msg_id
|
287
284
|
|
288
285
|
# Remember `metadata` of the in message
|
289
286
|
nonlocal metadata
|
@@ -312,20 +309,25 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
312
309
|
log(ERROR, "Invalid out message")
|
313
310
|
return
|
314
311
|
|
312
|
+
# Get all nested objects
|
313
|
+
all_objects = get_all_nested_objects(message)
|
314
|
+
all_object_ids = list(all_objects.keys())
|
315
|
+
msg_id = all_object_ids[-1] # Last object is the message itself
|
316
|
+
descendant_ids = all_object_ids[:-1] # All but the last object are descendants
|
317
|
+
|
315
318
|
# Serialize Message
|
316
319
|
message_proto = message_to_proto(message=remove_content_from_message(message))
|
317
|
-
descendants_mapping = get_message_to_descendant_id_mapping(message)
|
318
320
|
request = PushMessagesRequest(
|
319
321
|
node=node,
|
320
322
|
messages_list=[message_proto],
|
321
|
-
msg_to_descendant_mapping=
|
323
|
+
msg_to_descendant_mapping={msg_id: ObjectIDs(object_ids=descendant_ids)},
|
322
324
|
)
|
323
325
|
response: PushMessagesResponse = stub.PushMessages(request=request)
|
324
326
|
|
325
327
|
if response.objects_to_push:
|
326
328
|
objs_to_push = set(response.objects_to_push[message.object_id].object_ids)
|
327
|
-
|
328
|
-
|
329
|
+
push_objects(
|
330
|
+
all_objects,
|
329
331
|
push_object_fn=make_push_object_fn_grpc(
|
330
332
|
push_object_grpc=stub.PushObject,
|
331
333
|
node=node,
|
{flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/constant.py
RENAMED
@@ -138,6 +138,17 @@ HEAD_VALUE_DIVIDER = " "
|
|
138
138
|
# Constants for serialization
|
139
139
|
INT64_MAX_VALUE = 9223372036854775807 # (1 << 63) - 1
|
140
140
|
|
141
|
+
# Constants for `flwr-serverapp` and `flwr-clientapp` CLI commands
|
142
|
+
FLWR_APP_TOKEN_LENGTH = 128 # Length of the token used
|
143
|
+
|
144
|
+
# Constants for object pushing and pulling
|
145
|
+
MAX_CONCURRENT_PUSHES = 8 # Default maximum number of concurrent pushes
|
146
|
+
MAX_CONCURRENT_PULLS = 8 # Default maximum number of concurrent pulls
|
147
|
+
PULL_MAX_TIME = 7200 # Default maximum time to wait for pulling objects
|
148
|
+
PULL_MAX_TRIES_PER_OBJECT = 500 # Default maximum number of tries to pull an object
|
149
|
+
PULL_INITIAL_BACKOFF = 1 # Initial backoff time for pulling objects
|
150
|
+
PULL_BACKOFF_CAP = 10 # Maximum backoff time for pulling objects
|
151
|
+
|
141
152
|
|
142
153
|
class MessageType:
|
143
154
|
"""Message type."""
|
{flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/inflatable.py
RENAMED
@@ -25,6 +25,16 @@ from .constant import HEAD_BODY_DIVIDER, HEAD_VALUE_DIVIDER
|
|
25
25
|
from .logger import log
|
26
26
|
|
27
27
|
|
28
|
+
class UnexpectedObjectContentError(Exception):
|
29
|
+
"""Exception raised when the content of an object does not conform to the expected
|
30
|
+
structure for an InflatableObject (i.e., head, body, and values within the head)."""
|
31
|
+
|
32
|
+
def __init__(self, object_id: str, reason: str):
|
33
|
+
super().__init__(
|
34
|
+
f"Object with ID '{object_id}' has an unexpected structure. {reason}"
|
35
|
+
)
|
36
|
+
|
37
|
+
|
28
38
|
class InflatableObject:
|
29
39
|
"""Base class for inflatable objects."""
|
30
40
|
|
@@ -117,12 +127,14 @@ def add_header_to_object_body(object_body: bytes, obj: InflatableObject) -> byte
|
|
117
127
|
|
118
128
|
def _get_object_head(object_content: bytes) -> bytes:
|
119
129
|
"""Return object head from object content."""
|
120
|
-
|
130
|
+
index = object_content.find(HEAD_BODY_DIVIDER)
|
131
|
+
return object_content[:index]
|
121
132
|
|
122
133
|
|
123
134
|
def _get_object_body(object_content: bytes) -> bytes:
|
124
135
|
"""Return object body from object content."""
|
125
|
-
|
136
|
+
index = object_content.find(HEAD_BODY_DIVIDER)
|
137
|
+
return object_content[index + len(HEAD_BODY_DIVIDER) :]
|
126
138
|
|
127
139
|
|
128
140
|
def is_valid_sha256_hash(object_id: str) -> bool:
|
@@ -197,21 +209,25 @@ def get_object_head_values_from_object_content(
|
|
197
209
|
return obj_type, children_ids, int(body_len)
|
198
210
|
|
199
211
|
|
200
|
-
def
|
212
|
+
def get_descendant_object_ids(obj: InflatableObject) -> set[str]:
|
213
|
+
"""Get a set of object IDs of all descendants."""
|
214
|
+
descendants = set(get_all_nested_objects(obj).keys())
|
215
|
+
# Exclude Object ID of parent object
|
216
|
+
descendants.discard(obj.object_id)
|
217
|
+
return descendants
|
201
218
|
|
202
|
-
descendants: set[str] = set()
|
203
|
-
if children := obj.children:
|
204
|
-
for child in children.values():
|
205
|
-
descendants |= _get_descendants_object_ids_recursively(child)
|
206
219
|
|
207
|
-
|
220
|
+
def get_all_nested_objects(obj: InflatableObject) -> dict[str, InflatableObject]:
|
221
|
+
"""Get a dictionary of all nested objects, including the object itself.
|
208
222
|
|
209
|
-
|
223
|
+
Each key in the dictionary is an object ID, and the entries are ordered by post-
|
224
|
+
order traversal, i.e., child objects appear before their respective parents.
|
225
|
+
"""
|
226
|
+
ret: dict[str, InflatableObject] = {}
|
227
|
+
if children := obj.children:
|
228
|
+
for child in children.values():
|
229
|
+
ret.update(get_all_nested_objects(child))
|
210
230
|
|
231
|
+
ret[obj.object_id] = obj
|
211
232
|
|
212
|
-
|
213
|
-
"""Get a set of object IDs of all descendants."""
|
214
|
-
descendants = _get_descendants_object_ids_recursively(obj)
|
215
|
-
# Exclude Object ID of parent object
|
216
|
-
descendants.discard(obj.object_id)
|
217
|
-
return descendants
|
233
|
+
return ret
|
@@ -0,0 +1,362 @@
|
|
1
|
+
# Copyright 2025 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
|
+
"""InflatableObject utils."""
|
16
|
+
|
17
|
+
|
18
|
+
import concurrent.futures
|
19
|
+
import random
|
20
|
+
import threading
|
21
|
+
import time
|
22
|
+
from typing import Callable, Optional
|
23
|
+
|
24
|
+
from flwr.proto.message_pb2 import ( # pylint: disable=E0611
|
25
|
+
PullObjectRequest,
|
26
|
+
PullObjectResponse,
|
27
|
+
PushObjectRequest,
|
28
|
+
PushObjectResponse,
|
29
|
+
)
|
30
|
+
from flwr.proto.node_pb2 import Node # pylint: disable=E0611
|
31
|
+
|
32
|
+
from .constant import (
|
33
|
+
MAX_CONCURRENT_PULLS,
|
34
|
+
MAX_CONCURRENT_PUSHES,
|
35
|
+
PULL_BACKOFF_CAP,
|
36
|
+
PULL_INITIAL_BACKOFF,
|
37
|
+
PULL_MAX_TIME,
|
38
|
+
PULL_MAX_TRIES_PER_OBJECT,
|
39
|
+
)
|
40
|
+
from .inflatable import InflatableObject, get_object_head_values_from_object_content
|
41
|
+
from .message import Message
|
42
|
+
from .record import Array, ArrayRecord, ConfigRecord, MetricRecord, RecordDict
|
43
|
+
|
44
|
+
# Helper registry that maps names of classes to their type
|
45
|
+
inflatable_class_registry: dict[str, type[InflatableObject]] = {
|
46
|
+
Array.__qualname__: Array,
|
47
|
+
ArrayRecord.__qualname__: ArrayRecord,
|
48
|
+
ConfigRecord.__qualname__: ConfigRecord,
|
49
|
+
Message.__qualname__: Message,
|
50
|
+
MetricRecord.__qualname__: MetricRecord,
|
51
|
+
RecordDict.__qualname__: RecordDict,
|
52
|
+
}
|
53
|
+
|
54
|
+
|
55
|
+
class ObjectUnavailableError(Exception):
|
56
|
+
"""Exception raised when an object has been pre-registered but is not yet
|
57
|
+
available."""
|
58
|
+
|
59
|
+
def __init__(self, object_id: str):
|
60
|
+
super().__init__(f"Object with ID '{object_id}' is not yet available.")
|
61
|
+
|
62
|
+
|
63
|
+
class ObjectIdNotPreregisteredError(Exception):
|
64
|
+
"""Exception raised when an object ID is not pre-registered."""
|
65
|
+
|
66
|
+
def __init__(self, object_id: str):
|
67
|
+
super().__init__(f"Object with ID '{object_id}' could not be found.")
|
68
|
+
|
69
|
+
|
70
|
+
def make_pull_object_fn_grpc(
|
71
|
+
pull_object_grpc: Callable[[PullObjectRequest], PullObjectResponse],
|
72
|
+
node: Node,
|
73
|
+
run_id: int,
|
74
|
+
) -> Callable[[str], bytes]:
|
75
|
+
"""Create a pull object function that uses gRPC to pull objects.
|
76
|
+
|
77
|
+
Parameters
|
78
|
+
----------
|
79
|
+
pull_object_grpc : Callable[[PullObjectRequest], PullObjectResponse]
|
80
|
+
The gRPC function to pull objects, e.g., `FleetStub.PullObject`.
|
81
|
+
node : Node
|
82
|
+
The node making the request.
|
83
|
+
run_id : int
|
84
|
+
The run ID for the current operation.
|
85
|
+
|
86
|
+
Returns
|
87
|
+
-------
|
88
|
+
Callable[[str], bytes]
|
89
|
+
A function that takes an object ID and returns the object content as bytes.
|
90
|
+
The function raises `ObjectIdNotPreregisteredError` if the object ID is not
|
91
|
+
pre-registered, or `ObjectUnavailableError` if the object is not yet available.
|
92
|
+
"""
|
93
|
+
|
94
|
+
def pull_object_fn(object_id: str) -> bytes:
|
95
|
+
request = PullObjectRequest(node=node, run_id=run_id, object_id=object_id)
|
96
|
+
response: PullObjectResponse = pull_object_grpc(request)
|
97
|
+
if not response.object_found:
|
98
|
+
raise ObjectIdNotPreregisteredError(object_id)
|
99
|
+
if not response.object_available:
|
100
|
+
raise ObjectUnavailableError(object_id)
|
101
|
+
return response.object_content
|
102
|
+
|
103
|
+
return pull_object_fn
|
104
|
+
|
105
|
+
|
106
|
+
def make_push_object_fn_grpc(
|
107
|
+
push_object_grpc: Callable[[PushObjectRequest], PushObjectResponse],
|
108
|
+
node: Node,
|
109
|
+
run_id: int,
|
110
|
+
) -> Callable[[str, bytes], None]:
|
111
|
+
"""Create a push object function that uses gRPC to push objects.
|
112
|
+
|
113
|
+
Parameters
|
114
|
+
----------
|
115
|
+
push_object_grpc : Callable[[PushObjectRequest], PushObjectResponse]
|
116
|
+
The gRPC function to push objects, e.g., `FleetStub.PushObject`.
|
117
|
+
node : Node
|
118
|
+
The node making the request.
|
119
|
+
run_id : int
|
120
|
+
The run ID for the current operation.
|
121
|
+
|
122
|
+
Returns
|
123
|
+
-------
|
124
|
+
Callable[[str, bytes], None]
|
125
|
+
A function that takes an object ID and its content as bytes, and pushes it
|
126
|
+
to the servicer. The function raises `ObjectIdNotPreregisteredError` if
|
127
|
+
the object ID is not pre-registered.
|
128
|
+
"""
|
129
|
+
|
130
|
+
def push_object_fn(object_id: str, object_content: bytes) -> None:
|
131
|
+
request = PushObjectRequest(
|
132
|
+
node=node, run_id=run_id, object_id=object_id, object_content=object_content
|
133
|
+
)
|
134
|
+
response: PushObjectResponse = push_object_grpc(request)
|
135
|
+
if not response.stored:
|
136
|
+
raise ObjectIdNotPreregisteredError(object_id)
|
137
|
+
|
138
|
+
return push_object_fn
|
139
|
+
|
140
|
+
|
141
|
+
def push_objects(
|
142
|
+
objects: dict[str, InflatableObject],
|
143
|
+
push_object_fn: Callable[[str, bytes], None],
|
144
|
+
*,
|
145
|
+
object_ids_to_push: Optional[set[str]] = None,
|
146
|
+
keep_objects: bool = False,
|
147
|
+
max_concurrent_pushes: int = MAX_CONCURRENT_PUSHES,
|
148
|
+
) -> None:
|
149
|
+
"""Push multiple objects to the servicer.
|
150
|
+
|
151
|
+
Parameters
|
152
|
+
----------
|
153
|
+
objects : dict[str, InflatableObject]
|
154
|
+
A dictionary of objects to push, where keys are object IDs and values are
|
155
|
+
`InflatableObject` instances.
|
156
|
+
push_object_fn : Callable[[str, bytes], None]
|
157
|
+
A function that takes an object ID and its content as bytes, and pushes
|
158
|
+
it to the servicer. This function should raise `ObjectIdNotPreregisteredError`
|
159
|
+
if the object ID is not pre-registered.
|
160
|
+
object_ids_to_push : Optional[set[str]] (default: None)
|
161
|
+
A set of object IDs to push. If not provided, all objects will be pushed.
|
162
|
+
keep_objects : bool (default: False)
|
163
|
+
If `True`, the original objects will be kept in the `objects` dictionary
|
164
|
+
after pushing. If `False`, they will be removed from the dictionary to avoid
|
165
|
+
high memory usage.
|
166
|
+
max_concurrent_pushes : int (default: MAX_CONCURRENT_PUSHES)
|
167
|
+
The maximum number of concurrent pushes to perform.
|
168
|
+
"""
|
169
|
+
if object_ids_to_push is not None:
|
170
|
+
# Filter objects to push only those with IDs in the set
|
171
|
+
objects = {k: v for k, v in objects.items() if k in object_ids_to_push}
|
172
|
+
|
173
|
+
lock = threading.Lock()
|
174
|
+
|
175
|
+
def push(obj_id: str) -> None:
|
176
|
+
"""Push a single object."""
|
177
|
+
object_content = objects[obj_id].deflate()
|
178
|
+
if not keep_objects:
|
179
|
+
with lock:
|
180
|
+
del objects[obj_id]
|
181
|
+
push_object_fn(obj_id, object_content)
|
182
|
+
|
183
|
+
with concurrent.futures.ThreadPoolExecutor(
|
184
|
+
max_workers=max_concurrent_pushes
|
185
|
+
) as executor:
|
186
|
+
list(executor.map(push, list(objects.keys())))
|
187
|
+
|
188
|
+
|
189
|
+
def pull_objects( # pylint: disable=too-many-arguments
|
190
|
+
object_ids: list[str],
|
191
|
+
pull_object_fn: Callable[[str], bytes],
|
192
|
+
*,
|
193
|
+
max_concurrent_pulls: int = MAX_CONCURRENT_PULLS,
|
194
|
+
max_time: Optional[float] = PULL_MAX_TIME,
|
195
|
+
max_tries_per_object: Optional[int] = PULL_MAX_TRIES_PER_OBJECT,
|
196
|
+
initial_backoff: float = PULL_INITIAL_BACKOFF,
|
197
|
+
backoff_cap: float = PULL_BACKOFF_CAP,
|
198
|
+
) -> dict[str, bytes]:
|
199
|
+
"""Pull multiple objects from the servicer.
|
200
|
+
|
201
|
+
Parameters
|
202
|
+
----------
|
203
|
+
object_ids : list[str]
|
204
|
+
A list of object IDs to pull.
|
205
|
+
pull_object_fn : Callable[[str], bytes]
|
206
|
+
A function that takes an object ID and returns the object content as bytes.
|
207
|
+
The function should raise `ObjectUnavailableError` if the object is not yet
|
208
|
+
available, or `ObjectIdNotPreregisteredError` if the object ID is not
|
209
|
+
pre-registered.
|
210
|
+
max_concurrent_pulls : int (default: MAX_CONCURRENT_PULLS)
|
211
|
+
The maximum number of concurrent pulls to perform.
|
212
|
+
max_time : Optional[float] (default: PULL_MAX_TIME)
|
213
|
+
The maximum time to wait for all pulls to complete. If `None`, waits
|
214
|
+
indefinitely.
|
215
|
+
max_tries_per_object : Optional[int] (default: PULL_MAX_TRIES_PER_OBJECT)
|
216
|
+
The maximum number of attempts to pull each object. If `None`, pulls
|
217
|
+
indefinitely until the object is available.
|
218
|
+
initial_backoff : float (default: PULL_INITIAL_BACKOFF)
|
219
|
+
The initial backoff time in seconds for retrying pulls after an
|
220
|
+
`ObjectUnavailableError`.
|
221
|
+
backoff_cap : float (default: PULL_BACKOFF_CAP)
|
222
|
+
The maximum backoff time in seconds. Backoff times will not exceed this value.
|
223
|
+
|
224
|
+
Returns
|
225
|
+
-------
|
226
|
+
dict[str, bytes]
|
227
|
+
A dictionary where keys are object IDs and values are the pulled
|
228
|
+
object contents.
|
229
|
+
"""
|
230
|
+
if max_tries_per_object is None:
|
231
|
+
max_tries_per_object = int(1e9)
|
232
|
+
if max_time is None:
|
233
|
+
max_time = float("inf")
|
234
|
+
|
235
|
+
results: dict[str, bytes] = {}
|
236
|
+
results_lock = threading.Lock()
|
237
|
+
err_to_raise: Optional[Exception] = None
|
238
|
+
early_stop = threading.Event()
|
239
|
+
start = time.monotonic()
|
240
|
+
|
241
|
+
def pull_with_retries(object_id: str) -> None:
|
242
|
+
"""Attempt to pull a single object with retry and backoff."""
|
243
|
+
nonlocal err_to_raise
|
244
|
+
tries = 0
|
245
|
+
delay = initial_backoff
|
246
|
+
|
247
|
+
while not early_stop.is_set():
|
248
|
+
try:
|
249
|
+
object_content = pull_object_fn(object_id)
|
250
|
+
with results_lock:
|
251
|
+
results[object_id] = object_content
|
252
|
+
return
|
253
|
+
|
254
|
+
except ObjectUnavailableError as err:
|
255
|
+
tries += 1
|
256
|
+
if (
|
257
|
+
tries >= max_tries_per_object
|
258
|
+
or time.monotonic() - start >= max_time
|
259
|
+
):
|
260
|
+
# Stop all work if one object exhausts retries
|
261
|
+
early_stop.set()
|
262
|
+
with results_lock:
|
263
|
+
if err_to_raise is None:
|
264
|
+
err_to_raise = err
|
265
|
+
return
|
266
|
+
|
267
|
+
# Apply exponential backoff with ±20% jitter
|
268
|
+
sleep_time = delay * (1 + random.uniform(-0.2, 0.2))
|
269
|
+
early_stop.wait(sleep_time)
|
270
|
+
delay = min(delay * 2, backoff_cap)
|
271
|
+
|
272
|
+
except ObjectIdNotPreregisteredError as err:
|
273
|
+
# Permanent failure: object ID is invalid
|
274
|
+
early_stop.set()
|
275
|
+
with results_lock:
|
276
|
+
if err_to_raise is None:
|
277
|
+
err_to_raise = err
|
278
|
+
return
|
279
|
+
|
280
|
+
# Submit all pull tasks concurrently
|
281
|
+
with concurrent.futures.ThreadPoolExecutor(
|
282
|
+
max_workers=max_concurrent_pulls
|
283
|
+
) as executor:
|
284
|
+
futures = {
|
285
|
+
executor.submit(pull_with_retries, obj_id): obj_id for obj_id in object_ids
|
286
|
+
}
|
287
|
+
|
288
|
+
# Wait for completion
|
289
|
+
concurrent.futures.wait(futures)
|
290
|
+
|
291
|
+
if err_to_raise is not None:
|
292
|
+
raise err_to_raise
|
293
|
+
|
294
|
+
return results
|
295
|
+
|
296
|
+
|
297
|
+
def inflate_object_from_contents(
|
298
|
+
object_id: str,
|
299
|
+
object_contents: dict[str, bytes],
|
300
|
+
*,
|
301
|
+
keep_object_contents: bool = False,
|
302
|
+
objects: Optional[dict[str, InflatableObject]] = None,
|
303
|
+
) -> InflatableObject:
|
304
|
+
"""Inflate an object from object contents.
|
305
|
+
|
306
|
+
Parameters
|
307
|
+
----------
|
308
|
+
object_id : str
|
309
|
+
The ID of the object to inflate.
|
310
|
+
object_contents : dict[str, bytes]
|
311
|
+
A dictionary mapping object IDs to their contents as bytes.
|
312
|
+
All descendant objects must be present in this dictionary.
|
313
|
+
keep_object_contents : bool (default: False)
|
314
|
+
If `True`, the object content will be kept in the `object_contents`
|
315
|
+
dictionary after inflation. If `False`, the object content will be
|
316
|
+
removed from the dictionary to save memory.
|
317
|
+
objects : Optional[dict[str, InflatableObject]] (default: None)
|
318
|
+
No need to provide this parameter. A dictionary to store already
|
319
|
+
inflated objects, mapping object IDs to their corresponding
|
320
|
+
`InflatableObject` instances.
|
321
|
+
|
322
|
+
Returns
|
323
|
+
-------
|
324
|
+
InflatableObject
|
325
|
+
The inflated object.
|
326
|
+
"""
|
327
|
+
if objects is None:
|
328
|
+
# Initialize objects dictionary
|
329
|
+
objects = {}
|
330
|
+
|
331
|
+
if object_id in objects:
|
332
|
+
# If the object is already in the objects dictionary, return it
|
333
|
+
return objects[object_id]
|
334
|
+
|
335
|
+
# Extract object class and object_ids of children
|
336
|
+
object_content = object_contents[object_id]
|
337
|
+
obj_type, children_obj_ids, _ = get_object_head_values_from_object_content(
|
338
|
+
object_content=object_contents[object_id]
|
339
|
+
)
|
340
|
+
|
341
|
+
# Remove the object content from the dictionary to save memory
|
342
|
+
if not keep_object_contents:
|
343
|
+
del object_contents[object_id]
|
344
|
+
|
345
|
+
# Resolve object class
|
346
|
+
cls_type = inflatable_class_registry[obj_type]
|
347
|
+
|
348
|
+
# Inflate all children objects
|
349
|
+
children: dict[str, InflatableObject] = {}
|
350
|
+
for child_obj_id in children_obj_ids:
|
351
|
+
children[child_obj_id] = inflate_object_from_contents(
|
352
|
+
child_obj_id,
|
353
|
+
object_contents,
|
354
|
+
keep_object_contents=keep_object_contents,
|
355
|
+
objects=objects,
|
356
|
+
)
|
357
|
+
|
358
|
+
# Inflate object passing its children
|
359
|
+
obj = cls_type.inflate(object_content, children=children)
|
360
|
+
del object_content # Free memory after inflation
|
361
|
+
objects[object_id] = obj
|
362
|
+
return obj
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# Copyright 2025 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
|
+
"""InflatableObject utilities."""
|
16
|
+
|
17
|
+
|
18
|
+
from .constant import HEAD_BODY_DIVIDER, HEAD_VALUE_DIVIDER
|
19
|
+
from .inflatable import (
|
20
|
+
UnexpectedObjectContentError,
|
21
|
+
_get_object_head,
|
22
|
+
get_object_id,
|
23
|
+
is_valid_sha256_hash,
|
24
|
+
)
|
25
|
+
from .inflatable_grpc_utils import inflatable_class_registry
|
26
|
+
|
27
|
+
|
28
|
+
def validate_object_content(content: bytes) -> None:
|
29
|
+
"""Validate the deflated content of an InflatableObject."""
|
30
|
+
try:
|
31
|
+
# Check if there is a head-body divider
|
32
|
+
index = content.find(HEAD_BODY_DIVIDER)
|
33
|
+
if index == -1:
|
34
|
+
raise ValueError(
|
35
|
+
"Unexpected format for object content. Head and body "
|
36
|
+
"could not be split."
|
37
|
+
)
|
38
|
+
|
39
|
+
head = _get_object_head(content)
|
40
|
+
|
41
|
+
# check if the head has three parts:
|
42
|
+
# <object_type> <children_ids> <object_body_len>
|
43
|
+
head_decoded = head.decode(encoding="utf-8")
|
44
|
+
head_parts = head_decoded.split(HEAD_VALUE_DIVIDER)
|
45
|
+
|
46
|
+
if len(head_parts) != 3:
|
47
|
+
raise ValueError("Unexpected format for object head.")
|
48
|
+
|
49
|
+
obj_type, children_str, body_len = head_parts
|
50
|
+
|
51
|
+
# Check that children IDs are valid IDs
|
52
|
+
children = children_str.split(",")
|
53
|
+
for children_id in children:
|
54
|
+
if children_id and not is_valid_sha256_hash(children_id):
|
55
|
+
raise ValueError(
|
56
|
+
f"Detected invalid object ID ({children_id}) in children."
|
57
|
+
)
|
58
|
+
|
59
|
+
# Check that object type is recognized
|
60
|
+
if obj_type not in inflatable_class_registry:
|
61
|
+
if obj_type != "CustomDataClass": # to allow for the class in tests
|
62
|
+
raise ValueError(f"Object of type {obj_type} is not supported.")
|
63
|
+
|
64
|
+
# Check if the body length in the head matches that of the body
|
65
|
+
actual_body_len = len(content) - len(head) - len(HEAD_BODY_DIVIDER)
|
66
|
+
if actual_body_len != int(body_len):
|
67
|
+
raise ValueError(
|
68
|
+
f"Object content length expected {body_len} bytes but got "
|
69
|
+
f"{actual_body_len} bytes."
|
70
|
+
)
|
71
|
+
|
72
|
+
except ValueError as err:
|
73
|
+
raise UnexpectedObjectContentError(
|
74
|
+
object_id=get_object_id(content), reason=str(err)
|
75
|
+
) from err
|
{flwr_nightly-1.19.0.dev20250606 → flwr_nightly-1.19.0.dev20250607}/py/flwr/common/message.py
RENAMED
@@ -32,7 +32,7 @@ from .constant import MESSAGE_TTL_TOLERANCE
|
|
32
32
|
from .inflatable import (
|
33
33
|
InflatableObject,
|
34
34
|
add_header_to_object_body,
|
35
|
-
|
35
|
+
get_descendant_object_ids,
|
36
36
|
get_object_body,
|
37
37
|
get_object_children_ids_from_object_content,
|
38
38
|
)
|
@@ -524,6 +524,6 @@ def get_message_to_descendant_id_mapping(message: Message) -> dict[str, ObjectID
|
|
524
524
|
"""Construct a mapping between message object_id and that of its descendants."""
|
525
525
|
return {
|
526
526
|
message.object_id: ObjectIDs(
|
527
|
-
object_ids=list(
|
527
|
+
object_ids=list(get_descendant_object_ids(message))
|
528
528
|
)
|
529
529
|
}
|