flwr-nightly 1.9.0.dev20240416__tar.gz → 1.9.0.dev20240418__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 (212) hide show
  1. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/PKG-INFO +1 -1
  2. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/pyproject.toml +1 -1
  3. flwr_nightly-1.9.0.dev20240416/src/py/flwr/cli/flower_toml.py → flwr_nightly-1.9.0.dev20240418/src/py/flwr/cli/config_utils.py +7 -7
  4. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/new.py +9 -5
  5. flwr_nightly-1.9.0.dev20240418/src/py/flwr/cli/new/templates/app/.gitignore.tpl +160 -0
  6. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +4 -0
  7. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +4 -0
  8. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +4 -0
  9. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/run/run.py +2 -2
  10. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/rest_client/connection.py +6 -6
  11. flwr_nightly-1.9.0.dev20240418/src/py/flwr/common/record/recordset.py +118 -0
  12. flwr_nightly-1.9.0.dev20240418/src/py/flwr/server/driver/abc_driver.py +140 -0
  13. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/driver/driver_servicer.py +1 -1
  14. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/state/in_memory_state.py +13 -4
  15. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/state/sqlite_state.py +17 -5
  16. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/state/state.py +21 -3
  17. flwr_nightly-1.9.0.dev20240416/src/py/flwr/cli/new/templates/app/flower.toml.tpl +0 -13
  18. flwr_nightly-1.9.0.dev20240416/src/py/flwr/common/record/recordset.py +0 -79
  19. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/LICENSE +0 -0
  20. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/README.md +0 -0
  21. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/__init__.py +0 -0
  22. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/__init__.py +0 -0
  23. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/app.py +0 -0
  24. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/example.py +0 -0
  25. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/__init__.py +0 -0
  26. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/templates/__init__.py +0 -0
  27. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/templates/app/README.md.tpl +0 -0
  28. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/templates/app/__init__.py +0 -0
  29. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
  30. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
  31. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
  32. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -0
  33. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -0
  34. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
  35. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -0
  36. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -0
  37. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
  38. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/run/__init__.py +0 -0
  39. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/cli/utils.py +0 -0
  40. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/__init__.py +0 -0
  41. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/app.py +0 -0
  42. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/client.py +0 -0
  43. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/client_app.py +0 -0
  44. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/dpfedavg_numpy_client.py +0 -0
  45. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/grpc_client/__init__.py +0 -0
  46. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/grpc_client/connection.py +0 -0
  47. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/grpc_rere_client/__init__.py +0 -0
  48. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/grpc_rere_client/connection.py +0 -0
  49. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/heartbeat.py +0 -0
  50. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/message_handler/__init__.py +0 -0
  51. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/message_handler/message_handler.py +0 -0
  52. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/message_handler/task_handler.py +0 -0
  53. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/mod/__init__.py +0 -0
  54. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/mod/centraldp_mods.py +0 -0
  55. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/mod/comms_mods.py +0 -0
  56. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/mod/localdp_mod.py +0 -0
  57. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
  58. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
  59. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
  60. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/mod/utils.py +0 -0
  61. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/node_state.py +0 -0
  62. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/node_state_tests.py +0 -0
  63. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/numpy_client.py +0 -0
  64. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/rest_client/__init__.py +0 -0
  65. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/client/typing.py +0 -0
  66. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/__init__.py +0 -0
  67. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/address.py +0 -0
  68. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/constant.py +0 -0
  69. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/context.py +0 -0
  70. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/date.py +0 -0
  71. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/differential_privacy.py +0 -0
  72. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/differential_privacy_constants.py +0 -0
  73. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/dp.py +0 -0
  74. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/exit_handlers.py +0 -0
  75. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/grpc.py +0 -0
  76. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/logger.py +0 -0
  77. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/message.py +0 -0
  78. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/object_ref.py +0 -0
  79. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/parameter.py +0 -0
  80. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/pyproject.py +0 -0
  81. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/record/__init__.py +0 -0
  82. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/record/configsrecord.py +0 -0
  83. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/record/conversion_utils.py +0 -0
  84. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/record/metricsrecord.py +0 -0
  85. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/record/parametersrecord.py +0 -0
  86. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/record/typeddict.py +0 -0
  87. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/recordset_compat.py +0 -0
  88. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/retry_invoker.py +0 -0
  89. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/secure_aggregation/__init__.py +0 -0
  90. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
  91. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
  92. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
  93. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
  94. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/secure_aggregation/quantization.py +0 -0
  95. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
  96. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
  97. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/serde.py +0 -0
  98. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/telemetry.py +0 -0
  99. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/typing.py +0 -0
  100. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/common/version.py +0 -0
  101. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/__init__.py +0 -0
  102. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/driver_pb2.py +0 -0
  103. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/driver_pb2.pyi +0 -0
  104. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/driver_pb2_grpc.py +0 -0
  105. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/driver_pb2_grpc.pyi +0 -0
  106. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/error_pb2.py +0 -0
  107. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/error_pb2.pyi +0 -0
  108. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/error_pb2_grpc.py +0 -0
  109. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/error_pb2_grpc.pyi +0 -0
  110. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/fleet_pb2.py +0 -0
  111. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/fleet_pb2.pyi +0 -0
  112. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/fleet_pb2_grpc.py +0 -0
  113. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
  114. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/node_pb2.py +0 -0
  115. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/node_pb2.pyi +0 -0
  116. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/node_pb2_grpc.py +0 -0
  117. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/node_pb2_grpc.pyi +0 -0
  118. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/recordset_pb2.py +0 -0
  119. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/recordset_pb2.pyi +0 -0
  120. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/recordset_pb2_grpc.py +0 -0
  121. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/recordset_pb2_grpc.pyi +0 -0
  122. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/task_pb2.py +0 -0
  123. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/task_pb2.pyi +0 -0
  124. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/task_pb2_grpc.py +0 -0
  125. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/task_pb2_grpc.pyi +0 -0
  126. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/transport_pb2.py +0 -0
  127. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/transport_pb2.pyi +0 -0
  128. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/transport_pb2_grpc.py +0 -0
  129. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
  130. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/py.typed +0 -0
  131. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/__init__.py +0 -0
  132. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/app.py +0 -0
  133. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/client_manager.py +0 -0
  134. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/client_proxy.py +0 -0
  135. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/compat/__init__.py +0 -0
  136. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/compat/app.py +0 -0
  137. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/compat/app_utils.py +0 -0
  138. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/compat/driver_client_proxy.py +0 -0
  139. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/compat/legacy_context.py +0 -0
  140. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/criterion.py +0 -0
  141. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/driver/__init__.py +0 -0
  142. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/driver/driver.py +0 -0
  143. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/driver/grpc_driver.py +0 -0
  144. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/history.py +0 -0
  145. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/run_serverapp.py +0 -0
  146. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/server.py +0 -0
  147. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/server_app.py +0 -0
  148. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/server_config.py +0 -0
  149. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/__init__.py +0 -0
  150. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/aggregate.py +0 -0
  151. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/bulyan.py +0 -0
  152. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
  153. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
  154. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
  155. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
  156. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
  157. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/fedadagrad.py +0 -0
  158. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/fedadam.py +0 -0
  159. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/fedavg.py +0 -0
  160. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/fedavg_android.py +0 -0
  161. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/fedavgm.py +0 -0
  162. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/fedmedian.py +0 -0
  163. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/fedopt.py +0 -0
  164. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/fedprox.py +0 -0
  165. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
  166. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
  167. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
  168. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
  169. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/fedyogi.py +0 -0
  170. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/krum.py +0 -0
  171. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/qfedavg.py +0 -0
  172. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/strategy/strategy.py +0 -0
  173. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/__init__.py +0 -0
  174. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/driver/__init__.py +0 -0
  175. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/driver/driver_grpc.py +0 -0
  176. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/__init__.py +0 -0
  177. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
  178. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
  179. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
  180. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
  181. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
  182. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
  183. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +0 -0
  184. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
  185. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py +0 -0
  186. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
  187. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +0 -0
  188. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
  189. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
  190. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
  191. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +0 -0
  192. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/fleet/vce/vce_api.py +0 -0
  193. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/state/__init__.py +0 -0
  194. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/state/state_factory.py +0 -0
  195. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/superlink/state/utils.py +0 -0
  196. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/typing.py +0 -0
  197. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/utils/__init__.py +0 -0
  198. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/utils/tensorboard.py +0 -0
  199. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/utils/validator.py +0 -0
  200. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/workflow/__init__.py +0 -0
  201. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/workflow/constant.py +0 -0
  202. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/workflow/default_workflows.py +0 -0
  203. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
  204. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
  205. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
  206. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/simulation/__init__.py +0 -0
  207. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/simulation/app.py +0 -0
  208. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/simulation/ray_transport/__init__.py +0 -0
  209. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
  210. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
  211. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/simulation/ray_transport/utils.py +0 -0
  212. {flwr_nightly-1.9.0.dev20240416 → flwr_nightly-1.9.0.dev20240418}/src/py/flwr/simulation/run_simulation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flwr-nightly
3
- Version: 1.9.0.dev20240416
3
+ Version: 1.9.0.dev20240418
4
4
  Summary: Flower: A Friendly Federated Learning Framework
5
5
  Home-page: https://flower.ai
6
6
  License: Apache-2.0
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "flwr-nightly"
7
- version = "1.9.0-dev20240416"
7
+ version = "1.9.0.dev20240418"
8
8
  description = "Flower: A Friendly Federated Learning Framework"
9
9
  license = "Apache-2.0"
10
10
  authors = ["The Flower Authors <hello@flower.ai>"]
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  # ==============================================================================
15
- """Utility to validate the `flower.toml` file."""
15
+ """Utility to validate the `pyproject.toml` file."""
16
16
 
17
17
  import os
18
18
  from typing import Any, Dict, List, Optional, Tuple
@@ -25,7 +25,7 @@ from flwr.common import object_ref
25
25
  def load_and_validate_with_defaults(
26
26
  path: Optional[str] = None,
27
27
  ) -> Tuple[Optional[Dict[str, Any]], List[str], List[str]]:
28
- """Load and validate flower.toml as dict.
28
+ """Load and validate pyproject.toml as dict.
29
29
 
30
30
  Returns
31
31
  -------
@@ -37,7 +37,7 @@ def load_and_validate_with_defaults(
37
37
 
38
38
  if config is None:
39
39
  errors = [
40
- "Project configuration could not be loaded. flower.toml does not exist."
40
+ "Project configuration could not be loaded. pyproject.toml does not exist."
41
41
  ]
42
42
  return (None, errors, [])
43
43
 
@@ -58,10 +58,10 @@ def load_and_validate_with_defaults(
58
58
 
59
59
 
60
60
  def load(path: Optional[str] = None) -> Optional[Dict[str, Any]]:
61
- """Load flower.toml and return as dict."""
61
+ """Load pyproject.toml and return as dict."""
62
62
  if path is None:
63
63
  cur_dir = os.getcwd()
64
- toml_path = os.path.join(cur_dir, "flower.toml")
64
+ toml_path = os.path.join(cur_dir, "pyproject.toml")
65
65
  else:
66
66
  toml_path = path
67
67
 
@@ -74,7 +74,7 @@ def load(path: Optional[str] = None) -> Optional[Dict[str, Any]]:
74
74
 
75
75
 
76
76
  def validate_fields(config: Dict[str, Any]) -> Tuple[bool, List[str], List[str]]:
77
- """Validate flower.toml fields."""
77
+ """Validate pyproject.toml fields."""
78
78
  errors = []
79
79
  warnings = []
80
80
 
@@ -106,7 +106,7 @@ def validate_fields(config: Dict[str, Any]) -> Tuple[bool, List[str], List[str]]
106
106
 
107
107
 
108
108
  def validate(config: Dict[str, Any]) -> Tuple[bool, List[str], List[str]]:
109
- """Validate flower.toml."""
109
+ """Validate pyproject.toml."""
110
110
  is_valid, errors, warnings = validate_fields(config)
111
111
 
112
112
  if not is_valid:
@@ -58,8 +58,9 @@ def render_template(template: str, data: Dict[str, str]) -> str:
58
58
  """Render template."""
59
59
  tpl_file = load_template(template)
60
60
  tpl = Template(tpl_file)
61
- result = tpl.substitute(data)
62
- return result
61
+ if ".gitignore" not in template:
62
+ return tpl.substitute(data)
63
+ return tpl.template
63
64
 
64
65
 
65
66
  def create_file(file_path: str, content: str) -> None:
@@ -127,16 +128,19 @@ def new(
127
128
 
128
129
  # List of files to render
129
130
  files = {
131
+ ".gitignore": {"template": "app/.gitignore.tpl"},
130
132
  "README.md": {"template": "app/README.md.tpl"},
131
- "flower.toml": {"template": "app/flower.toml.tpl"},
132
133
  "pyproject.toml": {"template": f"app/pyproject.{framework_str}.toml.tpl"},
133
134
  f"{pnl}/__init__.py": {"template": "app/code/__init__.py.tpl"},
134
135
  f"{pnl}/server.py": {"template": f"app/code/server.{framework_str}.py.tpl"},
135
136
  f"{pnl}/client.py": {"template": f"app/code/client.{framework_str}.py.tpl"},
136
137
  }
137
138
 
138
- # In case framework is MlFramework.PYTORCH generate additionally the task.py file
139
- if framework_str == MlFramework.PYTORCH.value.lower():
139
+ # Depending on the framework, generate task.py file
140
+ frameworks_with_tasks = [
141
+ MlFramework.PYTORCH.value.lower(),
142
+ ]
143
+ if framework_str in frameworks_with_tasks:
140
144
  files[f"{pnl}/task.py"] = {"template": f"app/code/task.{framework_str}.py.tpl"}
141
145
 
142
146
  context = {"project_name": project_name}
@@ -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/
@@ -17,3 +17,7 @@ dependencies = [
17
17
 
18
18
  [tool.hatch.build.targets.wheel]
19
19
  packages = ["."]
20
+
21
+ [flower.components]
22
+ serverapp = "$project_name.server:app"
23
+ clientapp = "$project_name.client:app"
@@ -19,3 +19,7 @@ dependencies = [
19
19
 
20
20
  [tool.hatch.build.targets.wheel]
21
21
  packages = ["."]
22
+
23
+ [flower.components]
24
+ serverapp = "$project_name.server:app"
25
+ clientapp = "$project_name.client:app"
@@ -18,3 +18,7 @@ dependencies = [
18
18
 
19
19
  [tool.hatch.build.targets.wheel]
20
20
  packages = ["."]
21
+
22
+ [flower.components]
23
+ serverapp = "$project_name.server:app"
24
+ clientapp = "$project_name.client:app"
@@ -18,7 +18,7 @@ import sys
18
18
 
19
19
  import typer
20
20
 
21
- from flwr.cli import flower_toml
21
+ from flwr.cli import config_utils
22
22
  from flwr.simulation.run_simulation import _run_simulation
23
23
 
24
24
 
@@ -26,7 +26,7 @@ def run() -> None:
26
26
  """Run Flower project."""
27
27
  typer.secho("Loading project configuration... ", fg=typer.colors.BLUE)
28
28
 
29
- config, errors, warnings = flower_toml.load_and_validate_with_defaults()
29
+ config, errors, warnings = config_utils.load_and_validate_with_defaults()
30
30
 
31
31
  if config is None:
32
32
  typer.secho(
@@ -173,14 +173,14 @@ def http_request_response( # pylint: disable=R0914, R0915
173
173
  log(
174
174
  WARN,
175
175
  "[Node] POST /%s: missing header `Content-Type`",
176
- PATH_PULL_TASK_INS,
176
+ PATH_PING,
177
177
  )
178
178
  return
179
179
  if res.headers["content-type"] != "application/protobuf":
180
180
  log(
181
181
  WARN,
182
182
  "[Node] POST /%s: header `Content-Type` has wrong value",
183
- PATH_PULL_TASK_INS,
183
+ PATH_PING,
184
184
  )
185
185
  return
186
186
 
@@ -223,14 +223,14 @@ def http_request_response( # pylint: disable=R0914, R0915
223
223
  log(
224
224
  WARN,
225
225
  "[Node] POST /%s: missing header `Content-Type`",
226
- PATH_PULL_TASK_INS,
226
+ PATH_CREATE_NODE,
227
227
  )
228
228
  return
229
229
  if res.headers["content-type"] != "application/protobuf":
230
230
  log(
231
231
  WARN,
232
232
  "[Node] POST /%s: header `Content-Type` has wrong value",
233
- PATH_PULL_TASK_INS,
233
+ PATH_CREATE_NODE,
234
234
  )
235
235
  return
236
236
 
@@ -277,14 +277,14 @@ def http_request_response( # pylint: disable=R0914, R0915
277
277
  log(
278
278
  WARN,
279
279
  "[Node] POST /%s: missing header `Content-Type`",
280
- PATH_PULL_TASK_INS,
280
+ PATH_DELETE_NODE,
281
281
  )
282
282
  return
283
283
  if res.headers["content-type"] != "application/protobuf":
284
284
  log(
285
285
  WARN,
286
286
  "[Node] POST /%s: header `Content-Type` has wrong value",
287
- PATH_PULL_TASK_INS,
287
+ PATH_DELETE_NODE,
288
288
  )
289
289
 
290
290
  # Cleanup
@@ -0,0 +1,118 @@
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
+ """RecordSet."""
16
+
17
+
18
+ from dataclasses import dataclass
19
+ from typing import Dict, Optional, cast
20
+
21
+ from .configsrecord import ConfigsRecord
22
+ from .metricsrecord import MetricsRecord
23
+ from .parametersrecord import ParametersRecord
24
+ from .typeddict import TypedDict
25
+
26
+
27
+ class RecordSetData:
28
+ """Inner data container for the RecordSet class."""
29
+
30
+ parameters_records: TypedDict[str, ParametersRecord]
31
+ metrics_records: TypedDict[str, MetricsRecord]
32
+ configs_records: TypedDict[str, ConfigsRecord]
33
+
34
+ def __init__(
35
+ self,
36
+ parameters_records: Optional[Dict[str, ParametersRecord]] = None,
37
+ metrics_records: Optional[Dict[str, MetricsRecord]] = None,
38
+ configs_records: Optional[Dict[str, ConfigsRecord]] = None,
39
+ ) -> None:
40
+ self.parameters_records = TypedDict[str, ParametersRecord](
41
+ self._check_fn_str, self._check_fn_params
42
+ )
43
+ self.metrics_records = TypedDict[str, MetricsRecord](
44
+ self._check_fn_str, self._check_fn_metrics
45
+ )
46
+ self.configs_records = TypedDict[str, ConfigsRecord](
47
+ self._check_fn_str, self._check_fn_configs
48
+ )
49
+ if parameters_records is not None:
50
+ self.parameters_records.update(parameters_records)
51
+ if metrics_records is not None:
52
+ self.metrics_records.update(metrics_records)
53
+ if configs_records is not None:
54
+ self.configs_records.update(configs_records)
55
+
56
+ def _check_fn_str(self, key: str) -> None:
57
+ if not isinstance(key, str):
58
+ raise TypeError(
59
+ f"Expected `{str.__name__}`, but "
60
+ f"received `{type(key).__name__}` for the key."
61
+ )
62
+
63
+ def _check_fn_params(self, record: ParametersRecord) -> None:
64
+ if not isinstance(record, ParametersRecord):
65
+ raise TypeError(
66
+ f"Expected `{ParametersRecord.__name__}`, but "
67
+ f"received `{type(record).__name__}` for the value."
68
+ )
69
+
70
+ def _check_fn_metrics(self, record: MetricsRecord) -> None:
71
+ if not isinstance(record, MetricsRecord):
72
+ raise TypeError(
73
+ f"Expected `{MetricsRecord.__name__}`, but "
74
+ f"received `{type(record).__name__}` for the value."
75
+ )
76
+
77
+ def _check_fn_configs(self, record: ConfigsRecord) -> None:
78
+ if not isinstance(record, ConfigsRecord):
79
+ raise TypeError(
80
+ f"Expected `{ConfigsRecord.__name__}`, but "
81
+ f"received `{type(record).__name__}` for the value."
82
+ )
83
+
84
+
85
+ @dataclass
86
+ class RecordSet:
87
+ """RecordSet stores groups of parameters, metrics and configs."""
88
+
89
+ def __init__(
90
+ self,
91
+ parameters_records: Optional[Dict[str, ParametersRecord]] = None,
92
+ metrics_records: Optional[Dict[str, MetricsRecord]] = None,
93
+ configs_records: Optional[Dict[str, ConfigsRecord]] = None,
94
+ ) -> None:
95
+ data = RecordSetData(
96
+ parameters_records=parameters_records,
97
+ metrics_records=metrics_records,
98
+ configs_records=configs_records,
99
+ )
100
+ setattr(self, "_data", data) # noqa
101
+
102
+ @property
103
+ def parameters_records(self) -> TypedDict[str, ParametersRecord]:
104
+ """Dictionary holding ParametersRecord instances."""
105
+ data = cast(RecordSetData, getattr(self, "_data")) # noqa
106
+ return data.parameters_records
107
+
108
+ @property
109
+ def metrics_records(self) -> TypedDict[str, MetricsRecord]:
110
+ """Dictionary holding MetricsRecord instances."""
111
+ data = cast(RecordSetData, getattr(self, "_data")) # noqa
112
+ return data.metrics_records
113
+
114
+ @property
115
+ def configs_records(self) -> TypedDict[str, ConfigsRecord]:
116
+ """Dictionary holding ConfigsRecord instances."""
117
+ data = cast(RecordSetData, getattr(self, "_data")) # noqa
118
+ return data.configs_records
@@ -0,0 +1,140 @@
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
+ """Driver (abstract base class)."""
16
+
17
+
18
+ from abc import ABC, abstractmethod
19
+ from typing import Iterable, List, Optional
20
+
21
+ from flwr.common import Message, RecordSet
22
+
23
+
24
+ class Driver(ABC):
25
+ """Abstract base Driver class for the Driver API."""
26
+
27
+ @abstractmethod
28
+ def create_message( # pylint: disable=too-many-arguments
29
+ self,
30
+ content: RecordSet,
31
+ message_type: str,
32
+ dst_node_id: int,
33
+ group_id: str,
34
+ ttl: Optional[float] = None,
35
+ ) -> Message:
36
+ """Create a new message with specified parameters.
37
+
38
+ This method constructs a new `Message` with given content and metadata.
39
+ The `run_id` and `src_node_id` will be set automatically.
40
+
41
+ Parameters
42
+ ----------
43
+ content : RecordSet
44
+ The content for the new message. This holds records that are to be sent
45
+ to the destination node.
46
+ message_type : str
47
+ The type of the message, defining the action to be executed on
48
+ the receiving end.
49
+ dst_node_id : int
50
+ The ID of the destination node to which the message is being sent.
51
+ group_id : str
52
+ The ID of the group to which this message is associated. In some settings,
53
+ this is used as the FL round.
54
+ ttl : Optional[float] (default: None)
55
+ Time-to-live for the round trip of this message, i.e., the time from sending
56
+ this message to receiving a reply. It specifies in seconds the duration for
57
+ which the message and its potential reply are considered valid. If unset,
58
+ the default TTL (i.e., `common.DEFAULT_TTL`) will be used.
59
+
60
+ Returns
61
+ -------
62
+ message : Message
63
+ A new `Message` instance with the specified content and metadata.
64
+ """
65
+
66
+ @abstractmethod
67
+ def get_node_ids(self) -> List[int]:
68
+ """Get node IDs."""
69
+
70
+ @abstractmethod
71
+ def push_messages(self, messages: Iterable[Message]) -> Iterable[str]:
72
+ """Push messages to specified node IDs.
73
+
74
+ This method takes an iterable of messages and sends each message
75
+ to the node specified in `dst_node_id`.
76
+
77
+ Parameters
78
+ ----------
79
+ messages : Iterable[Message]
80
+ An iterable of messages to be sent.
81
+
82
+ Returns
83
+ -------
84
+ message_ids : Iterable[str]
85
+ An iterable of IDs for the messages that were sent, which can be used
86
+ to pull replies.
87
+ """
88
+
89
+ @abstractmethod
90
+ def pull_messages(self, message_ids: Iterable[str]) -> Iterable[Message]:
91
+ """Pull messages based on message IDs.
92
+
93
+ This method is used to collect messages from the SuperLink
94
+ that correspond to a set of given message IDs.
95
+
96
+ Parameters
97
+ ----------
98
+ message_ids : Iterable[str]
99
+ An iterable of message IDs for which reply messages are to be retrieved.
100
+
101
+ Returns
102
+ -------
103
+ messages : Iterable[Message]
104
+ An iterable of messages received.
105
+ """
106
+
107
+ @abstractmethod
108
+ def send_and_receive(
109
+ self,
110
+ messages: Iterable[Message],
111
+ *,
112
+ timeout: Optional[float] = None,
113
+ ) -> Iterable[Message]:
114
+ """Push messages to specified node IDs and pull the reply messages.
115
+
116
+ This method sends a list of messages to their destination node IDs and then
117
+ waits for the replies. It continues to pull replies until either all
118
+ replies are received or the specified timeout duration is exceeded.
119
+
120
+ Parameters
121
+ ----------
122
+ messages : Iterable[Message]
123
+ An iterable of messages to be sent.
124
+ timeout : Optional[float] (default: None)
125
+ The timeout duration in seconds. If specified, the method will wait for
126
+ replies for this duration. If `None`, there is no time limit and the method
127
+ will wait until replies for all messages are received.
128
+
129
+ Returns
130
+ -------
131
+ replies : Iterable[Message]
132
+ An iterable of reply messages received from the SuperLink.
133
+
134
+ Notes
135
+ -----
136
+ This method uses `push_messages` to send the messages and `pull_messages`
137
+ to collect the replies. If `timeout` is set, the method may not return
138
+ replies for all sent messages. A message remains valid until its TTL,
139
+ which is not affected by `timeout`.
140
+ """
@@ -64,7 +64,7 @@ class DriverServicer(driver_pb2_grpc.DriverServicer):
64
64
  """Create run ID."""
65
65
  log(INFO, "DriverServicer.CreateRun")
66
66
  state: State = self.state_factory.state()
67
- run_id = state.create_run()
67
+ run_id = state.create_run("None/None", "None")
68
68
  return CreateRunResponse(run_id=run_id)
69
69
 
70
70
  def PushTaskIns(
@@ -36,7 +36,8 @@ class InMemoryState(State):
36
36
  def __init__(self) -> None:
37
37
  # Map node_id to (online_until, ping_interval)
38
38
  self.node_ids: Dict[int, Tuple[float, float]] = {}
39
- self.run_ids: Set[int] = set()
39
+ # Map run_id to (fab_id, fab_version)
40
+ self.run_ids: Dict[int, Tuple[str, str]] = {}
40
41
  self.task_ins_store: Dict[UUID, TaskIns] = {}
41
42
  self.task_res_store: Dict[UUID, TaskRes] = {}
42
43
  self.lock = threading.Lock()
@@ -238,18 +239,26 @@ class InMemoryState(State):
238
239
  if online_until > current_time
239
240
  }
240
241
 
241
- def create_run(self) -> int:
242
- """Create one run."""
242
+ def create_run(self, fab_id: str, fab_version: str) -> int:
243
+ """Create a new run for the specified `fab_id` and `fab_version`."""
243
244
  # Sample a random int64 as run_id
244
245
  with self.lock:
245
246
  run_id: int = int.from_bytes(os.urandom(8), "little", signed=True)
246
247
 
247
248
  if run_id not in self.run_ids:
248
- self.run_ids.add(run_id)
249
+ self.run_ids[run_id] = (fab_id, fab_version)
249
250
  return run_id
250
251
  log(ERROR, "Unexpected run creation failure.")
251
252
  return 0
252
253
 
254
+ def get_run(self, run_id: int) -> Tuple[int, str, str]:
255
+ """Retrieve information about the run with the specified `run_id`."""
256
+ with self.lock:
257
+ if run_id not in self.run_ids:
258
+ log(ERROR, "`run_id` is invalid")
259
+ return 0, "", ""
260
+ return run_id, *self.run_ids[run_id]
261
+
253
262
  def acknowledge_ping(self, node_id: int, ping_interval: float) -> bool:
254
263
  """Acknowledge a ping received from a node, serving as a heartbeat."""
255
264
  with self.lock: