flwr 1.21.0__py3-none-any.whl → 1.23.0__py3-none-any.whl

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 (175) hide show
  1. flwr/cli/app.py +17 -1
  2. flwr/cli/auth_plugin/__init__.py +15 -6
  3. flwr/cli/auth_plugin/auth_plugin.py +95 -0
  4. flwr/cli/auth_plugin/noop_auth_plugin.py +58 -0
  5. flwr/cli/auth_plugin/oidc_cli_plugin.py +16 -25
  6. flwr/cli/build.py +118 -47
  7. flwr/cli/{cli_user_auth_interceptor.py → cli_account_auth_interceptor.py} +6 -5
  8. flwr/cli/log.py +2 -2
  9. flwr/cli/login/login.py +34 -23
  10. flwr/cli/ls.py +13 -9
  11. flwr/cli/new/new.py +196 -42
  12. flwr/cli/new/templates/app/README.flowertune.md.tpl +1 -1
  13. flwr/cli/new/templates/app/code/client.baseline.py.tpl +64 -47
  14. flwr/cli/new/templates/app/code/client.huggingface.py.tpl +68 -30
  15. flwr/cli/new/templates/app/code/client.jax.py.tpl +63 -42
  16. flwr/cli/new/templates/app/code/client.mlx.py.tpl +80 -51
  17. flwr/cli/new/templates/app/code/client.numpy.py.tpl +36 -13
  18. flwr/cli/new/templates/app/code/client.pytorch.py.tpl +71 -46
  19. flwr/cli/new/templates/app/code/client.pytorch_legacy_api.py.tpl +55 -0
  20. flwr/cli/new/templates/app/code/client.sklearn.py.tpl +75 -30
  21. flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +69 -44
  22. flwr/cli/new/templates/app/code/client.xgboost.py.tpl +110 -0
  23. flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +56 -90
  24. flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +1 -23
  25. flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +37 -58
  26. flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +39 -44
  27. flwr/cli/new/templates/app/code/model.baseline.py.tpl +0 -14
  28. flwr/cli/new/templates/app/code/server.baseline.py.tpl +27 -29
  29. flwr/cli/new/templates/app/code/server.huggingface.py.tpl +23 -19
  30. flwr/cli/new/templates/app/code/server.jax.py.tpl +27 -14
  31. flwr/cli/new/templates/app/code/server.mlx.py.tpl +29 -19
  32. flwr/cli/new/templates/app/code/server.numpy.py.tpl +30 -17
  33. flwr/cli/new/templates/app/code/server.pytorch.py.tpl +36 -26
  34. flwr/cli/new/templates/app/code/server.pytorch_legacy_api.py.tpl +31 -0
  35. flwr/cli/new/templates/app/code/server.sklearn.py.tpl +29 -21
  36. flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +28 -19
  37. flwr/cli/new/templates/app/code/server.xgboost.py.tpl +56 -0
  38. flwr/cli/new/templates/app/code/task.huggingface.py.tpl +16 -20
  39. flwr/cli/new/templates/app/code/task.jax.py.tpl +1 -1
  40. flwr/cli/new/templates/app/code/task.numpy.py.tpl +1 -1
  41. flwr/cli/new/templates/app/code/task.pytorch.py.tpl +14 -27
  42. flwr/cli/new/templates/app/code/{task.pytorch_msg_api.py.tpl → task.pytorch_legacy_api.py.tpl} +27 -14
  43. flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +1 -2
  44. flwr/cli/new/templates/app/code/task.xgboost.py.tpl +67 -0
  45. flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +4 -4
  46. flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +2 -2
  47. flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +4 -4
  48. flwr/cli/new/templates/app/pyproject.jax.toml.tpl +1 -1
  49. flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +2 -2
  50. flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +1 -1
  51. flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +3 -3
  52. flwr/cli/new/templates/app/{pyproject.pytorch_msg_api.toml.tpl → pyproject.pytorch_legacy_api.toml.tpl} +3 -3
  53. flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +1 -1
  54. flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +1 -1
  55. flwr/cli/new/templates/app/pyproject.xgboost.toml.tpl +61 -0
  56. flwr/cli/pull.py +100 -0
  57. flwr/cli/run/run.py +11 -7
  58. flwr/cli/stop.py +2 -2
  59. flwr/cli/supernode/__init__.py +25 -0
  60. flwr/cli/supernode/ls.py +260 -0
  61. flwr/cli/supernode/register.py +185 -0
  62. flwr/cli/supernode/unregister.py +138 -0
  63. flwr/cli/utils.py +109 -69
  64. flwr/client/__init__.py +2 -1
  65. flwr/client/grpc_adapter_client/connection.py +6 -8
  66. flwr/client/grpc_rere_client/connection.py +59 -31
  67. flwr/client/grpc_rere_client/grpc_adapter.py +28 -12
  68. flwr/client/grpc_rere_client/{client_interceptor.py → node_auth_client_interceptor.py} +3 -6
  69. flwr/client/mod/secure_aggregation/secaggplus_mod.py +7 -5
  70. flwr/client/rest_client/connection.py +82 -37
  71. flwr/clientapp/__init__.py +1 -2
  72. flwr/clientapp/mod/__init__.py +4 -1
  73. flwr/clientapp/mod/centraldp_mods.py +156 -40
  74. flwr/clientapp/mod/localdp_mod.py +169 -0
  75. flwr/clientapp/typing.py +22 -0
  76. flwr/{client/clientapp → clientapp}/utils.py +1 -1
  77. flwr/common/constant.py +56 -13
  78. flwr/common/exit/exit_code.py +24 -10
  79. flwr/common/inflatable_utils.py +10 -10
  80. flwr/common/record/array.py +3 -3
  81. flwr/common/record/arrayrecord.py +10 -1
  82. flwr/common/record/typeddict.py +12 -0
  83. flwr/common/secure_aggregation/crypto/symmetric_encryption.py +1 -89
  84. flwr/common/serde.py +4 -2
  85. flwr/common/typing.py +7 -6
  86. flwr/compat/client/app.py +1 -1
  87. flwr/compat/client/grpc_client/connection.py +2 -2
  88. flwr/proto/control_pb2.py +48 -31
  89. flwr/proto/control_pb2.pyi +95 -5
  90. flwr/proto/control_pb2_grpc.py +136 -0
  91. flwr/proto/control_pb2_grpc.pyi +52 -0
  92. flwr/proto/fab_pb2.py +11 -7
  93. flwr/proto/fab_pb2.pyi +21 -1
  94. flwr/proto/fleet_pb2.py +31 -23
  95. flwr/proto/fleet_pb2.pyi +63 -23
  96. flwr/proto/fleet_pb2_grpc.py +98 -28
  97. flwr/proto/fleet_pb2_grpc.pyi +45 -13
  98. flwr/proto/node_pb2.py +3 -1
  99. flwr/proto/node_pb2.pyi +48 -0
  100. flwr/server/app.py +152 -114
  101. flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +17 -7
  102. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +132 -38
  103. flwr/server/superlink/fleet/grpc_rere/{server_interceptor.py → node_auth_server_interceptor.py} +27 -51
  104. flwr/server/superlink/fleet/message_handler/message_handler.py +67 -22
  105. flwr/server/superlink/fleet/rest_rere/rest_api.py +52 -31
  106. flwr/server/superlink/fleet/vce/backend/backend.py +1 -1
  107. flwr/server/superlink/fleet/vce/backend/raybackend.py +1 -1
  108. flwr/server/superlink/fleet/vce/vce_api.py +18 -5
  109. flwr/server/superlink/linkstate/in_memory_linkstate.py +167 -73
  110. flwr/server/superlink/linkstate/linkstate.py +107 -24
  111. flwr/server/superlink/linkstate/linkstate_factory.py +2 -1
  112. flwr/server/superlink/linkstate/sqlite_linkstate.py +306 -255
  113. flwr/server/superlink/linkstate/utils.py +3 -54
  114. flwr/server/superlink/serverappio/serverappio_servicer.py +2 -2
  115. flwr/server/superlink/simulation/simulationio_servicer.py +1 -1
  116. flwr/server/utils/validator.py +2 -3
  117. flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +4 -2
  118. flwr/serverapp/strategy/__init__.py +26 -0
  119. flwr/serverapp/strategy/bulyan.py +238 -0
  120. flwr/serverapp/strategy/dp_adaptive_clipping.py +335 -0
  121. flwr/serverapp/strategy/dp_fixed_clipping.py +71 -49
  122. flwr/serverapp/strategy/fedadagrad.py +0 -3
  123. flwr/serverapp/strategy/fedadam.py +0 -3
  124. flwr/serverapp/strategy/fedavg.py +89 -64
  125. flwr/serverapp/strategy/fedavgm.py +198 -0
  126. flwr/serverapp/strategy/fedmedian.py +105 -0
  127. flwr/serverapp/strategy/fedprox.py +174 -0
  128. flwr/serverapp/strategy/fedtrimmedavg.py +176 -0
  129. flwr/serverapp/strategy/fedxgb_bagging.py +117 -0
  130. flwr/serverapp/strategy/fedxgb_cyclic.py +220 -0
  131. flwr/serverapp/strategy/fedyogi.py +0 -3
  132. flwr/serverapp/strategy/krum.py +112 -0
  133. flwr/serverapp/strategy/multikrum.py +247 -0
  134. flwr/serverapp/strategy/qfedavg.py +252 -0
  135. flwr/serverapp/strategy/strategy_utils.py +48 -0
  136. flwr/simulation/app.py +1 -1
  137. flwr/simulation/ray_transport/ray_actor.py +1 -1
  138. flwr/simulation/ray_transport/ray_client_proxy.py +1 -1
  139. flwr/simulation/run_simulation.py +28 -32
  140. flwr/supercore/cli/flower_superexec.py +26 -1
  141. flwr/supercore/constant.py +41 -0
  142. flwr/supercore/object_store/in_memory_object_store.py +0 -4
  143. flwr/supercore/object_store/object_store_factory.py +26 -6
  144. flwr/supercore/object_store/sqlite_object_store.py +252 -0
  145. flwr/{client/clientapp → supercore/primitives}/__init__.py +1 -1
  146. flwr/supercore/primitives/asymmetric.py +117 -0
  147. flwr/supercore/primitives/asymmetric_ed25519.py +165 -0
  148. flwr/supercore/sqlite_mixin.py +156 -0
  149. flwr/supercore/superexec/plugin/exec_plugin.py +11 -1
  150. flwr/supercore/superexec/run_superexec.py +16 -2
  151. flwr/supercore/utils.py +20 -0
  152. flwr/superlink/artifact_provider/__init__.py +22 -0
  153. flwr/superlink/artifact_provider/artifact_provider.py +37 -0
  154. flwr/{common → superlink}/auth_plugin/__init__.py +6 -6
  155. flwr/superlink/auth_plugin/auth_plugin.py +91 -0
  156. flwr/superlink/auth_plugin/noop_auth_plugin.py +87 -0
  157. flwr/superlink/servicer/control/{control_user_auth_interceptor.py → control_account_auth_interceptor.py} +19 -19
  158. flwr/superlink/servicer/control/control_event_log_interceptor.py +1 -1
  159. flwr/superlink/servicer/control/control_grpc.py +16 -11
  160. flwr/superlink/servicer/control/control_servicer.py +207 -58
  161. flwr/supernode/cli/flower_supernode.py +19 -26
  162. flwr/supernode/runtime/run_clientapp.py +2 -2
  163. flwr/supernode/servicer/clientappio/clientappio_servicer.py +1 -1
  164. flwr/supernode/start_client_internal.py +17 -9
  165. {flwr-1.21.0.dist-info → flwr-1.23.0.dist-info}/METADATA +6 -16
  166. {flwr-1.21.0.dist-info → flwr-1.23.0.dist-info}/RECORD +170 -140
  167. flwr/cli/new/templates/app/code/client.pytorch_msg_api.py.tpl +0 -80
  168. flwr/cli/new/templates/app/code/server.pytorch_msg_api.py.tpl +0 -41
  169. flwr/common/auth_plugin/auth_plugin.py +0 -149
  170. flwr/serverapp/dp_fixed_clipping.py +0 -352
  171. flwr/serverapp/strategy/strategy_utils_tests.py +0 -304
  172. /flwr/cli/new/templates/app/code/{__init__.pytorch_msg_api.py.tpl → __init__.pytorch_legacy_api.py.tpl} +0 -0
  173. /flwr/{client → clientapp}/client_app.py +0 -0
  174. {flwr-1.21.0.dist-info → flwr-1.23.0.dist-info}/WHEEL +0 -0
  175. {flwr-1.21.0.dist-info → flwr-1.23.0.dist-info}/entry_points.txt +0 -0
@@ -25,10 +25,10 @@ from typing import Callable, Optional, TypeVar
25
25
  from flwr.proto.message_pb2 import ObjectTree # pylint: disable=E0611
26
26
 
27
27
  from .constant import (
28
+ FLWR_PRIVATE_MAX_CONCURRENT_OBJ_PULLS,
29
+ FLWR_PRIVATE_MAX_CONCURRENT_OBJ_PUSHES,
28
30
  HEAD_BODY_DIVIDER,
29
31
  HEAD_VALUE_DIVIDER,
30
- MAX_CONCURRENT_PULLS,
31
- MAX_CONCURRENT_PUSHES,
32
32
  PULL_BACKOFF_CAP,
33
33
  PULL_INITIAL_BACKOFF,
34
34
  PULL_MAX_TIME,
@@ -118,7 +118,7 @@ def push_objects(
118
118
  *,
119
119
  object_ids_to_push: Optional[set[str]] = None,
120
120
  keep_objects: bool = False,
121
- max_concurrent_pushes: int = MAX_CONCURRENT_PUSHES,
121
+ max_concurrent_pushes: int = FLWR_PRIVATE_MAX_CONCURRENT_OBJ_PUSHES,
122
122
  ) -> None:
123
123
  """Push multiple objects to the servicer.
124
124
 
@@ -137,7 +137,7 @@ def push_objects(
137
137
  If `True`, the original objects will be kept in the `objects` dictionary
138
138
  after pushing. If `False`, they will be removed from the dictionary to avoid
139
139
  high memory usage.
140
- max_concurrent_pushes : int (default: MAX_CONCURRENT_PUSHES)
140
+ max_concurrent_pushes : int (default: FLWR_PRIVATE_MAX_CONCURRENT_OBJ_PUSHES)
141
141
  The maximum number of concurrent pushes to perform.
142
142
  """
143
143
  lock = threading.Lock()
@@ -168,7 +168,7 @@ def push_object_contents_from_iterable(
168
168
  object_contents: Iterable[tuple[str, bytes]],
169
169
  push_object_fn: Callable[[str, bytes], None],
170
170
  *,
171
- max_concurrent_pushes: int = MAX_CONCURRENT_PUSHES,
171
+ max_concurrent_pushes: int = FLWR_PRIVATE_MAX_CONCURRENT_OBJ_PUSHES,
172
172
  ) -> None:
173
173
  """Push multiple object contents to the servicer.
174
174
 
@@ -181,7 +181,7 @@ def push_object_contents_from_iterable(
181
181
  A function that takes an object ID and its content as bytes, and pushes
182
182
  it to the servicer. This function should raise `ObjectIdNotPreregisteredError`
183
183
  if the object ID is not pre-registered.
184
- max_concurrent_pushes : int (default: MAX_CONCURRENT_PUSHES)
184
+ max_concurrent_pushes : int (default: FLWR_PRIVATE_MAX_CONCURRENT_OBJ_PUSHES)
185
185
  The maximum number of concurrent pushes to perform.
186
186
  """
187
187
 
@@ -210,7 +210,7 @@ def pull_objects( # pylint: disable=too-many-arguments,too-many-locals
210
210
  object_ids: list[str],
211
211
  pull_object_fn: Callable[[str], bytes],
212
212
  *,
213
- max_concurrent_pulls: int = MAX_CONCURRENT_PULLS,
213
+ max_concurrent_pulls: int = FLWR_PRIVATE_MAX_CONCURRENT_OBJ_PULLS,
214
214
  max_time: Optional[float] = PULL_MAX_TIME,
215
215
  max_tries_per_object: Optional[int] = PULL_MAX_TRIES_PER_OBJECT,
216
216
  initial_backoff: float = PULL_INITIAL_BACKOFF,
@@ -227,7 +227,7 @@ def pull_objects( # pylint: disable=too-many-arguments,too-many-locals
227
227
  The function should raise `ObjectUnavailableError` if the object is not yet
228
228
  available, or `ObjectIdNotPreregisteredError` if the object ID is not
229
229
  pre-registered.
230
- max_concurrent_pulls : int (default: MAX_CONCURRENT_PULLS)
230
+ max_concurrent_pulls : int (default: FLWR_PRIVATE_MAX_CONCURRENT_OBJ_PULLS)
231
231
  The maximum number of concurrent pulls to perform.
232
232
  max_time : Optional[float] (default: PULL_MAX_TIME)
233
233
  The maximum time to wait for all pulls to complete. If `None`, waits
@@ -442,7 +442,7 @@ def pull_and_inflate_object_from_tree( # pylint: disable=R0913
442
442
  confirm_object_received_fn: Callable[[str], None],
443
443
  *,
444
444
  return_type: type[T] = InflatableObject, # type: ignore
445
- max_concurrent_pulls: int = MAX_CONCURRENT_PULLS,
445
+ max_concurrent_pulls: int = FLWR_PRIVATE_MAX_CONCURRENT_OBJ_PULLS,
446
446
  max_time: Optional[float] = PULL_MAX_TIME,
447
447
  max_tries_per_object: Optional[int] = PULL_MAX_TRIES_PER_OBJECT,
448
448
  initial_backoff: float = PULL_INITIAL_BACKOFF,
@@ -460,7 +460,7 @@ def pull_and_inflate_object_from_tree( # pylint: disable=R0913
460
460
  A function to confirm that the object has been received.
461
461
  return_type : type[T] (default: InflatableObject)
462
462
  The type of the object to return. Must be a subclass of `InflatableObject`.
463
- max_concurrent_pulls : int (default: MAX_CONCURRENT_PULLS)
463
+ max_concurrent_pulls : int (default: FLWR_PRIVATE_MAX_CONCURRENT_OBJ_PULLS)
464
464
  The maximum number of concurrent pulls to perform.
465
465
  max_time : Optional[float] (default: PULL_MAX_TIME)
466
466
  The maximum time to wait for all pulls to complete. If `None`, waits
@@ -25,7 +25,7 @@ from typing import TYPE_CHECKING, Any, cast, overload
25
25
 
26
26
  import numpy as np
27
27
 
28
- from ..constant import MAX_ARRAY_CHUNK_SIZE, SType
28
+ from ..constant import FLWR_PRIVATE_MAX_ARRAY_CHUNK_SIZE, SType
29
29
  from ..inflatable import (
30
30
  InflatableObject,
31
31
  add_header_to_object_body,
@@ -272,8 +272,8 @@ class Array(InflatableObject):
272
272
  chunks: list[tuple[str, InflatableObject]] = []
273
273
  # memoryview allows for zero-copy slicing
274
274
  data_view = memoryview(self.data)
275
- for start in range(0, len(data_view), MAX_ARRAY_CHUNK_SIZE):
276
- end = min(start + MAX_ARRAY_CHUNK_SIZE, len(data_view))
275
+ for start in range(0, len(data_view), FLWR_PRIVATE_MAX_ARRAY_CHUNK_SIZE):
276
+ end = min(start + FLWR_PRIVATE_MAX_ARRAY_CHUNK_SIZE, len(data_view))
277
277
  ac = ArrayChunk(data_view[start:end])
278
278
  chunks.append((ac.object_id, ac))
279
279
 
@@ -147,11 +147,20 @@ class ArrayRecord(TypedDict[str, Array], InflatableObject):
147
147
  keep_input: bool = True,
148
148
  ) -> None: ...
149
149
 
150
+ # This is also required for PyTorch state dict because they are not strongly typed
151
+ @overload
152
+ def __init__( # noqa: E704
153
+ self,
154
+ torch_state_dict: dict[str, Any],
155
+ *,
156
+ keep_input: bool = True,
157
+ ) -> None: ...
158
+
150
159
  def __init__( # pylint: disable=too-many-arguments
151
160
  self,
152
161
  *args: Any,
153
162
  numpy_ndarrays: list[NDArray] | None = None,
154
- torch_state_dict: OrderedDict[str, torch.Tensor] | None = None,
163
+ torch_state_dict: OrderedDict[str, torch.Tensor] | dict[str, Any] | None = None,
155
164
  array_dict: OrderedDict[str, Array] | None = None,
156
165
  keep_input: bool = True,
157
166
  ) -> None:
@@ -18,6 +18,8 @@
18
18
  from collections.abc import ItemsView, Iterator, KeysView, MutableMapping, ValuesView
19
19
  from typing import Callable, Generic, TypeVar, cast
20
20
 
21
+ from typing_extensions import Self
22
+
21
23
  K = TypeVar("K") # Key type
22
24
  V = TypeVar("V") # Value type
23
25
 
@@ -86,3 +88,13 @@ class TypedDict(MutableMapping[K, V], Generic[K, V]):
86
88
  def items(self) -> ItemsView[K, V]:
87
89
  """D.items() -> a set-like object providing a view on D's items."""
88
90
  return cast(dict[K, V], self.__dict__["_data"]).items()
91
+
92
+ def copy(self) -> Self:
93
+ """Return a shallow copy of the dictionary."""
94
+ # Allocate instance without going through __init__
95
+ new = self.__class__.__new__(type(self))
96
+ # Copy internal state
97
+ new.__dict__["_check_key_fn"] = self.__dict__["_check_key_fn"]
98
+ new.__dict__["_check_value_fn"] = self.__dict__["_check_value_fn"]
99
+ new.__dict__["_data"] = cast(dict[K, V], self.__dict__["_data"]).copy()
100
+ return new
@@ -16,57 +16,14 @@
16
16
 
17
17
 
18
18
  import base64
19
- from typing import cast
20
19
 
21
20
  from cryptography.exceptions import InvalidSignature
22
21
  from cryptography.fernet import Fernet
23
- from cryptography.hazmat.primitives import hashes, hmac, serialization
22
+ from cryptography.hazmat.primitives import hashes, hmac
24
23
  from cryptography.hazmat.primitives.asymmetric import ec
25
24
  from cryptography.hazmat.primitives.kdf.hkdf import HKDF
26
25
 
27
26
 
28
- def generate_key_pairs() -> (
29
- tuple[ec.EllipticCurvePrivateKey, ec.EllipticCurvePublicKey]
30
- ):
31
- """Generate private and public key pairs with Cryptography."""
32
- private_key = ec.generate_private_key(ec.SECP384R1())
33
- public_key = private_key.public_key()
34
- return private_key, public_key
35
-
36
-
37
- def private_key_to_bytes(private_key: ec.EllipticCurvePrivateKey) -> bytes:
38
- """Serialize private key to bytes."""
39
- return private_key.private_bytes(
40
- encoding=serialization.Encoding.PEM,
41
- format=serialization.PrivateFormat.PKCS8,
42
- encryption_algorithm=serialization.NoEncryption(),
43
- )
44
-
45
-
46
- def bytes_to_private_key(private_key_bytes: bytes) -> ec.EllipticCurvePrivateKey:
47
- """Deserialize private key from bytes."""
48
- return cast(
49
- ec.EllipticCurvePrivateKey,
50
- serialization.load_pem_private_key(data=private_key_bytes, password=None),
51
- )
52
-
53
-
54
- def public_key_to_bytes(public_key: ec.EllipticCurvePublicKey) -> bytes:
55
- """Serialize public key to bytes."""
56
- return public_key.public_bytes(
57
- encoding=serialization.Encoding.PEM,
58
- format=serialization.PublicFormat.SubjectPublicKeyInfo,
59
- )
60
-
61
-
62
- def bytes_to_public_key(public_key_bytes: bytes) -> ec.EllipticCurvePublicKey:
63
- """Deserialize public key from bytes."""
64
- return cast(
65
- ec.EllipticCurvePublicKey,
66
- serialization.load_pem_public_key(data=public_key_bytes),
67
- )
68
-
69
-
70
27
  def generate_shared_key(
71
28
  private_key: ec.EllipticCurvePrivateKey, public_key: ec.EllipticCurvePublicKey
72
29
  ) -> bytes:
@@ -117,48 +74,3 @@ def verify_hmac(key: bytes, message: bytes, hmac_value: bytes) -> bool:
117
74
  return True
118
75
  except InvalidSignature:
119
76
  return False
120
-
121
-
122
- def sign_message(private_key: ec.EllipticCurvePrivateKey, message: bytes) -> bytes:
123
- """Sign a message using the provided EC private key.
124
-
125
- Parameters
126
- ----------
127
- private_key : ec.EllipticCurvePrivateKey
128
- The EC private key to sign the message with.
129
- message : bytes
130
- The message to be signed.
131
-
132
- Returns
133
- -------
134
- bytes
135
- The signature of the message.
136
- """
137
- signature = private_key.sign(message, ec.ECDSA(hashes.SHA256()))
138
- return signature
139
-
140
-
141
- def verify_signature(
142
- public_key: ec.EllipticCurvePublicKey, message: bytes, signature: bytes
143
- ) -> bool:
144
- """Verify a signature against a message using the provided EC public key.
145
-
146
- Parameters
147
- ----------
148
- public_key : ec.EllipticCurvePublicKey
149
- The EC public key to verify the signature.
150
- message : bytes
151
- The original message.
152
- signature : bytes
153
- The signature to verify.
154
-
155
- Returns
156
- -------
157
- bool
158
- True if the signature is valid, False otherwise.
159
- """
160
- try:
161
- public_key.verify(signature, message, ec.ECDSA(hashes.SHA256()))
162
- return True
163
- except InvalidSignature:
164
- return False
flwr/common/serde.py CHANGED
@@ -501,12 +501,14 @@ def recorddict_from_proto(recorddict_proto: ProtoRecordDict) -> RecordDict:
501
501
 
502
502
  def fab_to_proto(fab: typing.Fab) -> ProtoFab:
503
503
  """Create a proto Fab object from a Python Fab."""
504
- return ProtoFab(hash_str=fab.hash_str, content=fab.content)
504
+ return ProtoFab(
505
+ hash_str=fab.hash_str, content=fab.content, verifications=fab.verifications
506
+ )
505
507
 
506
508
 
507
509
  def fab_from_proto(fab: ProtoFab) -> typing.Fab:
508
510
  """Create a Python Fab object from a proto Fab."""
509
- return typing.Fab(fab.hash_str, fab.content)
511
+ return typing.Fab(fab.hash_str, fab.content, dict(fab.verifications))
510
512
 
511
513
 
512
514
  # === User configs ===
flwr/common/typing.py CHANGED
@@ -256,6 +256,7 @@ class Fab:
256
256
 
257
257
  hash_str: str
258
258
  content: bytes
259
+ verifications: dict[str, str]
259
260
 
260
261
 
261
262
  class RunNotRunningException(BaseException):
@@ -270,12 +271,12 @@ class InvalidRunStatusException(BaseException):
270
271
  self.message = message
271
272
 
272
273
 
273
- # OIDC user authentication types
274
+ # OIDC account authentication types
274
275
  @dataclass
275
- class UserAuthLoginDetails:
276
- """User authentication login details."""
276
+ class AccountAuthLoginDetails:
277
+ """Account authentication login details."""
277
278
 
278
- auth_type: str
279
+ authn_type: str
279
280
  device_code: str
280
281
  verification_uri_complete: str
281
282
  expires_in: int
@@ -283,8 +284,8 @@ class UserAuthLoginDetails:
283
284
 
284
285
 
285
286
  @dataclass
286
- class UserAuthCredentials:
287
- """User authentication tokens."""
287
+ class AccountAuthCredentials:
288
+ """Account authentication tokens."""
288
289
 
289
290
  access_token: str
290
291
  refresh_token: str
flwr/compat/client/app.py CHANGED
@@ -28,11 +28,11 @@ from flwr.app.error import Error
28
28
  from flwr.cli.config_utils import get_fab_metadata
29
29
  from flwr.cli.install import install_from_fab
30
30
  from flwr.client.client import Client
31
- from flwr.client.client_app import ClientApp, LoadClientAppError
32
31
  from flwr.client.message_handler.message_handler import handle_control_message
33
32
  from flwr.client.numpy_client import NumPyClient
34
33
  from flwr.client.run_info_store import DeprecatedRunInfoStore
35
34
  from flwr.client.typing import ClientFnExt
35
+ from flwr.clientapp.client_app import ClientApp, LoadClientAppError
36
36
  from flwr.common import GRPC_MAX_MESSAGE_LENGTH, Context, EventType, Message, event
37
37
  from flwr.common.address import parse_address
38
38
  from flwr.common.constant import (
@@ -96,7 +96,7 @@ def grpc_connection( # pylint: disable=R0913,R0915,too-many-positional-argument
96
96
  If provided, a secure connection using the certificates will be
97
97
  established to an SSL-enabled Flower server.
98
98
  authentication_keys : Optional[Tuple[PrivateKey, PublicKey]] (default: None)
99
- Client authentication is not supported for this transport type.
99
+ SuperNode authentication is not supported for this transport type.
100
100
 
101
101
  Returns
102
102
  -------
@@ -120,7 +120,7 @@ def grpc_connection( # pylint: disable=R0913,R0915,too-many-positional-argument
120
120
  if isinstance(root_certificates, str):
121
121
  root_certificates = Path(root_certificates).read_bytes()
122
122
  if authentication_keys is not None:
123
- log(ERROR, "Client authentication is not supported for this transport type.")
123
+ log(ERROR, "SuperNode authentication is not supported for this transport type.")
124
124
 
125
125
  channel = create_channel(
126
126
  server_address=server_address,
flwr/proto/control_pb2.py CHANGED
@@ -16,9 +16,10 @@ from flwr.proto import fab_pb2 as flwr_dot_proto_dot_fab__pb2
16
16
  from flwr.proto import transport_pb2 as flwr_dot_proto_dot_transport__pb2
17
17
  from flwr.proto import recorddict_pb2 as flwr_dot_proto_dot_recorddict__pb2
18
18
  from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2
19
+ from flwr.proto import node_pb2 as flwr_dot_proto_dot_node__pb2
19
20
 
20
21
 
21
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18\x66lwr/proto/control.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x1b\x66lwr/proto/recorddict.proto\x1a\x14\x66lwr/proto/run.proto\"\xfa\x01\n\x0fStartRunRequest\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fab\x12H\n\x0foverride_config\x18\x02 \x03(\x0b\x32/.flwr.proto.StartRunRequest.OverrideConfigEntry\x12\x34\n\x12\x66\x65\x64\x65ration_options\x18\x03 \x01(\x0b\x32\x18.flwr.proto.ConfigRecord\x1aI\n\x13OverrideConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"2\n\x10StartRunResponse\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"<\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x17\n\x0f\x61\x66ter_timestamp\x18\x02 \x01(\x01\"B\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t\x12\x18\n\x10latest_timestamp\x18\x02 \x01(\x01\"1\n\x0fListRunsRequest\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"\x9d\x01\n\x10ListRunsResponse\x12;\n\x08run_dict\x18\x01 \x03(\x0b\x32).flwr.proto.ListRunsResponse.RunDictEntry\x12\x0b\n\x03now\x18\x02 \x01(\t\x1a?\n\x0cRunDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x1e\n\x05value\x18\x02 \x01(\x0b\x32\x0f.flwr.proto.Run:\x02\x38\x01\"\x18\n\x16GetLoginDetailsRequest\"\x8a\x01\n\x17GetLoginDetailsResponse\x12\x11\n\tauth_type\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65vice_code\x18\x02 \x01(\t\x12!\n\x19verification_uri_complete\x18\x03 \x01(\t\x12\x12\n\nexpires_in\x18\x04 \x01(\x03\x12\x10\n\x08interval\x18\x05 \x01(\x03\"+\n\x14GetAuthTokensRequest\x12\x13\n\x0b\x64\x65vice_code\x18\x01 \x01(\t\"D\n\x15GetAuthTokensResponse\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x01 \x01(\t\x12\x15\n\rrefresh_token\x18\x02 \x01(\t\" \n\x0eStopRunRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"\"\n\x0fStopRunResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x32\xe8\x03\n\x07\x43ontrol\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\x00\x12\x44\n\x07StopRun\x12\x1a.flwr.proto.StopRunRequest\x1a\x1b.flwr.proto.StopRunResponse\"\x00\x12O\n\nStreamLogs\x12\x1d.flwr.proto.StreamLogsRequest\x1a\x1e.flwr.proto.StreamLogsResponse\"\x00\x30\x01\x12G\n\x08ListRuns\x12\x1b.flwr.proto.ListRunsRequest\x1a\x1c.flwr.proto.ListRunsResponse\"\x00\x12\\\n\x0fGetLoginDetails\x12\".flwr.proto.GetLoginDetailsRequest\x1a#.flwr.proto.GetLoginDetailsResponse\"\x00\x12V\n\rGetAuthTokens\x12 .flwr.proto.GetAuthTokensRequest\x1a!.flwr.proto.GetAuthTokensResponse\"\x00\x62\x06proto3')
22
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18\x66lwr/proto/control.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x1b\x66lwr/proto/recorddict.proto\x1a\x14\x66lwr/proto/run.proto\x1a\x15\x66lwr/proto/node.proto\"\x8a\x02\n\x0fStartRunRequest\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fab\x12H\n\x0foverride_config\x18\x02 \x03(\x0b\x32/.flwr.proto.StartRunRequest.OverrideConfigEntry\x12\x34\n\x12\x66\x65\x64\x65ration_options\x18\x03 \x01(\x0b\x32\x18.flwr.proto.ConfigRecord\x12\x0e\n\x06\x61pp_id\x18\x04 \x01(\t\x1aI\n\x13OverrideConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"2\n\x10StartRunResponse\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"<\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x17\n\x0f\x61\x66ter_timestamp\x18\x02 \x01(\x01\"B\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t\x12\x18\n\x10latest_timestamp\x18\x02 \x01(\x01\"1\n\x0fListRunsRequest\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"\x9d\x01\n\x10ListRunsResponse\x12;\n\x08run_dict\x18\x01 \x03(\x0b\x32).flwr.proto.ListRunsResponse.RunDictEntry\x12\x0b\n\x03now\x18\x02 \x01(\t\x1a?\n\x0cRunDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x1e\n\x05value\x18\x02 \x01(\x0b\x32\x0f.flwr.proto.Run:\x02\x38\x01\"\x18\n\x16GetLoginDetailsRequest\"\x8b\x01\n\x17GetLoginDetailsResponse\x12\x12\n\nauthn_type\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65vice_code\x18\x02 \x01(\t\x12!\n\x19verification_uri_complete\x18\x03 \x01(\t\x12\x12\n\nexpires_in\x18\x04 \x01(\x03\x12\x10\n\x08interval\x18\x05 \x01(\x03\"+\n\x14GetAuthTokensRequest\x12\x13\n\x0b\x64\x65vice_code\x18\x01 \x01(\t\"D\n\x15GetAuthTokensResponse\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x01 \x01(\t\x12\x15\n\rrefresh_token\x18\x02 \x01(\t\" \n\x0eStopRunRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"\"\n\x0fStopRunResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\"&\n\x14PullArtifactsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"1\n\x15PullArtifactsResponse\x12\x10\n\x03url\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x06\n\x04_url\")\n\x13RegisterNodeRequest\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\"8\n\x14RegisterNodeResponse\x12\x14\n\x07node_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\n\n\x08_node_id\"(\n\x15UnregisterNodeRequest\x12\x0f\n\x07node_id\x18\x01 \x01(\x04\"\x18\n\x16UnregisterNodeResponse\"\x12\n\x10ListNodesRequest\"J\n\x11ListNodesResponse\x12(\n\nnodes_info\x18\x01 \x03(\x0b\x32\x14.flwr.proto.NodeInfo\x12\x0b\n\x03now\x18\x02 \x01(\t2\xbc\x06\n\x07\x43ontrol\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\x00\x12\x44\n\x07StopRun\x12\x1a.flwr.proto.StopRunRequest\x1a\x1b.flwr.proto.StopRunResponse\"\x00\x12O\n\nStreamLogs\x12\x1d.flwr.proto.StreamLogsRequest\x1a\x1e.flwr.proto.StreamLogsResponse\"\x00\x30\x01\x12G\n\x08ListRuns\x12\x1b.flwr.proto.ListRunsRequest\x1a\x1c.flwr.proto.ListRunsResponse\"\x00\x12\\\n\x0fGetLoginDetails\x12\".flwr.proto.GetLoginDetailsRequest\x1a#.flwr.proto.GetLoginDetailsResponse\"\x00\x12V\n\rGetAuthTokens\x12 .flwr.proto.GetAuthTokensRequest\x1a!.flwr.proto.GetAuthTokensResponse\"\x00\x12V\n\rPullArtifacts\x12 .flwr.proto.PullArtifactsRequest\x1a!.flwr.proto.PullArtifactsResponse\"\x00\x12S\n\x0cRegisterNode\x12\x1f.flwr.proto.RegisterNodeRequest\x1a .flwr.proto.RegisterNodeResponse\"\x00\x12Y\n\x0eUnregisterNode\x12!.flwr.proto.UnregisterNodeRequest\x1a\".flwr.proto.UnregisterNodeResponse\"\x00\x12J\n\tListNodes\x12\x1c.flwr.proto.ListNodesRequest\x1a\x1d.flwr.proto.ListNodesResponse\"\x00\x62\x06proto3')
22
23
 
23
24
  _globals = globals()
24
25
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -29,34 +30,50 @@ if _descriptor._USE_C_DESCRIPTORS == False:
29
30
  _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_options = b'8\001'
30
31
  _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._options = None
31
32
  _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_options = b'8\001'
32
- _globals['_STARTRUNREQUEST']._serialized_start=142
33
- _globals['_STARTRUNREQUEST']._serialized_end=392
34
- _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=319
35
- _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=392
36
- _globals['_STARTRUNRESPONSE']._serialized_start=394
37
- _globals['_STARTRUNRESPONSE']._serialized_end=444
38
- _globals['_STREAMLOGSREQUEST']._serialized_start=446
39
- _globals['_STREAMLOGSREQUEST']._serialized_end=506
40
- _globals['_STREAMLOGSRESPONSE']._serialized_start=508
41
- _globals['_STREAMLOGSRESPONSE']._serialized_end=574
42
- _globals['_LISTRUNSREQUEST']._serialized_start=576
43
- _globals['_LISTRUNSREQUEST']._serialized_end=625
44
- _globals['_LISTRUNSRESPONSE']._serialized_start=628
45
- _globals['_LISTRUNSRESPONSE']._serialized_end=785
46
- _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_start=722
47
- _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_end=785
48
- _globals['_GETLOGINDETAILSREQUEST']._serialized_start=787
49
- _globals['_GETLOGINDETAILSREQUEST']._serialized_end=811
50
- _globals['_GETLOGINDETAILSRESPONSE']._serialized_start=814
51
- _globals['_GETLOGINDETAILSRESPONSE']._serialized_end=952
52
- _globals['_GETAUTHTOKENSREQUEST']._serialized_start=954
53
- _globals['_GETAUTHTOKENSREQUEST']._serialized_end=997
54
- _globals['_GETAUTHTOKENSRESPONSE']._serialized_start=999
55
- _globals['_GETAUTHTOKENSRESPONSE']._serialized_end=1067
56
- _globals['_STOPRUNREQUEST']._serialized_start=1069
57
- _globals['_STOPRUNREQUEST']._serialized_end=1101
58
- _globals['_STOPRUNRESPONSE']._serialized_start=1103
59
- _globals['_STOPRUNRESPONSE']._serialized_end=1137
60
- _globals['_CONTROL']._serialized_start=1140
61
- _globals['_CONTROL']._serialized_end=1628
33
+ _globals['_STARTRUNREQUEST']._serialized_start=165
34
+ _globals['_STARTRUNREQUEST']._serialized_end=431
35
+ _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=358
36
+ _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=431
37
+ _globals['_STARTRUNRESPONSE']._serialized_start=433
38
+ _globals['_STARTRUNRESPONSE']._serialized_end=483
39
+ _globals['_STREAMLOGSREQUEST']._serialized_start=485
40
+ _globals['_STREAMLOGSREQUEST']._serialized_end=545
41
+ _globals['_STREAMLOGSRESPONSE']._serialized_start=547
42
+ _globals['_STREAMLOGSRESPONSE']._serialized_end=613
43
+ _globals['_LISTRUNSREQUEST']._serialized_start=615
44
+ _globals['_LISTRUNSREQUEST']._serialized_end=664
45
+ _globals['_LISTRUNSRESPONSE']._serialized_start=667
46
+ _globals['_LISTRUNSRESPONSE']._serialized_end=824
47
+ _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_start=761
48
+ _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_end=824
49
+ _globals['_GETLOGINDETAILSREQUEST']._serialized_start=826
50
+ _globals['_GETLOGINDETAILSREQUEST']._serialized_end=850
51
+ _globals['_GETLOGINDETAILSRESPONSE']._serialized_start=853
52
+ _globals['_GETLOGINDETAILSRESPONSE']._serialized_end=992
53
+ _globals['_GETAUTHTOKENSREQUEST']._serialized_start=994
54
+ _globals['_GETAUTHTOKENSREQUEST']._serialized_end=1037
55
+ _globals['_GETAUTHTOKENSRESPONSE']._serialized_start=1039
56
+ _globals['_GETAUTHTOKENSRESPONSE']._serialized_end=1107
57
+ _globals['_STOPRUNREQUEST']._serialized_start=1109
58
+ _globals['_STOPRUNREQUEST']._serialized_end=1141
59
+ _globals['_STOPRUNRESPONSE']._serialized_start=1143
60
+ _globals['_STOPRUNRESPONSE']._serialized_end=1177
61
+ _globals['_PULLARTIFACTSREQUEST']._serialized_start=1179
62
+ _globals['_PULLARTIFACTSREQUEST']._serialized_end=1217
63
+ _globals['_PULLARTIFACTSRESPONSE']._serialized_start=1219
64
+ _globals['_PULLARTIFACTSRESPONSE']._serialized_end=1268
65
+ _globals['_REGISTERNODEREQUEST']._serialized_start=1270
66
+ _globals['_REGISTERNODEREQUEST']._serialized_end=1311
67
+ _globals['_REGISTERNODERESPONSE']._serialized_start=1313
68
+ _globals['_REGISTERNODERESPONSE']._serialized_end=1369
69
+ _globals['_UNREGISTERNODEREQUEST']._serialized_start=1371
70
+ _globals['_UNREGISTERNODEREQUEST']._serialized_end=1411
71
+ _globals['_UNREGISTERNODERESPONSE']._serialized_start=1413
72
+ _globals['_UNREGISTERNODERESPONSE']._serialized_end=1437
73
+ _globals['_LISTNODESREQUEST']._serialized_start=1439
74
+ _globals['_LISTNODESREQUEST']._serialized_end=1457
75
+ _globals['_LISTNODESRESPONSE']._serialized_start=1459
76
+ _globals['_LISTNODESRESPONSE']._serialized_end=1533
77
+ _globals['_CONTROL']._serialized_start=1536
78
+ _globals['_CONTROL']._serialized_end=2364
62
79
  # @@protoc_insertion_point(module_scope)
@@ -4,6 +4,7 @@ isort:skip_file
4
4
  """
5
5
  import builtins
6
6
  import flwr.proto.fab_pb2
7
+ import flwr.proto.node_pb2
7
8
  import flwr.proto.recorddict_pb2
8
9
  import flwr.proto.run_pb2
9
10
  import flwr.proto.transport_pb2
@@ -35,20 +36,23 @@ class StartRunRequest(google.protobuf.message.Message):
35
36
  FAB_FIELD_NUMBER: builtins.int
36
37
  OVERRIDE_CONFIG_FIELD_NUMBER: builtins.int
37
38
  FEDERATION_OPTIONS_FIELD_NUMBER: builtins.int
39
+ APP_ID_FIELD_NUMBER: builtins.int
38
40
  @property
39
41
  def fab(self) -> flwr.proto.fab_pb2.Fab: ...
40
42
  @property
41
43
  def override_config(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, flwr.proto.transport_pb2.Scalar]: ...
42
44
  @property
43
45
  def federation_options(self) -> flwr.proto.recorddict_pb2.ConfigRecord: ...
46
+ app_id: typing.Text
44
47
  def __init__(self,
45
48
  *,
46
49
  fab: typing.Optional[flwr.proto.fab_pb2.Fab] = ...,
47
50
  override_config: typing.Optional[typing.Mapping[typing.Text, flwr.proto.transport_pb2.Scalar]] = ...,
48
51
  federation_options: typing.Optional[flwr.proto.recorddict_pb2.ConfigRecord] = ...,
52
+ app_id: typing.Text = ...,
49
53
  ) -> None: ...
50
54
  def HasField(self, field_name: typing_extensions.Literal["fab",b"fab","federation_options",b"federation_options"]) -> builtins.bool: ...
51
- def ClearField(self, field_name: typing_extensions.Literal["fab",b"fab","federation_options",b"federation_options","override_config",b"override_config"]) -> None: ...
55
+ def ClearField(self, field_name: typing_extensions.Literal["app_id",b"app_id","fab",b"fab","federation_options",b"federation_options","override_config",b"override_config"]) -> None: ...
52
56
  global___StartRunRequest = StartRunRequest
53
57
 
54
58
  class StartRunResponse(google.protobuf.message.Message):
@@ -143,25 +147,25 @@ global___GetLoginDetailsRequest = GetLoginDetailsRequest
143
147
 
144
148
  class GetLoginDetailsResponse(google.protobuf.message.Message):
145
149
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
146
- AUTH_TYPE_FIELD_NUMBER: builtins.int
150
+ AUTHN_TYPE_FIELD_NUMBER: builtins.int
147
151
  DEVICE_CODE_FIELD_NUMBER: builtins.int
148
152
  VERIFICATION_URI_COMPLETE_FIELD_NUMBER: builtins.int
149
153
  EXPIRES_IN_FIELD_NUMBER: builtins.int
150
154
  INTERVAL_FIELD_NUMBER: builtins.int
151
- auth_type: typing.Text
155
+ authn_type: typing.Text
152
156
  device_code: typing.Text
153
157
  verification_uri_complete: typing.Text
154
158
  expires_in: builtins.int
155
159
  interval: builtins.int
156
160
  def __init__(self,
157
161
  *,
158
- auth_type: typing.Text = ...,
162
+ authn_type: typing.Text = ...,
159
163
  device_code: typing.Text = ...,
160
164
  verification_uri_complete: typing.Text = ...,
161
165
  expires_in: builtins.int = ...,
162
166
  interval: builtins.int = ...,
163
167
  ) -> None: ...
164
- def ClearField(self, field_name: typing_extensions.Literal["auth_type",b"auth_type","device_code",b"device_code","expires_in",b"expires_in","interval",b"interval","verification_uri_complete",b"verification_uri_complete"]) -> None: ...
168
+ def ClearField(self, field_name: typing_extensions.Literal["authn_type",b"authn_type","device_code",b"device_code","expires_in",b"expires_in","interval",b"interval","verification_uri_complete",b"verification_uri_complete"]) -> None: ...
165
169
  global___GetLoginDetailsResponse = GetLoginDetailsResponse
166
170
 
167
171
  class GetAuthTokensRequest(google.protobuf.message.Message):
@@ -210,3 +214,89 @@ class StopRunResponse(google.protobuf.message.Message):
210
214
  ) -> None: ...
211
215
  def ClearField(self, field_name: typing_extensions.Literal["success",b"success"]) -> None: ...
212
216
  global___StopRunResponse = StopRunResponse
217
+
218
+ class PullArtifactsRequest(google.protobuf.message.Message):
219
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
220
+ RUN_ID_FIELD_NUMBER: builtins.int
221
+ run_id: builtins.int
222
+ def __init__(self,
223
+ *,
224
+ run_id: builtins.int = ...,
225
+ ) -> None: ...
226
+ def ClearField(self, field_name: typing_extensions.Literal["run_id",b"run_id"]) -> None: ...
227
+ global___PullArtifactsRequest = PullArtifactsRequest
228
+
229
+ class PullArtifactsResponse(google.protobuf.message.Message):
230
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
231
+ URL_FIELD_NUMBER: builtins.int
232
+ url: typing.Text
233
+ def __init__(self,
234
+ *,
235
+ url: typing.Optional[typing.Text] = ...,
236
+ ) -> None: ...
237
+ def HasField(self, field_name: typing_extensions.Literal["_url",b"_url","url",b"url"]) -> builtins.bool: ...
238
+ def ClearField(self, field_name: typing_extensions.Literal["_url",b"_url","url",b"url"]) -> None: ...
239
+ def WhichOneof(self, oneof_group: typing_extensions.Literal["_url",b"_url"]) -> typing.Optional[typing_extensions.Literal["url"]]: ...
240
+ global___PullArtifactsResponse = PullArtifactsResponse
241
+
242
+ class RegisterNodeRequest(google.protobuf.message.Message):
243
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
244
+ PUBLIC_KEY_FIELD_NUMBER: builtins.int
245
+ public_key: builtins.bytes
246
+ def __init__(self,
247
+ *,
248
+ public_key: builtins.bytes = ...,
249
+ ) -> None: ...
250
+ def ClearField(self, field_name: typing_extensions.Literal["public_key",b"public_key"]) -> None: ...
251
+ global___RegisterNodeRequest = RegisterNodeRequest
252
+
253
+ class RegisterNodeResponse(google.protobuf.message.Message):
254
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
255
+ NODE_ID_FIELD_NUMBER: builtins.int
256
+ node_id: builtins.int
257
+ def __init__(self,
258
+ *,
259
+ node_id: typing.Optional[builtins.int] = ...,
260
+ ) -> None: ...
261
+ def HasField(self, field_name: typing_extensions.Literal["_node_id",b"_node_id","node_id",b"node_id"]) -> builtins.bool: ...
262
+ def ClearField(self, field_name: typing_extensions.Literal["_node_id",b"_node_id","node_id",b"node_id"]) -> None: ...
263
+ def WhichOneof(self, oneof_group: typing_extensions.Literal["_node_id",b"_node_id"]) -> typing.Optional[typing_extensions.Literal["node_id"]]: ...
264
+ global___RegisterNodeResponse = RegisterNodeResponse
265
+
266
+ class UnregisterNodeRequest(google.protobuf.message.Message):
267
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
268
+ NODE_ID_FIELD_NUMBER: builtins.int
269
+ node_id: builtins.int
270
+ def __init__(self,
271
+ *,
272
+ node_id: builtins.int = ...,
273
+ ) -> None: ...
274
+ def ClearField(self, field_name: typing_extensions.Literal["node_id",b"node_id"]) -> None: ...
275
+ global___UnregisterNodeRequest = UnregisterNodeRequest
276
+
277
+ class UnregisterNodeResponse(google.protobuf.message.Message):
278
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
279
+ def __init__(self,
280
+ ) -> None: ...
281
+ global___UnregisterNodeResponse = UnregisterNodeResponse
282
+
283
+ class ListNodesRequest(google.protobuf.message.Message):
284
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
285
+ def __init__(self,
286
+ ) -> None: ...
287
+ global___ListNodesRequest = ListNodesRequest
288
+
289
+ class ListNodesResponse(google.protobuf.message.Message):
290
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
291
+ NODES_INFO_FIELD_NUMBER: builtins.int
292
+ NOW_FIELD_NUMBER: builtins.int
293
+ @property
294
+ def nodes_info(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[flwr.proto.node_pb2.NodeInfo]: ...
295
+ now: typing.Text
296
+ def __init__(self,
297
+ *,
298
+ nodes_info: typing.Optional[typing.Iterable[flwr.proto.node_pb2.NodeInfo]] = ...,
299
+ now: typing.Text = ...,
300
+ ) -> None: ...
301
+ def ClearField(self, field_name: typing_extensions.Literal["nodes_info",b"nodes_info","now",b"now"]) -> None: ...
302
+ global___ListNodesResponse = ListNodesResponse