flwr-nightly 1.12.0.dev20241008__tar.gz → 1.12.0.dev20241010__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.

Potentially problematic release.


This version of flwr-nightly might be problematic. Click here for more details.

Files changed (307) hide show
  1. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/PKG-INFO +1 -1
  2. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/pyproject.toml +6 -1
  3. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/build.py +60 -29
  4. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/config_utils.py +10 -0
  5. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/install.py +60 -20
  6. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +1 -1
  7. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/run/run.py +5 -5
  8. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/app.py +13 -3
  9. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/clientapp/app.py +5 -2
  10. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/clientapp/utils.py +11 -5
  11. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/grpc_rere_client/connection.py +3 -0
  12. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/config.py +18 -5
  13. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/message.py +5 -0
  14. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/recordset_compat.py +10 -0
  15. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/retry_invoker.py +15 -0
  16. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/client_manager.py +2 -0
  17. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/driver/inmemory_driver.py +1 -1
  18. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/run_serverapp.py +11 -13
  19. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/driver/driver_servicer.py +1 -1
  20. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +3 -1
  21. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/vce/vce_api.py +1 -1
  22. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/state/in_memory_state.py +26 -8
  23. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/state/sqlite_state.py +46 -11
  24. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/state/state.py +1 -7
  25. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/state/utils.py +0 -10
  26. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/LICENSE +0 -0
  27. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/README.md +0 -0
  28. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/__init__.py +0 -0
  29. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/__init__.py +0 -0
  30. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/app.py +0 -0
  31. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/example.py +0 -0
  32. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/log.py +0 -0
  33. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/__init__.py +0 -0
  34. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/new.py +0 -0
  35. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/__init__.py +0 -0
  36. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/.gitignore.tpl +0 -0
  37. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/LICENSE.tpl +0 -0
  38. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/README.baseline.md.tpl +0 -0
  39. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/README.flowertune.md.tpl +0 -0
  40. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/README.md.tpl +0 -0
  41. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/__init__.py +0 -0
  42. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/__init__.baseline.py.tpl +0 -0
  43. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
  44. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
  45. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/client.baseline.py.tpl +0 -0
  46. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/client.huggingface.py.tpl +0 -0
  47. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/client.jax.py.tpl +0 -0
  48. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/client.mlx.py.tpl +0 -0
  49. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
  50. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -0
  51. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/client.sklearn.py.tpl +0 -0
  52. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -0
  53. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/dataset.baseline.py.tpl +0 -0
  54. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py +0 -0
  55. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +0 -0
  56. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +0 -0
  57. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +0 -0
  58. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +0 -0
  59. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +0 -0
  60. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/model.baseline.py.tpl +0 -0
  61. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/server.baseline.py.tpl +0 -0
  62. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/server.huggingface.py.tpl +0 -0
  63. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/server.jax.py.tpl +0 -0
  64. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/server.mlx.py.tpl +0 -0
  65. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
  66. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -0
  67. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/server.sklearn.py.tpl +0 -0
  68. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -0
  69. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/strategy.baseline.py.tpl +0 -0
  70. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/task.huggingface.py.tpl +0 -0
  71. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/task.jax.py.tpl +0 -0
  72. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/task.mlx.py.tpl +0 -0
  73. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/task.numpy.py.tpl +0 -0
  74. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
  75. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/task.sklearn.py.tpl +0 -0
  76. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +0 -0
  77. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/code/utils.baseline.py.tpl +0 -0
  78. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +0 -0
  79. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +0 -0
  80. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl +0 -0
  81. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +0 -0
  82. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +0 -0
  83. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +0 -0
  84. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +0 -0
  85. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +0 -0
  86. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/run/__init__.py +0 -0
  87. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/cli/utils.py +0 -0
  88. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/__init__.py +0 -0
  89. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/client.py +0 -0
  90. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/client_app.py +0 -0
  91. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/clientapp/__init__.py +0 -0
  92. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/clientapp/clientappio_servicer.py +0 -0
  93. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/dpfedavg_numpy_client.py +0 -0
  94. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/grpc_adapter_client/__init__.py +0 -0
  95. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/grpc_adapter_client/connection.py +0 -0
  96. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/grpc_client/__init__.py +0 -0
  97. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/grpc_client/connection.py +0 -0
  98. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/grpc_rere_client/__init__.py +0 -0
  99. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/grpc_rere_client/client_interceptor.py +0 -0
  100. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/grpc_rere_client/grpc_adapter.py +0 -0
  101. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/heartbeat.py +0 -0
  102. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/message_handler/__init__.py +0 -0
  103. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/message_handler/message_handler.py +0 -0
  104. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/message_handler/task_handler.py +0 -0
  105. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/mod/__init__.py +0 -0
  106. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/mod/centraldp_mods.py +0 -0
  107. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/mod/comms_mods.py +0 -0
  108. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/mod/localdp_mod.py +0 -0
  109. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
  110. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
  111. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
  112. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/mod/utils.py +0 -0
  113. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/node_state.py +0 -0
  114. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/node_state_tests.py +0 -0
  115. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/numpy_client.py +0 -0
  116. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/rest_client/__init__.py +0 -0
  117. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/rest_client/connection.py +0 -0
  118. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/supernode/__init__.py +0 -0
  119. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/supernode/app.py +0 -0
  120. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/client/typing.py +0 -0
  121. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/__init__.py +0 -0
  122. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/address.py +0 -0
  123. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/constant.py +0 -0
  124. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/context.py +0 -0
  125. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/date.py +0 -0
  126. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/differential_privacy.py +0 -0
  127. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/differential_privacy_constants.py +0 -0
  128. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/dp.py +0 -0
  129. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/exit_handlers.py +0 -0
  130. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/grpc.py +0 -0
  131. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/logger.py +0 -0
  132. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/object_ref.py +0 -0
  133. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/parameter.py +0 -0
  134. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/pyproject.py +0 -0
  135. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/record/__init__.py +0 -0
  136. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/record/configsrecord.py +0 -0
  137. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/record/conversion_utils.py +0 -0
  138. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/record/metricsrecord.py +0 -0
  139. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/record/parametersrecord.py +0 -0
  140. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/record/recordset.py +0 -0
  141. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/record/typeddict.py +0 -0
  142. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/secure_aggregation/__init__.py +0 -0
  143. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
  144. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
  145. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
  146. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
  147. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/secure_aggregation/quantization.py +0 -0
  148. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
  149. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
  150. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/serde.py +0 -0
  151. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/telemetry.py +0 -0
  152. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/typing.py +0 -0
  153. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/common/version.py +0 -0
  154. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/__init__.py +0 -0
  155. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/clientappio_pb2.py +0 -0
  156. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/clientappio_pb2.pyi +0 -0
  157. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/clientappio_pb2_grpc.py +0 -0
  158. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/clientappio_pb2_grpc.pyi +0 -0
  159. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/common_pb2.py +0 -0
  160. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/common_pb2.pyi +0 -0
  161. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/common_pb2_grpc.py +0 -0
  162. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/common_pb2_grpc.pyi +0 -0
  163. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/control_pb2.py +0 -0
  164. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/control_pb2.pyi +0 -0
  165. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/control_pb2_grpc.py +0 -0
  166. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/control_pb2_grpc.pyi +0 -0
  167. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/driver_pb2.py +0 -0
  168. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/driver_pb2.pyi +0 -0
  169. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/driver_pb2_grpc.py +0 -0
  170. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/driver_pb2_grpc.pyi +0 -0
  171. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/error_pb2.py +0 -0
  172. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/error_pb2.pyi +0 -0
  173. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/error_pb2_grpc.py +0 -0
  174. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/error_pb2_grpc.pyi +0 -0
  175. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/exec_pb2.py +0 -0
  176. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/exec_pb2.pyi +0 -0
  177. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/exec_pb2_grpc.py +0 -0
  178. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/exec_pb2_grpc.pyi +0 -0
  179. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/fab_pb2.py +0 -0
  180. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/fab_pb2.pyi +0 -0
  181. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/fab_pb2_grpc.py +0 -0
  182. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/fab_pb2_grpc.pyi +0 -0
  183. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/fleet_pb2.py +0 -0
  184. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/fleet_pb2.pyi +0 -0
  185. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/fleet_pb2_grpc.py +0 -0
  186. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
  187. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/grpcadapter_pb2.py +0 -0
  188. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/grpcadapter_pb2.pyi +0 -0
  189. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/grpcadapter_pb2_grpc.py +0 -0
  190. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/grpcadapter_pb2_grpc.pyi +0 -0
  191. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/message_pb2.py +0 -0
  192. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/message_pb2.pyi +0 -0
  193. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/message_pb2_grpc.py +0 -0
  194. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/message_pb2_grpc.pyi +0 -0
  195. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/node_pb2.py +0 -0
  196. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/node_pb2.pyi +0 -0
  197. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/node_pb2_grpc.py +0 -0
  198. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/node_pb2_grpc.pyi +0 -0
  199. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/recordset_pb2.py +0 -0
  200. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/recordset_pb2.pyi +0 -0
  201. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/recordset_pb2_grpc.py +0 -0
  202. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/recordset_pb2_grpc.pyi +0 -0
  203. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/run_pb2.py +0 -0
  204. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/run_pb2.pyi +0 -0
  205. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/run_pb2_grpc.py +0 -0
  206. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/run_pb2_grpc.pyi +0 -0
  207. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/task_pb2.py +0 -0
  208. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/task_pb2.pyi +0 -0
  209. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/task_pb2_grpc.py +0 -0
  210. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/task_pb2_grpc.pyi +0 -0
  211. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/transport_pb2.py +0 -0
  212. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/transport_pb2.pyi +0 -0
  213. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/transport_pb2_grpc.py +0 -0
  214. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
  215. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/py.typed +0 -0
  216. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/__init__.py +0 -0
  217. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/app.py +0 -0
  218. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/client_proxy.py +0 -0
  219. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/compat/__init__.py +0 -0
  220. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/compat/app.py +0 -0
  221. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/compat/app_utils.py +0 -0
  222. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/compat/driver_client_proxy.py +0 -0
  223. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/compat/legacy_context.py +0 -0
  224. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/criterion.py +0 -0
  225. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/driver/__init__.py +0 -0
  226. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/driver/driver.py +0 -0
  227. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/driver/grpc_driver.py +0 -0
  228. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/history.py +0 -0
  229. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/server.py +0 -0
  230. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/server_app.py +0 -0
  231. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/server_config.py +0 -0
  232. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/serverapp_components.py +0 -0
  233. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/__init__.py +0 -0
  234. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/aggregate.py +0 -0
  235. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/bulyan.py +0 -0
  236. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
  237. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
  238. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
  239. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
  240. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
  241. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/fedadagrad.py +0 -0
  242. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/fedadam.py +0 -0
  243. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/fedavg.py +0 -0
  244. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/fedavg_android.py +0 -0
  245. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/fedavgm.py +0 -0
  246. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/fedmedian.py +0 -0
  247. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/fedopt.py +0 -0
  248. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/fedprox.py +0 -0
  249. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
  250. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
  251. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
  252. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
  253. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/fedyogi.py +0 -0
  254. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/krum.py +0 -0
  255. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/qfedavg.py +0 -0
  256. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/strategy/strategy.py +0 -0
  257. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/__init__.py +0 -0
  258. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/driver/__init__.py +0 -0
  259. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/driver/driver_grpc.py +0 -0
  260. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/ffs/__init__.py +0 -0
  261. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/ffs/disk_ffs.py +0 -0
  262. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/ffs/ffs.py +0 -0
  263. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/ffs/ffs_factory.py +0 -0
  264. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/__init__.py +0 -0
  265. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py +0 -0
  266. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +0 -0
  267. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
  268. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
  269. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
  270. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
  271. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
  272. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +0 -0
  273. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +0 -0
  274. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
  275. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py +0 -0
  276. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
  277. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +0 -0
  278. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
  279. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
  280. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
  281. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +0 -0
  282. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/state/__init__.py +0 -0
  283. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/superlink/state/state_factory.py +0 -0
  284. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/typing.py +0 -0
  285. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/utils/__init__.py +0 -0
  286. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/utils/tensorboard.py +0 -0
  287. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/utils/validator.py +0 -0
  288. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/workflow/__init__.py +0 -0
  289. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/workflow/constant.py +0 -0
  290. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/workflow/default_workflows.py +0 -0
  291. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
  292. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
  293. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
  294. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/simulation/__init__.py +0 -0
  295. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/simulation/app.py +0 -0
  296. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/simulation/ray_transport/__init__.py +0 -0
  297. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
  298. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
  299. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/simulation/ray_transport/utils.py +0 -0
  300. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/simulation/run_simulation.py +0 -0
  301. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/superexec/__init__.py +0 -0
  302. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/superexec/app.py +0 -0
  303. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/superexec/deployment.py +0 -0
  304. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/superexec/exec_grpc.py +0 -0
  305. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/superexec/exec_servicer.py +0 -0
  306. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/py/flwr/superexec/executor.py +0 -0
  307. {flwr_nightly-1.12.0.dev20241008 → flwr_nightly-1.12.0.dev20241010}/src/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.12.0.dev20241008
3
+ Version: 1.12.0.dev20241010
4
4
  Summary: Flower: A Friendly Federated Learning Framework
5
5
  Home-page: https://flower.ai
6
6
  License: Apache-2.0
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "flwr-nightly"
7
- version = "1.12.0.dev20241008"
7
+ version = "1.12.0.dev20241010"
8
8
  description = "Flower: A Friendly Federated Learning Framework"
9
9
  license = "Apache-2.0"
10
10
  authors = ["The Flower Authors <hello@flower.ai>"]
@@ -134,6 +134,7 @@ pre-commit = "==3.5.0"
134
134
  sphinx-substitution-extensions = "2022.02.16"
135
135
  sphinxext-opengraph = "==0.9.1"
136
136
  docstrfmt = { git = "https://github.com/charlesbvll/docstrfmt.git", branch = "patch-1" }
137
+ docsig = "==0.64.0"
137
138
 
138
139
  [tool.docstrfmt]
139
140
  extend_exclude = [
@@ -224,3 +225,7 @@ convention = "numpy"
224
225
 
225
226
  [tool.ruff.per-file-ignores]
226
227
  "src/py/flwr/server/strategy/*.py" = ["E501"]
228
+
229
+ [tool.docsig]
230
+ ignore-no-params = true
231
+ exclude = 'src/py/flwr/proto/.*|src/py/flwr/.*_test\.py|src/py/flwr/cli/new/templates/.*\.tpl'
@@ -14,26 +14,50 @@
14
14
  # ==============================================================================
15
15
  """Flower command line interface `build` command."""
16
16
 
17
+ import hashlib
17
18
  import os
19
+ import shutil
20
+ import tempfile
18
21
  import zipfile
19
22
  from pathlib import Path
20
- from typing import Annotated, Optional
23
+ from typing import Annotated, Any, Optional, Union
21
24
 
22
25
  import pathspec
23
26
  import tomli_w
24
27
  import typer
25
28
 
29
+ from flwr.common.constant import FAB_ALLOWED_EXTENSIONS, FAB_DATE, FAB_HASH_TRUNCATION
30
+
26
31
  from .config_utils import load_and_validate
27
- from .utils import get_sha256_hash, is_valid_project_name
32
+ from .utils import is_valid_project_name
33
+
34
+
35
+ def write_to_zip(
36
+ zipfile_obj: zipfile.ZipFile, filename: str, contents: Union[bytes, str]
37
+ ) -> zipfile.ZipFile:
38
+ """Set a fixed date and write contents to a zip file."""
39
+ zip_info = zipfile.ZipInfo(filename)
40
+ zip_info.date_time = FAB_DATE
41
+ zipfile_obj.writestr(zip_info, contents)
42
+ return zipfile_obj
43
+
28
44
 
45
+ def get_fab_filename(conf: dict[str, Any], fab_hash: str) -> str:
46
+ """Get the FAB filename based on the given config and FAB hash."""
47
+ publisher = conf["tool"]["flwr"]["app"]["publisher"]
48
+ name = conf["project"]["name"]
49
+ version = conf["project"]["version"].replace(".", "-")
50
+ fab_hash_truncated = fab_hash[:FAB_HASH_TRUNCATION]
51
+ return f"{publisher}.{name}.{version}.{fab_hash_truncated}.fab"
29
52
 
30
- # pylint: disable=too-many-locals
53
+
54
+ # pylint: disable=too-many-locals, too-many-statements
31
55
  def build(
32
56
  app: Annotated[
33
57
  Optional[Path],
34
58
  typer.Option(help="Path of the Flower App to bundle into a FAB"),
35
59
  ] = None,
36
- ) -> str:
60
+ ) -> tuple[str, str]:
37
61
  """Build a Flower App into a Flower App Bundle (FAB).
38
62
 
39
63
  You can run ``flwr build`` without any arguments to bundle the app located in the
@@ -85,16 +109,8 @@ def build(
85
109
  # Load .gitignore rules if present
86
110
  ignore_spec = _load_gitignore(app)
87
111
 
88
- # Set the name of the zip file
89
- fab_filename = (
90
- f"{conf['tool']['flwr']['app']['publisher']}"
91
- f".{conf['project']['name']}"
92
- f".{conf['project']['version'].replace('.', '-')}.fab"
93
- )
94
112
  list_file_content = ""
95
113
 
96
- allowed_extensions = {".py", ".toml", ".md"}
97
-
98
114
  # Remove the 'federations' field from 'tool.flwr' if it exists
99
115
  if (
100
116
  "tool" in conf
@@ -105,38 +121,53 @@ def build(
105
121
 
106
122
  toml_contents = tomli_w.dumps(conf)
107
123
 
108
- with zipfile.ZipFile(fab_filename, "w", zipfile.ZIP_DEFLATED) as fab_file:
109
- fab_file.writestr("pyproject.toml", toml_contents)
124
+ with tempfile.NamedTemporaryFile(suffix=".zip", delete=False) as temp_file:
125
+ temp_filename = temp_file.name
126
+
127
+ with zipfile.ZipFile(temp_filename, "w", zipfile.ZIP_DEFLATED) as fab_file:
128
+ write_to_zip(fab_file, "pyproject.toml", toml_contents)
110
129
 
111
- # Continue with adding other files
112
- for root, _, files in os.walk(app, topdown=True):
113
- files = [
130
+ # Continue with adding other files
131
+ all_files = [
114
132
  f
115
- for f in files
116
- if not ignore_spec.match_file(Path(root) / f)
117
- and f != fab_filename
118
- and Path(f).suffix in allowed_extensions
119
- and f != "pyproject.toml" # Exclude the original pyproject.toml
133
+ for f in app.rglob("*")
134
+ if not ignore_spec.match_file(f)
135
+ and f.name != temp_filename
136
+ and f.suffix in FAB_ALLOWED_EXTENSIONS
137
+ and f.name != "pyproject.toml" # Exclude the original pyproject.toml
120
138
  ]
121
139
 
122
- for file in files:
123
- file_path = Path(root) / file
140
+ for file_path in all_files:
141
+ # Read the file content manually
142
+ with open(file_path, "rb") as f:
143
+ file_contents = f.read()
144
+
124
145
  archive_path = file_path.relative_to(app)
125
- fab_file.write(file_path, archive_path)
146
+ write_to_zip(fab_file, str(archive_path), file_contents)
126
147
 
127
148
  # Calculate file info
128
- sha256_hash = get_sha256_hash(file_path)
149
+ sha256_hash = hashlib.sha256(file_contents).hexdigest()
129
150
  file_size_bits = os.path.getsize(file_path) * 8 # size in bits
130
151
  list_file_content += f"{archive_path},{sha256_hash},{file_size_bits}\n"
131
152
 
132
- # Add CONTENT and CONTENT.jwt to the zip file
133
- fab_file.writestr(".info/CONTENT", list_file_content)
153
+ # Add CONTENT and CONTENT.jwt to the zip file
154
+ write_to_zip(fab_file, ".info/CONTENT", list_file_content)
155
+
156
+ # Get hash of FAB file
157
+ content = Path(temp_filename).read_bytes()
158
+ fab_hash = hashlib.sha256(content).hexdigest()
159
+
160
+ # Set the name of the zip file
161
+ fab_filename = get_fab_filename(conf, fab_hash)
162
+
163
+ # Once the temporary zip file is created, rename it to the final filename
164
+ shutil.move(temp_filename, fab_filename)
134
165
 
135
166
  typer.secho(
136
167
  f"🎊 Successfully built {fab_filename}", fg=typer.colors.GREEN, bold=True
137
168
  )
138
169
 
139
- return fab_filename
170
+ return fab_filename, fab_hash
140
171
 
141
172
 
142
173
  def _load_gitignore(app: Path) -> pathspec.PathSpec:
@@ -90,6 +90,16 @@ def load_and_validate(
90
90
  ) -> tuple[Optional[dict[str, Any]], list[str], list[str]]:
91
91
  """Load and validate pyproject.toml as dict.
92
92
 
93
+ Parameters
94
+ ----------
95
+ path : Optional[Path] (default: None)
96
+ The path of the Flower App config file to load. By default it
97
+ will try to use `pyproject.toml` inside the current directory.
98
+ check_module: bool (default: True)
99
+ Whether the validity of the Python module should be checked.
100
+ This requires the project to be installed in the currently
101
+ running environment. True by default.
102
+
93
103
  Returns
94
104
  -------
95
105
  Tuple[Optional[config], List[str], List[str]]
@@ -14,7 +14,7 @@
14
14
  # ==============================================================================
15
15
  """Flower command line interface `install` command."""
16
16
 
17
-
17
+ import hashlib
18
18
  import shutil
19
19
  import subprocess
20
20
  import tempfile
@@ -25,7 +25,8 @@ from typing import IO, Annotated, Optional, Union
25
25
 
26
26
  import typer
27
27
 
28
- from flwr.common.config import get_flwr_dir
28
+ from flwr.common.config import get_flwr_dir, get_metadata_from_config
29
+ from flwr.common.constant import FAB_HASH_TRUNCATION
29
30
 
30
31
  from .config_utils import load_and_validate
31
32
  from .utils import get_sha256_hash
@@ -91,9 +92,11 @@ def install_from_fab(
91
92
  fab_name: Optional[str]
92
93
  if isinstance(fab_file, bytes):
93
94
  fab_file_archive = BytesIO(fab_file)
95
+ fab_hash = hashlib.sha256(fab_file).hexdigest()
94
96
  fab_name = None
95
97
  elif isinstance(fab_file, Path):
96
98
  fab_file_archive = fab_file
99
+ fab_hash = hashlib.sha256(fab_file.read_bytes()).hexdigest()
97
100
  fab_name = fab_file.stem
98
101
  else:
99
102
  raise ValueError("fab_file must be either a Path or bytes")
@@ -126,14 +129,16 @@ def install_from_fab(
126
129
  shutil.rmtree(info_dir)
127
130
 
128
131
  installed_path = validate_and_install(
129
- tmpdir_path, fab_name, flwr_dir, skip_prompt
132
+ tmpdir_path, fab_hash, fab_name, flwr_dir, skip_prompt
130
133
  )
131
134
 
132
135
  return installed_path
133
136
 
134
137
 
138
+ # pylint: disable=too-many-locals
135
139
  def validate_and_install(
136
140
  project_dir: Path,
141
+ fab_hash: str,
137
142
  fab_name: Optional[str],
138
143
  flwr_dir: Optional[Path],
139
144
  skip_prompt: bool = False,
@@ -149,28 +154,17 @@ def validate_and_install(
149
154
  )
150
155
  raise typer.Exit(code=1)
151
156
 
152
- publisher = config["tool"]["flwr"]["app"]["publisher"]
153
- project_name = config["project"]["name"]
154
- version = config["project"]["version"]
157
+ version, fab_id = get_metadata_from_config(config)
158
+ publisher, project_name = fab_id.split("/")
159
+ config_metadata = (publisher, project_name, version, fab_hash)
155
160
 
156
- if (
157
- fab_name
158
- and fab_name != f"{publisher}.{project_name}.{version.replace('.', '-')}"
159
- ):
160
- typer.secho(
161
- "❌ FAB file has incorrect name. The file name must follow the format "
162
- "`<publisher>.<project_name>.<version>.fab`.",
163
- fg=typer.colors.RED,
164
- bold=True,
165
- )
166
- raise typer.Exit(code=1)
161
+ if fab_name:
162
+ _validate_fab_and_config_metadata(fab_name, config_metadata)
167
163
 
168
164
  install_dir: Path = (
169
165
  (get_flwr_dir() if not flwr_dir else flwr_dir)
170
166
  / "apps"
171
- / publisher
172
- / project_name
173
- / version
167
+ / f"{publisher}.{project_name}.{version}.{fab_hash[:FAB_HASH_TRUNCATION]}"
174
168
  )
175
169
  if install_dir.exists():
176
170
  if skip_prompt:
@@ -226,3 +220,49 @@ def _verify_hashes(list_content: str, tmpdir: Path) -> bool:
226
220
  if not file_path.exists() or get_sha256_hash(file_path) != hash_expected:
227
221
  return False
228
222
  return True
223
+
224
+
225
+ def _validate_fab_and_config_metadata(
226
+ fab_name: str, config_metadata: tuple[str, str, str, str]
227
+ ) -> None:
228
+ """Validate metadata from the FAB filename and config."""
229
+ publisher, project_name, version, fab_hash = config_metadata
230
+
231
+ fab_name = fab_name.removesuffix(".fab")
232
+
233
+ fab_publisher, fab_project_name, fab_version, fab_shorthash = fab_name.split(".")
234
+ fab_version = fab_version.replace("-", ".")
235
+
236
+ # Check FAB filename format
237
+ if (
238
+ f"{fab_publisher}.{fab_project_name}.{fab_version}"
239
+ != f"{publisher}.{project_name}.{version}"
240
+ or len(fab_shorthash) != FAB_HASH_TRUNCATION # Verify hash length
241
+ ):
242
+ typer.secho(
243
+ "❌ FAB file has incorrect name. The file name must follow the format "
244
+ "`<publisher>.<project_name>.<version>.<8hexchars>.fab`.",
245
+ fg=typer.colors.RED,
246
+ bold=True,
247
+ )
248
+ raise typer.Exit(code=1)
249
+
250
+ # Verify hash is a valid hexadecimal
251
+ try:
252
+ _ = int(fab_shorthash, 16)
253
+ except Exception as e:
254
+ typer.secho(
255
+ f"❌ FAB file has an invalid hexadecimal string `{fab_shorthash}`.",
256
+ fg=typer.colors.RED,
257
+ bold=True,
258
+ )
259
+ raise typer.Exit(code=1) from e
260
+
261
+ # Verify shorthash matches
262
+ if fab_shorthash != fab_hash[:FAB_HASH_TRUNCATION]:
263
+ typer.secho(
264
+ "❌ The hash in the FAB file name does not match the hash of the FAB.",
265
+ fg=typer.colors.RED,
266
+ bold=True,
267
+ )
268
+ raise typer.Exit(code=1)
@@ -14,7 +14,7 @@ dependencies = [
14
14
  "bitsandbytes==0.43.0",
15
15
  "scipy==1.13.0",
16
16
  "peft==0.6.2",
17
- "transformers==4.39.3",
17
+ "transformers==4.43.1",
18
18
  "sentencepiece==0.2.0",
19
19
  "omegaconf==2.3.0",
20
20
  "hf_transfer==0.1.8",
@@ -14,7 +14,6 @@
14
14
  # ==============================================================================
15
15
  """Flower command line interface `run` command."""
16
16
 
17
- import hashlib
18
17
  import json
19
18
  import subprocess
20
19
  import sys
@@ -134,6 +133,7 @@ def run(
134
133
  _run_without_superexec(app, federation_config, config_overrides, federation)
135
134
 
136
135
 
136
+ # pylint: disable=too-many-locals
137
137
  def _run_with_superexec(
138
138
  app: Path,
139
139
  federation_config: dict[str, Any],
@@ -179,9 +179,9 @@ def _run_with_superexec(
179
179
  channel.subscribe(on_channel_state_change)
180
180
  stub = ExecStub(channel)
181
181
 
182
- fab_path = Path(build(app))
183
- content = fab_path.read_bytes()
184
- fab = Fab(hashlib.sha256(content).hexdigest(), content)
182
+ fab_path, fab_hash = build(app)
183
+ content = Path(fab_path).read_bytes()
184
+ fab = Fab(fab_hash, content)
185
185
 
186
186
  req = StartRunRequest(
187
187
  fab=fab_to_proto(fab),
@@ -193,7 +193,7 @@ def _run_with_superexec(
193
193
  res = stub.StartRun(req)
194
194
 
195
195
  # Delete FAB file once it has been sent to the SuperExec
196
- fab_path.unlink()
196
+ Path(fab_path).unlink()
197
197
  typer.secho(f"🎊 Successfully started run {res.run_id}", fg=typer.colors.GREEN)
198
198
 
199
199
  if stream:
@@ -132,6 +132,11 @@ def start_client(
132
132
  - 'grpc-bidi': gRPC, bidirectional streaming
133
133
  - 'grpc-rere': gRPC, request-response (experimental)
134
134
  - 'rest': HTTP (experimental)
135
+ authentication_keys : Optional[Tuple[PrivateKey, PublicKey]] (default: None)
136
+ Tuple containing the elliptic curve private key and public key for
137
+ authentication from the cryptography library.
138
+ Source: https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/
139
+ Used to establish an authenticated connection with the server.
135
140
  max_retries: Optional[int] (default: None)
136
141
  The maximum number of times the client will try to connect to the
137
142
  server before giving up in case of a connection error. If set to None,
@@ -197,7 +202,7 @@ def start_client_internal(
197
202
  *,
198
203
  server_address: str,
199
204
  node_config: UserConfig,
200
- load_client_app_fn: Optional[Callable[[str, str], ClientApp]] = None,
205
+ load_client_app_fn: Optional[Callable[[str, str, str], ClientApp]] = None,
201
206
  client_fn: Optional[ClientFnExt] = None,
202
207
  client: Optional[Client] = None,
203
208
  grpc_max_message_length: int = GRPC_MAX_MESSAGE_LENGTH,
@@ -249,6 +254,11 @@ def start_client_internal(
249
254
  - 'grpc-bidi': gRPC, bidirectional streaming
250
255
  - 'grpc-rere': gRPC, request-response (experimental)
251
256
  - 'rest': HTTP (experimental)
257
+ authentication_keys : Optional[Tuple[PrivateKey, PublicKey]] (default: None)
258
+ Tuple containing the elliptic curve private key and public key for
259
+ authentication from the cryptography library.
260
+ Source: https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/
261
+ Used to establish an authenticated connection with the server.
252
262
  max_retries: Optional[int] (default: None)
253
263
  The maximum number of times the client will try to connect to the
254
264
  server before giving up in case of a connection error. If set to None,
@@ -288,7 +298,7 @@ def start_client_internal(
288
298
 
289
299
  client_fn = single_client_factory
290
300
 
291
- def _load_client_app(_1: str, _2: str) -> ClientApp:
301
+ def _load_client_app(_1: str, _2: str, _3: str) -> ClientApp:
292
302
  return ClientApp(client_fn=client_fn)
293
303
 
294
304
  load_client_app_fn = _load_client_app
@@ -519,7 +529,7 @@ def start_client_internal(
519
529
  else:
520
530
  # Load ClientApp instance
521
531
  client_app: ClientApp = load_client_app_fn(
522
- fab_id, fab_version
532
+ fab_id, fab_version, run.fab_hash
523
533
  )
524
534
 
525
535
  # Execute ClientApp
@@ -132,8 +132,11 @@ def run_clientapp( # pylint: disable=R0914
132
132
  )
133
133
 
134
134
  try:
135
- # Load ClientApp
136
- client_app: ClientApp = load_client_app_fn(run.fab_id, run.fab_version)
135
+ if fab:
136
+ # Load ClientApp
137
+ client_app: ClientApp = load_client_app_fn(
138
+ run.fab_id, run.fab_version, fab.hash_str
139
+ )
137
140
 
138
141
  # Execute ClientApp
139
142
  reply_message = client_app(message=message, context=context)
@@ -34,7 +34,7 @@ def get_load_client_app_fn(
34
34
  app_path: Optional[str],
35
35
  multi_app: bool,
36
36
  flwr_dir: Optional[str] = None,
37
- ) -> Callable[[str, str], ClientApp]:
37
+ ) -> Callable[[str, str, str], ClientApp]:
38
38
  """Get the load_client_app_fn function.
39
39
 
40
40
  If `multi_app` is True, this function loads the specified ClientApp
@@ -55,13 +55,14 @@ def get_load_client_app_fn(
55
55
  if not valid and error_msg:
56
56
  raise LoadClientAppError(error_msg) from None
57
57
 
58
- def _load(fab_id: str, fab_version: str) -> ClientApp:
58
+ def _load(fab_id: str, fab_version: str, fab_hash: str) -> ClientApp:
59
59
  runtime_app_dir = Path(app_path if app_path else "").absolute()
60
60
  # If multi-app feature is disabled
61
61
  if not multi_app:
62
62
  # Set app reference
63
63
  client_app_ref = default_app_ref
64
- # If multi-app feature is enabled but app directory is provided
64
+ # If multi-app feature is enabled but app directory is provided.
65
+ # `fab_hash` is not required since the app is loaded from `runtime_app_dir`.
65
66
  elif app_path is not None:
66
67
  config = get_project_config(runtime_app_dir)
67
68
  this_fab_version, this_fab_id = get_metadata_from_config(config)
@@ -81,11 +82,16 @@ def get_load_client_app_fn(
81
82
  else:
82
83
  try:
83
84
  runtime_app_dir = get_project_dir(
84
- fab_id, fab_version, get_flwr_dir(flwr_dir)
85
+ fab_id, fab_version, fab_hash, get_flwr_dir(flwr_dir)
85
86
  )
86
87
  config = get_project_config(runtime_app_dir)
87
88
  except Exception as e:
88
- raise LoadClientAppError("Failed to load ClientApp") from e
89
+ raise LoadClientAppError(
90
+ "Failed to load ClientApp."
91
+ "Possible reasons for error include mismatched "
92
+ "`fab_id`, `fab_version`, or `fab_hash` in "
93
+ f"{str(get_flwr_dir(flwr_dir).resolve())}."
94
+ ) from e
89
95
 
90
96
  # Set app reference
91
97
  client_app_ref = config["tool"]["flwr"]["app"]["components"]["clientapp"]
@@ -120,6 +120,9 @@ def grpc_request_response( # pylint: disable=R0913, R0914, R0915
120
120
  authentication from the cryptography library.
121
121
  Source: https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/
122
122
  Used to establish an authenticated connection with the server.
123
+ adapter_cls: Optional[Union[type[FleetStub], type[GrpcAdapter]]] (default: None)
124
+ A GrpcStub Class that can be used to send messages. By default the FleetStub
125
+ will be used.
123
126
 
124
127
  Returns
125
128
  -------
@@ -22,7 +22,12 @@ from typing import Any, Optional, Union, cast, get_args
22
22
  import tomli
23
23
 
24
24
  from flwr.cli.config_utils import get_fab_config, validate_fields
25
- from flwr.common.constant import APP_DIR, FAB_CONFIG_FILE, FLWR_HOME
25
+ from flwr.common.constant import (
26
+ APP_DIR,
27
+ FAB_CONFIG_FILE,
28
+ FAB_HASH_TRUNCATION,
29
+ FLWR_HOME,
30
+ )
26
31
  from flwr.common.typing import Run, UserConfig, UserConfigValue
27
32
 
28
33
 
@@ -39,7 +44,10 @@ def get_flwr_dir(provided_path: Optional[str] = None) -> Path:
39
44
 
40
45
 
41
46
  def get_project_dir(
42
- fab_id: str, fab_version: str, flwr_dir: Optional[Union[str, Path]] = None
47
+ fab_id: str,
48
+ fab_version: str,
49
+ fab_hash: str,
50
+ flwr_dir: Optional[Union[str, Path]] = None,
43
51
  ) -> Path:
44
52
  """Return the project directory based on the given fab_id and fab_version."""
45
53
  # Check the fab_id
@@ -50,7 +58,11 @@ def get_project_dir(
50
58
  publisher, project_name = fab_id.split("/")
51
59
  if flwr_dir is None:
52
60
  flwr_dir = get_flwr_dir()
53
- return Path(flwr_dir) / APP_DIR / publisher / project_name / fab_version
61
+ return (
62
+ Path(flwr_dir)
63
+ / APP_DIR
64
+ / f"{publisher}.{project_name}.{fab_version}.{fab_hash[:FAB_HASH_TRUNCATION]}"
65
+ )
54
66
 
55
67
 
56
68
  def get_project_config(project_dir: Union[str, Path]) -> dict[str, Any]:
@@ -127,7 +139,7 @@ def get_fused_config(run: Run, flwr_dir: Optional[Path]) -> UserConfig:
127
139
  if not run.fab_id or not run.fab_version:
128
140
  return {}
129
141
 
130
- project_dir = get_project_dir(run.fab_id, run.fab_version, flwr_dir)
142
+ project_dir = get_project_dir(run.fab_id, run.fab_version, run.fab_hash, flwr_dir)
131
143
 
132
144
  # Return empty dict if project directory does not exist
133
145
  if not project_dir.is_dir():
@@ -205,8 +217,9 @@ def parse_config_args(
205
217
  matches = pattern.findall(config_line)
206
218
  toml_str = "\n".join(f"{k} = {v}" for k, v in matches)
207
219
  overrides.update(tomli.loads(toml_str))
220
+ flat_overrides = flatten_dict(overrides)
208
221
 
209
- return overrides
222
+ return flat_overrides
210
223
 
211
224
 
212
225
  def get_metadata_from_config(config: dict[str, Any]) -> tuple[str, str]:
@@ -290,6 +290,11 @@ class Message:
290
290
  follows the equation:
291
291
 
292
292
  ttl = msg.meta.ttl - (reply.meta.created_at - msg.meta.created_at)
293
+
294
+ Returns
295
+ -------
296
+ message : Message
297
+ A Message containing only the relevant error and metadata.
293
298
  """
294
299
  # If no TTL passed, use default for message creation (will update after
295
300
  # message creation)
@@ -59,6 +59,11 @@ def parametersrecord_to_parameters(
59
59
  keep_input : bool
60
60
  A boolean indicating whether entries in the record should be deleted from the
61
61
  input dictionary immediately after adding them to the record.
62
+
63
+ Returns
64
+ -------
65
+ parameters : Parameters
66
+ The parameters in the legacy format Parameters.
62
67
  """
63
68
  parameters = Parameters(tensors=[], tensor_type="")
64
69
 
@@ -94,6 +99,11 @@ def parameters_to_parametersrecord(
94
99
  A boolean indicating whether parameters should be deleted from the input
95
100
  Parameters object (i.e. a list of serialized NumPy arrays) immediately after
96
101
  adding them to the record.
102
+
103
+ Returns
104
+ -------
105
+ ParametersRecord
106
+ The ParametersRecord containing the provided parameters.
97
107
  """
98
108
  tensor_type = parameters.tensor_type
99
109
 
@@ -38,6 +38,11 @@ def exponential(
38
38
  Factor by which the delay is multiplied after each retry.
39
39
  max_delay: Optional[float] (default: None)
40
40
  The maximum delay duration between two consecutive retries.
41
+
42
+ Returns
43
+ -------
44
+ Generator[float, None, None]
45
+ A generator for the delay between 2 retries.
41
46
  """
42
47
  delay = base_delay if max_delay is None else min(base_delay, max_delay)
43
48
  while True:
@@ -56,6 +61,11 @@ def constant(
56
61
  ----------
57
62
  interval: Union[float, Iterable[float]] (default: 1)
58
63
  A constant value to yield or an iterable of such values.
64
+
65
+ Returns
66
+ -------
67
+ Generator[float, None, None]
68
+ A generator for the delay between 2 retries.
59
69
  """
60
70
  if not isinstance(interval, Iterable):
61
71
  interval = itertools.repeat(interval)
@@ -73,6 +83,11 @@ def full_jitter(max_value: float) -> float:
73
83
  ----------
74
84
  max_value : float
75
85
  The upper limit for the randomized value.
86
+
87
+ Returns
88
+ -------
89
+ float
90
+ A random float that is less than max_value.
76
91
  """
77
92
  return random.uniform(0, max_value)
78
93
 
@@ -47,6 +47,7 @@ class ClientManager(ABC):
47
47
  Parameters
48
48
  ----------
49
49
  client : flwr.server.client_proxy.ClientProxy
50
+ The ClientProxy of the Client to register.
50
51
 
51
52
  Returns
52
53
  -------
@@ -64,6 +65,7 @@ class ClientManager(ABC):
64
65
  Parameters
65
66
  ----------
66
67
  client : flwr.server.client_proxy.ClientProxy
68
+ The ClientProxy of the Client to unregister.
67
69
  """
68
70
 
69
71
  @abstractmethod
@@ -150,7 +150,7 @@ class InMemoryDriver(Driver):
150
150
  """
151
151
  msg_ids = {UUID(msg_id) for msg_id in message_ids}
152
152
  # Pull TaskRes
153
- task_res_list = self.state.get_task_res(task_ids=msg_ids, limit=len(msg_ids))
153
+ task_res_list = self.state.get_task_res(task_ids=msg_ids)
154
154
  # Delete tasks in state
155
155
  self.state.delete_tasks(msg_ids)
156
156
  # Convert TaskRes to Message