flwr-nightly 1.19.0.dev20250528__py3-none-any.whl → 1.19.0.dev20250530__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 (33) hide show
  1. flwr/cli/utils.py +11 -3
  2. flwr/client/mod/comms_mods.py +36 -17
  3. flwr/common/auth_plugin/auth_plugin.py +9 -3
  4. flwr/common/exit_handlers.py +30 -0
  5. flwr/common/inflatable_grpc_utils.py +27 -13
  6. flwr/common/message.py +11 -0
  7. flwr/common/record/array.py +10 -21
  8. flwr/common/record/arrayrecord.py +1 -1
  9. flwr/common/recorddict_compat.py +2 -2
  10. flwr/common/serde.py +1 -1
  11. flwr/proto/fleet_pb2.py +16 -16
  12. flwr/proto/fleet_pb2.pyi +5 -5
  13. flwr/proto/message_pb2.py +10 -10
  14. flwr/proto/message_pb2.pyi +4 -4
  15. flwr/proto/serverappio_pb2.py +26 -26
  16. flwr/proto/serverappio_pb2.pyi +5 -5
  17. flwr/server/app.py +45 -57
  18. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +2 -0
  19. flwr/server/superlink/fleet/message_handler/message_handler.py +34 -7
  20. flwr/server/superlink/fleet/rest_rere/rest_api.py +5 -2
  21. flwr/server/superlink/linkstate/utils.py +8 -5
  22. flwr/server/superlink/serverappio/serverappio_servicer.py +45 -5
  23. flwr/server/superlink/utils.py +29 -0
  24. flwr/supercore/object_store/__init__.py +2 -1
  25. flwr/supercore/object_store/in_memory_object_store.py +9 -2
  26. flwr/supercore/object_store/object_store.py +12 -0
  27. flwr/superexec/exec_grpc.py +4 -3
  28. flwr/superexec/exec_user_auth_interceptor.py +33 -4
  29. flwr/supernode/start_client_internal.py +144 -170
  30. {flwr_nightly-1.19.0.dev20250528.dist-info → flwr_nightly-1.19.0.dev20250530.dist-info}/METADATA +1 -1
  31. {flwr_nightly-1.19.0.dev20250528.dist-info → flwr_nightly-1.19.0.dev20250530.dist-info}/RECORD +33 -33
  32. {flwr_nightly-1.19.0.dev20250528.dist-info → flwr_nightly-1.19.0.dev20250530.dist-info}/WHEEL +0 -0
  33. {flwr_nightly-1.19.0.dev20250528.dist-info → flwr_nightly-1.19.0.dev20250530.dist-info}/entry_points.txt +0 -0
flwr/cli/utils.py CHANGED
@@ -291,9 +291,9 @@ def init_channel(
291
291
  def flwr_cli_grpc_exc_handler() -> Iterator[None]:
292
292
  """Context manager to handle specific gRPC errors.
293
293
 
294
- It catches grpc.RpcError exceptions with UNAUTHENTICATED and UNIMPLEMENTED statuses,
295
- informs the user, and exits the application. All other exceptions will be allowed to
296
- escape.
294
+ It catches grpc.RpcError exceptions with UNAUTHENTICATED, UNIMPLEMENTED, and
295
+ PERMISSION_DENIED statuses, informs the user, and exits the application. All other
296
+ exceptions will be allowed to escape.
297
297
  """
298
298
  try:
299
299
  yield
@@ -313,4 +313,12 @@ def flwr_cli_grpc_exc_handler() -> Iterator[None]:
313
313
  bold=True,
314
314
  )
315
315
  raise typer.Exit(code=1) from None
316
+ if e.code() == grpc.StatusCode.PERMISSION_DENIED:
317
+ typer.secho(
318
+ "❌ Authorization failed. Please contact your administrator"
319
+ " to check your permissions.",
320
+ fg=typer.colors.RED,
321
+ bold=True,
322
+ )
323
+ raise typer.Exit(code=1) from None
316
324
  raise
@@ -32,14 +32,17 @@ def message_size_mod(
32
32
 
33
33
  This mod logs the size in bytes of the message being transmited.
34
34
  """
35
- message_size_in_bytes = 0
35
+ # Log the size of the incoming message in bytes
36
+ total_bytes = sum(record.count_bytes() for record in msg.content.values())
37
+ log(INFO, "Incoming message size: %i bytes", total_bytes)
36
38
 
37
- for record in msg.content.values():
38
- message_size_in_bytes += record.count_bytes()
39
+ # Call the next layer
40
+ msg = call_next(msg, ctxt)
39
41
 
40
- log(INFO, "Message size: %i bytes", message_size_in_bytes)
41
-
42
- return call_next(msg, ctxt)
42
+ # Log the size of the outgoing message in bytes
43
+ total_bytes = sum(record.count_bytes() for record in msg.content.values())
44
+ log(INFO, "Outgoing message size: %i bytes", total_bytes)
45
+ return msg
43
46
 
44
47
 
45
48
  def arrays_size_mod(
@@ -50,25 +53,41 @@ def arrays_size_mod(
50
53
  This mod logs the number of array elements transmitted in ``ArrayRecord`` objects
51
54
  of the message as well as their sizes in bytes.
52
55
  """
53
- model_size_stats = {}
54
- arrays_size_in_bytes = 0
56
+ # Log the ArrayRecord size statistics and the total size in the incoming message
57
+ array_record_size_stats = _get_array_record_size_stats(msg)
58
+ total_bytes = sum(stat["bytes"] for stat in array_record_size_stats.values())
59
+ if array_record_size_stats:
60
+ log(INFO, "Incoming `ArrayRecord` size statistics:")
61
+ log(INFO, array_record_size_stats)
62
+ log(INFO, "Total array elements received: %i bytes", total_bytes)
63
+
64
+ msg = call_next(msg, ctxt)
65
+
66
+ # Log the ArrayRecord size statistics and the total size in the outgoing message
67
+ array_record_size_stats = _get_array_record_size_stats(msg)
68
+ total_bytes = sum(stat["bytes"] for stat in array_record_size_stats.values())
69
+ if array_record_size_stats:
70
+ log(INFO, "Outgoing `ArrayRecord` size statistics:")
71
+ log(INFO, array_record_size_stats)
72
+ log(INFO, "Total array elements sent: %i bytes", total_bytes)
73
+ return msg
74
+
75
+
76
+ def _get_array_record_size_stats(
77
+ msg: Message,
78
+ ) -> dict[str, dict[str, int]]:
79
+ """Get `ArrayRecord` size statistics from the message."""
80
+ array_record_size_stats = {}
55
81
  for record_name, arr_record in msg.content.array_records.items():
56
82
  arr_record_bytes = arr_record.count_bytes()
57
- arrays_size_in_bytes += arr_record_bytes
58
83
  element_count = 0
59
84
  for array in arr_record.values():
60
85
  element_count += (
61
86
  int(np.prod(array.shape)) if array.shape else array.numpy().size
62
87
  )
63
88
 
64
- model_size_stats[f"{record_name}"] = {
89
+ array_record_size_stats[record_name] = {
65
90
  "elements": element_count,
66
91
  "bytes": arr_record_bytes,
67
92
  }
68
-
69
- if model_size_stats:
70
- log(INFO, model_size_stats)
71
-
72
- log(INFO, "Total array elements transmitted: %i bytes", arrays_size_in_bytes)
73
-
74
- return call_next(msg, ctxt)
93
+ return array_record_size_stats
@@ -33,6 +33,9 @@ class ExecAuthPlugin(ABC):
33
33
  ----------
34
34
  user_auth_config_path : Path
35
35
  Path to the YAML file containing the authentication configuration.
36
+ verify_tls_cert : bool
37
+ Boolean indicating whether to verify the TLS certificate
38
+ when making requests to the server.
36
39
  """
37
40
 
38
41
  @abstractmethod
@@ -60,7 +63,7 @@ class ExecAuthPlugin(ABC):
60
63
  @abstractmethod
61
64
  def refresh_tokens(
62
65
  self, metadata: Sequence[tuple[str, Union[str, bytes]]]
63
- ) -> Optional[Sequence[tuple[str, Union[str, bytes]]]]:
66
+ ) -> tuple[Optional[Sequence[tuple[str, Union[str, bytes]]]], Optional[UserInfo]]:
64
67
  """Refresh authentication tokens in the provided metadata."""
65
68
 
66
69
 
@@ -69,12 +72,15 @@ class ExecAuthzPlugin(ABC): # pylint: disable=too-few-public-methods
69
72
 
70
73
  Parameters
71
74
  ----------
72
- user_authz_config_path : Path
75
+ user_auth_config_path : Path
73
76
  Path to the YAML file containing the authorization configuration.
77
+ verify_tls_cert : bool
78
+ Boolean indicating whether to verify the TLS certificate
79
+ when making requests to the server.
74
80
  """
75
81
 
76
82
  @abstractmethod
77
- def __init__(self, user_authz_config_path: Path, verify_tls_cert: bool):
83
+ def __init__(self, user_auth_config_path: Path, verify_tls_cert: bool):
78
84
  """Abstract constructor."""
79
85
 
80
86
  @abstractmethod
@@ -30,6 +30,7 @@ SIGNAL_TO_EXIT_CODE: dict[int, int] = {
30
30
  signal.SIGINT: ExitCode.GRACEFUL_EXIT_SIGINT,
31
31
  signal.SIGTERM: ExitCode.GRACEFUL_EXIT_SIGTERM,
32
32
  }
33
+ registered_exit_handlers: list[Callable[[], None]] = []
33
34
 
34
35
  # SIGQUIT is not available on Windows
35
36
  if hasattr(signal, "SIGQUIT"):
@@ -41,6 +42,7 @@ def register_exit_handlers(
41
42
  exit_message: Optional[str] = None,
42
43
  grpc_servers: Optional[list[Server]] = None,
43
44
  bckg_threads: Optional[list[Thread]] = None,
45
+ exit_handlers: Optional[list[Callable[[], None]]] = None,
44
46
  ) -> None:
45
47
  """Register exit handlers for `SIGINT`, `SIGTERM` and `SIGQUIT` signals.
46
48
 
@@ -56,8 +58,12 @@ def register_exit_handlers(
56
58
  bckg_threads: Optional[List[Thread]] (default: None)
57
59
  An optional list of threads that need to be gracefully
58
60
  terminated before exiting.
61
+ exit_handlers: Optional[List[Callable[[], None]]] (default: None)
62
+ An optional list of exit handlers to be called before exiting.
63
+ Additional exit handlers can be added using `add_exit_handler`.
59
64
  """
60
65
  default_handlers: dict[int, Callable[[int, FrameType], None]] = {}
66
+ registered_exit_handlers.extend(exit_handlers or [])
61
67
 
62
68
  def graceful_exit_handler(signalnum: int, _frame: FrameType) -> None:
63
69
  """Exit handler to be registered with `signal.signal`.
@@ -68,6 +74,9 @@ def register_exit_handlers(
68
74
  # Reset to default handler
69
75
  signal.signal(signalnum, default_handlers[signalnum]) # type: ignore
70
76
 
77
+ for handler in registered_exit_handlers:
78
+ handler()
79
+
71
80
  if grpc_servers is not None:
72
81
  for grpc_server in grpc_servers:
73
82
  grpc_server.stop(grace=1)
@@ -87,3 +96,24 @@ def register_exit_handlers(
87
96
  for sig in SIGNAL_TO_EXIT_CODE:
88
97
  default_handler = signal.signal(sig, graceful_exit_handler) # type: ignore
89
98
  default_handlers[sig] = default_handler # type: ignore
99
+
100
+
101
+ def add_exit_handler(exit_handler: Callable[[], None]) -> None:
102
+ """Add an exit handler to be called on graceful exit.
103
+
104
+ This function allows you to register additional exit handlers
105
+ that will be executed when the application exits gracefully,
106
+ if `register_exit_handlers` was called.
107
+
108
+ Parameters
109
+ ----------
110
+ exit_handler : Callable[[], None]
111
+ A callable that takes no arguments and performs cleanup or
112
+ other actions before the application exits.
113
+
114
+ Notes
115
+ -----
116
+ This method is not thread-safe, and it allows you to add the
117
+ same exit handler multiple times.
118
+ """
119
+ registered_exit_handlers.append(exit_handler)
@@ -15,7 +15,7 @@
15
15
  """InflatableObject utils."""
16
16
 
17
17
 
18
- from typing import Union
18
+ from typing import Optional, Union
19
19
 
20
20
  from flwr.proto.fleet_pb2_grpc import FleetStub # pylint: disable=E0611
21
21
  from flwr.proto.message_pb2 import ( # pylint: disable=E0611
@@ -24,6 +24,7 @@ from flwr.proto.message_pb2 import ( # pylint: disable=E0611
24
24
  PushObjectRequest,
25
25
  PushObjectResponse,
26
26
  )
27
+ from flwr.proto.node_pb2 import Node # pylint: disable=E0611
27
28
  from flwr.proto.serverappio_pb2_grpc import ServerAppIoStub # pylint: disable=E0611
28
29
 
29
30
  from .inflatable import (
@@ -46,40 +47,51 @@ inflatable_class_registry: dict[str, type[InflatableObject]] = {
46
47
 
47
48
 
48
49
  def push_object_to_servicer(
49
- obj: InflatableObject, stub: Union[FleetStub, ServerAppIoStub]
50
+ obj: InflatableObject,
51
+ stub: Union[FleetStub, ServerAppIoStub],
52
+ node: Node,
53
+ object_ids_to_push: Optional[set[str]] = None,
50
54
  ) -> set[str]:
51
55
  """Recursively deflate an object and push it to the servicer.
52
56
 
53
- Objects with the same ID are not pushed twice. It returns the set of pushed object
57
+ Objects with the same ID are not pushed twice. If `object_ids_to_push` is set,
58
+ only objects with those IDs are pushed. It returns the set of pushed object
54
59
  IDs.
55
60
  """
56
61
  pushed_object_ids: set[str] = set()
57
62
  # Push children if it has any
58
63
  if children := obj.children:
59
64
  for child in children.values():
60
- pushed_object_ids |= push_object_to_servicer(child, stub)
65
+ pushed_object_ids |= push_object_to_servicer(
66
+ child, stub, node, object_ids_to_push
67
+ )
61
68
 
62
69
  # Deflate object and push
63
70
  object_content = obj.deflate()
64
71
  object_id = get_object_id(object_content)
65
- _: PushObjectResponse = stub.PushObject(
66
- PushObjectRequest(
67
- object_id=object_id,
68
- object_content=object_content,
72
+ # Push always if no object set is specified, or if the object is in the set
73
+ if object_ids_to_push is None or object_id in object_ids_to_push:
74
+ _: PushObjectResponse = stub.PushObject(
75
+ PushObjectRequest(
76
+ node=node,
77
+ object_id=object_id,
78
+ object_content=object_content,
79
+ )
69
80
  )
70
- )
71
- pushed_object_ids.add(object_id)
81
+ pushed_object_ids.add(object_id)
72
82
 
73
83
  return pushed_object_ids
74
84
 
75
85
 
76
86
  def pull_object_from_servicer(
77
- object_id: str, stub: Union[FleetStub, ServerAppIoStub]
87
+ object_id: str,
88
+ stub: Union[FleetStub, ServerAppIoStub],
89
+ node: Node,
78
90
  ) -> InflatableObject:
79
91
  """Recursively inflate an object by pulling it from the servicer."""
80
92
  # Pull object
81
93
  object_proto: PullObjectResponse = stub.PullObject(
82
- PullObjectRequest(object_id=object_id)
94
+ PullObjectRequest(node=node, object_id=object_id)
83
95
  )
84
96
  object_content = object_proto.object_content
85
97
 
@@ -93,7 +105,9 @@ def pull_object_from_servicer(
93
105
  # Pull all children objects
94
106
  children: dict[str, InflatableObject] = {}
95
107
  for child_object_id in children_obj_ids:
96
- children[child_object_id] = pull_object_from_servicer(child_object_id, stub)
108
+ children[child_object_id] = pull_object_from_servicer(
109
+ child_object_id, stub, node
110
+ )
97
111
 
98
112
  # Inflate object passing its children
99
113
  return cls_type.inflate(object_content, children=children)
flwr/common/message.py CHANGED
@@ -24,6 +24,7 @@ from flwr.common.date import now
24
24
  from flwr.common.logger import warn_deprecated_feature
25
25
  from flwr.proto.message_pb2 import Message as ProtoMessage # pylint: disable=E0611
26
26
  from flwr.proto.message_pb2 import Metadata as ProtoMetadata # pylint: disable=E0611
27
+ from flwr.proto.message_pb2 import ObjectIDs # pylint: disable=E0611
27
28
 
28
29
  from ..app.error import Error
29
30
  from ..app.metadata import Metadata
@@ -31,6 +32,7 @@ from .constant import MESSAGE_TTL_TOLERANCE
31
32
  from .inflatable import (
32
33
  InflatableObject,
33
34
  add_header_to_object_body,
35
+ get_desdendant_object_ids,
34
36
  get_object_body,
35
37
  get_object_children_ids_from_object_content,
36
38
  )
@@ -505,3 +507,12 @@ def _check_arg_types( # pylint: disable=too-many-arguments, R0917
505
507
  ):
506
508
  return
507
509
  raise MessageInitializationError()
510
+
511
+
512
+ def get_message_to_descendant_id_mapping(message: Message) -> dict[str, ObjectIDs]:
513
+ """Construct a mapping between message object_id and that of its descendants."""
514
+ return {
515
+ message.object_id: ObjectIDs(
516
+ object_ids=list(get_desdendant_object_ids(message))
517
+ )
518
+ }
@@ -62,8 +62,8 @@ class Array(InflatableObject):
62
62
  A string representing the data type of the serialized object (e.g. `"float32"`).
63
63
  Only required if you are not passing in a ndarray or a tensor.
64
64
 
65
- shape : Optional[list[int]] (default: None)
66
- A list representing the shape of the unserialized array-like object. Only
65
+ shape : Optional[tuple[int, ...]] (default: None)
66
+ A tuple representing the shape of the unserialized array-like object. Only
67
67
  required if you are not passing in a ndarray or a tensor.
68
68
 
69
69
  stype : Optional[str] (default: None)
@@ -107,24 +107,13 @@ class Array(InflatableObject):
107
107
  """
108
108
 
109
109
  dtype: str
110
+ shape: tuple[int, ...]
110
111
  stype: str
111
112
  data: bytes
112
113
 
113
- @property
114
- def shape(self) -> list[int]:
115
- """Get the shape of the array."""
116
- self.is_dirty = True # Mark as dirty when shape is accessed
117
- return cast(list[int], self.__dict__["_shape"])
118
-
119
- @shape.setter
120
- def shape(self, value: list[int]) -> None:
121
- """Set the shape of the array."""
122
- self.is_dirty = True # Mark as dirty when shape is set
123
- self.__dict__["_shape"] = value
124
-
125
114
  @overload
126
115
  def __init__( # noqa: E704
127
- self, dtype: str, shape: list[int], stype: str, data: bytes
116
+ self, dtype: str, shape: tuple[int, ...], stype: str, data: bytes
128
117
  ) -> None: ...
129
118
 
130
119
  @overload
@@ -137,7 +126,7 @@ class Array(InflatableObject):
137
126
  self,
138
127
  *args: Any,
139
128
  dtype: str | None = None,
140
- shape: list[int] | None = None,
129
+ shape: tuple[int, ...] | None = None,
141
130
  stype: str | None = None,
142
131
  data: bytes | None = None,
143
132
  ndarray: NDArray | None = None,
@@ -145,7 +134,7 @@ class Array(InflatableObject):
145
134
  ) -> None:
146
135
  # Determine the initialization method and validate input arguments.
147
136
  # Support three initialization formats:
148
- # 1. Array(dtype: str, shape: list[int], stype: str, data: bytes)
137
+ # 1. Array(dtype: str, shape: tuple[int, ...], stype: str, data: bytes)
149
138
  # 2. Array(ndarray: NDArray)
150
139
  # 3. Array(torch_tensor: torch.Tensor)
151
140
 
@@ -192,7 +181,7 @@ class Array(InflatableObject):
192
181
  if (
193
182
  len(all_args) == 4 # pylint: disable=too-many-boolean-expressions
194
183
  and isinstance(all_args[0], str)
195
- and isinstance(all_args[1], list)
184
+ and isinstance(all_args[1], tuple)
196
185
  and all(isinstance(i, int) for i in all_args[1])
197
186
  and isinstance(all_args[2], str)
198
187
  and isinstance(all_args[3], bytes)
@@ -232,7 +221,7 @@ class Array(InflatableObject):
232
221
  data = buffer.getvalue()
233
222
  return Array(
234
223
  dtype=str(ndarray.dtype),
235
- shape=list(ndarray.shape),
224
+ shape=tuple(ndarray.shape),
236
225
  stype=SType.NUMPY,
237
226
  data=data,
238
227
  )
@@ -302,7 +291,7 @@ class Array(InflatableObject):
302
291
  proto_array = ArrayProto.FromString(obj_body)
303
292
  return cls(
304
293
  dtype=proto_array.dtype,
305
- shape=list(proto_array.shape),
294
+ shape=tuple(proto_array.shape),
306
295
  stype=proto_array.stype,
307
296
  data=proto_array.data,
308
297
  )
@@ -328,7 +317,7 @@ class Array(InflatableObject):
328
317
 
329
318
  def __setattr__(self, name: str, value: Any) -> None:
330
319
  """Set attribute with special handling for dirty state."""
331
- if name in ("dtype", "stype", "data"):
320
+ if name in ("dtype", "shape", "stype", "data"):
332
321
  # Mark as dirty if any of the main attributes are set
333
322
  self.is_dirty = True
334
323
  super().__setattr__(name, value)
@@ -252,7 +252,7 @@ class ArrayRecord(TypedDict[str, Array], InflatableObject):
252
252
  record = ArrayRecord()
253
253
  for k, v in array_dict.items():
254
254
  record[k] = Array(
255
- dtype=v.dtype, shape=list(v.shape), stype=v.stype, data=v.data
255
+ dtype=v.dtype, shape=tuple(v.shape), stype=v.stype, data=v.data
256
256
  )
257
257
  if not keep_input:
258
258
  array_dict.clear()
@@ -111,12 +111,12 @@ def parameters_to_arrayrecord(parameters: Parameters, keep_input: bool) -> Array
111
111
  else:
112
112
  tensor = parameters.tensors.pop(0)
113
113
  ordered_dict[str(idx)] = Array(
114
- data=tensor, dtype="", stype=tensor_type, shape=[]
114
+ data=tensor, dtype="", stype=tensor_type, shape=()
115
115
  )
116
116
 
117
117
  if num_arrays == 0:
118
118
  ordered_dict[EMPTY_TENSOR_KEY] = Array(
119
- data=b"", dtype="", stype=tensor_type, shape=[]
119
+ data=b"", dtype="", stype=tensor_type, shape=()
120
120
  )
121
121
  return ArrayRecord(ordered_dict, keep_input=keep_input)
122
122
 
flwr/common/serde.py CHANGED
@@ -390,7 +390,7 @@ def array_from_proto(array_proto: ProtoArray) -> Array:
390
390
  """Deserialize Array from ProtoBuf."""
391
391
  return Array(
392
392
  dtype=array_proto.dtype,
393
- shape=list(array_proto.shape),
393
+ shape=tuple(array_proto.shape),
394
394
  stype=array_proto.stype,
395
395
  data=array_proto.data,
396
396
  )
flwr/proto/fleet_pb2.py CHANGED
@@ -19,7 +19,7 @@ from flwr.proto import fab_pb2 as flwr_dot_proto_dot_fab__pb2
19
19
  from flwr.proto import message_pb2 as flwr_dot_proto_dot_message__pb2
20
20
 
21
21
 
22
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x66lwr/proto/fleet.proto\x12\nflwr.proto\x1a\x1a\x66lwr/proto/heartbeat.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x14\x66lwr/proto/run.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x18\x66lwr/proto/message.proto\"/\n\x11\x43reateNodeRequest\x12\x1a\n\x12heartbeat_interval\x18\x01 \x01(\x01\"4\n\x12\x43reateNodeResponse\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"3\n\x11\x44\x65leteNodeRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"\x14\n\x12\x44\x65leteNodeResponse\"J\n\x13PullMessagesRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x13\n\x0bmessage_ids\x18\x02 \x03(\t\"\x87\x02\n\x14PullMessagesResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12*\n\rmessages_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.Message\x12L\n\x0fobjects_to_pull\x18\x03 \x03(\x0b\x32\x33.flwr.proto.PullMessagesResponse.ObjectsToPullEntry\x1aK\n\x12ObjectsToPullEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.flwr.proto.ObjectIDs:\x02\x38\x01\"\x91\x02\n\x13PushMessagesRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12*\n\rmessages_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.Message\x12Z\n\x17msg_to_children_mapping\x18\x03 \x03(\x0b\x32\x39.flwr.proto.PushMessagesRequest.MsgToChildrenMappingEntry\x1aR\n\x19MsgToChildrenMappingEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.flwr.proto.ObjectIDs:\x02\x38\x01\"\xcb\x02\n\x14PushMessagesResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12>\n\x07results\x18\x02 \x03(\x0b\x32-.flwr.proto.PushMessagesResponse.ResultsEntry\x12L\n\x0fobjects_to_push\x18\x03 \x03(\x0b\x32\x33.flwr.proto.PushMessagesResponse.ObjectsToPushEntry\x1a.\n\x0cResultsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\r:\x02\x38\x01\x1aK\n\x12ObjectsToPushEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.flwr.proto.ObjectIDs:\x02\x38\x01\"\x1e\n\tReconnect\x12\x11\n\treconnect\x18\x01 \x01(\x04\x32\xd7\x05\n\x05\x46leet\x12M\n\nCreateNode\x12\x1d.flwr.proto.CreateNodeRequest\x1a\x1e.flwr.proto.CreateNodeResponse\"\x00\x12M\n\nDeleteNode\x12\x1d.flwr.proto.DeleteNodeRequest\x1a\x1e.flwr.proto.DeleteNodeResponse\"\x00\x12\x62\n\x11SendNodeHeartbeat\x12$.flwr.proto.SendNodeHeartbeatRequest\x1a%.flwr.proto.SendNodeHeartbeatResponse\"\x00\x12S\n\x0cPullMessages\x12\x1f.flwr.proto.PullMessagesRequest\x1a .flwr.proto.PullMessagesResponse\"\x00\x12S\n\x0cPushMessages\x12\x1f.flwr.proto.PushMessagesRequest\x1a .flwr.proto.PushMessagesResponse\"\x00\x12\x41\n\x06GetRun\x12\x19.flwr.proto.GetRunRequest\x1a\x1a.flwr.proto.GetRunResponse\"\x00\x12\x41\n\x06GetFab\x12\x19.flwr.proto.GetFabRequest\x1a\x1a.flwr.proto.GetFabResponse\"\x00\x12M\n\nPushObject\x12\x1d.flwr.proto.PushObjectRequest\x1a\x1e.flwr.proto.PushObjectResponse\"\x00\x12M\n\nPullObject\x12\x1d.flwr.proto.PullObjectRequest\x1a\x1e.flwr.proto.PullObjectResponse\"\x00\x62\x06proto3')
22
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x66lwr/proto/fleet.proto\x12\nflwr.proto\x1a\x1a\x66lwr/proto/heartbeat.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x14\x66lwr/proto/run.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x18\x66lwr/proto/message.proto\"/\n\x11\x43reateNodeRequest\x12\x1a\n\x12heartbeat_interval\x18\x01 \x01(\x01\"4\n\x12\x43reateNodeResponse\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"3\n\x11\x44\x65leteNodeRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"\x14\n\x12\x44\x65leteNodeResponse\"J\n\x13PullMessagesRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x13\n\x0bmessage_ids\x18\x02 \x03(\t\"\x87\x02\n\x14PullMessagesResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12*\n\rmessages_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.Message\x12L\n\x0fobjects_to_pull\x18\x03 \x03(\x0b\x32\x33.flwr.proto.PullMessagesResponse.ObjectsToPullEntry\x1aK\n\x12ObjectsToPullEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.flwr.proto.ObjectIDs:\x02\x38\x01\"\x97\x02\n\x13PushMessagesRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12*\n\rmessages_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.Message\x12^\n\x19msg_to_descendant_mapping\x18\x03 \x03(\x0b\x32;.flwr.proto.PushMessagesRequest.MsgToDescendantMappingEntry\x1aT\n\x1bMsgToDescendantMappingEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.flwr.proto.ObjectIDs:\x02\x38\x01\"\xcb\x02\n\x14PushMessagesResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12>\n\x07results\x18\x02 \x03(\x0b\x32-.flwr.proto.PushMessagesResponse.ResultsEntry\x12L\n\x0fobjects_to_push\x18\x03 \x03(\x0b\x32\x33.flwr.proto.PushMessagesResponse.ObjectsToPushEntry\x1a.\n\x0cResultsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\r:\x02\x38\x01\x1aK\n\x12ObjectsToPushEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.flwr.proto.ObjectIDs:\x02\x38\x01\"\x1e\n\tReconnect\x12\x11\n\treconnect\x18\x01 \x01(\x04\x32\xd7\x05\n\x05\x46leet\x12M\n\nCreateNode\x12\x1d.flwr.proto.CreateNodeRequest\x1a\x1e.flwr.proto.CreateNodeResponse\"\x00\x12M\n\nDeleteNode\x12\x1d.flwr.proto.DeleteNodeRequest\x1a\x1e.flwr.proto.DeleteNodeResponse\"\x00\x12\x62\n\x11SendNodeHeartbeat\x12$.flwr.proto.SendNodeHeartbeatRequest\x1a%.flwr.proto.SendNodeHeartbeatResponse\"\x00\x12S\n\x0cPullMessages\x12\x1f.flwr.proto.PullMessagesRequest\x1a .flwr.proto.PullMessagesResponse\"\x00\x12S\n\x0cPushMessages\x12\x1f.flwr.proto.PushMessagesRequest\x1a .flwr.proto.PushMessagesResponse\"\x00\x12\x41\n\x06GetRun\x12\x19.flwr.proto.GetRunRequest\x1a\x1a.flwr.proto.GetRunResponse\"\x00\x12\x41\n\x06GetFab\x12\x19.flwr.proto.GetFabRequest\x1a\x1a.flwr.proto.GetFabResponse\"\x00\x12M\n\nPushObject\x12\x1d.flwr.proto.PushObjectRequest\x1a\x1e.flwr.proto.PushObjectResponse\"\x00\x12M\n\nPullObject\x12\x1d.flwr.proto.PullObjectRequest\x1a\x1e.flwr.proto.PullObjectResponse\"\x00\x62\x06proto3')
23
23
 
24
24
  _globals = globals()
25
25
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -28,8 +28,8 @@ if _descriptor._USE_C_DESCRIPTORS == False:
28
28
  DESCRIPTOR._options = None
29
29
  _globals['_PULLMESSAGESRESPONSE_OBJECTSTOPULLENTRY']._options = None
30
30
  _globals['_PULLMESSAGESRESPONSE_OBJECTSTOPULLENTRY']._serialized_options = b'8\001'
31
- _globals['_PUSHMESSAGESREQUEST_MSGTOCHILDRENMAPPINGENTRY']._options = None
32
- _globals['_PUSHMESSAGESREQUEST_MSGTOCHILDRENMAPPINGENTRY']._serialized_options = b'8\001'
31
+ _globals['_PUSHMESSAGESREQUEST_MSGTODESCENDANTMAPPINGENTRY']._options = None
32
+ _globals['_PUSHMESSAGESREQUEST_MSGTODESCENDANTMAPPINGENTRY']._serialized_options = b'8\001'
33
33
  _globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._options = None
34
34
  _globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_options = b'8\001'
35
35
  _globals['_PUSHMESSAGESRESPONSE_OBJECTSTOPUSHENTRY']._options = None
@@ -49,17 +49,17 @@ if _descriptor._USE_C_DESCRIPTORS == False:
49
49
  _globals['_PULLMESSAGESRESPONSE_OBJECTSTOPULLENTRY']._serialized_start=602
50
50
  _globals['_PULLMESSAGESRESPONSE_OBJECTSTOPULLENTRY']._serialized_end=677
51
51
  _globals['_PUSHMESSAGESREQUEST']._serialized_start=680
52
- _globals['_PUSHMESSAGESREQUEST']._serialized_end=953
53
- _globals['_PUSHMESSAGESREQUEST_MSGTOCHILDRENMAPPINGENTRY']._serialized_start=871
54
- _globals['_PUSHMESSAGESREQUEST_MSGTOCHILDRENMAPPINGENTRY']._serialized_end=953
55
- _globals['_PUSHMESSAGESRESPONSE']._serialized_start=956
56
- _globals['_PUSHMESSAGESRESPONSE']._serialized_end=1287
57
- _globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_start=1164
58
- _globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_end=1210
59
- _globals['_PUSHMESSAGESRESPONSE_OBJECTSTOPUSHENTRY']._serialized_start=1212
60
- _globals['_PUSHMESSAGESRESPONSE_OBJECTSTOPUSHENTRY']._serialized_end=1287
61
- _globals['_RECONNECT']._serialized_start=1289
62
- _globals['_RECONNECT']._serialized_end=1319
63
- _globals['_FLEET']._serialized_start=1322
64
- _globals['_FLEET']._serialized_end=2049
52
+ _globals['_PUSHMESSAGESREQUEST']._serialized_end=959
53
+ _globals['_PUSHMESSAGESREQUEST_MSGTODESCENDANTMAPPINGENTRY']._serialized_start=875
54
+ _globals['_PUSHMESSAGESREQUEST_MSGTODESCENDANTMAPPINGENTRY']._serialized_end=959
55
+ _globals['_PUSHMESSAGESRESPONSE']._serialized_start=962
56
+ _globals['_PUSHMESSAGESRESPONSE']._serialized_end=1293
57
+ _globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_start=1170
58
+ _globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_end=1216
59
+ _globals['_PUSHMESSAGESRESPONSE_OBJECTSTOPUSHENTRY']._serialized_start=1218
60
+ _globals['_PUSHMESSAGESRESPONSE_OBJECTSTOPUSHENTRY']._serialized_end=1293
61
+ _globals['_RECONNECT']._serialized_start=1295
62
+ _globals['_RECONNECT']._serialized_end=1325
63
+ _globals['_FLEET']._serialized_start=1328
64
+ _globals['_FLEET']._serialized_end=2055
65
65
  # @@protoc_insertion_point(module_scope)
flwr/proto/fleet_pb2.pyi CHANGED
@@ -115,7 +115,7 @@ global___PullMessagesResponse = PullMessagesResponse
115
115
  class PushMessagesRequest(google.protobuf.message.Message):
116
116
  """PushMessages messages"""
117
117
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
118
- class MsgToChildrenMappingEntry(google.protobuf.message.Message):
118
+ class MsgToDescendantMappingEntry(google.protobuf.message.Message):
119
119
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
120
120
  KEY_FIELD_NUMBER: builtins.int
121
121
  VALUE_FIELD_NUMBER: builtins.int
@@ -132,21 +132,21 @@ class PushMessagesRequest(google.protobuf.message.Message):
132
132
 
133
133
  NODE_FIELD_NUMBER: builtins.int
134
134
  MESSAGES_LIST_FIELD_NUMBER: builtins.int
135
- MSG_TO_CHILDREN_MAPPING_FIELD_NUMBER: builtins.int
135
+ MSG_TO_DESCENDANT_MAPPING_FIELD_NUMBER: builtins.int
136
136
  @property
137
137
  def node(self) -> flwr.proto.node_pb2.Node: ...
138
138
  @property
139
139
  def messages_list(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[flwr.proto.message_pb2.Message]: ...
140
140
  @property
141
- def msg_to_children_mapping(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, flwr.proto.message_pb2.ObjectIDs]: ...
141
+ def msg_to_descendant_mapping(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, flwr.proto.message_pb2.ObjectIDs]: ...
142
142
  def __init__(self,
143
143
  *,
144
144
  node: typing.Optional[flwr.proto.node_pb2.Node] = ...,
145
145
  messages_list: typing.Optional[typing.Iterable[flwr.proto.message_pb2.Message]] = ...,
146
- msg_to_children_mapping: typing.Optional[typing.Mapping[typing.Text, flwr.proto.message_pb2.ObjectIDs]] = ...,
146
+ msg_to_descendant_mapping: typing.Optional[typing.Mapping[typing.Text, flwr.proto.message_pb2.ObjectIDs]] = ...,
147
147
  ) -> None: ...
148
148
  def HasField(self, field_name: typing_extensions.Literal["node",b"node"]) -> builtins.bool: ...
149
- def ClearField(self, field_name: typing_extensions.Literal["messages_list",b"messages_list","msg_to_children_mapping",b"msg_to_children_mapping","node",b"node"]) -> None: ...
149
+ def ClearField(self, field_name: typing_extensions.Literal["messages_list",b"messages_list","msg_to_descendant_mapping",b"msg_to_descendant_mapping","node",b"node"]) -> None: ...
150
150
  global___PushMessagesRequest = PushMessagesRequest
151
151
 
152
152
  class PushMessagesResponse(google.protobuf.message.Message):
flwr/proto/message_pb2.py CHANGED
@@ -18,7 +18,7 @@ from flwr.proto import transport_pb2 as flwr_dot_proto_dot_transport__pb2
18
18
  from flwr.proto import node_pb2 as flwr_dot_proto_dot_node__pb2
19
19
 
20
20
 
21
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18\x66lwr/proto/message.proto\x12\nflwr.proto\x1a\x16\x66lwr/proto/error.proto\x1a\x1b\x66lwr/proto/recorddict.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x15\x66lwr/proto/node.proto\"|\n\x07Message\x12&\n\x08metadata\x18\x01 \x01(\x0b\x32\x14.flwr.proto.Metadata\x12\'\n\x07\x63ontent\x18\x02 \x01(\x0b\x32\x16.flwr.proto.RecordDict\x12 \n\x05\x65rror\x18\x03 \x01(\x0b\x32\x11.flwr.proto.Error\"\xd0\x02\n\x07\x43ontext\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x0f\n\x07node_id\x18\x02 \x01(\x04\x12\x38\n\x0bnode_config\x18\x03 \x03(\x0b\x32#.flwr.proto.Context.NodeConfigEntry\x12%\n\x05state\x18\x04 \x01(\x0b\x32\x16.flwr.proto.RecordDict\x12\x36\n\nrun_config\x18\x05 \x03(\x0b\x32\".flwr.proto.Context.RunConfigEntry\x1a\x45\n\x0fNodeConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\x1a\x44\n\x0eRunConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"\xbe\x01\n\x08Metadata\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x12\n\nmessage_id\x18\x02 \x01(\t\x12\x13\n\x0bsrc_node_id\x18\x03 \x01(\x04\x12\x13\n\x0b\x64st_node_id\x18\x04 \x01(\x04\x12\x1b\n\x13reply_to_message_id\x18\x05 \x01(\t\x12\x10\n\x08group_id\x18\x06 \x01(\t\x12\x0b\n\x03ttl\x18\x07 \x01(\x01\x12\x14\n\x0cmessage_type\x18\x08 \x01(\t\x12\x12\n\ncreated_at\x18\t \x01(\x01\"\x1e\n\tObjectIDs\x12\x11\n\tobject_id\x18\x01 \x03(\t\"^\n\x11PushObjectRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x11\n\tobject_id\x18\x02 \x01(\t\x12\x16\n\x0eobject_content\x18\x03 \x01(\x0c\"\x14\n\x12PushObjectResponse\"F\n\x11PullObjectRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x11\n\tobject_id\x18\x02 \x01(\t\",\n\x12PullObjectResponse\x12\x16\n\x0eobject_content\x18\x01 \x01(\x0c\x62\x06proto3')
21
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18\x66lwr/proto/message.proto\x12\nflwr.proto\x1a\x16\x66lwr/proto/error.proto\x1a\x1b\x66lwr/proto/recorddict.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x15\x66lwr/proto/node.proto\"|\n\x07Message\x12&\n\x08metadata\x18\x01 \x01(\x0b\x32\x14.flwr.proto.Metadata\x12\'\n\x07\x63ontent\x18\x02 \x01(\x0b\x32\x16.flwr.proto.RecordDict\x12 \n\x05\x65rror\x18\x03 \x01(\x0b\x32\x11.flwr.proto.Error\"\xd0\x02\n\x07\x43ontext\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x0f\n\x07node_id\x18\x02 \x01(\x04\x12\x38\n\x0bnode_config\x18\x03 \x03(\x0b\x32#.flwr.proto.Context.NodeConfigEntry\x12%\n\x05state\x18\x04 \x01(\x0b\x32\x16.flwr.proto.RecordDict\x12\x36\n\nrun_config\x18\x05 \x03(\x0b\x32\".flwr.proto.Context.RunConfigEntry\x1a\x45\n\x0fNodeConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\x1a\x44\n\x0eRunConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"\xbe\x01\n\x08Metadata\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x12\n\nmessage_id\x18\x02 \x01(\t\x12\x13\n\x0bsrc_node_id\x18\x03 \x01(\x04\x12\x13\n\x0b\x64st_node_id\x18\x04 \x01(\x04\x12\x1b\n\x13reply_to_message_id\x18\x05 \x01(\t\x12\x10\n\x08group_id\x18\x06 \x01(\t\x12\x0b\n\x03ttl\x18\x07 \x01(\x01\x12\x14\n\x0cmessage_type\x18\x08 \x01(\t\x12\x12\n\ncreated_at\x18\t \x01(\x01\"\x1f\n\tObjectIDs\x12\x12\n\nobject_ids\x18\x01 \x03(\t\"^\n\x11PushObjectRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x11\n\tobject_id\x18\x02 \x01(\t\x12\x16\n\x0eobject_content\x18\x03 \x01(\x0c\"\x14\n\x12PushObjectResponse\"F\n\x11PullObjectRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x11\n\tobject_id\x18\x02 \x01(\t\",\n\x12PullObjectResponse\x12\x16\n\x0eobject_content\x18\x01 \x01(\x0c\x62\x06proto3')
22
22
 
23
23
  _globals = globals()
24
24
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -40,13 +40,13 @@ if _descriptor._USE_C_DESCRIPTORS == False:
40
40
  _globals['_METADATA']._serialized_start=610
41
41
  _globals['_METADATA']._serialized_end=800
42
42
  _globals['_OBJECTIDS']._serialized_start=802
43
- _globals['_OBJECTIDS']._serialized_end=832
44
- _globals['_PUSHOBJECTREQUEST']._serialized_start=834
45
- _globals['_PUSHOBJECTREQUEST']._serialized_end=928
46
- _globals['_PUSHOBJECTRESPONSE']._serialized_start=930
47
- _globals['_PUSHOBJECTRESPONSE']._serialized_end=950
48
- _globals['_PULLOBJECTREQUEST']._serialized_start=952
49
- _globals['_PULLOBJECTREQUEST']._serialized_end=1022
50
- _globals['_PULLOBJECTRESPONSE']._serialized_start=1024
51
- _globals['_PULLOBJECTRESPONSE']._serialized_end=1068
43
+ _globals['_OBJECTIDS']._serialized_end=833
44
+ _globals['_PUSHOBJECTREQUEST']._serialized_start=835
45
+ _globals['_PUSHOBJECTREQUEST']._serialized_end=929
46
+ _globals['_PUSHOBJECTRESPONSE']._serialized_start=931
47
+ _globals['_PUSHOBJECTRESPONSE']._serialized_end=951
48
+ _globals['_PULLOBJECTREQUEST']._serialized_start=953
49
+ _globals['_PULLOBJECTREQUEST']._serialized_end=1023
50
+ _globals['_PULLOBJECTRESPONSE']._serialized_start=1025
51
+ _globals['_PULLOBJECTRESPONSE']._serialized_end=1069
52
52
  # @@protoc_insertion_point(module_scope)
@@ -130,14 +130,14 @@ global___Metadata = Metadata
130
130
 
131
131
  class ObjectIDs(google.protobuf.message.Message):
132
132
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
133
- OBJECT_ID_FIELD_NUMBER: builtins.int
133
+ OBJECT_IDS_FIELD_NUMBER: builtins.int
134
134
  @property
135
- def object_id(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[typing.Text]: ...
135
+ def object_ids(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[typing.Text]: ...
136
136
  def __init__(self,
137
137
  *,
138
- object_id: typing.Optional[typing.Iterable[typing.Text]] = ...,
138
+ object_ids: typing.Optional[typing.Iterable[typing.Text]] = ...,
139
139
  ) -> None: ...
140
- def ClearField(self, field_name: typing_extensions.Literal["object_id",b"object_id"]) -> None: ...
140
+ def ClearField(self, field_name: typing_extensions.Literal["object_ids",b"object_ids"]) -> None: ...
141
141
  global___ObjectIDs = ObjectIDs
142
142
 
143
143
  class PushObjectRequest(google.protobuf.message.Message):