flwr-nightly 1.14.0.dev20241209__tar.gz → 1.14.0.dev20241210__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of flwr-nightly might be problematic. Click here for more details.

Files changed (323) hide show
  1. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/PKG-INFO +3 -2
  2. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/pyproject.toml +5 -4
  3. flwr_nightly-1.14.0.dev20241210/src/py/flwr/common/auth_plugin/__init__.py +24 -0
  4. flwr_nightly-1.14.0.dev20241210/src/py/flwr/common/auth_plugin/auth_plugin.py +111 -0
  5. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/constant.py +2 -0
  6. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/app.py +52 -1
  7. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/superexec/exec_grpc.py +18 -1
  8. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/superexec/exec_servicer.py +22 -3
  9. flwr_nightly-1.14.0.dev20241210/src/py/flwr/superexec/exec_user_auth_interceptor.py +101 -0
  10. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/LICENSE +0 -0
  11. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/README.md +0 -0
  12. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/__init__.py +0 -0
  13. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/__init__.py +0 -0
  14. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/app.py +0 -0
  15. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/build.py +0 -0
  16. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/config_utils.py +0 -0
  17. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/example.py +0 -0
  18. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/install.py +0 -0
  19. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/log.py +0 -0
  20. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/ls.py +0 -0
  21. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/__init__.py +0 -0
  22. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/new.py +0 -0
  23. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/__init__.py +0 -0
  24. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/.gitignore.tpl +0 -0
  25. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/LICENSE.tpl +0 -0
  26. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/README.baseline.md.tpl +0 -0
  27. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/README.flowertune.md.tpl +0 -0
  28. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/README.md.tpl +0 -0
  29. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/__init__.py +0 -0
  30. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/__init__.baseline.py.tpl +0 -0
  31. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
  32. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
  33. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/client.baseline.py.tpl +0 -0
  34. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/client.huggingface.py.tpl +0 -0
  35. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/client.jax.py.tpl +0 -0
  36. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/client.mlx.py.tpl +0 -0
  37. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
  38. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -0
  39. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/client.sklearn.py.tpl +0 -0
  40. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -0
  41. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/dataset.baseline.py.tpl +0 -0
  42. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py +0 -0
  43. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +0 -0
  44. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +0 -0
  45. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +0 -0
  46. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +0 -0
  47. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +0 -0
  48. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/model.baseline.py.tpl +0 -0
  49. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/server.baseline.py.tpl +0 -0
  50. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/server.huggingface.py.tpl +0 -0
  51. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/server.jax.py.tpl +0 -0
  52. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/server.mlx.py.tpl +0 -0
  53. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
  54. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -0
  55. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/server.sklearn.py.tpl +0 -0
  56. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -0
  57. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/strategy.baseline.py.tpl +0 -0
  58. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/task.huggingface.py.tpl +0 -0
  59. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/task.jax.py.tpl +0 -0
  60. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/task.mlx.py.tpl +0 -0
  61. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/task.numpy.py.tpl +0 -0
  62. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
  63. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/task.sklearn.py.tpl +0 -0
  64. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +0 -0
  65. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/code/utils.baseline.py.tpl +0 -0
  66. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +0 -0
  67. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +0 -0
  68. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +0 -0
  69. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl +0 -0
  70. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +0 -0
  71. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +0 -0
  72. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +0 -0
  73. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +0 -0
  74. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +0 -0
  75. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/run/__init__.py +0 -0
  76. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/run/run.py +0 -0
  77. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/stop.py +0 -0
  78. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/cli/utils.py +0 -0
  79. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/__init__.py +0 -0
  80. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/app.py +0 -0
  81. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/client.py +0 -0
  82. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/client_app.py +0 -0
  83. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/clientapp/__init__.py +0 -0
  84. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/clientapp/app.py +0 -0
  85. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/clientapp/clientappio_servicer.py +0 -0
  86. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/clientapp/utils.py +0 -0
  87. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/dpfedavg_numpy_client.py +0 -0
  88. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/grpc_adapter_client/__init__.py +0 -0
  89. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/grpc_adapter_client/connection.py +0 -0
  90. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/grpc_client/__init__.py +0 -0
  91. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/grpc_client/connection.py +0 -0
  92. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/grpc_rere_client/__init__.py +0 -0
  93. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/grpc_rere_client/client_interceptor.py +0 -0
  94. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/grpc_rere_client/connection.py +0 -0
  95. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/grpc_rere_client/grpc_adapter.py +0 -0
  96. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/heartbeat.py +0 -0
  97. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/message_handler/__init__.py +0 -0
  98. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/message_handler/message_handler.py +0 -0
  99. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/message_handler/task_handler.py +0 -0
  100. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/mod/__init__.py +0 -0
  101. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/mod/centraldp_mods.py +0 -0
  102. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/mod/comms_mods.py +0 -0
  103. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/mod/localdp_mod.py +0 -0
  104. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
  105. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
  106. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
  107. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/mod/utils.py +0 -0
  108. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/nodestate/__init__.py +0 -0
  109. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/nodestate/in_memory_nodestate.py +0 -0
  110. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/nodestate/nodestate.py +0 -0
  111. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/nodestate/nodestate_factory.py +0 -0
  112. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/numpy_client.py +0 -0
  113. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/rest_client/__init__.py +0 -0
  114. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/rest_client/connection.py +0 -0
  115. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/run_info_store.py +0 -0
  116. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/supernode/__init__.py +0 -0
  117. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/supernode/app.py +0 -0
  118. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/client/typing.py +0 -0
  119. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/__init__.py +0 -0
  120. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/address.py +0 -0
  121. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/args.py +0 -0
  122. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/config.py +0 -0
  123. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/context.py +0 -0
  124. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/date.py +0 -0
  125. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/differential_privacy.py +0 -0
  126. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/differential_privacy_constants.py +0 -0
  127. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/dp.py +0 -0
  128. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/exit_handlers.py +0 -0
  129. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/grpc.py +0 -0
  130. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/logger.py +0 -0
  131. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/message.py +0 -0
  132. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/object_ref.py +0 -0
  133. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/parameter.py +0 -0
  134. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/pyproject.py +0 -0
  135. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/record/__init__.py +0 -0
  136. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/record/configsrecord.py +0 -0
  137. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/record/conversion_utils.py +0 -0
  138. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/record/metricsrecord.py +0 -0
  139. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/record/parametersrecord.py +0 -0
  140. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/record/recordset.py +0 -0
  141. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/record/typeddict.py +0 -0
  142. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/recordset_compat.py +0 -0
  143. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/retry_invoker.py +0 -0
  144. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/secure_aggregation/__init__.py +0 -0
  145. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
  146. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
  147. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
  148. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
  149. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/secure_aggregation/quantization.py +0 -0
  150. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
  151. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
  152. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/serde.py +0 -0
  153. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/telemetry.py +0 -0
  154. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/typing.py +0 -0
  155. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/common/version.py +0 -0
  156. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/__init__.py +0 -0
  157. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/clientappio_pb2.py +0 -0
  158. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/clientappio_pb2.pyi +0 -0
  159. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/clientappio_pb2_grpc.py +0 -0
  160. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/clientappio_pb2_grpc.pyi +0 -0
  161. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/error_pb2.py +0 -0
  162. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/error_pb2.pyi +0 -0
  163. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/error_pb2_grpc.py +0 -0
  164. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/error_pb2_grpc.pyi +0 -0
  165. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/exec_pb2.py +0 -0
  166. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/exec_pb2.pyi +0 -0
  167. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/exec_pb2_grpc.py +0 -0
  168. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/exec_pb2_grpc.pyi +0 -0
  169. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/fab_pb2.py +0 -0
  170. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/fab_pb2.pyi +0 -0
  171. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/fab_pb2_grpc.py +0 -0
  172. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/fab_pb2_grpc.pyi +0 -0
  173. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/fleet_pb2.py +0 -0
  174. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/fleet_pb2.pyi +0 -0
  175. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/fleet_pb2_grpc.py +0 -0
  176. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
  177. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/grpcadapter_pb2.py +0 -0
  178. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/grpcadapter_pb2.pyi +0 -0
  179. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/grpcadapter_pb2_grpc.py +0 -0
  180. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/grpcadapter_pb2_grpc.pyi +0 -0
  181. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/log_pb2.py +0 -0
  182. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/log_pb2.pyi +0 -0
  183. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/log_pb2_grpc.py +0 -0
  184. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/log_pb2_grpc.pyi +0 -0
  185. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/message_pb2.py +0 -0
  186. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/message_pb2.pyi +0 -0
  187. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/message_pb2_grpc.py +0 -0
  188. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/message_pb2_grpc.pyi +0 -0
  189. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/node_pb2.py +0 -0
  190. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/node_pb2.pyi +0 -0
  191. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/node_pb2_grpc.py +0 -0
  192. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/node_pb2_grpc.pyi +0 -0
  193. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/recordset_pb2.py +0 -0
  194. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/recordset_pb2.pyi +0 -0
  195. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/recordset_pb2_grpc.py +0 -0
  196. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/recordset_pb2_grpc.pyi +0 -0
  197. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/run_pb2.py +0 -0
  198. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/run_pb2.pyi +0 -0
  199. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/run_pb2_grpc.py +0 -0
  200. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/run_pb2_grpc.pyi +0 -0
  201. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/serverappio_pb2.py +0 -0
  202. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/serverappio_pb2.pyi +0 -0
  203. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/serverappio_pb2_grpc.py +0 -0
  204. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/serverappio_pb2_grpc.pyi +0 -0
  205. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/simulationio_pb2.py +0 -0
  206. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/simulationio_pb2.pyi +0 -0
  207. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/simulationio_pb2_grpc.py +0 -0
  208. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/simulationio_pb2_grpc.pyi +0 -0
  209. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/task_pb2.py +0 -0
  210. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/task_pb2.pyi +0 -0
  211. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/task_pb2_grpc.py +0 -0
  212. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/task_pb2_grpc.pyi +0 -0
  213. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/transport_pb2.py +0 -0
  214. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/transport_pb2.pyi +0 -0
  215. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/transport_pb2_grpc.py +0 -0
  216. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
  217. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/py.typed +0 -0
  218. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/__init__.py +0 -0
  219. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/client_manager.py +0 -0
  220. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/client_proxy.py +0 -0
  221. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/compat/__init__.py +0 -0
  222. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/compat/app.py +0 -0
  223. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/compat/app_utils.py +0 -0
  224. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/compat/driver_client_proxy.py +0 -0
  225. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/compat/legacy_context.py +0 -0
  226. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/criterion.py +0 -0
  227. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/driver/__init__.py +0 -0
  228. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/driver/driver.py +0 -0
  229. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/driver/grpc_driver.py +0 -0
  230. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/driver/inmemory_driver.py +0 -0
  231. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/history.py +0 -0
  232. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/run_serverapp.py +0 -0
  233. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/server.py +0 -0
  234. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/server_app.py +0 -0
  235. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/server_config.py +0 -0
  236. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/serverapp/__init__.py +0 -0
  237. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/serverapp/app.py +0 -0
  238. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/serverapp_components.py +0 -0
  239. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/__init__.py +0 -0
  240. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/aggregate.py +0 -0
  241. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/bulyan.py +0 -0
  242. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
  243. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
  244. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
  245. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
  246. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
  247. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/fedadagrad.py +0 -0
  248. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/fedadam.py +0 -0
  249. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/fedavg.py +0 -0
  250. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/fedavg_android.py +0 -0
  251. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/fedavgm.py +0 -0
  252. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/fedmedian.py +0 -0
  253. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/fedopt.py +0 -0
  254. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/fedprox.py +0 -0
  255. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
  256. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
  257. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
  258. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
  259. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/fedyogi.py +0 -0
  260. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/krum.py +0 -0
  261. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/qfedavg.py +0 -0
  262. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/strategy/strategy.py +0 -0
  263. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/__init__.py +0 -0
  264. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/driver/__init__.py +0 -0
  265. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/driver/serverappio_grpc.py +0 -0
  266. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/driver/serverappio_servicer.py +0 -0
  267. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/ffs/__init__.py +0 -0
  268. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/ffs/disk_ffs.py +0 -0
  269. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/ffs/ffs.py +0 -0
  270. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/ffs/ffs_factory.py +0 -0
  271. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/__init__.py +0 -0
  272. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py +0 -0
  273. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +0 -0
  274. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
  275. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
  276. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
  277. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
  278. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
  279. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
  280. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +0 -0
  281. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +0 -0
  282. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
  283. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py +0 -0
  284. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
  285. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +0 -0
  286. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
  287. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
  288. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
  289. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +0 -0
  290. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/fleet/vce/vce_api.py +0 -0
  291. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/linkstate/__init__.py +0 -0
  292. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/linkstate/in_memory_linkstate.py +0 -0
  293. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/linkstate/linkstate.py +0 -0
  294. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/linkstate/linkstate_factory.py +0 -0
  295. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/linkstate/sqlite_linkstate.py +0 -0
  296. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/linkstate/utils.py +0 -0
  297. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/simulation/__init__.py +0 -0
  298. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/simulation/simulationio_grpc.py +0 -0
  299. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/superlink/simulation/simulationio_servicer.py +0 -0
  300. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/typing.py +0 -0
  301. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/utils/__init__.py +0 -0
  302. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/utils/tensorboard.py +0 -0
  303. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/utils/validator.py +0 -0
  304. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/workflow/__init__.py +0 -0
  305. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/workflow/constant.py +0 -0
  306. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/workflow/default_workflows.py +0 -0
  307. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
  308. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
  309. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
  310. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/simulation/__init__.py +0 -0
  311. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/simulation/app.py +0 -0
  312. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/simulation/legacy_app.py +0 -0
  313. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/simulation/ray_transport/__init__.py +0 -0
  314. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
  315. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
  316. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/simulation/ray_transport/utils.py +0 -0
  317. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/simulation/run_simulation.py +0 -0
  318. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/simulation/simulationio_connection.py +0 -0
  319. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/superexec/__init__.py +0 -0
  320. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/superexec/app.py +0 -0
  321. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/superexec/deployment.py +0 -0
  322. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/superexec/executor.py +0 -0
  323. {flwr_nightly-1.14.0.dev20241209 → flwr_nightly-1.14.0.dev20241210}/src/py/flwr/superexec/simulation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flwr-nightly
3
- Version: 1.14.0.dev20241209
3
+ Version: 1.14.0.dev20241210
4
4
  Summary: Flower: A Friendly Federated AI Framework
5
5
  Home-page: https://flower.ai
6
6
  License: Apache-2.0
@@ -39,8 +39,9 @@ Requires-Dist: numpy (>=1.26.0,<3.0.0)
39
39
  Requires-Dist: pathspec (>=0.12.1,<0.13.0)
40
40
  Requires-Dist: protobuf (>=4.25.2,<5.0.0)
41
41
  Requires-Dist: pycryptodome (>=3.18.0,<4.0.0)
42
+ Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
42
43
  Requires-Dist: ray (==2.10.0) ; (python_version >= "3.9" and python_version < "3.12") and (extra == "simulation")
43
- Requires-Dist: requests (>=2.31.0,<3.0.0) ; extra == "rest"
44
+ Requires-Dist: requests (>=2.31.0,<3.0.0)
44
45
  Requires-Dist: rich (>=13.5.0,<14.0.0)
45
46
  Requires-Dist: starlette (>=0.31.0,<0.32.0) ; extra == "rest"
46
47
  Requires-Dist: tomli (>=2.0.1,<3.0.0)
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "flwr-nightly"
7
- version = "1.14.0.dev20241209"
7
+ version = "1.14.0.dev20241210"
8
8
  description = "Flower: A Friendly Federated AI Framework"
9
9
  license = "Apache-2.0"
10
10
  authors = ["The Flower Authors <hello@flower.ai>"]
@@ -78,16 +78,16 @@ tomli = "^2.0.1"
78
78
  tomli-w = "^1.0.0"
79
79
  pathspec = "^0.12.1"
80
80
  rich = "^13.5.0"
81
+ pyyaml = "^6.0.2"
82
+ requests = "^2.31.0"
81
83
  # Optional dependencies (Simulation Engine)
82
84
  ray = { version = "==2.10.0", optional = true, python = ">=3.9,<3.12" }
83
- # Optional dependencies (REST transport layer)
84
- requests = { version = "^2.31.0", optional = true }
85
85
  starlette = { version = "^0.31.0", optional = true }
86
86
  uvicorn = { version = "^0.23.0", extras = ["standard"], optional = true }
87
87
 
88
88
  [tool.poetry.extras]
89
89
  simulation = ["ray"]
90
- rest = ["requests", "starlette", "uvicorn"]
90
+ rest = ["starlette", "uvicorn"]
91
91
 
92
92
  [tool.poetry.group.dev.dependencies]
93
93
  types-dataclasses = "==0.6.6"
@@ -131,6 +131,7 @@ mdformat-gfm = "==0.3.6"
131
131
  mdformat-frontmatter = "==2.0.1"
132
132
  mdformat-beautysh = "==0.1.1"
133
133
  twine = "==5.1.1"
134
+ types-PyYAML = "^6.0.2"
134
135
  pyroma = "==4.2"
135
136
  check-wheel-contents = "==0.4.0"
136
137
  GitPython = "==3.1.32"
@@ -0,0 +1,24 @@
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ # ==============================================================================
15
+ """Auth plugin components."""
16
+
17
+
18
+ from .auth_plugin import CliAuthPlugin as CliAuthPlugin
19
+ from .auth_plugin import ExecAuthPlugin as ExecAuthPlugin
20
+
21
+ __all__ = [
22
+ "CliAuthPlugin",
23
+ "ExecAuthPlugin",
24
+ ]
@@ -0,0 +1,111 @@
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ # ==============================================================================
15
+ """Abstract classes for Flower User Auth Plugin."""
16
+
17
+
18
+ from abc import ABC, abstractmethod
19
+ from collections.abc import Sequence
20
+ from pathlib import Path
21
+ from typing import Any, Optional, Union
22
+
23
+ from flwr.proto.exec_pb2_grpc import ExecStub
24
+
25
+
26
+ class ExecAuthPlugin(ABC):
27
+ """Abstract Flower Auth Plugin class for ExecServicer.
28
+
29
+ Parameters
30
+ ----------
31
+ config : dict[str, Any]
32
+ The authentication configuration loaded from a YAML file.
33
+ """
34
+
35
+ @abstractmethod
36
+ def __init__(self, config: dict[str, Any]):
37
+ """Abstract constructor."""
38
+
39
+ @abstractmethod
40
+ def get_login_details(self) -> dict[str, str]:
41
+ """Get the login details."""
42
+
43
+ @abstractmethod
44
+ def validate_tokens_in_metadata(
45
+ self, metadata: Sequence[tuple[str, Union[str, bytes]]]
46
+ ) -> bool:
47
+ """Validate authentication tokens in the provided metadata."""
48
+
49
+ @abstractmethod
50
+ def get_auth_tokens(self, auth_details: dict[str, str]) -> dict[str, str]:
51
+ """Get authentication tokens."""
52
+
53
+ @abstractmethod
54
+ def refresh_tokens(
55
+ self, metadata: Sequence[tuple[str, Union[str, bytes]]]
56
+ ) -> Optional[Sequence[tuple[str, Union[str, bytes]]]]:
57
+ """Refresh authentication tokens in the provided metadata."""
58
+
59
+
60
+ class CliAuthPlugin(ABC):
61
+ """Abstract Flower Auth Plugin class for CLI.
62
+
63
+ Parameters
64
+ ----------
65
+ user_auth_config_path : Path
66
+ The path to the user's authentication configuration file.
67
+ """
68
+
69
+ @staticmethod
70
+ @abstractmethod
71
+ def login(
72
+ login_details: dict[str, str],
73
+ exec_stub: ExecStub,
74
+ ) -> dict[str, Any]:
75
+ """Authenticate the user with the SuperLink.
76
+
77
+ Parameters
78
+ ----------
79
+ login_details : dict[str, str]
80
+ A dictionary containing the user's login details.
81
+ exec_stub : ExecStub
82
+ An instance of `ExecStub` used for communication with the SuperLink.
83
+
84
+ Returns
85
+ -------
86
+ user_auth_config : dict[str, Any]
87
+ A dictionary containing the user's authentication configuration
88
+ in JSON format.
89
+ """
90
+
91
+ @abstractmethod
92
+ def __init__(self, user_auth_config_path: Path):
93
+ """Abstract constructor."""
94
+
95
+ @abstractmethod
96
+ def store_tokens(self, user_auth_config: dict[str, Any]) -> None:
97
+ """Store authentication tokens from the provided user_auth_config.
98
+
99
+ The configuration, including tokens, will be saved as a JSON file
100
+ at `user_auth_config_path`.
101
+ """
102
+
103
+ @abstractmethod
104
+ def load_tokens(self) -> None:
105
+ """Load authentication tokens from the user_auth_config_path."""
106
+
107
+ @abstractmethod
108
+ def write_tokens_to_metadata(
109
+ self, metadata: Sequence[tuple[str, Union[str, bytes]]]
110
+ ) -> Sequence[tuple[str, Union[str, bytes]]]:
111
+ """Write authentication tokens to the provided metadata."""
@@ -110,6 +110,8 @@ LOG_UPLOAD_INTERVAL = 0.2 # Minimum interval between two log uploads
110
110
  # Retry configurations
111
111
  MAX_RETRY_DELAY = 20 # Maximum delay duration between two consecutive retries.
112
112
 
113
+ AUTH_TYPE = "auth_type"
114
+
113
115
 
114
116
  class MessageType:
115
117
  """Message type."""
@@ -24,9 +24,10 @@ from collections.abc import Sequence
24
24
  from logging import DEBUG, INFO, WARN
25
25
  from pathlib import Path
26
26
  from time import sleep
27
- from typing import Optional
27
+ from typing import Any, Optional
28
28
 
29
29
  import grpc
30
+ import yaml
30
31
  from cryptography.exceptions import UnsupportedAlgorithm
31
32
  from cryptography.hazmat.primitives.asymmetric import ec
32
33
  from cryptography.hazmat.primitives.serialization import (
@@ -37,8 +38,10 @@ from cryptography.hazmat.primitives.serialization import (
37
38
  from flwr.common import GRPC_MAX_MESSAGE_LENGTH, EventType, event
38
39
  from flwr.common.address import parse_address
39
40
  from flwr.common.args import try_obtain_server_certificates
41
+ from flwr.common.auth_plugin import ExecAuthPlugin
40
42
  from flwr.common.config import get_flwr_dir, parse_config_args
41
43
  from flwr.common.constant import (
44
+ AUTH_TYPE,
42
45
  CLIENT_OCTET,
43
46
  EXEC_API_DEFAULT_SERVER_ADDRESS,
44
47
  FLEET_API_GRPC_BIDI_DEFAULT_ADDRESS,
@@ -88,6 +91,15 @@ DATABASE = ":flwr-in-memory-state:"
88
91
  BASE_DIR = get_flwr_dir() / "superlink" / "ffs"
89
92
 
90
93
 
94
+ try:
95
+ from flwr.ee import get_exec_auth_plugins
96
+ except ImportError:
97
+
98
+ def get_exec_auth_plugins() -> dict[str, type[ExecAuthPlugin]]:
99
+ """Return all Exec API authentication plugins."""
100
+ raise NotImplementedError("No authentication plugins are currently supported.")
101
+
102
+
91
103
  def start_server( # pylint: disable=too-many-arguments,too-many-locals
92
104
  *,
93
105
  server_address: str = FLEET_API_GRPC_BIDI_DEFAULT_ADDRESS,
@@ -246,6 +258,12 @@ def run_superlink() -> None:
246
258
  # Obtain certificates
247
259
  certificates = try_obtain_server_certificates(args, args.fleet_api_type)
248
260
 
261
+ user_auth_config = _try_obtain_user_auth_config(args)
262
+ auth_plugin: Optional[ExecAuthPlugin] = None
263
+ # user_auth_config is None only if the args.user_auth_config is not provided
264
+ if user_auth_config is not None:
265
+ auth_plugin = _try_obtain_exec_auth_plugin(user_auth_config)
266
+
249
267
  # Initialize StateFactory
250
268
  state_factory = LinkStateFactory(args.database)
251
269
 
@@ -263,6 +281,7 @@ def run_superlink() -> None:
263
281
  config=parse_config_args(
264
282
  [args.executor_config] if args.executor_config else args.executor_config
265
283
  ),
284
+ auth_plugin=auth_plugin,
266
285
  )
267
286
  grpc_servers = [exec_server]
268
287
 
@@ -559,6 +578,32 @@ def _try_setup_node_authentication(
559
578
  )
560
579
 
561
580
 
581
+ def _try_obtain_user_auth_config(args: argparse.Namespace) -> Optional[dict[str, Any]]:
582
+ if args.user_auth_config is not None:
583
+ with open(args.user_auth_config, encoding="utf-8") as file:
584
+ config: dict[str, Any] = yaml.safe_load(file)
585
+ return config
586
+ return None
587
+
588
+
589
+ def _try_obtain_exec_auth_plugin(config: dict[str, Any]) -> Optional[ExecAuthPlugin]:
590
+ auth_config: dict[str, Any] = config.get("authentication", {})
591
+ auth_type: str = auth_config.get(AUTH_TYPE, "")
592
+ try:
593
+ all_plugins: dict[str, type[ExecAuthPlugin]] = get_exec_auth_plugins()
594
+ auth_plugin_class = all_plugins[auth_type]
595
+ return auth_plugin_class(config=auth_config)
596
+ except KeyError:
597
+ if auth_type != "":
598
+ sys.exit(
599
+ f'Authentication type "{auth_type}" is not supported. '
600
+ "Please provide a valid authentication type in the configuration."
601
+ )
602
+ sys.exit("No authentication type is provided in the configuration.")
603
+ except NotImplementedError:
604
+ sys.exit("No authentication plugins are currently supported.")
605
+
606
+
562
607
  def _run_fleet_api_grpc_rere(
563
608
  address: str,
564
609
  state_factory: LinkStateFactory,
@@ -746,6 +791,12 @@ def _add_args_common(parser: argparse.ArgumentParser) -> None:
746
791
  type=str,
747
792
  help="The SuperLink's public key (as a path str) to enable authentication.",
748
793
  )
794
+ parser.add_argument(
795
+ "--user-auth-config",
796
+ help="The path to the user authentication configuration YAML file.",
797
+ type=str,
798
+ default=None,
799
+ )
749
800
 
750
801
 
751
802
  def _add_args_serverappio_api(parser: argparse.ArgumentParser) -> None:
@@ -14,18 +14,21 @@
14
14
  # ==============================================================================
15
15
  """SuperExec gRPC API."""
16
16
 
17
+ from collections.abc import Sequence
17
18
  from logging import INFO
18
19
  from typing import Optional
19
20
 
20
21
  import grpc
21
22
 
22
23
  from flwr.common import GRPC_MAX_MESSAGE_LENGTH
24
+ from flwr.common.auth_plugin import ExecAuthPlugin
23
25
  from flwr.common.logger import log
24
26
  from flwr.common.typing import UserConfig
25
27
  from flwr.proto.exec_pb2_grpc import add_ExecServicer_to_server
26
28
  from flwr.server.superlink.ffs.ffs_factory import FfsFactory
27
29
  from flwr.server.superlink.fleet.grpc_bidi.grpc_server import generic_create_grpc_server
28
30
  from flwr.server.superlink.linkstate import LinkStateFactory
31
+ from flwr.superexec.exec_user_auth_interceptor import ExecUserAuthInterceptor
29
32
 
30
33
  from .exec_servicer import ExecServicer
31
34
  from .executor import Executor
@@ -39,6 +42,7 @@ def run_exec_api_grpc(
39
42
  ffs_factory: FfsFactory,
40
43
  certificates: Optional[tuple[bytes, bytes, bytes]],
41
44
  config: UserConfig,
45
+ auth_plugin: Optional[ExecAuthPlugin] = None,
42
46
  ) -> grpc.Server:
43
47
  """Run Exec API (gRPC, request-response)."""
44
48
  executor.set_config(config)
@@ -47,16 +51,29 @@ def run_exec_api_grpc(
47
51
  linkstate_factory=state_factory,
48
52
  ffs_factory=ffs_factory,
49
53
  executor=executor,
54
+ auth_plugin=auth_plugin,
50
55
  )
56
+ interceptors: Optional[Sequence[grpc.ServerInterceptor]] = None
57
+ if auth_plugin is not None:
58
+ interceptors = [ExecUserAuthInterceptor(auth_plugin)]
51
59
  exec_add_servicer_to_server_fn = add_ExecServicer_to_server
52
60
  exec_grpc_server = generic_create_grpc_server(
53
61
  servicer_and_add_fn=(exec_servicer, exec_add_servicer_to_server_fn),
54
62
  server_address=address,
55
63
  max_message_length=GRPC_MAX_MESSAGE_LENGTH,
56
64
  certificates=certificates,
65
+ interceptors=interceptors,
57
66
  )
58
67
 
59
- log(INFO, "Flower Deployment Engine: Starting Exec API on %s", address)
68
+ if auth_plugin is None:
69
+ log(INFO, "Flower Deployment Engine: Starting Exec API on %s", address)
70
+ else:
71
+ log(
72
+ INFO,
73
+ "Flower Deployment Engine: Starting Exec API with user "
74
+ "authentication on %s",
75
+ address,
76
+ )
60
77
  exec_grpc_server.start()
61
78
 
62
79
  return exec_grpc_server
@@ -18,11 +18,12 @@
18
18
  import time
19
19
  from collections.abc import Generator
20
20
  from logging import ERROR, INFO
21
- from typing import Any
21
+ from typing import Any, Optional
22
22
 
23
23
  import grpc
24
24
 
25
25
  from flwr.common import now
26
+ from flwr.common.auth_plugin import ExecAuthPlugin
26
27
  from flwr.common.constant import LOG_STREAM_INTERVAL, Status, SubStatus
27
28
  from flwr.common.logger import log
28
29
  from flwr.common.serde import (
@@ -60,11 +61,13 @@ class ExecServicer(exec_pb2_grpc.ExecServicer):
60
61
  linkstate_factory: LinkStateFactory,
61
62
  ffs_factory: FfsFactory,
62
63
  executor: Executor,
64
+ auth_plugin: Optional[ExecAuthPlugin] = None,
63
65
  ) -> None:
64
66
  self.linkstate_factory = linkstate_factory
65
67
  self.ffs_factory = ffs_factory
66
68
  self.executor = executor
67
69
  self.executor.initialize(linkstate_factory, ffs_factory)
70
+ self.auth_plugin = auth_plugin
68
71
 
69
72
  def StartRun(
70
73
  self, request: StartRunRequest, context: grpc.ServicerContext
@@ -164,14 +167,30 @@ class ExecServicer(exec_pb2_grpc.ExecServicer):
164
167
  ) -> GetLoginDetailsResponse:
165
168
  """Start login."""
166
169
  log(INFO, "ExecServicer.GetLoginDetails")
167
- return GetLoginDetailsResponse(login_details={})
170
+ if self.auth_plugin is None:
171
+ context.abort(
172
+ grpc.StatusCode.UNIMPLEMENTED,
173
+ "ExecServicer initialized without user authentication",
174
+ )
175
+ raise grpc.RpcError() # This line is unreachable
176
+ return GetLoginDetailsResponse(
177
+ login_details=self.auth_plugin.get_login_details()
178
+ )
168
179
 
169
180
  def GetAuthTokens(
170
181
  self, request: GetAuthTokensRequest, context: grpc.ServicerContext
171
182
  ) -> GetAuthTokensResponse:
172
183
  """Get auth token."""
173
184
  log(INFO, "ExecServicer.GetAuthTokens")
174
- return GetAuthTokensResponse(auth_tokens={})
185
+ if self.auth_plugin is None:
186
+ context.abort(
187
+ grpc.StatusCode.UNIMPLEMENTED,
188
+ "ExecServicer initialized without user authentication",
189
+ )
190
+ raise grpc.RpcError() # This line is unreachable
191
+ return GetAuthTokensResponse(
192
+ auth_tokens=self.auth_plugin.get_auth_tokens(dict(request.auth_details))
193
+ )
175
194
 
176
195
 
177
196
  def _create_list_runs_response(run_ids: set[int], state: LinkState) -> ListRunsResponse:
@@ -0,0 +1,101 @@
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ # ==============================================================================
15
+ """Flower Exec API interceptor."""
16
+
17
+
18
+ from typing import Any, Callable, Union
19
+
20
+ import grpc
21
+
22
+ from flwr.common.auth_plugin import ExecAuthPlugin
23
+ from flwr.proto.exec_pb2 import ( # pylint: disable=E0611
24
+ GetAuthTokensRequest,
25
+ GetAuthTokensResponse,
26
+ GetLoginDetailsRequest,
27
+ GetLoginDetailsResponse,
28
+ StartRunRequest,
29
+ StartRunResponse,
30
+ StreamLogsRequest,
31
+ StreamLogsResponse,
32
+ )
33
+
34
+ Request = Union[
35
+ StartRunRequest,
36
+ StreamLogsRequest,
37
+ GetLoginDetailsRequest,
38
+ GetAuthTokensRequest,
39
+ ]
40
+
41
+ Response = Union[
42
+ StartRunResponse, StreamLogsResponse, GetLoginDetailsResponse, GetAuthTokensResponse
43
+ ]
44
+
45
+
46
+ class ExecUserAuthInterceptor(grpc.ServerInterceptor): # type: ignore
47
+ """Exec API interceptor for user authentication."""
48
+
49
+ def __init__(
50
+ self,
51
+ auth_plugin: ExecAuthPlugin,
52
+ ):
53
+ self.auth_plugin = auth_plugin
54
+
55
+ def intercept_service(
56
+ self,
57
+ continuation: Callable[[Any], Any],
58
+ handler_call_details: grpc.HandlerCallDetails,
59
+ ) -> grpc.RpcMethodHandler:
60
+ """Flower server interceptor authentication logic.
61
+
62
+ Intercept all unary-unary/unary-stream calls from users and authenticate users
63
+ by validating auth metadata sent by the user. Continue RPC call if user is
64
+ authenticated, else, terminate RPC call by setting context to abort.
65
+ """
66
+ # One of the method handlers in
67
+ # `flwr.superexec.exec_servicer.ExecServicer`
68
+ method_handler: grpc.RpcMethodHandler = continuation(handler_call_details)
69
+ return self._generic_auth_unary_method_handler(method_handler)
70
+
71
+ def _generic_auth_unary_method_handler(
72
+ self, method_handler: grpc.RpcMethodHandler
73
+ ) -> grpc.RpcMethodHandler:
74
+ def _generic_method_handler(
75
+ request: Request,
76
+ context: grpc.ServicerContext,
77
+ ) -> Response:
78
+ call = method_handler.unary_unary or method_handler.unary_stream
79
+ metadata = context.invocation_metadata()
80
+ if isinstance(
81
+ request, (GetLoginDetailsRequest, GetAuthTokensRequest)
82
+ ) or self.auth_plugin.validate_tokens_in_metadata(metadata):
83
+ return call(request, context) # type: ignore
84
+
85
+ tokens = self.auth_plugin.refresh_tokens(context.invocation_metadata())
86
+ if tokens is not None:
87
+ context.send_initial_metadata(tokens)
88
+ return call(request, context) # type: ignore
89
+
90
+ context.abort(grpc.StatusCode.UNAUTHENTICATED, "Access denied")
91
+ raise grpc.RpcError() # This line is unreachable
92
+
93
+ if method_handler.unary_unary:
94
+ message_handler = grpc.unary_unary_rpc_method_handler
95
+ else:
96
+ message_handler = grpc.unary_stream_rpc_method_handler
97
+ return message_handler(
98
+ _generic_method_handler,
99
+ request_deserializer=method_handler.request_deserializer,
100
+ response_serializer=method_handler.response_serializer,
101
+ )