flwr-nightly 1.19.0.dev20250527__py3-none-any.whl → 1.19.0.dev20250529__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.
- flwr/cli/log.py +3 -3
- flwr/cli/login/login.py +3 -7
- flwr/cli/ls.py +3 -3
- flwr/cli/run/run.py +2 -6
- flwr/cli/stop.py +2 -2
- flwr/cli/utils.py +5 -4
- flwr/client/grpc_rere_client/connection.py +2 -0
- flwr/client/message_handler/message_handler.py +1 -1
- flwr/client/mod/comms_mods.py +36 -17
- flwr/common/auth_plugin/auth_plugin.py +8 -2
- flwr/common/inflatable.py +33 -2
- flwr/common/message.py +11 -0
- flwr/common/record/array.py +38 -1
- flwr/common/record/arrayrecord.py +34 -0
- flwr/common/serde.py +6 -1
- flwr/proto/fleet_pb2.py +16 -16
- flwr/proto/fleet_pb2.pyi +5 -5
- flwr/proto/message_pb2.py +10 -10
- flwr/proto/message_pb2.pyi +4 -4
- flwr/proto/serverappio_pb2.py +26 -26
- flwr/proto/serverappio_pb2.pyi +5 -5
- flwr/server/app.py +52 -56
- flwr/server/grid/grpc_grid.py +2 -1
- flwr/server/grid/inmemory_grid.py +5 -4
- flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +1 -0
- flwr/server/superlink/fleet/message_handler/message_handler.py +11 -3
- flwr/server/superlink/fleet/rest_rere/rest_api.py +3 -1
- flwr/server/superlink/fleet/vce/vce_api.py +3 -0
- flwr/server/superlink/linkstate/in_memory_linkstate.py +14 -25
- flwr/server/superlink/linkstate/linkstate.py +9 -10
- flwr/server/superlink/linkstate/sqlite_linkstate.py +11 -21
- flwr/server/superlink/linkstate/utils.py +23 -23
- flwr/server/superlink/serverappio/serverappio_servicer.py +16 -11
- flwr/server/superlink/utils.py +29 -0
- flwr/server/utils/validator.py +2 -2
- flwr/supercore/object_store/in_memory_object_store.py +30 -4
- flwr/supercore/object_store/object_store.py +48 -1
- flwr/superexec/exec_servicer.py +1 -2
- {flwr_nightly-1.19.0.dev20250527.dist-info → flwr_nightly-1.19.0.dev20250529.dist-info}/METADATA +1 -1
- {flwr_nightly-1.19.0.dev20250527.dist-info → flwr_nightly-1.19.0.dev20250529.dist-info}/RECORD +42 -42
- {flwr_nightly-1.19.0.dev20250527.dist-info → flwr_nightly-1.19.0.dev20250529.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.19.0.dev20250527.dist-info → flwr_nightly-1.19.0.dev20250529.dist-info}/entry_points.txt +0 -0
flwr/cli/log.py
CHANGED
@@ -35,7 +35,7 @@ from flwr.common.logger import log as logger
|
|
35
35
|
from flwr.proto.exec_pb2 import StreamLogsRequest # pylint: disable=E0611
|
36
36
|
from flwr.proto.exec_pb2_grpc import ExecStub
|
37
37
|
|
38
|
-
from .utils import init_channel, try_obtain_cli_auth_plugin
|
38
|
+
from .utils import flwr_cli_grpc_exc_handler, init_channel, try_obtain_cli_auth_plugin
|
39
39
|
|
40
40
|
|
41
41
|
class AllLogsRetrieved(BaseException):
|
@@ -95,7 +95,7 @@ def stream_logs(
|
|
95
95
|
latest_timestamp = 0.0
|
96
96
|
res = None
|
97
97
|
try:
|
98
|
-
with
|
98
|
+
with flwr_cli_grpc_exc_handler():
|
99
99
|
for res in stub.StreamLogs(req, timeout=duration):
|
100
100
|
print(res.log_output, end="")
|
101
101
|
raise AllLogsRetrieved()
|
@@ -116,7 +116,7 @@ def print_logs(run_id: int, channel: grpc.Channel, timeout: int) -> None:
|
|
116
116
|
req = StreamLogsRequest(run_id=run_id, after_timestamp=0.0)
|
117
117
|
|
118
118
|
try:
|
119
|
-
with
|
119
|
+
with flwr_cli_grpc_exc_handler():
|
120
120
|
# Enforce timeout for graceful exit
|
121
121
|
for res in stub.StreamLogs(req, timeout=timeout):
|
122
122
|
print(res.log_output)
|
flwr/cli/login/login.py
CHANGED
@@ -35,11 +35,7 @@ from flwr.proto.exec_pb2 import ( # pylint: disable=E0611
|
|
35
35
|
)
|
36
36
|
from flwr.proto.exec_pb2_grpc import ExecStub
|
37
37
|
|
38
|
-
from ..utils import
|
39
|
-
init_channel,
|
40
|
-
try_obtain_cli_auth_plugin,
|
41
|
-
unauthenticated_exc_handler,
|
42
|
-
)
|
38
|
+
from ..utils import flwr_cli_grpc_exc_handler, init_channel, try_obtain_cli_auth_plugin
|
43
39
|
|
44
40
|
|
45
41
|
def login( # pylint: disable=R0914
|
@@ -96,7 +92,7 @@ def login( # pylint: disable=R0914
|
|
96
92
|
stub = ExecStub(channel)
|
97
93
|
|
98
94
|
login_request = GetLoginDetailsRequest()
|
99
|
-
with
|
95
|
+
with flwr_cli_grpc_exc_handler():
|
100
96
|
login_response: GetLoginDetailsResponse = stub.GetLoginDetails(login_request)
|
101
97
|
|
102
98
|
# Get the auth plugin
|
@@ -120,7 +116,7 @@ def login( # pylint: disable=R0914
|
|
120
116
|
expires_in=login_response.expires_in,
|
121
117
|
interval=login_response.interval,
|
122
118
|
)
|
123
|
-
with
|
119
|
+
with flwr_cli_grpc_exc_handler():
|
124
120
|
credentials = auth_plugin.login(details, stub)
|
125
121
|
|
126
122
|
# Store the tokens
|
flwr/cli/ls.py
CHANGED
@@ -44,7 +44,7 @@ from flwr.proto.exec_pb2 import ( # pylint: disable=E0611
|
|
44
44
|
)
|
45
45
|
from flwr.proto.exec_pb2_grpc import ExecStub
|
46
46
|
|
47
|
-
from .utils import init_channel, try_obtain_cli_auth_plugin
|
47
|
+
from .utils import flwr_cli_grpc_exc_handler, init_channel, try_obtain_cli_auth_plugin
|
48
48
|
|
49
49
|
_RunListType = tuple[int, str, str, str, str, str, str, str, str]
|
50
50
|
|
@@ -305,7 +305,7 @@ def _list_runs(
|
|
305
305
|
output_format: str = CliOutputFormat.DEFAULT,
|
306
306
|
) -> None:
|
307
307
|
"""List all runs."""
|
308
|
-
with
|
308
|
+
with flwr_cli_grpc_exc_handler():
|
309
309
|
res: ListRunsResponse = stub.ListRuns(ListRunsRequest())
|
310
310
|
run_dict = {run_id: run_from_proto(proto) for run_id, proto in res.run_dict.items()}
|
311
311
|
|
@@ -322,7 +322,7 @@ def _display_one_run(
|
|
322
322
|
output_format: str = CliOutputFormat.DEFAULT,
|
323
323
|
) -> None:
|
324
324
|
"""Display information about a specific run."""
|
325
|
-
with
|
325
|
+
with flwr_cli_grpc_exc_handler():
|
326
326
|
res: ListRunsResponse = stub.ListRuns(ListRunsRequest(run_id=run_id))
|
327
327
|
if not res.run_dict:
|
328
328
|
raise ValueError(f"Run ID {run_id} not found")
|
flwr/cli/run/run.py
CHANGED
@@ -45,11 +45,7 @@ from flwr.proto.exec_pb2 import StartRunRequest # pylint: disable=E0611
|
|
45
45
|
from flwr.proto.exec_pb2_grpc import ExecStub
|
46
46
|
|
47
47
|
from ..log import start_stream
|
48
|
-
from ..utils import
|
49
|
-
init_channel,
|
50
|
-
try_obtain_cli_auth_plugin,
|
51
|
-
unauthenticated_exc_handler,
|
52
|
-
)
|
48
|
+
from ..utils import flwr_cli_grpc_exc_handler, init_channel, try_obtain_cli_auth_plugin
|
53
49
|
|
54
50
|
CONN_REFRESH_PERIOD = 60 # Connection refresh period for log streaming (seconds)
|
55
51
|
|
@@ -172,7 +168,7 @@ def _run_with_exec_api(
|
|
172
168
|
override_config=user_config_to_proto(parse_config_args(config_overrides)),
|
173
169
|
federation_options=config_record_to_proto(c_record),
|
174
170
|
)
|
175
|
-
with
|
171
|
+
with flwr_cli_grpc_exc_handler():
|
176
172
|
res = stub.StartRun(req)
|
177
173
|
|
178
174
|
if res.HasField("run_id"):
|
flwr/cli/stop.py
CHANGED
@@ -35,7 +35,7 @@ from flwr.common.logger import print_json_error, redirect_output, restore_output
|
|
35
35
|
from flwr.proto.exec_pb2 import StopRunRequest, StopRunResponse # pylint: disable=E0611
|
36
36
|
from flwr.proto.exec_pb2_grpc import ExecStub
|
37
37
|
|
38
|
-
from .utils import init_channel, try_obtain_cli_auth_plugin
|
38
|
+
from .utils import flwr_cli_grpc_exc_handler, init_channel, try_obtain_cli_auth_plugin
|
39
39
|
|
40
40
|
|
41
41
|
def stop( # pylint: disable=R0914
|
@@ -122,7 +122,7 @@ def stop( # pylint: disable=R0914
|
|
122
122
|
|
123
123
|
def _stop_run(stub: ExecStub, run_id: int, output_format: str) -> None:
|
124
124
|
"""Stop a run."""
|
125
|
-
with
|
125
|
+
with flwr_cli_grpc_exc_handler():
|
126
126
|
response: StopRunResponse = stub.StopRun(request=StopRunRequest(run_id=run_id))
|
127
127
|
if response.success:
|
128
128
|
typer.secho(f"✅ Run {run_id} successfully stopped.", fg=typer.colors.GREEN)
|
flwr/cli/utils.py
CHANGED
@@ -288,11 +288,12 @@ def init_channel(
|
|
288
288
|
|
289
289
|
|
290
290
|
@contextmanager
|
291
|
-
def
|
292
|
-
"""Context manager to handle gRPC
|
291
|
+
def flwr_cli_grpc_exc_handler() -> Iterator[None]:
|
292
|
+
"""Context manager to handle specific gRPC errors.
|
293
293
|
|
294
|
-
It catches grpc.RpcError exceptions with UNAUTHENTICATED
|
295
|
-
and exits the application. All other exceptions will be allowed to
|
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.
|
296
297
|
"""
|
297
298
|
try:
|
298
299
|
yield
|
@@ -279,6 +279,8 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
279
279
|
log(ERROR, "No current message")
|
280
280
|
return
|
281
281
|
|
282
|
+
# Set message_id
|
283
|
+
message.metadata.__dict__["_message_id"] = message.object_id
|
282
284
|
# Validate out message
|
283
285
|
if not validate_out_message(message, metadata):
|
284
286
|
log(ERROR, "Invalid out message")
|
@@ -164,7 +164,7 @@ def validate_out_message(out_message: Message, in_message_metadata: Metadata) ->
|
|
164
164
|
in_meta = in_message_metadata
|
165
165
|
if ( # pylint: disable-next=too-many-boolean-expressions
|
166
166
|
out_meta.run_id == in_meta.run_id
|
167
|
-
and out_meta.message_id ==
|
167
|
+
and out_meta.message_id == out_message.object_id # Should match the object id
|
168
168
|
and out_meta.src_node_id == in_meta.dst_node_id
|
169
169
|
and out_meta.dst_node_id == in_meta.src_node_id
|
170
170
|
and out_meta.reply_to_message_id == in_meta.message_id
|
flwr/client/mod/comms_mods.py
CHANGED
@@ -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
|
-
|
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
|
-
|
38
|
-
|
39
|
+
# Call the next layer
|
40
|
+
msg = call_next(msg, ctxt)
|
39
41
|
|
40
|
-
|
41
|
-
|
42
|
-
|
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
|
-
|
54
|
-
|
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
|
-
|
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
|
@@ -69,12 +72,15 @@ class ExecAuthzPlugin(ABC): # pylint: disable=too-few-public-methods
|
|
69
72
|
|
70
73
|
Parameters
|
71
74
|
----------
|
72
|
-
|
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,
|
83
|
+
def __init__(self, user_auth_config_path: Path, verify_tls_cert: bool):
|
78
84
|
"""Abstract constructor."""
|
79
85
|
|
80
86
|
@abstractmethod
|
flwr/common/inflatable.py
CHANGED
@@ -18,7 +18,7 @@
|
|
18
18
|
from __future__ import annotations
|
19
19
|
|
20
20
|
import hashlib
|
21
|
-
from typing import TypeVar
|
21
|
+
from typing import TypeVar, cast
|
22
22
|
|
23
23
|
from .constant import HEAD_BODY_DIVIDER, HEAD_VALUE_DIVIDER
|
24
24
|
|
@@ -55,13 +55,24 @@ class InflatableObject:
|
|
55
55
|
@property
|
56
56
|
def object_id(self) -> str:
|
57
57
|
"""Get object_id."""
|
58
|
-
|
58
|
+
if self.is_dirty or "_object_id" not in self.__dict__:
|
59
|
+
self.__dict__["_object_id"] = get_object_id(self.deflate())
|
60
|
+
return cast(str, self.__dict__["_object_id"])
|
59
61
|
|
60
62
|
@property
|
61
63
|
def children(self) -> dict[str, InflatableObject] | None:
|
62
64
|
"""Get all child objects as a dictionary or None if there are no children."""
|
63
65
|
return None
|
64
66
|
|
67
|
+
@property
|
68
|
+
def is_dirty(self) -> bool:
|
69
|
+
"""Check if the object is dirty after the last deflation.
|
70
|
+
|
71
|
+
An object is considered dirty if its content has changed since the last its
|
72
|
+
object ID was computed.
|
73
|
+
"""
|
74
|
+
return True
|
75
|
+
|
65
76
|
|
66
77
|
T = TypeVar("T", bound=InflatableObject)
|
67
78
|
|
@@ -178,3 +189,23 @@ def get_object_head_values_from_object_content(
|
|
178
189
|
obj_type, children_str, body_len = head.split(HEAD_VALUE_DIVIDER)
|
179
190
|
children_ids = children_str.split(",") if children_str else []
|
180
191
|
return obj_type, children_ids, int(body_len)
|
192
|
+
|
193
|
+
|
194
|
+
def _get_descendants_object_ids_recursively(obj: InflatableObject) -> set[str]:
|
195
|
+
|
196
|
+
descendants: set[str] = set()
|
197
|
+
if children := obj.children:
|
198
|
+
for child in children.values():
|
199
|
+
descendants |= _get_descendants_object_ids_recursively(child)
|
200
|
+
|
201
|
+
descendants.add(obj.object_id)
|
202
|
+
|
203
|
+
return descendants
|
204
|
+
|
205
|
+
|
206
|
+
def get_desdendant_object_ids(obj: InflatableObject) -> set[str]:
|
207
|
+
"""Get a set of object IDs of all descendants."""
|
208
|
+
descendants = _get_descendants_object_ids_recursively(obj)
|
209
|
+
# Exclude Object ID of parent object
|
210
|
+
descendants.discard(obj.object_id)
|
211
|
+
return descendants
|
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
|
+
}
|
flwr/common/record/array.py
CHANGED
@@ -107,10 +107,21 @@ class Array(InflatableObject):
|
|
107
107
|
"""
|
108
108
|
|
109
109
|
dtype: str
|
110
|
-
shape: list[int]
|
111
110
|
stype: str
|
112
111
|
data: bytes
|
113
112
|
|
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
|
+
|
114
125
|
@overload
|
115
126
|
def __init__( # noqa: E704
|
116
127
|
self, dtype: str, shape: list[int], stype: str, data: bytes
|
@@ -295,3 +306,29 @@ class Array(InflatableObject):
|
|
295
306
|
stype=proto_array.stype,
|
296
307
|
data=proto_array.data,
|
297
308
|
)
|
309
|
+
|
310
|
+
@property
|
311
|
+
def object_id(self) -> str:
|
312
|
+
"""Get object ID."""
|
313
|
+
ret = super().object_id
|
314
|
+
self.is_dirty = False # Reset dirty flag
|
315
|
+
return ret
|
316
|
+
|
317
|
+
@property
|
318
|
+
def is_dirty(self) -> bool:
|
319
|
+
"""Check if the object is dirty after the last deflation."""
|
320
|
+
if "_is_dirty" not in self.__dict__:
|
321
|
+
self.__dict__["_is_dirty"] = True
|
322
|
+
return cast(bool, self.__dict__["_is_dirty"])
|
323
|
+
|
324
|
+
@is_dirty.setter
|
325
|
+
def is_dirty(self, value: bool) -> None:
|
326
|
+
"""Set the dirty flag."""
|
327
|
+
self.__dict__["_is_dirty"] = value
|
328
|
+
|
329
|
+
def __setattr__(self, name: str, value: Any) -> None:
|
330
|
+
"""Set attribute with special handling for dirty state."""
|
331
|
+
if name in ("dtype", "stype", "data"):
|
332
|
+
# Mark as dirty if any of the main attributes are set
|
333
|
+
self.is_dirty = True
|
334
|
+
super().__setattr__(name, value)
|
@@ -429,6 +429,40 @@ class ArrayRecord(TypedDict[str, Array], InflatableObject):
|
|
429
429
|
)
|
430
430
|
)
|
431
431
|
|
432
|
+
@property
|
433
|
+
def object_id(self) -> str:
|
434
|
+
"""Get object ID."""
|
435
|
+
ret = super().object_id
|
436
|
+
self.is_dirty = False # Reset dirty flag
|
437
|
+
return ret
|
438
|
+
|
439
|
+
@property
|
440
|
+
def is_dirty(self) -> bool:
|
441
|
+
"""Check if the object is dirty after the last deflation."""
|
442
|
+
if "_is_dirty" not in self.__dict__:
|
443
|
+
self.__dict__["_is_dirty"] = True
|
444
|
+
|
445
|
+
if not self.__dict__["_is_dirty"]:
|
446
|
+
if any(v.is_dirty for v in self.values()):
|
447
|
+
# If any Array is dirty, mark the record as dirty
|
448
|
+
self.__dict__["_is_dirty"] = True
|
449
|
+
return cast(bool, self.__dict__["_is_dirty"])
|
450
|
+
|
451
|
+
@is_dirty.setter
|
452
|
+
def is_dirty(self, value: bool) -> None:
|
453
|
+
"""Set the dirty flag."""
|
454
|
+
self.__dict__["_is_dirty"] = value
|
455
|
+
|
456
|
+
def __setitem__(self, key: str, value: Array) -> None:
|
457
|
+
"""Set item and mark the record as dirty."""
|
458
|
+
self.is_dirty = True # Mark as dirty when setting an item
|
459
|
+
super().__setitem__(key, value)
|
460
|
+
|
461
|
+
def __delitem__(self, key: str) -> None:
|
462
|
+
"""Delete item and mark the record as dirty."""
|
463
|
+
self.is_dirty = True # Mark as dirty when deleting an item
|
464
|
+
super().__delitem__(key)
|
465
|
+
|
432
466
|
|
433
467
|
class ParametersRecord(ArrayRecord):
|
434
468
|
"""Deprecated class ``ParametersRecord``, use ``ArrayRecord`` instead.
|
flwr/common/serde.py
CHANGED
@@ -378,7 +378,12 @@ def scalar_from_proto(scalar_msg: Scalar) -> typing.Scalar:
|
|
378
378
|
|
379
379
|
def array_to_proto(array: Array) -> ProtoArray:
|
380
380
|
"""Serialize Array to ProtoBuf."""
|
381
|
-
return ProtoArray(
|
381
|
+
return ProtoArray(
|
382
|
+
dtype=array.dtype,
|
383
|
+
shape=array.shape,
|
384
|
+
stype=array.stype,
|
385
|
+
data=array.data,
|
386
|
+
)
|
382
387
|
|
383
388
|
|
384
389
|
def array_from_proto(array_proto: ProtoArray) -> Array:
|
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\"\
|
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['
|
32
|
-
_globals['
|
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=
|
53
|
-
_globals['
|
54
|
-
_globals['
|
55
|
-
_globals['_PUSHMESSAGESRESPONSE']._serialized_start=
|
56
|
-
_globals['_PUSHMESSAGESRESPONSE']._serialized_end=
|
57
|
-
_globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_start=
|
58
|
-
_globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_end=
|
59
|
-
_globals['_PUSHMESSAGESRESPONSE_OBJECTSTOPUSHENTRY']._serialized_start=
|
60
|
-
_globals['_PUSHMESSAGESRESPONSE_OBJECTSTOPUSHENTRY']._serialized_end=
|
61
|
-
_globals['_RECONNECT']._serialized_start=
|
62
|
-
_globals['_RECONNECT']._serialized_end=
|
63
|
-
_globals['_FLEET']._serialized_start=
|
64
|
-
_globals['_FLEET']._serialized_end=
|
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
|
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
|
-
|
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
|
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
|
-
|
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","
|
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\"\
|
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=
|
44
|
-
_globals['_PUSHOBJECTREQUEST']._serialized_start=
|
45
|
-
_globals['_PUSHOBJECTREQUEST']._serialized_end=
|
46
|
-
_globals['_PUSHOBJECTRESPONSE']._serialized_start=
|
47
|
-
_globals['_PUSHOBJECTRESPONSE']._serialized_end=
|
48
|
-
_globals['_PULLOBJECTREQUEST']._serialized_start=
|
49
|
-
_globals['_PULLOBJECTREQUEST']._serialized_end=
|
50
|
-
_globals['_PULLOBJECTRESPONSE']._serialized_start=
|
51
|
-
_globals['_PULLOBJECTRESPONSE']._serialized_end=
|
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)
|
flwr/proto/message_pb2.pyi
CHANGED
@@ -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
|
-
|
133
|
+
OBJECT_IDS_FIELD_NUMBER: builtins.int
|
134
134
|
@property
|
135
|
-
def
|
135
|
+
def object_ids(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[typing.Text]: ...
|
136
136
|
def __init__(self,
|
137
137
|
*,
|
138
|
-
|
138
|
+
object_ids: typing.Optional[typing.Iterable[typing.Text]] = ...,
|
139
139
|
) -> None: ...
|
140
|
-
def ClearField(self, field_name: typing_extensions.Literal["
|
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):
|