flwr-nightly 1.19.0.dev20250510__tar.gz → 1.19.0.dev20250512__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 (338) hide show
  1. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/PKG-INFO +2 -1
  2. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/build.py +82 -57
  3. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/model.baseline.py.tpl +1 -1
  4. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.baseline.py.tpl +2 -3
  5. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +13 -16
  6. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/run/run.py +8 -12
  7. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/constant.py +1 -0
  8. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/linkstate/in_memory_linkstate.py +84 -4
  9. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/linkstate/linkstate.py +23 -0
  10. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/linkstate/sqlite_linkstate.py +98 -8
  11. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/pyproject.toml +2 -1
  12. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/README.md +0 -0
  13. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/__init__.py +0 -0
  14. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/__init__.py +0 -0
  15. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/app.py +0 -0
  16. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/auth_plugin/__init__.py +0 -0
  17. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/auth_plugin/oidc_cli_plugin.py +0 -0
  18. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/cli_user_auth_interceptor.py +0 -0
  19. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/config_utils.py +0 -0
  20. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/constant.py +0 -0
  21. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/example.py +0 -0
  22. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/install.py +0 -0
  23. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/log.py +0 -0
  24. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/login/__init__.py +0 -0
  25. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/login/login.py +0 -0
  26. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/ls.py +0 -0
  27. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/__init__.py +0 -0
  28. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/new.py +0 -0
  29. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/__init__.py +0 -0
  30. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/.gitignore.tpl +0 -0
  31. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/LICENSE.tpl +0 -0
  32. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/README.baseline.md.tpl +0 -0
  33. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/README.flowertune.md.tpl +0 -0
  34. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/README.md.tpl +0 -0
  35. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/__init__.py +0 -0
  36. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/__init__.baseline.py.tpl +0 -0
  37. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
  38. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
  39. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.baseline.py.tpl +1 -1
  40. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.huggingface.py.tpl +0 -0
  41. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.jax.py.tpl +0 -0
  42. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.mlx.py.tpl +0 -0
  43. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
  44. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -0
  45. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.sklearn.py.tpl +0 -0
  46. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -0
  47. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/dataset.baseline.py.tpl +0 -0
  48. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py +0 -0
  49. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +0 -0
  50. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +0 -0
  51. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +0 -0
  52. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +0 -0
  53. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +0 -0
  54. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.huggingface.py.tpl +0 -0
  55. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.jax.py.tpl +0 -0
  56. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.mlx.py.tpl +0 -0
  57. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
  58. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -0
  59. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.sklearn.py.tpl +0 -0
  60. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -0
  61. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/strategy.baseline.py.tpl +0 -0
  62. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/task.huggingface.py.tpl +0 -0
  63. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/task.jax.py.tpl +0 -0
  64. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/task.mlx.py.tpl +0 -0
  65. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/task.numpy.py.tpl +0 -0
  66. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
  67. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/task.sklearn.py.tpl +0 -0
  68. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +0 -0
  69. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/code/utils.baseline.py.tpl +0 -0
  70. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +0 -0
  71. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +0 -0
  72. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl +0 -0
  73. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +0 -0
  74. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +0 -0
  75. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +0 -0
  76. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +0 -0
  77. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +0 -0
  78. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/run/__init__.py +0 -0
  79. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/stop.py +0 -0
  80. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/cli/utils.py +0 -0
  81. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/__init__.py +0 -0
  82. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/app.py +0 -0
  83. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/client.py +0 -0
  84. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/client_app.py +0 -0
  85. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/clientapp/__init__.py +0 -0
  86. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/clientapp/app.py +0 -0
  87. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/clientapp/clientappio_servicer.py +0 -0
  88. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/clientapp/utils.py +0 -0
  89. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/dpfedavg_numpy_client.py +0 -0
  90. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_adapter_client/__init__.py +0 -0
  91. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_adapter_client/connection.py +0 -0
  92. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_client/__init__.py +0 -0
  93. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_client/connection.py +0 -0
  94. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_rere_client/__init__.py +0 -0
  95. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_rere_client/client_interceptor.py +0 -0
  96. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_rere_client/connection.py +0 -0
  97. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/grpc_rere_client/grpc_adapter.py +0 -0
  98. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/message_handler/__init__.py +0 -0
  99. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/message_handler/message_handler.py +0 -0
  100. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/__init__.py +0 -0
  101. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/centraldp_mods.py +0 -0
  102. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/comms_mods.py +0 -0
  103. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/localdp_mod.py +0 -0
  104. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
  105. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
  106. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
  107. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/mod/utils.py +0 -0
  108. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/nodestate/__init__.py +0 -0
  109. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/nodestate/in_memory_nodestate.py +0 -0
  110. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/nodestate/nodestate.py +0 -0
  111. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/nodestate/nodestate_factory.py +0 -0
  112. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/numpy_client.py +0 -0
  113. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/rest_client/__init__.py +0 -0
  114. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/rest_client/connection.py +0 -0
  115. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/run_info_store.py +0 -0
  116. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/supernode/__init__.py +0 -0
  117. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/supernode/app.py +0 -0
  118. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/client/typing.py +0 -0
  119. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/__init__.py +0 -0
  120. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/address.py +0 -0
  121. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/args.py +0 -0
  122. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/auth_plugin/__init__.py +0 -0
  123. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/auth_plugin/auth_plugin.py +0 -0
  124. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/config.py +0 -0
  125. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/context.py +0 -0
  126. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/date.py +0 -0
  127. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/differential_privacy.py +0 -0
  128. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/differential_privacy_constants.py +0 -0
  129. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/dp.py +0 -0
  130. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/event_log_plugin/__init__.py +0 -0
  131. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/event_log_plugin/event_log_plugin.py +0 -0
  132. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/exit/__init__.py +0 -0
  133. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/exit/exit.py +0 -0
  134. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/exit/exit_code.py +0 -0
  135. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/exit_handlers.py +0 -0
  136. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/grpc.py +0 -0
  137. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/heartbeat.py +0 -0
  138. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/inflatable.py +0 -0
  139. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/logger.py +0 -0
  140. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/message.py +0 -0
  141. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/object_ref.py +0 -0
  142. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/parameter.py +0 -0
  143. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/pyproject.py +0 -0
  144. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/__init__.py +0 -0
  145. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/array.py +0 -0
  146. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/arrayrecord.py +0 -0
  147. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/configrecord.py +0 -0
  148. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/conversion_utils.py +0 -0
  149. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/metricrecord.py +0 -0
  150. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/recorddict.py +0 -0
  151. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/record/typeddict.py +0 -0
  152. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/recorddict_compat.py +0 -0
  153. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/retry_invoker.py +0 -0
  154. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/__init__.py +0 -0
  155. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
  156. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
  157. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
  158. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
  159. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/quantization.py +0 -0
  160. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
  161. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
  162. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/serde.py +0 -0
  163. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/serde_utils.py +0 -0
  164. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/telemetry.py +0 -0
  165. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/typing.py +0 -0
  166. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/common/version.py +0 -0
  167. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/__init__.py +0 -0
  168. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/clientappio_pb2.py +0 -0
  169. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/clientappio_pb2.pyi +0 -0
  170. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/clientappio_pb2_grpc.py +0 -0
  171. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/clientappio_pb2_grpc.pyi +0 -0
  172. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/error_pb2.py +0 -0
  173. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/error_pb2.pyi +0 -0
  174. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/error_pb2_grpc.py +0 -0
  175. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/error_pb2_grpc.pyi +0 -0
  176. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/exec_pb2.py +0 -0
  177. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/exec_pb2.pyi +0 -0
  178. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/exec_pb2_grpc.py +0 -0
  179. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/exec_pb2_grpc.pyi +0 -0
  180. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fab_pb2.py +0 -0
  181. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fab_pb2.pyi +0 -0
  182. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fab_pb2_grpc.py +0 -0
  183. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fab_pb2_grpc.pyi +0 -0
  184. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fleet_pb2.py +0 -0
  185. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fleet_pb2.pyi +0 -0
  186. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fleet_pb2_grpc.py +0 -0
  187. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
  188. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/grpcadapter_pb2.py +0 -0
  189. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/grpcadapter_pb2.pyi +0 -0
  190. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/grpcadapter_pb2_grpc.py +0 -0
  191. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/grpcadapter_pb2_grpc.pyi +0 -0
  192. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/heartbeat_pb2.py +0 -0
  193. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/heartbeat_pb2.pyi +0 -0
  194. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/heartbeat_pb2_grpc.py +0 -0
  195. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/heartbeat_pb2_grpc.pyi +0 -0
  196. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/log_pb2.py +0 -0
  197. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/log_pb2.pyi +0 -0
  198. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/log_pb2_grpc.py +0 -0
  199. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/log_pb2_grpc.pyi +0 -0
  200. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/message_pb2.py +0 -0
  201. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/message_pb2.pyi +0 -0
  202. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/message_pb2_grpc.py +0 -0
  203. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/message_pb2_grpc.pyi +0 -0
  204. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/node_pb2.py +0 -0
  205. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/node_pb2.pyi +0 -0
  206. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/node_pb2_grpc.py +0 -0
  207. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/node_pb2_grpc.pyi +0 -0
  208. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/recorddict_pb2.py +0 -0
  209. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/recorddict_pb2.pyi +0 -0
  210. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/recorddict_pb2_grpc.py +0 -0
  211. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/recorddict_pb2_grpc.pyi +0 -0
  212. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/run_pb2.py +0 -0
  213. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/run_pb2.pyi +0 -0
  214. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/run_pb2_grpc.py +0 -0
  215. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/run_pb2_grpc.pyi +0 -0
  216. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/serverappio_pb2.py +0 -0
  217. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/serverappio_pb2.pyi +0 -0
  218. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/serverappio_pb2_grpc.py +0 -0
  219. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/serverappio_pb2_grpc.pyi +0 -0
  220. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/simulationio_pb2.py +0 -0
  221. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/simulationio_pb2.pyi +0 -0
  222. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/simulationio_pb2_grpc.py +0 -0
  223. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/simulationio_pb2_grpc.pyi +0 -0
  224. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/transport_pb2.py +0 -0
  225. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/transport_pb2.pyi +0 -0
  226. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/transport_pb2_grpc.py +0 -0
  227. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
  228. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/py.typed +0 -0
  229. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/__init__.py +0 -0
  230. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/app.py +0 -0
  231. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/client_manager.py +0 -0
  232. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/client_proxy.py +0 -0
  233. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/compat/__init__.py +0 -0
  234. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/compat/app.py +0 -0
  235. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/compat/app_utils.py +0 -0
  236. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/compat/grid_client_proxy.py +0 -0
  237. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/compat/legacy_context.py +0 -0
  238. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/criterion.py +0 -0
  239. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/fleet_event_log_interceptor.py +0 -0
  240. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/grid/__init__.py +0 -0
  241. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/grid/grid.py +0 -0
  242. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/grid/grpc_grid.py +0 -0
  243. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/grid/inmemory_grid.py +0 -0
  244. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/history.py +0 -0
  245. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/run_serverapp.py +0 -0
  246. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/server.py +0 -0
  247. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/server_app.py +0 -0
  248. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/server_config.py +0 -0
  249. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/serverapp/__init__.py +0 -0
  250. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/serverapp/app.py +0 -0
  251. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/serverapp_components.py +0 -0
  252. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/__init__.py +0 -0
  253. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/aggregate.py +0 -0
  254. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/bulyan.py +0 -0
  255. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
  256. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
  257. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
  258. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
  259. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
  260. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedadagrad.py +0 -0
  261. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedadam.py +0 -0
  262. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedavg.py +0 -0
  263. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedavg_android.py +0 -0
  264. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedavgm.py +0 -0
  265. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedmedian.py +0 -0
  266. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedopt.py +0 -0
  267. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedprox.py +0 -0
  268. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
  269. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
  270. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
  271. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
  272. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/fedyogi.py +0 -0
  273. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/krum.py +0 -0
  274. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/qfedavg.py +0 -0
  275. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/strategy/strategy.py +0 -0
  276. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/__init__.py +0 -0
  277. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/ffs/__init__.py +0 -0
  278. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/ffs/disk_ffs.py +0 -0
  279. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/ffs/ffs.py +0 -0
  280. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/ffs/ffs_factory.py +0 -0
  281. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/__init__.py +0 -0
  282. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py +0 -0
  283. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +0 -0
  284. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
  285. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
  286. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
  287. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
  288. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
  289. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
  290. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +0 -0
  291. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +0 -0
  292. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
  293. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/message_handler/message_handler.py +0 -0
  294. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
  295. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +0 -0
  296. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
  297. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
  298. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
  299. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +0 -0
  300. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/fleet/vce/vce_api.py +0 -0
  301. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/linkstate/__init__.py +0 -0
  302. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/linkstate/linkstate_factory.py +0 -0
  303. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/linkstate/utils.py +0 -0
  304. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/serverappio/__init__.py +0 -0
  305. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/serverappio/serverappio_grpc.py +0 -0
  306. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/serverappio/serverappio_servicer.py +0 -0
  307. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/simulation/__init__.py +0 -0
  308. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/simulation/simulationio_grpc.py +0 -0
  309. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/simulation/simulationio_servicer.py +0 -0
  310. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/superlink/utils.py +0 -0
  311. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/typing.py +0 -0
  312. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/utils/__init__.py +0 -0
  313. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/utils/tensorboard.py +0 -0
  314. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/utils/validator.py +0 -0
  315. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/workflow/__init__.py +0 -0
  316. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/workflow/constant.py +0 -0
  317. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/workflow/default_workflows.py +0 -0
  318. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
  319. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
  320. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
  321. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/__init__.py +0 -0
  322. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/app.py +0 -0
  323. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/legacy_app.py +0 -0
  324. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/ray_transport/__init__.py +0 -0
  325. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
  326. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
  327. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/ray_transport/utils.py +0 -0
  328. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/run_simulation.py +0 -0
  329. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/simulation/simulationio_connection.py +0 -0
  330. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/__init__.py +0 -0
  331. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/app.py +0 -0
  332. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/deployment.py +0 -0
  333. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/exec_event_log_interceptor.py +0 -0
  334. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/exec_grpc.py +0 -0
  335. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/exec_servicer.py +0 -0
  336. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/exec_user_auth_interceptor.py +0 -0
  337. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/executor.py +0 -0
  338. {flwr_nightly-1.19.0.dev20250510 → flwr_nightly-1.19.0.dev20250512}/py/flwr/superexec/simulation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: flwr-nightly
3
- Version: 1.19.0.dev20250510
3
+ Version: 1.19.0.dev20250512
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
@@ -31,6 +31,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
31
31
  Classifier: Typing :: Typed
32
32
  Provides-Extra: rest
33
33
  Provides-Extra: simulation
34
+ Requires-Dist: click (<8.2.0)
34
35
  Requires-Dist: cryptography (>=44.0.1,<45.0.0)
35
36
  Requires-Dist: grpcio (>=1.62.3,<2.0.0,!=1.65.0)
36
37
  Requires-Dist: iterators (>=0.0.2,<0.0.3)
@@ -16,10 +16,8 @@
16
16
 
17
17
 
18
18
  import hashlib
19
- import os
20
- import shutil
21
- import tempfile
22
19
  import zipfile
20
+ from io import BytesIO
23
21
  from pathlib import Path
24
22
  from typing import Annotated, Any, Optional, Union
25
23
 
@@ -29,6 +27,7 @@ import typer
29
27
 
30
28
  from flwr.common.constant import FAB_ALLOWED_EXTENSIONS, FAB_DATE, FAB_HASH_TRUNCATION
31
29
 
30
+ from .config_utils import load as load_toml
32
31
  from .config_utils import load_and_validate
33
32
  from .utils import is_valid_project_name
34
33
 
@@ -43,11 +42,11 @@ def write_to_zip(
43
42
  return zipfile_obj
44
43
 
45
44
 
46
- def get_fab_filename(conf: dict[str, Any], fab_hash: str) -> str:
45
+ def get_fab_filename(config: dict[str, Any], fab_hash: str) -> str:
47
46
  """Get the FAB filename based on the given config and FAB hash."""
48
- publisher = conf["tool"]["flwr"]["app"]["publisher"]
49
- name = conf["project"]["name"]
50
- version = conf["project"]["version"].replace(".", "-")
47
+ publisher = config["tool"]["flwr"]["app"]["publisher"]
48
+ name = config["project"]["name"]
49
+ version = config["project"]["version"].replace(".", "-")
51
50
  fab_hash_truncated = fab_hash[:FAB_HASH_TRUNCATION]
52
51
  return f"{publisher}.{name}.{version}.{fab_hash_truncated}.fab"
53
52
 
@@ -89,8 +88,8 @@ def build(
89
88
  )
90
89
  raise typer.Exit(code=1)
91
90
 
92
- conf, errors, warnings = load_and_validate(app / "pyproject.toml")
93
- if conf is None:
91
+ config, errors, warnings = load_and_validate(app / "pyproject.toml")
92
+ if config is None:
94
93
  typer.secho(
95
94
  "Project configuration could not be loaded.\npyproject.toml is invalid:\n"
96
95
  + "\n".join([f"- {line}" for line in errors]),
@@ -107,70 +106,96 @@ def build(
107
106
  bold=True,
108
107
  )
109
108
 
110
- # Load .gitignore rules if present
111
- ignore_spec = _load_gitignore(app)
109
+ # Build FAB
110
+ fab_bytes, fab_hash, _ = build_fab(app)
112
111
 
113
- list_file_content = ""
112
+ # Get the name of the zip file
113
+ fab_filename = get_fab_filename(config, fab_hash)
114
+
115
+ # Write the FAB
116
+ Path(fab_filename).write_bytes(fab_bytes)
117
+
118
+ typer.secho(
119
+ f"🎊 Successfully built {fab_filename}", fg=typer.colors.GREEN, bold=True
120
+ )
121
+
122
+ return fab_filename, fab_hash
114
123
 
115
- # Remove the 'federations' field from 'tool.flwr' if it exists
116
- if (
117
- "tool" in conf
118
- and "flwr" in conf["tool"]
119
- and "federations" in conf["tool"]["flwr"]
120
- ):
121
- del conf["tool"]["flwr"]["federations"]
122
124
 
123
- toml_contents = tomli_w.dumps(conf)
125
+ def build_fab(app: Path) -> tuple[bytes, str, dict[str, Any]]:
126
+ """Build a FAB in memory and return the bytes, hash, and config.
124
127
 
125
- with tempfile.NamedTemporaryFile(suffix=".zip", delete=False) as temp_file:
126
- temp_filename = temp_file.name
128
+ This function assumes that the provided path points to a valid Flower app and
129
+ bundles it into a FAB without performing additional validation.
127
130
 
128
- with zipfile.ZipFile(temp_filename, "w", zipfile.ZIP_DEFLATED) as fab_file:
129
- write_to_zip(fab_file, "pyproject.toml", toml_contents)
131
+ Parameters
132
+ ----------
133
+ app : Path
134
+ Path to the Flower app to bundle into a FAB.
130
135
 
131
- # Continue with adding other files
132
- all_files = [
133
- f
134
- for f in app.rglob("*")
135
- if not ignore_spec.match_file(f)
136
- and f.name != temp_filename
137
- and f.suffix in FAB_ALLOWED_EXTENSIONS
138
- and f.name != "pyproject.toml" # Exclude the original pyproject.toml
139
- ]
136
+ Returns
137
+ -------
138
+ tuple[bytes, str, dict[str, Any]]
139
+ A tuple containing:
140
+ - the FAB as bytes
141
+ - the SHA256 hash of the FAB
142
+ - the project configuration (with the 'federations' field removed)
143
+ """
144
+ app = app.resolve()
145
+
146
+ # Load the pyproject.toml file
147
+ config = load_toml(app / "pyproject.toml")
148
+ if config is None:
149
+ raise ValueError("Project configuration could not be loaded.")
140
150
 
141
- all_files.sort()
151
+ # Remove the 'federations' field if it exists
152
+ if (
153
+ "tool" in config
154
+ and "flwr" in config["tool"]
155
+ and "federations" in config["tool"]["flwr"]
156
+ ):
157
+ del config["tool"]["flwr"]["federations"]
142
158
 
143
- for file_path in all_files:
144
- # Read the file content manually
145
- with open(file_path, "rb") as f:
146
- file_contents = f.read()
159
+ # Load .gitignore rules if present
160
+ ignore_spec = _load_gitignore(app)
147
161
 
148
- archive_path = file_path.relative_to(app)
149
- write_to_zip(fab_file, str(archive_path), file_contents)
162
+ # Search for all files in the app directory
163
+ all_files = [
164
+ f
165
+ for f in app.rglob("*")
166
+ if not ignore_spec.match_file(f)
167
+ and f.suffix in FAB_ALLOWED_EXTENSIONS
168
+ and f.name != "pyproject.toml" # Exclude the original pyproject.toml
169
+ ]
170
+ all_files.sort()
171
+
172
+ # Create a zip file in memory
173
+ list_file_content = ""
150
174
 
151
- # Calculate file info
152
- sha256_hash = hashlib.sha256(file_contents).hexdigest()
153
- file_size_bits = os.path.getsize(file_path) * 8 # size in bits
154
- list_file_content += f"{archive_path},{sha256_hash},{file_size_bits}\n"
175
+ fab_buffer = BytesIO()
176
+ with zipfile.ZipFile(fab_buffer, "w", zipfile.ZIP_DEFLATED) as fab_file:
177
+ # Add pyproject.toml
178
+ write_to_zip(fab_file, "pyproject.toml", tomli_w.dumps(config))
155
179
 
156
- # Add CONTENT and CONTENT.jwt to the zip file
157
- write_to_zip(fab_file, ".info/CONTENT", list_file_content)
180
+ for file_path in all_files:
181
+ # Read the file content manually
182
+ file_contents = file_path.read_bytes()
158
183
 
159
- # Get hash of FAB file
160
- content = Path(temp_filename).read_bytes()
161
- fab_hash = hashlib.sha256(content).hexdigest()
184
+ archive_path = str(file_path.relative_to(app))
185
+ write_to_zip(fab_file, archive_path, file_contents)
162
186
 
163
- # Set the name of the zip file
164
- fab_filename = get_fab_filename(conf, fab_hash)
187
+ # Calculate file info
188
+ sha256_hash = hashlib.sha256(file_contents).hexdigest()
189
+ file_size_bits = len(file_contents) * 8 # size in bits
190
+ list_file_content += f"{archive_path},{sha256_hash},{file_size_bits}\n"
165
191
 
166
- # Once the temporary zip file is created, rename it to the final filename
167
- shutil.move(temp_filename, fab_filename)
192
+ # Add CONTENT and CONTENT.jwt to the zip file
193
+ write_to_zip(fab_file, ".info/CONTENT", list_file_content)
168
194
 
169
- typer.secho(
170
- f"🎊 Successfully built {fab_filename}", fg=typer.colors.GREEN, bold=True
171
- )
195
+ fab_bytes = fab_buffer.getvalue()
196
+ fab_hash = hashlib.sha256(fab_bytes).hexdigest()
172
197
 
173
- return fab_filename, fab_hash
198
+ return fab_bytes, fab_hash, config
174
199
 
175
200
 
176
201
  def _load_gitignore(app: Path) -> pathspec.PathSpec:
@@ -76,5 +76,5 @@ def get_weights(net):
76
76
  def set_weights(net, parameters):
77
77
  """Apply parameters to an existing model."""
78
78
  params_dict = zip(net.state_dict().keys(), parameters)
79
- state_dict = OrderedDict({k: torch.tensor(v) for k, v in params_dict})
79
+ state_dict = OrderedDict({k: torch.from_numpy(v) for k, v in params_dict})
80
80
  net.load_state_dict(state_dict, strict=True)
@@ -1,15 +1,14 @@
1
1
  """$project_name: A Flower Baseline."""
2
2
 
3
- from typing import List, Tuple
4
-
5
3
  from flwr.common import Context, Metrics, ndarrays_to_parameters
6
4
  from flwr.server import ServerApp, ServerAppComponents, ServerConfig
7
5
  from flwr.server.strategy import FedAvg
6
+
8
7
  from $import_name.model import Net, get_weights
9
8
 
10
9
 
11
10
  # Define metric aggregation function
12
- def weighted_average(metrics: List[Tuple[int, Metrics]]) -> Metrics:
11
+ def weighted_average(metrics: list[tuple[int, Metrics]]) -> Metrics:
13
12
  """Do weighted average of accuracy metric."""
14
13
  # Multiply accuracy of each client by number of examples used
15
14
  accuracies = [num_examples * float(m["accuracy"]) for num_examples, m in metrics]
@@ -10,8 +10,8 @@ license = "Apache-2.0"
10
10
  dependencies = [
11
11
  "flwr[simulation]>=1.19.0",
12
12
  "flwr-datasets[vision]>=0.5.0",
13
- "torch==2.5.1",
14
- "torchvision==0.20.1",
13
+ "torch==2.6.0",
14
+ "torchvision==0.21.0",
15
15
  ]
16
16
 
17
17
  [tool.hatch.metadata]
@@ -23,28 +23,23 @@ dev = [
23
23
  "black==24.2.0",
24
24
  "docformatter==1.7.5",
25
25
  "mypy==1.8.0",
26
- "pylint==3.2.6",
27
- "flake8==5.0.4",
28
- "pytest==6.2.4",
26
+ "pylint==3.3.1",
27
+ "pytest==7.4.4",
29
28
  "pytest-watch==4.2.0",
30
- "ruff==0.1.9",
29
+ "ruff==0.4.5",
31
30
  "types-requests==2.31.0.20240125",
32
31
  ]
33
32
 
34
33
  [tool.isort]
35
34
  profile = "black"
36
- known_first_party = ["flwr"]
37
35
 
38
36
  [tool.black]
39
37
  line-length = 88
40
- target-version = ["py38", "py39", "py310", "py311"]
38
+ target-version = ["py310", "py311", "py312"]
41
39
 
42
40
  [tool.pytest.ini_options]
43
41
  minversion = "6.2"
44
42
  addopts = "-qq"
45
- testpaths = [
46
- "flwr_baselines",
47
- ]
48
43
 
49
44
  [tool.mypy]
50
45
  ignore_missing_imports = true
@@ -82,11 +77,8 @@ wrap-summaries = 88
82
77
  wrap-descriptions = 88
83
78
 
84
79
  [tool.ruff]
85
- target-version = "py38"
80
+ target-version = "py310"
86
81
  line-length = 88
87
- select = ["D", "E", "F", "W", "B", "ISC", "C4"]
88
- fixable = ["D", "E", "F", "W", "B", "ISC", "C4"]
89
- ignore = ["B024", "B027"]
90
82
  exclude = [
91
83
  ".bzr",
92
84
  ".direnv",
@@ -111,7 +103,12 @@ exclude = [
111
103
  "proto",
112
104
  ]
113
105
 
114
- [tool.ruff.pydocstyle]
106
+ [tool.ruff.lint]
107
+ select = ["D", "E", "F", "W", "B", "ISC", "C4", "UP"]
108
+ fixable = ["D", "E", "F", "W", "B", "ISC", "C4", "UP"]
109
+ ignore = ["B024", "B027", "D205", "D209"]
110
+
111
+ [tool.ruff.lint.pydocstyle]
115
112
  convention = "numpy"
116
113
 
117
114
  [tool.hatch.build.targets.wheel]
@@ -24,9 +24,8 @@ from typing import Annotated, Any, Optional
24
24
  import typer
25
25
  from rich.console import Console
26
26
 
27
- from flwr.cli.build import build
27
+ from flwr.cli.build import build_fab, get_fab_filename
28
28
  from flwr.cli.config_utils import (
29
- get_fab_metadata,
30
29
  load_and_validate,
31
30
  process_loaded_project_config,
32
31
  validate_federation_in_project_config,
@@ -34,6 +33,7 @@ from flwr.cli.config_utils import (
34
33
  from flwr.cli.constant import FEDERATION_CONFIG_HELP_MESSAGE
35
34
  from flwr.common.config import (
36
35
  flatten_dict,
36
+ get_metadata_from_config,
37
37
  parse_config_args,
38
38
  user_config_to_configrecord,
39
39
  )
@@ -158,18 +158,14 @@ def _run_with_exec_api(
158
158
  channel = init_channel(app, federation_config, auth_plugin)
159
159
  stub = ExecStub(channel)
160
160
 
161
- fab_path, fab_hash = build(app)
162
- content = Path(fab_path).read_bytes()
163
- fab_id, fab_version = get_fab_metadata(Path(fab_path))
161
+ fab_bytes, fab_hash, config = build_fab(app)
162
+ fab_id, fab_version = get_metadata_from_config(config)
164
163
 
165
- # Delete FAB file once the bytes is computed
166
- Path(fab_path).unlink()
167
-
168
- fab = Fab(fab_hash, content)
164
+ fab = Fab(fab_hash, fab_bytes)
169
165
 
170
166
  # Construct a `ConfigRecord` out of a flattened `UserConfig`
171
- fed_conf = flatten_dict(federation_config.get("options", {}))
172
- c_record = user_config_to_configrecord(fed_conf)
167
+ fed_config = flatten_dict(federation_config.get("options", {}))
168
+ c_record = user_config_to_configrecord(fed_config)
173
169
 
174
170
  req = StartRunRequest(
175
171
  fab=fab_to_proto(fab),
@@ -194,7 +190,7 @@ def _run_with_exec_api(
194
190
  "fab-name": fab_id.rsplit("/", maxsplit=1)[-1],
195
191
  "fab-version": fab_version,
196
192
  "fab-hash": fab_hash[:8],
197
- "fab-filename": fab_path,
193
+ "fab-filename": get_fab_filename(config, fab_hash),
198
194
  }
199
195
  )
200
196
  restore_output()
@@ -62,6 +62,7 @@ HEARTBEAT_BASE_MULTIPLIER = 0.8
62
62
  HEARTBEAT_RANDOM_RANGE = (-0.1, 0.1)
63
63
  HEARTBEAT_MAX_INTERVAL = 1e300
64
64
  HEARTBEAT_PATIENCE = 2
65
+ RUN_FAILURE_DETAILS_NO_HEARTBEAT = "No heartbeat received from the run."
65
66
 
66
67
  # IDs
67
68
  RUN_ID_NUM_BYTES = 8
@@ -25,12 +25,15 @@ from uuid import UUID, uuid4
25
25
 
26
26
  from flwr.common import Context, Message, log, now
27
27
  from flwr.common.constant import (
28
+ HEARTBEAT_MAX_INTERVAL,
28
29
  HEARTBEAT_PATIENCE,
29
30
  MESSAGE_TTL_TOLERANCE,
30
31
  NODE_ID_NUM_BYTES,
32
+ RUN_FAILURE_DETAILS_NO_HEARTBEAT,
31
33
  RUN_ID_NUM_BYTES,
32
34
  SUPERLINK_NODE_ID,
33
35
  Status,
36
+ SubStatus,
34
37
  )
35
38
  from flwr.common.record import ConfigRecord
36
39
  from flwr.common.typing import Run, RunStatus, UserConfig
@@ -52,8 +55,11 @@ class RunRecord: # pylint: disable=R0902
52
55
  """The record of a specific run, including its status and timestamps."""
53
56
 
54
57
  run: Run
58
+ active_until: float = 0.0
59
+ heartbeat_interval: float = 0.0
55
60
  logs: list[tuple[float, str]] = field(default_factory=list)
56
61
  log_lock: threading.Lock = field(default_factory=threading.Lock)
62
+ lock: threading.RLock = field(default_factory=threading.RLock)
57
63
 
58
64
 
59
65
  class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
@@ -461,8 +467,29 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
461
467
  with self.lock:
462
468
  return set(self.run_ids.keys())
463
469
 
470
+ def _check_and_tag_inactive_run(self, run_ids: set[int]) -> None:
471
+ """Check if any runs are no longer active.
472
+
473
+ Marks runs with status 'starting' or 'running' as failed
474
+ if they have not sent a heartbeat before `active_until`.
475
+ """
476
+ current = now()
477
+ for record in [self.run_ids[run_id] for run_id in run_ids]:
478
+ with record.lock:
479
+ if record.run.status.status in (Status.STARTING, Status.RUNNING):
480
+ if record.active_until < current.timestamp():
481
+ record.run.status = RunStatus(
482
+ status=Status.FINISHED,
483
+ sub_status=SubStatus.FAILED,
484
+ details=RUN_FAILURE_DETAILS_NO_HEARTBEAT,
485
+ )
486
+ record.run.finished_at = now().isoformat()
487
+
464
488
  def get_run(self, run_id: int) -> Optional[Run]:
465
489
  """Retrieve information about the run with the specified `run_id`."""
490
+ # Check if runs are still active
491
+ self._check_and_tag_inactive_run(run_ids={run_id})
492
+
466
493
  with self.lock:
467
494
  if run_id not in self.run_ids:
468
495
  log(ERROR, "`run_id` is invalid")
@@ -471,6 +498,9 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
471
498
 
472
499
  def get_run_status(self, run_ids: set[int]) -> dict[int, RunStatus]:
473
500
  """Retrieve the statuses for the specified runs."""
501
+ # Check if runs are still active
502
+ self._check_and_tag_inactive_run(run_ids=run_ids)
503
+
474
504
  with self.lock:
475
505
  return {
476
506
  run_id: self.run_ids[run_id].run.status
@@ -480,12 +510,16 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
480
510
 
481
511
  def update_run_status(self, run_id: int, new_status: RunStatus) -> bool:
482
512
  """Update the status of the run with the specified `run_id`."""
513
+ # Check if runs are still active
514
+ self._check_and_tag_inactive_run(run_ids={run_id})
515
+
483
516
  with self.lock:
484
517
  # Check if the run_id exists
485
518
  if run_id not in self.run_ids:
486
519
  log(ERROR, "`run_id` is invalid")
487
520
  return False
488
521
 
522
+ with self.run_ids[run_id].lock:
489
523
  # Check if the status transition is valid
490
524
  current_status = self.run_ids[run_id].run.status
491
525
  if not is_valid_transition(current_status, new_status):
@@ -507,14 +541,23 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
507
541
  )
508
542
  return False
509
543
 
510
- # Update the status
544
+ # Initialize heartbeat_interval and active_until
545
+ # when switching to starting or running
546
+ current = now()
511
547
  run_record = self.run_ids[run_id]
548
+ if new_status.status in (Status.STARTING, Status.RUNNING):
549
+ run_record.heartbeat_interval = HEARTBEAT_MAX_INTERVAL
550
+ run_record.active_until = (
551
+ current.timestamp() + run_record.heartbeat_interval
552
+ )
553
+
554
+ # Update the run status
512
555
  if new_status.status == Status.STARTING:
513
- run_record.run.starting_at = now().isoformat()
556
+ run_record.run.starting_at = current.isoformat()
514
557
  elif new_status.status == Status.RUNNING:
515
- run_record.run.running_at = now().isoformat()
558
+ run_record.run.running_at = current.isoformat()
516
559
  elif new_status.status == Status.FINISHED:
517
- run_record.run.finished_at = now().isoformat()
560
+ run_record.run.finished_at = current.isoformat()
518
561
  run_record.run.status = new_status
519
562
  return True
520
563
 
@@ -558,6 +601,43 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
558
601
  return True
559
602
  return False
560
603
 
604
+ def acknowledge_app_heartbeat(self, run_id: int, heartbeat_interval: float) -> bool:
605
+ """Acknowledge a heartbeat received from a ServerApp for a given run.
606
+
607
+ A run with status `"running"` is considered alive as long as it sends heartbeats
608
+ within the tolerated interval: HEARTBEAT_PATIENCE × heartbeat_interval.
609
+ HEARTBEAT_PATIENCE = N allows for N-1 missed heartbeat before the run is
610
+ marked as `"completed:failed"`.
611
+ """
612
+ with self.lock:
613
+ # Search for the run
614
+ record = self.run_ids.get(run_id)
615
+
616
+ # Check if the run_id exists
617
+ if record is None:
618
+ log(ERROR, "`run_id` is invalid")
619
+ return False
620
+
621
+ with record.lock:
622
+ # Check if runs are still active
623
+ self._check_and_tag_inactive_run(run_ids={run_id})
624
+
625
+ # Check if the run is of status "running"/"starting"
626
+ current_status = record.run.status
627
+ if current_status.status not in (Status.RUNNING, Status.STARTING):
628
+ log(
629
+ ERROR,
630
+ 'Cannot acknowledge heartbeat for run with status "%s"',
631
+ current_status.status,
632
+ )
633
+ return False
634
+
635
+ # Update the `active_until` and `heartbeat_interval` for the given run
636
+ current = now().timestamp()
637
+ record.active_until = current + HEARTBEAT_PATIENCE * heartbeat_interval
638
+ record.heartbeat_interval = heartbeat_interval
639
+ return True
640
+
561
641
  def get_serverapp_context(self, run_id: int) -> Optional[Context]:
562
642
  """Get the context for the specified `run_id`."""
563
643
  return self.contexts.get(run_id)
@@ -292,6 +292,29 @@ class LinkState(abc.ABC): # pylint: disable=R0904
292
292
  True if the heartbeat is successfully acknowledged; otherwise, False.
293
293
  """
294
294
 
295
+ @abc.abstractmethod
296
+ def acknowledge_app_heartbeat(self, run_id: int, heartbeat_interval: float) -> bool:
297
+ """Acknowledge a heartbeat received from a ServerApp for a given run.
298
+
299
+ A run with status `"running"` is considered alive as long as it sends heartbeats
300
+ within the tolerated interval: HEARTBEAT_PATIENCE × heartbeat_interval.
301
+ HEARTBEAT_PATIENCE = N allows for N-1 missed heartbeat before the run is
302
+ marked as `"completed:failed"`.
303
+
304
+ Parameters
305
+ ----------
306
+ run_id : int
307
+ The `run_id` from which the heartbeat was received.
308
+ heartbeat_interval : float
309
+ The interval (in seconds) from the current timestamp within which the next
310
+ heartbeat from the ServerApp for this run must be received.
311
+
312
+ Returns
313
+ -------
314
+ is_acknowledged : bool
315
+ True if the heartbeat is successfully acknowledged; otherwise, False.
316
+ """
317
+
295
318
  @abc.abstractmethod
296
319
  def get_serverapp_context(self, run_id: int) -> Optional[Context]:
297
320
  """Get the context for the specified `run_id`.