flwr-nightly 1.19.0.dev20250429__tar.gz → 1.19.0.dev20250430__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 (334) hide show
  1. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/PKG-INFO +1 -1
  2. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/grpc_rere_client/connection.py +32 -32
  3. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/grpc_rere_client/grpc_adapter.py +6 -6
  4. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/rest_client/connection.py +24 -36
  5. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/constant.py +10 -7
  6. flwr_nightly-1.19.0.dev20250430/py/flwr/common/heartbeat.py +103 -0
  7. flwr_nightly-1.19.0.dev20250430/py/flwr/proto/fleet_pb2.py +56 -0
  8. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/fleet_pb2.pyi +13 -13
  9. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/fleet_pb2_grpc.py +13 -13
  10. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/fleet_pb2_grpc.pyi +6 -6
  11. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +3 -3
  12. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +12 -6
  13. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/message_handler/message_handler.py +8 -8
  14. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +7 -7
  15. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/vce/vce_api.py +2 -2
  16. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/linkstate/in_memory_linkstate.py +16 -11
  17. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/linkstate/linkstate.py +13 -8
  18. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/linkstate/sqlite_linkstate.py +19 -15
  19. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/linkstate/utils.py +3 -2
  20. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/pyproject.toml +1 -1
  21. flwr_nightly-1.19.0.dev20250429/py/flwr/client/heartbeat.py +0 -74
  22. flwr_nightly-1.19.0.dev20250429/py/flwr/proto/fleet_pb2.py +0 -56
  23. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/README.md +0 -0
  24. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/__init__.py +0 -0
  25. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/__init__.py +0 -0
  26. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/app.py +0 -0
  27. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/auth_plugin/__init__.py +0 -0
  28. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/auth_plugin/oidc_cli_plugin.py +0 -0
  29. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/build.py +0 -0
  30. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/cli_user_auth_interceptor.py +0 -0
  31. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/config_utils.py +0 -0
  32. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/constant.py +0 -0
  33. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/example.py +0 -0
  34. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/install.py +0 -0
  35. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/log.py +0 -0
  36. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/login/__init__.py +0 -0
  37. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/login/login.py +0 -0
  38. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/ls.py +0 -0
  39. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/__init__.py +0 -0
  40. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/new.py +0 -0
  41. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/__init__.py +0 -0
  42. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/.gitignore.tpl +0 -0
  43. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/LICENSE.tpl +0 -0
  44. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/README.baseline.md.tpl +0 -0
  45. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/README.flowertune.md.tpl +0 -0
  46. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/README.md.tpl +0 -0
  47. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/__init__.py +0 -0
  48. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/__init__.baseline.py.tpl +0 -0
  49. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
  50. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
  51. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/client.baseline.py.tpl +0 -0
  52. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/client.huggingface.py.tpl +0 -0
  53. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/client.jax.py.tpl +0 -0
  54. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/client.mlx.py.tpl +0 -0
  55. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
  56. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -0
  57. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/client.sklearn.py.tpl +0 -0
  58. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -0
  59. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/dataset.baseline.py.tpl +0 -0
  60. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py +0 -0
  61. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +0 -0
  62. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +0 -0
  63. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +0 -0
  64. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +0 -0
  65. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +0 -0
  66. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/model.baseline.py.tpl +0 -0
  67. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/server.baseline.py.tpl +0 -0
  68. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/server.huggingface.py.tpl +0 -0
  69. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/server.jax.py.tpl +0 -0
  70. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/server.mlx.py.tpl +0 -0
  71. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
  72. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -0
  73. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/server.sklearn.py.tpl +0 -0
  74. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -0
  75. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/strategy.baseline.py.tpl +0 -0
  76. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/task.huggingface.py.tpl +0 -0
  77. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/task.jax.py.tpl +0 -0
  78. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/task.mlx.py.tpl +0 -0
  79. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/task.numpy.py.tpl +0 -0
  80. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
  81. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/task.sklearn.py.tpl +0 -0
  82. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +0 -0
  83. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/code/utils.baseline.py.tpl +0 -0
  84. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +0 -0
  85. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +0 -0
  86. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +0 -0
  87. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl +0 -0
  88. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +0 -0
  89. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +0 -0
  90. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +0 -0
  91. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +0 -0
  92. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +0 -0
  93. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/run/__init__.py +0 -0
  94. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/run/run.py +0 -0
  95. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/stop.py +0 -0
  96. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/cli/utils.py +0 -0
  97. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/__init__.py +0 -0
  98. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/app.py +0 -0
  99. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/client.py +0 -0
  100. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/client_app.py +0 -0
  101. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/clientapp/__init__.py +0 -0
  102. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/clientapp/app.py +0 -0
  103. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/clientapp/clientappio_servicer.py +0 -0
  104. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/clientapp/utils.py +0 -0
  105. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/dpfedavg_numpy_client.py +0 -0
  106. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/grpc_adapter_client/__init__.py +0 -0
  107. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/grpc_adapter_client/connection.py +0 -0
  108. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/grpc_client/__init__.py +0 -0
  109. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/grpc_client/connection.py +0 -0
  110. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/grpc_rere_client/__init__.py +0 -0
  111. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/grpc_rere_client/client_interceptor.py +0 -0
  112. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/message_handler/__init__.py +0 -0
  113. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/message_handler/message_handler.py +0 -0
  114. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/mod/__init__.py +0 -0
  115. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/mod/centraldp_mods.py +0 -0
  116. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/mod/comms_mods.py +0 -0
  117. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/mod/localdp_mod.py +0 -0
  118. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
  119. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
  120. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
  121. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/mod/utils.py +0 -0
  122. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/nodestate/__init__.py +0 -0
  123. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/nodestate/in_memory_nodestate.py +0 -0
  124. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/nodestate/nodestate.py +0 -0
  125. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/nodestate/nodestate_factory.py +0 -0
  126. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/numpy_client.py +0 -0
  127. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/rest_client/__init__.py +0 -0
  128. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/run_info_store.py +0 -0
  129. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/supernode/__init__.py +0 -0
  130. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/supernode/app.py +0 -0
  131. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/client/typing.py +0 -0
  132. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/__init__.py +0 -0
  133. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/address.py +0 -0
  134. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/args.py +0 -0
  135. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/auth_plugin/__init__.py +0 -0
  136. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/auth_plugin/auth_plugin.py +0 -0
  137. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/config.py +0 -0
  138. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/context.py +0 -0
  139. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/date.py +0 -0
  140. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/differential_privacy.py +0 -0
  141. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/differential_privacy_constants.py +0 -0
  142. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/dp.py +0 -0
  143. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/event_log_plugin/__init__.py +0 -0
  144. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/event_log_plugin/event_log_plugin.py +0 -0
  145. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/exit/__init__.py +0 -0
  146. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/exit/exit.py +0 -0
  147. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/exit/exit_code.py +0 -0
  148. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/exit_handlers.py +0 -0
  149. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/grpc.py +0 -0
  150. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/logger.py +0 -0
  151. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/message.py +0 -0
  152. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/object_ref.py +0 -0
  153. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/parameter.py +0 -0
  154. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/pyproject.py +0 -0
  155. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/record/__init__.py +0 -0
  156. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/record/array.py +0 -0
  157. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/record/arrayrecord.py +0 -0
  158. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/record/configrecord.py +0 -0
  159. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/record/conversion_utils.py +0 -0
  160. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/record/metricrecord.py +0 -0
  161. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/record/recorddict.py +0 -0
  162. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/record/typeddict.py +0 -0
  163. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/recorddict_compat.py +0 -0
  164. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/retry_invoker.py +0 -0
  165. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/secure_aggregation/__init__.py +0 -0
  166. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
  167. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
  168. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
  169. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
  170. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/secure_aggregation/quantization.py +0 -0
  171. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
  172. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
  173. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/serde.py +0 -0
  174. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/telemetry.py +0 -0
  175. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/typing.py +0 -0
  176. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/common/version.py +0 -0
  177. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/__init__.py +0 -0
  178. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/clientappio_pb2.py +0 -0
  179. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/clientappio_pb2.pyi +0 -0
  180. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/clientappio_pb2_grpc.py +0 -0
  181. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/clientappio_pb2_grpc.pyi +0 -0
  182. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/error_pb2.py +0 -0
  183. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/error_pb2.pyi +0 -0
  184. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/error_pb2_grpc.py +0 -0
  185. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/error_pb2_grpc.pyi +0 -0
  186. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/exec_pb2.py +0 -0
  187. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/exec_pb2.pyi +0 -0
  188. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/exec_pb2_grpc.py +0 -0
  189. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/exec_pb2_grpc.pyi +0 -0
  190. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/fab_pb2.py +0 -0
  191. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/fab_pb2.pyi +0 -0
  192. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/fab_pb2_grpc.py +0 -0
  193. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/fab_pb2_grpc.pyi +0 -0
  194. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/grpcadapter_pb2.py +0 -0
  195. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/grpcadapter_pb2.pyi +0 -0
  196. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/grpcadapter_pb2_grpc.py +0 -0
  197. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/grpcadapter_pb2_grpc.pyi +0 -0
  198. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/log_pb2.py +0 -0
  199. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/log_pb2.pyi +0 -0
  200. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/log_pb2_grpc.py +0 -0
  201. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/log_pb2_grpc.pyi +0 -0
  202. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/message_pb2.py +0 -0
  203. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/message_pb2.pyi +0 -0
  204. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/message_pb2_grpc.py +0 -0
  205. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/message_pb2_grpc.pyi +0 -0
  206. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/node_pb2.py +0 -0
  207. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/node_pb2.pyi +0 -0
  208. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/node_pb2_grpc.py +0 -0
  209. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/node_pb2_grpc.pyi +0 -0
  210. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/recorddict_pb2.py +0 -0
  211. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/recorddict_pb2.pyi +0 -0
  212. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/recorddict_pb2_grpc.py +0 -0
  213. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/recorddict_pb2_grpc.pyi +0 -0
  214. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/run_pb2.py +0 -0
  215. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/run_pb2.pyi +0 -0
  216. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/run_pb2_grpc.py +0 -0
  217. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/run_pb2_grpc.pyi +0 -0
  218. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/serverappio_pb2.py +0 -0
  219. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/serverappio_pb2.pyi +0 -0
  220. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/serverappio_pb2_grpc.py +0 -0
  221. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/serverappio_pb2_grpc.pyi +0 -0
  222. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/simulationio_pb2.py +0 -0
  223. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/simulationio_pb2.pyi +0 -0
  224. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/simulationio_pb2_grpc.py +0 -0
  225. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/simulationio_pb2_grpc.pyi +0 -0
  226. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/transport_pb2.py +0 -0
  227. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/transport_pb2.pyi +0 -0
  228. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/transport_pb2_grpc.py +0 -0
  229. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
  230. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/py.typed +0 -0
  231. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/__init__.py +0 -0
  232. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/app.py +0 -0
  233. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/client_manager.py +0 -0
  234. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/client_proxy.py +0 -0
  235. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/compat/__init__.py +0 -0
  236. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/compat/app.py +0 -0
  237. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/compat/app_utils.py +0 -0
  238. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/compat/grid_client_proxy.py +0 -0
  239. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/compat/legacy_context.py +0 -0
  240. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/criterion.py +0 -0
  241. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/fleet_event_log_interceptor.py +0 -0
  242. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/grid/__init__.py +0 -0
  243. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/grid/grid.py +0 -0
  244. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/grid/grpc_grid.py +0 -0
  245. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/grid/inmemory_grid.py +0 -0
  246. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/history.py +0 -0
  247. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/run_serverapp.py +0 -0
  248. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/server.py +0 -0
  249. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/server_app.py +0 -0
  250. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/server_config.py +0 -0
  251. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/serverapp/__init__.py +0 -0
  252. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/serverapp/app.py +0 -0
  253. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/serverapp_components.py +0 -0
  254. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/__init__.py +0 -0
  255. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/aggregate.py +0 -0
  256. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/bulyan.py +0 -0
  257. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
  258. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
  259. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
  260. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
  261. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
  262. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/fedadagrad.py +0 -0
  263. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/fedadam.py +0 -0
  264. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/fedavg.py +0 -0
  265. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/fedavg_android.py +0 -0
  266. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/fedavgm.py +0 -0
  267. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/fedmedian.py +0 -0
  268. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/fedopt.py +0 -0
  269. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/fedprox.py +0 -0
  270. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
  271. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
  272. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
  273. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
  274. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/fedyogi.py +0 -0
  275. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/krum.py +0 -0
  276. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/qfedavg.py +0 -0
  277. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/strategy/strategy.py +0 -0
  278. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/__init__.py +0 -0
  279. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/ffs/__init__.py +0 -0
  280. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/ffs/disk_ffs.py +0 -0
  281. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/ffs/ffs.py +0 -0
  282. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/ffs/ffs_factory.py +0 -0
  283. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/__init__.py +0 -0
  284. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py +0 -0
  285. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
  286. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
  287. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
  288. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
  289. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
  290. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
  291. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +0 -0
  292. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
  293. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
  294. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
  295. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
  296. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
  297. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +0 -0
  298. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/linkstate/__init__.py +0 -0
  299. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/linkstate/linkstate_factory.py +0 -0
  300. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/serverappio/__init__.py +0 -0
  301. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/serverappio/serverappio_grpc.py +0 -0
  302. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/serverappio/serverappio_servicer.py +0 -0
  303. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/simulation/__init__.py +0 -0
  304. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/simulation/simulationio_grpc.py +0 -0
  305. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/simulation/simulationio_servicer.py +0 -0
  306. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/superlink/utils.py +0 -0
  307. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/typing.py +0 -0
  308. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/utils/__init__.py +0 -0
  309. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/utils/tensorboard.py +0 -0
  310. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/utils/validator.py +0 -0
  311. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/workflow/__init__.py +0 -0
  312. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/workflow/constant.py +0 -0
  313. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/workflow/default_workflows.py +0 -0
  314. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
  315. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
  316. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
  317. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/simulation/__init__.py +0 -0
  318. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/simulation/app.py +0 -0
  319. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/simulation/legacy_app.py +0 -0
  320. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/simulation/ray_transport/__init__.py +0 -0
  321. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
  322. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
  323. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/simulation/ray_transport/utils.py +0 -0
  324. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/simulation/run_simulation.py +0 -0
  325. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/simulation/simulationio_connection.py +0 -0
  326. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/superexec/__init__.py +0 -0
  327. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/superexec/app.py +0 -0
  328. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/superexec/deployment.py +0 -0
  329. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/superexec/exec_event_log_interceptor.py +0 -0
  330. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/superexec/exec_grpc.py +0 -0
  331. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/superexec/exec_servicer.py +0 -0
  332. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/superexec/exec_user_auth_interceptor.py +0 -0
  333. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/superexec/executor.py +0 -0
  334. {flwr_nightly-1.19.0.dev20250429 → flwr_nightly-1.19.0.dev20250430}/py/flwr/superexec/simulation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flwr-nightly
3
- Version: 1.19.0.dev20250429
3
+ Version: 1.19.0.dev20250430
4
4
  Summary: Flower: A Friendly Federated AI Framework
5
5
  Home-page: https://flower.ai
6
6
  License: Apache-2.0
@@ -15,8 +15,6 @@
15
15
  """Contextmanager for a gRPC request-response channel to the Flower server."""
16
16
 
17
17
 
18
- import random
19
- import threading
20
18
  from collections.abc import Iterator, Sequence
21
19
  from contextlib import contextmanager
22
20
  from copy import copy
@@ -27,16 +25,11 @@ from typing import Callable, Optional, Union, cast
27
25
  import grpc
28
26
  from cryptography.hazmat.primitives.asymmetric import ec
29
27
 
30
- from flwr.client.heartbeat import start_ping_loop
31
28
  from flwr.client.message_handler.message_handler import validate_out_message
32
29
  from flwr.common import GRPC_MAX_MESSAGE_LENGTH
33
- from flwr.common.constant import (
34
- PING_BASE_MULTIPLIER,
35
- PING_CALL_TIMEOUT,
36
- PING_DEFAULT_INTERVAL,
37
- PING_RANDOM_RANGE,
38
- )
30
+ from flwr.common.constant import HEARTBEAT_CALL_TIMEOUT, HEARTBEAT_DEFAULT_INTERVAL
39
31
  from flwr.common.grpc import create_channel, on_channel_state_change
32
+ from flwr.common.heartbeat import HeartbeatSender
40
33
  from flwr.common.logger import log
41
34
  from flwr.common.message import Message, Metadata
42
35
  from flwr.common.retry_invoker import RetryInvoker
@@ -49,8 +42,8 @@ from flwr.proto.fab_pb2 import GetFabRequest, GetFabResponse # pylint: disable=
49
42
  from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
50
43
  CreateNodeRequest,
51
44
  DeleteNodeRequest,
52
- PingRequest,
53
- PingResponse,
45
+ HeartbeatRequest,
46
+ HeartbeatResponse,
54
47
  PullMessagesRequest,
55
48
  PullMessagesResponse,
56
49
  PushMessagesRequest,
@@ -151,8 +144,6 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
151
144
  stub = adapter_cls(channel)
152
145
  metadata: Optional[Metadata] = None
153
146
  node: Optional[Node] = None
154
- ping_thread: Optional[threading.Thread] = None
155
- ping_stop_event = threading.Event()
156
147
 
157
148
  def _should_giveup_fn(e: Exception) -> bool:
158
149
  if e.code() == grpc.StatusCode.PERMISSION_DENIED: # type: ignore
@@ -166,45 +157,54 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
166
157
  retry_invoker.should_giveup = _should_giveup_fn
167
158
 
168
159
  ###########################################################################
169
- # ping/create_node/delete_node/receive/send/get_run functions
160
+ # heartbeat/create_node/delete_node/receive/send/get_run functions
170
161
  ###########################################################################
171
162
 
172
- def ping() -> None:
163
+ def heartbeat() -> bool:
173
164
  # Get Node
174
165
  if node is None:
175
166
  log(ERROR, "Node instance missing")
176
- return
167
+ return False
177
168
 
178
- # Construct the ping request
179
- req = PingRequest(node=node, ping_interval=PING_DEFAULT_INTERVAL)
169
+ # Construct the heartbeat request
170
+ req = HeartbeatRequest(node=node, heartbeat_interval=HEARTBEAT_DEFAULT_INTERVAL)
180
171
 
181
172
  # Call FleetAPI
182
- res: PingResponse = stub.Ping(req, timeout=PING_CALL_TIMEOUT)
173
+ try:
174
+ res: HeartbeatResponse = stub.Heartbeat(req, timeout=HEARTBEAT_CALL_TIMEOUT)
175
+ except grpc.RpcError as e:
176
+ status_code = e.code()
177
+ if status_code == grpc.StatusCode.UNAVAILABLE:
178
+ return False
179
+ if status_code == grpc.StatusCode.DEADLINE_EXCEEDED:
180
+ return False
181
+ raise
183
182
 
184
183
  # Check if success
185
184
  if not res.success:
186
- raise RuntimeError("Ping failed unexpectedly.")
185
+ raise RuntimeError(
186
+ "Heartbeat failed unexpectedly. The SuperLink does not "
187
+ "recognize this SuperNode."
188
+ )
189
+ return True
187
190
 
188
- # Wait
189
- rd = random.uniform(*PING_RANDOM_RANGE)
190
- next_interval: float = PING_DEFAULT_INTERVAL - PING_CALL_TIMEOUT
191
- next_interval *= PING_BASE_MULTIPLIER + rd
192
- if not ping_stop_event.is_set():
193
- ping_stop_event.wait(next_interval)
191
+ heartbeat_sender = HeartbeatSender(heartbeat)
194
192
 
195
193
  def create_node() -> Optional[int]:
196
194
  """Set create_node."""
197
195
  # Call FleetAPI
198
- create_node_request = CreateNodeRequest(ping_interval=PING_DEFAULT_INTERVAL)
196
+ create_node_request = CreateNodeRequest(
197
+ heartbeat_interval=HEARTBEAT_DEFAULT_INTERVAL
198
+ )
199
199
  create_node_response = retry_invoker.invoke(
200
200
  stub.CreateNode,
201
201
  request=create_node_request,
202
202
  )
203
203
 
204
- # Remember the node and the ping-loop thread
205
- nonlocal node, ping_thread
204
+ # Remember the node and start the heartbeat sender
205
+ nonlocal node
206
206
  node = cast(Node, create_node_response.node)
207
- ping_thread = start_ping_loop(ping, ping_stop_event)
207
+ heartbeat_sender.start()
208
208
  return node.node_id
209
209
 
210
210
  def delete_node() -> None:
@@ -215,8 +215,8 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
215
215
  log(ERROR, "Node instance missing")
216
216
  return
217
217
 
218
- # Stop the ping-loop thread
219
- ping_stop_event.set()
218
+ # Stop the heartbeat sender
219
+ heartbeat_sender.stop()
220
220
 
221
221
  # Call FleetAPI
222
222
  delete_node_request = DeleteNodeRequest(node=node)
@@ -38,8 +38,8 @@ from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
38
38
  CreateNodeResponse,
39
39
  DeleteNodeRequest,
40
40
  DeleteNodeResponse,
41
- PingRequest,
42
- PingResponse,
41
+ HeartbeatRequest,
42
+ HeartbeatResponse,
43
43
  PullMessagesRequest,
44
44
  PullMessagesResponse,
45
45
  PushMessagesRequest,
@@ -120,11 +120,11 @@ class GrpcAdapter:
120
120
  """."""
121
121
  return self._send_and_receive(request, DeleteNodeResponse, **kwargs)
122
122
 
123
- def Ping( # pylint: disable=C0103
124
- self, request: PingRequest, **kwargs: Any
125
- ) -> PingResponse:
123
+ def Heartbeat( # pylint: disable=C0103
124
+ self, request: HeartbeatRequest, **kwargs: Any
125
+ ) -> HeartbeatResponse:
126
126
  """."""
127
- return self._send_and_receive(request, PingResponse, **kwargs)
127
+ return self._send_and_receive(request, HeartbeatResponse, **kwargs)
128
128
 
129
129
  def PullMessages( # pylint: disable=C0103
130
130
  self, request: PullMessagesRequest, **kwargs: Any
@@ -15,8 +15,6 @@
15
15
  """Contextmanager for a REST request-response channel to the Flower server."""
16
16
 
17
17
 
18
- import random
19
- import threading
20
18
  from collections.abc import Iterator
21
19
  from contextlib import contextmanager
22
20
  from copy import copy
@@ -27,16 +25,11 @@ from cryptography.hazmat.primitives.asymmetric import ec
27
25
  from google.protobuf.message import Message as GrpcMessage
28
26
  from requests.exceptions import ConnectionError as RequestsConnectionError
29
27
 
30
- from flwr.client.heartbeat import start_ping_loop
31
28
  from flwr.client.message_handler.message_handler import validate_out_message
32
29
  from flwr.common import GRPC_MAX_MESSAGE_LENGTH
33
- from flwr.common.constant import (
34
- PING_BASE_MULTIPLIER,
35
- PING_CALL_TIMEOUT,
36
- PING_DEFAULT_INTERVAL,
37
- PING_RANDOM_RANGE,
38
- )
30
+ from flwr.common.constant import HEARTBEAT_DEFAULT_INTERVAL
39
31
  from flwr.common.exit import ExitCode, flwr_exit
32
+ from flwr.common.heartbeat import HeartbeatSender
40
33
  from flwr.common.logger import log
41
34
  from flwr.common.message import Message, Metadata
42
35
  from flwr.common.retry_invoker import RetryInvoker
@@ -48,8 +41,8 @@ from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
48
41
  CreateNodeResponse,
49
42
  DeleteNodeRequest,
50
43
  DeleteNodeResponse,
51
- PingRequest,
52
- PingResponse,
44
+ HeartbeatRequest,
45
+ HeartbeatResponse,
53
46
  PullMessagesRequest,
54
47
  PullMessagesResponse,
55
48
  PushMessagesRequest,
@@ -68,7 +61,7 @@ PATH_CREATE_NODE: str = "api/v0/fleet/create-node"
68
61
  PATH_DELETE_NODE: str = "api/v0/fleet/delete-node"
69
62
  PATH_PULL_MESSAGES: str = "/api/v0/fleet/pull-messages"
70
63
  PATH_PUSH_MESSAGES: str = "/api/v0/fleet/push-messages"
71
- PATH_PING: str = "api/v0/fleet/ping"
64
+ PATH_PING: str = "api/v0/fleet/heartbeat"
72
65
  PATH_GET_RUN: str = "/api/v0/fleet/get-run"
73
66
  PATH_GET_FAB: str = "/api/v0/fleet/get-fab"
74
67
 
@@ -160,11 +153,9 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
160
153
  # Shared variables for inner functions
161
154
  metadata: Optional[Metadata] = None
162
155
  node: Optional[Node] = None
163
- ping_thread: Optional[threading.Thread] = None
164
- ping_stop_event = threading.Event()
165
156
 
166
157
  ###########################################################################
167
- # ping/create_node/delete_node/receive/send/get_run functions
158
+ # heartbeat/create_node/delete_node/receive/send/get_run functions
168
159
  ###########################################################################
169
160
 
170
161
  def _request(
@@ -214,44 +205,43 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
214
205
  grpc_res.ParseFromString(res.content)
215
206
  return grpc_res
216
207
 
217
- def ping() -> None:
208
+ def heartbeat() -> bool:
218
209
  # Get Node
219
210
  if node is None:
220
211
  log(ERROR, "Node instance missing")
221
- return
212
+ return False
222
213
 
223
- # Construct the ping request
224
- req = PingRequest(node=node, ping_interval=PING_DEFAULT_INTERVAL)
214
+ # Construct the heartbeat request
215
+ req = HeartbeatRequest(node=node, heartbeat_interval=HEARTBEAT_DEFAULT_INTERVAL)
225
216
 
226
217
  # Send the request
227
- res = _request(req, PingResponse, PATH_PING, retry=False)
218
+ res = _request(req, HeartbeatResponse, PATH_PING, retry=False)
228
219
  if res is None:
229
- return
220
+ return False
230
221
 
231
222
  # Check if success
232
223
  if not res.success:
233
- raise RuntimeError("Ping failed unexpectedly.")
224
+ raise RuntimeError(
225
+ "Heartbeat failed unexpectedly. The SuperLink does not "
226
+ "recognize this SuperNode."
227
+ )
228
+ return True
234
229
 
235
- # Wait
236
- rd = random.uniform(*PING_RANDOM_RANGE)
237
- next_interval: float = PING_DEFAULT_INTERVAL - PING_CALL_TIMEOUT
238
- next_interval *= PING_BASE_MULTIPLIER + rd
239
- if not ping_stop_event.is_set():
240
- ping_stop_event.wait(next_interval)
230
+ heartbeat_sender = HeartbeatSender(heartbeat)
241
231
 
242
232
  def create_node() -> Optional[int]:
243
233
  """Set create_node."""
244
- req = CreateNodeRequest(ping_interval=PING_DEFAULT_INTERVAL)
234
+ req = CreateNodeRequest(heartbeat_interval=HEARTBEAT_DEFAULT_INTERVAL)
245
235
 
246
236
  # Send the request
247
237
  res = _request(req, CreateNodeResponse, PATH_CREATE_NODE)
248
238
  if res is None:
249
239
  return None
250
240
 
251
- # Remember the node and the ping-loop thread
252
- nonlocal node, ping_thread
241
+ # Remember the node and start the heartbeat sender
242
+ nonlocal node
253
243
  node = res.node
254
- ping_thread = start_ping_loop(ping, ping_stop_event)
244
+ heartbeat_sender.start()
255
245
  return node.node_id
256
246
 
257
247
  def delete_node() -> None:
@@ -261,10 +251,8 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
261
251
  log(ERROR, "Node instance missing")
262
252
  return
263
253
 
264
- # Stop the ping-loop thread
265
- ping_stop_event.set()
266
- if ping_thread is not None:
267
- ping_thread.join()
254
+ # Stop the heartbeat sender
255
+ heartbeat_sender.stop()
268
256
 
269
257
  # Send DeleteNode request
270
258
  req = DeleteNodeRequest(node=node)
@@ -55,13 +55,13 @@ EXEC_API_DEFAULT_SERVER_ADDRESS = f"{SERVER_OCTET}:{EXEC_API_PORT}"
55
55
  SIMULATIONIO_API_DEFAULT_SERVER_ADDRESS = f"{SERVER_OCTET}:{SIMULATIONIO_PORT}"
56
56
  SIMULATIONIO_API_DEFAULT_CLIENT_ADDRESS = f"{CLIENT_OCTET}:{SIMULATIONIO_PORT}"
57
57
 
58
- # Constants for ping
59
- PING_DEFAULT_INTERVAL = 30
60
- PING_CALL_TIMEOUT = 5
61
- PING_BASE_MULTIPLIER = 0.8
62
- PING_RANDOM_RANGE = (-0.1, 0.1)
63
- PING_MAX_INTERVAL = 1e300
64
- PING_PATIENCE = 2
58
+ # Constants for heartbeat
59
+ HEARTBEAT_DEFAULT_INTERVAL = 30
60
+ HEARTBEAT_CALL_TIMEOUT = 5
61
+ HEARTBEAT_BASE_MULTIPLIER = 0.8
62
+ HEARTBEAT_RANDOM_RANGE = (-0.1, 0.1)
63
+ HEARTBEAT_MAX_INTERVAL = 1e300
64
+ HEARTBEAT_PATIENCE = 2
65
65
 
66
66
  # IDs
67
67
  RUN_ID_NUM_BYTES = 8
@@ -121,6 +121,9 @@ TIMESTAMP_HEADER = "flwr-timestamp"
121
121
  TIMESTAMP_TOLERANCE = 10 # General tolerance for timestamp verification
122
122
  SYSTEM_TIME_TOLERANCE = 5 # Allowance for system time drift
123
123
 
124
+ # Constants for grpc retry
125
+ GRPC_RETRY_MAX_DELAY = 20 # Maximum delay duration between two consecutive retries.
126
+
124
127
  # Constants for ArrayRecord
125
128
  GC_THRESHOLD = 200_000_000 # 200 MB
126
129
 
@@ -0,0 +1,103 @@
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
+ """Heartbeat sender."""
16
+
17
+
18
+ import random
19
+ import threading
20
+ from typing import Callable
21
+
22
+ from .constant import (
23
+ HEARTBEAT_BASE_MULTIPLIER,
24
+ HEARTBEAT_CALL_TIMEOUT,
25
+ HEARTBEAT_DEFAULT_INTERVAL,
26
+ HEARTBEAT_RANDOM_RANGE,
27
+ )
28
+ from .retry_invoker import RetryInvoker, exponential
29
+
30
+
31
+ class HeartbeatFailure(Exception):
32
+ """Exception raised when a heartbeat fails."""
33
+
34
+
35
+ class HeartbeatSender:
36
+ """Periodically send heartbeat signals to a server in a background thread.
37
+
38
+ This class uses the provided `heartbeat_fn` to send heartbeats. If a heartbeat
39
+ attempt fails, it will be retried using an exponential backoff strategy.
40
+
41
+ Parameters
42
+ ----------
43
+ heartbeat_fn : Callable[[], bool]
44
+ Function used to send a heartbeat signal. It should return True if the heartbeat
45
+ succeeds, or False if it fails. Any internal exceptions (e.g., gRPC errors)
46
+ should be handled within this function to ensure boolean return values.
47
+ """
48
+
49
+ def __init__(
50
+ self,
51
+ heartbeat_fn: Callable[[], bool],
52
+ ) -> None:
53
+ self.heartbeat_fn = heartbeat_fn
54
+ self._stop_event = threading.Event()
55
+ self._thread = threading.Thread(target=self._run, daemon=True)
56
+ self._retry_invoker = RetryInvoker(
57
+ lambda: exponential(max_delay=20),
58
+ HeartbeatFailure, # The only exception we want to retry on
59
+ max_tries=None,
60
+ max_time=None,
61
+ # Allow the stop event to interrupt the wait
62
+ wait_function=self._stop_event.wait, # type: ignore
63
+ )
64
+
65
+ def start(self) -> None:
66
+ """Start the heartbeat sender."""
67
+ if self._thread.is_alive():
68
+ raise RuntimeError("Heartbeat sender is already running.")
69
+ if self._stop_event.is_set():
70
+ raise RuntimeError("Cannot start a stopped heartbeat sender.")
71
+ self._thread.start()
72
+
73
+ def stop(self) -> None:
74
+ """Stop the heartbeat sender."""
75
+ if not self._thread.is_alive():
76
+ raise RuntimeError("Heartbeat sender is not running.")
77
+ self._stop_event.set()
78
+ self._thread.join()
79
+
80
+ def _run(self) -> None:
81
+ """Periodically send heartbeats until stopped."""
82
+ while not self._stop_event.is_set():
83
+ # Attempt to send a heartbeat with retry on failure
84
+ self._retry_invoker.invoke(self._heartbeat)
85
+
86
+ # Calculate the interval for the next heartbeat
87
+ # Formula: next_interval = (interval - timeout) * random.uniform(0.7, 0.9)
88
+ rd = random.uniform(*HEARTBEAT_RANDOM_RANGE)
89
+ next_interval: float = HEARTBEAT_DEFAULT_INTERVAL - HEARTBEAT_CALL_TIMEOUT
90
+ next_interval *= HEARTBEAT_BASE_MULTIPLIER + rd
91
+
92
+ # Wait for the calculated interval or exit early if stopped
93
+ self._stop_event.wait(next_interval)
94
+
95
+ def _heartbeat(self) -> None:
96
+ """Send a single heartbeat and raise an exception if it fails.
97
+
98
+ Call the provided `heartbeat_fn`. If the function returns False,
99
+ a `HeartbeatFailure` exception is raised to trigger the retry mechanism.
100
+ """
101
+ if not self._stop_event.is_set():
102
+ if not self.heartbeat_fn():
103
+ raise HeartbeatFailure
@@ -0,0 +1,56 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: flwr/proto/fleet.proto
4
+ # Protobuf Python Version: 4.25.1
5
+ """Generated protocol buffer code."""
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ from google.protobuf.internal import builder as _builder
10
+ # @@protoc_insertion_point(imports)
11
+
12
+ _sym_db = _symbol_database.Default()
13
+
14
+
15
+ from flwr.proto import node_pb2 as flwr_dot_proto_dot_node__pb2
16
+ from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2
17
+ from flwr.proto import fab_pb2 as flwr_dot_proto_dot_fab__pb2
18
+ from flwr.proto import message_pb2 as flwr_dot_proto_dot_message__pb2
19
+
20
+
21
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x66lwr/proto/fleet.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x14\x66lwr/proto/run.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x18\x66lwr/proto/message.proto\"/\n\x11\x43reateNodeRequest\x12\x1a\n\x12heartbeat_interval\x18\x01 \x01(\x01\"4\n\x12\x43reateNodeResponse\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"3\n\x11\x44\x65leteNodeRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"\x14\n\x12\x44\x65leteNodeResponse\"N\n\x10HeartbeatRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x1a\n\x12heartbeat_interval\x18\x02 \x01(\x01\"$\n\x11HeartbeatResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\"J\n\x13PullMessagesRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x13\n\x0bmessage_ids\x18\x02 \x03(\t\"l\n\x14PullMessagesResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12*\n\rmessages_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.Message\"a\n\x13PushMessagesRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12*\n\rmessages_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.Message\"\xb0\x01\n\x14PushMessagesResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12>\n\x07results\x18\x02 \x03(\x0b\x32-.flwr.proto.PushMessagesResponse.ResultsEntry\x1a.\n\x0cResultsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\r:\x02\x38\x01\"\x1e\n\tReconnect\x12\x11\n\treconnect\x18\x01 \x01(\x04\x32\xa1\x04\n\x05\x46leet\x12M\n\nCreateNode\x12\x1d.flwr.proto.CreateNodeRequest\x1a\x1e.flwr.proto.CreateNodeResponse\"\x00\x12M\n\nDeleteNode\x12\x1d.flwr.proto.DeleteNodeRequest\x1a\x1e.flwr.proto.DeleteNodeResponse\"\x00\x12J\n\tHeartbeat\x12\x1c.flwr.proto.HeartbeatRequest\x1a\x1d.flwr.proto.HeartbeatResponse\"\x00\x12S\n\x0cPullMessages\x12\x1f.flwr.proto.PullMessagesRequest\x1a .flwr.proto.PullMessagesResponse\"\x00\x12S\n\x0cPushMessages\x12\x1f.flwr.proto.PushMessagesRequest\x1a .flwr.proto.PushMessagesResponse\"\x00\x12\x41\n\x06GetRun\x12\x19.flwr.proto.GetRunRequest\x1a\x1a.flwr.proto.GetRunResponse\"\x00\x12\x41\n\x06GetFab\x12\x19.flwr.proto.GetFabRequest\x1a\x1a.flwr.proto.GetFabResponse\"\x00\x62\x06proto3')
22
+
23
+ _globals = globals()
24
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
25
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.fleet_pb2', _globals)
26
+ if _descriptor._USE_C_DESCRIPTORS == False:
27
+ DESCRIPTOR._options = None
28
+ _globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._options = None
29
+ _globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_options = b'8\001'
30
+ _globals['_CREATENODEREQUEST']._serialized_start=131
31
+ _globals['_CREATENODEREQUEST']._serialized_end=178
32
+ _globals['_CREATENODERESPONSE']._serialized_start=180
33
+ _globals['_CREATENODERESPONSE']._serialized_end=232
34
+ _globals['_DELETENODEREQUEST']._serialized_start=234
35
+ _globals['_DELETENODEREQUEST']._serialized_end=285
36
+ _globals['_DELETENODERESPONSE']._serialized_start=287
37
+ _globals['_DELETENODERESPONSE']._serialized_end=307
38
+ _globals['_HEARTBEATREQUEST']._serialized_start=309
39
+ _globals['_HEARTBEATREQUEST']._serialized_end=387
40
+ _globals['_HEARTBEATRESPONSE']._serialized_start=389
41
+ _globals['_HEARTBEATRESPONSE']._serialized_end=425
42
+ _globals['_PULLMESSAGESREQUEST']._serialized_start=427
43
+ _globals['_PULLMESSAGESREQUEST']._serialized_end=501
44
+ _globals['_PULLMESSAGESRESPONSE']._serialized_start=503
45
+ _globals['_PULLMESSAGESRESPONSE']._serialized_end=611
46
+ _globals['_PUSHMESSAGESREQUEST']._serialized_start=613
47
+ _globals['_PUSHMESSAGESREQUEST']._serialized_end=710
48
+ _globals['_PUSHMESSAGESRESPONSE']._serialized_start=713
49
+ _globals['_PUSHMESSAGESRESPONSE']._serialized_end=889
50
+ _globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_start=843
51
+ _globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_end=889
52
+ _globals['_RECONNECT']._serialized_start=891
53
+ _globals['_RECONNECT']._serialized_end=921
54
+ _globals['_FLEET']._serialized_start=924
55
+ _globals['_FLEET']._serialized_end=1469
56
+ # @@protoc_insertion_point(module_scope)
@@ -16,13 +16,13 @@ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
16
16
  class CreateNodeRequest(google.protobuf.message.Message):
17
17
  """CreateNode messages"""
18
18
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
19
- PING_INTERVAL_FIELD_NUMBER: builtins.int
20
- ping_interval: builtins.float
19
+ HEARTBEAT_INTERVAL_FIELD_NUMBER: builtins.int
20
+ heartbeat_interval: builtins.float
21
21
  def __init__(self,
22
22
  *,
23
- ping_interval: builtins.float = ...,
23
+ heartbeat_interval: builtins.float = ...,
24
24
  ) -> None: ...
25
- def ClearField(self, field_name: typing_extensions.Literal["ping_interval",b"ping_interval"]) -> None: ...
25
+ def ClearField(self, field_name: typing_extensions.Literal["heartbeat_interval",b"heartbeat_interval"]) -> None: ...
26
26
  global___CreateNodeRequest = CreateNodeRequest
27
27
 
28
28
  class CreateNodeResponse(google.protobuf.message.Message):
@@ -58,24 +58,24 @@ class DeleteNodeResponse(google.protobuf.message.Message):
58
58
  ) -> None: ...
59
59
  global___DeleteNodeResponse = DeleteNodeResponse
60
60
 
61
- class PingRequest(google.protobuf.message.Message):
62
- """Ping messages"""
61
+ class HeartbeatRequest(google.protobuf.message.Message):
62
+ """Heartbeat messages"""
63
63
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
64
64
  NODE_FIELD_NUMBER: builtins.int
65
- PING_INTERVAL_FIELD_NUMBER: builtins.int
65
+ HEARTBEAT_INTERVAL_FIELD_NUMBER: builtins.int
66
66
  @property
67
67
  def node(self) -> flwr.proto.node_pb2.Node: ...
68
- ping_interval: builtins.float
68
+ heartbeat_interval: builtins.float
69
69
  def __init__(self,
70
70
  *,
71
71
  node: typing.Optional[flwr.proto.node_pb2.Node] = ...,
72
- ping_interval: builtins.float = ...,
72
+ heartbeat_interval: builtins.float = ...,
73
73
  ) -> None: ...
74
74
  def HasField(self, field_name: typing_extensions.Literal["node",b"node"]) -> builtins.bool: ...
75
- def ClearField(self, field_name: typing_extensions.Literal["node",b"node","ping_interval",b"ping_interval"]) -> None: ...
76
- global___PingRequest = PingRequest
75
+ def ClearField(self, field_name: typing_extensions.Literal["heartbeat_interval",b"heartbeat_interval","node",b"node"]) -> None: ...
76
+ global___HeartbeatRequest = HeartbeatRequest
77
77
 
78
- class PingResponse(google.protobuf.message.Message):
78
+ class HeartbeatResponse(google.protobuf.message.Message):
79
79
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
80
80
  SUCCESS_FIELD_NUMBER: builtins.int
81
81
  success: builtins.bool
@@ -84,7 +84,7 @@ class PingResponse(google.protobuf.message.Message):
84
84
  success: builtins.bool = ...,
85
85
  ) -> None: ...
86
86
  def ClearField(self, field_name: typing_extensions.Literal["success",b"success"]) -> None: ...
87
- global___PingResponse = PingResponse
87
+ global___HeartbeatResponse = HeartbeatResponse
88
88
 
89
89
  class PullMessagesRequest(google.protobuf.message.Message):
90
90
  """PullMessages messages"""
@@ -26,10 +26,10 @@ class FleetStub(object):
26
26
  request_serializer=flwr_dot_proto_dot_fleet__pb2.DeleteNodeRequest.SerializeToString,
27
27
  response_deserializer=flwr_dot_proto_dot_fleet__pb2.DeleteNodeResponse.FromString,
28
28
  )
29
- self.Ping = channel.unary_unary(
30
- '/flwr.proto.Fleet/Ping',
31
- request_serializer=flwr_dot_proto_dot_fleet__pb2.PingRequest.SerializeToString,
32
- response_deserializer=flwr_dot_proto_dot_fleet__pb2.PingResponse.FromString,
29
+ self.Heartbeat = channel.unary_unary(
30
+ '/flwr.proto.Fleet/Heartbeat',
31
+ request_serializer=flwr_dot_proto_dot_fleet__pb2.HeartbeatRequest.SerializeToString,
32
+ response_deserializer=flwr_dot_proto_dot_fleet__pb2.HeartbeatResponse.FromString,
33
33
  )
34
34
  self.PullMessages = channel.unary_unary(
35
35
  '/flwr.proto.Fleet/PullMessages',
@@ -68,7 +68,7 @@ class FleetServicer(object):
68
68
  context.set_details('Method not implemented!')
69
69
  raise NotImplementedError('Method not implemented!')
70
70
 
71
- def Ping(self, request, context):
71
+ def Heartbeat(self, request, context):
72
72
  """Missing associated documentation comment in .proto file."""
73
73
  context.set_code(grpc.StatusCode.UNIMPLEMENTED)
74
74
  context.set_details('Method not implemented!')
@@ -118,10 +118,10 @@ def add_FleetServicer_to_server(servicer, server):
118
118
  request_deserializer=flwr_dot_proto_dot_fleet__pb2.DeleteNodeRequest.FromString,
119
119
  response_serializer=flwr_dot_proto_dot_fleet__pb2.DeleteNodeResponse.SerializeToString,
120
120
  ),
121
- 'Ping': grpc.unary_unary_rpc_method_handler(
122
- servicer.Ping,
123
- request_deserializer=flwr_dot_proto_dot_fleet__pb2.PingRequest.FromString,
124
- response_serializer=flwr_dot_proto_dot_fleet__pb2.PingResponse.SerializeToString,
121
+ 'Heartbeat': grpc.unary_unary_rpc_method_handler(
122
+ servicer.Heartbeat,
123
+ request_deserializer=flwr_dot_proto_dot_fleet__pb2.HeartbeatRequest.FromString,
124
+ response_serializer=flwr_dot_proto_dot_fleet__pb2.HeartbeatResponse.SerializeToString,
125
125
  ),
126
126
  'PullMessages': grpc.unary_unary_rpc_method_handler(
127
127
  servicer.PullMessages,
@@ -188,7 +188,7 @@ class Fleet(object):
188
188
  insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
189
189
 
190
190
  @staticmethod
191
- def Ping(request,
191
+ def Heartbeat(request,
192
192
  target,
193
193
  options=(),
194
194
  channel_credentials=None,
@@ -198,9 +198,9 @@ class Fleet(object):
198
198
  wait_for_ready=None,
199
199
  timeout=None,
200
200
  metadata=None):
201
- return grpc.experimental.unary_unary(request, target, '/flwr.proto.Fleet/Ping',
202
- flwr_dot_proto_dot_fleet__pb2.PingRequest.SerializeToString,
203
- flwr_dot_proto_dot_fleet__pb2.PingResponse.FromString,
201
+ return grpc.experimental.unary_unary(request, target, '/flwr.proto.Fleet/Heartbeat',
202
+ flwr_dot_proto_dot_fleet__pb2.HeartbeatRequest.SerializeToString,
203
+ flwr_dot_proto_dot_fleet__pb2.HeartbeatResponse.FromString,
204
204
  options, channel_credentials,
205
205
  insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
206
206
 
@@ -18,9 +18,9 @@ class FleetStub:
18
18
  flwr.proto.fleet_pb2.DeleteNodeRequest,
19
19
  flwr.proto.fleet_pb2.DeleteNodeResponse]
20
20
 
21
- Ping: grpc.UnaryUnaryMultiCallable[
22
- flwr.proto.fleet_pb2.PingRequest,
23
- flwr.proto.fleet_pb2.PingResponse]
21
+ Heartbeat: grpc.UnaryUnaryMultiCallable[
22
+ flwr.proto.fleet_pb2.HeartbeatRequest,
23
+ flwr.proto.fleet_pb2.HeartbeatResponse]
24
24
 
25
25
  PullMessages: grpc.UnaryUnaryMultiCallable[
26
26
  flwr.proto.fleet_pb2.PullMessagesRequest,
@@ -62,10 +62,10 @@ class FleetServicer(metaclass=abc.ABCMeta):
62
62
  ) -> flwr.proto.fleet_pb2.DeleteNodeResponse: ...
63
63
 
64
64
  @abc.abstractmethod
65
- def Ping(self,
66
- request: flwr.proto.fleet_pb2.PingRequest,
65
+ def Heartbeat(self,
66
+ request: flwr.proto.fleet_pb2.HeartbeatRequest,
67
67
  context: grpc.ServicerContext,
68
- ) -> flwr.proto.fleet_pb2.PingResponse: ...
68
+ ) -> flwr.proto.fleet_pb2.HeartbeatResponse: ...
69
69
 
70
70
  @abc.abstractmethod
71
71
  def PullMessages(self,
@@ -35,7 +35,7 @@ from flwr.proto.fab_pb2 import GetFabRequest # pylint: disable=E0611
35
35
  from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
36
36
  CreateNodeRequest,
37
37
  DeleteNodeRequest,
38
- PingRequest,
38
+ HeartbeatRequest,
39
39
  PullMessagesRequest,
40
40
  PushMessagesRequest,
41
41
  )
@@ -81,8 +81,8 @@ class GrpcAdapterServicer(grpcadapter_pb2_grpc.GrpcAdapterServicer, FleetService
81
81
  return _handle(request, context, CreateNodeRequest, self.CreateNode)
82
82
  if request.grpc_message_name == DeleteNodeRequest.__qualname__:
83
83
  return _handle(request, context, DeleteNodeRequest, self.DeleteNode)
84
- if request.grpc_message_name == PingRequest.__qualname__:
85
- return _handle(request, context, PingRequest, self.Ping)
84
+ if request.grpc_message_name == HeartbeatRequest.__qualname__:
85
+ return _handle(request, context, HeartbeatRequest, self.Heartbeat)
86
86
  if request.grpc_message_name == GetRunRequest.__qualname__:
87
87
  return _handle(request, context, GetRunRequest, self.GetRun)
88
88
  if request.grpc_message_name == GetFabRequest.__qualname__: