flwr 1.19.0__tar.gz → 1.21.0__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 (435) hide show
  1. {flwr-1.19.0 → flwr-1.21.0}/PKG-INFO +5 -3
  2. {flwr-1.19.0 → flwr-1.21.0}/README.md +3 -2
  3. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/__init__.py +4 -1
  4. flwr-1.21.0/py/flwr/app/__init__.py +43 -0
  5. flwr-1.21.0/py/flwr/app/exception.py +31 -0
  6. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/auth_plugin/oidc_cli_plugin.py +4 -4
  7. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/build.py +15 -5
  8. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/cli_user_auth_interceptor.py +1 -1
  9. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/config_utils.py +3 -3
  10. flwr-1.21.0/py/flwr/cli/constant.py +44 -0
  11. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/log.py +9 -9
  12. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/login/login.py +3 -3
  13. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/ls.py +5 -5
  14. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/new.py +23 -4
  15. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/README.flowertune.md.tpl +2 -0
  16. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/README.md.tpl +5 -0
  17. flwr-1.21.0/py/flwr/cli/new/templates/app/code/__init__.pytorch_msg_api.py.tpl +1 -0
  18. flwr-1.21.0/py/flwr/cli/new/templates/app/code/client.pytorch_msg_api.py.tpl +80 -0
  19. flwr-1.21.0/py/flwr/cli/new/templates/app/code/server.pytorch_msg_api.py.tpl +41 -0
  20. flwr-1.21.0/py/flwr/cli/new/templates/app/code/task.pytorch_msg_api.py.tpl +98 -0
  21. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +14 -3
  22. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +13 -1
  23. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +21 -2
  24. flwr-1.21.0/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl +52 -0
  25. flwr-1.21.0/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +56 -0
  26. flwr-1.21.0/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +49 -0
  27. flwr-1.21.0/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +53 -0
  28. flwr-1.21.0/py/flwr/cli/new/templates/app/pyproject.pytorch_msg_api.toml.tpl +53 -0
  29. flwr-1.21.0/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +52 -0
  30. flwr-1.21.0/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +53 -0
  31. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/run/run.py +53 -50
  32. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/stop.py +7 -4
  33. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/utils.py +29 -11
  34. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/grpc_adapter_client/connection.py +11 -4
  35. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/grpc_rere_client/connection.py +93 -129
  36. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/rest_client/connection.py +134 -164
  37. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/clientapp/__init__.py +10 -0
  38. flwr-1.21.0/py/flwr/clientapp/mod/__init__.py +26 -0
  39. flwr-1.21.0/py/flwr/clientapp/mod/centraldp_mods.py +132 -0
  40. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/args.py +20 -6
  41. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/auth_plugin/__init__.py +4 -4
  42. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/auth_plugin/auth_plugin.py +7 -7
  43. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/constant.py +26 -5
  44. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/event_log_plugin/event_log_plugin.py +1 -1
  45. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/exit/__init__.py +4 -0
  46. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/exit/exit.py +8 -1
  47. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/exit/exit_code.py +42 -8
  48. flwr-1.21.0/py/flwr/common/exit/exit_handler.py +62 -0
  49. flwr-1.19.0/py/flwr/common/exit_handlers.py → flwr-1.21.0/py/flwr/common/exit/signal_handler.py +20 -37
  50. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/grpc.py +1 -1
  51. flwr-1.19.0/py/flwr/common/inflatable_grpc_utils.py → flwr-1.21.0/py/flwr/common/inflatable_protobuf_utils.py +52 -10
  52. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/inflatable_utils.py +191 -24
  53. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/record/array.py +101 -22
  54. flwr-1.21.0/py/flwr/common/record/arraychunk.py +59 -0
  55. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/retry_invoker.py +30 -11
  56. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/serde.py +0 -28
  57. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/telemetry.py +4 -0
  58. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/compat/client/app.py +14 -31
  59. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/compat/server/app.py +2 -2
  60. flwr-1.21.0/py/flwr/proto/appio_pb2.py +51 -0
  61. flwr-1.19.0/py/flwr/proto/serverappio_pb2.pyi → flwr-1.21.0/py/flwr/proto/appio_pb2.pyi +76 -70
  62. flwr-1.21.0/py/flwr/proto/clientappio_pb2.py +30 -0
  63. flwr-1.21.0/py/flwr/proto/clientappio_pb2.pyi +7 -0
  64. flwr-1.21.0/py/flwr/proto/clientappio_pb2_grpc.py +375 -0
  65. flwr-1.21.0/py/flwr/proto/clientappio_pb2_grpc.pyi +146 -0
  66. flwr-1.21.0/py/flwr/proto/control_pb2.py +62 -0
  67. flwr-1.19.0/py/flwr/proto/exec_pb2_grpc.py → flwr-1.21.0/py/flwr/proto/control_pb2_grpc.py +54 -54
  68. flwr-1.19.0/py/flwr/proto/exec_pb2_grpc.pyi → flwr-1.21.0/py/flwr/proto/control_pb2_grpc.pyi +28 -28
  69. flwr-1.21.0/py/flwr/proto/fleet_pb2.py +53 -0
  70. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/fleet_pb2.pyi +6 -36
  71. flwr-1.21.0/py/flwr/proto/run_pb2_grpc.py +4 -0
  72. flwr-1.21.0/py/flwr/proto/run_pb2_grpc.pyi +4 -0
  73. flwr-1.21.0/py/flwr/proto/serverappio_pb2.py +37 -0
  74. flwr-1.21.0/py/flwr/proto/serverappio_pb2.pyi +37 -0
  75. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/serverappio_pb2_grpc.py +107 -38
  76. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/serverappio_pb2_grpc.pyi +47 -20
  77. flwr-1.21.0/py/flwr/proto/simulationio_pb2.py +32 -0
  78. flwr-1.21.0/py/flwr/proto/simulationio_pb2.pyi +7 -0
  79. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/simulationio_pb2_grpc.py +129 -27
  80. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/simulationio_pb2_grpc.pyi +52 -13
  81. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/app.py +130 -153
  82. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/fleet_event_log_interceptor.py +4 -0
  83. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/grid/grpc_grid.py +94 -54
  84. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/grid/inmemory_grid.py +1 -0
  85. flwr-1.21.0/py/flwr/server/serverapp/app.py +297 -0
  86. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +8 -0
  87. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +1 -1
  88. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +2 -5
  89. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/message_handler/message_handler.py +10 -16
  90. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +1 -2
  91. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +3 -1
  92. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/vce/vce_api.py +6 -6
  93. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/linkstate/in_memory_linkstate.py +34 -0
  94. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/linkstate/linkstate.py +2 -1
  95. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/linkstate/sqlite_linkstate.py +45 -0
  96. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/serverappio/serverappio_grpc.py +2 -2
  97. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/serverappio/serverappio_servicer.py +95 -48
  98. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/simulation/simulationio_grpc.py +1 -1
  99. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/simulation/simulationio_servicer.py +98 -22
  100. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/utils.py +0 -35
  101. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/serverapp/__init__.py +12 -0
  102. flwr-1.21.0/py/flwr/serverapp/dp_fixed_clipping.py +352 -0
  103. flwr-1.21.0/py/flwr/serverapp/exception.py +38 -0
  104. flwr-1.21.0/py/flwr/serverapp/strategy/__init__.py +38 -0
  105. flwr-1.21.0/py/flwr/serverapp/strategy/dp_fixed_clipping.py +352 -0
  106. flwr-1.21.0/py/flwr/serverapp/strategy/fedadagrad.py +162 -0
  107. flwr-1.21.0/py/flwr/serverapp/strategy/fedadam.py +181 -0
  108. flwr-1.21.0/py/flwr/serverapp/strategy/fedavg.py +295 -0
  109. flwr-1.21.0/py/flwr/serverapp/strategy/fedopt.py +218 -0
  110. flwr-1.21.0/py/flwr/serverapp/strategy/fedyogi.py +173 -0
  111. flwr-1.21.0/py/flwr/serverapp/strategy/result.py +105 -0
  112. flwr-1.21.0/py/flwr/serverapp/strategy/strategy.py +285 -0
  113. flwr-1.21.0/py/flwr/serverapp/strategy/strategy_utils.py +251 -0
  114. flwr-1.21.0/py/flwr/serverapp/strategy/strategy_utils_tests.py +304 -0
  115. flwr-1.21.0/py/flwr/simulation/app.py +303 -0
  116. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/simulation/run_simulation.py +17 -0
  117. flwr-1.21.0/py/flwr/supercore/app_utils.py +58 -0
  118. flwr-1.21.0/py/flwr/supercore/cli/__init__.py +22 -0
  119. flwr-1.21.0/py/flwr/supercore/cli/flower_superexec.py +141 -0
  120. flwr-1.21.0/py/flwr/supercore/corestate/__init__.py +22 -0
  121. flwr-1.21.0/py/flwr/supercore/corestate/corestate.py +81 -0
  122. {flwr-1.19.0/py/flwr/server/superlink → flwr-1.21.0/py/flwr/supercore}/ffs/disk_ffs.py +1 -1
  123. flwr-1.21.0/py/flwr/supercore/grpc_health/__init__.py +25 -0
  124. flwr-1.21.0/py/flwr/supercore/grpc_health/health_server.py +53 -0
  125. flwr-1.21.0/py/flwr/supercore/grpc_health/simple_health_servicer.py +38 -0
  126. flwr-1.21.0/py/flwr/supercore/license_plugin/__init__.py +22 -0
  127. flwr-1.21.0/py/flwr/supercore/license_plugin/license_plugin.py +26 -0
  128. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supercore/object_store/in_memory_object_store.py +31 -31
  129. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supercore/object_store/object_store.py +20 -42
  130. flwr-1.21.0/py/flwr/supercore/object_store/utils.py +43 -0
  131. flwr-1.21.0/py/flwr/supercore/superexec/__init__.py +15 -0
  132. flwr-1.21.0/py/flwr/supercore/superexec/plugin/__init__.py +28 -0
  133. flwr-1.21.0/py/flwr/supercore/superexec/plugin/base_exec_plugin.py +53 -0
  134. flwr-1.21.0/py/flwr/supercore/superexec/plugin/clientapp_exec_plugin.py +28 -0
  135. flwr-1.21.0/py/flwr/supercore/superexec/plugin/exec_plugin.py +71 -0
  136. flwr-1.21.0/py/flwr/supercore/superexec/plugin/serverapp_exec_plugin.py +28 -0
  137. flwr-1.21.0/py/flwr/supercore/superexec/plugin/simulation_exec_plugin.py +28 -0
  138. flwr-1.21.0/py/flwr/supercore/superexec/run_superexec.py +185 -0
  139. flwr-1.21.0/py/flwr/supercore/utils.py +32 -0
  140. {flwr-1.19.0/py/flwr/app → flwr-1.21.0/py/flwr/superlink/servicer}/__init__.py +1 -1
  141. flwr-1.21.0/py/flwr/superlink/servicer/control/__init__.py +22 -0
  142. flwr-1.19.0/py/flwr/superexec/exec_event_log_interceptor.py → flwr-1.21.0/py/flwr/superlink/servicer/control/control_event_log_interceptor.py +9 -5
  143. flwr-1.19.0/py/flwr/superexec/exec_grpc.py → flwr-1.21.0/py/flwr/superlink/servicer/control/control_grpc.py +39 -28
  144. flwr-1.21.0/py/flwr/superlink/servicer/control/control_license_interceptor.py +82 -0
  145. flwr-1.19.0/py/flwr/superexec/exec_servicer.py → flwr-1.21.0/py/flwr/superlink/servicer/control/control_servicer.py +79 -31
  146. flwr-1.19.0/py/flwr/superexec/exec_user_auth_interceptor.py → flwr-1.21.0/py/flwr/superlink/servicer/control/control_user_auth_interceptor.py +18 -10
  147. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supernode/cli/flower_supernode.py +3 -7
  148. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supernode/cli/flwr_clientapp.py +20 -16
  149. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supernode/nodestate/in_memory_nodestate.py +13 -4
  150. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supernode/nodestate/nodestate.py +3 -44
  151. flwr-1.21.0/py/flwr/supernode/runtime/run_clientapp.py +240 -0
  152. flwr-1.21.0/py/flwr/supernode/servicer/clientappio/__init__.py +22 -0
  153. flwr-1.21.0/py/flwr/supernode/servicer/clientappio/clientappio_servicer.py +296 -0
  154. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supernode/start_client_internal.py +205 -148
  155. {flwr-1.19.0 → flwr-1.21.0}/pyproject.toml +4 -2
  156. flwr-1.19.0/py/flwr/cli/constant.py +0 -27
  157. flwr-1.19.0/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl +0 -35
  158. flwr-1.19.0/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +0 -39
  159. flwr-1.19.0/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +0 -32
  160. flwr-1.19.0/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +0 -36
  161. flwr-1.19.0/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +0 -35
  162. flwr-1.19.0/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +0 -36
  163. flwr-1.19.0/py/flwr/common/inflatable_rest_utils.py +0 -99
  164. flwr-1.19.0/py/flwr/proto/clientappio_pb2.py +0 -45
  165. flwr-1.19.0/py/flwr/proto/clientappio_pb2.pyi +0 -132
  166. flwr-1.19.0/py/flwr/proto/clientappio_pb2_grpc.py +0 -135
  167. flwr-1.19.0/py/flwr/proto/clientappio_pb2_grpc.pyi +0 -53
  168. flwr-1.19.0/py/flwr/proto/exec_pb2.py +0 -62
  169. flwr-1.19.0/py/flwr/proto/fleet_pb2.py +0 -61
  170. flwr-1.19.0/py/flwr/proto/serverappio_pb2.py +0 -60
  171. flwr-1.19.0/py/flwr/proto/simulationio_pb2.py +0 -39
  172. flwr-1.19.0/py/flwr/proto/simulationio_pb2.pyi +0 -65
  173. flwr-1.19.0/py/flwr/server/serverapp/app.py +0 -276
  174. flwr-1.19.0/py/flwr/simulation/app.py +0 -298
  175. flwr-1.19.0/py/flwr/superexec/__init__.py +0 -15
  176. flwr-1.19.0/py/flwr/superexec/app.py +0 -45
  177. flwr-1.19.0/py/flwr/superexec/deployment.py +0 -192
  178. flwr-1.19.0/py/flwr/superexec/executor.py +0 -100
  179. flwr-1.19.0/py/flwr/superexec/simulation.py +0 -130
  180. flwr-1.19.0/py/flwr/supernode/runtime/run_clientapp.py +0 -226
  181. flwr-1.19.0/py/flwr/supernode/servicer/clientappio/__init__.py +0 -24
  182. flwr-1.19.0/py/flwr/supernode/servicer/clientappio/clientappio_servicer.py +0 -244
  183. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/app/error.py +0 -0
  184. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/app/metadata.py +0 -0
  185. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/__init__.py +0 -0
  186. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/app.py +0 -0
  187. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/auth_plugin/__init__.py +0 -0
  188. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/example.py +0 -0
  189. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/install.py +0 -0
  190. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/login/__init__.py +0 -0
  191. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/__init__.py +0 -0
  192. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/__init__.py +0 -0
  193. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/.gitignore.tpl +0 -0
  194. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/LICENSE.tpl +0 -0
  195. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/README.baseline.md.tpl +0 -0
  196. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/__init__.py +0 -0
  197. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/__init__.baseline.py.tpl +0 -0
  198. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
  199. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
  200. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.baseline.py.tpl +0 -0
  201. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.huggingface.py.tpl +0 -0
  202. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.jax.py.tpl +0 -0
  203. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.mlx.py.tpl +0 -0
  204. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
  205. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -0
  206. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.sklearn.py.tpl +0 -0
  207. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -0
  208. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/dataset.baseline.py.tpl +0 -0
  209. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py +0 -0
  210. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +0 -0
  211. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +0 -0
  212. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +0 -0
  213. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +0 -0
  214. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +0 -0
  215. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/model.baseline.py.tpl +0 -0
  216. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.baseline.py.tpl +0 -0
  217. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.huggingface.py.tpl +0 -0
  218. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.jax.py.tpl +0 -0
  219. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.mlx.py.tpl +0 -0
  220. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
  221. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -0
  222. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.sklearn.py.tpl +0 -0
  223. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -0
  224. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/strategy.baseline.py.tpl +0 -0
  225. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/task.huggingface.py.tpl +0 -0
  226. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/task.jax.py.tpl +0 -0
  227. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/task.mlx.py.tpl +0 -0
  228. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/task.numpy.py.tpl +0 -0
  229. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
  230. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/task.sklearn.py.tpl +0 -0
  231. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +0 -0
  232. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/utils.baseline.py.tpl +0 -0
  233. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/cli/run/__init__.py +0 -0
  234. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/__init__.py +0 -0
  235. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/client.py +0 -0
  236. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/client_app.py +0 -0
  237. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/clientapp/__init__.py +0 -0
  238. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/clientapp/utils.py +0 -0
  239. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/dpfedavg_numpy_client.py +0 -0
  240. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/grpc_adapter_client/__init__.py +0 -0
  241. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/grpc_rere_client/__init__.py +0 -0
  242. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/grpc_rere_client/client_interceptor.py +0 -0
  243. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/grpc_rere_client/grpc_adapter.py +0 -0
  244. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/message_handler/__init__.py +0 -0
  245. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/message_handler/message_handler.py +0 -0
  246. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/mod/__init__.py +0 -0
  247. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/mod/centraldp_mods.py +0 -0
  248. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/mod/comms_mods.py +0 -0
  249. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/mod/localdp_mod.py +0 -0
  250. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
  251. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
  252. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
  253. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/mod/utils.py +0 -0
  254. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/numpy_client.py +0 -0
  255. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/rest_client/__init__.py +0 -0
  256. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/run_info_store.py +0 -0
  257. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/client/typing.py +0 -0
  258. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/__init__.py +0 -0
  259. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/address.py +0 -0
  260. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/config.py +0 -0
  261. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/context.py +0 -0
  262. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/date.py +0 -0
  263. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/differential_privacy.py +0 -0
  264. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/differential_privacy_constants.py +0 -0
  265. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/dp.py +0 -0
  266. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/event_log_plugin/__init__.py +0 -0
  267. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/heartbeat.py +0 -0
  268. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/inflatable.py +0 -0
  269. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/logger.py +1 -1
  270. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/message.py +0 -0
  271. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/object_ref.py +0 -0
  272. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/parameter.py +0 -0
  273. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/pyproject.py +0 -0
  274. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/record/__init__.py +0 -0
  275. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/record/arrayrecord.py +0 -0
  276. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/record/configrecord.py +0 -0
  277. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/record/conversion_utils.py +0 -0
  278. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/record/metricrecord.py +0 -0
  279. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/record/recorddict.py +0 -0
  280. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/record/typeddict.py +0 -0
  281. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/recorddict_compat.py +0 -0
  282. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/__init__.py +0 -0
  283. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
  284. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
  285. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
  286. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
  287. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/quantization.py +0 -0
  288. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
  289. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
  290. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/serde_utils.py +0 -0
  291. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/typing.py +0 -0
  292. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/common/version.py +0 -0
  293. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/compat/__init__.py +0 -0
  294. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/compat/client/__init__.py +0 -0
  295. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/compat/client/grpc_client/__init__.py +0 -0
  296. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/compat/client/grpc_client/connection.py +0 -0
  297. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/compat/common/__init__.py +0 -0
  298. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/compat/server/__init__.py +0 -0
  299. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/compat/simulation/__init__.py +0 -0
  300. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/__init__.py +0 -0
  301. /flwr-1.19.0/py/flwr/proto/error_pb2_grpc.py → /flwr-1.21.0/py/flwr/proto/appio_pb2_grpc.py +0 -0
  302. /flwr-1.19.0/py/flwr/proto/error_pb2_grpc.pyi → /flwr-1.21.0/py/flwr/proto/appio_pb2_grpc.pyi +0 -0
  303. /flwr-1.19.0/py/flwr/proto/exec_pb2.pyi → /flwr-1.21.0/py/flwr/proto/control_pb2.pyi +0 -0
  304. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/error_pb2.py +0 -0
  305. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/error_pb2.pyi +0 -0
  306. /flwr-1.19.0/py/flwr/proto/fab_pb2_grpc.py → /flwr-1.21.0/py/flwr/proto/error_pb2_grpc.py +0 -0
  307. /flwr-1.19.0/py/flwr/proto/fab_pb2_grpc.pyi → /flwr-1.21.0/py/flwr/proto/error_pb2_grpc.pyi +0 -0
  308. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/fab_pb2.py +0 -0
  309. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/fab_pb2.pyi +0 -0
  310. /flwr-1.19.0/py/flwr/proto/heartbeat_pb2_grpc.py → /flwr-1.21.0/py/flwr/proto/fab_pb2_grpc.py +0 -0
  311. /flwr-1.19.0/py/flwr/proto/heartbeat_pb2_grpc.pyi → /flwr-1.21.0/py/flwr/proto/fab_pb2_grpc.pyi +0 -0
  312. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/fleet_pb2_grpc.py +0 -0
  313. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
  314. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/grpcadapter_pb2.py +0 -0
  315. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/grpcadapter_pb2.pyi +0 -0
  316. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/grpcadapter_pb2_grpc.py +0 -0
  317. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/grpcadapter_pb2_grpc.pyi +0 -0
  318. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/heartbeat_pb2.py +0 -0
  319. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/heartbeat_pb2.pyi +0 -0
  320. /flwr-1.19.0/py/flwr/proto/log_pb2_grpc.py → /flwr-1.21.0/py/flwr/proto/heartbeat_pb2_grpc.py +0 -0
  321. /flwr-1.19.0/py/flwr/proto/log_pb2_grpc.pyi → /flwr-1.21.0/py/flwr/proto/heartbeat_pb2_grpc.pyi +0 -0
  322. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/log_pb2.py +0 -0
  323. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/log_pb2.pyi +0 -0
  324. /flwr-1.19.0/py/flwr/proto/message_pb2_grpc.py → /flwr-1.21.0/py/flwr/proto/log_pb2_grpc.py +0 -0
  325. /flwr-1.19.0/py/flwr/proto/message_pb2_grpc.pyi → /flwr-1.21.0/py/flwr/proto/log_pb2_grpc.pyi +0 -0
  326. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/message_pb2.py +0 -0
  327. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/message_pb2.pyi +0 -0
  328. /flwr-1.19.0/py/flwr/proto/node_pb2_grpc.py → /flwr-1.21.0/py/flwr/proto/message_pb2_grpc.py +0 -0
  329. /flwr-1.19.0/py/flwr/proto/node_pb2_grpc.pyi → /flwr-1.21.0/py/flwr/proto/message_pb2_grpc.pyi +0 -0
  330. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/node_pb2.py +0 -0
  331. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/node_pb2.pyi +0 -0
  332. /flwr-1.19.0/py/flwr/proto/recorddict_pb2_grpc.py → /flwr-1.21.0/py/flwr/proto/node_pb2_grpc.py +0 -0
  333. /flwr-1.19.0/py/flwr/proto/recorddict_pb2_grpc.pyi → /flwr-1.21.0/py/flwr/proto/node_pb2_grpc.pyi +0 -0
  334. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/recorddict_pb2.py +0 -0
  335. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/recorddict_pb2.pyi +0 -0
  336. /flwr-1.19.0/py/flwr/proto/run_pb2_grpc.py → /flwr-1.21.0/py/flwr/proto/recorddict_pb2_grpc.py +0 -0
  337. /flwr-1.19.0/py/flwr/proto/run_pb2_grpc.pyi → /flwr-1.21.0/py/flwr/proto/recorddict_pb2_grpc.pyi +0 -0
  338. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/run_pb2.py +0 -0
  339. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/run_pb2.pyi +0 -0
  340. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/transport_pb2.py +0 -0
  341. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/transport_pb2.pyi +0 -0
  342. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/transport_pb2_grpc.py +0 -0
  343. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
  344. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/py.typed +0 -0
  345. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/__init__.py +0 -0
  346. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/client_manager.py +0 -0
  347. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/client_proxy.py +0 -0
  348. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/compat/__init__.py +0 -0
  349. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/compat/app.py +0 -0
  350. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/compat/app_utils.py +0 -0
  351. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/compat/grid_client_proxy.py +0 -0
  352. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/compat/legacy_context.py +0 -0
  353. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/criterion.py +0 -0
  354. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/grid/__init__.py +0 -0
  355. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/grid/grid.py +0 -0
  356. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/history.py +0 -0
  357. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/run_serverapp.py +0 -0
  358. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/server.py +0 -0
  359. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/server_app.py +0 -0
  360. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/server_config.py +0 -0
  361. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/serverapp/__init__.py +0 -0
  362. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/serverapp_components.py +0 -0
  363. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/__init__.py +0 -0
  364. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/aggregate.py +0 -0
  365. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/bulyan.py +0 -0
  366. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
  367. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
  368. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
  369. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
  370. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
  371. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/fedadagrad.py +0 -0
  372. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/fedadam.py +0 -0
  373. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/fedavg.py +0 -0
  374. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/fedavg_android.py +0 -0
  375. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/fedavgm.py +0 -0
  376. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/fedmedian.py +0 -0
  377. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/fedopt.py +0 -0
  378. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/fedprox.py +0 -0
  379. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
  380. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
  381. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
  382. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
  383. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/fedyogi.py +0 -0
  384. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/krum.py +0 -0
  385. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/qfedavg.py +0 -0
  386. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/strategy/strategy.py +0 -0
  387. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/__init__.py +0 -0
  388. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/__init__.py +0 -0
  389. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py +0 -0
  390. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
  391. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
  392. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
  393. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
  394. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
  395. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
  396. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
  397. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
  398. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
  399. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
  400. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
  401. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/linkstate/__init__.py +0 -0
  402. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/linkstate/linkstate_factory.py +0 -0
  403. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/linkstate/utils.py +0 -0
  404. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/serverappio/__init__.py +0 -0
  405. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/superlink/simulation/__init__.py +0 -0
  406. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/typing.py +0 -0
  407. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/utils/__init__.py +0 -0
  408. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/utils/tensorboard.py +0 -0
  409. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/utils/validator.py +0 -0
  410. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/workflow/__init__.py +0 -0
  411. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/workflow/constant.py +0 -0
  412. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/workflow/default_workflows.py +0 -0
  413. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
  414. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
  415. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
  416. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/simulation/__init__.py +0 -0
  417. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/simulation/legacy_app.py +0 -0
  418. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/simulation/ray_transport/__init__.py +0 -0
  419. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
  420. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
  421. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/simulation/ray_transport/utils.py +0 -0
  422. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/simulation/simulationio_connection.py +0 -0
  423. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supercore/__init__.py +0 -0
  424. {flwr-1.19.0/py/flwr/server/superlink → flwr-1.21.0/py/flwr/supercore}/ffs/__init__.py +0 -0
  425. {flwr-1.19.0/py/flwr/server/superlink → flwr-1.21.0/py/flwr/supercore}/ffs/ffs.py +0 -0
  426. {flwr-1.19.0/py/flwr/server/superlink → flwr-1.21.0/py/flwr/supercore}/ffs/ffs_factory.py +0 -0
  427. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supercore/object_store/__init__.py +0 -0
  428. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supercore/object_store/object_store_factory.py +0 -0
  429. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/superlink/__init__.py +0 -0
  430. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supernode/__init__.py +0 -0
  431. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supernode/cli/__init__.py +0 -0
  432. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supernode/nodestate/__init__.py +0 -0
  433. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supernode/nodestate/nodestate_factory.py +0 -0
  434. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supernode/runtime/__init__.py +0 -0
  435. {flwr-1.19.0 → flwr-1.21.0}/py/flwr/supernode/servicer/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: flwr
3
- Version: 1.19.0
3
+ Version: 1.21.0
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
@@ -34,6 +34,7 @@ Provides-Extra: simulation
34
34
  Requires-Dist: click (<8.2.0)
35
35
  Requires-Dist: cryptography (>=44.0.1,<45.0.0)
36
36
  Requires-Dist: grpcio (>=1.62.3,<2.0.0,!=1.65.0)
37
+ Requires-Dist: grpcio-health-checking (>=1.62.3,<2.0.0)
37
38
  Requires-Dist: iterators (>=0.0.2,<0.0.3)
38
39
  Requires-Dist: numpy (>=1.26.0,<3.0.0)
39
40
  Requires-Dist: pathspec (>=0.12.1,<0.13.0)
@@ -171,8 +172,9 @@ Flower Baselines is a collection of community-contributed projects that reproduc
171
172
  - [FedOpt](https://github.com/adap/flower/tree/main/baselines/flwr_baselines/flwr_baselines/publications/adaptive_federated_optimization)
172
173
 
173
174
  Please refer to the [Flower Baselines Documentation](https://flower.ai/docs/baselines/) for a detailed categorization of baselines and for additional info including:
174
- * [How to use Flower Baselines](https://flower.ai/docs/baselines/how-to-use-baselines.html)
175
- * [How to contribute a new Flower Baseline](https://flower.ai/docs/baselines/how-to-contribute-baselines.html)
175
+
176
+ - [How to use Flower Baselines](https://flower.ai/docs/baselines/how-to-use-baselines.html)
177
+ - [How to contribute a new Flower Baseline](https://flower.ai/docs/baselines/how-to-contribute-baselines.html)
176
178
 
177
179
  ## Flower Usage Examples
178
180
 
@@ -116,8 +116,9 @@ Flower Baselines is a collection of community-contributed projects that reproduc
116
116
  - [FedOpt](https://github.com/adap/flower/tree/main/baselines/flwr_baselines/flwr_baselines/publications/adaptive_federated_optimization)
117
117
 
118
118
  Please refer to the [Flower Baselines Documentation](https://flower.ai/docs/baselines/) for a detailed categorization of baselines and for additional info including:
119
- * [How to use Flower Baselines](https://flower.ai/docs/baselines/how-to-use-baselines.html)
120
- * [How to contribute a new Flower Baseline](https://flower.ai/docs/baselines/how-to-contribute-baselines.html)
119
+
120
+ - [How to use Flower Baselines](https://flower.ai/docs/baselines/how-to-use-baselines.html)
121
+ - [How to contribute a new Flower Baseline](https://flower.ai/docs/baselines/how-to-contribute-baselines.html)
121
122
 
122
123
  ## Flower Usage Examples
123
124
 
@@ -17,12 +17,15 @@
17
17
 
18
18
  from flwr.common.version import package_version as _package_version
19
19
 
20
- from . import client, common, server, simulation
20
+ from . import app, client, clientapp, common, server, serverapp, simulation
21
21
 
22
22
  __all__ = [
23
+ "app",
23
24
  "client",
25
+ "clientapp",
24
26
  "common",
25
27
  "server",
28
+ "serverapp",
26
29
  "simulation",
27
30
  ]
28
31
 
@@ -0,0 +1,43 @@
1
+ # Copyright 2025 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
+ """Public Flower App APIs."""
16
+
17
+
18
+ from flwr.common.constant import MessageType
19
+ from flwr.common.context import Context
20
+ from flwr.common.message import Message
21
+ from flwr.common.record import (
22
+ Array,
23
+ ArrayRecord,
24
+ ConfigRecord,
25
+ MetricRecord,
26
+ RecordDict,
27
+ )
28
+
29
+ from .error import Error
30
+ from .metadata import Metadata
31
+
32
+ __all__ = [
33
+ "Array",
34
+ "ArrayRecord",
35
+ "ConfigRecord",
36
+ "Context",
37
+ "Error",
38
+ "Message",
39
+ "MessageType",
40
+ "Metadata",
41
+ "MetricRecord",
42
+ "RecordDict",
43
+ ]
@@ -0,0 +1,31 @@
1
+ # Copyright 2025 Flower Labs GmbH. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ # ==============================================================================
15
+ """Flower application exceptions."""
16
+
17
+
18
+ class AppExitException(BaseException):
19
+ """Base exception for all application-level errors in ServerApp and ClientApp.
20
+
21
+ When raised, the process will exit and report a telemetry event with the associated
22
+ exit code. This is not intended to be caught by user code.
23
+ """
24
+
25
+ # Default exit code — subclasses must override
26
+ exit_code = -1
27
+
28
+ def __init_subclass__(cls) -> None:
29
+ """Ensure subclasses override the exit_code attribute."""
30
+ if cls.exit_code == -1:
31
+ raise ValueError("Subclasses must override the exit_code attribute.")
@@ -31,11 +31,11 @@ from flwr.common.constant import (
31
31
  AuthType,
32
32
  )
33
33
  from flwr.common.typing import UserAuthCredentials, UserAuthLoginDetails
34
- from flwr.proto.exec_pb2 import ( # pylint: disable=E0611
34
+ from flwr.proto.control_pb2 import ( # pylint: disable=E0611
35
35
  GetAuthTokensRequest,
36
36
  GetAuthTokensResponse,
37
37
  )
38
- from flwr.proto.exec_pb2_grpc import ExecStub
38
+ from flwr.proto.control_pb2_grpc import ControlStub
39
39
 
40
40
 
41
41
  class OidcCliPlugin(CliAuthPlugin):
@@ -49,7 +49,7 @@ class OidcCliPlugin(CliAuthPlugin):
49
49
  @staticmethod
50
50
  def login(
51
51
  login_details: UserAuthLoginDetails,
52
- exec_stub: ExecStub,
52
+ control_stub: ControlStub,
53
53
  ) -> UserAuthCredentials:
54
54
  """Authenticate the user and retrieve authentication credentials."""
55
55
  typer.secho(
@@ -61,7 +61,7 @@ class OidcCliPlugin(CliAuthPlugin):
61
61
  time.sleep(login_details.interval)
62
62
 
63
63
  while (time.time() - start_time) < login_details.expires_in:
64
- res: GetAuthTokensResponse = exec_stub.GetAuthTokens(
64
+ res: GetAuthTokensResponse = control_stub.GetAuthTokens(
65
65
  GetAuthTokensRequest(device_code=login_details.device_code)
66
66
  )
67
67
 
@@ -25,7 +25,12 @@ import pathspec
25
25
  import tomli_w
26
26
  import typer
27
27
 
28
- from flwr.common.constant import FAB_ALLOWED_EXTENSIONS, FAB_DATE, FAB_HASH_TRUNCATION
28
+ from flwr.common.constant import (
29
+ FAB_ALLOWED_EXTENSIONS,
30
+ FAB_DATE,
31
+ FAB_HASH_TRUNCATION,
32
+ FAB_MAX_SIZE,
33
+ )
29
34
 
30
35
  from .config_utils import load as load_toml
31
36
  from .config_utils import load_and_validate
@@ -57,7 +62,7 @@ def build(
57
62
  Optional[Path],
58
63
  typer.Option(help="Path of the Flower App to bundle into a FAB"),
59
64
  ] = None,
60
- ) -> tuple[str, str]:
65
+ ) -> None:
61
66
  """Build a Flower App into a Flower App Bundle (FAB).
62
67
 
63
68
  You can run ``flwr build`` without any arguments to bundle the app located in the
@@ -119,8 +124,6 @@ def build(
119
124
  f"🎊 Successfully built {fab_filename}", fg=typer.colors.GREEN, bold=True
120
125
  )
121
126
 
122
- return fab_filename, fab_hash
123
-
124
127
 
125
128
  def build_fab(app: Path) -> tuple[bytes, str, dict[str, Any]]:
126
129
  """Build a FAB in memory and return the bytes, hash, and config.
@@ -181,7 +184,7 @@ def build_fab(app: Path) -> tuple[bytes, str, dict[str, Any]]:
181
184
  # Read the file content manually
182
185
  file_contents = file_path.read_bytes()
183
186
 
184
- archive_path = str(file_path.relative_to(app))
187
+ archive_path = str(file_path.relative_to(app)).replace("\\", "/")
185
188
  write_to_zip(fab_file, archive_path, file_contents)
186
189
 
187
190
  # Calculate file info
@@ -193,6 +196,13 @@ def build_fab(app: Path) -> tuple[bytes, str, dict[str, Any]]:
193
196
  write_to_zip(fab_file, ".info/CONTENT", list_file_content)
194
197
 
195
198
  fab_bytes = fab_buffer.getvalue()
199
+ if len(fab_bytes) > FAB_MAX_SIZE:
200
+ raise ValueError(
201
+ f"FAB size exceeds maximum allowed size of {FAB_MAX_SIZE:,} bytes."
202
+ "To reduce the package size, consider ignoring unnecessary files "
203
+ "via your `.gitignore` file or excluding them from the build."
204
+ )
205
+
196
206
  fab_hash = hashlib.sha256(fab_bytes).hexdigest()
197
207
 
198
208
  return fab_bytes, fab_hash, config
@@ -20,7 +20,7 @@ from typing import Any, Callable, Union
20
20
  import grpc
21
21
 
22
22
  from flwr.common.auth_plugin import CliAuthPlugin
23
- from flwr.proto.exec_pb2 import ( # pylint: disable=E0611
23
+ from flwr.proto.control_pb2 import ( # pylint: disable=E0611
24
24
  StartRunRequest,
25
25
  StreamLogsRequest,
26
26
  )
@@ -143,7 +143,7 @@ def validate_federation_in_project_config(
143
143
  if federation is None:
144
144
  typer.secho(
145
145
  "❌ No federation name was provided and the project's `pyproject.toml` "
146
- "doesn't declare a default federation (with an Exec API address or an "
146
+ "doesn't declare a default federation (with an Control API address or an "
147
147
  "`options.num-supernodes` value).",
148
148
  fg=typer.colors.RED,
149
149
  bold=True,
@@ -230,8 +230,8 @@ def exit_if_no_address(federation_config: dict[str, Any], cmd: str) -> None:
230
230
  """Exit if the provided federation_config has no "address" key."""
231
231
  if "address" not in federation_config:
232
232
  typer.secho(
233
- f"❌ `flwr {cmd}` currently works with a SuperLink. Ensure that the correct"
234
- "SuperLink (Exec API) address is provided in `pyproject.toml`.",
233
+ f"❌ `flwr {cmd}` currently works with a SuperLink. Ensure that the "
234
+ "correct SuperLink (Control API) address is provided in `pyproject.toml`.",
235
235
  fg=typer.colors.RED,
236
236
  bold=True,
237
237
  )
@@ -0,0 +1,44 @@
1
+ # Copyright 2025 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
+ """Constants for CLI commands."""
16
+
17
+
18
+ # General help message for config overrides
19
+ CONFIG_HELP_MESSAGE = (
20
+ "Override {0} values using one of the following formats:\n\n"
21
+ "--{1} '<k1>=<v1> <k2>=<v2>' | --{1} '<k1>=<v1>' --{1} '<k2>=<v2>'{2}\n\n"
22
+ "When providing key-value pairs, values can be of any type supported by TOML "
23
+ "(e.g., bool, int, float, string). The specified keys (<k1> and <k2> in the "
24
+ "example) must exist in the {0} under the `{3}` section of `pyproject.toml` to be "
25
+ "overridden.{4}"
26
+ )
27
+
28
+ # The help message for `--run-config` option
29
+ RUN_CONFIG_HELP_MESSAGE = CONFIG_HELP_MESSAGE.format(
30
+ "run configuration",
31
+ "run-config",
32
+ " | --run-config <path/to/your/toml>",
33
+ "[tool.flwr.app.config]",
34
+ " Alternatively, provide a TOML file containing overrides.",
35
+ )
36
+
37
+ # The help message for `--federation-config` option
38
+ FEDERATION_CONFIG_HELP_MESSAGE = CONFIG_HELP_MESSAGE.format(
39
+ "federation configuration",
40
+ "federation-config",
41
+ "",
42
+ "[tool.flwr.federations.<YOUR-FEDERATION>]",
43
+ "",
44
+ )
@@ -32,8 +32,8 @@ from flwr.cli.config_utils import (
32
32
  from flwr.cli.constant import FEDERATION_CONFIG_HELP_MESSAGE
33
33
  from flwr.common.constant import CONN_RECONNECT_INTERVAL, CONN_REFRESH_PERIOD
34
34
  from flwr.common.logger import log as logger
35
- from flwr.proto.exec_pb2 import StreamLogsRequest # pylint: disable=E0611
36
- from flwr.proto.exec_pb2_grpc import ExecStub
35
+ from flwr.proto.control_pb2 import StreamLogsRequest # pylint: disable=E0611
36
+ from flwr.proto.control_pb2_grpc import ControlStub
37
37
 
38
38
  from .utils import flwr_cli_grpc_exc_handler, init_channel, try_obtain_cli_auth_plugin
39
39
 
@@ -46,7 +46,7 @@ def start_stream(
46
46
  run_id: int, channel: grpc.Channel, refresh_period: int = CONN_REFRESH_PERIOD
47
47
  ) -> None:
48
48
  """Start log streaming for a given run ID."""
49
- stub = ExecStub(channel)
49
+ stub = ControlStub(channel)
50
50
  after_timestamp = 0.0
51
51
  try:
52
52
  logger(INFO, "Starting logstream for run_id `%s`", run_id)
@@ -69,7 +69,7 @@ def start_stream(
69
69
 
70
70
 
71
71
  def stream_logs(
72
- run_id: int, stub: ExecStub, duration: int, after_timestamp: float
72
+ run_id: int, stub: ControlStub, duration: int, after_timestamp: float
73
73
  ) -> float:
74
74
  """Stream logs from the beginning of a run with connection refresh.
75
75
 
@@ -77,8 +77,8 @@ def stream_logs(
77
77
  ----------
78
78
  run_id : int
79
79
  The identifier of the run.
80
- stub : ExecStub
81
- The gRPC stub to interact with the Exec service.
80
+ stub : ControlStub
81
+ The gRPC stub to interact with the Control service.
82
82
  duration : int
83
83
  The timeout duration for each stream connection in seconds.
84
84
  after_timestamp : float
@@ -112,7 +112,7 @@ def stream_logs(
112
112
 
113
113
  def print_logs(run_id: int, channel: grpc.Channel, timeout: int) -> None:
114
114
  """Print logs from the beginning of a run."""
115
- stub = ExecStub(channel)
115
+ stub = ControlStub(channel)
116
116
  req = StreamLogsRequest(run_id=run_id, after_timestamp=0.0)
117
117
 
118
118
  try:
@@ -173,13 +173,13 @@ def log(
173
173
  exit_if_no_address(federation_config, "log")
174
174
 
175
175
  try:
176
- _log_with_exec_api(app, federation, federation_config, run_id, stream)
176
+ _log_with_control_api(app, federation, federation_config, run_id, stream)
177
177
  except Exception as err: # pylint: disable=broad-except
178
178
  typer.secho(str(err), fg=typer.colors.RED, bold=True)
179
179
  raise typer.Exit(code=1) from None
180
180
 
181
181
 
182
- def _log_with_exec_api(
182
+ def _log_with_control_api(
183
183
  app: Path,
184
184
  federation: str,
185
185
  federation_config: dict[str, Any],
@@ -29,11 +29,11 @@ from flwr.cli.config_utils import (
29
29
  )
30
30
  from flwr.cli.constant import FEDERATION_CONFIG_HELP_MESSAGE
31
31
  from flwr.common.typing import UserAuthLoginDetails
32
- from flwr.proto.exec_pb2 import ( # pylint: disable=E0611
32
+ from flwr.proto.control_pb2 import ( # pylint: disable=E0611
33
33
  GetLoginDetailsRequest,
34
34
  GetLoginDetailsResponse,
35
35
  )
36
- from flwr.proto.exec_pb2_grpc import ExecStub
36
+ from flwr.proto.control_pb2_grpc import ControlStub
37
37
 
38
38
  from ..utils import flwr_cli_grpc_exc_handler, init_channel, try_obtain_cli_auth_plugin
39
39
 
@@ -89,7 +89,7 @@ def login( # pylint: disable=R0914
89
89
  raise typer.Exit(code=1)
90
90
 
91
91
  channel = init_channel(app, federation_config, None)
92
- stub = ExecStub(channel)
92
+ stub = ControlStub(channel)
93
93
 
94
94
  login_request = GetLoginDetailsRequest()
95
95
  with flwr_cli_grpc_exc_handler():
@@ -38,11 +38,11 @@ from flwr.common.date import format_timedelta, isoformat8601_utc
38
38
  from flwr.common.logger import print_json_error, redirect_output, restore_output
39
39
  from flwr.common.serde import run_from_proto
40
40
  from flwr.common.typing import Run
41
- from flwr.proto.exec_pb2 import ( # pylint: disable=E0611
41
+ from flwr.proto.control_pb2 import ( # pylint: disable=E0611
42
42
  ListRunsRequest,
43
43
  ListRunsResponse,
44
44
  )
45
- from flwr.proto.exec_pb2_grpc import ExecStub
45
+ from flwr.proto.control_pb2_grpc import ControlStub
46
46
 
47
47
  from .utils import flwr_cli_grpc_exc_handler, init_channel, try_obtain_cli_auth_plugin
48
48
 
@@ -125,7 +125,7 @@ def ls( # pylint: disable=too-many-locals, too-many-branches, R0913, R0917
125
125
  )
126
126
  auth_plugin = try_obtain_cli_auth_plugin(app, federation, federation_config)
127
127
  channel = init_channel(app, federation_config, auth_plugin)
128
- stub = ExecStub(channel)
128
+ stub = ControlStub(channel)
129
129
 
130
130
  # Display information about a specific run ID
131
131
  if run_id is not None:
@@ -293,7 +293,7 @@ def _to_json(run_list: list[_RunListType]) -> str:
293
293
  return json.dumps({"success": True, "runs": runs_list})
294
294
 
295
295
 
296
- def _list_runs(stub: ExecStub) -> list[_RunListType]:
296
+ def _list_runs(stub: ControlStub) -> list[_RunListType]:
297
297
  """List all runs."""
298
298
  with flwr_cli_grpc_exc_handler():
299
299
  res: ListRunsResponse = stub.ListRuns(ListRunsRequest())
@@ -302,7 +302,7 @@ def _list_runs(stub: ExecStub) -> list[_RunListType]:
302
302
  return _format_runs(run_dict, res.now)
303
303
 
304
304
 
305
- def _display_one_run(stub: ExecStub, run_id: int) -> list[_RunListType]:
305
+ def _display_one_run(stub: ControlStub, run_id: int) -> list[_RunListType]:
306
306
  """Display information about a specific run."""
307
307
  with flwr_cli_grpc_exc_handler():
308
308
  res: ListRunsResponse = stub.ListRuns(ListRunsRequest(run_id=run_id))
@@ -35,6 +35,7 @@ class MlFramework(str, Enum):
35
35
  """Available frameworks."""
36
36
 
37
37
  PYTORCH = "PyTorch"
38
+ PYTORCH_MSG_API = "PyTorch (Message API)"
38
39
  TENSORFLOW = "TensorFlow"
39
40
  SKLEARN = "sklearn"
40
41
  HUGGINGFACE = "HuggingFace"
@@ -154,6 +155,9 @@ def new(
154
155
  if framework_str == MlFramework.BASELINE:
155
156
  framework_str = "baseline"
156
157
 
158
+ if framework_str == MlFramework.PYTORCH_MSG_API:
159
+ framework_str = "pytorch_msg_api"
160
+
157
161
  print(
158
162
  typer.style(
159
163
  f"\n🔨 Creating Flower App {app_name}...",
@@ -243,12 +247,19 @@ def new(
243
247
  MlFramework.TENSORFLOW.value,
244
248
  MlFramework.SKLEARN.value,
245
249
  MlFramework.NUMPY.value,
250
+ "pytorch_msg_api",
246
251
  ]
247
252
  if framework_str in frameworks_with_tasks:
248
253
  files[f"{import_name}/task.py"] = {
249
254
  "template": f"app/code/task.{template_name}.py.tpl"
250
255
  }
251
256
 
257
+ if framework_str == "pytorch_msg_api":
258
+ # Use custom __init__ that better captures name of framework
259
+ files[f"{import_name}/__init__.py"] = {
260
+ "template": f"app/code/__init__.{framework_str}.py.tpl"
261
+ }
262
+
252
263
  if framework_str == "baseline":
253
264
  # Include additional files for baseline template
254
265
  for file_name in ["model", "dataset", "strategy", "utils", "__init__"]:
@@ -271,28 +282,36 @@ def new(
271
282
 
272
283
  prompt = typer.style(
273
284
  "🎊 Flower App creation successful.\n\n"
274
- "To run your Flower App, use the following command:\n\n",
285
+ "To run your Flower App, first install its dependencies:\n\n",
275
286
  fg=typer.colors.GREEN,
276
287
  bold=True,
277
288
  )
278
289
 
279
290
  _add = " huggingface-cli login\n" if llm_challenge_str else ""
291
+
280
292
  prompt += typer.style(
281
- _add + f" flwr run {package_name}\n\n",
293
+ f" cd {package_name} && pip install -e .\n" + _add + "\n",
282
294
  fg=typer.colors.BRIGHT_CYAN,
283
295
  bold=True,
284
296
  )
285
297
 
286
298
  prompt += typer.style(
287
- "If you haven't installed all dependencies yet, follow these steps:\n\n",
299
+ "then, run the app:\n\n ",
288
300
  fg=typer.colors.GREEN,
289
301
  bold=True,
290
302
  )
291
303
 
292
304
  prompt += typer.style(
293
- f" cd {package_name}\n" + " pip install -e .\n" + _add + " flwr run .\n",
305
+ "\tflwr run .\n\n",
294
306
  fg=typer.colors.BRIGHT_CYAN,
295
307
  bold=True,
296
308
  )
297
309
 
310
+ prompt += typer.style(
311
+ "💡 Check the README in your app directory to learn how to\n"
312
+ "customize it and how to run it using the Deployment Runtime.\n",
313
+ fg=typer.colors.GREEN,
314
+ bold=True,
315
+ )
316
+
298
317
  print(prompt)
@@ -21,6 +21,8 @@ Project dependencies are defined in `pyproject.toml`. Install them in an activat
21
21
  pip install -e .
22
22
  ```
23
23
 
24
+ > **Tip:** Learn how to configure your `pyproject.toml` file for Flower apps in [this guide](https://flower.ai/docs/framework/how-to-configure-pyproject-toml.html).
25
+
24
26
  ## Experimental setup
25
27
 
26
28
  The dataset is divided into $num_clients partitions in an IID fashion, a partition is assigned to each ClientApp.
@@ -2,10 +2,15 @@
2
2
 
3
3
  ## Install dependencies and project
4
4
 
5
+ The dependencies are listed in the `pyproject.toml` and you can install them as follows:
6
+
5
7
  ```bash
6
8
  pip install -e .
7
9
  ```
8
10
 
11
+ > **Tip:** Your `pyproject.toml` file can define more than just the dependencies of your Flower app. You can also use it to specify hyperparameters for your runs and control which Flower Runtime is used. By default, it uses the Simulation Runtime, but you can switch to the Deployment Runtime when needed.
12
+ > Learn more in the [TOML configuration guide](https://flower.ai/docs/framework/how-to-configure-pyproject-toml.html).
13
+
9
14
  ## Run with the Simulation Engine
10
15
 
11
16
  In the `$project_name` directory, use `flwr run` to run a local simulation:
@@ -0,0 +1 @@
1
+ """$project_name: A Flower / PyTorch app."""
@@ -0,0 +1,80 @@
1
+ """$project_name: A Flower / $framework_str app."""
2
+
3
+ import torch
4
+ from flwr.app import ArrayRecord, Context, Message, MetricRecord, RecordDict
5
+ from flwr.clientapp import ClientApp
6
+
7
+ from $import_name.task import Net, load_data
8
+ from $import_name.task import test as test_fn
9
+ from $import_name.task import train as train_fn
10
+
11
+ # Flower ClientApp
12
+ app = ClientApp()
13
+
14
+
15
+ @app.train()
16
+ def train(msg: Message, context: Context):
17
+ """Train the model on local data."""
18
+
19
+ # Load the model and initialize it with the received weights
20
+ model = Net()
21
+ model.load_state_dict(msg.content["arrays"].to_torch_state_dict())
22
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
23
+ model.to(device)
24
+
25
+ # Load the data
26
+ partition_id = context.node_config["partition-id"]
27
+ num_partitions = context.node_config["num-partitions"]
28
+ trainloader, _ = load_data(partition_id, num_partitions)
29
+
30
+ # Call the training function
31
+ train_loss = train_fn(
32
+ model,
33
+ trainloader,
34
+ context.run_config["local-epochs"],
35
+ msg.content["config"]["lr"],
36
+ device,
37
+ )
38
+
39
+ # Construct and return reply Message
40
+ model_record = ArrayRecord(model.state_dict())
41
+ metrics = {
42
+ "train_loss": train_loss,
43
+ "num-examples": len(trainloader.dataset),
44
+ }
45
+ metric_record = MetricRecord(metrics)
46
+ content = RecordDict({"arrays": model_record, "metrics": metric_record})
47
+ return Message(content=content, reply_to=msg)
48
+
49
+
50
+ @app.evaluate()
51
+ def evaluate(msg: Message, context: Context):
52
+ """Evaluate the model on local data."""
53
+
54
+ # Load the model and initialize it with the received weights
55
+ model = Net()
56
+ model.load_state_dict(msg.content["arrays"].to_torch_state_dict())
57
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
58
+ model.to(device)
59
+
60
+ # Load the data
61
+ partition_id = context.node_config["partition-id"]
62
+ num_partitions = context.node_config["num-partitions"]
63
+ _, valloader = load_data(partition_id, num_partitions)
64
+
65
+ # Call the evaluation function
66
+ eval_loss, eval_acc = test_fn(
67
+ model,
68
+ valloader,
69
+ device,
70
+ )
71
+
72
+ # Construct and return reply Message
73
+ metrics = {
74
+ "eval_loss": eval_loss,
75
+ "eval_acc": eval_acc,
76
+ "num-examples": len(valloader.dataset),
77
+ }
78
+ metric_record = MetricRecord(metrics)
79
+ content = RecordDict({"metrics": metric_record})
80
+ return Message(content=content, reply_to=msg)
@@ -0,0 +1,41 @@
1
+ """$project_name: A Flower / $framework_str app."""
2
+
3
+ import torch
4
+ from flwr.app import ArrayRecord, ConfigRecord, Context
5
+ from flwr.serverapp import Grid, ServerApp
6
+ from flwr.serverapp.strategy import FedAvg
7
+
8
+ from $import_name.task import Net
9
+
10
+ # Create ServerApp
11
+ app = ServerApp()
12
+
13
+
14
+ @app.main()
15
+ def main(grid: Grid, context: Context) -> None:
16
+ """Main entry point for the ServerApp."""
17
+
18
+ # Read run config
19
+ fraction_train: float = context.run_config["fraction-train"]
20
+ num_rounds: int = context.run_config["num-server-rounds"]
21
+ lr: float = context.run_config["lr"]
22
+
23
+ # Load global model
24
+ global_model = Net()
25
+ arrays = ArrayRecord(global_model.state_dict())
26
+
27
+ # Initialize FedAvg strategy
28
+ strategy = FedAvg(fraction_train=fraction_train)
29
+
30
+ # Start strategy, run FedAvg for `num_rounds`
31
+ result = strategy.start(
32
+ grid=grid,
33
+ initial_arrays=arrays,
34
+ train_config=ConfigRecord({"lr": lr}),
35
+ num_rounds=num_rounds,
36
+ )
37
+
38
+ # Save final model to disk
39
+ print("\nSaving final model to disk...")
40
+ state_dict = result.arrays.to_torch_state_dict()
41
+ torch.save(state_dict, "final_model.pt")