flwr-nightly 1.15.0.dev20250121__tar.gz → 1.15.0.dev20250122__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 (333) hide show
  1. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/PKG-INFO +1 -1
  2. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/pyproject.toml +1 -1
  3. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/config_utils.py +9 -145
  4. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/install.py +1 -1
  5. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/clientapp/utils.py +1 -1
  6. flwr_nightly-1.15.0.dev20250122/src/py/flwr/client/grpc_rere_client/client_interceptor.py +70 -0
  7. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/config.py +132 -6
  8. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/constant.py +6 -0
  9. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/exit/exit_code.py +8 -5
  10. flwr_nightly-1.15.0.dev20250122/src/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +94 -0
  11. flwr_nightly-1.15.0.dev20250122/src/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +154 -0
  12. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/simulation/app.py +4 -6
  13. flwr_nightly-1.15.0.dev20250121/src/py/flwr/client/grpc_rere_client/client_interceptor.py +0 -176
  14. flwr_nightly-1.15.0.dev20250121/src/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +0 -162
  15. flwr_nightly-1.15.0.dev20250121/src/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +0 -228
  16. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/LICENSE +0 -0
  17. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/README.md +0 -0
  18. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/__init__.py +0 -0
  19. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/__init__.py +0 -0
  20. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/app.py +0 -0
  21. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/build.py +0 -0
  22. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/cli_user_auth_interceptor.py +0 -0
  23. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/example.py +0 -0
  24. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/log.py +0 -0
  25. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/login/__init__.py +0 -0
  26. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/login/login.py +0 -0
  27. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/ls.py +0 -0
  28. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/__init__.py +0 -0
  29. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/new.py +0 -0
  30. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/__init__.py +0 -0
  31. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/.gitignore.tpl +0 -0
  32. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/LICENSE.tpl +0 -0
  33. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/README.baseline.md.tpl +0 -0
  34. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/README.flowertune.md.tpl +0 -0
  35. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/README.md.tpl +0 -0
  36. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/__init__.py +0 -0
  37. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/__init__.baseline.py.tpl +0 -0
  38. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
  39. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
  40. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/client.baseline.py.tpl +0 -0
  41. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/client.huggingface.py.tpl +0 -0
  42. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/client.jax.py.tpl +0 -0
  43. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/client.mlx.py.tpl +0 -0
  44. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
  45. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -0
  46. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/client.sklearn.py.tpl +0 -0
  47. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -0
  48. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/dataset.baseline.py.tpl +0 -0
  49. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py +0 -0
  50. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +0 -0
  51. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +0 -0
  52. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +0 -0
  53. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +0 -0
  54. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +0 -0
  55. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/model.baseline.py.tpl +0 -0
  56. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/server.baseline.py.tpl +0 -0
  57. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/server.huggingface.py.tpl +0 -0
  58. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/server.jax.py.tpl +0 -0
  59. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/server.mlx.py.tpl +0 -0
  60. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
  61. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -0
  62. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/server.sklearn.py.tpl +0 -0
  63. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -0
  64. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/strategy.baseline.py.tpl +0 -0
  65. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/task.huggingface.py.tpl +0 -0
  66. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/task.jax.py.tpl +0 -0
  67. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/task.mlx.py.tpl +0 -0
  68. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/task.numpy.py.tpl +0 -0
  69. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
  70. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/task.sklearn.py.tpl +0 -0
  71. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +0 -0
  72. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/code/utils.baseline.py.tpl +0 -0
  73. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +0 -0
  74. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +0 -0
  75. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +0 -0
  76. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl +0 -0
  77. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +0 -0
  78. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +0 -0
  79. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +0 -0
  80. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +0 -0
  81. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +0 -0
  82. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/run/__init__.py +0 -0
  83. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/run/run.py +0 -0
  84. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/stop.py +0 -0
  85. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/cli/utils.py +0 -0
  86. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/__init__.py +0 -0
  87. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/app.py +0 -0
  88. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/client.py +0 -0
  89. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/client_app.py +0 -0
  90. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/clientapp/__init__.py +0 -0
  91. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/clientapp/app.py +0 -0
  92. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/clientapp/clientappio_servicer.py +0 -0
  93. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/dpfedavg_numpy_client.py +0 -0
  94. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/grpc_adapter_client/__init__.py +0 -0
  95. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/grpc_adapter_client/connection.py +0 -0
  96. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/grpc_client/__init__.py +0 -0
  97. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/grpc_client/connection.py +0 -0
  98. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/grpc_rere_client/__init__.py +0 -0
  99. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/grpc_rere_client/connection.py +0 -0
  100. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/grpc_rere_client/grpc_adapter.py +0 -0
  101. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/heartbeat.py +0 -0
  102. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/message_handler/__init__.py +0 -0
  103. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/message_handler/message_handler.py +0 -0
  104. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/message_handler/task_handler.py +0 -0
  105. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/mod/__init__.py +0 -0
  106. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/mod/centraldp_mods.py +0 -0
  107. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/mod/comms_mods.py +0 -0
  108. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/mod/localdp_mod.py +0 -0
  109. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
  110. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
  111. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
  112. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/mod/utils.py +0 -0
  113. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/nodestate/__init__.py +0 -0
  114. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/nodestate/in_memory_nodestate.py +0 -0
  115. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/nodestate/nodestate.py +0 -0
  116. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/nodestate/nodestate_factory.py +0 -0
  117. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/numpy_client.py +0 -0
  118. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/rest_client/__init__.py +0 -0
  119. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/rest_client/connection.py +0 -0
  120. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/run_info_store.py +0 -0
  121. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/supernode/__init__.py +0 -0
  122. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/supernode/app.py +0 -0
  123. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/client/typing.py +0 -0
  124. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/__init__.py +0 -0
  125. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/address.py +0 -0
  126. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/args.py +0 -0
  127. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/auth_plugin/__init__.py +0 -0
  128. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/auth_plugin/auth_plugin.py +0 -0
  129. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/context.py +0 -0
  130. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/date.py +0 -0
  131. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/differential_privacy.py +0 -0
  132. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/differential_privacy_constants.py +0 -0
  133. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/dp.py +0 -0
  134. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/exit/__init__.py +0 -0
  135. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/exit/exit.py +0 -0
  136. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/exit_handlers.py +0 -0
  137. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/grpc.py +0 -0
  138. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/logger.py +0 -0
  139. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/message.py +0 -0
  140. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/object_ref.py +0 -0
  141. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/parameter.py +0 -0
  142. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/pyproject.py +0 -0
  143. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/record/__init__.py +0 -0
  144. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/record/configsrecord.py +0 -0
  145. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/record/conversion_utils.py +0 -0
  146. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/record/metricsrecord.py +0 -0
  147. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/record/parametersrecord.py +0 -0
  148. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/record/recordset.py +0 -0
  149. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/record/typeddict.py +0 -0
  150. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/recordset_compat.py +0 -0
  151. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/retry_invoker.py +0 -0
  152. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/secure_aggregation/__init__.py +0 -0
  153. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
  154. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
  155. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
  156. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
  157. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/secure_aggregation/quantization.py +0 -0
  158. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
  159. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
  160. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/serde.py +0 -0
  161. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/telemetry.py +0 -0
  162. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/typing.py +0 -0
  163. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/common/version.py +0 -0
  164. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/__init__.py +0 -0
  165. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/clientappio_pb2.py +0 -0
  166. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/clientappio_pb2.pyi +0 -0
  167. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/clientappio_pb2_grpc.py +0 -0
  168. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/clientappio_pb2_grpc.pyi +0 -0
  169. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/error_pb2.py +0 -0
  170. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/error_pb2.pyi +0 -0
  171. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/error_pb2_grpc.py +0 -0
  172. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/error_pb2_grpc.pyi +0 -0
  173. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/exec_pb2.py +0 -0
  174. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/exec_pb2.pyi +0 -0
  175. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/exec_pb2_grpc.py +0 -0
  176. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/exec_pb2_grpc.pyi +0 -0
  177. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/fab_pb2.py +0 -0
  178. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/fab_pb2.pyi +0 -0
  179. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/fab_pb2_grpc.py +0 -0
  180. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/fab_pb2_grpc.pyi +0 -0
  181. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/fleet_pb2.py +0 -0
  182. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/fleet_pb2.pyi +0 -0
  183. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/fleet_pb2_grpc.py +0 -0
  184. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
  185. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/grpcadapter_pb2.py +0 -0
  186. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/grpcadapter_pb2.pyi +0 -0
  187. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/grpcadapter_pb2_grpc.py +0 -0
  188. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/grpcadapter_pb2_grpc.pyi +0 -0
  189. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/log_pb2.py +0 -0
  190. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/log_pb2.pyi +0 -0
  191. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/log_pb2_grpc.py +0 -0
  192. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/log_pb2_grpc.pyi +0 -0
  193. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/message_pb2.py +0 -0
  194. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/message_pb2.pyi +0 -0
  195. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/message_pb2_grpc.py +0 -0
  196. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/message_pb2_grpc.pyi +0 -0
  197. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/node_pb2.py +0 -0
  198. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/node_pb2.pyi +0 -0
  199. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/node_pb2_grpc.py +0 -0
  200. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/node_pb2_grpc.pyi +0 -0
  201. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/recordset_pb2.py +0 -0
  202. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/recordset_pb2.pyi +0 -0
  203. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/recordset_pb2_grpc.py +0 -0
  204. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/recordset_pb2_grpc.pyi +0 -0
  205. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/run_pb2.py +0 -0
  206. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/run_pb2.pyi +0 -0
  207. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/run_pb2_grpc.py +0 -0
  208. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/run_pb2_grpc.pyi +0 -0
  209. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/serverappio_pb2.py +0 -0
  210. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/serverappio_pb2.pyi +0 -0
  211. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/serverappio_pb2_grpc.py +0 -0
  212. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/serverappio_pb2_grpc.pyi +0 -0
  213. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/simulationio_pb2.py +0 -0
  214. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/simulationio_pb2.pyi +0 -0
  215. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/simulationio_pb2_grpc.py +0 -0
  216. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/simulationio_pb2_grpc.pyi +0 -0
  217. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/task_pb2.py +0 -0
  218. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/task_pb2.pyi +0 -0
  219. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/task_pb2_grpc.py +0 -0
  220. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/task_pb2_grpc.pyi +0 -0
  221. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/transport_pb2.py +0 -0
  222. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/transport_pb2.pyi +0 -0
  223. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/transport_pb2_grpc.py +0 -0
  224. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
  225. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/py.typed +0 -0
  226. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/__init__.py +0 -0
  227. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/app.py +0 -0
  228. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/client_manager.py +0 -0
  229. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/client_proxy.py +0 -0
  230. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/compat/__init__.py +0 -0
  231. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/compat/app.py +0 -0
  232. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/compat/app_utils.py +0 -0
  233. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/compat/driver_client_proxy.py +0 -0
  234. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/compat/legacy_context.py +0 -0
  235. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/criterion.py +0 -0
  236. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/driver/__init__.py +0 -0
  237. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/driver/driver.py +0 -0
  238. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/driver/grpc_driver.py +0 -0
  239. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/driver/inmemory_driver.py +0 -0
  240. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/history.py +0 -0
  241. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/run_serverapp.py +0 -0
  242. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/server.py +0 -0
  243. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/server_app.py +0 -0
  244. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/server_config.py +0 -0
  245. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/serverapp/__init__.py +0 -0
  246. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/serverapp/app.py +0 -0
  247. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/serverapp_components.py +0 -0
  248. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/__init__.py +0 -0
  249. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/aggregate.py +0 -0
  250. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/bulyan.py +0 -0
  251. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
  252. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
  253. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
  254. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
  255. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
  256. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/fedadagrad.py +0 -0
  257. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/fedadam.py +0 -0
  258. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/fedavg.py +0 -0
  259. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/fedavg_android.py +0 -0
  260. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/fedavgm.py +0 -0
  261. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/fedmedian.py +0 -0
  262. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/fedopt.py +0 -0
  263. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/fedprox.py +0 -0
  264. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
  265. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
  266. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
  267. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
  268. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/fedyogi.py +0 -0
  269. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/krum.py +0 -0
  270. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/qfedavg.py +0 -0
  271. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/strategy/strategy.py +0 -0
  272. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/__init__.py +0 -0
  273. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/driver/__init__.py +0 -0
  274. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/driver/serverappio_grpc.py +0 -0
  275. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/driver/serverappio_servicer.py +0 -0
  276. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/ffs/__init__.py +0 -0
  277. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/ffs/disk_ffs.py +0 -0
  278. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/ffs/ffs.py +0 -0
  279. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/ffs/ffs_factory.py +0 -0
  280. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/__init__.py +0 -0
  281. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py +0 -0
  282. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
  283. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
  284. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
  285. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
  286. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
  287. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
  288. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +0 -0
  289. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
  290. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py +0 -0
  291. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
  292. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +0 -0
  293. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
  294. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
  295. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
  296. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +0 -0
  297. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/fleet/vce/vce_api.py +0 -0
  298. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/linkstate/__init__.py +0 -0
  299. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/linkstate/in_memory_linkstate.py +0 -0
  300. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/linkstate/linkstate.py +0 -0
  301. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/linkstate/linkstate_factory.py +0 -0
  302. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/linkstate/sqlite_linkstate.py +0 -0
  303. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/linkstate/utils.py +0 -0
  304. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/simulation/__init__.py +0 -0
  305. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/simulation/simulationio_grpc.py +0 -0
  306. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/simulation/simulationio_servicer.py +0 -0
  307. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/superlink/utils.py +0 -0
  308. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/typing.py +0 -0
  309. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/utils/__init__.py +0 -0
  310. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/utils/tensorboard.py +0 -0
  311. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/utils/validator.py +0 -0
  312. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/workflow/__init__.py +0 -0
  313. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/workflow/constant.py +0 -0
  314. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/workflow/default_workflows.py +0 -0
  315. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
  316. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
  317. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
  318. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/simulation/__init__.py +0 -0
  319. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/simulation/legacy_app.py +0 -0
  320. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/simulation/ray_transport/__init__.py +0 -0
  321. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
  322. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
  323. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/simulation/ray_transport/utils.py +0 -0
  324. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/simulation/run_simulation.py +0 -0
  325. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/simulation/simulationio_connection.py +0 -0
  326. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/superexec/__init__.py +0 -0
  327. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/superexec/app.py +0 -0
  328. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/superexec/deployment.py +0 -0
  329. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/superexec/exec_grpc.py +0 -0
  330. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/superexec/exec_servicer.py +0 -0
  331. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/superexec/exec_user_auth_interceptor.py +0 -0
  332. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/src/py/flwr/superexec/executor.py +0 -0
  333. {flwr_nightly-1.15.0.dev20250121 → flwr_nightly-1.15.0.dev20250122}/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.15.0.dev20250121
3
+ Version: 1.15.0.dev20250122
4
4
  Summary: Flower: A Friendly Federated AI 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.15.0.dev20250121"
7
+ version = "1.15.0.dev20250122"
8
8
  description = "Flower: A Friendly Federated AI Framework"
9
9
  license = "Apache-2.0"
10
10
  authors = ["The Flower Authors <hello@flower.ai>"]
@@ -15,53 +15,13 @@
15
15
  """Utility to validate the `pyproject.toml` file."""
16
16
 
17
17
 
18
- import zipfile
19
- from io import BytesIO
20
18
  from pathlib import Path
21
- from typing import IO, Any, Optional, Union, get_args
19
+ from typing import Any, Optional, Union
22
20
 
23
21
  import tomli
24
22
  import typer
25
23
 
26
- from flwr.common import object_ref
27
- from flwr.common.typing import UserConfigValue
28
-
29
-
30
- def get_fab_config(fab_file: Union[Path, bytes]) -> dict[str, Any]:
31
- """Extract the config from a FAB file or path.
32
-
33
- Parameters
34
- ----------
35
- fab_file : Union[Path, bytes]
36
- The Flower App Bundle file to validate and extract the metadata from.
37
- It can either be a path to the file or the file itself as bytes.
38
-
39
- Returns
40
- -------
41
- Dict[str, Any]
42
- The `config` of the given Flower App Bundle.
43
- """
44
- fab_file_archive: Union[Path, IO[bytes]]
45
- if isinstance(fab_file, bytes):
46
- fab_file_archive = BytesIO(fab_file)
47
- elif isinstance(fab_file, Path):
48
- fab_file_archive = fab_file
49
- else:
50
- raise ValueError("fab_file must be either a Path or bytes")
51
-
52
- with zipfile.ZipFile(fab_file_archive, "r") as zipf:
53
- with zipf.open("pyproject.toml") as file:
54
- toml_content = file.read().decode("utf-8")
55
-
56
- conf = load_from_string(toml_content)
57
- if conf is None:
58
- raise ValueError("Invalid TOML content in pyproject.toml")
59
-
60
- is_valid, errors, _ = validate(conf, check_module=False)
61
- if not is_valid:
62
- raise ValueError(errors)
63
-
64
- return conf
24
+ from flwr.common.config import get_fab_config, get_metadata_from_config, validate_config
65
25
 
66
26
 
67
27
  def get_fab_metadata(fab_file: Union[Path, bytes]) -> tuple[str, str]:
@@ -78,12 +38,7 @@ def get_fab_metadata(fab_file: Union[Path, bytes]) -> tuple[str, str]:
78
38
  Tuple[str, str]
79
39
  The `fab_id` and `fab_version` of the given Flower App Bundle.
80
40
  """
81
- conf = get_fab_config(fab_file)
82
-
83
- return (
84
- f"{conf['tool']['flwr']['app']['publisher']}/{conf['project']['name']}",
85
- conf["project"]["version"],
86
- )
41
+ return get_metadata_from_config(get_fab_config(fab_file))
87
42
 
88
43
 
89
44
  def load_and_validate(
@@ -120,7 +75,7 @@ def load_and_validate(
120
75
  ]
121
76
  return (None, errors, [])
122
77
 
123
- is_valid, errors, warnings = validate(config, check_module, path.parent)
78
+ is_valid, errors, warnings = validate_config(config, check_module, path.parent)
124
79
 
125
80
  if not is_valid:
126
81
  return (None, errors, warnings)
@@ -133,102 +88,11 @@ def load(toml_path: Path) -> Optional[dict[str, Any]]:
133
88
  if not toml_path.is_file():
134
89
  return None
135
90
 
136
- with toml_path.open(encoding="utf-8") as toml_file:
137
- return load_from_string(toml_file.read())
138
-
139
-
140
- def _validate_run_config(config_dict: dict[str, Any], errors: list[str]) -> None:
141
- for key, value in config_dict.items():
142
- if isinstance(value, dict):
143
- _validate_run_config(config_dict[key], errors)
144
- elif not isinstance(value, get_args(UserConfigValue)):
145
- raise ValueError(
146
- f"The value for key {key} needs to be of type `int`, `float`, "
147
- "`bool, `str`, or a `dict` of those.",
148
- )
149
-
150
-
151
- # pylint: disable=too-many-branches
152
- def validate_fields(config: dict[str, Any]) -> tuple[bool, list[str], list[str]]:
153
- """Validate pyproject.toml fields."""
154
- errors = []
155
- warnings = []
156
-
157
- if "project" not in config:
158
- errors.append("Missing [project] section")
159
- else:
160
- if "name" not in config["project"]:
161
- errors.append('Property "name" missing in [project]')
162
- if "version" not in config["project"]:
163
- errors.append('Property "version" missing in [project]')
164
- if "description" not in config["project"]:
165
- warnings.append('Recommended property "description" missing in [project]')
166
- if "license" not in config["project"]:
167
- warnings.append('Recommended property "license" missing in [project]')
168
- if "authors" not in config["project"]:
169
- warnings.append('Recommended property "authors" missing in [project]')
170
-
171
- if (
172
- "tool" not in config
173
- or "flwr" not in config["tool"]
174
- or "app" not in config["tool"]["flwr"]
175
- ):
176
- errors.append("Missing [tool.flwr.app] section")
177
- else:
178
- if "publisher" not in config["tool"]["flwr"]["app"]:
179
- errors.append('Property "publisher" missing in [tool.flwr.app]')
180
- if "config" in config["tool"]["flwr"]["app"]:
181
- _validate_run_config(config["tool"]["flwr"]["app"]["config"], errors)
182
- if "components" not in config["tool"]["flwr"]["app"]:
183
- errors.append("Missing [tool.flwr.app.components] section")
184
- else:
185
- if "serverapp" not in config["tool"]["flwr"]["app"]["components"]:
186
- errors.append(
187
- 'Property "serverapp" missing in [tool.flwr.app.components]'
188
- )
189
- if "clientapp" not in config["tool"]["flwr"]["app"]["components"]:
190
- errors.append(
191
- 'Property "clientapp" missing in [tool.flwr.app.components]'
192
- )
193
-
194
- return len(errors) == 0, errors, warnings
195
-
196
-
197
- def validate(
198
- config: dict[str, Any],
199
- check_module: bool = True,
200
- project_dir: Optional[Union[str, Path]] = None,
201
- ) -> tuple[bool, list[str], list[str]]:
202
- """Validate pyproject.toml."""
203
- is_valid, errors, warnings = validate_fields(config)
204
-
205
- if not is_valid:
206
- return False, errors, warnings
207
-
208
- # Validate serverapp
209
- serverapp_ref = config["tool"]["flwr"]["app"]["components"]["serverapp"]
210
- is_valid, reason = object_ref.validate(serverapp_ref, check_module, project_dir)
211
-
212
- if not is_valid and isinstance(reason, str):
213
- return False, [reason], []
214
-
215
- # Validate clientapp
216
- clientapp_ref = config["tool"]["flwr"]["app"]["components"]["clientapp"]
217
- is_valid, reason = object_ref.validate(clientapp_ref, check_module, project_dir)
218
-
219
- if not is_valid and isinstance(reason, str):
220
- return False, [reason], []
221
-
222
- return True, [], []
223
-
224
-
225
- def load_from_string(toml_content: str) -> Optional[dict[str, Any]]:
226
- """Load TOML content from a string and return as dict."""
227
- try:
228
- data = tomli.loads(toml_content)
229
- return data
230
- except tomli.TOMLDecodeError:
231
- return None
91
+ with toml_path.open("rb") as toml_file:
92
+ try:
93
+ return tomli.load(toml_file)
94
+ except tomli.TOMLDecodeError:
95
+ return None
232
96
 
233
97
 
234
98
  def process_loaded_project_config(
@@ -154,7 +154,7 @@ def validate_and_install(
154
154
  )
155
155
  raise typer.Exit(code=1)
156
156
 
157
- version, fab_id = get_metadata_from_config(config)
157
+ fab_id, version = get_metadata_from_config(config)
158
158
  publisher, project_name = fab_id.split("/")
159
159
  config_metadata = (publisher, project_name, version, fab_hash)
160
160
 
@@ -66,7 +66,7 @@ def get_load_client_app_fn(
66
66
  # `fab_hash` is not required since the app is loaded from `runtime_app_dir`.
67
67
  elif app_path is not None:
68
68
  config = get_project_config(runtime_app_dir)
69
- this_fab_version, this_fab_id = get_metadata_from_config(config)
69
+ this_fab_id, this_fab_version = get_metadata_from_config(config)
70
70
 
71
71
  if this_fab_version != fab_version or this_fab_id != fab_id:
72
72
  raise LoadClientAppError(
@@ -0,0 +1,70 @@
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ # ==============================================================================
15
+ """Flower client interceptor."""
16
+
17
+
18
+ from typing import Any, Callable
19
+
20
+ import grpc
21
+ from cryptography.hazmat.primitives.asymmetric import ec
22
+ from google.protobuf.message import Message as GrpcMessage
23
+
24
+ from flwr.common import now
25
+ from flwr.common.constant import PUBLIC_KEY_HEADER, SIGNATURE_HEADER, TIMESTAMP_HEADER
26
+ from flwr.common.secure_aggregation.crypto.symmetric_encryption import (
27
+ public_key_to_bytes,
28
+ sign_message,
29
+ )
30
+
31
+
32
+ class AuthenticateClientInterceptor(grpc.UnaryUnaryClientInterceptor): # type: ignore
33
+ """Client interceptor for client authentication."""
34
+
35
+ def __init__(
36
+ self,
37
+ private_key: ec.EllipticCurvePrivateKey,
38
+ public_key: ec.EllipticCurvePublicKey,
39
+ ):
40
+ self.private_key = private_key
41
+ self.public_key_bytes = public_key_to_bytes(public_key)
42
+
43
+ def intercept_unary_unary(
44
+ self,
45
+ continuation: Callable[[Any, Any], Any],
46
+ client_call_details: grpc.ClientCallDetails,
47
+ request: GrpcMessage,
48
+ ) -> grpc.Call:
49
+ """Flower client interceptor.
50
+
51
+ Intercept unary call from client and add necessary authentication header in the
52
+ RPC metadata.
53
+ """
54
+ metadata = list(client_call_details.metadata or [])
55
+
56
+ # Add the public key
57
+ metadata.append((PUBLIC_KEY_HEADER, self.public_key_bytes))
58
+
59
+ # Add timestamp
60
+ timestamp = now().isoformat()
61
+ metadata.append((TIMESTAMP_HEADER, timestamp))
62
+
63
+ # Sign and add the signature
64
+ signature = sign_message(self.private_key, timestamp.encode("ascii"))
65
+ metadata.append((SIGNATURE_HEADER, signature))
66
+
67
+ # Overwrite the metadata
68
+ details = client_call_details._replace(metadata=metadata)
69
+
70
+ return continuation(details, request)
@@ -17,13 +17,13 @@
17
17
 
18
18
  import os
19
19
  import re
20
+ import zipfile
21
+ from io import BytesIO
20
22
  from pathlib import Path
21
- from typing import Any, Optional, Union, cast, get_args
23
+ from typing import IO, Any, Optional, Union, cast, get_args
22
24
 
23
25
  import tomli
24
26
 
25
- from flwr.cli.config_utils import get_fab_config, validate_fields
26
- from flwr.common import ConfigsRecord
27
27
  from flwr.common.constant import (
28
28
  APP_DIR,
29
29
  FAB_CONFIG_FILE,
@@ -33,6 +33,8 @@ from flwr.common.constant import (
33
33
  )
34
34
  from flwr.common.typing import Run, UserConfig, UserConfigValue
35
35
 
36
+ from . import ConfigsRecord, object_ref
37
+
36
38
 
37
39
  def get_flwr_dir(provided_path: Optional[str] = None) -> Path:
38
40
  """Return the Flower home directory based on env variables."""
@@ -80,7 +82,7 @@ def get_project_config(project_dir: Union[str, Path]) -> dict[str, Any]:
80
82
  config = tomli.loads(toml_file.read())
81
83
 
82
84
  # Validate pyproject.toml fields
83
- is_valid, errors, _ = validate_fields(config)
85
+ is_valid, errors, _ = validate_fields_in_config(config)
84
86
  if not is_valid:
85
87
  error_msg = "\n".join([f" - {error}" for error in errors])
86
88
  raise ValueError(
@@ -227,10 +229,10 @@ def parse_config_args(
227
229
 
228
230
 
229
231
  def get_metadata_from_config(config: dict[str, Any]) -> tuple[str, str]:
230
- """Extract `fab_version` and `fab_id` from a project config."""
232
+ """Extract `fab_id` and `fab_version` from a project config."""
231
233
  return (
232
- config["project"]["version"],
233
234
  f"{config['tool']['flwr']['app']['publisher']}/{config['project']['name']}",
235
+ config["project"]["version"],
234
236
  )
235
237
 
236
238
 
@@ -241,3 +243,127 @@ def user_config_to_configsrecord(config: UserConfig) -> ConfigsRecord:
241
243
  c_record[k] = v
242
244
 
243
245
  return c_record
246
+
247
+
248
+ def get_fab_config(fab_file: Union[Path, bytes]) -> dict[str, Any]:
249
+ """Extract the config from a FAB file or path.
250
+
251
+ Parameters
252
+ ----------
253
+ fab_file : Union[Path, bytes]
254
+ The Flower App Bundle file to validate and extract the metadata from.
255
+ It can either be a path to the file or the file itself as bytes.
256
+
257
+ Returns
258
+ -------
259
+ Dict[str, Any]
260
+ The `config` of the given Flower App Bundle.
261
+ """
262
+ fab_file_archive: Union[Path, IO[bytes]]
263
+ if isinstance(fab_file, bytes):
264
+ fab_file_archive = BytesIO(fab_file)
265
+ elif isinstance(fab_file, Path):
266
+ fab_file_archive = fab_file
267
+ else:
268
+ raise ValueError("fab_file must be either a Path or bytes")
269
+
270
+ with zipfile.ZipFile(fab_file_archive, "r") as zipf:
271
+ with zipf.open("pyproject.toml") as file:
272
+ toml_content = file.read().decode("utf-8")
273
+ try:
274
+ conf = tomli.loads(toml_content)
275
+ except tomli.TOMLDecodeError:
276
+ raise ValueError("Invalid TOML content in pyproject.toml") from None
277
+
278
+ is_valid, errors, _ = validate_config(conf, check_module=False)
279
+ if not is_valid:
280
+ raise ValueError(errors)
281
+
282
+ return conf
283
+
284
+
285
+ def _validate_run_config(config_dict: dict[str, Any], errors: list[str]) -> None:
286
+ for key, value in config_dict.items():
287
+ if isinstance(value, dict):
288
+ _validate_run_config(config_dict[key], errors)
289
+ elif not isinstance(value, get_args(UserConfigValue)):
290
+ raise ValueError(
291
+ f"The value for key {key} needs to be of type `int`, `float`, "
292
+ "`bool, `str`, or a `dict` of those.",
293
+ )
294
+
295
+
296
+ # pylint: disable=too-many-branches
297
+ def validate_fields_in_config(
298
+ config: dict[str, Any]
299
+ ) -> tuple[bool, list[str], list[str]]:
300
+ """Validate pyproject.toml fields."""
301
+ errors = []
302
+ warnings = []
303
+
304
+ if "project" not in config:
305
+ errors.append("Missing [project] section")
306
+ else:
307
+ if "name" not in config["project"]:
308
+ errors.append('Property "name" missing in [project]')
309
+ if "version" not in config["project"]:
310
+ errors.append('Property "version" missing in [project]')
311
+ if "description" not in config["project"]:
312
+ warnings.append('Recommended property "description" missing in [project]')
313
+ if "license" not in config["project"]:
314
+ warnings.append('Recommended property "license" missing in [project]')
315
+ if "authors" not in config["project"]:
316
+ warnings.append('Recommended property "authors" missing in [project]')
317
+
318
+ if (
319
+ "tool" not in config
320
+ or "flwr" not in config["tool"]
321
+ or "app" not in config["tool"]["flwr"]
322
+ ):
323
+ errors.append("Missing [tool.flwr.app] section")
324
+ else:
325
+ if "publisher" not in config["tool"]["flwr"]["app"]:
326
+ errors.append('Property "publisher" missing in [tool.flwr.app]')
327
+ if "config" in config["tool"]["flwr"]["app"]:
328
+ _validate_run_config(config["tool"]["flwr"]["app"]["config"], errors)
329
+ if "components" not in config["tool"]["flwr"]["app"]:
330
+ errors.append("Missing [tool.flwr.app.components] section")
331
+ else:
332
+ if "serverapp" not in config["tool"]["flwr"]["app"]["components"]:
333
+ errors.append(
334
+ 'Property "serverapp" missing in [tool.flwr.app.components]'
335
+ )
336
+ if "clientapp" not in config["tool"]["flwr"]["app"]["components"]:
337
+ errors.append(
338
+ 'Property "clientapp" missing in [tool.flwr.app.components]'
339
+ )
340
+
341
+ return len(errors) == 0, errors, warnings
342
+
343
+
344
+ def validate_config(
345
+ config: dict[str, Any],
346
+ check_module: bool = True,
347
+ project_dir: Optional[Union[str, Path]] = None,
348
+ ) -> tuple[bool, list[str], list[str]]:
349
+ """Validate pyproject.toml."""
350
+ is_valid, errors, warnings = validate_fields_in_config(config)
351
+
352
+ if not is_valid:
353
+ return False, errors, warnings
354
+
355
+ # Validate serverapp
356
+ serverapp_ref = config["tool"]["flwr"]["app"]["components"]["serverapp"]
357
+ is_valid, reason = object_ref.validate(serverapp_ref, check_module, project_dir)
358
+
359
+ if not is_valid and isinstance(reason, str):
360
+ return False, [reason], []
361
+
362
+ # Validate clientapp
363
+ clientapp_ref = config["tool"]["flwr"]["app"]["components"]["clientapp"]
364
+ is_valid, reason = object_ref.validate(clientapp_ref, check_module, project_dir)
365
+
366
+ if not is_valid and isinstance(reason, str):
367
+ return False, [reason], []
368
+
369
+ return True, [], []
@@ -112,6 +112,12 @@ AUTH_TYPE = "auth_type"
112
112
  ACCESS_TOKEN_KEY = "access_token"
113
113
  REFRESH_TOKEN_KEY = "refresh_token"
114
114
 
115
+ # Constants for node authentication
116
+ PUBLIC_KEY_HEADER = "public-key-bin" # Must end with "-bin" for binary data
117
+ SIGNATURE_HEADER = "signature-bin" # Must end with "-bin" for binary data
118
+ TIMESTAMP_HEADER = "timestamp"
119
+ TIMESTAMP_TOLERANCE = 10 # Tolerance for timestamp verification
120
+
115
121
 
116
122
  class MessageType:
117
123
  """Message type."""
@@ -39,10 +39,12 @@ class ExitCode:
39
39
 
40
40
  # ClientApp-specific exit codes (400-499)
41
41
 
42
- # Common exit codes (500-)
43
- COMMON_ADDRESS_INVALID = 500
44
- COMMON_MISSING_EXTRA_REST = 501
45
- COMMON_TLS_NOT_SUPPORTED = 502
42
+ # Simulation-specific exit codes (500-599)
43
+
44
+ # Common exit codes (600-)
45
+ COMMON_ADDRESS_INVALID = 600
46
+ COMMON_MISSING_EXTRA_REST = 601
47
+ COMMON_TLS_NOT_SUPPORTED = 602
46
48
 
47
49
  def __new__(cls) -> ExitCode:
48
50
  """Prevent instantiation."""
@@ -75,7 +77,8 @@ EXIT_CODE_HELP = {
75
77
  "file and try again."
76
78
  ),
77
79
  # ClientApp-specific exit codes (400-499)
78
- # Common exit codes (500-)
80
+ # Simulation-specific exit codes (500-599)
81
+ # Common exit codes (600-)
79
82
  ExitCode.COMMON_ADDRESS_INVALID: (
80
83
  "Please provide a valid URL, IPv4 or IPv6 address."
81
84
  ),
@@ -0,0 +1,94 @@
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ # ==============================================================================
15
+ """Fleet API gRPC adapter servicer."""
16
+
17
+
18
+ from logging import DEBUG
19
+ from typing import Callable, TypeVar
20
+
21
+ import grpc
22
+ from google.protobuf.message import Message as GrpcMessage
23
+
24
+ from flwr.common.constant import (
25
+ GRPC_ADAPTER_METADATA_FLOWER_PACKAGE_NAME_KEY,
26
+ GRPC_ADAPTER_METADATA_FLOWER_PACKAGE_VERSION_KEY,
27
+ GRPC_ADAPTER_METADATA_FLOWER_VERSION_KEY,
28
+ GRPC_ADAPTER_METADATA_MESSAGE_MODULE_KEY,
29
+ GRPC_ADAPTER_METADATA_MESSAGE_QUALNAME_KEY,
30
+ )
31
+ from flwr.common.logger import log
32
+ from flwr.common.version import package_name, package_version
33
+ from flwr.proto import grpcadapter_pb2_grpc # pylint: disable=E0611
34
+ from flwr.proto.fab_pb2 import GetFabRequest # pylint: disable=E0611
35
+ from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
36
+ CreateNodeRequest,
37
+ DeleteNodeRequest,
38
+ PingRequest,
39
+ PullMessagesRequest,
40
+ PushMessagesRequest,
41
+ )
42
+ from flwr.proto.grpcadapter_pb2 import MessageContainer # pylint: disable=E0611
43
+ from flwr.proto.run_pb2 import GetRunRequest # pylint: disable=E0611
44
+
45
+ from ..grpc_rere.fleet_servicer import FleetServicer
46
+
47
+ T = TypeVar("T", bound=GrpcMessage)
48
+
49
+
50
+ def _handle(
51
+ msg_container: MessageContainer,
52
+ context: grpc.ServicerContext,
53
+ request_type: type[T],
54
+ handler: Callable[[T, grpc.ServicerContext], GrpcMessage],
55
+ ) -> MessageContainer:
56
+ req = request_type.FromString(msg_container.grpc_message_content)
57
+ res = handler(req, context)
58
+ res_cls = res.__class__
59
+ return MessageContainer(
60
+ metadata={
61
+ GRPC_ADAPTER_METADATA_FLOWER_PACKAGE_NAME_KEY: package_name,
62
+ GRPC_ADAPTER_METADATA_FLOWER_PACKAGE_VERSION_KEY: package_version,
63
+ GRPC_ADAPTER_METADATA_FLOWER_VERSION_KEY: package_version,
64
+ GRPC_ADAPTER_METADATA_MESSAGE_MODULE_KEY: res_cls.__module__,
65
+ GRPC_ADAPTER_METADATA_MESSAGE_QUALNAME_KEY: res_cls.__qualname__,
66
+ },
67
+ grpc_message_name=res_cls.__qualname__,
68
+ grpc_message_content=res.SerializeToString(),
69
+ )
70
+
71
+
72
+ class GrpcAdapterServicer(grpcadapter_pb2_grpc.GrpcAdapterServicer, FleetServicer):
73
+ """Fleet API via GrpcAdapter servicer."""
74
+
75
+ def SendReceive( # pylint: disable=too-many-return-statements
76
+ self, request: MessageContainer, context: grpc.ServicerContext
77
+ ) -> MessageContainer:
78
+ """."""
79
+ log(DEBUG, "GrpcAdapterServicer.SendReceive")
80
+ if request.grpc_message_name == CreateNodeRequest.__qualname__:
81
+ return _handle(request, context, CreateNodeRequest, self.CreateNode)
82
+ if request.grpc_message_name == DeleteNodeRequest.__qualname__:
83
+ return _handle(request, context, DeleteNodeRequest, self.DeleteNode)
84
+ if request.grpc_message_name == PingRequest.__qualname__:
85
+ return _handle(request, context, PingRequest, self.Ping)
86
+ if request.grpc_message_name == GetRunRequest.__qualname__:
87
+ return _handle(request, context, GetRunRequest, self.GetRun)
88
+ if request.grpc_message_name == GetFabRequest.__qualname__:
89
+ return _handle(request, context, GetFabRequest, self.GetFab)
90
+ if request.grpc_message_name == PullMessagesRequest.__qualname__:
91
+ return _handle(request, context, PullMessagesRequest, self.PullMessages)
92
+ if request.grpc_message_name == PushMessagesRequest.__qualname__:
93
+ return _handle(request, context, PushMessagesRequest, self.PushMessages)
94
+ raise ValueError(f"Invalid grpc_message_name: {request.grpc_message_name}")