flwr-nightly 1.9.0.dev20240417__tar.gz → 1.9.0.dev20240507__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 (226) hide show
  1. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/PKG-INFO +3 -2
  2. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/README.md +1 -1
  3. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/pyproject.toml +5 -9
  4. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/app.py +2 -0
  5. flwr_nightly-1.9.0.dev20240507/src/py/flwr/cli/build.py +151 -0
  6. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/config_utils.py +19 -14
  7. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/new/new.py +51 -22
  8. flwr_nightly-1.9.0.dev20240507/src/py/flwr/cli/new/templates/app/.gitignore.tpl +160 -0
  9. flwr_nightly-1.9.0.dev20240507/src/py/flwr/cli/new/templates/app/code/client.mlx.py.tpl +70 -0
  10. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +1 -1
  11. flwr_nightly-1.9.0.dev20240507/src/py/flwr/cli/new/templates/app/code/client.sklearn.py.tpl +94 -0
  12. flwr_nightly-1.9.0.dev20240507/src/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +43 -0
  13. flwr_nightly-1.9.0.dev20240507/src/py/flwr/cli/new/templates/app/code/server.mlx.py.tpl +15 -0
  14. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +1 -1
  15. flwr_nightly-1.9.0.dev20240507/src/py/flwr/cli/new/templates/app/code/server.sklearn.py.tpl +17 -0
  16. flwr_nightly-1.9.0.dev20240507/src/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +27 -0
  17. flwr_nightly-1.9.0.dev20240507/src/py/flwr/cli/new/templates/app/code/task.mlx.py.tpl +89 -0
  18. flwr_nightly-1.9.0.dev20240507/src/py/flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +29 -0
  19. flwr_nightly-1.9.0.dev20240507/src/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +28 -0
  20. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +7 -4
  21. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +7 -4
  22. flwr_nightly-1.9.0.dev20240507/src/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +27 -0
  23. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +7 -4
  24. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/run/run.py +1 -1
  25. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/utils.py +18 -17
  26. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/__init__.py +3 -1
  27. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/app.py +20 -142
  28. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/grpc_client/connection.py +8 -2
  29. flwr_nightly-1.9.0.dev20240507/src/py/flwr/client/grpc_rere_client/client_interceptor.py +158 -0
  30. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/grpc_rere_client/connection.py +33 -4
  31. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/mod/centraldp_mods.py +4 -2
  32. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/mod/localdp_mod.py +9 -3
  33. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/rest_client/connection.py +92 -169
  34. flwr_nightly-1.9.0.dev20240507/src/py/flwr/client/supernode/__init__.py +24 -0
  35. flwr_nightly-1.9.0.dev20240507/src/py/flwr/client/supernode/app.py +281 -0
  36. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/grpc.py +5 -1
  37. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/logger.py +37 -4
  38. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/message.py +105 -86
  39. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/record/parametersrecord.py +0 -1
  40. flwr_nightly-1.9.0.dev20240507/src/py/flwr/common/record/recordset.py +130 -0
  41. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +35 -1
  42. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/telemetry.py +4 -0
  43. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/app.py +116 -6
  44. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/compat/app.py +2 -2
  45. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/compat/app_utils.py +1 -1
  46. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/compat/driver_client_proxy.py +27 -70
  47. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/driver/__init__.py +2 -1
  48. flwr_nightly-1.9.0.dev20240507/src/py/flwr/server/driver/driver.py +140 -0
  49. flwr_nightly-1.9.0.dev20240417/src/py/flwr/server/driver/driver.py → flwr_nightly-1.9.0.dev20240507/src/py/flwr/server/driver/grpc_driver.py +141 -93
  50. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/run_serverapp.py +18 -4
  51. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/dp_adaptive_clipping.py +5 -3
  52. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/dp_fixed_clipping.py +6 -3
  53. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/driver/driver_servicer.py +1 -1
  54. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +3 -1
  55. flwr_nightly-1.9.0.dev20240507/src/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +215 -0
  56. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py +4 -1
  57. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +5 -5
  58. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/vce/vce_api.py +1 -1
  59. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/state/in_memory_state.py +89 -12
  60. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/state/sqlite_state.py +133 -16
  61. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/state/state.py +56 -6
  62. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/simulation/__init__.py +2 -2
  63. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/simulation/app.py +16 -1
  64. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/simulation/run_simulation.py +10 -7
  65. flwr_nightly-1.9.0.dev20240417/src/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -1
  66. flwr_nightly-1.9.0.dev20240417/src/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -1
  67. flwr_nightly-1.9.0.dev20240417/src/py/flwr/common/record/recordset.py +0 -79
  68. flwr_nightly-1.9.0.dev20240417/src/py/flwr/server/driver/grpc_driver.py +0 -129
  69. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/LICENSE +0 -0
  70. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/__init__.py +0 -0
  71. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/__init__.py +0 -0
  72. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/example.py +0 -0
  73. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/new/__init__.py +0 -0
  74. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/new/templates/__init__.py +0 -0
  75. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/new/templates/app/README.md.tpl +0 -0
  76. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/new/templates/app/__init__.py +0 -0
  77. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
  78. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
  79. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
  80. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
  81. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
  82. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/cli/run/__init__.py +0 -0
  83. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/client.py +0 -0
  84. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/client_app.py +0 -0
  85. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/dpfedavg_numpy_client.py +0 -0
  86. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/grpc_client/__init__.py +0 -0
  87. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/grpc_rere_client/__init__.py +0 -0
  88. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/heartbeat.py +0 -0
  89. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/message_handler/__init__.py +0 -0
  90. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/message_handler/message_handler.py +0 -0
  91. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/message_handler/task_handler.py +0 -0
  92. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/mod/__init__.py +0 -0
  93. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/mod/comms_mods.py +0 -0
  94. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
  95. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
  96. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
  97. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/mod/utils.py +0 -0
  98. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/node_state.py +0 -0
  99. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/node_state_tests.py +0 -0
  100. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/numpy_client.py +0 -0
  101. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/rest_client/__init__.py +0 -0
  102. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/client/typing.py +0 -0
  103. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/__init__.py +0 -0
  104. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/address.py +0 -0
  105. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/constant.py +0 -0
  106. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/context.py +0 -0
  107. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/date.py +0 -0
  108. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/differential_privacy.py +0 -0
  109. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/differential_privacy_constants.py +0 -0
  110. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/dp.py +0 -0
  111. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/exit_handlers.py +0 -0
  112. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/object_ref.py +0 -0
  113. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/parameter.py +0 -0
  114. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/pyproject.py +0 -0
  115. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/record/__init__.py +0 -0
  116. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/record/configsrecord.py +0 -0
  117. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/record/conversion_utils.py +0 -0
  118. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/record/metricsrecord.py +0 -0
  119. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/record/typeddict.py +0 -0
  120. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/recordset_compat.py +0 -0
  121. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/retry_invoker.py +0 -0
  122. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/secure_aggregation/__init__.py +0 -0
  123. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
  124. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
  125. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
  126. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/secure_aggregation/quantization.py +0 -0
  127. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
  128. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
  129. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/serde.py +0 -0
  130. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/typing.py +0 -0
  131. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/common/version.py +0 -0
  132. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/__init__.py +0 -0
  133. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/driver_pb2.py +0 -0
  134. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/driver_pb2.pyi +0 -0
  135. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/driver_pb2_grpc.py +0 -0
  136. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/driver_pb2_grpc.pyi +0 -0
  137. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/error_pb2.py +0 -0
  138. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/error_pb2.pyi +0 -0
  139. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/error_pb2_grpc.py +0 -0
  140. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/error_pb2_grpc.pyi +0 -0
  141. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/fleet_pb2.py +0 -0
  142. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/fleet_pb2.pyi +0 -0
  143. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/fleet_pb2_grpc.py +0 -0
  144. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
  145. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/node_pb2.py +0 -0
  146. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/node_pb2.pyi +0 -0
  147. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/node_pb2_grpc.py +0 -0
  148. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/node_pb2_grpc.pyi +0 -0
  149. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/recordset_pb2.py +0 -0
  150. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/recordset_pb2.pyi +0 -0
  151. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/recordset_pb2_grpc.py +0 -0
  152. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/recordset_pb2_grpc.pyi +0 -0
  153. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/task_pb2.py +0 -0
  154. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/task_pb2.pyi +0 -0
  155. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/task_pb2_grpc.py +0 -0
  156. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/task_pb2_grpc.pyi +0 -0
  157. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/transport_pb2.py +0 -0
  158. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/transport_pb2.pyi +0 -0
  159. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/transport_pb2_grpc.py +0 -0
  160. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
  161. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/py.typed +0 -0
  162. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/__init__.py +0 -0
  163. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/client_manager.py +0 -0
  164. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/client_proxy.py +0 -0
  165. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/compat/__init__.py +0 -0
  166. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/compat/legacy_context.py +0 -0
  167. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/criterion.py +0 -0
  168. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/history.py +0 -0
  169. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/server.py +0 -0
  170. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/server_app.py +0 -0
  171. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/server_config.py +0 -0
  172. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/__init__.py +0 -0
  173. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/aggregate.py +0 -0
  174. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/bulyan.py +0 -0
  175. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
  176. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
  177. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
  178. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/fedadagrad.py +0 -0
  179. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/fedadam.py +0 -0
  180. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/fedavg.py +0 -0
  181. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/fedavg_android.py +0 -0
  182. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/fedavgm.py +0 -0
  183. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/fedmedian.py +0 -0
  184. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/fedopt.py +0 -0
  185. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/fedprox.py +0 -0
  186. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
  187. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
  188. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
  189. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
  190. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/fedyogi.py +0 -0
  191. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/krum.py +0 -0
  192. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/qfedavg.py +0 -0
  193. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/strategy/strategy.py +0 -0
  194. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/__init__.py +0 -0
  195. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/driver/__init__.py +0 -0
  196. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/driver/driver_grpc.py +0 -0
  197. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/__init__.py +0 -0
  198. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
  199. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
  200. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
  201. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
  202. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
  203. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +0 -0
  204. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
  205. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
  206. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +0 -0
  207. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
  208. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
  209. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
  210. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/state/__init__.py +0 -0
  211. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/state/state_factory.py +0 -0
  212. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/superlink/state/utils.py +0 -0
  213. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/typing.py +0 -0
  214. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/utils/__init__.py +0 -0
  215. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/utils/tensorboard.py +0 -0
  216. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/utils/validator.py +0 -0
  217. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/workflow/__init__.py +0 -0
  218. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/workflow/constant.py +0 -0
  219. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/workflow/default_workflows.py +0 -0
  220. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
  221. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
  222. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
  223. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/simulation/ray_transport/__init__.py +0 -0
  224. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
  225. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
  226. {flwr_nightly-1.9.0.dev20240417 → flwr_nightly-1.9.0.dev20240507}/src/py/flwr/simulation/ray_transport/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flwr-nightly
3
- Version: 1.9.0.dev20240417
3
+ Version: 1.9.0.dev20240507
4
4
  Summary: Flower: A Friendly Federated Learning Framework
5
5
  Home-page: https://flower.ai
6
6
  License: Apache-2.0
@@ -36,6 +36,7 @@ Requires-Dist: cryptography (>=42.0.4,<43.0.0)
36
36
  Requires-Dist: grpcio (>=1.60.0,<2.0.0)
37
37
  Requires-Dist: iterators (>=0.0.2,<0.0.3)
38
38
  Requires-Dist: numpy (>=1.21.0,<2.0.0)
39
+ Requires-Dist: pathspec (>=0.12.1,<0.13.0)
39
40
  Requires-Dist: protobuf (>=4.25.2,<5.0.0)
40
41
  Requires-Dist: pycryptodome (>=3.18.0,<4.0.0)
41
42
  Requires-Dist: ray (==2.6.3) ; (python_version >= "3.8" and python_version < "3.12") and (extra == "simulation")
@@ -193,7 +194,7 @@ Other [examples](https://github.com/adap/flower/tree/main/examples):
193
194
  - [PyTorch: From Centralized to Federated](https://github.com/adap/flower/tree/main/examples/pytorch-from-centralized-to-federated)
194
195
  - [Vertical FL](https://github.com/adap/flower/tree/main/examples/vertical-fl)
195
196
  - [Federated Finetuning of OpenAI's Whisper](https://github.com/adap/flower/tree/main/examples/whisper-federated-finetuning)
196
- - [Federated Finetuning of Large Language Model](https://github.com/adap/flower/tree/main/examples/fedllm-finetune)
197
+ - [Federated Finetuning of Large Language Model](https://github.com/adap/flower/tree/main/examples/llm-flowertune)
197
198
  - [Federated Finetuning of a Vision Transformer](https://github.com/adap/flower/tree/main/examples/vit-finetune)
198
199
  - [Advanced Flower with TensorFlow/Keras](https://github.com/adap/flower/tree/main/examples/advanced-tensorflow)
199
200
  - [Advanced Flower with PyTorch](https://github.com/adap/flower/tree/main/examples/advanced-pytorch)
@@ -143,7 +143,7 @@ Other [examples](https://github.com/adap/flower/tree/main/examples):
143
143
  - [PyTorch: From Centralized to Federated](https://github.com/adap/flower/tree/main/examples/pytorch-from-centralized-to-federated)
144
144
  - [Vertical FL](https://github.com/adap/flower/tree/main/examples/vertical-fl)
145
145
  - [Federated Finetuning of OpenAI's Whisper](https://github.com/adap/flower/tree/main/examples/whisper-federated-finetuning)
146
- - [Federated Finetuning of Large Language Model](https://github.com/adap/flower/tree/main/examples/fedllm-finetune)
146
+ - [Federated Finetuning of Large Language Model](https://github.com/adap/flower/tree/main/examples/llm-flowertune)
147
147
  - [Federated Finetuning of a Vision Transformer](https://github.com/adap/flower/tree/main/examples/vit-finetune)
148
148
  - [Advanced Flower with TensorFlow/Keras](https://github.com/adap/flower/tree/main/examples/advanced-tensorflow)
149
149
  - [Advanced Flower with PyTorch](https://github.com/adap/flower/tree/main/examples/advanced-pytorch)
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "flwr-nightly"
7
- version = "1.9.0.dev20240417"
7
+ version = "1.9.0.dev20240507"
8
8
  description = "Flower: A Friendly Federated Learning Framework"
9
9
  license = "Apache-2.0"
10
10
  authors = ["The Flower Authors <hello@flower.ai>"]
@@ -56,9 +56,10 @@ flwr = "flwr.cli.app:app"
56
56
  flower-driver-api = "flwr.server:run_driver_api"
57
57
  flower-fleet-api = "flwr.server:run_fleet_api"
58
58
  flower-superlink = "flwr.server:run_superlink"
59
+ flower-supernode = "flwr.client:run_supernode"
59
60
  flower-client-app = "flwr.client:run_client_app"
60
61
  flower-server-app = "flwr.server:run_server_app"
61
- flower-simulation = "flwr.simulation:run_simulation_from_cli"
62
+ flower-simulation = "flwr.simulation.run_simulation:run_simulation_from_cli"
62
63
 
63
64
  [tool.poetry.dependencies]
64
65
  python = "^3.8"
@@ -71,6 +72,7 @@ pycryptodome = "^3.18.0"
71
72
  iterators = "^0.0.2"
72
73
  typer = { version = "^0.9.0", extras=["all"] }
73
74
  tomli = "^2.0.1"
75
+ pathspec = "^0.12.1"
74
76
  # Optional dependencies (Simulation Engine)
75
77
  ray = { version = "==2.6.3", optional = true, python = ">=3.8,<3.12" }
76
78
  # Optional dependencies (REST transport layer)
@@ -135,7 +137,7 @@ multi_line_output = 3
135
137
  include_trailing_comma = true
136
138
  force_grid_wrap = 0
137
139
  use_parentheses = true
138
- known_first_party = ["flwr", "flwr_experimental", "flwr_tool"]
140
+ known_first_party = ["flwr", "flwr_tool"]
139
141
 
140
142
  [tool.black]
141
143
  line-length = 88
@@ -169,12 +171,6 @@ plugins = [
169
171
  ignore_missing_imports = true
170
172
  strict = true
171
173
 
172
- [[tool.mypy.overrides]]
173
- module = [
174
- "flwr_experimental.*",
175
- ]
176
- ignore_errors = true
177
-
178
174
  [[tool.mypy.overrides]]
179
175
  module = [
180
176
  "importlib.metadata.*",
@@ -16,6 +16,7 @@
16
16
 
17
17
  import typer
18
18
 
19
+ from .build import build
19
20
  from .example import example
20
21
  from .new import new
21
22
  from .run import run
@@ -32,6 +33,7 @@ app = typer.Typer(
32
33
  app.command()(new)
33
34
  app.command()(example)
34
35
  app.command()(run)
36
+ app.command()(build)
35
37
 
36
38
  if __name__ == "__main__":
37
39
  app()
@@ -0,0 +1,151 @@
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 command line interface `build` command."""
16
+
17
+ import hashlib
18
+ import os
19
+ import zipfile
20
+ from pathlib import Path
21
+ from typing import Optional
22
+
23
+ import pathspec
24
+ import typer
25
+ from typing_extensions import Annotated
26
+
27
+ from .config_utils import load_and_validate_with_defaults
28
+ from .utils import is_valid_project_name
29
+
30
+
31
+ # pylint: disable=too-many-locals
32
+ def build(
33
+ directory: Annotated[
34
+ Optional[Path],
35
+ typer.Option(help="The Flower project directory to bundle into a FAB"),
36
+ ] = None,
37
+ ) -> None:
38
+ """Build a Flower project into a Flower App Bundle (FAB).
39
+
40
+ You can run `flwr build` without any argument to bundle the current directory:
41
+
42
+ `flwr build`
43
+
44
+ You can also build a specific directory:
45
+
46
+ `flwr build --directory ./projects/flower-hello-world`
47
+ """
48
+ if directory is None:
49
+ directory = Path.cwd()
50
+
51
+ directory = directory.resolve()
52
+ if not directory.is_dir():
53
+ typer.secho(
54
+ f"❌ The path {directory} is not a valid directory.",
55
+ fg=typer.colors.RED,
56
+ bold=True,
57
+ )
58
+ raise typer.Exit(code=1)
59
+
60
+ if not is_valid_project_name(directory.name):
61
+ typer.secho(
62
+ f"❌ The project name {directory.name} is invalid, "
63
+ "a valid project name must start with a letter or an underscore, "
64
+ "and can only contain letters, digits, and underscores.",
65
+ fg=typer.colors.RED,
66
+ bold=True,
67
+ )
68
+ raise typer.Exit(code=1)
69
+
70
+ conf, errors, warnings = load_and_validate_with_defaults(
71
+ directory / "pyproject.toml"
72
+ )
73
+ if conf is None:
74
+ typer.secho(
75
+ "Project configuration could not be loaded.\npyproject.toml is invalid:\n"
76
+ + "\n".join([f"- {line}" for line in errors]),
77
+ fg=typer.colors.RED,
78
+ bold=True,
79
+ )
80
+ raise typer.Exit(code=1)
81
+
82
+ if warnings:
83
+ typer.secho(
84
+ "Project configuration is missing the following "
85
+ "recommended properties:\n" + "\n".join([f"- {line}" for line in warnings]),
86
+ fg=typer.colors.RED,
87
+ bold=True,
88
+ )
89
+
90
+ # Load .gitignore rules if present
91
+ ignore_spec = _load_gitignore(directory)
92
+
93
+ # Set the name of the zip file
94
+ fab_filename = (
95
+ f"{conf['flower']['publisher']}"
96
+ f".{directory.name}"
97
+ f".{conf['project']['version'].replace('.', '-')}.fab"
98
+ )
99
+ list_file_content = ""
100
+
101
+ allowed_extensions = {".py", ".toml", ".md"}
102
+
103
+ with zipfile.ZipFile(fab_filename, "w", zipfile.ZIP_DEFLATED) as fab_file:
104
+ for root, _, files in os.walk(directory, topdown=True):
105
+ # Filter directories and files based on .gitignore
106
+ files = [
107
+ f
108
+ for f in files
109
+ if not ignore_spec.match_file(Path(root) / f)
110
+ and f != fab_filename
111
+ and Path(f).suffix in allowed_extensions
112
+ ]
113
+
114
+ for file in files:
115
+ file_path = Path(root) / file
116
+ archive_path = file_path.relative_to(directory)
117
+ fab_file.write(file_path, archive_path)
118
+
119
+ # Calculate file info
120
+ sha256_hash = _get_sha256_hash(file_path)
121
+ file_size_bits = os.path.getsize(file_path) * 8 # size in bits
122
+ list_file_content += f"{archive_path},{sha256_hash},{file_size_bits}\n"
123
+
124
+ # Add CONTENT and CONTENT.jwt to the zip file
125
+ fab_file.writestr(".info/CONTENT", list_file_content)
126
+
127
+ typer.secho(
128
+ f"🎊 Successfully built {fab_filename}.", fg=typer.colors.GREEN, bold=True
129
+ )
130
+
131
+
132
+ def _get_sha256_hash(file_path: Path) -> str:
133
+ """Calculate the SHA-256 hash of a file."""
134
+ sha256 = hashlib.sha256()
135
+ with open(file_path, "rb") as f:
136
+ while True:
137
+ data = f.read(65536) # Read in 64kB blocks
138
+ if not data:
139
+ break
140
+ sha256.update(data)
141
+ return sha256.hexdigest()
142
+
143
+
144
+ def _load_gitignore(directory: Path) -> pathspec.PathSpec:
145
+ """Load and parse .gitignore file, returning a pathspec."""
146
+ gitignore_path = directory / ".gitignore"
147
+ patterns = ["__pycache__/"] # Default pattern
148
+ if gitignore_path.exists():
149
+ with open(gitignore_path, encoding="UTF-8") as file:
150
+ patterns.extend(file.readlines())
151
+ return pathspec.PathSpec.from_lines("gitwildmatch", patterns)
@@ -14,7 +14,7 @@
14
14
  # ==============================================================================
15
15
  """Utility to validate the `pyproject.toml` file."""
16
16
 
17
- import os
17
+ from pathlib import Path
18
18
  from typing import Any, Dict, List, Optional, Tuple
19
19
 
20
20
  import tomli
@@ -23,7 +23,7 @@ from flwr.common import object_ref
23
23
 
24
24
 
25
25
  def load_and_validate_with_defaults(
26
- path: Optional[str] = None,
26
+ path: Optional[Path] = None,
27
27
  ) -> Tuple[Optional[Dict[str, Any]], List[str], List[str]]:
28
28
  """Load and validate pyproject.toml as dict.
29
29
 
@@ -37,7 +37,8 @@ def load_and_validate_with_defaults(
37
37
 
38
38
  if config is None:
39
39
  errors = [
40
- "Project configuration could not be loaded. pyproject.toml does not exist."
40
+ "Project configuration could not be loaded. "
41
+ "`pyproject.toml` does not exist."
41
42
  ]
42
43
  return (None, errors, [])
43
44
 
@@ -57,22 +58,23 @@ def load_and_validate_with_defaults(
57
58
  return (config, errors, warnings)
58
59
 
59
60
 
60
- def load(path: Optional[str] = None) -> Optional[Dict[str, Any]]:
61
+ def load(path: Optional[Path] = None) -> Optional[Dict[str, Any]]:
61
62
  """Load pyproject.toml and return as dict."""
62
63
  if path is None:
63
- cur_dir = os.getcwd()
64
- toml_path = os.path.join(cur_dir, "pyproject.toml")
64
+ cur_dir = Path.cwd()
65
+ toml_path = cur_dir / "pyproject.toml"
65
66
  else:
66
67
  toml_path = path
67
68
 
68
- if not os.path.isfile(toml_path):
69
+ if not toml_path.is_file():
69
70
  return None
70
71
 
71
- with open(toml_path, encoding="utf-8") as toml_file:
72
+ with toml_path.open(encoding="utf-8") as toml_file:
72
73
  data = tomli.loads(toml_file.read())
73
74
  return data
74
75
 
75
76
 
77
+ # pylint: disable=too-many-branches
76
78
  def validate_fields(config: Dict[str, Any]) -> Tuple[bool, List[str], List[str]]:
77
79
  """Validate pyproject.toml fields."""
78
80
  errors = []
@@ -94,13 +96,16 @@ def validate_fields(config: Dict[str, Any]) -> Tuple[bool, List[str], List[str]]
94
96
 
95
97
  if "flower" not in config:
96
98
  errors.append("Missing [flower] section")
97
- elif "components" not in config["flower"]:
98
- errors.append("Missing [flower.components] section")
99
99
  else:
100
- if "serverapp" not in config["flower"]["components"]:
101
- errors.append('Property "serverapp" missing in [flower.components]')
102
- if "clientapp" not in config["flower"]["components"]:
103
- errors.append('Property "clientapp" missing in [flower.components]')
100
+ if "publisher" not in config["flower"]:
101
+ errors.append('Property "publisher" missing in [flower]')
102
+ if "components" not in config["flower"]:
103
+ errors.append("Missing [flower.components] section")
104
+ else:
105
+ if "serverapp" not in config["flower"]["components"]:
106
+ errors.append('Property "serverapp" missing in [flower.components]')
107
+ if "clientapp" not in config["flower"]["components"]:
108
+ errors.append('Property "clientapp" missing in [flower.components]')
104
109
 
105
110
  return len(errors) == 0, errors, warnings
106
111
 
@@ -15,6 +15,7 @@
15
15
  """Flower command line interface `new` command."""
16
16
 
17
17
  import os
18
+ import re
18
19
  from enum import Enum
19
20
  from string import Template
20
21
  from typing import Dict, Optional
@@ -36,6 +37,8 @@ class MlFramework(str, Enum):
36
37
  NUMPY = "NumPy"
37
38
  PYTORCH = "PyTorch"
38
39
  TENSORFLOW = "TensorFlow"
40
+ MLX = "MLX"
41
+ SKLEARN = "sklearn"
39
42
 
40
43
 
41
44
  class TemplateNotFound(Exception):
@@ -58,8 +61,9 @@ def render_template(template: str, data: Dict[str, str]) -> str:
58
61
  """Render template."""
59
62
  tpl_file = load_template(template)
60
63
  tpl = Template(tpl_file)
61
- result = tpl.substitute(data)
62
- return result
64
+ if ".gitignore" not in template:
65
+ return tpl.substitute(data)
66
+ return tpl.template
63
67
 
64
68
 
65
69
  def create_file(file_path: str, content: str) -> None:
@@ -84,32 +88,31 @@ def new(
84
88
  Optional[MlFramework],
85
89
  typer.Option(case_sensitive=False, help="The ML framework to use"),
86
90
  ] = None,
91
+ username: Annotated[
92
+ Optional[str],
93
+ typer.Option(case_sensitive=False, help="The Flower username of the author"),
94
+ ] = None,
87
95
  ) -> None:
88
96
  """Create new Flower project."""
89
97
  if project_name is None:
90
- project_name = prompt_text("Please provide project name")
98
+ project_name = prompt_text("Please provide the project name")
91
99
  if not is_valid_project_name(project_name):
92
100
  project_name = prompt_text(
93
101
  "Please provide a name that only contains "
94
- "characters in {'_', 'a-zA-Z', '0-9'}",
102
+ "characters in {'-', a-zA-Z', '0-9'}",
95
103
  predicate=is_valid_project_name,
96
104
  default=sanitize_project_name(project_name),
97
105
  )
98
106
 
99
- print(
100
- typer.style(
101
- f"🔨 Creating Flower project {project_name}...",
102
- fg=typer.colors.GREEN,
103
- bold=True,
104
- )
105
- )
107
+ if username is None:
108
+ username = prompt_text("Please provide your Flower username")
106
109
 
107
110
  if framework is not None:
108
111
  framework_str = str(framework.value)
109
112
  else:
110
113
  framework_value = prompt_options(
111
114
  "Please select ML framework by typing in the number",
112
- [mlf.value for mlf in MlFramework],
115
+ sorted([mlf.value for mlf in MlFramework]),
113
116
  )
114
117
  selected_value = [
115
118
  name
@@ -120,25 +123,51 @@ def new(
120
123
 
121
124
  framework_str = framework_str.lower()
122
125
 
126
+ print(
127
+ typer.style(
128
+ f"\n🔨 Creating Flower project {project_name}...",
129
+ fg=typer.colors.GREEN,
130
+ bold=True,
131
+ )
132
+ )
133
+
123
134
  # Set project directory path
124
135
  cwd = os.getcwd()
125
- pnl = project_name.lower()
126
- project_dir = os.path.join(cwd, pnl)
136
+ package_name = re.sub(r"[-_.]+", "-", project_name).lower()
137
+ import_name = package_name.replace("-", "_")
138
+ project_dir = os.path.join(cwd, package_name)
127
139
 
128
140
  # List of files to render
129
141
  files = {
142
+ ".gitignore": {"template": "app/.gitignore.tpl"},
130
143
  "README.md": {"template": "app/README.md.tpl"},
131
144
  "pyproject.toml": {"template": f"app/pyproject.{framework_str}.toml.tpl"},
132
- f"{pnl}/__init__.py": {"template": "app/code/__init__.py.tpl"},
133
- f"{pnl}/server.py": {"template": f"app/code/server.{framework_str}.py.tpl"},
134
- f"{pnl}/client.py": {"template": f"app/code/client.{framework_str}.py.tpl"},
145
+ f"{import_name}/__init__.py": {"template": "app/code/__init__.py.tpl"},
146
+ f"{import_name}/server.py": {
147
+ "template": f"app/code/server.{framework_str}.py.tpl"
148
+ },
149
+ f"{import_name}/client.py": {
150
+ "template": f"app/code/client.{framework_str}.py.tpl"
151
+ },
135
152
  }
136
153
 
137
- # In case framework is MlFramework.PYTORCH generate additionally the task.py file
138
- if framework_str == MlFramework.PYTORCH.value.lower():
139
- files[f"{pnl}/task.py"] = {"template": f"app/code/task.{framework_str}.py.tpl"}
140
-
141
- context = {"project_name": project_name}
154
+ # Depending on the framework, generate task.py file
155
+ frameworks_with_tasks = [
156
+ MlFramework.PYTORCH.value.lower(),
157
+ MlFramework.MLX.value.lower(),
158
+ MlFramework.TENSORFLOW.value.lower(),
159
+ ]
160
+ if framework_str in frameworks_with_tasks:
161
+ files[f"{import_name}/task.py"] = {
162
+ "template": f"app/code/task.{framework_str}.py.tpl"
163
+ }
164
+
165
+ context = {
166
+ "project_name": project_name,
167
+ "package_name": package_name,
168
+ "import_name": import_name.replace("-", "_"),
169
+ "username": username,
170
+ }
142
171
 
143
172
  for file_path, value in files.items():
144
173
  render_and_create(
@@ -0,0 +1,160 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # poetry
98
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102
+ #poetry.lock
103
+
104
+ # pdm
105
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106
+ #pdm.lock
107
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108
+ # in version control.
109
+ # https://pdm.fming.dev/#use-with-ide
110
+ .pdm.toml
111
+
112
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
113
+ __pypackages__/
114
+
115
+ # Celery stuff
116
+ celerybeat-schedule
117
+ celerybeat.pid
118
+
119
+ # SageMath parsed files
120
+ *.sage.py
121
+
122
+ # Environments
123
+ .env
124
+ .venv
125
+ env/
126
+ venv/
127
+ ENV/
128
+ env.bak/
129
+ venv.bak/
130
+
131
+ # Spyder project settings
132
+ .spyderproject
133
+ .spyproject
134
+
135
+ # Rope project settings
136
+ .ropeproject
137
+
138
+ # mkdocs documentation
139
+ /site
140
+
141
+ # mypy
142
+ .mypy_cache/
143
+ .dmypy.json
144
+ dmypy.json
145
+
146
+ # Pyre type checker
147
+ .pyre/
148
+
149
+ # pytype static type analyzer
150
+ .pytype/
151
+
152
+ # Cython debug symbols
153
+ cython_debug/
154
+
155
+ # PyCharm
156
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
157
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
158
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
159
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
160
+ #.idea/