flwr 1.22.0__tar.gz → 1.23.0__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-1.22.0 → flwr-1.23.0}/PKG-INFO +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/app.py +15 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/auth_plugin/__init__.py +15 -6
- flwr-1.23.0/py/flwr/cli/auth_plugin/auth_plugin.py +95 -0
- flwr-1.23.0/py/flwr/cli/auth_plugin/noop_auth_plugin.py +58 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/auth_plugin/oidc_cli_plugin.py +16 -25
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/build.py +118 -47
- flwr-1.22.0/py/flwr/cli/cli_user_auth_interceptor.py → flwr-1.23.0/py/flwr/cli/cli_account_auth_interceptor.py +6 -5
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/log.py +2 -2
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/login/login.py +34 -23
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/ls.py +13 -9
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/new.py +187 -35
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/pyproject.pytorch_legacy_api.toml.tpl +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/pyproject.xgboost.toml.tpl +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/pull.py +2 -2
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/run/run.py +11 -7
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/stop.py +2 -2
- flwr-1.23.0/py/flwr/cli/supernode/__init__.py +25 -0
- flwr-1.23.0/py/flwr/cli/supernode/ls.py +260 -0
- flwr-1.23.0/py/flwr/cli/supernode/register.py +185 -0
- flwr-1.23.0/py/flwr/cli/supernode/unregister.py +138 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/utils.py +92 -69
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/__init__.py +2 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/grpc_adapter_client/connection.py +6 -8
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/grpc_rere_client/connection.py +59 -31
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/grpc_rere_client/grpc_adapter.py +28 -12
- flwr-1.22.0/py/flwr/client/grpc_rere_client/client_interceptor.py → flwr-1.23.0/py/flwr/client/grpc_rere_client/node_auth_client_interceptor.py +3 -6
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +7 -5
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/rest_client/connection.py +82 -37
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/clientapp/__init__.py +1 -2
- {flwr-1.22.0/py/flwr/client → flwr-1.23.0/py/flwr}/clientapp/utils.py +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/constant.py +53 -13
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/exit/exit_code.py +20 -10
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/inflatable_utils.py +10 -10
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/record/array.py +3 -3
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/record/arrayrecord.py +10 -1
- flwr-1.23.0/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +76 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/serde.py +4 -2
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/typing.py +7 -6
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/compat/client/app.py +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/compat/client/grpc_client/connection.py +2 -2
- flwr-1.23.0/py/flwr/proto/control_pb2.py +79 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/control_pb2.pyi +71 -5
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/control_pb2_grpc.py +102 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/control_pb2_grpc.pyi +39 -0
- flwr-1.23.0/py/flwr/proto/fab_pb2.py +35 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/fab_pb2.pyi +21 -1
- flwr-1.23.0/py/flwr/proto/fleet_pb2.py +61 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/fleet_pb2.pyi +63 -23
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/fleet_pb2_grpc.py +98 -28
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/fleet_pb2_grpc.pyi +45 -13
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/node_pb2.py +3 -1
- flwr-1.23.0/py/flwr/proto/node_pb2.pyi +69 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/app.py +139 -114
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +17 -7
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +132 -38
- flwr-1.22.0/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py → flwr-1.23.0/py/flwr/server/superlink/fleet/grpc_rere/node_auth_server_interceptor.py +27 -51
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/message_handler/message_handler.py +67 -22
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +52 -31
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/vce/backend/backend.py +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/vce/vce_api.py +18 -5
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/linkstate/in_memory_linkstate.py +167 -73
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/linkstate/linkstate.py +107 -24
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/linkstate/linkstate_factory.py +2 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/linkstate/sqlite_linkstate.py +306 -255
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/linkstate/utils.py +3 -54
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/serverappio/serverappio_servicer.py +2 -2
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/simulation/simulationio_servicer.py +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/utils/validator.py +2 -3
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +4 -2
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/simulation/ray_transport/ray_actor.py +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/simulation/ray_transport/ray_client_proxy.py +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/simulation/run_simulation.py +3 -2
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/constant.py +22 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/object_store/in_memory_object_store.py +0 -4
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/object_store/object_store_factory.py +26 -6
- flwr-1.23.0/py/flwr/supercore/object_store/sqlite_object_store.py +252 -0
- flwr-1.23.0/py/flwr/supercore/primitives/__init__.py +15 -0
- flwr-1.22.0/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py → flwr-1.23.0/py/flwr/supercore/primitives/asymmetric.py +10 -57
- flwr-1.23.0/py/flwr/supercore/primitives/asymmetric_ed25519.py +165 -0
- flwr-1.23.0/py/flwr/supercore/sqlite_mixin.py +156 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/utils.py +20 -0
- {flwr-1.22.0/py/flwr/common → flwr-1.23.0/py/flwr/superlink}/auth_plugin/__init__.py +6 -6
- flwr-1.23.0/py/flwr/superlink/auth_plugin/auth_plugin.py +91 -0
- flwr-1.23.0/py/flwr/superlink/auth_plugin/noop_auth_plugin.py +87 -0
- flwr-1.22.0/py/flwr/superlink/servicer/control/control_user_auth_interceptor.py → flwr-1.23.0/py/flwr/superlink/servicer/control/control_account_auth_interceptor.py +19 -19
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/superlink/servicer/control/control_event_log_interceptor.py +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/superlink/servicer/control/control_grpc.py +13 -11
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/superlink/servicer/control/control_servicer.py +152 -60
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supernode/cli/flower_supernode.py +19 -26
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supernode/runtime/run_clientapp.py +2 -2
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supernode/servicer/clientappio/clientappio_servicer.py +1 -1
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supernode/start_client_internal.py +17 -9
- {flwr-1.22.0 → flwr-1.23.0}/pyproject.toml +3 -2
- flwr-1.22.0/py/flwr/client/clientapp/__init__.py +0 -15
- flwr-1.22.0/py/flwr/common/auth_plugin/auth_plugin.py +0 -149
- flwr-1.22.0/py/flwr/proto/control_pb2.py +0 -66
- flwr-1.22.0/py/flwr/proto/fab_pb2.py +0 -31
- flwr-1.22.0/py/flwr/proto/fleet_pb2.py +0 -53
- flwr-1.22.0/py/flwr/proto/node_pb2.pyi +0 -21
- {flwr-1.22.0 → flwr-1.23.0}/README.md +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/app/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/app/error.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/app/exception.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/app/metadata.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/config_utils.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/constant.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/example.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/install.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/login/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/.gitignore.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/LICENSE.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/README.baseline.md.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/README.flowertune.md.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/README.md.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/__init__.baseline.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/__init__.pytorch_legacy_api.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/client.baseline.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/client.huggingface.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/client.jax.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/client.mlx.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/client.pytorch_legacy_api.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/client.sklearn.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/client.xgboost.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/dataset.baseline.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/model.baseline.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/server.baseline.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/server.huggingface.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/server.jax.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/server.mlx.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/server.pytorch_legacy_api.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/server.sklearn.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/server.xgboost.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/strategy.baseline.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/task.huggingface.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/task.jax.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/task.mlx.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/task.numpy.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/task.pytorch_legacy_api.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/task.sklearn.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/task.xgboost.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/new/templates/app/code/utils.baseline.py.tpl +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/cli/run/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/client.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/dpfedavg_numpy_client.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/grpc_adapter_client/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/grpc_rere_client/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/message_handler/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/message_handler/message_handler.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/mod/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/mod/centraldp_mods.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/mod/comms_mods.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/mod/localdp_mod.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/mod/utils.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/numpy_client.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/rest_client/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/run_info_store.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/client/typing.py +0 -0
- {flwr-1.22.0/py/flwr/client → flwr-1.23.0/py/flwr/clientapp}/client_app.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/clientapp/mod/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/clientapp/mod/centraldp_mods.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/clientapp/mod/localdp_mod.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/clientapp/typing.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/address.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/args.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/config.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/context.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/date.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/differential_privacy.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/differential_privacy_constants.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/dp.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/event_log_plugin/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/event_log_plugin/event_log_plugin.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/exit/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/exit/exit.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/exit/exit_handler.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/exit/signal_handler.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/heartbeat.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/inflatable.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/inflatable_protobuf_utils.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/logger.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/message.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/object_ref.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/parameter.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/pyproject.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/record/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/record/arraychunk.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/record/configrecord.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/record/conversion_utils.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/record/metricrecord.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/record/recorddict.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/record/typeddict.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/recorddict_compat.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/retry_invoker.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/secure_aggregation/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/secure_aggregation/quantization.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/serde_utils.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/telemetry.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/common/version.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/compat/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/compat/client/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/compat/client/grpc_client/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/compat/common/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/compat/server/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/compat/server/app.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/compat/simulation/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/appio_pb2.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/appio_pb2.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/appio_pb2_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/appio_pb2_grpc.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/clientappio_pb2.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/clientappio_pb2.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/clientappio_pb2_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/clientappio_pb2_grpc.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/error_pb2.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/error_pb2.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/error_pb2_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/error_pb2_grpc.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/fab_pb2_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/fab_pb2_grpc.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/grpcadapter_pb2.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/grpcadapter_pb2.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/grpcadapter_pb2_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/grpcadapter_pb2_grpc.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/heartbeat_pb2.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/heartbeat_pb2.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/heartbeat_pb2_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/heartbeat_pb2_grpc.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/log_pb2.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/log_pb2.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/log_pb2_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/log_pb2_grpc.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/message_pb2.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/message_pb2.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/message_pb2_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/message_pb2_grpc.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/node_pb2_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/node_pb2_grpc.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/recorddict_pb2.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/recorddict_pb2.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/recorddict_pb2_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/recorddict_pb2_grpc.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/run_pb2.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/run_pb2.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/run_pb2_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/run_pb2_grpc.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/serverappio_pb2.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/serverappio_pb2.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/serverappio_pb2_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/serverappio_pb2_grpc.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/simulationio_pb2.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/simulationio_pb2.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/simulationio_pb2_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/simulationio_pb2_grpc.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/transport_pb2.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/transport_pb2.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/transport_pb2_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/py.typed +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/client_manager.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/client_proxy.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/compat/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/compat/app.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/compat/app_utils.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/compat/grid_client_proxy.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/compat/legacy_context.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/criterion.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/fleet_event_log_interceptor.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/grid/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/grid/grid.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/grid/grpc_grid.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/grid/inmemory_grid.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/history.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/run_serverapp.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/server.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/server_app.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/server_config.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/serverapp/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/serverapp/app.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/serverapp_components.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/aggregate.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/bulyan.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/fedadagrad.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/fedadam.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/fedavg.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/fedavg_android.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/fedavgm.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/fedmedian.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/fedopt.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/fedprox.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/fedyogi.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/krum.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/qfedavg.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/strategy/strategy.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/linkstate/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/serverappio/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/serverappio/serverappio_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/simulation/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/simulation/simulationio_grpc.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/superlink/utils.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/typing.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/utils/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/utils/tensorboard.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/workflow/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/workflow/constant.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/workflow/default_workflows.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/exception.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/bulyan.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/dp_adaptive_clipping.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/dp_fixed_clipping.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/fedadagrad.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/fedadam.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/fedavg.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/fedavgm.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/fedmedian.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/fedopt.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/fedprox.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/fedtrimmedavg.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/fedxgb_bagging.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/fedxgb_cyclic.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/fedyogi.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/krum.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/multikrum.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/qfedavg.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/result.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/strategy.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/serverapp/strategy/strategy_utils.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/simulation/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/simulation/app.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/simulation/legacy_app.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/simulation/ray_transport/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/simulation/ray_transport/utils.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/simulation/simulationio_connection.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/app_utils.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/cli/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/cli/flower_superexec.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/corestate/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/corestate/corestate.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/ffs/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/ffs/disk_ffs.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/ffs/ffs.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/ffs/ffs_factory.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/grpc_health/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/grpc_health/health_server.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/grpc_health/simple_health_servicer.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/license_plugin/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/license_plugin/license_plugin.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/object_store/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/object_store/object_store.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/object_store/utils.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/superexec/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/superexec/plugin/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/superexec/plugin/base_exec_plugin.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/superexec/plugin/clientapp_exec_plugin.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/superexec/plugin/exec_plugin.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/superexec/plugin/serverapp_exec_plugin.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/superexec/plugin/simulation_exec_plugin.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supercore/superexec/run_superexec.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/superlink/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/superlink/artifact_provider/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/superlink/artifact_provider/artifact_provider.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/superlink/servicer/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/superlink/servicer/control/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/superlink/servicer/control/control_license_interceptor.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supernode/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supernode/cli/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supernode/cli/flwr_clientapp.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supernode/nodestate/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supernode/nodestate/in_memory_nodestate.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supernode/nodestate/nodestate.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supernode/nodestate/nodestate_factory.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supernode/runtime/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supernode/servicer/__init__.py +0 -0
- {flwr-1.22.0 → flwr-1.23.0}/py/flwr/supernode/servicer/clientappio/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: flwr
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.23.0
|
|
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
|
|
@@ -28,6 +28,9 @@ from .new import new
|
|
|
28
28
|
from .pull import pull
|
|
29
29
|
from .run import run
|
|
30
30
|
from .stop import stop
|
|
31
|
+
from .supernode import ls as supernode_list
|
|
32
|
+
from .supernode import register as supernode_register
|
|
33
|
+
from .supernode import unregister as supernode_unregister
|
|
31
34
|
|
|
32
35
|
app = typer.Typer(
|
|
33
36
|
help=typer.style(
|
|
@@ -44,11 +47,22 @@ app.command()(run)
|
|
|
44
47
|
app.command()(build)
|
|
45
48
|
app.command()(install)
|
|
46
49
|
app.command()(log)
|
|
47
|
-
app.command()(ls)
|
|
50
|
+
app.command("list")(ls)
|
|
51
|
+
app.command(hidden=True)(ls)
|
|
48
52
|
app.command()(stop)
|
|
49
53
|
app.command()(login)
|
|
50
54
|
app.command()(pull)
|
|
51
55
|
|
|
56
|
+
# Create supernode command group
|
|
57
|
+
supernode_app = typer.Typer(help="Manage SuperNodes")
|
|
58
|
+
supernode_app.command()(supernode_register)
|
|
59
|
+
supernode_app.command()(supernode_unregister)
|
|
60
|
+
# Make it appear as "list"
|
|
61
|
+
supernode_app.command("list")(supernode_list)
|
|
62
|
+
# Hide "ls" command (left as alias)
|
|
63
|
+
supernode_app.command(hidden=True)(supernode_list)
|
|
64
|
+
app.add_typer(supernode_app, name="supernode")
|
|
65
|
+
|
|
52
66
|
typer_click_object = get_command(app)
|
|
53
67
|
|
|
54
68
|
|
|
@@ -12,20 +12,29 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
# ==============================================================================
|
|
15
|
-
"""Flower
|
|
15
|
+
"""Flower account auth plugins."""
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
from flwr.common.
|
|
19
|
-
from flwr.common.constant import AuthType
|
|
18
|
+
from flwr.common.constant import AuthnType
|
|
20
19
|
|
|
20
|
+
from .auth_plugin import CliAuthPlugin, LoginError
|
|
21
|
+
from .noop_auth_plugin import NoOpCliAuthPlugin
|
|
21
22
|
from .oidc_cli_plugin import OidcCliPlugin
|
|
22
23
|
|
|
23
24
|
|
|
24
|
-
def
|
|
25
|
+
def get_cli_plugin_class(authn_type: str) -> type[CliAuthPlugin]:
|
|
25
26
|
"""Return all CLI authentication plugins."""
|
|
26
|
-
|
|
27
|
+
if authn_type == AuthnType.NOOP:
|
|
28
|
+
return NoOpCliAuthPlugin
|
|
29
|
+
if authn_type == AuthnType.OIDC:
|
|
30
|
+
return OidcCliPlugin
|
|
31
|
+
raise ValueError(f"Unsupported authentication type: {authn_type}")
|
|
27
32
|
|
|
28
33
|
|
|
29
34
|
__all__ = [
|
|
30
|
-
"
|
|
35
|
+
"CliAuthPlugin",
|
|
36
|
+
"LoginError",
|
|
37
|
+
"NoOpCliAuthPlugin",
|
|
38
|
+
"OidcCliPlugin",
|
|
39
|
+
"get_cli_plugin_class",
|
|
31
40
|
]
|
|
@@ -0,0 +1,95 @@
|
|
|
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
|
+
"""Abstract classes for Flower account auth plugin."""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
from abc import ABC, abstractmethod
|
|
19
|
+
from collections.abc import Sequence
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
from typing import Optional, Union
|
|
22
|
+
|
|
23
|
+
from flwr.common.typing import AccountAuthCredentials, AccountAuthLoginDetails
|
|
24
|
+
from flwr.proto.control_pb2_grpc import ControlStub
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class LoginError(Exception):
|
|
28
|
+
"""Login error exception."""
|
|
29
|
+
|
|
30
|
+
def __init__(self, message: str):
|
|
31
|
+
self.message = message
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class CliAuthPlugin(ABC):
|
|
35
|
+
"""Abstract Flower Auth Plugin class for CLI.
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
credentials_path : Path
|
|
40
|
+
Path to the Flower account's authentication credentials file.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
@staticmethod
|
|
44
|
+
@abstractmethod
|
|
45
|
+
def login(
|
|
46
|
+
login_details: AccountAuthLoginDetails,
|
|
47
|
+
control_stub: ControlStub,
|
|
48
|
+
) -> AccountAuthCredentials:
|
|
49
|
+
"""Authenticate the account and retrieve authentication credentials.
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
login_details : AccountAuthLoginDetails
|
|
54
|
+
An object containing the account's login details.
|
|
55
|
+
control_stub : ControlStub
|
|
56
|
+
A stub for executing RPC calls to the server.
|
|
57
|
+
|
|
58
|
+
Returns
|
|
59
|
+
-------
|
|
60
|
+
AccountAuthCredentials
|
|
61
|
+
The authentication credentials obtained after login.
|
|
62
|
+
|
|
63
|
+
Raises
|
|
64
|
+
------
|
|
65
|
+
LoginError
|
|
66
|
+
If the login process fails.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
@abstractmethod
|
|
70
|
+
def __init__(self, credentials_path: Path):
|
|
71
|
+
"""Abstract constructor."""
|
|
72
|
+
|
|
73
|
+
@abstractmethod
|
|
74
|
+
def store_tokens(self, credentials: AccountAuthCredentials) -> None:
|
|
75
|
+
"""Store authentication tokens to the `credentials_path`.
|
|
76
|
+
|
|
77
|
+
The credentials, including tokens, will be saved as a JSON file
|
|
78
|
+
at `credentials_path`.
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
@abstractmethod
|
|
82
|
+
def load_tokens(self) -> None:
|
|
83
|
+
"""Load authentication tokens from the `credentials_path`."""
|
|
84
|
+
|
|
85
|
+
@abstractmethod
|
|
86
|
+
def write_tokens_to_metadata(
|
|
87
|
+
self, metadata: Sequence[tuple[str, Union[str, bytes]]]
|
|
88
|
+
) -> Sequence[tuple[str, Union[str, bytes]]]:
|
|
89
|
+
"""Write authentication tokens to the provided metadata."""
|
|
90
|
+
|
|
91
|
+
@abstractmethod
|
|
92
|
+
def read_tokens_from_metadata(
|
|
93
|
+
self, metadata: Sequence[tuple[str, Union[str, bytes]]]
|
|
94
|
+
) -> Optional[AccountAuthCredentials]:
|
|
95
|
+
"""Read authentication tokens from the provided metadata."""
|
|
@@ -0,0 +1,58 @@
|
|
|
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
|
+
"""Concrete NoOp implementation for CLI-side account authentication plugin."""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
from collections.abc import Sequence
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import Optional, Union
|
|
21
|
+
|
|
22
|
+
from flwr.common.typing import AccountAuthCredentials, AccountAuthLoginDetails
|
|
23
|
+
from flwr.proto.control_pb2_grpc import ControlStub
|
|
24
|
+
|
|
25
|
+
from .auth_plugin import CliAuthPlugin, LoginError
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class NoOpCliAuthPlugin(CliAuthPlugin):
|
|
29
|
+
"""No-operation implementation of the CliAuthPlugin."""
|
|
30
|
+
|
|
31
|
+
@staticmethod
|
|
32
|
+
def login(
|
|
33
|
+
login_details: AccountAuthLoginDetails,
|
|
34
|
+
control_stub: ControlStub,
|
|
35
|
+
) -> AccountAuthCredentials:
|
|
36
|
+
"""Raise LoginError as no-op plugin does not support login."""
|
|
37
|
+
raise LoginError("Account authentication is not enabled on this SuperLink.")
|
|
38
|
+
|
|
39
|
+
def __init__(self, credentials_path: Path) -> None:
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
def store_tokens(self, credentials: AccountAuthCredentials) -> None:
|
|
43
|
+
"""Do nothing."""
|
|
44
|
+
|
|
45
|
+
def load_tokens(self) -> None:
|
|
46
|
+
"""Do nothing."""
|
|
47
|
+
|
|
48
|
+
def write_tokens_to_metadata(
|
|
49
|
+
self, metadata: Sequence[tuple[str, Union[str, bytes]]]
|
|
50
|
+
) -> Sequence[tuple[str, Union[str, bytes]]]:
|
|
51
|
+
"""Return the metadata unchanged."""
|
|
52
|
+
return metadata
|
|
53
|
+
|
|
54
|
+
def read_tokens_from_metadata(
|
|
55
|
+
self, metadata: Sequence[tuple[str, Union[str, bytes]]]
|
|
56
|
+
) -> Optional[AccountAuthCredentials]:
|
|
57
|
+
"""Return None."""
|
|
58
|
+
return None
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
# ==============================================================================
|
|
15
|
-
"""Flower CLI
|
|
15
|
+
"""Flower CLI account auth plugin for OIDC."""
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
import json
|
|
@@ -23,20 +23,21 @@ from typing import Any, Optional, Union
|
|
|
23
23
|
|
|
24
24
|
import typer
|
|
25
25
|
|
|
26
|
-
from flwr.common.auth_plugin import CliAuthPlugin
|
|
27
26
|
from flwr.common.constant import (
|
|
28
27
|
ACCESS_TOKEN_KEY,
|
|
29
|
-
|
|
28
|
+
AUTHN_TYPE_JSON_KEY,
|
|
30
29
|
REFRESH_TOKEN_KEY,
|
|
31
|
-
|
|
30
|
+
AuthnType,
|
|
32
31
|
)
|
|
33
|
-
from flwr.common.typing import
|
|
32
|
+
from flwr.common.typing import AccountAuthCredentials, AccountAuthLoginDetails
|
|
34
33
|
from flwr.proto.control_pb2 import ( # pylint: disable=E0611
|
|
35
34
|
GetAuthTokensRequest,
|
|
36
35
|
GetAuthTokensResponse,
|
|
37
36
|
)
|
|
38
37
|
from flwr.proto.control_pb2_grpc import ControlStub
|
|
39
38
|
|
|
39
|
+
from .auth_plugin import CliAuthPlugin, LoginError
|
|
40
|
+
|
|
40
41
|
|
|
41
42
|
class OidcCliPlugin(CliAuthPlugin):
|
|
42
43
|
"""Flower OIDC auth plugin for CLI."""
|
|
@@ -48,12 +49,12 @@ class OidcCliPlugin(CliAuthPlugin):
|
|
|
48
49
|
|
|
49
50
|
@staticmethod
|
|
50
51
|
def login(
|
|
51
|
-
login_details:
|
|
52
|
+
login_details: AccountAuthLoginDetails,
|
|
52
53
|
control_stub: ControlStub,
|
|
53
|
-
) ->
|
|
54
|
-
"""Authenticate the
|
|
54
|
+
) -> AccountAuthCredentials:
|
|
55
|
+
"""Authenticate the account and retrieve authentication credentials."""
|
|
55
56
|
typer.secho(
|
|
56
|
-
"Please
|
|
57
|
+
"Please log into your Flower account here: "
|
|
57
58
|
f"{login_details.verification_uri_complete}",
|
|
58
59
|
fg=typer.colors.BLUE,
|
|
59
60
|
)
|
|
@@ -69,26 +70,16 @@ class OidcCliPlugin(CliAuthPlugin):
|
|
|
69
70
|
refresh_token = res.refresh_token
|
|
70
71
|
|
|
71
72
|
if access_token and refresh_token:
|
|
72
|
-
|
|
73
|
-
"✅ Login successful.",
|
|
74
|
-
fg=typer.colors.GREEN,
|
|
75
|
-
bold=False,
|
|
76
|
-
)
|
|
77
|
-
return UserAuthCredentials(
|
|
73
|
+
return AccountAuthCredentials(
|
|
78
74
|
access_token=access_token,
|
|
79
75
|
refresh_token=refresh_token,
|
|
80
76
|
)
|
|
81
77
|
|
|
82
78
|
time.sleep(login_details.interval)
|
|
83
79
|
|
|
84
|
-
|
|
85
|
-
"❌ Timeout, failed to sign in.",
|
|
86
|
-
fg=typer.colors.RED,
|
|
87
|
-
bold=True,
|
|
88
|
-
)
|
|
89
|
-
raise typer.Exit(code=1)
|
|
80
|
+
raise LoginError("Process timed out.")
|
|
90
81
|
|
|
91
|
-
def store_tokens(self, credentials:
|
|
82
|
+
def store_tokens(self, credentials: AccountAuthCredentials) -> None:
|
|
92
83
|
"""Store authentication tokens to the `credentials_path`.
|
|
93
84
|
|
|
94
85
|
The credentials, including tokens, will be saved as a JSON file
|
|
@@ -97,7 +88,7 @@ class OidcCliPlugin(CliAuthPlugin):
|
|
|
97
88
|
self.access_token = credentials.access_token
|
|
98
89
|
self.refresh_token = credentials.refresh_token
|
|
99
90
|
json_dict = {
|
|
100
|
-
|
|
91
|
+
AUTHN_TYPE_JSON_KEY: AuthnType.OIDC,
|
|
101
92
|
ACCESS_TOKEN_KEY: credentials.access_token,
|
|
102
93
|
REFRESH_TOKEN_KEY: credentials.refresh_token,
|
|
103
94
|
}
|
|
@@ -135,14 +126,14 @@ class OidcCliPlugin(CliAuthPlugin):
|
|
|
135
126
|
|
|
136
127
|
def read_tokens_from_metadata(
|
|
137
128
|
self, metadata: Sequence[tuple[str, Union[str, bytes]]]
|
|
138
|
-
) -> Optional[
|
|
129
|
+
) -> Optional[AccountAuthCredentials]:
|
|
139
130
|
"""Read authentication tokens from the provided metadata."""
|
|
140
131
|
metadata_dict = dict(metadata)
|
|
141
132
|
access_token = metadata_dict.get(ACCESS_TOKEN_KEY)
|
|
142
133
|
refresh_token = metadata_dict.get(REFRESH_TOKEN_KEY)
|
|
143
134
|
|
|
144
135
|
if isinstance(access_token, str) and isinstance(refresh_token, str):
|
|
145
|
-
return
|
|
136
|
+
return AccountAuthCredentials(
|
|
146
137
|
access_token=access_token,
|
|
147
138
|
refresh_token=refresh_token,
|
|
148
139
|
)
|
|
@@ -17,22 +17,25 @@
|
|
|
17
17
|
|
|
18
18
|
import hashlib
|
|
19
19
|
import zipfile
|
|
20
|
+
from collections.abc import Iterable
|
|
20
21
|
from io import BytesIO
|
|
21
22
|
from pathlib import Path
|
|
22
23
|
from typing import Annotated, Any, Optional, Union
|
|
23
24
|
|
|
24
25
|
import pathspec
|
|
26
|
+
import tomli
|
|
25
27
|
import tomli_w
|
|
26
28
|
import typer
|
|
27
29
|
|
|
28
30
|
from flwr.common.constant import (
|
|
29
|
-
|
|
31
|
+
FAB_CONFIG_FILE,
|
|
30
32
|
FAB_DATE,
|
|
33
|
+
FAB_EXCLUDE_PATTERNS,
|
|
31
34
|
FAB_HASH_TRUNCATION,
|
|
35
|
+
FAB_INCLUDE_PATTERNS,
|
|
32
36
|
FAB_MAX_SIZE,
|
|
33
37
|
)
|
|
34
38
|
|
|
35
|
-
from .config_utils import load as load_toml
|
|
36
39
|
from .config_utils import load_and_validate
|
|
37
40
|
from .utils import is_valid_project_name
|
|
38
41
|
|
|
@@ -112,7 +115,10 @@ def build(
|
|
|
112
115
|
)
|
|
113
116
|
|
|
114
117
|
# Build FAB
|
|
115
|
-
fab_bytes
|
|
118
|
+
fab_bytes = build_fab_from_disk(app)
|
|
119
|
+
|
|
120
|
+
# Calculate hash for filename
|
|
121
|
+
fab_hash = hashlib.sha256(fab_bytes).hexdigest()
|
|
116
122
|
|
|
117
123
|
# Get the name of the zip file
|
|
118
124
|
fab_filename = get_fab_filename(config, fab_hash)
|
|
@@ -125,11 +131,10 @@ def build(
|
|
|
125
131
|
)
|
|
126
132
|
|
|
127
133
|
|
|
128
|
-
def
|
|
129
|
-
"""Build a FAB
|
|
134
|
+
def build_fab_from_disk(app: Path) -> bytes:
|
|
135
|
+
"""Build a FAB from files on disk and return the FAB as bytes.
|
|
130
136
|
|
|
131
|
-
This function
|
|
132
|
-
bundles it into a FAB without performing additional validation.
|
|
137
|
+
This function reads files from disk and bundles them into a FAB.
|
|
133
138
|
|
|
134
139
|
Parameters
|
|
135
140
|
----------
|
|
@@ -138,18 +143,67 @@ def build_fab(app: Path) -> tuple[bytes, str, dict[str, Any]]:
|
|
|
138
143
|
|
|
139
144
|
Returns
|
|
140
145
|
-------
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
- the FAB as bytes
|
|
144
|
-
- the SHA256 hash of the FAB
|
|
145
|
-
- the project configuration (with the 'federations' field removed)
|
|
146
|
+
bytes
|
|
147
|
+
The FAB as bytes.
|
|
146
148
|
"""
|
|
147
149
|
app = app.resolve()
|
|
148
150
|
|
|
149
|
-
#
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
# Collect all files recursively (including pyproject.toml and .gitignore)
|
|
152
|
+
all_files = [f for f in app.rglob("*") if f.is_file()]
|
|
153
|
+
|
|
154
|
+
# Create dict mapping relative paths to Path objects
|
|
155
|
+
files_dict: dict[str, Union[bytes, Path]] = {
|
|
156
|
+
# Ensure consistent path separators across platforms
|
|
157
|
+
str(file_path.relative_to(app)).replace("\\", "/"): file_path
|
|
158
|
+
for file_path in all_files
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
# Build FAB from the files dict
|
|
162
|
+
return build_fab_from_files(files_dict)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def build_fab_from_files(files: dict[str, Union[bytes, Path]]) -> bytes:
|
|
166
|
+
r"""Build a FAB from in-memory files and return the FAB as bytes.
|
|
167
|
+
|
|
168
|
+
This is the core FAB building function that works with in-memory data.
|
|
169
|
+
It accepts either bytes or Path objects as file contents, applies filtering
|
|
170
|
+
rules (include/exclude patterns), and builds the FAB.
|
|
171
|
+
|
|
172
|
+
Parameters
|
|
173
|
+
----------
|
|
174
|
+
files : dict[str, Union[bytes, Path]]
|
|
175
|
+
Dictionary mapping relative file paths to their contents.
|
|
176
|
+
- Keys: Relative paths (strings)
|
|
177
|
+
- Values: Either bytes (file contents) or Path (will be read)
|
|
178
|
+
Must include "pyproject.toml" and optionally ".gitignore".
|
|
179
|
+
|
|
180
|
+
Returns
|
|
181
|
+
-------
|
|
182
|
+
bytes
|
|
183
|
+
The FAB as bytes.
|
|
184
|
+
|
|
185
|
+
Examples
|
|
186
|
+
--------
|
|
187
|
+
Build a FAB from in-memory files::
|
|
188
|
+
|
|
189
|
+
files = {
|
|
190
|
+
"pyproject.toml": b"[project]\nname = 'myapp'\n...",
|
|
191
|
+
".gitignore": b"*.pyc\n__pycache__/\n",
|
|
192
|
+
"src/client.py": Path("/path/to/client.py"),
|
|
193
|
+
"src/server.py": b"print('hello')",
|
|
194
|
+
"README.md": b"# My App\n",
|
|
195
|
+
}
|
|
196
|
+
fab_bytes = build_fab_from_files(files)
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
def to_bytes(content: Union[bytes, Path]) -> bytes:
|
|
200
|
+
return content.read_bytes() if isinstance(content, Path) else content
|
|
201
|
+
|
|
202
|
+
# Extract, load, and parse pyproject.toml
|
|
203
|
+
if FAB_CONFIG_FILE not in files:
|
|
204
|
+
raise ValueError(f"{FAB_CONFIG_FILE} not found in files")
|
|
205
|
+
pyproject_content = to_bytes(files[FAB_CONFIG_FILE])
|
|
206
|
+
config = tomli.loads(pyproject_content.decode("utf-8"))
|
|
153
207
|
|
|
154
208
|
# Remove the 'federations' field if it exists
|
|
155
209
|
if (
|
|
@@ -159,18 +213,22 @@ def build_fab(app: Path) -> tuple[bytes, str, dict[str, Any]]:
|
|
|
159
213
|
):
|
|
160
214
|
del config["tool"]["flwr"]["federations"]
|
|
161
215
|
|
|
162
|
-
#
|
|
163
|
-
|
|
216
|
+
# Extract and load .gitignore if present
|
|
217
|
+
gitignore_content = None
|
|
218
|
+
if ".gitignore" in files:
|
|
219
|
+
gitignore_content = to_bytes(files[".gitignore"])
|
|
220
|
+
|
|
221
|
+
# Get exclude and include specs
|
|
222
|
+
exclude_spec = get_fab_exclude_pathspec(gitignore_content)
|
|
223
|
+
include_spec = get_fab_include_pathspec()
|
|
164
224
|
|
|
165
|
-
#
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
for
|
|
169
|
-
if not
|
|
170
|
-
and f.suffix in FAB_ALLOWED_EXTENSIONS
|
|
171
|
-
and f.name != "pyproject.toml" # Exclude the original pyproject.toml
|
|
225
|
+
# Filter files based on include/exclude specs
|
|
226
|
+
filtered_paths = [
|
|
227
|
+
path.replace("\\", "/") # Ensure consistent path separators across platforms
|
|
228
|
+
for path in files.keys()
|
|
229
|
+
if include_spec.match_file(path) and not exclude_spec.match_file(path)
|
|
172
230
|
]
|
|
173
|
-
|
|
231
|
+
filtered_paths.sort() # Sort for deterministic output
|
|
174
232
|
|
|
175
233
|
# Create a zip file in memory
|
|
176
234
|
list_file_content = ""
|
|
@@ -178,41 +236,54 @@ def build_fab(app: Path) -> tuple[bytes, str, dict[str, Any]]:
|
|
|
178
236
|
fab_buffer = BytesIO()
|
|
179
237
|
with zipfile.ZipFile(fab_buffer, "w", zipfile.ZIP_DEFLATED) as fab_file:
|
|
180
238
|
# Add pyproject.toml
|
|
181
|
-
write_to_zip(fab_file,
|
|
239
|
+
write_to_zip(fab_file, FAB_CONFIG_FILE, tomli_w.dumps(config))
|
|
182
240
|
|
|
183
|
-
for file_path in
|
|
184
|
-
# Read the file content manually
|
|
185
|
-
file_contents = file_path.read_bytes()
|
|
241
|
+
for file_path in filtered_paths:
|
|
186
242
|
|
|
187
|
-
|
|
188
|
-
|
|
243
|
+
# Get file contents as bytes
|
|
244
|
+
file_content = to_bytes(files[file_path])
|
|
189
245
|
|
|
190
|
-
#
|
|
191
|
-
|
|
192
|
-
file_size_bits = len(file_contents) * 8 # size in bits
|
|
193
|
-
list_file_content += f"{archive_path},{sha256_hash},{file_size_bits}\n"
|
|
246
|
+
# Write file to FAB
|
|
247
|
+
write_to_zip(fab_file, file_path, file_content)
|
|
194
248
|
|
|
195
|
-
|
|
249
|
+
# Calculate file info for CONTENT manifest
|
|
250
|
+
sha256_hash = hashlib.sha256(file_content).hexdigest()
|
|
251
|
+
file_size_bits = len(file_content) * 8 # size in bits
|
|
252
|
+
list_file_content += f"{file_path},{sha256_hash},{file_size_bits}\n"
|
|
253
|
+
|
|
254
|
+
# Add CONTENT manifest to the zip file
|
|
196
255
|
write_to_zip(fab_file, ".info/CONTENT", list_file_content)
|
|
197
256
|
|
|
198
257
|
fab_bytes = fab_buffer.getvalue()
|
|
258
|
+
|
|
259
|
+
# Validate FAB size
|
|
199
260
|
if len(fab_bytes) > FAB_MAX_SIZE:
|
|
200
261
|
raise ValueError(
|
|
201
|
-
f"FAB size exceeds maximum allowed size of {FAB_MAX_SIZE:,} bytes."
|
|
262
|
+
f"FAB size exceeds maximum allowed size of {FAB_MAX_SIZE:,} bytes. "
|
|
202
263
|
"To reduce the package size, consider ignoring unnecessary files "
|
|
203
264
|
"via your `.gitignore` file or excluding them from the build."
|
|
204
265
|
)
|
|
205
266
|
|
|
206
|
-
|
|
267
|
+
return fab_bytes
|
|
207
268
|
|
|
208
|
-
return fab_bytes, fab_hash, config
|
|
209
269
|
|
|
270
|
+
def build_pathspec(patterns: Iterable[str]) -> pathspec.PathSpec:
|
|
271
|
+
"""Build a PathSpec from a list of patterns."""
|
|
272
|
+
return pathspec.PathSpec.from_lines("gitwildmatch", patterns)
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def get_fab_include_pathspec() -> pathspec.PathSpec:
|
|
276
|
+
"""Get the PathSpec for files to include in a FAB."""
|
|
277
|
+
return build_pathspec(FAB_INCLUDE_PATTERNS)
|
|
210
278
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
279
|
+
|
|
280
|
+
def get_fab_exclude_pathspec(gitignore_content: Optional[bytes]) -> pathspec.PathSpec:
|
|
281
|
+
"""Get the PathSpec for files to exclude from a FAB.
|
|
282
|
+
|
|
283
|
+
If gitignore_content is provided, its patterns will be combined with the default
|
|
284
|
+
exclude patterns.
|
|
285
|
+
"""
|
|
286
|
+
patterns = list(FAB_EXCLUDE_PATTERNS)
|
|
287
|
+
if gitignore_content:
|
|
288
|
+
patterns += gitignore_content.decode("UTF-8").splitlines()
|
|
218
289
|
return pathspec.PathSpec.from_lines("gitwildmatch", patterns)
|
|
@@ -19,22 +19,23 @@ from typing import Any, Callable, Union
|
|
|
19
19
|
|
|
20
20
|
import grpc
|
|
21
21
|
|
|
22
|
-
from flwr.common.auth_plugin import CliAuthPlugin
|
|
23
22
|
from flwr.proto.control_pb2 import ( # pylint: disable=E0611
|
|
24
23
|
StartRunRequest,
|
|
25
24
|
StreamLogsRequest,
|
|
26
25
|
)
|
|
27
26
|
|
|
27
|
+
from .auth_plugin import CliAuthPlugin
|
|
28
|
+
|
|
28
29
|
Request = Union[
|
|
29
30
|
StartRunRequest,
|
|
30
31
|
StreamLogsRequest,
|
|
31
32
|
]
|
|
32
33
|
|
|
33
34
|
|
|
34
|
-
class
|
|
35
|
+
class CliAccountAuthInterceptor(
|
|
35
36
|
grpc.UnaryUnaryClientInterceptor, grpc.UnaryStreamClientInterceptor # type: ignore
|
|
36
37
|
):
|
|
37
|
-
"""CLI interceptor for
|
|
38
|
+
"""CLI interceptor for account authentication."""
|
|
38
39
|
|
|
39
40
|
def __init__(self, auth_plugin: CliAuthPlugin):
|
|
40
41
|
self.auth_plugin = auth_plugin
|
|
@@ -69,7 +70,7 @@ class CliUserAuthInterceptor(
|
|
|
69
70
|
client_call_details: grpc.ClientCallDetails,
|
|
70
71
|
request: Request,
|
|
71
72
|
) -> grpc.Call:
|
|
72
|
-
"""Intercept a unary-unary call for
|
|
73
|
+
"""Intercept a unary-unary call for account authentication.
|
|
73
74
|
|
|
74
75
|
This method intercepts a unary-unary RPC call initiated from the CLI and adds
|
|
75
76
|
the required authentication tokens to the RPC metadata.
|
|
@@ -82,7 +83,7 @@ class CliUserAuthInterceptor(
|
|
|
82
83
|
client_call_details: grpc.ClientCallDetails,
|
|
83
84
|
request: Request,
|
|
84
85
|
) -> grpc.Call:
|
|
85
|
-
"""Intercept a unary-stream call for
|
|
86
|
+
"""Intercept a unary-stream call for account authentication.
|
|
86
87
|
|
|
87
88
|
This method intercepts a unary-stream RPC call initiated from the CLI and adds
|
|
88
89
|
the required authentication tokens to the RPC metadata.
|
|
@@ -35,7 +35,7 @@ from flwr.common.logger import log as logger
|
|
|
35
35
|
from flwr.proto.control_pb2 import StreamLogsRequest # pylint: disable=E0611
|
|
36
36
|
from flwr.proto.control_pb2_grpc import ControlStub
|
|
37
37
|
|
|
38
|
-
from .utils import flwr_cli_grpc_exc_handler, init_channel,
|
|
38
|
+
from .utils import flwr_cli_grpc_exc_handler, init_channel, load_cli_auth_plugin
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
class AllLogsRetrieved(BaseException):
|
|
@@ -186,7 +186,7 @@ def _log_with_control_api(
|
|
|
186
186
|
run_id: int,
|
|
187
187
|
stream: bool,
|
|
188
188
|
) -> None:
|
|
189
|
-
auth_plugin =
|
|
189
|
+
auth_plugin = load_cli_auth_plugin(app, federation, federation_config)
|
|
190
190
|
channel = init_channel(app, federation_config, auth_plugin)
|
|
191
191
|
|
|
192
192
|
if stream:
|