flwr-nightly 1.19.0.dev20250602__tar.gz → 1.19.0.dev20250604__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (362) hide show
  1. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/PKG-INFO +1 -1
  2. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/grpc_rere_client/connection.py +52 -24
  3. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/inflatable.py +8 -2
  4. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/inflatable_grpc_utils.py +12 -6
  5. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/record/metricrecord.py +1 -1
  6. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/retry_invoker.py +5 -1
  7. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/message_pb2.py +2 -2
  8. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/message_pb2.pyi +7 -1
  9. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/grid/grpc_grid.py +73 -34
  10. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/ffs/__init__.py +2 -0
  11. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +62 -5
  12. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/serverappio/serverappio_servicer.py +58 -3
  13. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supernode/cli/flower_supernode.py +1 -2
  14. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supernode/cli/flwr_clientapp.py +8 -0
  15. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supernode/runtime/run_clientapp.py +22 -1
  16. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supernode/start_client_internal.py +83 -100
  17. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/pyproject.toml +1 -1
  18. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/README.md +0 -0
  19. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/__init__.py +0 -0
  20. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/app/__init__.py +0 -0
  21. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/app/error.py +0 -0
  22. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/app/metadata.py +0 -0
  23. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/__init__.py +0 -0
  24. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/app.py +0 -0
  25. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/auth_plugin/__init__.py +0 -0
  26. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/auth_plugin/oidc_cli_plugin.py +0 -0
  27. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/build.py +0 -0
  28. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/cli_user_auth_interceptor.py +0 -0
  29. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/config_utils.py +0 -0
  30. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/constant.py +0 -0
  31. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/example.py +0 -0
  32. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/install.py +0 -0
  33. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/log.py +0 -0
  34. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/login/__init__.py +0 -0
  35. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/login/login.py +0 -0
  36. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/ls.py +0 -0
  37. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/__init__.py +0 -0
  38. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/new.py +0 -0
  39. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/__init__.py +0 -0
  40. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/.gitignore.tpl +0 -0
  41. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/LICENSE.tpl +0 -0
  42. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/README.baseline.md.tpl +0 -0
  43. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/README.flowertune.md.tpl +0 -0
  44. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/README.md.tpl +0 -0
  45. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/__init__.py +0 -0
  46. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/__init__.baseline.py.tpl +0 -0
  47. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
  48. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
  49. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/client.baseline.py.tpl +0 -0
  50. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/client.huggingface.py.tpl +0 -0
  51. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/client.jax.py.tpl +0 -0
  52. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/client.mlx.py.tpl +0 -0
  53. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
  54. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -0
  55. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/client.sklearn.py.tpl +0 -0
  56. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -0
  57. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/dataset.baseline.py.tpl +0 -0
  58. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py +0 -0
  59. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +0 -0
  60. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +0 -0
  61. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +0 -0
  62. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +0 -0
  63. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +0 -0
  64. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/model.baseline.py.tpl +0 -0
  65. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/server.baseline.py.tpl +0 -0
  66. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/server.huggingface.py.tpl +0 -0
  67. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/server.jax.py.tpl +0 -0
  68. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/server.mlx.py.tpl +0 -0
  69. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
  70. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -0
  71. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/server.sklearn.py.tpl +0 -0
  72. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -0
  73. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/strategy.baseline.py.tpl +0 -0
  74. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/task.huggingface.py.tpl +0 -0
  75. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/task.jax.py.tpl +0 -0
  76. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/task.mlx.py.tpl +0 -0
  77. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/task.numpy.py.tpl +0 -0
  78. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
  79. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/task.sklearn.py.tpl +0 -0
  80. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +0 -0
  81. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/code/utils.baseline.py.tpl +0 -0
  82. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +0 -0
  83. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +0 -0
  84. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +0 -0
  85. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl +0 -0
  86. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +0 -0
  87. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +0 -0
  88. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +0 -0
  89. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +0 -0
  90. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +0 -0
  91. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/run/__init__.py +0 -0
  92. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/run/run.py +0 -0
  93. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/stop.py +0 -0
  94. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/cli/utils.py +0 -0
  95. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/__init__.py +0 -0
  96. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/client.py +0 -0
  97. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/client_app.py +0 -0
  98. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/clientapp/__init__.py +0 -0
  99. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/clientapp/utils.py +0 -0
  100. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/dpfedavg_numpy_client.py +0 -0
  101. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/grpc_adapter_client/__init__.py +0 -0
  102. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/grpc_adapter_client/connection.py +0 -0
  103. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/grpc_rere_client/__init__.py +0 -0
  104. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/grpc_rere_client/client_interceptor.py +0 -0
  105. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/grpc_rere_client/grpc_adapter.py +0 -0
  106. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/message_handler/__init__.py +0 -0
  107. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/message_handler/message_handler.py +0 -0
  108. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/mod/__init__.py +0 -0
  109. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/mod/centraldp_mods.py +0 -0
  110. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/mod/comms_mods.py +0 -0
  111. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/mod/localdp_mod.py +0 -0
  112. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
  113. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
  114. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
  115. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/mod/utils.py +0 -0
  116. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/numpy_client.py +0 -0
  117. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/rest_client/__init__.py +0 -0
  118. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/rest_client/connection.py +0 -0
  119. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/run_info_store.py +0 -0
  120. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/client/typing.py +0 -0
  121. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/clientapp/__init__.py +0 -0
  122. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/__init__.py +0 -0
  123. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/address.py +0 -0
  124. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/args.py +0 -0
  125. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/auth_plugin/__init__.py +0 -0
  126. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/auth_plugin/auth_plugin.py +0 -0
  127. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/config.py +0 -0
  128. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/constant.py +0 -0
  129. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/context.py +0 -0
  130. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/date.py +0 -0
  131. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/differential_privacy.py +0 -0
  132. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/differential_privacy_constants.py +0 -0
  133. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/dp.py +0 -0
  134. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/event_log_plugin/__init__.py +0 -0
  135. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/event_log_plugin/event_log_plugin.py +0 -0
  136. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/exit/__init__.py +0 -0
  137. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/exit/exit.py +0 -0
  138. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/exit/exit_code.py +0 -0
  139. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/exit_handlers.py +0 -0
  140. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/grpc.py +0 -0
  141. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/heartbeat.py +0 -0
  142. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/logger.py +0 -0
  143. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/message.py +0 -0
  144. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/object_ref.py +0 -0
  145. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/parameter.py +0 -0
  146. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/pyproject.py +0 -0
  147. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/record/__init__.py +0 -0
  148. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/record/array.py +0 -0
  149. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/record/arrayrecord.py +0 -0
  150. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/record/configrecord.py +0 -0
  151. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/record/conversion_utils.py +0 -0
  152. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/record/recorddict.py +0 -0
  153. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/record/typeddict.py +0 -0
  154. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/recorddict_compat.py +0 -0
  155. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/secure_aggregation/__init__.py +0 -0
  156. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
  157. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
  158. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
  159. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
  160. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/secure_aggregation/quantization.py +0 -0
  161. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
  162. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
  163. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/serde.py +0 -0
  164. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/serde_utils.py +0 -0
  165. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/telemetry.py +0 -0
  166. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/typing.py +0 -0
  167. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/common/version.py +0 -0
  168. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/compat/__init__.py +0 -0
  169. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/compat/client/__init__.py +0 -0
  170. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/compat/client/app.py +0 -0
  171. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/compat/client/grpc_client/__init__.py +0 -0
  172. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/compat/client/grpc_client/connection.py +0 -0
  173. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/compat/common/__init__.py +0 -0
  174. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/compat/server/__init__.py +0 -0
  175. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/compat/server/app.py +0 -0
  176. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/compat/simulation/__init__.py +0 -0
  177. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/__init__.py +0 -0
  178. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/clientappio_pb2.py +0 -0
  179. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/clientappio_pb2.pyi +0 -0
  180. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/clientappio_pb2_grpc.py +0 -0
  181. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/clientappio_pb2_grpc.pyi +0 -0
  182. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/error_pb2.py +0 -0
  183. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/error_pb2.pyi +0 -0
  184. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/error_pb2_grpc.py +0 -0
  185. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/error_pb2_grpc.pyi +0 -0
  186. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/exec_pb2.py +0 -0
  187. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/exec_pb2.pyi +0 -0
  188. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/exec_pb2_grpc.py +0 -0
  189. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/exec_pb2_grpc.pyi +0 -0
  190. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/fab_pb2.py +0 -0
  191. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/fab_pb2.pyi +0 -0
  192. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/fab_pb2_grpc.py +0 -0
  193. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/fab_pb2_grpc.pyi +0 -0
  194. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/fleet_pb2.py +0 -0
  195. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/fleet_pb2.pyi +0 -0
  196. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/fleet_pb2_grpc.py +0 -0
  197. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
  198. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/grpcadapter_pb2.py +0 -0
  199. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/grpcadapter_pb2.pyi +0 -0
  200. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/grpcadapter_pb2_grpc.py +0 -0
  201. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/grpcadapter_pb2_grpc.pyi +0 -0
  202. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/heartbeat_pb2.py +0 -0
  203. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/heartbeat_pb2.pyi +0 -0
  204. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/heartbeat_pb2_grpc.py +0 -0
  205. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/heartbeat_pb2_grpc.pyi +0 -0
  206. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/log_pb2.py +0 -0
  207. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/log_pb2.pyi +0 -0
  208. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/log_pb2_grpc.py +0 -0
  209. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/log_pb2_grpc.pyi +0 -0
  210. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/message_pb2_grpc.py +0 -0
  211. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/message_pb2_grpc.pyi +0 -0
  212. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/node_pb2.py +0 -0
  213. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/node_pb2.pyi +0 -0
  214. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/node_pb2_grpc.py +0 -0
  215. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/node_pb2_grpc.pyi +0 -0
  216. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/recorddict_pb2.py +0 -0
  217. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/recorddict_pb2.pyi +0 -0
  218. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/recorddict_pb2_grpc.py +0 -0
  219. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/recorddict_pb2_grpc.pyi +0 -0
  220. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/run_pb2.py +0 -0
  221. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/run_pb2.pyi +0 -0
  222. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/run_pb2_grpc.py +0 -0
  223. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/run_pb2_grpc.pyi +0 -0
  224. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/serverappio_pb2.py +0 -0
  225. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/serverappio_pb2.pyi +0 -0
  226. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/serverappio_pb2_grpc.py +0 -0
  227. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/serverappio_pb2_grpc.pyi +0 -0
  228. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/simulationio_pb2.py +0 -0
  229. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/simulationio_pb2.pyi +0 -0
  230. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/simulationio_pb2_grpc.py +0 -0
  231. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/simulationio_pb2_grpc.pyi +0 -0
  232. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/transport_pb2.py +0 -0
  233. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/transport_pb2.pyi +0 -0
  234. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/transport_pb2_grpc.py +0 -0
  235. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
  236. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/py.typed +0 -0
  237. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/__init__.py +0 -0
  238. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/app.py +0 -0
  239. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/client_manager.py +0 -0
  240. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/client_proxy.py +0 -0
  241. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/compat/__init__.py +0 -0
  242. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/compat/app.py +0 -0
  243. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/compat/app_utils.py +0 -0
  244. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/compat/grid_client_proxy.py +0 -0
  245. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/compat/legacy_context.py +0 -0
  246. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/criterion.py +0 -0
  247. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/fleet_event_log_interceptor.py +0 -0
  248. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/grid/__init__.py +0 -0
  249. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/grid/grid.py +0 -0
  250. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/grid/inmemory_grid.py +0 -0
  251. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/history.py +0 -0
  252. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/run_serverapp.py +0 -0
  253. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/server.py +0 -0
  254. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/server_app.py +0 -0
  255. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/server_config.py +0 -0
  256. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/serverapp/__init__.py +0 -0
  257. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/serverapp/app.py +0 -0
  258. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/serverapp_components.py +0 -0
  259. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/__init__.py +0 -0
  260. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/aggregate.py +0 -0
  261. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/bulyan.py +0 -0
  262. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
  263. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
  264. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
  265. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
  266. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
  267. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/fedadagrad.py +0 -0
  268. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/fedadam.py +0 -0
  269. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/fedavg.py +0 -0
  270. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/fedavg_android.py +0 -0
  271. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/fedavgm.py +0 -0
  272. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/fedmedian.py +0 -0
  273. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/fedopt.py +0 -0
  274. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/fedprox.py +0 -0
  275. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
  276. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
  277. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
  278. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
  279. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/fedyogi.py +0 -0
  280. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/krum.py +0 -0
  281. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/qfedavg.py +0 -0
  282. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/strategy/strategy.py +0 -0
  283. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/__init__.py +0 -0
  284. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/ffs/disk_ffs.py +0 -0
  285. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/ffs/ffs.py +0 -0
  286. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/ffs/ffs_factory.py +0 -0
  287. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/__init__.py +0 -0
  288. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py +0 -0
  289. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +0 -0
  290. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
  291. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
  292. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
  293. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
  294. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
  295. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
  296. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +0 -0
  297. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
  298. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/message_handler/message_handler.py +0 -0
  299. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
  300. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +0 -0
  301. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
  302. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
  303. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
  304. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +0 -0
  305. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/fleet/vce/vce_api.py +0 -0
  306. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/linkstate/__init__.py +0 -0
  307. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/linkstate/in_memory_linkstate.py +0 -0
  308. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/linkstate/linkstate.py +0 -0
  309. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/linkstate/linkstate_factory.py +0 -0
  310. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/linkstate/sqlite_linkstate.py +0 -0
  311. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/linkstate/utils.py +0 -0
  312. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/serverappio/__init__.py +0 -0
  313. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/serverappio/serverappio_grpc.py +0 -0
  314. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/simulation/__init__.py +0 -0
  315. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/simulation/simulationio_grpc.py +0 -0
  316. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/simulation/simulationio_servicer.py +0 -0
  317. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/superlink/utils.py +0 -0
  318. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/typing.py +0 -0
  319. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/utils/__init__.py +0 -0
  320. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/utils/tensorboard.py +0 -0
  321. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/utils/validator.py +0 -0
  322. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/workflow/__init__.py +0 -0
  323. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/workflow/constant.py +0 -0
  324. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/workflow/default_workflows.py +0 -0
  325. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
  326. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
  327. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
  328. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/serverapp/__init__.py +0 -0
  329. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/simulation/__init__.py +0 -0
  330. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/simulation/app.py +0 -0
  331. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/simulation/legacy_app.py +0 -0
  332. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/simulation/ray_transport/__init__.py +0 -0
  333. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
  334. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
  335. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/simulation/ray_transport/utils.py +0 -0
  336. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/simulation/run_simulation.py +0 -0
  337. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/simulation/simulationio_connection.py +0 -0
  338. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supercore/__init__.py +0 -0
  339. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supercore/object_store/__init__.py +0 -0
  340. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supercore/object_store/in_memory_object_store.py +0 -0
  341. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supercore/object_store/object_store.py +0 -0
  342. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supercore/object_store/object_store_factory.py +0 -0
  343. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/superexec/__init__.py +0 -0
  344. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/superexec/app.py +0 -0
  345. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/superexec/deployment.py +0 -0
  346. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/superexec/exec_event_log_interceptor.py +0 -0
  347. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/superexec/exec_grpc.py +0 -0
  348. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/superexec/exec_servicer.py +0 -0
  349. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/superexec/exec_user_auth_interceptor.py +0 -0
  350. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/superexec/executor.py +0 -0
  351. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/superexec/simulation.py +0 -0
  352. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/superlink/__init__.py +0 -0
  353. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supernode/__init__.py +0 -0
  354. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supernode/cli/__init__.py +0 -0
  355. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supernode/nodestate/__init__.py +0 -0
  356. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supernode/nodestate/in_memory_nodestate.py +0 -0
  357. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supernode/nodestate/nodestate.py +0 -0
  358. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supernode/nodestate/nodestate_factory.py +0 -0
  359. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supernode/runtime/__init__.py +0 -0
  360. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supernode/servicer/__init__.py +0 -0
  361. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supernode/servicer/clientappio/__init__.py +0 -0
  362. {flwr_nightly-1.19.0.dev20250602 → flwr_nightly-1.19.0.dev20250604}/py/flwr/supernode/servicer/clientappio/clientappio_servicer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: flwr-nightly
3
- Version: 1.19.0.dev20250602
3
+ Version: 1.19.0.dev20250604
4
4
  Summary: Flower: A Friendly Federated AI Framework
5
5
  License: Apache-2.0
6
6
  Keywords: Artificial Intelligence,Federated AI,Federated Analytics,Federated Evaluation,Federated Learning,Flower,Machine Learning
@@ -14,11 +14,10 @@
14
14
  # ==============================================================================
15
15
  """Contextmanager for a gRPC request-response channel to the Flower server."""
16
16
 
17
-
18
17
  from collections.abc import Iterator, Sequence
19
18
  from contextlib import contextmanager
20
19
  from copy import copy
21
- from logging import ERROR
20
+ from logging import DEBUG, ERROR
22
21
  from pathlib import Path
23
22
  from typing import Callable, Optional, Union, cast
24
23
 
@@ -31,13 +30,17 @@ from flwr.common import GRPC_MAX_MESSAGE_LENGTH
31
30
  from flwr.common.constant import HEARTBEAT_CALL_TIMEOUT, HEARTBEAT_DEFAULT_INTERVAL
32
31
  from flwr.common.grpc import create_channel, on_channel_state_change
33
32
  from flwr.common.heartbeat import HeartbeatSender
33
+ from flwr.common.inflatable_grpc_utils import (
34
+ pull_object_from_servicer,
35
+ push_object_to_servicer,
36
+ )
34
37
  from flwr.common.logger import log
35
- from flwr.common.message import Message
36
- from flwr.common.retry_invoker import RetryInvoker
38
+ from flwr.common.message import Message, get_message_to_descendant_id_mapping
39
+ from flwr.common.retry_invoker import RetryInvoker, _wrap_stub
37
40
  from flwr.common.secure_aggregation.crypto.symmetric_encryption import (
38
41
  generate_key_pairs,
39
42
  )
40
- from flwr.common.serde import message_from_proto, message_to_proto, run_from_proto
43
+ from flwr.common.serde import message_to_proto, run_from_proto
41
44
  from flwr.common.typing import Fab, Run, RunNotRunningException
42
45
  from flwr.proto.fab_pb2 import GetFabRequest, GetFabResponse # pylint: disable=E0611
43
46
  from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
@@ -46,6 +49,7 @@ from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
46
49
  PullMessagesRequest,
47
50
  PullMessagesResponse,
48
51
  PushMessagesRequest,
52
+ PushMessagesResponse,
49
53
  )
50
54
  from flwr.proto.fleet_pb2_grpc import FleetStub # pylint: disable=E0611
51
55
  from flwr.proto.heartbeat_pb2 import ( # pylint: disable=E0611
@@ -159,6 +163,8 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
159
163
  # If the status code is PERMISSION_DENIED, additionally raise RunNotRunningException
160
164
  retry_invoker.should_giveup = _should_giveup_fn
161
165
 
166
+ # Wrap stub
167
+ _wrap_stub(stub, retry_invoker)
162
168
  ###########################################################################
163
169
  # send_node_heartbeat/create_node/delete_node/receive/send/get_run functions
164
170
  ###########################################################################
@@ -203,10 +209,7 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
203
209
  create_node_request = CreateNodeRequest(
204
210
  heartbeat_interval=HEARTBEAT_DEFAULT_INTERVAL
205
211
  )
206
- create_node_response = retry_invoker.invoke(
207
- stub.CreateNode,
208
- request=create_node_request,
209
- )
212
+ create_node_response = stub.CreateNode(request=create_node_request)
210
213
 
211
214
  # Remember the node and start the heartbeat sender
212
215
  nonlocal node
@@ -227,7 +230,7 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
227
230
 
228
231
  # Call FleetAPI
229
232
  delete_node_request = DeleteNodeRequest(node=node)
230
- retry_invoker.invoke(stub.DeleteNode, request=delete_node_request)
233
+ stub.DeleteNode(request=delete_node_request)
231
234
 
232
235
  # Cleanup
233
236
  node = None
@@ -241,9 +244,7 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
241
244
 
242
245
  # Request instructions (message) from server
243
246
  request = PullMessagesRequest(node=node)
244
- response: PullMessagesResponse = retry_invoker.invoke(
245
- stub.PullMessages, request=request
246
- )
247
+ response: PullMessagesResponse = stub.PullMessages(request=request)
247
248
 
248
249
  # Get the current Messages
249
250
  message_proto = (
@@ -257,7 +258,24 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
257
258
  message_proto = None
258
259
 
259
260
  # Construct the Message
260
- in_message = message_from_proto(message_proto) if message_proto else None
261
+ in_message: Optional[Message] = None
262
+
263
+ if message_proto:
264
+ in_message = cast(
265
+ Message,
266
+ pull_object_from_servicer(
267
+ object_id=message_proto.metadata.message_id,
268
+ stub=stub,
269
+ node=node,
270
+ run_id=message_proto.metadata.run_id,
271
+ ),
272
+ )
273
+
274
+ if in_message:
275
+ # The deflated message doesn't contain the message_id (its own object_id)
276
+ # Inject
277
+ # pylint: disable-next=W0212
278
+ in_message.metadata._message_id = message_proto.metadata.message_id # type: ignore
261
279
 
262
280
  # Remember `metadata` of the in message
263
281
  nonlocal metadata
@@ -288,8 +306,24 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
288
306
 
289
307
  # Serialize Message
290
308
  message_proto = message_to_proto(message=message)
291
- request = PushMessagesRequest(node=node, messages_list=[message_proto])
292
- _ = retry_invoker.invoke(stub.PushMessages, request)
309
+ descendants_mapping = get_message_to_descendant_id_mapping(message)
310
+ request = PushMessagesRequest(
311
+ node=node,
312
+ messages_list=[message_proto],
313
+ msg_to_descendant_mapping=descendants_mapping,
314
+ )
315
+ response: PushMessagesResponse = stub.PushMessages(request=request)
316
+
317
+ if response.objects_to_push:
318
+ objs_to_push = set(response.objects_to_push[message.object_id].object_ids)
319
+ push_object_to_servicer(
320
+ message,
321
+ stub,
322
+ node,
323
+ run_id=message.metadata.run_id,
324
+ object_ids_to_push=objs_to_push,
325
+ )
326
+ log(DEBUG, "Pushed %s objects to servicer.", len(objs_to_push))
293
327
 
294
328
  # Cleanup
295
329
  metadata = None
@@ -297,10 +331,7 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
297
331
  def get_run(run_id: int) -> Run:
298
332
  # Call FleetAPI
299
333
  get_run_request = GetRunRequest(node=node, run_id=run_id)
300
- get_run_response: GetRunResponse = retry_invoker.invoke(
301
- stub.GetRun,
302
- request=get_run_request,
303
- )
334
+ get_run_response: GetRunResponse = stub.GetRun(request=get_run_request)
304
335
 
305
336
  # Return fab_id and fab_version
306
337
  return run_from_proto(get_run_response.run)
@@ -308,10 +339,7 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
308
339
  def get_fab(fab_hash: str, run_id: int) -> Fab:
309
340
  # Call FleetAPI
310
341
  get_fab_request = GetFabRequest(node=node, hash_str=fab_hash, run_id=run_id)
311
- get_fab_response: GetFabResponse = retry_invoker.invoke(
312
- stub.GetFab,
313
- request=get_fab_request,
314
- )
342
+ get_fab_response: GetFabResponse = stub.GetFab(request=get_fab_request)
315
343
 
316
344
  return Fab(get_fab_response.fab.hash_str, get_fab_response.fab.content)
317
345
 
@@ -18,9 +18,11 @@
18
18
  from __future__ import annotations
19
19
 
20
20
  import hashlib
21
+ from logging import ERROR
21
22
  from typing import TypeVar, cast
22
23
 
23
24
  from .constant import HEAD_BODY_DIVIDER, HEAD_VALUE_DIVIDER
25
+ from .logger import log
24
26
 
25
27
 
26
28
  class InflatableObject:
@@ -163,8 +165,12 @@ def get_object_body_len_from_object_content(object_content: bytes) -> int:
163
165
 
164
166
  def check_body_len_consistency(object_content: bytes) -> bool:
165
167
  """Check that the object body is of length as specified in the head."""
166
- body_len = get_object_body_len_from_object_content(object_content)
167
- return body_len == len(_get_object_body(object_content))
168
+ try:
169
+ body_len = get_object_body_len_from_object_content(object_content)
170
+ return body_len == len(_get_object_body(object_content))
171
+ except ValueError:
172
+ log(ERROR, "Object content does match the expected format.")
173
+ return False
168
174
 
169
175
 
170
176
  def get_object_head_values_from_object_content(
@@ -15,8 +15,10 @@
15
15
  """InflatableObject utils."""
16
16
 
17
17
 
18
+ from time import sleep
18
19
  from typing import Optional, Union
19
20
 
21
+ from flwr.client.grpc_rere_client.grpc_adapter import GrpcAdapter
20
22
  from flwr.proto.fleet_pb2_grpc import FleetStub # pylint: disable=E0611
21
23
  from flwr.proto.message_pb2 import ( # pylint: disable=E0611
22
24
  PullObjectRequest,
@@ -48,7 +50,7 @@ inflatable_class_registry: dict[str, type[InflatableObject]] = {
48
50
 
49
51
  def push_object_to_servicer(
50
52
  obj: InflatableObject,
51
- stub: Union[FleetStub, ServerAppIoStub],
53
+ stub: Union[FleetStub, ServerAppIoStub, GrpcAdapter],
52
54
  node: Node,
53
55
  run_id: int,
54
56
  object_ids_to_push: Optional[set[str]] = None,
@@ -87,16 +89,20 @@ def push_object_to_servicer(
87
89
 
88
90
  def pull_object_from_servicer(
89
91
  object_id: str,
90
- stub: Union[FleetStub, ServerAppIoStub],
92
+ stub: Union[FleetStub, ServerAppIoStub, GrpcAdapter],
91
93
  node: Node,
92
94
  run_id: int,
93
95
  ) -> InflatableObject:
94
96
  """Recursively inflate an object by pulling it from the servicer."""
95
97
  # Pull object
96
- object_proto: PullObjectResponse = stub.PullObject(
97
- PullObjectRequest(node=node, run_id=run_id, object_id=object_id)
98
- )
99
- object_content = object_proto.object_content
98
+ object_available = False
99
+ while not object_available:
100
+ object_proto: PullObjectResponse = stub.PullObject(
101
+ PullObjectRequest(node=node, run_id=run_id, object_id=object_id)
102
+ )
103
+ object_available = object_proto.object_available
104
+ object_content = object_proto.object_content
105
+ sleep(0.1)
100
106
 
101
107
  # Extract object class and object_ids of children
102
108
  obj_type, children_obj_ids, _ = get_object_head_values_from_object_content(
@@ -180,7 +180,7 @@ class MetricRecord(TypedDict[str, MetricRecordValues], InflatableObject):
180
180
  MetricRecord
181
181
  The inflated MetricRecord.
182
182
  """
183
- if children is not None:
183
+ if children:
184
184
  raise ValueError("`MetricRecord` objects do not have children.")
185
185
 
186
186
  obj_body = get_object_body(object_content, cls)
@@ -25,10 +25,12 @@ from typing import Any, Callable, Optional, Union, cast
25
25
 
26
26
  import grpc
27
27
 
28
+ from flwr.client.grpc_rere_client.grpc_adapter import GrpcAdapter
28
29
  from flwr.common.constant import MAX_RETRY_DELAY
29
30
  from flwr.common.logger import log
30
31
  from flwr.common.typing import RunNotRunningException
31
32
  from flwr.proto.clientappio_pb2_grpc import ClientAppIoStub
33
+ from flwr.proto.fleet_pb2_grpc import FleetStub
32
34
  from flwr.proto.serverappio_pb2_grpc import ServerAppIoStub
33
35
  from flwr.proto.simulationio_pb2_grpc import SimulationIoStub
34
36
 
@@ -366,7 +368,9 @@ def _make_simple_grpc_retry_invoker() -> RetryInvoker:
366
368
 
367
369
 
368
370
  def _wrap_stub(
369
- stub: Union[ServerAppIoStub, ClientAppIoStub, SimulationIoStub],
371
+ stub: Union[
372
+ ServerAppIoStub, ClientAppIoStub, SimulationIoStub, FleetStub, GrpcAdapter
373
+ ],
370
374
  retry_invoker: RetryInvoker,
371
375
  ) -> None:
372
376
  """Wrap a gRPC stub with a retry invoker."""
@@ -18,7 +18,7 @@ from flwr.proto import transport_pb2 as flwr_dot_proto_dot_transport__pb2
18
18
  from flwr.proto import node_pb2 as flwr_dot_proto_dot_node__pb2
19
19
 
20
20
 
21
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18\x66lwr/proto/message.proto\x12\nflwr.proto\x1a\x16\x66lwr/proto/error.proto\x1a\x1b\x66lwr/proto/recorddict.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x15\x66lwr/proto/node.proto\"|\n\x07Message\x12&\n\x08metadata\x18\x01 \x01(\x0b\x32\x14.flwr.proto.Metadata\x12\'\n\x07\x63ontent\x18\x02 \x01(\x0b\x32\x16.flwr.proto.RecordDict\x12 \n\x05\x65rror\x18\x03 \x01(\x0b\x32\x11.flwr.proto.Error\"\xd0\x02\n\x07\x43ontext\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x0f\n\x07node_id\x18\x02 \x01(\x04\x12\x38\n\x0bnode_config\x18\x03 \x03(\x0b\x32#.flwr.proto.Context.NodeConfigEntry\x12%\n\x05state\x18\x04 \x01(\x0b\x32\x16.flwr.proto.RecordDict\x12\x36\n\nrun_config\x18\x05 \x03(\x0b\x32\".flwr.proto.Context.RunConfigEntry\x1a\x45\n\x0fNodeConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\x1a\x44\n\x0eRunConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"\xbe\x01\n\x08Metadata\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x12\n\nmessage_id\x18\x02 \x01(\t\x12\x13\n\x0bsrc_node_id\x18\x03 \x01(\x04\x12\x13\n\x0b\x64st_node_id\x18\x04 \x01(\x04\x12\x1b\n\x13reply_to_message_id\x18\x05 \x01(\t\x12\x10\n\x08group_id\x18\x06 \x01(\t\x12\x0b\n\x03ttl\x18\x07 \x01(\x01\x12\x14\n\x0cmessage_type\x18\x08 \x01(\t\x12\x12\n\ncreated_at\x18\t \x01(\x01\"\x1f\n\tObjectIDs\x12\x12\n\nobject_ids\x18\x01 \x03(\t\"n\n\x11PushObjectRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0e\n\x06run_id\x18\x02 \x01(\x04\x12\x11\n\tobject_id\x18\x03 \x01(\t\x12\x16\n\x0eobject_content\x18\x04 \x01(\x0c\"$\n\x12PushObjectResponse\x12\x0e\n\x06stored\x18\x01 \x01(\x08\"V\n\x11PullObjectRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0e\n\x06run_id\x18\x02 \x01(\x04\x12\x11\n\tobject_id\x18\x03 \x01(\t\",\n\x12PullObjectResponse\x12\x16\n\x0eobject_content\x18\x01 \x01(\x0c\x62\x06proto3')
21
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18\x66lwr/proto/message.proto\x12\nflwr.proto\x1a\x16\x66lwr/proto/error.proto\x1a\x1b\x66lwr/proto/recorddict.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x15\x66lwr/proto/node.proto\"|\n\x07Message\x12&\n\x08metadata\x18\x01 \x01(\x0b\x32\x14.flwr.proto.Metadata\x12\'\n\x07\x63ontent\x18\x02 \x01(\x0b\x32\x16.flwr.proto.RecordDict\x12 \n\x05\x65rror\x18\x03 \x01(\x0b\x32\x11.flwr.proto.Error\"\xd0\x02\n\x07\x43ontext\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x0f\n\x07node_id\x18\x02 \x01(\x04\x12\x38\n\x0bnode_config\x18\x03 \x03(\x0b\x32#.flwr.proto.Context.NodeConfigEntry\x12%\n\x05state\x18\x04 \x01(\x0b\x32\x16.flwr.proto.RecordDict\x12\x36\n\nrun_config\x18\x05 \x03(\x0b\x32\".flwr.proto.Context.RunConfigEntry\x1a\x45\n\x0fNodeConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\x1a\x44\n\x0eRunConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"\xbe\x01\n\x08Metadata\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x12\n\nmessage_id\x18\x02 \x01(\t\x12\x13\n\x0bsrc_node_id\x18\x03 \x01(\x04\x12\x13\n\x0b\x64st_node_id\x18\x04 \x01(\x04\x12\x1b\n\x13reply_to_message_id\x18\x05 \x01(\t\x12\x10\n\x08group_id\x18\x06 \x01(\t\x12\x0b\n\x03ttl\x18\x07 \x01(\x01\x12\x14\n\x0cmessage_type\x18\x08 \x01(\t\x12\x12\n\ncreated_at\x18\t \x01(\x01\"\x1f\n\tObjectIDs\x12\x12\n\nobject_ids\x18\x01 \x03(\t\"n\n\x11PushObjectRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0e\n\x06run_id\x18\x02 \x01(\x04\x12\x11\n\tobject_id\x18\x03 \x01(\t\x12\x16\n\x0eobject_content\x18\x04 \x01(\x0c\"$\n\x12PushObjectResponse\x12\x0e\n\x06stored\x18\x01 \x01(\x08\"V\n\x11PullObjectRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0e\n\x06run_id\x18\x02 \x01(\x04\x12\x11\n\tobject_id\x18\x03 \x01(\t\"\\\n\x12PullObjectResponse\x12\x14\n\x0cobject_found\x18\x01 \x01(\x08\x12\x18\n\x10object_available\x18\x02 \x01(\x08\x12\x16\n\x0eobject_content\x18\x03 \x01(\x0c\x62\x06proto3')
22
22
 
23
23
  _globals = globals()
24
24
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -48,5 +48,5 @@ if _descriptor._USE_C_DESCRIPTORS == False:
48
48
  _globals['_PULLOBJECTREQUEST']._serialized_start=985
49
49
  _globals['_PULLOBJECTREQUEST']._serialized_end=1071
50
50
  _globals['_PULLOBJECTRESPONSE']._serialized_start=1073
51
- _globals['_PULLOBJECTRESPONSE']._serialized_end=1117
51
+ _globals['_PULLOBJECTRESPONSE']._serialized_end=1165
52
52
  # @@protoc_insertion_point(module_scope)
@@ -196,11 +196,17 @@ global___PullObjectRequest = PullObjectRequest
196
196
 
197
197
  class PullObjectResponse(google.protobuf.message.Message):
198
198
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
199
+ OBJECT_FOUND_FIELD_NUMBER: builtins.int
200
+ OBJECT_AVAILABLE_FIELD_NUMBER: builtins.int
199
201
  OBJECT_CONTENT_FIELD_NUMBER: builtins.int
202
+ object_found: builtins.bool
203
+ object_available: builtins.bool
200
204
  object_content: builtins.bytes
201
205
  def __init__(self,
202
206
  *,
207
+ object_found: builtins.bool = ...,
208
+ object_available: builtins.bool = ...,
203
209
  object_content: builtins.bytes = ...,
204
210
  ) -> None: ...
205
- def ClearField(self, field_name: typing_extensions.Literal["object_content",b"object_content"]) -> None: ...
211
+ def ClearField(self, field_name: typing_extensions.Literal["object_available",b"object_available","object_content",b"object_content","object_found",b"object_found"]) -> None: ...
206
212
  global___PullObjectResponse = PullObjectResponse
@@ -28,11 +28,15 @@ from flwr.common.constant import (
28
28
  SUPERLINK_NODE_ID,
29
29
  )
30
30
  from flwr.common.grpc import create_channel, on_channel_state_change
31
+ from flwr.common.inflatable_grpc_utils import (
32
+ pull_object_from_servicer,
33
+ push_object_to_servicer,
34
+ )
31
35
  from flwr.common.logger import log, warn_deprecated_feature
36
+ from flwr.common.message import get_message_to_descendant_id_mapping
32
37
  from flwr.common.retry_invoker import _make_simple_grpc_retry_invoker, _wrap_stub
33
- from flwr.common.serde import message_from_proto, message_to_proto, run_from_proto
38
+ from flwr.common.serde import message_to_proto, run_from_proto
34
39
  from flwr.common.typing import Run
35
- from flwr.proto.message_pb2 import Message as ProtoMessage # pylint: disable=E0611
36
40
  from flwr.proto.node_pb2 import Node # pylint: disable=E0611
37
41
  from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611
38
42
  from flwr.proto.serverappio_pb2 import ( # pylint: disable=E0611
@@ -198,6 +202,35 @@ class GrpcGrid(Grid):
198
202
  )
199
203
  return [node.node_id for node in res.nodes]
200
204
 
205
+ def _try_push_message(self, run_id: int, message: Message) -> str:
206
+ """Push one message and its associated objects."""
207
+ # Compute mapping of message descendants
208
+ descendants_mapping = get_message_to_descendant_id_mapping(message)
209
+
210
+ # Call GrpcServerAppIoStub method
211
+ res: PushInsMessagesResponse = self._stub.PushMessages(
212
+ PushInsMessagesRequest(
213
+ messages_list=[message_to_proto(message)],
214
+ run_id=run_id,
215
+ msg_to_descendant_mapping=descendants_mapping,
216
+ )
217
+ )
218
+
219
+ # Push objects
220
+ msg_id = res.message_ids[0]
221
+ # If Message was added to the LinkState correctly
222
+ if msg_id is not None:
223
+ obj_ids_to_push = set(res.objects_to_push[msg_id].object_ids)
224
+ # Push only object that are not in the store
225
+ push_object_to_servicer(
226
+ message,
227
+ self._stub,
228
+ node=self.node,
229
+ run_id=run_id,
230
+ object_ids_to_push=obj_ids_to_push,
231
+ )
232
+ return msg_id
233
+
201
234
  def push_messages(self, messages: Iterable[Message]) -> Iterable[str]:
202
235
  """Push messages to specified node IDs.
203
236
 
@@ -206,58 +239,64 @@ class GrpcGrid(Grid):
206
239
  """
207
240
  # Construct Messages
208
241
  run_id = cast(Run, self._run).run_id
209
- message_proto_list: list[ProtoMessage] = []
210
- for msg in messages:
211
- # Populate metadata
212
- msg.metadata.__dict__["_run_id"] = run_id
213
- msg.metadata.__dict__["_src_node_id"] = self.node.node_id
214
- msg.metadata.__dict__["_message_id"] = msg.object_id
215
- # Check message
216
- self._check_message(msg)
217
- # Convert to proto
218
- msg_proto = message_to_proto(msg)
219
- # Add to list
220
- message_proto_list.append(msg_proto)
221
-
242
+ message_ids: list[str] = []
222
243
  try:
223
- # Call GrpcServerAppIoStub method
224
- res: PushInsMessagesResponse = self._stub.PushMessages(
225
- PushInsMessagesRequest(messages_list=message_proto_list, run_id=run_id)
226
- )
227
- if len([msg_id for msg_id in res.message_ids if msg_id]) != len(
228
- message_proto_list
229
- ):
230
- log(
231
- WARNING,
232
- "Not all messages could be pushed to the SuperLink. The returned "
233
- "list has `None` for those messages (the order is preserved as "
234
- "passed to `push_messages`). This could be due to a malformed "
235
- "message.",
236
- )
237
- return list(res.message_ids)
244
+ for msg in messages:
245
+ # Populate metadata
246
+ msg.metadata.__dict__["_run_id"] = run_id
247
+ msg.metadata.__dict__["_src_node_id"] = self.node.node_id
248
+ msg.metadata.__dict__["_message_id"] = msg.object_id
249
+ # Check message
250
+ self._check_message(msg)
251
+ # Try pushing message and its objects
252
+ message_ids.append(self._try_push_message(run_id, msg))
253
+
238
254
  except grpc.RpcError as e:
239
255
  if e.code() == grpc.StatusCode.RESOURCE_EXHAUSTED: # pylint: disable=E1101
240
256
  log(ERROR, ERROR_MESSAGE_PUSH_MESSAGES_RESOURCE_EXHAUSTED)
241
257
  return []
242
258
  raise
243
259
 
260
+ if None in message_ids:
261
+ log(
262
+ WARNING,
263
+ "Not all messages could be pushed to the SuperLink. The returned "
264
+ "list has `None` for those messages (the order is preserved as "
265
+ "passed to `push_messages`). This could be due to a malformed "
266
+ "message.",
267
+ )
268
+
269
+ return message_ids
270
+
244
271
  def pull_messages(self, message_ids: Iterable[str]) -> Iterable[Message]:
245
272
  """Pull messages based on message IDs.
246
273
 
247
274
  This method is used to collect messages from the SuperLink that correspond to a
248
275
  set of given message IDs.
249
276
  """
277
+ run_id = cast(Run, self._run).run_id
250
278
  try:
251
279
  # Pull Messages
252
280
  res: PullResMessagesResponse = self._stub.PullMessages(
253
281
  PullResMessagesRequest(
254
282
  message_ids=message_ids,
255
- run_id=cast(Run, self._run).run_id,
283
+ run_id=run_id,
256
284
  )
257
285
  )
258
- # Convert Message from Protobuf representation
259
- msgs = [message_from_proto(msg_proto) for msg_proto in res.messages_list]
260
- return msgs
286
+ # Pull Messages from store
287
+ inflated_msgs: list[Message] = []
288
+ for msg_proto in res.messages_list:
289
+
290
+ message = pull_object_from_servicer(
291
+ msg_proto.metadata.message_id,
292
+ self._stub,
293
+ node=self.node,
294
+ run_id=run_id,
295
+ )
296
+ inflated_msgs.append(cast(Message, message))
297
+
298
+ return inflated_msgs
299
+
261
300
  except grpc.RpcError as e:
262
301
  if e.code() == grpc.StatusCode.RESOURCE_EXHAUSTED: # pylint: disable=E1101
263
302
  log(ERROR, ERROR_MESSAGE_PULL_MESSAGES_RESOURCE_EXHAUSTED)
@@ -17,8 +17,10 @@
17
17
 
18
18
  from .disk_ffs import DiskFfs as DiskFfs
19
19
  from .ffs import Ffs as Ffs
20
+ from .ffs_factory import FfsFactory as FfsFactory
20
21
 
21
22
  __all__ = [
22
23
  "DiskFfs",
23
24
  "Ffs",
25
+ "FfsFactory",
24
26
  ]
@@ -15,11 +15,12 @@
15
15
  """Fleet API gRPC request-response servicer."""
16
16
 
17
17
 
18
- from logging import DEBUG, INFO
18
+ from logging import DEBUG, ERROR, INFO
19
19
 
20
20
  import grpc
21
21
  from google.protobuf.json_format import MessageToDict
22
22
 
23
+ from flwr.common.constant import Status
23
24
  from flwr.common.inflatable import check_body_len_consistency
24
25
  from flwr.common.logger import log
25
26
  from flwr.common.typing import InvalidRunStatusException
@@ -49,8 +50,9 @@ from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=
49
50
  from flwr.server.superlink.ffs.ffs_factory import FfsFactory
50
51
  from flwr.server.superlink.fleet.message_handler import message_handler
51
52
  from flwr.server.superlink.linkstate import LinkStateFactory
52
- from flwr.server.superlink.utils import abort_grpc_context
53
+ from flwr.server.superlink.utils import abort_grpc_context, check_abort
53
54
  from flwr.supercore.object_store import ObjectStoreFactory
55
+ from flwr.supercore.object_store.object_store import NoObjectInStoreError
54
56
 
55
57
 
56
58
  class FleetServicer(fleet_pb2_grpc.FleetServicer):
@@ -183,11 +185,39 @@ class FleetServicer(fleet_pb2_grpc.FleetServicer):
183
185
  request.object_id,
184
186
  )
185
187
 
188
+ state = self.state_factory.state()
189
+
190
+ # Abort if the run is not running
191
+ abort_msg = check_abort(
192
+ request.run_id,
193
+ [Status.PENDING, Status.STARTING, Status.FINISHED],
194
+ state,
195
+ )
196
+ if abort_msg:
197
+ abort_grpc_context(abort_msg, context)
198
+
199
+ if request.node.node_id not in state.get_nodes(run_id=request.run_id):
200
+ # Cancel insertion in ObjectStore
201
+ context.abort(grpc.StatusCode.FAILED_PRECONDITION, "Unexpected node ID.")
202
+
186
203
  if not check_body_len_consistency(request.object_content):
187
204
  # Cancel insertion in ObjectStore
188
- context.abort(grpc.StatusCode.PERMISSION_DENIED, "Unexpected object length")
205
+ context.abort(
206
+ grpc.StatusCode.FAILED_PRECONDITION, "Unexpected object length"
207
+ )
208
+
209
+ # Init store
210
+ store = self.objectstore_factory.store()
211
+
212
+ # Insert in store
213
+ stored = False
214
+ try:
215
+ store.put(request.object_id, request.object_content)
216
+ stored = True
217
+ except (NoObjectInStoreError, ValueError) as e:
218
+ log(ERROR, str(e))
189
219
 
190
- return PushObjectResponse()
220
+ return PushObjectResponse(stored=stored)
191
221
 
192
222
  def PullObject(
193
223
  self, request: PullObjectRequest, context: grpc.ServicerContext
@@ -199,4 +229,31 @@ class FleetServicer(fleet_pb2_grpc.FleetServicer):
199
229
  request.object_id,
200
230
  )
201
231
 
202
- return PullObjectResponse()
232
+ state = self.state_factory.state()
233
+
234
+ # Abort if the run is not running
235
+ abort_msg = check_abort(
236
+ request.run_id,
237
+ [Status.PENDING, Status.STARTING, Status.FINISHED],
238
+ state,
239
+ )
240
+ if abort_msg:
241
+ abort_grpc_context(abort_msg, context)
242
+
243
+ if request.node.node_id not in state.get_nodes(run_id=request.run_id):
244
+ # Cancel insertion in ObjectStore
245
+ context.abort(grpc.StatusCode.FAILED_PRECONDITION, "Unexpected node ID.")
246
+
247
+ # Init store
248
+ store = self.objectstore_factory.store()
249
+
250
+ # Fetch from store
251
+ content = store.get(request.object_id)
252
+ if content is not None:
253
+ object_available = content != b""
254
+ return PullObjectResponse(
255
+ object_found=True,
256
+ object_available=object_available,
257
+ object_content=content,
258
+ )
259
+ return PullObjectResponse(object_found=False, object_available=False)
@@ -409,11 +409,39 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
409
409
  """Push an object to the ObjectStore."""
410
410
  log(DEBUG, "ServerAppIoServicer.PushObject")
411
411
 
412
+ # Init state
413
+ state: LinkState = self.state_factory.state()
414
+
415
+ # Abort if the run is not running
416
+ abort_if(
417
+ request.run_id,
418
+ [Status.PENDING, Status.STARTING, Status.FINISHED],
419
+ state,
420
+ context,
421
+ )
422
+
423
+ if request.node.node_id != SUPERLINK_NODE_ID:
424
+ # Cancel insertion in ObjectStore
425
+ context.abort(grpc.StatusCode.FAILED_PRECONDITION, "Unexpected node ID.")
426
+
412
427
  if not check_body_len_consistency(request.object_content):
413
428
  # Cancel insertion in ObjectStore
414
- context.abort(grpc.StatusCode.PERMISSION_DENIED, "Unexpected object length")
429
+ context.abort(
430
+ grpc.StatusCode.FAILED_PRECONDITION, "Unexpected object length."
431
+ )
432
+
433
+ # Init store
434
+ store = self.objectstore_factory.store()
435
+
436
+ # Insert in store
437
+ stored = False
438
+ try:
439
+ store.put(request.object_id, request.object_content)
440
+ stored = True
441
+ except (NoObjectInStoreError, ValueError) as e:
442
+ log(ERROR, str(e))
415
443
 
416
- return PushObjectResponse()
444
+ return PushObjectResponse(stored=stored)
417
445
 
418
446
  def PullObject(
419
447
  self, request: PullObjectRequest, context: grpc.ServicerContext
@@ -421,7 +449,34 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
421
449
  """Pull an object from the ObjectStore."""
422
450
  log(DEBUG, "ServerAppIoServicer.PullObject")
423
451
 
424
- return PullObjectResponse()
452
+ # Init state
453
+ state: LinkState = self.state_factory.state()
454
+
455
+ # Abort if the run is not running
456
+ abort_if(
457
+ request.run_id,
458
+ [Status.PENDING, Status.STARTING, Status.FINISHED],
459
+ state,
460
+ context,
461
+ )
462
+
463
+ if request.node.node_id != SUPERLINK_NODE_ID:
464
+ # Cancel insertion in ObjectStore
465
+ context.abort(grpc.StatusCode.FAILED_PRECONDITION, "Unexpected node ID.")
466
+
467
+ # Init store
468
+ store = self.objectstore_factory.store()
469
+
470
+ # Fetch from store
471
+ content = store.get(request.object_id)
472
+ if content is not None:
473
+ object_available = content != b""
474
+ return PullObjectResponse(
475
+ object_found=True,
476
+ object_available=object_available,
477
+ object_content=content,
478
+ )
479
+ return PullObjectResponse(object_found=False, object_available=False)
425
480
 
426
481
 
427
482
  def _raise_if(validation_error: bool, request_name: str, detail: str) -> None:
@@ -42,8 +42,7 @@ from flwr.common.constant import (
42
42
  from flwr.common.exit import ExitCode, flwr_exit
43
43
  from flwr.common.exit_handlers import register_exit_handlers
44
44
  from flwr.common.logger import log
45
-
46
- from ..start_client_internal import start_client_internal
45
+ from flwr.supernode.start_client_internal import start_client_internal
47
46
 
48
47
 
49
48
  def flower_supernode() -> None: