flwr-nightly 1.21.0.dev20250831__tar.gz → 1.21.0.dev20250902__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.
Files changed (398) hide show
  1. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/PKG-INFO +1 -1
  2. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/exit/__init__.py +4 -0
  3. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/exit/exit.py +4 -0
  4. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/exit/exit_code.py +5 -0
  5. flwr_nightly-1.21.0.dev20250902/py/flwr/common/exit/exit_handler.py +62 -0
  6. flwr_nightly-1.21.0.dev20250831/py/flwr/common/exit_handlers.py → flwr_nightly-1.21.0.dev20250902/py/flwr/common/exit/signal_handler.py +20 -37
  7. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/grpc.py +0 -11
  8. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/inflatable_utils.py +1 -1
  9. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/compat/server/app.py +2 -2
  10. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/app.py +12 -3
  11. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/cli/flower_superexec.py +3 -0
  12. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/grpc_health/__init__.py +3 -0
  13. flwr_nightly-1.21.0.dev20250902/py/flwr/supercore/grpc_health/health_server.py +53 -0
  14. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/grpc_health/simple_health_servicer.py +2 -2
  15. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/superexec/run_superexec.py +15 -3
  16. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supernode/cli/flower_supernode.py +3 -0
  17. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supernode/start_client_internal.py +15 -4
  18. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/pyproject.toml +1 -1
  19. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/README.md +0 -0
  20. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/__init__.py +0 -0
  21. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/app/__init__.py +0 -0
  22. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/app/error.py +0 -0
  23. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/app/metadata.py +0 -0
  24. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/__init__.py +0 -0
  25. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/app.py +0 -0
  26. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/auth_plugin/__init__.py +0 -0
  27. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/auth_plugin/oidc_cli_plugin.py +0 -0
  28. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/build.py +0 -0
  29. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/cli_user_auth_interceptor.py +0 -0
  30. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/config_utils.py +0 -0
  31. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/constant.py +0 -0
  32. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/example.py +0 -0
  33. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/install.py +0 -0
  34. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/log.py +0 -0
  35. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/login/__init__.py +0 -0
  36. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/login/login.py +0 -0
  37. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/ls.py +0 -0
  38. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/__init__.py +0 -0
  39. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/new.py +0 -0
  40. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/__init__.py +0 -0
  41. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/.gitignore.tpl +0 -0
  42. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/LICENSE.tpl +0 -0
  43. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/README.baseline.md.tpl +0 -0
  44. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/README.flowertune.md.tpl +0 -0
  45. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/README.md.tpl +0 -0
  46. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/__init__.py +0 -0
  47. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/__init__.baseline.py.tpl +0 -0
  48. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
  49. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
  50. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/__init__.pytorch_msg_api.py.tpl +0 -0
  51. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/client.baseline.py.tpl +0 -0
  52. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/client.huggingface.py.tpl +0 -0
  53. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/client.jax.py.tpl +0 -0
  54. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/client.mlx.py.tpl +0 -0
  55. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
  56. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -0
  57. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/client.pytorch_msg_api.py.tpl +0 -0
  58. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/client.sklearn.py.tpl +0 -0
  59. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -0
  60. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/dataset.baseline.py.tpl +0 -0
  61. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py +0 -0
  62. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +0 -0
  63. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +0 -0
  64. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +0 -0
  65. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +0 -0
  66. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +0 -0
  67. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/model.baseline.py.tpl +0 -0
  68. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/server.baseline.py.tpl +0 -0
  69. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/server.huggingface.py.tpl +0 -0
  70. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/server.jax.py.tpl +0 -0
  71. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/server.mlx.py.tpl +0 -0
  72. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
  73. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -0
  74. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/server.pytorch_msg_api.py.tpl +0 -0
  75. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/server.sklearn.py.tpl +0 -0
  76. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -0
  77. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/strategy.baseline.py.tpl +0 -0
  78. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/task.huggingface.py.tpl +0 -0
  79. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/task.jax.py.tpl +0 -0
  80. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/task.mlx.py.tpl +0 -0
  81. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/task.numpy.py.tpl +0 -0
  82. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
  83. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/task.pytorch_msg_api.py.tpl +0 -0
  84. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/task.sklearn.py.tpl +0 -0
  85. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +0 -0
  86. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/code/utils.baseline.py.tpl +0 -0
  87. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +0 -0
  88. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +0 -0
  89. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +0 -0
  90. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl +0 -0
  91. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +0 -0
  92. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +0 -0
  93. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +0 -0
  94. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/pyproject.pytorch_msg_api.toml.tpl +0 -0
  95. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +0 -0
  96. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +0 -0
  97. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/run/__init__.py +0 -0
  98. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/run/run.py +0 -0
  99. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/stop.py +0 -0
  100. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/cli/utils.py +0 -0
  101. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/__init__.py +0 -0
  102. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/client.py +0 -0
  103. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/client_app.py +0 -0
  104. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/clientapp/__init__.py +0 -0
  105. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/clientapp/utils.py +0 -0
  106. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/dpfedavg_numpy_client.py +0 -0
  107. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/grpc_adapter_client/__init__.py +0 -0
  108. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/grpc_adapter_client/connection.py +0 -0
  109. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/grpc_rere_client/__init__.py +0 -0
  110. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/grpc_rere_client/client_interceptor.py +0 -0
  111. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/grpc_rere_client/connection.py +0 -0
  112. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/grpc_rere_client/grpc_adapter.py +0 -0
  113. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/message_handler/__init__.py +0 -0
  114. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/message_handler/message_handler.py +0 -0
  115. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/mod/__init__.py +0 -0
  116. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/mod/centraldp_mods.py +0 -0
  117. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/mod/comms_mods.py +0 -0
  118. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/mod/localdp_mod.py +0 -0
  119. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
  120. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
  121. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
  122. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/mod/utils.py +0 -0
  123. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/numpy_client.py +0 -0
  124. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/rest_client/__init__.py +0 -0
  125. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/rest_client/connection.py +0 -0
  126. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/run_info_store.py +0 -0
  127. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/client/typing.py +0 -0
  128. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/clientapp/__init__.py +0 -0
  129. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/__init__.py +0 -0
  130. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/address.py +0 -0
  131. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/args.py +0 -0
  132. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/auth_plugin/__init__.py +0 -0
  133. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/auth_plugin/auth_plugin.py +0 -0
  134. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/config.py +0 -0
  135. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/constant.py +0 -0
  136. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/context.py +0 -0
  137. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/date.py +0 -0
  138. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/differential_privacy.py +0 -0
  139. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/differential_privacy_constants.py +0 -0
  140. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/dp.py +0 -0
  141. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/event_log_plugin/__init__.py +0 -0
  142. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/event_log_plugin/event_log_plugin.py +0 -0
  143. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/heartbeat.py +0 -0
  144. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/inflatable.py +0 -0
  145. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/inflatable_protobuf_utils.py +0 -0
  146. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/logger.py +0 -0
  147. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/message.py +0 -0
  148. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/object_ref.py +0 -0
  149. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/parameter.py +0 -0
  150. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/pyproject.py +0 -0
  151. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/record/__init__.py +0 -0
  152. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/record/array.py +0 -0
  153. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/record/arraychunk.py +0 -0
  154. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/record/arrayrecord.py +0 -0
  155. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/record/configrecord.py +0 -0
  156. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/record/conversion_utils.py +0 -0
  157. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/record/metricrecord.py +0 -0
  158. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/record/recorddict.py +0 -0
  159. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/record/typeddict.py +0 -0
  160. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/recorddict_compat.py +0 -0
  161. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/retry_invoker.py +0 -0
  162. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/secure_aggregation/__init__.py +0 -0
  163. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
  164. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
  165. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
  166. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
  167. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/secure_aggregation/quantization.py +0 -0
  168. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
  169. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
  170. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/serde.py +0 -0
  171. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/serde_utils.py +0 -0
  172. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/telemetry.py +0 -0
  173. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/typing.py +0 -0
  174. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/common/version.py +0 -0
  175. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/compat/__init__.py +0 -0
  176. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/compat/client/__init__.py +0 -0
  177. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/compat/client/app.py +0 -0
  178. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/compat/client/grpc_client/__init__.py +0 -0
  179. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/compat/client/grpc_client/connection.py +0 -0
  180. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/compat/common/__init__.py +0 -0
  181. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/compat/server/__init__.py +0 -0
  182. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/compat/simulation/__init__.py +0 -0
  183. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/__init__.py +0 -0
  184. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/appio_pb2.py +0 -0
  185. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/appio_pb2.pyi +0 -0
  186. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/appio_pb2_grpc.py +0 -0
  187. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/appio_pb2_grpc.pyi +0 -0
  188. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/clientappio_pb2.py +0 -0
  189. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/clientappio_pb2.pyi +0 -0
  190. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/clientappio_pb2_grpc.py +0 -0
  191. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/clientappio_pb2_grpc.pyi +0 -0
  192. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/control_pb2.py +0 -0
  193. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/control_pb2.pyi +0 -0
  194. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/control_pb2_grpc.py +0 -0
  195. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/control_pb2_grpc.pyi +0 -0
  196. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/error_pb2.py +0 -0
  197. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/error_pb2.pyi +0 -0
  198. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/error_pb2_grpc.py +0 -0
  199. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/error_pb2_grpc.pyi +0 -0
  200. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/fab_pb2.py +0 -0
  201. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/fab_pb2.pyi +0 -0
  202. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/fab_pb2_grpc.py +0 -0
  203. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/fab_pb2_grpc.pyi +0 -0
  204. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/fleet_pb2.py +0 -0
  205. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/fleet_pb2.pyi +0 -0
  206. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/fleet_pb2_grpc.py +0 -0
  207. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
  208. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/grpcadapter_pb2.py +0 -0
  209. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/grpcadapter_pb2.pyi +0 -0
  210. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/grpcadapter_pb2_grpc.py +0 -0
  211. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/grpcadapter_pb2_grpc.pyi +0 -0
  212. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/heartbeat_pb2.py +0 -0
  213. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/heartbeat_pb2.pyi +0 -0
  214. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/heartbeat_pb2_grpc.py +0 -0
  215. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/heartbeat_pb2_grpc.pyi +0 -0
  216. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/log_pb2.py +0 -0
  217. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/log_pb2.pyi +0 -0
  218. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/log_pb2_grpc.py +0 -0
  219. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/log_pb2_grpc.pyi +0 -0
  220. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/message_pb2.py +0 -0
  221. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/message_pb2.pyi +0 -0
  222. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/message_pb2_grpc.py +0 -0
  223. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/message_pb2_grpc.pyi +0 -0
  224. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/node_pb2.py +0 -0
  225. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/node_pb2.pyi +0 -0
  226. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/node_pb2_grpc.py +0 -0
  227. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/node_pb2_grpc.pyi +0 -0
  228. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/recorddict_pb2.py +0 -0
  229. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/recorddict_pb2.pyi +0 -0
  230. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/recorddict_pb2_grpc.py +0 -0
  231. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/recorddict_pb2_grpc.pyi +0 -0
  232. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/run_pb2.py +0 -0
  233. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/run_pb2.pyi +0 -0
  234. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/run_pb2_grpc.py +0 -0
  235. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/run_pb2_grpc.pyi +0 -0
  236. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/serverappio_pb2.py +0 -0
  237. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/serverappio_pb2.pyi +0 -0
  238. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/serverappio_pb2_grpc.py +0 -0
  239. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/serverappio_pb2_grpc.pyi +0 -0
  240. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/simulationio_pb2.py +0 -0
  241. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/simulationio_pb2.pyi +0 -0
  242. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/simulationio_pb2_grpc.py +0 -0
  243. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/simulationio_pb2_grpc.pyi +0 -0
  244. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/transport_pb2.py +0 -0
  245. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/transport_pb2.pyi +0 -0
  246. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/transport_pb2_grpc.py +0 -0
  247. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
  248. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/py.typed +0 -0
  249. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/__init__.py +0 -0
  250. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/client_manager.py +0 -0
  251. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/client_proxy.py +0 -0
  252. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/compat/__init__.py +0 -0
  253. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/compat/app.py +0 -0
  254. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/compat/app_utils.py +0 -0
  255. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/compat/grid_client_proxy.py +0 -0
  256. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/compat/legacy_context.py +0 -0
  257. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/criterion.py +0 -0
  258. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/fleet_event_log_interceptor.py +0 -0
  259. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/grid/__init__.py +0 -0
  260. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/grid/grid.py +0 -0
  261. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/grid/grpc_grid.py +0 -0
  262. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/grid/inmemory_grid.py +0 -0
  263. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/history.py +0 -0
  264. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/run_serverapp.py +0 -0
  265. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/server.py +0 -0
  266. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/server_app.py +0 -0
  267. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/server_config.py +0 -0
  268. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/serverapp/__init__.py +0 -0
  269. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/serverapp/app.py +0 -0
  270. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/serverapp_components.py +0 -0
  271. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/__init__.py +0 -0
  272. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/aggregate.py +0 -0
  273. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/bulyan.py +0 -0
  274. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
  275. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
  276. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
  277. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
  278. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
  279. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/fedadagrad.py +0 -0
  280. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/fedadam.py +0 -0
  281. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/fedavg.py +0 -0
  282. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/fedavg_android.py +0 -0
  283. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/fedavgm.py +0 -0
  284. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/fedmedian.py +0 -0
  285. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/fedopt.py +0 -0
  286. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/fedprox.py +0 -0
  287. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
  288. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
  289. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
  290. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
  291. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/fedyogi.py +0 -0
  292. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/krum.py +0 -0
  293. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/qfedavg.py +0 -0
  294. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/strategy/strategy.py +0 -0
  295. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/__init__.py +0 -0
  296. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/__init__.py +0 -0
  297. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py +0 -0
  298. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +0 -0
  299. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
  300. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
  301. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
  302. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
  303. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
  304. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
  305. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +0 -0
  306. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +0 -0
  307. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
  308. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/message_handler/message_handler.py +0 -0
  309. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
  310. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +0 -0
  311. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
  312. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
  313. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
  314. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +0 -0
  315. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/fleet/vce/vce_api.py +0 -0
  316. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/linkstate/__init__.py +0 -0
  317. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/linkstate/in_memory_linkstate.py +0 -0
  318. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/linkstate/linkstate.py +0 -0
  319. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/linkstate/linkstate_factory.py +0 -0
  320. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/linkstate/sqlite_linkstate.py +0 -0
  321. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/linkstate/utils.py +0 -0
  322. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/serverappio/__init__.py +0 -0
  323. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/serverappio/serverappio_grpc.py +0 -0
  324. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/serverappio/serverappio_servicer.py +0 -0
  325. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/simulation/__init__.py +0 -0
  326. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/simulation/simulationio_grpc.py +0 -0
  327. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/simulation/simulationio_servicer.py +0 -0
  328. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/superlink/utils.py +0 -0
  329. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/typing.py +0 -0
  330. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/utils/__init__.py +0 -0
  331. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/utils/tensorboard.py +0 -0
  332. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/utils/validator.py +0 -0
  333. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/workflow/__init__.py +0 -0
  334. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/workflow/constant.py +0 -0
  335. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/workflow/default_workflows.py +0 -0
  336. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
  337. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
  338. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
  339. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/serverapp/__init__.py +0 -0
  340. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/serverapp/strategy/__init__.py +0 -0
  341. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/serverapp/strategy/fedavg.py +0 -0
  342. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/serverapp/strategy/result.py +0 -0
  343. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/serverapp/strategy/strategy.py +0 -0
  344. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/serverapp/strategy/strategy_utils.py +0 -0
  345. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/serverapp/strategy/strategy_utils_tests.py +0 -0
  346. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/simulation/__init__.py +0 -0
  347. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/simulation/app.py +0 -0
  348. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/simulation/legacy_app.py +0 -0
  349. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/simulation/ray_transport/__init__.py +0 -0
  350. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
  351. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
  352. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/simulation/ray_transport/utils.py +0 -0
  353. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/simulation/run_simulation.py +0 -0
  354. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/simulation/simulationio_connection.py +0 -0
  355. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/__init__.py +0 -0
  356. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/app_utils.py +0 -0
  357. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/cli/__init__.py +0 -0
  358. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/corestate/__init__.py +0 -0
  359. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/corestate/corestate.py +0 -0
  360. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/ffs/__init__.py +0 -0
  361. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/ffs/disk_ffs.py +0 -0
  362. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/ffs/ffs.py +0 -0
  363. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/ffs/ffs_factory.py +0 -0
  364. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/license_plugin/__init__.py +0 -0
  365. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/license_plugin/license_plugin.py +0 -0
  366. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/object_store/__init__.py +0 -0
  367. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/object_store/in_memory_object_store.py +0 -0
  368. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/object_store/object_store.py +0 -0
  369. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/object_store/object_store_factory.py +0 -0
  370. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/object_store/utils.py +0 -0
  371. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/superexec/__init__.py +0 -0
  372. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/superexec/plugin/__init__.py +0 -0
  373. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/superexec/plugin/base_exec_plugin.py +0 -0
  374. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/superexec/plugin/clientapp_exec_plugin.py +0 -0
  375. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/superexec/plugin/exec_plugin.py +0 -0
  376. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/superexec/plugin/serverapp_exec_plugin.py +0 -0
  377. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/superexec/plugin/simulation_exec_plugin.py +0 -0
  378. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supercore/utils.py +0 -0
  379. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/superlink/__init__.py +0 -0
  380. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/superlink/servicer/__init__.py +0 -0
  381. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/superlink/servicer/control/__init__.py +0 -0
  382. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/superlink/servicer/control/control_event_log_interceptor.py +0 -0
  383. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/superlink/servicer/control/control_grpc.py +0 -0
  384. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/superlink/servicer/control/control_license_interceptor.py +0 -0
  385. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/superlink/servicer/control/control_servicer.py +0 -0
  386. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/superlink/servicer/control/control_user_auth_interceptor.py +0 -0
  387. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supernode/__init__.py +0 -0
  388. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supernode/cli/__init__.py +0 -0
  389. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supernode/cli/flwr_clientapp.py +0 -0
  390. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supernode/nodestate/__init__.py +0 -0
  391. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supernode/nodestate/in_memory_nodestate.py +0 -0
  392. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supernode/nodestate/nodestate.py +0 -0
  393. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supernode/nodestate/nodestate_factory.py +0 -0
  394. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supernode/runtime/__init__.py +0 -0
  395. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supernode/runtime/run_clientapp.py +0 -0
  396. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supernode/servicer/__init__.py +0 -0
  397. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supernode/servicer/clientappio/__init__.py +0 -0
  398. {flwr_nightly-1.21.0.dev20250831 → flwr_nightly-1.21.0.dev20250902}/py/flwr/supernode/servicer/clientappio/clientappio_servicer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: flwr-nightly
3
- Version: 1.21.0.dev20250831
3
+ Version: 1.21.0.dev20250902
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
@@ -17,8 +17,12 @@
17
17
 
18
18
  from .exit import flwr_exit
19
19
  from .exit_code import ExitCode
20
+ from .exit_handler import add_exit_handler
21
+ from .signal_handler import register_signal_handlers
20
22
 
21
23
  __all__ = [
22
24
  "ExitCode",
25
+ "add_exit_handler",
23
26
  "flwr_exit",
27
+ "register_signal_handlers",
24
28
  ]
@@ -26,6 +26,7 @@ from flwr.common.version import package_version
26
26
 
27
27
  from ..logger import log
28
28
  from .exit_code import EXIT_CODE_HELP
29
+ from .exit_handler import trigger_exit_handlers
29
30
 
30
31
  HELP_PAGE_URL = (
31
32
  f"https://flower.ai/docs/framework/v{package_version}/en/ref-exit-codes/"
@@ -80,6 +81,9 @@ def flwr_exit(
80
81
  # Log the exit message
81
82
  log(log_level, exit_message)
82
83
 
84
+ # Trigger exit handlers
85
+ trigger_exit_handlers()
86
+
83
87
  # Exit
84
88
  sys.exit(sys_exit_code)
85
89
 
@@ -36,6 +36,7 @@ class ExitCode:
36
36
 
37
37
  # ServerApp-specific exit codes (200-299)
38
38
  SERVERAPP_STRATEGY_PRECONDITION_UNMET = 200
39
+ SERVERAPP_STRATEGY_AGGREGATION_ERROR = 202
39
40
 
40
41
  # SuperNode-specific exit codes (300-399)
41
42
  SUPERNODE_REST_ADDRESS_INVALID = 300
@@ -89,6 +90,10 @@ EXIT_CODE_HELP = {
89
90
  "perform weighted average (e.g. in FedAvg) please ensure the returned "
90
91
  "MetricRecord from ClientApps do include this key."
91
92
  ),
93
+ ExitCode.SERVERAPP_STRATEGY_AGGREGATION_ERROR: (
94
+ "The strategy encountered an error during aggregation. Please check the logs "
95
+ "for more details."
96
+ ),
92
97
  # SuperNode-specific exit codes (300-399)
93
98
  ExitCode.SUPERNODE_REST_ADDRESS_INVALID: (
94
99
  "When using the REST API, please provide `https://` or "
@@ -0,0 +1,62 @@
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
+ """Common function to register exit handlers."""
16
+
17
+
18
+ import signal
19
+ import threading
20
+ from typing import Callable
21
+
22
+ from .exit_code import ExitCode
23
+
24
+ SIGNAL_TO_EXIT_CODE: dict[int, int] = {
25
+ signal.SIGINT: ExitCode.GRACEFUL_EXIT_SIGINT,
26
+ signal.SIGTERM: ExitCode.GRACEFUL_EXIT_SIGTERM,
27
+ }
28
+ registered_exit_handlers: list[Callable[[], None]] = []
29
+ _lock_handlers = threading.Lock()
30
+
31
+ # SIGQUIT is not available on Windows
32
+ if hasattr(signal, "SIGQUIT"):
33
+ SIGNAL_TO_EXIT_CODE[signal.SIGQUIT] = ExitCode.GRACEFUL_EXIT_SIGQUIT
34
+
35
+
36
+ def add_exit_handler(exit_handler: Callable[[], None]) -> None:
37
+ """Add an exit handler to be called on graceful exit.
38
+
39
+ This function allows you to register additional exit handlers
40
+ that will be executed when `flwr_exit` is called.
41
+
42
+ Parameters
43
+ ----------
44
+ exit_handler : Callable[[], None]
45
+ A callable that takes no arguments and performs cleanup or
46
+ other actions before the application exits.
47
+
48
+ Notes
49
+ -----
50
+ The registered exit handlers will be called in LIFO order, i.e.,
51
+ the last registered handler will be the first to be called.
52
+ """
53
+ with _lock_handlers:
54
+ registered_exit_handlers.append(exit_handler)
55
+
56
+
57
+ def trigger_exit_handlers() -> None:
58
+ """Trigger all registered exit handlers in LIFO order."""
59
+ with _lock_handlers:
60
+ for handler in reversed(registered_exit_handlers):
61
+ handler()
62
+ registered_exit_handlers.clear()
@@ -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
- """Common function to register exit handlers for server and client."""
15
+ """Common function to register signal handlers."""
16
16
 
17
17
 
18
18
  import signal
@@ -24,20 +24,21 @@ from grpc import Server
24
24
 
25
25
  from flwr.common.telemetry import EventType
26
26
 
27
- from .exit import ExitCode, flwr_exit
27
+ from .exit import flwr_exit
28
+ from .exit_code import ExitCode
29
+ from .exit_handler import add_exit_handler
28
30
 
29
31
  SIGNAL_TO_EXIT_CODE: dict[int, int] = {
30
32
  signal.SIGINT: ExitCode.GRACEFUL_EXIT_SIGINT,
31
33
  signal.SIGTERM: ExitCode.GRACEFUL_EXIT_SIGTERM,
32
34
  }
33
- registered_exit_handlers: list[Callable[[], None]] = []
34
35
 
35
36
  # SIGQUIT is not available on Windows
36
37
  if hasattr(signal, "SIGQUIT"):
37
38
  SIGNAL_TO_EXIT_CODE[signal.SIGQUIT] = ExitCode.GRACEFUL_EXIT_SIGQUIT
38
39
 
39
40
 
40
- def register_exit_handlers(
41
+ def register_signal_handlers(
41
42
  event_type: EventType,
42
43
  exit_message: Optional[str] = None,
43
44
  grpc_servers: Optional[list[Server]] = None,
@@ -63,7 +64,21 @@ def register_exit_handlers(
63
64
  Additional exit handlers can be added using `add_exit_handler`.
64
65
  """
65
66
  default_handlers: dict[int, Callable[[int, FrameType], None]] = {}
66
- registered_exit_handlers.extend(exit_handlers or [])
67
+
68
+ def _wait_to_stop() -> None:
69
+ if grpc_servers is not None:
70
+ for grpc_server in grpc_servers:
71
+ grpc_server.stop(grace=1)
72
+
73
+ if bckg_threads is not None:
74
+ for bckg_thread in bckg_threads:
75
+ bckg_thread.join()
76
+
77
+ # Ensure that `_wait_to_stop` is the last handler called on exit
78
+ add_exit_handler(_wait_to_stop)
79
+
80
+ for handler in exit_handlers or []:
81
+ add_exit_handler(handler)
67
82
 
68
83
  def graceful_exit_handler(signalnum: int, _frame: FrameType) -> None:
69
84
  """Exit handler to be registered with `signal.signal`.
@@ -74,17 +89,6 @@ def register_exit_handlers(
74
89
  # Reset to default handler
75
90
  signal.signal(signalnum, default_handlers[signalnum]) # type: ignore
76
91
 
77
- for handler in registered_exit_handlers:
78
- handler()
79
-
80
- if grpc_servers is not None:
81
- for grpc_server in grpc_servers:
82
- grpc_server.stop(grace=1)
83
-
84
- if bckg_threads is not None:
85
- for bckg_thread in bckg_threads:
86
- bckg_thread.join()
87
-
88
92
  # Setup things for graceful exit
89
93
  flwr_exit(
90
94
  code=SIGNAL_TO_EXIT_CODE[signalnum],
@@ -96,24 +100,3 @@ def register_exit_handlers(
96
100
  for sig in SIGNAL_TO_EXIT_CODE:
97
101
  default_handler = signal.signal(sig, graceful_exit_handler) # type: ignore
98
102
  default_handlers[sig] = default_handler # type: ignore
99
-
100
-
101
- def add_exit_handler(exit_handler: Callable[[], None]) -> None:
102
- """Add an exit handler to be called on graceful exit.
103
-
104
- This function allows you to register additional exit handlers
105
- that will be executed when the application exits gracefully,
106
- if `register_exit_handlers` was called.
107
-
108
- Parameters
109
- ----------
110
- exit_handler : Callable[[], None]
111
- A callable that takes no arguments and performs cleanup or
112
- other actions before the application exits.
113
-
114
- Notes
115
- -----
116
- This method is not thread-safe, and it allows you to add the
117
- same exit handler multiple times.
118
- """
119
- registered_exit_handlers.append(exit_handler)
@@ -23,9 +23,6 @@ from logging import DEBUG, ERROR
23
23
  from typing import Any, Callable, Optional
24
24
 
25
25
  import grpc
26
- from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server
27
-
28
- from flwr.supercore.grpc_health import SimpleHealthServicer
29
26
 
30
27
  from .address import is_port_in_use
31
28
  from .logger import log
@@ -109,7 +106,6 @@ def generic_create_grpc_server( # pylint: disable=too-many-arguments, R0914, R0
109
106
  keepalive_time_ms: int = 210000,
110
107
  certificates: Optional[tuple[bytes, bytes, bytes]] = None,
111
108
  interceptors: Optional[Sequence[grpc.ServerInterceptor]] = None,
112
- health_servicer: Optional[Any] = None,
113
109
  ) -> grpc.Server:
114
110
  """Create a gRPC server with a single servicer.
115
111
 
@@ -157,10 +153,6 @@ def generic_create_grpc_server( # pylint: disable=too-many-arguments, R0914, R0
157
153
  * server private key.
158
154
  interceptors : Optional[Sequence[grpc.ServerInterceptor]] (default: None)
159
155
  A list of gRPC interceptors.
160
- health_servicer : Optional[Any] (default: None)
161
- An optional health servicer to add to the server. If provided, it should be an
162
- instance of a class that inherits the `HealthServicer` class.
163
- If None is provided, `SimpleHealthServicer` will be used by default.
164
156
 
165
157
  Returns
166
158
  -------
@@ -211,9 +203,6 @@ def generic_create_grpc_server( # pylint: disable=too-many-arguments, R0914, R0
211
203
  )
212
204
  add_servicer_to_server_fn(servicer, server)
213
205
 
214
- # Enable health service
215
- add_HealthServicer_to_server(health_servicer or SimpleHealthServicer(), server)
216
-
217
206
  if certificates is not None:
218
207
  if not valid_certificates(certificates):
219
208
  sys.exit(1)
@@ -34,7 +34,7 @@ from .constant import (
34
34
  PULL_MAX_TIME,
35
35
  PULL_MAX_TRIES_PER_OBJECT,
36
36
  )
37
- from .exit_handlers import add_exit_handler
37
+ from .exit import add_exit_handler
38
38
  from .inflatable import (
39
39
  InflatableObject,
40
40
  UnexpectedObjectContentError,
@@ -22,7 +22,7 @@ from typing import Optional
22
22
  from flwr.common import GRPC_MAX_MESSAGE_LENGTH, EventType, event
23
23
  from flwr.common.address import parse_address
24
24
  from flwr.common.constant import FLEET_API_GRPC_BIDI_DEFAULT_ADDRESS
25
- from flwr.common.exit_handlers import register_exit_handlers
25
+ from flwr.common.exit import register_signal_handlers
26
26
  from flwr.common.logger import log, warn_deprecated_feature
27
27
  from flwr.server.client_manager import ClientManager
28
28
  from flwr.server.history import History
@@ -154,7 +154,7 @@ def start_server( # pylint: disable=too-many-arguments,too-many-locals
154
154
  )
155
155
 
156
156
  # Graceful shutdown
157
- register_exit_handlers(
157
+ register_signal_handlers(
158
158
  event_type=EventType.START_SERVER_LEAVE,
159
159
  exit_message="Flower server terminated gracefully.",
160
160
  grpc_servers=[grpc_server],
@@ -57,8 +57,7 @@ from flwr.common.constant import (
57
57
  ExecPluginType,
58
58
  )
59
59
  from flwr.common.event_log_plugin import EventLogWriterPlugin
60
- from flwr.common.exit import ExitCode, flwr_exit
61
- from flwr.common.exit_handlers import register_exit_handlers
60
+ from flwr.common.exit import ExitCode, flwr_exit, register_signal_handlers
62
61
  from flwr.common.grpc import generic_create_grpc_server
63
62
  from flwr.common.logger import log
64
63
  from flwr.common.secure_aggregation.crypto.symmetric_encryption import (
@@ -70,6 +69,7 @@ from flwr.proto.fleet_pb2_grpc import ( # pylint: disable=E0611
70
69
  from flwr.proto.grpcadapter_pb2_grpc import add_GrpcAdapterServicer_to_server
71
70
  from flwr.server.fleet_event_log_interceptor import FleetEventLogInterceptor
72
71
  from flwr.supercore.ffs import FfsFactory
72
+ from flwr.supercore.grpc_health import add_args_health, run_health_server_grpc_no_tls
73
73
  from flwr.supercore.object_store import ObjectStoreFactory
74
74
  from flwr.superlink.servicer.control import run_control_api_grpc
75
75
 
@@ -176,6 +176,9 @@ def run_superlink() -> None:
176
176
  serverappio_address, _, _ = _format_address(args.serverappio_api_address)
177
177
  control_address, _, _ = _format_address(args.control_api_address)
178
178
  simulationio_address, _, _ = _format_address(args.simulationio_api_address)
179
+ health_server_address = None
180
+ if args.health_server_address is not None:
181
+ health_server_address, _, _ = _format_address(args.health_server_address)
179
182
 
180
183
  # Obtain certificates
181
184
  certificates = try_obtain_server_certificates(args)
@@ -352,8 +355,13 @@ def run_superlink() -> None:
352
355
  # pylint: disable-next=consider-using-with
353
356
  subprocess.Popen(command)
354
357
 
358
+ # Launch gRPC health server
359
+ if health_server_address is not None:
360
+ health_server = run_health_server_grpc_no_tls(health_server_address)
361
+ grpc_servers.append(health_server)
362
+
355
363
  # Graceful shutdown
356
- register_exit_handlers(
364
+ register_signal_handlers(
357
365
  event_type=EventType.RUN_SUPERLINK_LEAVE,
358
366
  exit_message="SuperLink terminated gracefully.",
359
367
  grpc_servers=grpc_servers,
@@ -610,6 +618,7 @@ def _parse_args_run_superlink() -> argparse.ArgumentParser:
610
618
  _add_args_fleet_api(parser=parser)
611
619
  _add_args_control_api(parser=parser)
612
620
  _add_args_simulationio_api(parser=parser)
621
+ add_args_health(parser=parser)
613
622
 
614
623
  return parser
615
624
 
@@ -25,6 +25,7 @@ from flwr.common.logger import log
25
25
  from flwr.proto.clientappio_pb2_grpc import ClientAppIoStub
26
26
  from flwr.proto.serverappio_pb2_grpc import ServerAppIoStub
27
27
  from flwr.proto.simulationio_pb2_grpc import SimulationIoStub
28
+ from flwr.supercore.grpc_health import add_args_health
28
29
  from flwr.supercore.superexec.plugin import (
29
30
  ClientAppExecPlugin,
30
31
  ExecPlugin,
@@ -57,6 +58,7 @@ def flower_superexec() -> None:
57
58
  appio_api_address=args.appio_api_address,
58
59
  flwr_dir=args.flwr_dir,
59
60
  parent_pid=args.parent_pid,
61
+ health_server_address=args.health_server_address,
60
62
  )
61
63
 
62
64
 
@@ -100,6 +102,7 @@ def _parse_args() -> argparse.ArgumentParser:
100
102
  help="The PID of the parent process. When set, the process will terminate "
101
103
  "when the parent process exits.",
102
104
  )
105
+ add_args_health(parser)
103
106
  return parser
104
107
 
105
108
 
@@ -15,8 +15,11 @@
15
15
  """GRPC health servicers."""
16
16
 
17
17
 
18
+ from .health_server import add_args_health, run_health_server_grpc_no_tls
18
19
  from .simple_health_servicer import SimpleHealthServicer
19
20
 
20
21
  __all__ = [
21
22
  "SimpleHealthServicer",
23
+ "add_args_health",
24
+ "run_health_server_grpc_no_tls",
22
25
  ]
@@ -0,0 +1,53 @@
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
+ """Health servers."""
16
+
17
+
18
+ import argparse
19
+ from logging import INFO
20
+
21
+ import grpc
22
+ from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server
23
+
24
+ from flwr.common.grpc import generic_create_grpc_server
25
+ from flwr.common.logger import log
26
+
27
+ from .simple_health_servicer import SimpleHealthServicer
28
+
29
+
30
+ def run_health_server_grpc_no_tls(address: str) -> grpc.Server:
31
+ """Run gRPC health server with no TLS."""
32
+ health_server = generic_create_grpc_server(
33
+ servicer_and_add_fn=(
34
+ SimpleHealthServicer(),
35
+ add_HealthServicer_to_server,
36
+ ),
37
+ server_address=address,
38
+ certificates=None,
39
+ )
40
+ log(INFO, "Starting gRPC health server on %s", address)
41
+ health_server.start()
42
+ return health_server
43
+
44
+
45
+ def add_args_health(parser: argparse.ArgumentParser) -> None:
46
+ """Add arguments for health server."""
47
+ parser.add_argument(
48
+ "--health-server-address",
49
+ type=str,
50
+ default=None,
51
+ help="Health service gRPC server address (IPv4, IPv6, or a domain name) "
52
+ "with no TLS. If not set, the health server will not be started.",
53
+ )
@@ -28,11 +28,11 @@ class SimpleHealthServicer(HealthServicer): # type: ignore
28
28
  """A simple gRPC health servicer that always returns SERVING."""
29
29
 
30
30
  def Check(
31
- self, request: HealthCheckRequest, context: grpc.RpcContext
31
+ self, request: HealthCheckRequest, context: grpc.ServicerContext
32
32
  ) -> HealthCheckResponse:
33
33
  """Return a HealthCheckResponse with SERVING status."""
34
34
  return HealthCheckResponse(status=HealthCheckResponse.SERVING)
35
35
 
36
- def Watch(self, request: HealthCheckRequest, context: grpc.RpcContext) -> None:
36
+ def Watch(self, request: HealthCheckRequest, context: grpc.ServicerContext) -> None:
37
37
  """Watch the health status (not implemented)."""
38
38
  context.abort(grpc.StatusCode.UNIMPLEMENTED, "Watch is not implemented")
@@ -20,7 +20,7 @@ from logging import WARN
20
20
  from typing import Optional, Union
21
21
 
22
22
  from flwr.common.config import get_flwr_dir
23
- from flwr.common.exit_handlers import register_exit_handlers
23
+ from flwr.common.exit import register_signal_handlers
24
24
  from flwr.common.grpc import create_channel, on_channel_state_change
25
25
  from flwr.common.logger import log
26
26
  from flwr.common.retry_invoker import _make_simple_grpc_retry_invoker, _wrap_stub
@@ -36,11 +36,12 @@ from flwr.proto.run_pb2 import GetRunRequest # pylint: disable=E0611
36
36
  from flwr.proto.serverappio_pb2_grpc import ServerAppIoStub
37
37
  from flwr.proto.simulationio_pb2_grpc import SimulationIoStub
38
38
  from flwr.supercore.app_utils import start_parent_process_monitor
39
+ from flwr.supercore.grpc_health import run_health_server_grpc_no_tls
39
40
 
40
41
  from .plugin import ExecPlugin
41
42
 
42
43
 
43
- def run_superexec(
44
+ def run_superexec( # pylint: disable=R0913,R0914,R0917
44
45
  plugin_class: type[ExecPlugin],
45
46
  stub_class: Union[
46
47
  type[ClientAppIoStub], type[ServerAppIoStub], type[SimulationIoStub]
@@ -48,6 +49,7 @@ def run_superexec(
48
49
  appio_api_address: str,
49
50
  flwr_dir: Optional[str] = None,
50
51
  parent_pid: Optional[int] = None,
52
+ health_server_address: Optional[str] = None,
51
53
  ) -> None:
52
54
  """Run Flower SuperExec.
53
55
 
@@ -64,11 +66,20 @@ def run_superexec(
64
66
  parent_pid : Optional[int] (default: None)
65
67
  The PID of the parent process. If provided, the SuperExec will terminate
66
68
  when the parent process exits.
69
+ health_server_address : Optional[str] (default: None)
70
+ The address of the health server. If `None` is provided, the health server will
71
+ NOT be started.
67
72
  """
68
73
  # Start monitoring the parent process if a PID is provided
69
74
  if parent_pid is not None:
70
75
  start_parent_process_monitor(parent_pid)
71
76
 
77
+ # Launch gRPC health server
78
+ grpc_servers = []
79
+ if health_server_address is not None:
80
+ health_server = run_health_server_grpc_no_tls(health_server_address)
81
+ grpc_servers.append(health_server)
82
+
72
83
  # Create the channel to the AppIO API
73
84
  # No TLS support for now, so insecure connection
74
85
  channel = create_channel(
@@ -79,9 +90,10 @@ def run_superexec(
79
90
  channel.subscribe(on_channel_state_change)
80
91
 
81
92
  # Register exit handlers to close the channel on exit
82
- register_exit_handlers(
93
+ register_signal_handlers(
83
94
  event_type=EventType.RUN_SUPEREXEC_LEAVE,
84
95
  exit_message="SuperExec terminated gracefully.",
96
+ grpc_servers=grpc_servers,
85
97
  exit_handlers=[lambda: channel.close()], # pylint: disable=W0108
86
98
  )
87
99
 
@@ -41,6 +41,7 @@ from flwr.common.constant import (
41
41
  )
42
42
  from flwr.common.exit import ExitCode, flwr_exit
43
43
  from flwr.common.logger import log
44
+ from flwr.supercore.grpc_health import add_args_health
44
45
  from flwr.supernode.start_client_internal import start_client_internal
45
46
 
46
47
 
@@ -79,6 +80,7 @@ def flower_supernode() -> None:
79
80
  flwr_path=args.flwr_dir,
80
81
  isolation=args.isolation,
81
82
  clientappio_api_address=args.clientappio_api_address,
83
+ health_server_address=args.health_server_address,
82
84
  )
83
85
 
84
86
 
@@ -118,6 +120,7 @@ def _parse_args_run_supernode() -> argparse.ArgumentParser:
118
120
  help="ClientAppIo API (gRPC) server address (IPv4, IPv6, or a domain name). "
119
121
  f"By default, it is set to {CLIENTAPPIO_API_DEFAULT_SERVER_ADDRESS}.",
120
122
  )
123
+ add_args_health(parser)
121
124
 
122
125
  return parser
123
126
 
@@ -43,8 +43,7 @@ from flwr.common.constant import (
43
43
  TRANSPORT_TYPES,
44
44
  ExecPluginType,
45
45
  )
46
- from flwr.common.exit import ExitCode, flwr_exit
47
- from flwr.common.exit_handlers import register_exit_handlers
46
+ from flwr.common.exit import ExitCode, flwr_exit, register_signal_handlers
48
47
  from flwr.common.grpc import generic_create_grpc_server
49
48
  from flwr.common.inflatable import iterate_object_tree
50
49
  from flwr.common.inflatable_utils import (
@@ -58,6 +57,7 @@ from flwr.common.typing import Fab, Run, RunNotRunningException, UserConfig
58
57
  from flwr.proto.clientappio_pb2_grpc import add_ClientAppIoServicer_to_server
59
58
  from flwr.proto.message_pb2 import ObjectTree # pylint: disable=E0611
60
59
  from flwr.supercore.ffs import Ffs, FfsFactory
60
+ from flwr.supercore.grpc_health import run_health_server_grpc_no_tls
61
61
  from flwr.supercore.object_store import ObjectStore, ObjectStoreFactory
62
62
  from flwr.supernode.nodestate import NodeState, NodeStateFactory
63
63
  from flwr.supernode.servicer.clientappio import ClientAppIoServicer
@@ -85,6 +85,7 @@ def start_client_internal(
85
85
  flwr_path: Optional[Path] = None,
86
86
  isolation: str = ISOLATION_MODE_SUBPROCESS,
87
87
  clientappio_api_address: str = CLIENTAPPIO_API_DEFAULT_SERVER_ADDRESS,
88
+ health_server_address: Optional[str] = None,
88
89
  ) -> None:
89
90
  """Start a Flower client node which connects to a Flower server.
90
91
 
@@ -133,6 +134,9 @@ def start_client_internal(
133
134
  clientappio_api_address : str
134
135
  (default: `CLIENTAPPIO_API_DEFAULT_SERVER_ADDRESS`)
135
136
  The SuperNode gRPC server address.
137
+ health_server_address : Optional[str] (default: None)
138
+ The address of the health server. If `None` is provided, the health server will
139
+ NOT be started.
136
140
  """
137
141
  if insecure is None:
138
142
  insecure = root_certificates is None
@@ -143,6 +147,7 @@ def start_client_internal(
143
147
  object_store_factory = ObjectStoreFactory()
144
148
 
145
149
  # Launch ClientAppIo API server
150
+ grpc_servers = []
146
151
  clientappio_server = run_clientappio_api_grpc(
147
152
  address=clientappio_api_address,
148
153
  state_factory=state_factory,
@@ -150,12 +155,18 @@ def start_client_internal(
150
155
  objectstore_factory=object_store_factory,
151
156
  certificates=None,
152
157
  )
158
+ grpc_servers.append(clientappio_server)
159
+
160
+ # Launch gRPC health server
161
+ if health_server_address is not None:
162
+ health_server = run_health_server_grpc_no_tls(health_server_address)
163
+ grpc_servers.append(health_server)
153
164
 
154
165
  # Register handlers for graceful shutdown
155
- register_exit_handlers(
166
+ register_signal_handlers(
156
167
  event_type=EventType.RUN_SUPERNODE_LEAVE,
157
168
  exit_message="SuperNode terminated gracefully.",
158
- grpc_servers=[clientappio_server],
169
+ grpc_servers=grpc_servers,
159
170
  )
160
171
 
161
172
  # Initialize NodeState, Ffs, and ObjectStore
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "flwr-nightly"
7
- version = "1.21.0.dev20250831"
7
+ version = "1.21.0.dev20250902"
8
8
  description = "Flower: A Friendly Federated AI Framework"
9
9
  license = "Apache-2.0"
10
10
  authors = ["The Flower Authors <hello@flower.ai>"]