flwr 1.20.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 (423) hide show
  1. {flwr-1.20.0 → flwr-1.21.0}/PKG-INFO +4 -3
  2. {flwr-1.20.0 → flwr-1.21.0}/README.md +3 -2
  3. {flwr-1.20.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.20.0 → flwr-1.21.0}/py/flwr/cli/auth_plugin/oidc_cli_plugin.py +4 -4
  7. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/cli_user_auth_interceptor.py +1 -1
  8. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/config_utils.py +3 -3
  9. flwr-1.21.0/py/flwr/cli/constant.py +44 -0
  10. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/log.py +9 -9
  11. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/login/login.py +3 -3
  12. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/ls.py +5 -5
  13. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/new.py +11 -0
  14. flwr-1.21.0/py/flwr/cli/new/templates/app/code/__init__.pytorch_msg_api.py.tpl +1 -0
  15. flwr-1.21.0/py/flwr/cli/new/templates/app/code/client.pytorch_msg_api.py.tpl +80 -0
  16. flwr-1.21.0/py/flwr/cli/new/templates/app/code/server.pytorch_msg_api.py.tpl +41 -0
  17. flwr-1.21.0/py/flwr/cli/new/templates/app/code/task.pytorch_msg_api.py.tpl +98 -0
  18. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +1 -1
  19. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +1 -1
  20. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +1 -1
  21. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl +1 -1
  22. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +1 -1
  23. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +1 -1
  24. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +1 -1
  25. flwr-1.21.0/py/flwr/cli/new/templates/app/pyproject.pytorch_msg_api.toml.tpl +53 -0
  26. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +1 -1
  27. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +1 -1
  28. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/run/run.py +9 -13
  29. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/stop.py +7 -4
  30. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/utils.py +19 -8
  31. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/grpc_rere_client/connection.py +1 -12
  32. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/rest_client/connection.py +3 -0
  33. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/clientapp/__init__.py +10 -0
  34. flwr-1.21.0/py/flwr/clientapp/mod/__init__.py +26 -0
  35. flwr-1.21.0/py/flwr/clientapp/mod/centraldp_mods.py +132 -0
  36. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/args.py +20 -6
  37. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/auth_plugin/__init__.py +4 -4
  38. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/auth_plugin/auth_plugin.py +7 -7
  39. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/constant.py +23 -4
  40. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/event_log_plugin/event_log_plugin.py +1 -1
  41. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/exit/__init__.py +4 -0
  42. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/exit/exit.py +8 -1
  43. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/exit/exit_code.py +26 -7
  44. flwr-1.21.0/py/flwr/common/exit/exit_handler.py +62 -0
  45. flwr-1.20.0/py/flwr/common/exit_handlers.py → flwr-1.21.0/py/flwr/common/exit/signal_handler.py +20 -37
  46. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/grpc.py +0 -11
  47. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/inflatable_utils.py +1 -1
  48. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/retry_invoker.py +30 -11
  49. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/telemetry.py +4 -0
  50. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/compat/server/app.py +2 -2
  51. flwr-1.21.0/py/flwr/proto/appio_pb2.py +51 -0
  52. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/appio_pb2.pyi +46 -2
  53. flwr-1.21.0/py/flwr/proto/clientappio_pb2.py +30 -0
  54. flwr-1.21.0/py/flwr/proto/clientappio_pb2.pyi +7 -0
  55. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/clientappio_pb2_grpc.py +19 -20
  56. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/clientappio_pb2_grpc.pyi +10 -11
  57. flwr-1.21.0/py/flwr/proto/control_pb2.py +62 -0
  58. flwr-1.20.0/py/flwr/proto/exec_pb2_grpc.py → flwr-1.21.0/py/flwr/proto/control_pb2_grpc.py +54 -54
  59. flwr-1.20.0/py/flwr/proto/exec_pb2_grpc.pyi → flwr-1.21.0/py/flwr/proto/control_pb2_grpc.pyi +28 -28
  60. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/serverappio_pb2.py +2 -2
  61. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/serverappio_pb2_grpc.py +68 -0
  62. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/serverappio_pb2_grpc.pyi +26 -0
  63. flwr-1.21.0/py/flwr/proto/simulationio_pb2.py +32 -0
  64. flwr-1.21.0/py/flwr/proto/simulationio_pb2.pyi +7 -0
  65. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/simulationio_pb2_grpc.py +129 -27
  66. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/simulationio_pb2_grpc.pyi +52 -13
  67. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/app.py +129 -152
  68. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/grid/grpc_grid.py +3 -0
  69. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/grid/inmemory_grid.py +1 -0
  70. flwr-1.21.0/py/flwr/server/serverapp/app.py +297 -0
  71. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +3 -1
  72. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/vce/vce_api.py +6 -6
  73. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/linkstate/in_memory_linkstate.py +34 -0
  74. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/linkstate/linkstate.py +2 -1
  75. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/linkstate/sqlite_linkstate.py +45 -0
  76. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/serverappio/serverappio_grpc.py +1 -1
  77. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/serverappio/serverappio_servicer.py +61 -6
  78. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/simulation/simulationio_servicer.py +97 -21
  79. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/serverapp/__init__.py +12 -0
  80. flwr-1.21.0/py/flwr/serverapp/dp_fixed_clipping.py +352 -0
  81. flwr-1.21.0/py/flwr/serverapp/exception.py +38 -0
  82. flwr-1.21.0/py/flwr/serverapp/strategy/__init__.py +38 -0
  83. flwr-1.21.0/py/flwr/serverapp/strategy/dp_fixed_clipping.py +352 -0
  84. flwr-1.21.0/py/flwr/serverapp/strategy/fedadagrad.py +162 -0
  85. flwr-1.21.0/py/flwr/serverapp/strategy/fedadam.py +181 -0
  86. flwr-1.21.0/py/flwr/serverapp/strategy/fedavg.py +295 -0
  87. flwr-1.21.0/py/flwr/serverapp/strategy/fedopt.py +218 -0
  88. flwr-1.21.0/py/flwr/serverapp/strategy/fedyogi.py +173 -0
  89. flwr-1.21.0/py/flwr/serverapp/strategy/result.py +105 -0
  90. flwr-1.21.0/py/flwr/serverapp/strategy/strategy.py +285 -0
  91. flwr-1.21.0/py/flwr/serverapp/strategy/strategy_utils.py +251 -0
  92. flwr-1.21.0/py/flwr/serverapp/strategy/strategy_utils_tests.py +304 -0
  93. flwr-1.21.0/py/flwr/simulation/app.py +303 -0
  94. flwr-1.21.0/py/flwr/supercore/app_utils.py +58 -0
  95. flwr-1.21.0/py/flwr/supercore/cli/__init__.py +22 -0
  96. flwr-1.21.0/py/flwr/supercore/cli/flower_superexec.py +141 -0
  97. {flwr-1.20.0/py/flwr/supercore/scheduler → flwr-1.21.0/py/flwr/supercore/corestate}/__init__.py +3 -3
  98. flwr-1.21.0/py/flwr/supercore/corestate/corestate.py +81 -0
  99. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supercore/grpc_health/__init__.py +3 -0
  100. flwr-1.21.0/py/flwr/supercore/grpc_health/health_server.py +53 -0
  101. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supercore/grpc_health/simple_health_servicer.py +2 -2
  102. flwr-1.21.0/py/flwr/supercore/superexec/__init__.py +15 -0
  103. flwr-1.21.0/py/flwr/supercore/superexec/plugin/__init__.py +28 -0
  104. flwr-1.20.0/py/flwr/supernode/scheduler/simple_clientapp_scheduler_plugin.py → flwr-1.21.0/py/flwr/supercore/superexec/plugin/base_exec_plugin.py +10 -6
  105. flwr-1.21.0/py/flwr/supercore/superexec/plugin/clientapp_exec_plugin.py +28 -0
  106. flwr-1.20.0/py/flwr/supercore/scheduler/plugin.py → flwr-1.21.0/py/flwr/supercore/superexec/plugin/exec_plugin.py +4 -4
  107. flwr-1.21.0/py/flwr/supercore/superexec/plugin/serverapp_exec_plugin.py +28 -0
  108. flwr-1.21.0/py/flwr/supercore/superexec/plugin/simulation_exec_plugin.py +28 -0
  109. flwr-1.21.0/py/flwr/supercore/superexec/run_superexec.py +185 -0
  110. {flwr-1.20.0/py/flwr/app → flwr-1.21.0/py/flwr/superlink/servicer}/__init__.py +1 -1
  111. flwr-1.21.0/py/flwr/superlink/servicer/control/__init__.py +22 -0
  112. flwr-1.20.0/py/flwr/superexec/exec_event_log_interceptor.py → flwr-1.21.0/py/flwr/superlink/servicer/control/control_event_log_interceptor.py +7 -7
  113. flwr-1.20.0/py/flwr/superexec/exec_grpc.py → flwr-1.21.0/py/flwr/superlink/servicer/control/control_grpc.py +24 -29
  114. flwr-1.20.0/py/flwr/superexec/exec_license_interceptor.py → flwr-1.21.0/py/flwr/superlink/servicer/control/control_license_interceptor.py +6 -6
  115. flwr-1.20.0/py/flwr/superexec/exec_servicer.py → flwr-1.21.0/py/flwr/superlink/servicer/control/control_servicer.py +69 -30
  116. flwr-1.20.0/py/flwr/superexec/exec_user_auth_interceptor.py → flwr-1.21.0/py/flwr/superlink/servicer/control/control_user_auth_interceptor.py +10 -10
  117. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supernode/cli/flower_supernode.py +3 -0
  118. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supernode/cli/flwr_clientapp.py +18 -21
  119. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supernode/nodestate/in_memory_nodestate.py +2 -2
  120. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supernode/nodestate/nodestate.py +3 -59
  121. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supernode/runtime/run_clientapp.py +39 -102
  122. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supernode/servicer/clientappio/clientappio_servicer.py +10 -17
  123. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supernode/start_client_internal.py +35 -76
  124. {flwr-1.20.0 → flwr-1.21.0}/pyproject.toml +3 -2
  125. flwr-1.20.0/py/flwr/cli/constant.py +0 -27
  126. flwr-1.20.0/py/flwr/proto/appio_pb2.py +0 -43
  127. flwr-1.20.0/py/flwr/proto/clientappio_pb2.py +0 -38
  128. flwr-1.20.0/py/flwr/proto/clientappio_pb2.pyi +0 -54
  129. flwr-1.20.0/py/flwr/proto/exec_pb2.py +0 -62
  130. flwr-1.20.0/py/flwr/proto/simulationio_pb2.py +0 -39
  131. flwr-1.20.0/py/flwr/proto/simulationio_pb2.pyi +0 -65
  132. flwr-1.20.0/py/flwr/server/serverapp/app.py +0 -286
  133. flwr-1.20.0/py/flwr/simulation/app.py +0 -306
  134. flwr-1.20.0/py/flwr/superexec/__init__.py +0 -15
  135. flwr-1.20.0/py/flwr/superexec/app.py +0 -45
  136. flwr-1.20.0/py/flwr/superexec/deployment.py +0 -191
  137. flwr-1.20.0/py/flwr/superexec/executor.py +0 -100
  138. flwr-1.20.0/py/flwr/superexec/simulation.py +0 -129
  139. flwr-1.20.0/py/flwr/supernode/scheduler/__init__.py +0 -22
  140. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/app/error.py +0 -0
  141. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/app/metadata.py +0 -0
  142. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/__init__.py +0 -0
  143. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/app.py +0 -0
  144. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/auth_plugin/__init__.py +0 -0
  145. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/build.py +0 -0
  146. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/example.py +0 -0
  147. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/install.py +0 -0
  148. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/login/__init__.py +0 -0
  149. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/__init__.py +0 -0
  150. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/__init__.py +0 -0
  151. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/.gitignore.tpl +0 -0
  152. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/LICENSE.tpl +0 -0
  153. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/README.baseline.md.tpl +0 -0
  154. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/README.flowertune.md.tpl +0 -0
  155. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/README.md.tpl +0 -0
  156. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/__init__.py +0 -0
  157. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/__init__.baseline.py.tpl +0 -0
  158. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
  159. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
  160. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.baseline.py.tpl +0 -0
  161. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.huggingface.py.tpl +0 -0
  162. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.jax.py.tpl +0 -0
  163. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.mlx.py.tpl +0 -0
  164. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
  165. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -0
  166. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.sklearn.py.tpl +0 -0
  167. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -0
  168. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/dataset.baseline.py.tpl +0 -0
  169. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py +0 -0
  170. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +0 -0
  171. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +0 -0
  172. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +0 -0
  173. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +0 -0
  174. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +0 -0
  175. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/model.baseline.py.tpl +0 -0
  176. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.baseline.py.tpl +0 -0
  177. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.huggingface.py.tpl +0 -0
  178. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.jax.py.tpl +0 -0
  179. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.mlx.py.tpl +0 -0
  180. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
  181. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -0
  182. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.sklearn.py.tpl +0 -0
  183. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -0
  184. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/strategy.baseline.py.tpl +0 -0
  185. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/task.huggingface.py.tpl +0 -0
  186. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/task.jax.py.tpl +0 -0
  187. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/task.mlx.py.tpl +0 -0
  188. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/task.numpy.py.tpl +0 -0
  189. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
  190. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/task.sklearn.py.tpl +0 -0
  191. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +0 -0
  192. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/new/templates/app/code/utils.baseline.py.tpl +0 -0
  193. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/cli/run/__init__.py +0 -0
  194. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/__init__.py +0 -0
  195. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/client.py +0 -0
  196. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/client_app.py +0 -0
  197. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/clientapp/__init__.py +0 -0
  198. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/clientapp/utils.py +0 -0
  199. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/dpfedavg_numpy_client.py +0 -0
  200. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/grpc_adapter_client/__init__.py +0 -0
  201. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/grpc_adapter_client/connection.py +0 -0
  202. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/grpc_rere_client/__init__.py +0 -0
  203. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/grpc_rere_client/client_interceptor.py +0 -0
  204. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/grpc_rere_client/grpc_adapter.py +0 -0
  205. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/message_handler/__init__.py +0 -0
  206. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/message_handler/message_handler.py +0 -0
  207. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/mod/__init__.py +0 -0
  208. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/mod/centraldp_mods.py +0 -0
  209. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/mod/comms_mods.py +0 -0
  210. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/mod/localdp_mod.py +0 -0
  211. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
  212. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
  213. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
  214. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/mod/utils.py +0 -0
  215. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/numpy_client.py +0 -0
  216. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/rest_client/__init__.py +0 -0
  217. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/run_info_store.py +0 -0
  218. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/client/typing.py +0 -0
  219. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/__init__.py +0 -0
  220. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/address.py +0 -0
  221. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/config.py +0 -0
  222. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/context.py +0 -0
  223. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/date.py +0 -0
  224. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/differential_privacy.py +0 -0
  225. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/differential_privacy_constants.py +0 -0
  226. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/dp.py +0 -0
  227. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/event_log_plugin/__init__.py +0 -0
  228. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/heartbeat.py +0 -0
  229. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/inflatable.py +0 -0
  230. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/inflatable_protobuf_utils.py +0 -0
  231. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/logger.py +1 -1
  232. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/message.py +0 -0
  233. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/object_ref.py +0 -0
  234. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/parameter.py +0 -0
  235. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/pyproject.py +0 -0
  236. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/record/__init__.py +0 -0
  237. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/record/array.py +0 -0
  238. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/record/arraychunk.py +0 -0
  239. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/record/arrayrecord.py +0 -0
  240. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/record/configrecord.py +0 -0
  241. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/record/conversion_utils.py +0 -0
  242. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/record/metricrecord.py +0 -0
  243. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/record/recorddict.py +0 -0
  244. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/record/typeddict.py +0 -0
  245. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/recorddict_compat.py +0 -0
  246. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/__init__.py +0 -0
  247. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
  248. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
  249. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
  250. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
  251. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/quantization.py +0 -0
  252. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
  253. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
  254. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/serde.py +0 -0
  255. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/serde_utils.py +0 -0
  256. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/typing.py +0 -0
  257. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/common/version.py +0 -0
  258. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/compat/__init__.py +0 -0
  259. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/compat/client/__init__.py +0 -0
  260. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/compat/client/app.py +0 -0
  261. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/compat/client/grpc_client/__init__.py +0 -0
  262. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/compat/client/grpc_client/connection.py +0 -0
  263. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/compat/common/__init__.py +0 -0
  264. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/compat/server/__init__.py +0 -0
  265. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/compat/simulation/__init__.py +0 -0
  266. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/__init__.py +0 -0
  267. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/appio_pb2_grpc.py +0 -0
  268. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/appio_pb2_grpc.pyi +0 -0
  269. /flwr-1.20.0/py/flwr/proto/exec_pb2.pyi → /flwr-1.21.0/py/flwr/proto/control_pb2.pyi +0 -0
  270. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/error_pb2.py +0 -0
  271. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/error_pb2.pyi +0 -0
  272. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/error_pb2_grpc.py +0 -0
  273. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/error_pb2_grpc.pyi +0 -0
  274. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/fab_pb2.py +0 -0
  275. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/fab_pb2.pyi +0 -0
  276. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/fab_pb2_grpc.py +0 -0
  277. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/fab_pb2_grpc.pyi +0 -0
  278. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/fleet_pb2.py +0 -0
  279. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/fleet_pb2.pyi +0 -0
  280. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/fleet_pb2_grpc.py +0 -0
  281. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
  282. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/grpcadapter_pb2.py +0 -0
  283. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/grpcadapter_pb2.pyi +0 -0
  284. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/grpcadapter_pb2_grpc.py +0 -0
  285. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/grpcadapter_pb2_grpc.pyi +0 -0
  286. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/heartbeat_pb2.py +0 -0
  287. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/heartbeat_pb2.pyi +0 -0
  288. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/heartbeat_pb2_grpc.py +0 -0
  289. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/heartbeat_pb2_grpc.pyi +0 -0
  290. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/log_pb2.py +0 -0
  291. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/log_pb2.pyi +0 -0
  292. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/log_pb2_grpc.py +0 -0
  293. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/log_pb2_grpc.pyi +0 -0
  294. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/message_pb2.py +0 -0
  295. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/message_pb2.pyi +0 -0
  296. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/message_pb2_grpc.py +0 -0
  297. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/message_pb2_grpc.pyi +0 -0
  298. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/node_pb2.py +0 -0
  299. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/node_pb2.pyi +0 -0
  300. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/node_pb2_grpc.py +0 -0
  301. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/node_pb2_grpc.pyi +0 -0
  302. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/recorddict_pb2.py +0 -0
  303. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/recorddict_pb2.pyi +0 -0
  304. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/recorddict_pb2_grpc.py +0 -0
  305. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/recorddict_pb2_grpc.pyi +0 -0
  306. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/run_pb2.py +0 -0
  307. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/run_pb2.pyi +0 -0
  308. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/run_pb2_grpc.py +0 -0
  309. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/run_pb2_grpc.pyi +0 -0
  310. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/serverappio_pb2.pyi +0 -0
  311. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/transport_pb2.py +0 -0
  312. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/transport_pb2.pyi +0 -0
  313. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/transport_pb2_grpc.py +0 -0
  314. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
  315. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/py.typed +0 -0
  316. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/__init__.py +0 -0
  317. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/client_manager.py +0 -0
  318. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/client_proxy.py +0 -0
  319. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/compat/__init__.py +0 -0
  320. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/compat/app.py +0 -0
  321. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/compat/app_utils.py +0 -0
  322. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/compat/grid_client_proxy.py +0 -0
  323. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/compat/legacy_context.py +0 -0
  324. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/criterion.py +0 -0
  325. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/fleet_event_log_interceptor.py +0 -0
  326. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/grid/__init__.py +0 -0
  327. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/grid/grid.py +0 -0
  328. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/history.py +0 -0
  329. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/run_serverapp.py +0 -0
  330. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/server.py +0 -0
  331. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/server_app.py +0 -0
  332. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/server_config.py +0 -0
  333. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/serverapp/__init__.py +0 -0
  334. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/serverapp_components.py +0 -0
  335. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/__init__.py +0 -0
  336. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/aggregate.py +0 -0
  337. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/bulyan.py +0 -0
  338. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
  339. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
  340. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
  341. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
  342. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
  343. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/fedadagrad.py +0 -0
  344. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/fedadam.py +0 -0
  345. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/fedavg.py +0 -0
  346. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/fedavg_android.py +0 -0
  347. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/fedavgm.py +0 -0
  348. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/fedmedian.py +0 -0
  349. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/fedopt.py +0 -0
  350. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/fedprox.py +0 -0
  351. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
  352. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
  353. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
  354. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
  355. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/fedyogi.py +0 -0
  356. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/krum.py +0 -0
  357. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/qfedavg.py +0 -0
  358. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/strategy/strategy.py +0 -0
  359. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/__init__.py +0 -0
  360. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/__init__.py +0 -0
  361. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py +0 -0
  362. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +0 -0
  363. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
  364. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
  365. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
  366. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
  367. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
  368. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
  369. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +0 -0
  370. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +0 -0
  371. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
  372. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/message_handler/message_handler.py +0 -0
  373. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
  374. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +0 -0
  375. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
  376. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
  377. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
  378. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/linkstate/__init__.py +0 -0
  379. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/linkstate/linkstate_factory.py +0 -0
  380. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/linkstate/utils.py +0 -0
  381. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/serverappio/__init__.py +0 -0
  382. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/simulation/__init__.py +0 -0
  383. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/simulation/simulationio_grpc.py +0 -0
  384. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/superlink/utils.py +0 -0
  385. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/typing.py +0 -0
  386. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/utils/__init__.py +0 -0
  387. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/utils/tensorboard.py +0 -0
  388. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/utils/validator.py +0 -0
  389. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/workflow/__init__.py +0 -0
  390. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/workflow/constant.py +0 -0
  391. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/workflow/default_workflows.py +0 -0
  392. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
  393. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
  394. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
  395. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/simulation/__init__.py +0 -0
  396. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/simulation/legacy_app.py +0 -0
  397. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/simulation/ray_transport/__init__.py +0 -0
  398. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
  399. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
  400. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/simulation/ray_transport/utils.py +0 -0
  401. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/simulation/run_simulation.py +0 -0
  402. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/simulation/simulationio_connection.py +0 -0
  403. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supercore/__init__.py +0 -0
  404. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supercore/ffs/__init__.py +0 -0
  405. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supercore/ffs/disk_ffs.py +0 -0
  406. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supercore/ffs/ffs.py +0 -0
  407. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supercore/ffs/ffs_factory.py +0 -0
  408. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supercore/license_plugin/__init__.py +0 -0
  409. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supercore/license_plugin/license_plugin.py +0 -0
  410. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supercore/object_store/__init__.py +0 -0
  411. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supercore/object_store/in_memory_object_store.py +0 -0
  412. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supercore/object_store/object_store.py +0 -0
  413. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supercore/object_store/object_store_factory.py +0 -0
  414. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supercore/object_store/utils.py +0 -0
  415. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supercore/utils.py +0 -0
  416. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/superlink/__init__.py +0 -0
  417. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supernode/__init__.py +0 -0
  418. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supernode/cli/__init__.py +0 -0
  419. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supernode/nodestate/__init__.py +0 -0
  420. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supernode/nodestate/nodestate_factory.py +0 -0
  421. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supernode/runtime/__init__.py +0 -0
  422. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supernode/servicer/__init__.py +0 -0
  423. {flwr-1.20.0 → flwr-1.21.0}/py/flwr/supernode/servicer/clientappio/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: flwr
3
- Version: 1.20.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
@@ -172,8 +172,9 @@ Flower Baselines is a collection of community-contributed projects that reproduc
172
172
  - [FedOpt](https://github.com/adap/flower/tree/main/baselines/flwr_baselines/flwr_baselines/publications/adaptive_federated_optimization)
173
173
 
174
174
  Please refer to the [Flower Baselines Documentation](https://flower.ai/docs/baselines/) for a detailed categorization of baselines and for additional info including:
175
- * [How to use Flower Baselines](https://flower.ai/docs/baselines/how-to-use-baselines.html)
176
- * [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)
177
178
 
178
179
  ## Flower Usage Examples
179
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
 
@@ -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__"]:
@@ -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")
@@ -0,0 +1,98 @@
1
+ """$project_name: A Flower / $framework_str app."""
2
+
3
+ import torch
4
+ import torch.nn as nn
5
+ import torch.nn.functional as F
6
+ from flwr_datasets import FederatedDataset
7
+ from flwr_datasets.partitioner import IidPartitioner
8
+ from torch.utils.data import DataLoader
9
+ from torchvision.transforms import Compose, Normalize, ToTensor
10
+
11
+
12
+ class Net(nn.Module):
13
+ """Model (simple CNN adapted from 'PyTorch: A 60 Minute Blitz')"""
14
+
15
+ def __init__(self):
16
+ super(Net, self).__init__()
17
+ self.conv1 = nn.Conv2d(3, 6, 5)
18
+ self.pool = nn.MaxPool2d(2, 2)
19
+ self.conv2 = nn.Conv2d(6, 16, 5)
20
+ self.fc1 = nn.Linear(16 * 5 * 5, 120)
21
+ self.fc2 = nn.Linear(120, 84)
22
+ self.fc3 = nn.Linear(84, 10)
23
+
24
+ def forward(self, x):
25
+ x = self.pool(F.relu(self.conv1(x)))
26
+ x = self.pool(F.relu(self.conv2(x)))
27
+ x = x.view(-1, 16 * 5 * 5)
28
+ x = F.relu(self.fc1(x))
29
+ x = F.relu(self.fc2(x))
30
+ return self.fc3(x)
31
+
32
+
33
+ fds = None # Cache FederatedDataset
34
+
35
+ pytorch_transforms = Compose([ToTensor(), Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
36
+
37
+
38
+ def apply_transforms(batch):
39
+ """Apply transforms to the partition from FederatedDataset."""
40
+ batch["img"] = [pytorch_transforms(img) for img in batch["img"]]
41
+ return batch
42
+
43
+
44
+ def load_data(partition_id: int, num_partitions: int):
45
+ """Load partition CIFAR10 data."""
46
+ # Only initialize `FederatedDataset` once
47
+ global fds
48
+ if fds is None:
49
+ partitioner = IidPartitioner(num_partitions=num_partitions)
50
+ fds = FederatedDataset(
51
+ dataset="uoft-cs/cifar10",
52
+ partitioners={"train": partitioner},
53
+ )
54
+ partition = fds.load_partition(partition_id)
55
+ # Divide data on each node: 80% train, 20% test
56
+ partition_train_test = partition.train_test_split(test_size=0.2, seed=42)
57
+ # Construct dataloaders
58
+ partition_train_test = partition_train_test.with_transform(apply_transforms)
59
+ trainloader = DataLoader(partition_train_test["train"], batch_size=32, shuffle=True)
60
+ testloader = DataLoader(partition_train_test["test"], batch_size=32)
61
+ return trainloader, testloader
62
+
63
+
64
+ def train(net, trainloader, epochs, lr, device):
65
+ """Train the model on the training set."""
66
+ net.to(device) # move model to GPU if available
67
+ criterion = torch.nn.CrossEntropyLoss().to(device)
68
+ optimizer = torch.optim.Adam(net.parameters(), lr=lr)
69
+ net.train()
70
+ running_loss = 0.0
71
+ for _ in range(epochs):
72
+ for batch in trainloader:
73
+ images = batch["img"].to(device)
74
+ labels = batch["label"].to(device)
75
+ optimizer.zero_grad()
76
+ loss = criterion(net(images), labels)
77
+ loss.backward()
78
+ optimizer.step()
79
+ running_loss += loss.item()
80
+ avg_trainloss = running_loss / len(trainloader)
81
+ return avg_trainloss
82
+
83
+
84
+ def test(net, testloader, device):
85
+ """Validate the model on the test set."""
86
+ net.to(device)
87
+ criterion = torch.nn.CrossEntropyLoss()
88
+ correct, loss = 0, 0.0
89
+ with torch.no_grad():
90
+ for batch in testloader:
91
+ images = batch["img"].to(device)
92
+ labels = batch["label"].to(device)
93
+ outputs = net(images)
94
+ loss += criterion(outputs, labels).item()
95
+ correct += (torch.max(outputs.data, 1)[1] == labels).sum().item()
96
+ accuracy = correct / len(testloader.dataset)
97
+ loss = loss / len(testloader)
98
+ return loss, accuracy
@@ -14,7 +14,7 @@ description = ""
14
14
  license = "Apache-2.0"
15
15
  # Dependencies for your Flower App
16
16
  dependencies = [
17
- "flwr[simulation]>=1.20.0",
17
+ "flwr[simulation]>=1.21.0",
18
18
  "flwr-datasets[vision]>=0.5.0",
19
19
  "torch==2.7.1",
20
20
  "torchvision==0.22.1",
@@ -14,7 +14,7 @@ description = ""
14
14
  license = "Apache-2.0"
15
15
  # Dependencies for your Flower App
16
16
  dependencies = [
17
- "flwr[simulation]>=1.20.0",
17
+ "flwr[simulation]>=1.21.0",
18
18
  "flwr-datasets>=0.5.0",
19
19
  "torch==2.4.0",
20
20
  "trl==0.8.1",
@@ -14,7 +14,7 @@ description = ""
14
14
  license = "Apache-2.0"
15
15
  # Dependencies for your Flower App
16
16
  dependencies = [
17
- "flwr[simulation]>=1.20.0",
17
+ "flwr[simulation]>=1.21.0",
18
18
  "flwr-datasets>=0.5.0",
19
19
  "torch==2.7.1",
20
20
  "transformers>=4.30.0,<5.0",
@@ -14,7 +14,7 @@ description = ""
14
14
  license = "Apache-2.0"
15
15
  # Dependencies for your Flower App
16
16
  dependencies = [
17
- "flwr[simulation]>=1.20.0",
17
+ "flwr[simulation]>=1.21.0",
18
18
  "jax==0.4.30",
19
19
  "jaxlib==0.4.30",
20
20
  "scikit-learn==1.6.1",