flwr 1.24.0__tar.gz → 1.25.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.24.0 → flwr-1.25.0}/PKG-INFO +2 -4
- {flwr-1.24.0 → flwr-1.25.0}/README.md +1 -3
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/app_cmd/review.py +13 -3
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/federation/show.py +4 -3
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/ls.py +44 -3
- flwr-1.25.0/py/flwr/cli/new/new.py +263 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/run/run.py +12 -17
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/run_utils.py +23 -5
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/stop.py +1 -1
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/supernode/ls.py +10 -5
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/utils.py +0 -137
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/grpc_adapter_client/connection.py +2 -2
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/grpc_rere_client/connection.py +6 -3
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/rest_client/connection.py +6 -4
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/serde.py +6 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/typing.py +6 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/fleet_pb2.py +10 -10
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/fleet_pb2.pyi +5 -1
- flwr-1.25.0/py/flwr/proto/run_pb2.py +65 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/run_pb2.pyi +10 -1
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/app.py +1 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/message_handler/message_handler.py +41 -2
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/linkstate/in_memory_linkstate.py +34 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/linkstate/linkstate.py +32 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/linkstate/sqlite_linkstate.py +60 -3
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/constant.py +3 -0
- flwr-1.25.0/py/flwr/supercore/utils.py +242 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/servicer/control/control_grpc.py +2 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/servicer/control/control_servicer.py +88 -5
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supernode/nodestate/in_memory_nodestate.py +62 -1
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supernode/nodestate/nodestate.py +45 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supernode/servicer/clientappio/clientappio_servicer.py +7 -1
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supernode/start_client_internal.py +7 -4
- {flwr-1.24.0 → flwr-1.25.0}/pyproject.toml +1 -1
- flwr-1.24.0/py/flwr/cli/new/new.py +0 -454
- flwr-1.24.0/py/flwr/cli/new/templates/__init__.py +0 -15
- flwr-1.24.0/py/flwr/cli/new/templates/app/.gitignore.tpl +0 -163
- flwr-1.24.0/py/flwr/cli/new/templates/app/LICENSE.tpl +0 -202
- flwr-1.24.0/py/flwr/cli/new/templates/app/README.baseline.md.tpl +0 -127
- flwr-1.24.0/py/flwr/cli/new/templates/app/README.flowertune.md.tpl +0 -68
- flwr-1.24.0/py/flwr/cli/new/templates/app/README.md.tpl +0 -37
- flwr-1.24.0/py/flwr/cli/new/templates/app/__init__.py +0 -15
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/__init__.baseline.py.tpl +0 -1
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/__init__.py +0 -15
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -1
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/__init__.pytorch_legacy_api.py.tpl +0 -1
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/client.baseline.py.tpl +0 -75
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/client.huggingface.py.tpl +0 -93
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/client.jax.py.tpl +0 -71
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/client.mlx.py.tpl +0 -102
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -46
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -80
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/client.pytorch_legacy_api.py.tpl +0 -55
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/client.sklearn.py.tpl +0 -108
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -82
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/client.xgboost.py.tpl +0 -110
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/dataset.baseline.py.tpl +0 -36
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py +0 -15
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +0 -92
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +0 -87
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +0 -56
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +0 -73
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +0 -78
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/model.baseline.py.tpl +0 -66
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/server.baseline.py.tpl +0 -43
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/server.huggingface.py.tpl +0 -42
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/server.jax.py.tpl +0 -39
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/server.mlx.py.tpl +0 -41
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -38
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -41
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/server.pytorch_legacy_api.py.tpl +0 -31
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/server.sklearn.py.tpl +0 -44
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -38
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/server.xgboost.py.tpl +0 -56
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/strategy.baseline.py.tpl +0 -1
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/task.huggingface.py.tpl +0 -98
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/task.jax.py.tpl +0 -57
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/task.mlx.py.tpl +0 -102
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/task.numpy.py.tpl +0 -7
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -99
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/task.pytorch_legacy_api.py.tpl +0 -111
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/task.sklearn.py.tpl +0 -67
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +0 -52
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/task.xgboost.py.tpl +0 -67
- flwr-1.24.0/py/flwr/cli/new/templates/app/code/utils.baseline.py.tpl +0 -1
- flwr-1.24.0/py/flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +0 -146
- flwr-1.24.0/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +0 -80
- flwr-1.24.0/py/flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +0 -65
- flwr-1.24.0/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl +0 -52
- flwr-1.24.0/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +0 -56
- flwr-1.24.0/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +0 -49
- flwr-1.24.0/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +0 -53
- flwr-1.24.0/py/flwr/cli/new/templates/app/pyproject.pytorch_legacy_api.toml.tpl +0 -53
- flwr-1.24.0/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +0 -52
- flwr-1.24.0/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +0 -53
- flwr-1.24.0/py/flwr/cli/new/templates/app/pyproject.xgboost.toml.tpl +0 -61
- flwr-1.24.0/py/flwr/proto/run_pb2.py +0 -65
- flwr-1.24.0/py/flwr/supercore/utils.py +0 -52
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/app/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/app/error.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/app/exception.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/app/metadata.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/app.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/app_cmd/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/app_cmd/publish.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/auth_plugin/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/auth_plugin/auth_plugin.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/auth_plugin/noop_auth_plugin.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/auth_plugin/oidc_cli_plugin.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/build.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/cli_account_auth_interceptor.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/config_utils.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/constant.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/example.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/federation/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/federation/ls.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/install.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/log.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/login/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/login/login.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/new/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/pull.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/run/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/supernode/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/supernode/register.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/cli/supernode/unregister.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/client.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/dpfedavg_numpy_client.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/grpc_adapter_client/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/grpc_rere_client/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/grpc_rere_client/grpc_adapter.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/grpc_rere_client/node_auth_client_interceptor.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/message_handler/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/message_handler/message_handler.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/mod/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/mod/centraldp_mods.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/mod/comms_mods.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/mod/localdp_mod.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/mod/utils.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/numpy_client.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/rest_client/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/run_info_store.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/client/typing.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/clientapp/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/clientapp/client_app.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/clientapp/mod/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/clientapp/mod/centraldp_mods.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/clientapp/mod/localdp_mod.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/clientapp/typing.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/clientapp/utils.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/address.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/args.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/config.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/constant.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/context.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/date.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/differential_privacy.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/differential_privacy_constants.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/dp.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/event_log_plugin/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/event_log_plugin/event_log_plugin.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/exit/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/exit/exit.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/exit/exit_code.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/exit/exit_handler.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/exit/signal_handler.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/inflatable.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/inflatable_protobuf_utils.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/inflatable_utils.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/logger.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/message.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/object_ref.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/parameter.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/pyproject.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/record/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/record/array.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/record/arraychunk.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/record/arrayrecord.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/record/configrecord.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/record/conversion_utils.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/record/metricrecord.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/record/recorddict.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/record/typeddict.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/recorddict_compat.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/retry_invoker.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/secure_aggregation/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/secure_aggregation/quantization.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/serde_utils.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/telemetry.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/common/version.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/compat/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/compat/client/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/compat/client/app.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/compat/client/grpc_client/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/compat/client/grpc_client/connection.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/compat/common/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/compat/server/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/compat/server/app.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/compat/simulation/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/appio_pb2.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/appio_pb2.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/appio_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/appio_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/clientappio_pb2.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/clientappio_pb2.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/clientappio_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/clientappio_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/control_pb2.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/control_pb2.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/control_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/control_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/error_pb2.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/error_pb2.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/error_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/error_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/fab_pb2.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/fab_pb2.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/fab_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/fab_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/federation_pb2.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/federation_pb2.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/federation_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/federation_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/fleet_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/grpcadapter_pb2.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/grpcadapter_pb2.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/grpcadapter_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/grpcadapter_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/heartbeat_pb2.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/heartbeat_pb2.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/heartbeat_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/heartbeat_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/log_pb2.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/log_pb2.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/log_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/log_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/message_pb2.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/message_pb2.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/message_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/message_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/node_pb2.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/node_pb2.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/node_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/node_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/recorddict_pb2.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/recorddict_pb2.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/recorddict_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/recorddict_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/run_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/run_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/serverappio_pb2.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/serverappio_pb2.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/serverappio_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/serverappio_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/simulationio_pb2.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/simulationio_pb2.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/simulationio_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/simulationio_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/transport_pb2.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/transport_pb2.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/transport_pb2_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/py.typed +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/client_manager.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/client_proxy.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/compat/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/compat/app.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/compat/app_utils.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/compat/grid_client_proxy.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/compat/legacy_context.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/criterion.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/fleet_event_log_interceptor.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/grid/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/grid/grid.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/grid/grpc_grid.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/grid/inmemory_grid.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/history.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/run_serverapp.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/server.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/server_app.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/server_config.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/serverapp/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/serverapp/app.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/serverapp_components.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/aggregate.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/bulyan.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/fedadagrad.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/fedadam.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/fedavg.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/fedavg_android.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/fedavgm.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/fedmedian.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/fedopt.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/fedprox.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/fedyogi.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/krum.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/qfedavg.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/strategy/strategy.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/grpc_rere/node_auth_server_interceptor.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/fleet/vce/vce_api.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/linkstate/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/linkstate/linkstate_factory.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/linkstate/utils.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/serverappio/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/serverappio/serverappio_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/serverappio/serverappio_servicer.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/simulation/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/simulation/simulationio_grpc.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/simulation/simulationio_servicer.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/superlink/utils.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/typing.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/utils/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/utils/tensorboard.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/utils/validator.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/workflow/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/workflow/constant.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/workflow/default_workflows.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/exception.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/bulyan.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/dp_adaptive_clipping.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/dp_fixed_clipping.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/fedadagrad.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/fedadam.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/fedavg.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/fedavgm.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/fedmedian.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/fedopt.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/fedprox.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/fedtrimmedavg.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/fedxgb_bagging.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/fedxgb_cyclic.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/fedyogi.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/krum.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/multikrum.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/qfedavg.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/result.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/strategy.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/serverapp/strategy/strategy_utils.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/simulation/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/simulation/app.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/simulation/legacy_app.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/simulation/ray_transport/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/simulation/ray_transport/utils.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/simulation/run_simulation.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/simulation/simulationio_connection.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/app_utils.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/cli/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/cli/flower_superexec.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/corestate/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/corestate/corestate.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/corestate/in_memory_corestate.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/corestate/sqlite_corestate.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/ffs/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/ffs/disk_ffs.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/ffs/ffs.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/ffs/ffs_factory.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/grpc_health/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/grpc_health/health_server.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/grpc_health/simple_health_servicer.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/heartbeat.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/license_plugin/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/license_plugin/license_plugin.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/object_store/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/object_store/in_memory_object_store.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/object_store/object_store.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/object_store/object_store_factory.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/object_store/sqlite_object_store.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/primitives/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/primitives/asymmetric.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/primitives/asymmetric_ed25519.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/sqlite_mixin.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/superexec/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/superexec/plugin/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/superexec/plugin/base_exec_plugin.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/superexec/plugin/clientapp_exec_plugin.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/superexec/plugin/exec_plugin.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/superexec/plugin/serverapp_exec_plugin.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/superexec/plugin/simulation_exec_plugin.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supercore/superexec/run_superexec.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/artifact_provider/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/artifact_provider/artifact_provider.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/auth_plugin/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/auth_plugin/auth_plugin.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/auth_plugin/noop_auth_plugin.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/federation/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/federation/federation_manager.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/federation/noop_federation_manager.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/servicer/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/servicer/control/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/servicer/control/control_account_auth_interceptor.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/servicer/control/control_event_log_interceptor.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/superlink/servicer/control/control_license_interceptor.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supernode/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supernode/cli/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supernode/cli/flower_supernode.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supernode/cli/flwr_clientapp.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supernode/nodestate/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supernode/nodestate/nodestate_factory.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supernode/runtime/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supernode/runtime/run_clientapp.py +0 -0
- {flwr-1.24.0 → flwr-1.25.0}/py/flwr/supernode/servicer/__init__.py +0 -0
- {flwr-1.24.0 → flwr-1.25.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.25.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
|
|
@@ -180,7 +180,7 @@ Quickstart examples:
|
|
|
180
180
|
- [Quickstart (Pandas)](https://github.com/adap/flower/tree/main/examples/quickstart-pandas)
|
|
181
181
|
- [Quickstart (JAX)](https://github.com/adap/flower/tree/main/examples/quickstart-jax)
|
|
182
182
|
- [Quickstart (MONAI)](https://github.com/adap/flower/tree/main/examples/quickstart-monai)
|
|
183
|
-
- [Quickstart (scikit-learn)](https://github.com/adap/flower/tree/main/examples/sklearn
|
|
183
|
+
- [Quickstart (scikit-learn)](https://github.com/adap/flower/tree/main/examples/quickstart-sklearn)
|
|
184
184
|
- [Quickstart (Android [TFLite])](https://github.com/adap/flower/tree/main/examples/android)
|
|
185
185
|
- [Quickstart (iOS [CoreML])](https://github.com/adap/flower/tree/main/examples/ios)
|
|
186
186
|
- [Quickstart (MLX)](https://github.com/adap/flower/tree/main/examples/quickstart-mlx)
|
|
@@ -197,10 +197,8 @@ Other [examples](https://github.com/adap/flower/tree/main/examples):
|
|
|
197
197
|
- [Advanced Flower with TensorFlow/Keras](https://github.com/adap/flower/tree/main/examples/advanced-tensorflow)
|
|
198
198
|
- [Advanced Flower with PyTorch](https://github.com/adap/flower/tree/main/examples/advanced-pytorch)
|
|
199
199
|
- [Comprehensive Flower+XGBoost](https://github.com/adap/flower/tree/main/examples/xgboost-comprehensive)
|
|
200
|
-
- [Flower through Docker Compose and with Grafana dashboard](https://github.com/adap/flower/tree/main/examples/flower-via-docker-compose)
|
|
201
200
|
- [Flower with KaplanMeierFitter from the lifelines library](https://github.com/adap/flower/tree/main/examples/federated-kaplan-meier-fitter)
|
|
202
201
|
- [Sample Level Privacy with Opacus](https://github.com/adap/flower/tree/main/examples/opacus)
|
|
203
|
-
- [Sample Level Privacy with TensorFlow-Privacy](https://github.com/adap/flower/tree/main/examples/tensorflow-privacy)
|
|
204
202
|
- [Flower with a Tabular Dataset](https://github.com/adap/flower/tree/main/examples/fl-tabular)
|
|
205
203
|
|
|
206
204
|
## Community
|
|
@@ -124,7 +124,7 @@ Quickstart examples:
|
|
|
124
124
|
- [Quickstart (Pandas)](https://github.com/adap/flower/tree/main/examples/quickstart-pandas)
|
|
125
125
|
- [Quickstart (JAX)](https://github.com/adap/flower/tree/main/examples/quickstart-jax)
|
|
126
126
|
- [Quickstart (MONAI)](https://github.com/adap/flower/tree/main/examples/quickstart-monai)
|
|
127
|
-
- [Quickstart (scikit-learn)](https://github.com/adap/flower/tree/main/examples/sklearn
|
|
127
|
+
- [Quickstart (scikit-learn)](https://github.com/adap/flower/tree/main/examples/quickstart-sklearn)
|
|
128
128
|
- [Quickstart (Android [TFLite])](https://github.com/adap/flower/tree/main/examples/android)
|
|
129
129
|
- [Quickstart (iOS [CoreML])](https://github.com/adap/flower/tree/main/examples/ios)
|
|
130
130
|
- [Quickstart (MLX)](https://github.com/adap/flower/tree/main/examples/quickstart-mlx)
|
|
@@ -141,10 +141,8 @@ Other [examples](https://github.com/adap/flower/tree/main/examples):
|
|
|
141
141
|
- [Advanced Flower with TensorFlow/Keras](https://github.com/adap/flower/tree/main/examples/advanced-tensorflow)
|
|
142
142
|
- [Advanced Flower with PyTorch](https://github.com/adap/flower/tree/main/examples/advanced-pytorch)
|
|
143
143
|
- [Comprehensive Flower+XGBoost](https://github.com/adap/flower/tree/main/examples/xgboost-comprehensive)
|
|
144
|
-
- [Flower through Docker Compose and with Grafana dashboard](https://github.com/adap/flower/tree/main/examples/flower-via-docker-compose)
|
|
145
144
|
- [Flower with KaplanMeierFitter from the lifelines library](https://github.com/adap/flower/tree/main/examples/federated-kaplan-meier-fitter)
|
|
146
145
|
- [Sample Level Privacy with Opacus](https://github.com/adap/flower/tree/main/examples/opacus)
|
|
147
|
-
- [Sample Level Privacy with TensorFlow-Privacy](https://github.com/adap/flower/tree/main/examples/tensorflow-privacy)
|
|
148
146
|
- [Flower with a Tabular Dataset](https://github.com/adap/flower/tree/main/examples/fl-tabular)
|
|
149
147
|
|
|
150
148
|
## Community
|
|
@@ -36,6 +36,7 @@ from flwr.supercore.primitives.asymmetric_ed25519 import (
|
|
|
36
36
|
load_private_key,
|
|
37
37
|
sign_message,
|
|
38
38
|
)
|
|
39
|
+
from flwr.supercore.utils import parse_app_spec, request_download_link
|
|
39
40
|
|
|
40
41
|
from ..auth_plugin.oidc_cli_plugin import OidcCliPlugin
|
|
41
42
|
from ..config_utils import (
|
|
@@ -45,7 +46,7 @@ from ..config_utils import (
|
|
|
45
46
|
)
|
|
46
47
|
from ..constant import FEDERATION_CONFIG_HELP_MESSAGE
|
|
47
48
|
from ..install import install_from_fab
|
|
48
|
-
from ..utils import load_cli_auth_plugin
|
|
49
|
+
from ..utils import load_cli_auth_plugin
|
|
49
50
|
|
|
50
51
|
TRY_AGAIN_MESSAGE = "Please try again or press CTRL+C to abort.\n"
|
|
51
52
|
|
|
@@ -104,12 +105,21 @@ def review(
|
|
|
104
105
|
token = auth_plugin.access_token
|
|
105
106
|
|
|
106
107
|
# Validate app version and ID format
|
|
107
|
-
|
|
108
|
+
try:
|
|
109
|
+
app_id, app_version = parse_app_spec(app_spec)
|
|
110
|
+
except ValueError as e:
|
|
111
|
+
typer.secho(f"❌ {e}", fg=typer.colors.RED, err=True)
|
|
112
|
+
raise typer.Exit(code=1) from e
|
|
108
113
|
|
|
109
114
|
# Download FAB
|
|
110
115
|
typer.secho("Downloading FAB... ", fg=typer.colors.BLUE)
|
|
111
116
|
url = f"{PLATFORM_API_URL}/hub/fetch-fab"
|
|
112
|
-
|
|
117
|
+
try:
|
|
118
|
+
presigned_url, _ = request_download_link(app_id, app_version, url, "fab_url")
|
|
119
|
+
except ValueError as e:
|
|
120
|
+
typer.secho(f"❌ {e}", fg=typer.colors.RED, err=True)
|
|
121
|
+
raise typer.Exit(code=1) from e
|
|
122
|
+
|
|
113
123
|
fab_bytes = _download_fab(presigned_url)
|
|
114
124
|
|
|
115
125
|
# Unpack FAB
|
|
@@ -41,6 +41,7 @@ from flwr.proto.control_pb2 import ( # pylint: disable=E0611
|
|
|
41
41
|
from flwr.proto.control_pb2_grpc import ControlStub
|
|
42
42
|
from flwr.proto.node_pb2 import NodeInfo # pylint: disable=E0611
|
|
43
43
|
from flwr.supercore.constant import NOOP_FEDERATION
|
|
44
|
+
from flwr.supercore.utils import humanize_duration
|
|
44
45
|
|
|
45
46
|
from ..run_utils import RunRow, format_runs
|
|
46
47
|
from ..utils import flwr_cli_grpc_exc_handler, init_channel, load_cli_auth_plugin
|
|
@@ -262,7 +263,7 @@ def _to_runs_table(run_list: list[RunRow]) -> Table:
|
|
|
262
263
|
f"[bold]{row.run_id}[/bold]",
|
|
263
264
|
f"@{row.fab_id}=={row.fab_version}",
|
|
264
265
|
f"[{status_style}]{row.status_text}[/{status_style}]",
|
|
265
|
-
row.elapsed,
|
|
266
|
+
f"{humanize_duration(row.elapsed)}",
|
|
266
267
|
)
|
|
267
268
|
table.add_row(*formatted_row)
|
|
268
269
|
|
|
@@ -298,7 +299,7 @@ def _to_json(
|
|
|
298
299
|
for node in nodes:
|
|
299
300
|
nodes_list.append(
|
|
300
301
|
{
|
|
301
|
-
"node_id": node.node_id,
|
|
302
|
+
"node_id": f"{node.node_id}",
|
|
302
303
|
"owner": node.owner_name,
|
|
303
304
|
"status": node.status,
|
|
304
305
|
}
|
|
@@ -307,7 +308,7 @@ def _to_json(
|
|
|
307
308
|
for run in runs:
|
|
308
309
|
runs_list.append(
|
|
309
310
|
{
|
|
310
|
-
"run_id": run.run_id,
|
|
311
|
+
"run_id": f"{run.run_id}",
|
|
311
312
|
"app": f"@{run.fab_id}=={run.fab_version}",
|
|
312
313
|
"status": run.status_text,
|
|
313
314
|
"elapsed": run.elapsed,
|
|
@@ -40,6 +40,7 @@ from flwr.proto.control_pb2 import ( # pylint: disable=E0611
|
|
|
40
40
|
ListRunsResponse,
|
|
41
41
|
)
|
|
42
42
|
from flwr.proto.control_pb2_grpc import ControlStub
|
|
43
|
+
from flwr.supercore.utils import humanize_bytes, humanize_duration
|
|
43
44
|
|
|
44
45
|
from .run_utils import RunRow, format_runs
|
|
45
46
|
from .utils import flwr_cli_grpc_exc_handler, init_channel, load_cli_auth_plugin
|
|
@@ -231,7 +232,7 @@ def _to_table(run_list: list[RunRow]) -> Table:
|
|
|
231
232
|
row.federation,
|
|
232
233
|
f"@{row.fab_id}=={row.fab_version}",
|
|
233
234
|
f"[{status_style}]{row.status_text}[/{status_style}]",
|
|
234
|
-
row.elapsed,
|
|
235
|
+
humanize_duration(row.elapsed),
|
|
235
236
|
status_changed_at,
|
|
236
237
|
)
|
|
237
238
|
table.add_row(*formatted_row)
|
|
@@ -265,11 +266,39 @@ def _to_detail_table(run: RunRow) -> Table:
|
|
|
265
266
|
table.add_row("App", f"@{run.fab_id}=={run.fab_version}")
|
|
266
267
|
table.add_row("FAB Hash", f"{run.fab_hash[:8]}...{run.fab_hash[-8:]}")
|
|
267
268
|
table.add_row("Status", f"[{status_style}]{run.status_text}[/{status_style}]")
|
|
268
|
-
table.add_row("Elapsed", f"[blue]{run.elapsed}[/blue]")
|
|
269
|
+
table.add_row("Elapsed", f"[blue]{humanize_duration(run.elapsed)}[/blue]")
|
|
269
270
|
table.add_row("Pending At", run.pending_at)
|
|
270
271
|
table.add_row("Starting At", run.starting_at)
|
|
271
272
|
table.add_row("Running At", run.running_at)
|
|
272
273
|
table.add_row("Finished At", run.finished_at)
|
|
274
|
+
table.add_row(
|
|
275
|
+
"Network traffic (inbound)",
|
|
276
|
+
f"[blue]{humanize_bytes(run.network_traffic_inbound)}[/blue]",
|
|
277
|
+
)
|
|
278
|
+
table.add_row(
|
|
279
|
+
"Network traffic (outbound)",
|
|
280
|
+
f"[blue]{humanize_bytes(run.network_traffic_outbound)}[/blue]",
|
|
281
|
+
)
|
|
282
|
+
table.add_row(
|
|
283
|
+
"Network Traffic (total)",
|
|
284
|
+
"[blue]"
|
|
285
|
+
f"{humanize_bytes(run.network_traffic_inbound + run.network_traffic_outbound)}"
|
|
286
|
+
"[/blue]",
|
|
287
|
+
)
|
|
288
|
+
table.add_row(
|
|
289
|
+
"Compute Time (ServerApp)",
|
|
290
|
+
f"[blue]{humanize_duration(run.compute_time_serverapp)}[/blue]",
|
|
291
|
+
)
|
|
292
|
+
table.add_row(
|
|
293
|
+
"Compute Time (ClientApp)",
|
|
294
|
+
f"[blue]{humanize_duration(run.compute_time_clientapp)}[/blue]",
|
|
295
|
+
)
|
|
296
|
+
table.add_row(
|
|
297
|
+
"Compute Time (total)",
|
|
298
|
+
"[blue]"
|
|
299
|
+
f"{humanize_duration(run.compute_time_serverapp + run.compute_time_clientapp)}"
|
|
300
|
+
"[/blue]",
|
|
301
|
+
)
|
|
273
302
|
|
|
274
303
|
return table
|
|
275
304
|
|
|
@@ -291,7 +320,7 @@ def _to_json(run_list: list[RunRow]) -> str:
|
|
|
291
320
|
for row in run_list:
|
|
292
321
|
runs_list.append(
|
|
293
322
|
{
|
|
294
|
-
"run-id": row.run_id,
|
|
323
|
+
"run-id": f"{row.run_id}",
|
|
295
324
|
"federation": row.federation,
|
|
296
325
|
"fab-id": row.fab_id,
|
|
297
326
|
"fab-name": row.fab_id.split("/")[-1],
|
|
@@ -303,6 +332,18 @@ def _to_json(run_list: list[RunRow]) -> str:
|
|
|
303
332
|
"starting-at": row.starting_at,
|
|
304
333
|
"running-at": row.running_at,
|
|
305
334
|
"finished-at": row.finished_at,
|
|
335
|
+
"network-traffic": {
|
|
336
|
+
"inbound-bytes": row.network_traffic_inbound,
|
|
337
|
+
"outbound-bytes": row.network_traffic_outbound,
|
|
338
|
+
"total-bytes": row.network_traffic_inbound
|
|
339
|
+
+ row.network_traffic_outbound,
|
|
340
|
+
},
|
|
341
|
+
"compute-time": {
|
|
342
|
+
"serverapp-seconds": row.compute_time_serverapp,
|
|
343
|
+
"clientapp-seconds": row.compute_time_clientapp,
|
|
344
|
+
"total-seconds": row.compute_time_serverapp
|
|
345
|
+
+ row.compute_time_clientapp,
|
|
346
|
+
},
|
|
306
347
|
}
|
|
307
348
|
)
|
|
308
349
|
|
|
@@ -0,0 +1,263 @@
|
|
|
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
|
+
"""Flower command line interface `new` command."""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
import io
|
|
19
|
+
import zipfile
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
from typing import Annotated, cast
|
|
22
|
+
|
|
23
|
+
import requests
|
|
24
|
+
import typer
|
|
25
|
+
|
|
26
|
+
from flwr.supercore.constant import PLATFORM_API_URL
|
|
27
|
+
from flwr.supercore.utils import parse_app_spec, request_download_link
|
|
28
|
+
|
|
29
|
+
from ..utils import prompt_options, prompt_text
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# pylint: disable=too-many-locals,too-many-branches,too-many-statements
|
|
33
|
+
def new(
|
|
34
|
+
app_spec: Annotated[
|
|
35
|
+
str | None,
|
|
36
|
+
typer.Argument(
|
|
37
|
+
help="Flower app specifier. Use the format "
|
|
38
|
+
"'@account_name/app_name' or '@account_name/app_name==x.y.z'. "
|
|
39
|
+
"Version is optional (defaults to latest)."
|
|
40
|
+
),
|
|
41
|
+
] = None,
|
|
42
|
+
framework: Annotated[
|
|
43
|
+
str | None,
|
|
44
|
+
typer.Option(case_sensitive=False, help="Deprecated. The ML framework to use"),
|
|
45
|
+
] = None,
|
|
46
|
+
username: Annotated[
|
|
47
|
+
str | None,
|
|
48
|
+
typer.Option(
|
|
49
|
+
case_sensitive=False, help="Deprecated. The Flower username of the author"
|
|
50
|
+
),
|
|
51
|
+
] = None,
|
|
52
|
+
) -> None:
|
|
53
|
+
"""Create new Flower App."""
|
|
54
|
+
if framework is not None or username is not None:
|
|
55
|
+
typer.secho(
|
|
56
|
+
"❌ The --framework and --username options are deprecated and will be "
|
|
57
|
+
"removed in future versions of Flower. Please provide an app specifier "
|
|
58
|
+
"after `flwr new` instead, e.g., '@account_name/app_name' or "
|
|
59
|
+
"'@account_name/app_name==x.y.z'.",
|
|
60
|
+
fg=typer.colors.RED,
|
|
61
|
+
bold=True,
|
|
62
|
+
err=True,
|
|
63
|
+
)
|
|
64
|
+
raise typer.Exit(code=1)
|
|
65
|
+
|
|
66
|
+
if app_spec is None:
|
|
67
|
+
# Fetch recommended apps
|
|
68
|
+
print(
|
|
69
|
+
typer.style(
|
|
70
|
+
"\n🌸 Fetching recommended apps...",
|
|
71
|
+
fg=typer.colors.GREEN,
|
|
72
|
+
bold=True,
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
apps = fetch_recommended_apps()
|
|
76
|
+
|
|
77
|
+
if not apps:
|
|
78
|
+
typer.secho(
|
|
79
|
+
"No recommended apps found. Please provide an app specifier manually.",
|
|
80
|
+
fg=typer.colors.YELLOW,
|
|
81
|
+
)
|
|
82
|
+
app_spec = prompt_text("Please provide the app specifier")
|
|
83
|
+
else:
|
|
84
|
+
# Extract app_ids and show selection menu
|
|
85
|
+
app_ids = [app["app_id"] for app in apps]
|
|
86
|
+
app_spec = prompt_options(
|
|
87
|
+
"Select a Flower App to create by entering "
|
|
88
|
+
"the number from the list below:",
|
|
89
|
+
app_ids,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# Download remote app
|
|
93
|
+
download_remote_app_via_api(app_spec)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def print_success_prompt(package_name: str) -> None:
|
|
97
|
+
"""Print styled setup instructions for running a new Flower App after creation."""
|
|
98
|
+
prompt = typer.style(
|
|
99
|
+
"🎊 Flower App creation successful.\n\n"
|
|
100
|
+
"To run your Flower App, first install its dependencies:\n\n",
|
|
101
|
+
fg=typer.colors.GREEN,
|
|
102
|
+
bold=True,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
prompt += typer.style(
|
|
106
|
+
f" cd {package_name} && pip install -e .\n\n",
|
|
107
|
+
fg=typer.colors.BRIGHT_CYAN,
|
|
108
|
+
bold=True,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
prompt += typer.style(
|
|
112
|
+
"then, run the app:\n\n ",
|
|
113
|
+
fg=typer.colors.GREEN,
|
|
114
|
+
bold=True,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
prompt += typer.style(
|
|
118
|
+
"\tflwr run .\n\n",
|
|
119
|
+
fg=typer.colors.BRIGHT_CYAN,
|
|
120
|
+
bold=True,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
prompt += typer.style(
|
|
124
|
+
"💡 Check the README in your app directory to learn how to\n"
|
|
125
|
+
"customize it and how to run it using the Deployment Runtime.\n",
|
|
126
|
+
fg=typer.colors.GREEN,
|
|
127
|
+
bold=True,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
print(prompt)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def fetch_recommended_apps() -> list[dict[str, str]]:
|
|
134
|
+
"""Fetch recommended apps from Platform API."""
|
|
135
|
+
url = f"{PLATFORM_API_URL}/hub/apps?tag=recommended"
|
|
136
|
+
try:
|
|
137
|
+
response = requests.get(url, headers={"accept": "application/json"}, timeout=10)
|
|
138
|
+
response.raise_for_status()
|
|
139
|
+
data = response.json()
|
|
140
|
+
apps = data.get("apps", [])
|
|
141
|
+
return cast(list[dict[str, str]], apps)
|
|
142
|
+
|
|
143
|
+
except requests.RequestException as e:
|
|
144
|
+
typer.secho(
|
|
145
|
+
f"❌ Failed to fetch recommended apps: {e}",
|
|
146
|
+
fg=typer.colors.RED,
|
|
147
|
+
err=True,
|
|
148
|
+
)
|
|
149
|
+
raise typer.Exit(code=1) from e
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
# Security: prevent zip-slip
|
|
153
|
+
def _safe_extract_zip(zf: zipfile.ZipFile, dest_dir: Path) -> None:
|
|
154
|
+
"""Extract ZIP file into destination directory."""
|
|
155
|
+
dest_dir = dest_dir.resolve()
|
|
156
|
+
|
|
157
|
+
def _is_within_directory(base: Path, target: Path) -> bool:
|
|
158
|
+
try:
|
|
159
|
+
target.relative_to(base)
|
|
160
|
+
return True
|
|
161
|
+
except ValueError:
|
|
162
|
+
return False
|
|
163
|
+
|
|
164
|
+
for member in zf.infolist():
|
|
165
|
+
# Skip directory placeholders;
|
|
166
|
+
# ZipInfo can represent them as names ending with '/'.
|
|
167
|
+
if member.is_dir():
|
|
168
|
+
target_path = (dest_dir / member.filename).resolve()
|
|
169
|
+
if not _is_within_directory(dest_dir, target_path):
|
|
170
|
+
raise ValueError(f"Unsafe path in zip: {member.filename}")
|
|
171
|
+
target_path.mkdir(parents=True, exist_ok=True)
|
|
172
|
+
continue
|
|
173
|
+
|
|
174
|
+
# Files
|
|
175
|
+
target_path = (dest_dir / member.filename).resolve()
|
|
176
|
+
if not _is_within_directory(dest_dir, target_path):
|
|
177
|
+
raise ValueError(f"Unsafe path in zip: {member.filename}")
|
|
178
|
+
|
|
179
|
+
# Ensure parent exists
|
|
180
|
+
target_path.parent.mkdir(parents=True, exist_ok=True)
|
|
181
|
+
|
|
182
|
+
# Extract
|
|
183
|
+
with zf.open(member, "r") as src, open(target_path, "wb") as dst:
|
|
184
|
+
dst.write(src.read())
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def _download_zip_to_memory(presigned_url: str) -> io.BytesIO:
|
|
188
|
+
"""Download ZIP file from Platform API to memory."""
|
|
189
|
+
try:
|
|
190
|
+
r = requests.get(presigned_url, timeout=60)
|
|
191
|
+
r.raise_for_status()
|
|
192
|
+
except requests.RequestException as e:
|
|
193
|
+
typer.secho(
|
|
194
|
+
f"ZIP download failed: {e}",
|
|
195
|
+
fg=typer.colors.RED,
|
|
196
|
+
err=True,
|
|
197
|
+
)
|
|
198
|
+
raise typer.Exit(code=1) from e
|
|
199
|
+
|
|
200
|
+
buf = io.BytesIO(r.content)
|
|
201
|
+
# Validate it's a zip
|
|
202
|
+
if not zipfile.is_zipfile(buf):
|
|
203
|
+
typer.secho(
|
|
204
|
+
"Downloaded file is not a valid ZIP",
|
|
205
|
+
fg=typer.colors.RED,
|
|
206
|
+
err=True,
|
|
207
|
+
)
|
|
208
|
+
raise typer.Exit(code=1)
|
|
209
|
+
buf.seek(0)
|
|
210
|
+
return buf
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def download_remote_app_via_api(app_spec: str) -> None:
|
|
214
|
+
"""Download App from Platform API."""
|
|
215
|
+
# Validate app version and ID format
|
|
216
|
+
try:
|
|
217
|
+
app_id, app_version = parse_app_spec(app_spec)
|
|
218
|
+
except ValueError as e:
|
|
219
|
+
typer.secho(f"❌ {e}", fg=typer.colors.RED, err=True)
|
|
220
|
+
raise typer.Exit(code=1) from e
|
|
221
|
+
|
|
222
|
+
app_name = app_id.split("/")[1]
|
|
223
|
+
|
|
224
|
+
project_dir = Path.cwd() / app_name
|
|
225
|
+
if project_dir.exists():
|
|
226
|
+
if not typer.confirm(
|
|
227
|
+
typer.style(
|
|
228
|
+
f"\n💬 {app_name} already exists, do you want to override it?",
|
|
229
|
+
fg=typer.colors.MAGENTA,
|
|
230
|
+
bold=True,
|
|
231
|
+
)
|
|
232
|
+
):
|
|
233
|
+
return
|
|
234
|
+
|
|
235
|
+
typer.secho(
|
|
236
|
+
f"\n🔗 Requesting download link for {app_id}...",
|
|
237
|
+
fg=typer.colors.GREEN,
|
|
238
|
+
bold=True,
|
|
239
|
+
)
|
|
240
|
+
# Fetch ZIP downloading URL
|
|
241
|
+
url = f"{PLATFORM_API_URL}/hub/fetch-zip"
|
|
242
|
+
try:
|
|
243
|
+
presigned_url, _ = request_download_link(app_id, app_version, url, "zip_url")
|
|
244
|
+
except ValueError as e:
|
|
245
|
+
typer.secho(f"❌ {e}", fg=typer.colors.RED, err=True)
|
|
246
|
+
raise typer.Exit(code=1) from e
|
|
247
|
+
|
|
248
|
+
typer.secho(
|
|
249
|
+
"🔽 Downloading ZIP into memory...",
|
|
250
|
+
fg=typer.colors.GREEN,
|
|
251
|
+
bold=True,
|
|
252
|
+
)
|
|
253
|
+
zip_buf = _download_zip_to_memory(presigned_url)
|
|
254
|
+
|
|
255
|
+
typer.secho(
|
|
256
|
+
f"📦 Unpacking into {project_dir}...",
|
|
257
|
+
fg=typer.colors.GREEN,
|
|
258
|
+
bold=True,
|
|
259
|
+
)
|
|
260
|
+
with zipfile.ZipFile(zip_buf) as zf:
|
|
261
|
+
_safe_extract_zip(zf, Path.cwd())
|
|
262
|
+
|
|
263
|
+
print_success_prompt(app_name)
|
|
@@ -46,14 +46,10 @@ from flwr.common.typing import Fab
|
|
|
46
46
|
from flwr.proto.control_pb2 import StartRunRequest # pylint: disable=E0611
|
|
47
47
|
from flwr.proto.control_pb2_grpc import ControlStub
|
|
48
48
|
from flwr.supercore.constant import NOOP_FEDERATION
|
|
49
|
+
from flwr.supercore.utils import parse_app_spec
|
|
49
50
|
|
|
50
51
|
from ..log import start_stream
|
|
51
|
-
from ..utils import
|
|
52
|
-
flwr_cli_grpc_exc_handler,
|
|
53
|
-
init_channel,
|
|
54
|
-
load_cli_auth_plugin,
|
|
55
|
-
parse_app_spec,
|
|
56
|
-
)
|
|
52
|
+
from ..utils import flwr_cli_grpc_exc_handler, init_channel, load_cli_auth_plugin
|
|
57
53
|
|
|
58
54
|
CONN_REFRESH_PERIOD = 60 # Connection refresh period for log streaming (seconds)
|
|
59
55
|
|
|
@@ -111,8 +107,15 @@ def run(
|
|
|
111
107
|
app_spec = None
|
|
112
108
|
if (app_str := str(app)).startswith("@"):
|
|
113
109
|
# Validate app version and ID format
|
|
114
|
-
|
|
110
|
+
try:
|
|
111
|
+
_ = parse_app_spec(app_str)
|
|
112
|
+
except ValueError as e:
|
|
113
|
+
typer.secho(f"❌ {e}", fg=typer.colors.RED, err=True)
|
|
114
|
+
raise typer.Exit(code=1) from e
|
|
115
|
+
|
|
115
116
|
app_spec = app_str
|
|
117
|
+
# Set `app` to current directory for credential storage
|
|
118
|
+
app = Path(".")
|
|
116
119
|
is_remote_app = app_spec is not None
|
|
117
120
|
|
|
118
121
|
typer.secho("Loading project configuration... ", fg=typer.colors.BLUE)
|
|
@@ -212,22 +215,14 @@ def _run_with_control_api(
|
|
|
212
215
|
f"🎊 Successfully started run {res.run_id}", fg=typer.colors.GREEN
|
|
213
216
|
)
|
|
214
217
|
else:
|
|
215
|
-
|
|
216
|
-
typer.secho(
|
|
217
|
-
"❌ Failed to start run. Please check that the provided "
|
|
218
|
-
"app identifier (@account_name/app_name) is correct.",
|
|
219
|
-
fg=typer.colors.RED,
|
|
220
|
-
err=True,
|
|
221
|
-
)
|
|
222
|
-
else:
|
|
223
|
-
typer.secho("❌ Failed to start run", fg=typer.colors.RED, err=True)
|
|
218
|
+
typer.secho("❌ Failed to start run", fg=typer.colors.RED, err=True)
|
|
224
219
|
raise typer.Exit(code=1)
|
|
225
220
|
|
|
226
221
|
if output_format == CliOutputFormat.JSON:
|
|
227
222
|
# Only include FAB metadata if we actually built a local FAB
|
|
228
223
|
payload: dict[str, Any] = {
|
|
229
224
|
"success": res.HasField("run_id"),
|
|
230
|
-
"run-id": res.run_id if res.HasField("run_id") else None,
|
|
225
|
+
"run-id": f"{res.run_id}" if res.HasField("run_id") else None,
|
|
231
226
|
}
|
|
232
227
|
if not is_remote_app:
|
|
233
228
|
payload.update(
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
from dataclasses import dataclass
|
|
19
19
|
from datetime import datetime, timedelta
|
|
20
20
|
|
|
21
|
-
from flwr.common.date import
|
|
21
|
+
from flwr.common.date import isoformat8601_utc
|
|
22
22
|
from flwr.common.typing import Run
|
|
23
23
|
|
|
24
24
|
|
|
@@ -40,8 +40,8 @@ class RunRow: # pylint: disable=too-many-instance-attributes
|
|
|
40
40
|
The SHA-256 hash of the FAB.
|
|
41
41
|
status_text : str
|
|
42
42
|
The formatted status text.
|
|
43
|
-
elapsed :
|
|
44
|
-
The
|
|
43
|
+
elapsed : float
|
|
44
|
+
The elapsed time in seconds.
|
|
45
45
|
pending_at : str
|
|
46
46
|
Timestamp when run entered pending state.
|
|
47
47
|
starting_at : str
|
|
@@ -50,6 +50,16 @@ class RunRow: # pylint: disable=too-many-instance-attributes
|
|
|
50
50
|
Timestamp when run entered running state.
|
|
51
51
|
finished_at : str
|
|
52
52
|
Timestamp when run finished.
|
|
53
|
+
network_traffic_inbound : int
|
|
54
|
+
The total inbound network traffic (in bytes) used during the run.
|
|
55
|
+
It includes the traffic from SuperNodes to SuperLink.
|
|
56
|
+
network_traffic_outbound : int
|
|
57
|
+
The total outbound network traffic (in bytes) used during the run.
|
|
58
|
+
It includes the traffic from SuperLink to SuperNodes.
|
|
59
|
+
compute_time_serverapp : float
|
|
60
|
+
The total compute time (in seconds) of the ServerApp during the run.
|
|
61
|
+
compute_time_clientapp : float
|
|
62
|
+
The total compute time (in seconds) of all ClientApps during the run.
|
|
53
63
|
"""
|
|
54
64
|
|
|
55
65
|
run_id: int
|
|
@@ -58,11 +68,15 @@ class RunRow: # pylint: disable=too-many-instance-attributes
|
|
|
58
68
|
fab_version: str
|
|
59
69
|
fab_hash: str
|
|
60
70
|
status_text: str
|
|
61
|
-
elapsed:
|
|
71
|
+
elapsed: float
|
|
62
72
|
pending_at: str
|
|
63
73
|
starting_at: str
|
|
64
74
|
running_at: str
|
|
65
75
|
finished_at: str
|
|
76
|
+
network_traffic_inbound: int
|
|
77
|
+
network_traffic_outbound: int
|
|
78
|
+
compute_time_serverapp: float
|
|
79
|
+
compute_time_clientapp: float
|
|
66
80
|
|
|
67
81
|
|
|
68
82
|
def format_runs(runs: list[Run], now_isoformat: str) -> list[RunRow]:
|
|
@@ -120,11 +134,15 @@ def format_runs(runs: list[Run], now_isoformat: str) -> list[RunRow]:
|
|
|
120
134
|
fab_version=run.fab_version,
|
|
121
135
|
fab_hash=run.fab_hash,
|
|
122
136
|
status_text=status_text,
|
|
123
|
-
elapsed=
|
|
137
|
+
elapsed=elapsed_time.total_seconds(),
|
|
124
138
|
pending_at=_format_datetime(pending_at),
|
|
125
139
|
starting_at=_format_datetime(starting_at),
|
|
126
140
|
running_at=_format_datetime(running_at),
|
|
127
141
|
finished_at=_format_datetime(finished_at),
|
|
142
|
+
network_traffic_inbound=run.bytes_recv,
|
|
143
|
+
network_traffic_outbound=run.bytes_sent,
|
|
144
|
+
compute_time_serverapp=elapsed_time.total_seconds(),
|
|
145
|
+
compute_time_clientapp=run.clientapp_runtime,
|
|
128
146
|
)
|
|
129
147
|
run_list.append(row)
|
|
130
148
|
return run_list
|
|
@@ -33,7 +33,7 @@ from flwr.cli.config_utils import (
|
|
|
33
33
|
validate_federation_in_project_config,
|
|
34
34
|
)
|
|
35
35
|
from flwr.common.constant import FAB_CONFIG_FILE, NOOP_ACCOUNT_NAME, CliOutputFormat
|
|
36
|
-
from flwr.common.date import
|
|
36
|
+
from flwr.common.date import isoformat8601_utc
|
|
37
37
|
from flwr.common.logger import print_json_error, redirect_output, restore_output
|
|
38
38
|
from flwr.proto.control_pb2 import ( # pylint: disable=E0611
|
|
39
39
|
ListNodesRequest,
|
|
@@ -41,10 +41,11 @@ from flwr.proto.control_pb2 import ( # pylint: disable=E0611
|
|
|
41
41
|
)
|
|
42
42
|
from flwr.proto.control_pb2_grpc import ControlStub
|
|
43
43
|
from flwr.proto.node_pb2 import NodeInfo # pylint: disable=E0611
|
|
44
|
+
from flwr.supercore.utils import humanize_duration
|
|
44
45
|
|
|
45
46
|
from ..utils import flwr_cli_grpc_exc_handler, init_channel, load_cli_auth_plugin
|
|
46
47
|
|
|
47
|
-
_NodeListType = tuple[int, str, str, str, str, str, str, str,
|
|
48
|
+
_NodeListType = tuple[int, str, str, str, str, str, str, str, float]
|
|
48
49
|
|
|
49
50
|
|
|
50
51
|
def ls( # pylint: disable=R0914, R0913, R0917
|
|
@@ -166,7 +167,7 @@ def _format_nodes(
|
|
|
166
167
|
_format_datetime(node.last_activated_at),
|
|
167
168
|
_format_datetime(node.last_deactivated_at),
|
|
168
169
|
_format_datetime(node.unregistered_at),
|
|
169
|
-
|
|
170
|
+
elapsed_time_activated.total_seconds(),
|
|
170
171
|
)
|
|
171
172
|
)
|
|
172
173
|
|
|
@@ -224,7 +225,11 @@ def _to_table(nodes_info: list[_NodeListType], verbose: bool) -> Table:
|
|
|
224
225
|
else f"[dim]{owner_name}[/dim]"
|
|
225
226
|
),
|
|
226
227
|
f"[{status_style}]{status}",
|
|
227
|
-
|
|
228
|
+
(
|
|
229
|
+
f"[cyan]{humanize_duration(elapse_activated)}[/cyan]"
|
|
230
|
+
if status == "online"
|
|
231
|
+
else ""
|
|
232
|
+
),
|
|
228
233
|
time_at,
|
|
229
234
|
)
|
|
230
235
|
table.add_row(*formatted_row)
|
|
@@ -253,7 +258,7 @@ def _to_json(nodes_info: list[_NodeListType], verbose: bool) -> str:
|
|
|
253
258
|
|
|
254
259
|
nodes_list.append(
|
|
255
260
|
{
|
|
256
|
-
"node-id": node_id,
|
|
261
|
+
"node-id": f"{node_id}",
|
|
257
262
|
"owner-aid": owner_aid,
|
|
258
263
|
"owner-name": owner_name,
|
|
259
264
|
"status": status,
|