flwr-nightly 1.20.0.dev20250714__py3-none-any.whl → 1.20.0.dev20250716__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/client/grpc_rere_client/connection.py +10 -8
- flwr/client/rest_client/connection.py +11 -8
- flwr/common/grpc.py +12 -1
- flwr/common/{inflatable_grpc_utils.py → inflatable_protobuf_utils.py} +12 -10
- flwr/proto/fleet_pb2.py +14 -18
- flwr/proto/fleet_pb2.pyi +4 -19
- flwr/server/grid/grpc_grid.py +7 -7
- flwr/server/superlink/fleet/message_handler/message_handler.py +8 -13
- flwr/server/superlink/serverappio/serverappio_servicer.py +4 -8
- flwr/server/superlink/utils.py +1 -9
- flwr/supercore/grpc_health/__init__.py +22 -0
- flwr/supercore/grpc_health/simple_health_servicer.py +38 -0
- flwr/supercore/object_store/in_memory_object_store.py +31 -31
- flwr/supercore/object_store/object_store.py +16 -40
- {flwr_nightly-1.20.0.dev20250714.dist-info → flwr_nightly-1.20.0.dev20250716.dist-info}/METADATA +2 -1
- {flwr_nightly-1.20.0.dev20250714.dist-info → flwr_nightly-1.20.0.dev20250716.dist-info}/RECORD +18 -17
- flwr/common/inflatable_rest_utils.py +0 -99
- {flwr_nightly-1.20.0.dev20250714.dist-info → flwr_nightly-1.20.0.dev20250716.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.20.0.dev20250714.dist-info → flwr_nightly-1.20.0.dev20250716.dist-info}/entry_points.txt +0 -0
@@ -31,11 +31,12 @@ from flwr.common.heartbeat import HeartbeatSender
|
|
31
31
|
from flwr.common.inflatable import (
|
32
32
|
get_all_nested_objects,
|
33
33
|
get_object_tree,
|
34
|
+
iterate_object_tree,
|
34
35
|
no_object_id_recompute,
|
35
36
|
)
|
36
|
-
from flwr.common.
|
37
|
-
|
38
|
-
|
37
|
+
from flwr.common.inflatable_protobuf_utils import (
|
38
|
+
make_pull_object_fn_protobuf,
|
39
|
+
make_push_object_fn_protobuf,
|
39
40
|
)
|
40
41
|
from flwr.common.inflatable_utils import (
|
41
42
|
inflate_object_from_contents,
|
@@ -273,10 +274,11 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
273
274
|
if message_proto:
|
274
275
|
msg_id = message_proto.metadata.message_id
|
275
276
|
run_id = message_proto.metadata.run_id
|
277
|
+
object_tree = response.message_object_trees[0]
|
276
278
|
all_object_contents = pull_objects(
|
277
|
-
|
278
|
-
pull_object_fn=
|
279
|
-
|
279
|
+
[tree.object_id for tree in iterate_object_tree(object_tree)],
|
280
|
+
pull_object_fn=make_pull_object_fn_protobuf(
|
281
|
+
pull_object_protobuf=stub.PullObject,
|
280
282
|
node=node,
|
281
283
|
run_id=run_id,
|
282
284
|
),
|
@@ -328,8 +330,8 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
328
330
|
)
|
329
331
|
push_objects(
|
330
332
|
all_objects,
|
331
|
-
push_object_fn=
|
332
|
-
|
333
|
+
push_object_fn=make_push_object_fn_protobuf(
|
334
|
+
push_object_protobuf=stub.PushObject,
|
333
335
|
node=node,
|
334
336
|
run_id=message.metadata.run_id,
|
335
337
|
),
|
@@ -14,6 +14,7 @@
|
|
14
14
|
# ==============================================================================
|
15
15
|
"""Contextmanager for a REST request-response channel to the Flower server."""
|
16
16
|
|
17
|
+
|
17
18
|
from collections.abc import Iterator
|
18
19
|
from contextlib import contextmanager
|
19
20
|
from logging import DEBUG, ERROR, INFO, WARN
|
@@ -30,11 +31,12 @@ from flwr.common.heartbeat import HeartbeatSender
|
|
30
31
|
from flwr.common.inflatable import (
|
31
32
|
get_all_nested_objects,
|
32
33
|
get_object_tree,
|
34
|
+
iterate_object_tree,
|
33
35
|
no_object_id_recompute,
|
34
36
|
)
|
35
|
-
from flwr.common.
|
36
|
-
|
37
|
-
|
37
|
+
from flwr.common.inflatable_protobuf_utils import (
|
38
|
+
make_pull_object_fn_protobuf,
|
39
|
+
make_push_object_fn_protobuf,
|
38
40
|
)
|
39
41
|
from flwr.common.inflatable_utils import (
|
40
42
|
inflate_object_from_contents,
|
@@ -333,10 +335,11 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
333
335
|
return res
|
334
336
|
|
335
337
|
try:
|
338
|
+
object_tree = res.message_object_trees[0]
|
336
339
|
all_object_contents = pull_objects(
|
337
|
-
|
338
|
-
pull_object_fn=
|
339
|
-
|
340
|
+
[tree.object_id for tree in iterate_object_tree(object_tree)],
|
341
|
+
pull_object_fn=make_pull_object_fn_protobuf(
|
342
|
+
pull_object_protobuf=fn,
|
340
343
|
node=node,
|
341
344
|
run_id=run_id,
|
342
345
|
),
|
@@ -413,8 +416,8 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
413
416
|
try:
|
414
417
|
push_objects(
|
415
418
|
all_objects,
|
416
|
-
push_object_fn=
|
417
|
-
|
419
|
+
push_object_fn=make_push_object_fn_protobuf(
|
420
|
+
push_object_protobuf=fn,
|
418
421
|
node=node,
|
419
422
|
run_id=message_proto.metadata.run_id,
|
420
423
|
),
|
flwr/common/grpc.py
CHANGED
@@ -23,6 +23,9 @@ from logging import DEBUG, ERROR
|
|
23
23
|
from typing import Any, Callable, Optional
|
24
24
|
|
25
25
|
import grpc
|
26
|
+
from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server
|
27
|
+
|
28
|
+
from flwr.supercore.grpc_health import SimpleHealthServicer
|
26
29
|
|
27
30
|
from .address import is_port_in_use
|
28
31
|
from .logger import log
|
@@ -98,7 +101,7 @@ def valid_certificates(certificates: tuple[bytes, bytes, bytes]) -> bool:
|
|
98
101
|
return is_valid
|
99
102
|
|
100
103
|
|
101
|
-
def generic_create_grpc_server( # pylint: disable=too-many-arguments,R0917
|
104
|
+
def generic_create_grpc_server( # pylint: disable=too-many-arguments, R0914, R0917
|
102
105
|
servicer_and_add_fn: tuple[Any, AddServicerToServerFn],
|
103
106
|
server_address: str,
|
104
107
|
max_concurrent_workers: int = 1000,
|
@@ -106,6 +109,7 @@ def generic_create_grpc_server( # pylint: disable=too-many-arguments,R0917
|
|
106
109
|
keepalive_time_ms: int = 210000,
|
107
110
|
certificates: Optional[tuple[bytes, bytes, bytes]] = None,
|
108
111
|
interceptors: Optional[Sequence[grpc.ServerInterceptor]] = None,
|
112
|
+
health_servicer: Optional[Any] = None,
|
109
113
|
) -> grpc.Server:
|
110
114
|
"""Create a gRPC server with a single servicer.
|
111
115
|
|
@@ -153,6 +157,10 @@ def generic_create_grpc_server( # pylint: disable=too-many-arguments,R0917
|
|
153
157
|
* server private key.
|
154
158
|
interceptors : Optional[Sequence[grpc.ServerInterceptor]] (default: None)
|
155
159
|
A list of gRPC interceptors.
|
160
|
+
health_servicer : Optional[Any] (default: None)
|
161
|
+
An optional health servicer to add to the server. If provided, it should be an
|
162
|
+
instance of a class that inherits the `HealthServicer` class.
|
163
|
+
If None is provided, `SimpleHealthServicer` will be used by default.
|
156
164
|
|
157
165
|
Returns
|
158
166
|
-------
|
@@ -203,6 +211,9 @@ def generic_create_grpc_server( # pylint: disable=too-many-arguments,R0917
|
|
203
211
|
)
|
204
212
|
add_servicer_to_server_fn(servicer, server)
|
205
213
|
|
214
|
+
# Enable health service
|
215
|
+
add_HealthServicer_to_server(health_servicer or SimpleHealthServicer(), server)
|
216
|
+
|
206
217
|
if certificates is not None:
|
207
218
|
if not valid_certificates(certificates):
|
208
219
|
sys.exit(1)
|
@@ -28,8 +28,8 @@ from flwr.proto.node_pb2 import Node # pylint: disable=E0611
|
|
28
28
|
from .inflatable_utils import ObjectIdNotPreregisteredError, ObjectUnavailableError
|
29
29
|
|
30
30
|
|
31
|
-
def
|
32
|
-
|
31
|
+
def make_pull_object_fn_protobuf(
|
32
|
+
pull_object_protobuf: Callable[[PullObjectRequest], PullObjectResponse],
|
33
33
|
node: Node,
|
34
34
|
run_id: int,
|
35
35
|
) -> Callable[[str], bytes]:
|
@@ -37,8 +37,9 @@ def make_pull_object_fn_grpc(
|
|
37
37
|
|
38
38
|
Parameters
|
39
39
|
----------
|
40
|
-
|
41
|
-
|
40
|
+
pull_object_protobuf : Callable[[PullObjectRequest], PullObjectResponse]
|
41
|
+
A callable that takes a `PullObjectRequest` and returns a `PullObjectResponse`.
|
42
|
+
This function is typically backed by a gRPC client stub.
|
42
43
|
node : Node
|
43
44
|
The node making the request.
|
44
45
|
run_id : int
|
@@ -54,7 +55,7 @@ def make_pull_object_fn_grpc(
|
|
54
55
|
|
55
56
|
def pull_object_fn(object_id: str) -> bytes:
|
56
57
|
request = PullObjectRequest(node=node, run_id=run_id, object_id=object_id)
|
57
|
-
response: PullObjectResponse =
|
58
|
+
response: PullObjectResponse = pull_object_protobuf(request)
|
58
59
|
if not response.object_found:
|
59
60
|
raise ObjectIdNotPreregisteredError(object_id)
|
60
61
|
if not response.object_available:
|
@@ -64,8 +65,8 @@ def make_pull_object_fn_grpc(
|
|
64
65
|
return pull_object_fn
|
65
66
|
|
66
67
|
|
67
|
-
def
|
68
|
-
|
68
|
+
def make_push_object_fn_protobuf(
|
69
|
+
push_object_protobuf: Callable[[PushObjectRequest], PushObjectResponse],
|
69
70
|
node: Node,
|
70
71
|
run_id: int,
|
71
72
|
) -> Callable[[str, bytes], None]:
|
@@ -73,8 +74,9 @@ def make_push_object_fn_grpc(
|
|
73
74
|
|
74
75
|
Parameters
|
75
76
|
----------
|
76
|
-
|
77
|
-
|
77
|
+
push_object_protobuf : Callable[[PushObjectRequest], PushObjectResponse]
|
78
|
+
A callable that takes a `PushObjectRequest` and returns a `PushObjectResponse`.
|
79
|
+
This function is typically backed by a gRPC client stub.
|
78
80
|
node : Node
|
79
81
|
The node making the request.
|
80
82
|
run_id : int
|
@@ -92,7 +94,7 @@ def make_push_object_fn_grpc(
|
|
92
94
|
request = PushObjectRequest(
|
93
95
|
node=node, run_id=run_id, object_id=object_id, object_content=object_content
|
94
96
|
)
|
95
|
-
response: PushObjectResponse =
|
97
|
+
response: PushObjectResponse = push_object_protobuf(request)
|
96
98
|
if not response.stored:
|
97
99
|
raise ObjectIdNotPreregisteredError(object_id)
|
98
100
|
|
flwr/proto/fleet_pb2.py
CHANGED
@@ -19,15 +19,13 @@ 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\"\
|
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\"\xa2\x01\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\x12\x34\n\x14message_object_trees\x18\x03 \x03(\x0b\x32\x16.flwr.proto.ObjectTree\"\x97\x01\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\x34\n\x14message_object_trees\x18\x03 \x03(\x0b\x32\x16.flwr.proto.ObjectTree\"\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\xca\x06\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\x12q\n\x16\x43onfirmMessageReceived\x12).flwr.proto.ConfirmMessageReceivedRequest\x1a*.flwr.proto.ConfirmMessageReceivedResponse\"\x00\x62\x06proto3')
|
23
23
|
|
24
24
|
_globals = globals()
|
25
25
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
26
26
|
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.fleet_pb2', _globals)
|
27
27
|
if _descriptor._USE_C_DESCRIPTORS == False:
|
28
28
|
DESCRIPTOR._options = None
|
29
|
-
_globals['_PULLMESSAGESRESPONSE_OBJECTSTOPULLENTRY']._options = None
|
30
|
-
_globals['_PULLMESSAGESRESPONSE_OBJECTSTOPULLENTRY']._serialized_options = b'8\001'
|
31
29
|
_globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._options = None
|
32
30
|
_globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_options = b'8\001'
|
33
31
|
_globals['_PUSHMESSAGESRESPONSE_OBJECTSTOPUSHENTRY']._options = None
|
@@ -43,19 +41,17 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
|
43
41
|
_globals['_PULLMESSAGESREQUEST']._serialized_start=337
|
44
42
|
_globals['_PULLMESSAGESREQUEST']._serialized_end=411
|
45
43
|
_globals['_PULLMESSAGESRESPONSE']._serialized_start=414
|
46
|
-
_globals['_PULLMESSAGESRESPONSE']._serialized_end=
|
47
|
-
_globals['
|
48
|
-
_globals['
|
49
|
-
_globals['
|
50
|
-
_globals['
|
51
|
-
_globals['
|
52
|
-
_globals['
|
53
|
-
_globals['
|
54
|
-
_globals['
|
55
|
-
_globals['
|
56
|
-
_globals['
|
57
|
-
_globals['
|
58
|
-
_globals['
|
59
|
-
_globals['_FLEET']._serialized_start=1200
|
60
|
-
_globals['_FLEET']._serialized_end=2042
|
44
|
+
_globals['_PULLMESSAGESRESPONSE']._serialized_end=576
|
45
|
+
_globals['_PUSHMESSAGESREQUEST']._serialized_start=579
|
46
|
+
_globals['_PUSHMESSAGESREQUEST']._serialized_end=730
|
47
|
+
_globals['_PUSHMESSAGESRESPONSE']._serialized_start=733
|
48
|
+
_globals['_PUSHMESSAGESRESPONSE']._serialized_end=1064
|
49
|
+
_globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_start=941
|
50
|
+
_globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_end=987
|
51
|
+
_globals['_PUSHMESSAGESRESPONSE_OBJECTSTOPUSHENTRY']._serialized_start=989
|
52
|
+
_globals['_PUSHMESSAGESRESPONSE_OBJECTSTOPUSHENTRY']._serialized_end=1064
|
53
|
+
_globals['_RECONNECT']._serialized_start=1066
|
54
|
+
_globals['_RECONNECT']._serialized_end=1096
|
55
|
+
_globals['_FLEET']._serialized_start=1099
|
56
|
+
_globals['_FLEET']._serialized_end=1941
|
61
57
|
# @@protoc_insertion_point(module_scope)
|
flwr/proto/fleet_pb2.pyi
CHANGED
@@ -78,38 +78,23 @@ global___PullMessagesRequest = PullMessagesRequest
|
|
78
78
|
|
79
79
|
class PullMessagesResponse(google.protobuf.message.Message):
|
80
80
|
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
81
|
-
class ObjectsToPullEntry(google.protobuf.message.Message):
|
82
|
-
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
83
|
-
KEY_FIELD_NUMBER: builtins.int
|
84
|
-
VALUE_FIELD_NUMBER: builtins.int
|
85
|
-
key: typing.Text
|
86
|
-
@property
|
87
|
-
def value(self) -> flwr.proto.message_pb2.ObjectIDs: ...
|
88
|
-
def __init__(self,
|
89
|
-
*,
|
90
|
-
key: typing.Text = ...,
|
91
|
-
value: typing.Optional[flwr.proto.message_pb2.ObjectIDs] = ...,
|
92
|
-
) -> None: ...
|
93
|
-
def HasField(self, field_name: typing_extensions.Literal["value",b"value"]) -> builtins.bool: ...
|
94
|
-
def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ...
|
95
|
-
|
96
81
|
RECONNECT_FIELD_NUMBER: builtins.int
|
97
82
|
MESSAGES_LIST_FIELD_NUMBER: builtins.int
|
98
|
-
|
83
|
+
MESSAGE_OBJECT_TREES_FIELD_NUMBER: builtins.int
|
99
84
|
@property
|
100
85
|
def reconnect(self) -> global___Reconnect: ...
|
101
86
|
@property
|
102
87
|
def messages_list(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[flwr.proto.message_pb2.Message]: ...
|
103
88
|
@property
|
104
|
-
def
|
89
|
+
def message_object_trees(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[flwr.proto.message_pb2.ObjectTree]: ...
|
105
90
|
def __init__(self,
|
106
91
|
*,
|
107
92
|
reconnect: typing.Optional[global___Reconnect] = ...,
|
108
93
|
messages_list: typing.Optional[typing.Iterable[flwr.proto.message_pb2.Message]] = ...,
|
109
|
-
|
94
|
+
message_object_trees: typing.Optional[typing.Iterable[flwr.proto.message_pb2.ObjectTree]] = ...,
|
110
95
|
) -> None: ...
|
111
96
|
def HasField(self, field_name: typing_extensions.Literal["reconnect",b"reconnect"]) -> builtins.bool: ...
|
112
|
-
def ClearField(self, field_name: typing_extensions.Literal["
|
97
|
+
def ClearField(self, field_name: typing_extensions.Literal["message_object_trees",b"message_object_trees","messages_list",b"messages_list","reconnect",b"reconnect"]) -> None: ...
|
113
98
|
global___PullMessagesResponse = PullMessagesResponse
|
114
99
|
|
115
100
|
class PushMessagesRequest(google.protobuf.message.Message):
|
flwr/server/grid/grpc_grid.py
CHANGED
@@ -33,9 +33,9 @@ from flwr.common.inflatable import (
|
|
33
33
|
get_object_tree,
|
34
34
|
no_object_id_recompute,
|
35
35
|
)
|
36
|
-
from flwr.common.
|
37
|
-
|
38
|
-
|
36
|
+
from flwr.common.inflatable_protobuf_utils import (
|
37
|
+
make_pull_object_fn_protobuf,
|
38
|
+
make_push_object_fn_protobuf,
|
39
39
|
)
|
40
40
|
from flwr.common.inflatable_utils import (
|
41
41
|
inflate_object_from_contents,
|
@@ -240,8 +240,8 @@ class GrpcGrid(Grid):
|
|
240
240
|
# Push only object that are not in the store
|
241
241
|
push_objects(
|
242
242
|
all_objects,
|
243
|
-
push_object_fn=
|
244
|
-
|
243
|
+
push_object_fn=make_push_object_fn_protobuf(
|
244
|
+
push_object_protobuf=self._stub.PushObject,
|
245
245
|
node=self.node,
|
246
246
|
run_id=run_id,
|
247
247
|
),
|
@@ -308,8 +308,8 @@ class GrpcGrid(Grid):
|
|
308
308
|
msg_id = msg_proto.metadata.message_id
|
309
309
|
all_object_contents = pull_objects(
|
310
310
|
list(res.objects_to_pull[msg_id].object_ids) + [msg_id],
|
311
|
-
pull_object_fn=
|
312
|
-
|
311
|
+
pull_object_fn=make_pull_object_fn_protobuf(
|
312
|
+
pull_object_protobuf=self._stub.PullObject,
|
313
313
|
node=self.node,
|
314
314
|
run_id=run_id,
|
315
315
|
),
|
@@ -46,7 +46,6 @@ from flwr.proto.heartbeat_pb2 import ( # pylint: disable=E0611
|
|
46
46
|
from flwr.proto.message_pb2 import ( # pylint: disable=E0611
|
47
47
|
ConfirmMessageReceivedRequest,
|
48
48
|
ConfirmMessageReceivedResponse,
|
49
|
-
ObjectIDs,
|
50
49
|
PullObjectRequest,
|
51
50
|
PullObjectResponse,
|
52
51
|
PushObjectRequest,
|
@@ -113,25 +112,22 @@ def pull_messages(
|
|
113
112
|
|
114
113
|
# Convert to Messages
|
115
114
|
msg_proto = []
|
116
|
-
|
115
|
+
trees = []
|
117
116
|
for msg in message_list:
|
118
117
|
try:
|
119
|
-
|
120
|
-
|
118
|
+
# Retrieve Message object tree from ObjectStore
|
121
119
|
msg_object_id = msg.metadata.message_id
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
)
|
120
|
+
obj_tree = store.get_object_tree(msg_object_id)
|
121
|
+
|
122
|
+
# Add Message and its object tree to the response
|
123
|
+
msg_proto.append(message_to_proto(msg))
|
124
|
+
trees.append(obj_tree)
|
127
125
|
except NoObjectInStoreError as e:
|
128
126
|
log(ERROR, e.message)
|
129
127
|
# Delete message ins from state
|
130
128
|
state.delete_messages(message_ins_ids={msg_object_id})
|
131
129
|
|
132
|
-
return PullMessagesResponse(
|
133
|
-
messages_list=msg_proto, objects_to_pull=objects_to_pull
|
134
|
-
)
|
130
|
+
return PullMessagesResponse(messages_list=msg_proto, message_object_trees=trees)
|
135
131
|
|
136
132
|
|
137
133
|
def push_messages(
|
@@ -287,6 +283,5 @@ def confirm_message_received(
|
|
287
283
|
|
288
284
|
# Delete the message object
|
289
285
|
store.delete(request.message_object_id)
|
290
|
-
store.delete_message_descendant_ids(request.message_object_id)
|
291
286
|
|
292
287
|
return ConfirmMessageReceivedResponse()
|
@@ -27,6 +27,7 @@ from flwr.common.inflatable import (
|
|
27
27
|
UnexpectedObjectContentError,
|
28
28
|
get_all_nested_objects,
|
29
29
|
get_object_tree,
|
30
|
+
iterate_object_tree,
|
30
31
|
no_object_id_recompute,
|
31
32
|
)
|
32
33
|
from flwr.common.logger import log
|
@@ -211,12 +212,6 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
|
|
211
212
|
if msg_res.metadata.src_node_id == SUPERLINK_NODE_ID:
|
212
213
|
with no_object_id_recompute():
|
213
214
|
all_objects = get_all_nested_objects(msg_res)
|
214
|
-
descendants = list(all_objects.keys())[:-1]
|
215
|
-
message_obj_id = msg_res.metadata.message_id
|
216
|
-
# Store mapping
|
217
|
-
store.set_message_descendant_ids(
|
218
|
-
msg_object_id=message_obj_id, descendant_ids=descendants
|
219
|
-
)
|
220
215
|
# Preregister
|
221
216
|
store.preregister(request.run_id, get_object_tree(msg_res))
|
222
217
|
# Store objects
|
@@ -247,7 +242,9 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
|
|
247
242
|
|
248
243
|
try:
|
249
244
|
msg_object_id = msg.metadata.message_id
|
250
|
-
|
245
|
+
obj_tree = store.get_object_tree(msg_object_id)
|
246
|
+
descendants = [node.object_id for node in iterate_object_tree(obj_tree)]
|
247
|
+
descendants = descendants[:-1] # Exclude the message itself
|
251
248
|
# Add mapping of message object ID to its descendants
|
252
249
|
objects_to_pull[msg_object_id] = ObjectIDs(object_ids=descendants)
|
253
250
|
except NoObjectInStoreError as e:
|
@@ -513,7 +510,6 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
|
|
513
510
|
|
514
511
|
# Delete the message object
|
515
512
|
store.delete(request.message_object_id)
|
516
|
-
store.delete_message_descendant_ids(request.message_object_id)
|
517
513
|
|
518
514
|
return ConfirmMessageReceivedResponse()
|
519
515
|
|
flwr/server/superlink/utils.py
CHANGED
@@ -20,7 +20,6 @@ from typing import Optional, Union
|
|
20
20
|
import grpc
|
21
21
|
|
22
22
|
from flwr.common.constant import Status, SubStatus
|
23
|
-
from flwr.common.inflatable import iterate_object_tree
|
24
23
|
from flwr.common.typing import RunStatus
|
25
24
|
from flwr.proto.appio_pb2 import PushAppMessagesRequest # pylint: disable=E0611
|
26
25
|
from flwr.proto.fleet_pb2 import PushMessagesRequest # pylint: disable=E0611
|
@@ -90,17 +89,10 @@ def store_mapping_and_register_objects(
|
|
90
89
|
run_id = request.messages_list[0].metadata.run_id
|
91
90
|
|
92
91
|
for object_tree in request.message_object_trees:
|
93
|
-
all_object_ids = [obj.object_id for obj in iterate_object_tree(object_tree)]
|
94
|
-
msg_object_id, descendant_ids = all_object_ids[-1], all_object_ids[:-1]
|
95
|
-
# Store mapping
|
96
|
-
store.set_message_descendant_ids(
|
97
|
-
msg_object_id=msg_object_id, descendant_ids=descendant_ids
|
98
|
-
)
|
99
|
-
|
100
92
|
# Preregister
|
101
93
|
object_ids_just_registered = store.preregister(run_id, object_tree)
|
102
94
|
# Keep track of objects that need to be pushed
|
103
|
-
objects_to_push[
|
95
|
+
objects_to_push[object_tree.object_id] = ObjectIDs(
|
104
96
|
object_ids=object_ids_just_registered
|
105
97
|
)
|
106
98
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Copyright 2025 Flower Labs GmbH. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
# ==============================================================================
|
15
|
+
"""GRPC health servicers."""
|
16
|
+
|
17
|
+
|
18
|
+
from .simple_health_servicer import SimpleHealthServicer
|
19
|
+
|
20
|
+
__all__ = [
|
21
|
+
"SimpleHealthServicer",
|
22
|
+
]
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Copyright 2025 Flower Labs GmbH. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
# ==============================================================================
|
15
|
+
"""Simple gRPC health servicers."""
|
16
|
+
|
17
|
+
|
18
|
+
import grpc
|
19
|
+
|
20
|
+
# pylint: disable=E0611
|
21
|
+
from grpc_health.v1.health_pb2 import HealthCheckRequest, HealthCheckResponse
|
22
|
+
from grpc_health.v1.health_pb2_grpc import HealthServicer
|
23
|
+
|
24
|
+
# pylint: enable=E0611
|
25
|
+
|
26
|
+
|
27
|
+
class SimpleHealthServicer(HealthServicer): # type: ignore
|
28
|
+
"""A simple gRPC health servicer that always returns SERVING."""
|
29
|
+
|
30
|
+
def Check(
|
31
|
+
self, request: HealthCheckRequest, context: grpc.RpcContext
|
32
|
+
) -> HealthCheckResponse:
|
33
|
+
"""Return a HealthCheckResponse with SERVING status."""
|
34
|
+
return HealthCheckResponse(status=HealthCheckResponse.SERVING)
|
35
|
+
|
36
|
+
def Watch(self, request: HealthCheckRequest, context: grpc.RpcContext) -> None:
|
37
|
+
"""Watch the health status (not implemented)."""
|
38
|
+
context.abort(grpc.StatusCode.UNIMPLEMENTED, "Watch is not implemented")
|
@@ -20,7 +20,6 @@ from dataclasses import dataclass
|
|
20
20
|
from typing import Optional
|
21
21
|
|
22
22
|
from flwr.common.inflatable import (
|
23
|
-
get_object_children_ids_from_object_content,
|
24
23
|
get_object_id,
|
25
24
|
is_valid_sha256_hash,
|
26
25
|
iterate_object_tree,
|
@@ -37,6 +36,7 @@ class ObjectEntry:
|
|
37
36
|
|
38
37
|
content: bytes
|
39
38
|
is_available: bool
|
39
|
+
child_object_ids: list[str] # List of child object IDs
|
40
40
|
ref_count: int # Number of references (direct parents) to this object
|
41
41
|
runs: set[int] # Set of run IDs that used this object
|
42
42
|
|
@@ -70,6 +70,9 @@ class InMemoryObjectStore(ObjectStore):
|
|
70
70
|
self.store[obj_id] = ObjectEntry(
|
71
71
|
content=b"", # Initially empty content
|
72
72
|
is_available=False, # Initially not available
|
73
|
+
child_object_ids=[ # List of child object IDs
|
74
|
+
child.object_id for child in tree_node.children
|
75
|
+
],
|
73
76
|
ref_count=0, # Reference count starts at 0
|
74
77
|
runs={run_id}, # Start with the current run ID
|
75
78
|
)
|
@@ -102,6 +105,32 @@ class InMemoryObjectStore(ObjectStore):
|
|
102
105
|
|
103
106
|
return new_objects
|
104
107
|
|
108
|
+
def get_object_tree(self, object_id: str) -> ObjectTree:
|
109
|
+
"""Get the object tree for a given object ID."""
|
110
|
+
with self.lock_store:
|
111
|
+
# Raise an exception if there's no object with the given ID
|
112
|
+
if not (object_entry := self.store.get(object_id)):
|
113
|
+
raise NoObjectInStoreError(
|
114
|
+
f"Object with ID '{object_id}' was not pre-registered."
|
115
|
+
)
|
116
|
+
|
117
|
+
# Build the object trees of all children
|
118
|
+
try:
|
119
|
+
child_trees = [
|
120
|
+
self.get_object_tree(child_id)
|
121
|
+
for child_id in object_entry.child_object_ids
|
122
|
+
]
|
123
|
+
except NoObjectInStoreError as e:
|
124
|
+
# Raise an error if any child object is missing
|
125
|
+
# This indicates an integrity issue
|
126
|
+
raise NoObjectInStoreError(
|
127
|
+
f"Object tree for object ID '{object_id}' contains missing "
|
128
|
+
"children. This may indicate a corrupted object store."
|
129
|
+
) from e
|
130
|
+
|
131
|
+
# Create and return the ObjectTree for the current object
|
132
|
+
return ObjectTree(object_id=object_id, children=child_trees)
|
133
|
+
|
105
134
|
def put(self, object_id: str, object_content: bytes) -> None:
|
106
135
|
"""Put an object into the store."""
|
107
136
|
if self.verify:
|
@@ -128,29 +157,6 @@ class InMemoryObjectStore(ObjectStore):
|
|
128
157
|
self.store[object_id].content = object_content
|
129
158
|
self.store[object_id].is_available = True
|
130
159
|
|
131
|
-
def set_message_descendant_ids(
|
132
|
-
self, msg_object_id: str, descendant_ids: list[str]
|
133
|
-
) -> None:
|
134
|
-
"""Store the mapping from a ``Message`` object ID to the object IDs of its
|
135
|
-
descendants."""
|
136
|
-
with self.lock_msg_mapping:
|
137
|
-
self.msg_descendant_objects_mapping[msg_object_id] = descendant_ids
|
138
|
-
|
139
|
-
def get_message_descendant_ids(self, msg_object_id: str) -> list[str]:
|
140
|
-
"""Retrieve the object IDs of all descendants of a given Message."""
|
141
|
-
with self.lock_msg_mapping:
|
142
|
-
if msg_object_id not in self.msg_descendant_objects_mapping:
|
143
|
-
raise NoObjectInStoreError(
|
144
|
-
f"No message registered in Object Store with ID '{msg_object_id}'. "
|
145
|
-
"Mapping to descendants could not be found."
|
146
|
-
)
|
147
|
-
return self.msg_descendant_objects_mapping[msg_object_id]
|
148
|
-
|
149
|
-
def delete_message_descendant_ids(self, msg_object_id: str) -> None:
|
150
|
-
"""Delete the mapping from a ``Message`` object ID to its descendants."""
|
151
|
-
with self.lock_msg_mapping:
|
152
|
-
self.msg_descendant_objects_mapping.pop(msg_object_id, None)
|
153
|
-
|
154
160
|
def get(self, object_id: str) -> Optional[bytes]:
|
155
161
|
"""Get an object from the store."""
|
156
162
|
with self.lock_store:
|
@@ -177,10 +183,7 @@ class InMemoryObjectStore(ObjectStore):
|
|
177
183
|
self.run_objects_mapping[run_id].discard(object_id)
|
178
184
|
|
179
185
|
# Decrease the reference count of its children
|
180
|
-
|
181
|
-
object_entry.content
|
182
|
-
)
|
183
|
-
for child_id in children_ids:
|
186
|
+
for child_id in object_entry.child_object_ids:
|
184
187
|
self.store[child_id].ref_count -= 1
|
185
188
|
|
186
189
|
# Recursively try to delete the child object
|
@@ -205,9 +208,6 @@ class InMemoryObjectStore(ObjectStore):
|
|
205
208
|
# Delete the message object and its unreferenced descendants
|
206
209
|
self.delete(object_id)
|
207
210
|
|
208
|
-
# Delete the message's descendants mapping
|
209
|
-
self.delete_message_descendant_ids(object_id)
|
210
|
-
|
211
211
|
# Remove the run from the mapping
|
212
212
|
del self.run_objects_mapping[run_id]
|
213
213
|
|
@@ -60,6 +60,22 @@ class ObjectStore(abc.ABC):
|
|
60
60
|
in the `ObjectStore`, or were preregistered but are not yet available.
|
61
61
|
"""
|
62
62
|
|
63
|
+
@abc.abstractmethod
|
64
|
+
def get_object_tree(self, object_id: str) -> ObjectTree:
|
65
|
+
"""Get the object tree for a given object ID.
|
66
|
+
|
67
|
+
Parameters
|
68
|
+
----------
|
69
|
+
object_id : str
|
70
|
+
The ID of the object for which to retrieve the object tree.
|
71
|
+
|
72
|
+
Returns
|
73
|
+
-------
|
74
|
+
ObjectTree
|
75
|
+
An ObjectTree representing the hierarchical structure of the object with
|
76
|
+
the given ID and its descendants.
|
77
|
+
"""
|
78
|
+
|
63
79
|
@abc.abstractmethod
|
64
80
|
def put(self, object_id: str, object_content: bytes) -> None:
|
65
81
|
"""Put an object into the store.
|
@@ -126,46 +142,6 @@ class ObjectStore(abc.ABC):
|
|
126
142
|
This method should remove all objects from the store.
|
127
143
|
"""
|
128
144
|
|
129
|
-
@abc.abstractmethod
|
130
|
-
def set_message_descendant_ids(
|
131
|
-
self, msg_object_id: str, descendant_ids: list[str]
|
132
|
-
) -> None:
|
133
|
-
"""Store the mapping from a ``Message`` object ID to the object IDs of its
|
134
|
-
descendants.
|
135
|
-
|
136
|
-
Parameters
|
137
|
-
----------
|
138
|
-
msg_object_id : str
|
139
|
-
The object ID of the ``Message``.
|
140
|
-
descendant_ids : list[str]
|
141
|
-
A list of object IDs representing all descendant objects of the ``Message``.
|
142
|
-
"""
|
143
|
-
|
144
|
-
@abc.abstractmethod
|
145
|
-
def get_message_descendant_ids(self, msg_object_id: str) -> list[str]:
|
146
|
-
"""Retrieve the object IDs of all descendants of a given ``Message``.
|
147
|
-
|
148
|
-
Parameters
|
149
|
-
----------
|
150
|
-
msg_object_id : str
|
151
|
-
The object ID of the ``Message``.
|
152
|
-
|
153
|
-
Returns
|
154
|
-
-------
|
155
|
-
list[str]
|
156
|
-
A list of object IDs of all descendant objects of the ``Message``.
|
157
|
-
"""
|
158
|
-
|
159
|
-
@abc.abstractmethod
|
160
|
-
def delete_message_descendant_ids(self, msg_object_id: str) -> None:
|
161
|
-
"""Delete the mapping from a ``Message`` object ID to its descendants.
|
162
|
-
|
163
|
-
Parameters
|
164
|
-
----------
|
165
|
-
msg_object_id : str
|
166
|
-
The object ID of the ``Message``.
|
167
|
-
"""
|
168
|
-
|
169
145
|
@abc.abstractmethod
|
170
146
|
def __contains__(self, object_id: str) -> bool:
|
171
147
|
"""Check if an object_id is in the store.
|
{flwr_nightly-1.20.0.dev20250714.dist-info → flwr_nightly-1.20.0.dev20250716.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: flwr-nightly
|
3
|
-
Version: 1.20.0.
|
3
|
+
Version: 1.20.0.dev20250716
|
4
4
|
Summary: Flower: A Friendly Federated AI Framework
|
5
5
|
License: Apache-2.0
|
6
6
|
Keywords: Artificial Intelligence,Federated AI,Federated Analytics,Federated Evaluation,Federated Learning,Flower,Machine Learning
|
@@ -34,6 +34,7 @@ Provides-Extra: simulation
|
|
34
34
|
Requires-Dist: click (<8.2.0)
|
35
35
|
Requires-Dist: cryptography (>=44.0.1,<45.0.0)
|
36
36
|
Requires-Dist: grpcio (>=1.62.3,<2.0.0,!=1.65.0)
|
37
|
+
Requires-Dist: grpcio-health-checking (>=1.62.3,<2.0.0)
|
37
38
|
Requires-Dist: iterators (>=0.0.2,<0.0.3)
|
38
39
|
Requires-Dist: numpy (>=1.26.0,<3.0.0)
|
39
40
|
Requires-Dist: pathspec (>=0.12.1,<0.13.0)
|
{flwr_nightly-1.20.0.dev20250714.dist-info → flwr_nightly-1.20.0.dev20250716.dist-info}/RECORD
RENAMED
@@ -84,7 +84,7 @@ flwr/client/grpc_adapter_client/__init__.py,sha256=RQWP5mFPROLHKgombiRvPXVWSoVrQ
|
|
84
84
|
flwr/client/grpc_adapter_client/connection.py,sha256=aj5tTYyE8z2hQLXPPydsJiz8gBDIWLUhfWvqYkAL1L4,3966
|
85
85
|
flwr/client/grpc_rere_client/__init__.py,sha256=i7iS0Lt8B7q0E2L72e4F_YrKm6ClRKnd71PNA6PW2O0,752
|
86
86
|
flwr/client/grpc_rere_client/client_interceptor.py,sha256=zFaVHw6AxeNO-7eCKKb-RxrPa7zbM5Z-2-1Efc4adQY,2451
|
87
|
-
flwr/client/grpc_rere_client/connection.py,sha256=
|
87
|
+
flwr/client/grpc_rere_client/connection.py,sha256=jndP_Z8yNGHocJfucUspk2bcrjPeI3s-nOb1tEeDlT4,13732
|
88
88
|
flwr/client/grpc_rere_client/grpc_adapter.py,sha256=dLGB5GriszAmtgvuFGuz_F7rIwpzLfDxhJ7T3Un-Ce0,6694
|
89
89
|
flwr/client/message_handler/__init__.py,sha256=0lyljDVqre3WljiZbPcwCCf8GiIaSVI_yo_ylEyPwSE,719
|
90
90
|
flwr/client/message_handler/message_handler.py,sha256=X9SXX6et97Lw9_DGD93HKsEBGNjXClcFgc_5aLK0oiU,6541
|
@@ -98,7 +98,7 @@ flwr/client/mod/secure_aggregation/secaggplus_mod.py,sha256=aKqjZCrikF73y3E-7h40
|
|
98
98
|
flwr/client/mod/utils.py,sha256=FUgD2TfcWqSeF6jUKZ4i6Ke56U4Nrv85AeVb93s6R9g,1201
|
99
99
|
flwr/client/numpy_client.py,sha256=Qq6ghsIAop2slKqAfgiI5NiHJ4LIxGmrik3Ror4_XVc,9581
|
100
100
|
flwr/client/rest_client/__init__.py,sha256=MBiuK62hj439m9rtwSwI184Hth6Tt5GbmpNMyl3zkZY,735
|
101
|
-
flwr/client/rest_client/connection.py,sha256=
|
101
|
+
flwr/client/rest_client/connection.py,sha256=zZ-HYLPCQxKtTo1Sc-n8jkl_GB4bpfViuif8h9HFSqI,16388
|
102
102
|
flwr/client/run_info_store.py,sha256=MaJ3UQ-07hWtK67wnWu0zR29jrk0fsfgJX506dvEOfE,4042
|
103
103
|
flwr/client/typing.py,sha256=Jw3rawDzI_-ZDcRmEQcs5gZModY7oeQlEeltYsdOhlU,1048
|
104
104
|
flwr/clientapp/__init__.py,sha256=zGW4z49Ojzoi1hDiRC7kyhLjijUilc6fqHhtM_ATRVA,719
|
@@ -120,11 +120,10 @@ flwr/common/exit/__init__.py,sha256=-ZOJYLaNnR729a7VzZiFsLiqngzKQh3xc27svYStZ_Q,
|
|
120
120
|
flwr/common/exit/exit.py,sha256=mJgbqMlVlwAgYtq-Vedj53wO4VxcDcy_P-GzqGK-1GQ,3452
|
121
121
|
flwr/common/exit/exit_code.py,sha256=qpOQsh2-TNJosxrGpR-rKnLBiv5lnl_2sClNoDblAW4,3882
|
122
122
|
flwr/common/exit_handlers.py,sha256=IaqJ60fXZuu7McaRYnoYKtlbH9t4Yl9goNExKqtmQbs,4304
|
123
|
-
flwr/common/grpc.py,sha256=
|
123
|
+
flwr/common/grpc.py,sha256=y70hUFvXkIf3l03xOhlb7qhS6W1UJZRSZqCdB0ir0v8,10381
|
124
124
|
flwr/common/heartbeat.py,sha256=SyEpNDnmJ0lni0cWO67rcoJVKasCLmkNHm3dKLeNrLU,5749
|
125
125
|
flwr/common/inflatable.py,sha256=GDL9oBKs16_yyVdlH6kBf493O5xll_h9V7XB5Mpx1Hc,9524
|
126
|
-
flwr/common/
|
127
|
-
flwr/common/inflatable_rest_utils.py,sha256=KiZd06XRiXcl_WewOrag0JTvUQt5kZ74UIsQ3FCAXGc,3580
|
126
|
+
flwr/common/inflatable_protobuf_utils.py,sha256=lvKR5jD5P8AlpknD_1BlvUoTuT6Iyd8oodXfUQvjDRU,3746
|
128
127
|
flwr/common/inflatable_utils.py,sha256=yew5VU8po8yZsmoTVxg-tB5vrvnb2mvBAE55qjiOAq8,12840
|
129
128
|
flwr/common/logger.py,sha256=JbRf6E2vQxXzpDBq1T8IDUJo_usu3gjWEBPQ6uKcmdg,13049
|
130
129
|
flwr/common/message.py,sha256=xAL7iZN5-n-xPQpgoSFvxNrzs8fmiiPfoU0DjNQEhRw,19953
|
@@ -185,8 +184,8 @@ flwr/proto/fab_pb2.py,sha256=2Nu0WaWxDZ8TbutMtctjdcGM7OtXiyP4kmCgg5o7Jjw,1627
|
|
185
184
|
flwr/proto/fab_pb2.pyi,sha256=AMXpiDK0fo3nZWjxsC2E4otSaVjyQbU7iiWKrsSZavs,2395
|
186
185
|
flwr/proto/fab_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
|
187
186
|
flwr/proto/fab_pb2_grpc.pyi,sha256=ff2TSiLVnG6IVQcTGzb2DIH3XRSoAvAo_RMcvbMFyc0,76
|
188
|
-
flwr/proto/fleet_pb2.py,sha256=
|
189
|
-
flwr/proto/fleet_pb2.pyi,sha256=
|
187
|
+
flwr/proto/fleet_pb2.py,sha256=GbPhzqW-yBYduHcmlgc3YiXOeOZ_ThT46QfE6ck7jak,5660
|
188
|
+
flwr/proto/fleet_pb2.pyi,sha256=K6Qt5lb_wVekUbgNA5Y5ora4N4Ow9bclp2h85VKiZBU,8555
|
190
189
|
flwr/proto/fleet_pb2_grpc.py,sha256=NmzrDYxyM3MQNh3vwYczQNuFimZz3prU6ke3E-fKk_g,17539
|
191
190
|
flwr/proto/fleet_pb2_grpc.pyi,sha256=PDERhzOrBCMAytTLS65Qck8A45bTIYni7Lotq6_I0sM,4721
|
192
191
|
flwr/proto/grpcadapter_pb2.py,sha256=PJ8DtfeV29g_y4Z3aNZlSZocLqSxeLmTsYCdOZDYCiE,1843
|
@@ -243,7 +242,7 @@ flwr/server/criterion.py,sha256=G4e-6B48Pc7d5rmGVUpIzNKb6UF88O3VmTRuUltgjzM,1061
|
|
243
242
|
flwr/server/fleet_event_log_interceptor.py,sha256=ifV4gUB_hSg7QPLIrAyDpjciqZBOKb0L0abZno3GTwA,3780
|
244
243
|
flwr/server/grid/__init__.py,sha256=aWZHezoR2UGMJISB_gPMCm2N_2GSbm97A3lAp7ruhRQ,888
|
245
244
|
flwr/server/grid/grid.py,sha256=naGCYt5J6dnmUvrcGkdNyKPe3MBd-0awGm1ALmgahqY,6625
|
246
|
-
flwr/server/grid/grpc_grid.py,sha256
|
245
|
+
flwr/server/grid/grpc_grid.py,sha256=6w-X6mRyAmaWyrUaBnRp3enM4e63iEMUUWPIRFqO1qw,13609
|
247
246
|
flwr/server/grid/inmemory_grid.py,sha256=RjejYT-d-hHuTs1KSs_5wvOdAWKLus8w5_UAcnGt4iw,6168
|
248
247
|
flwr/server/history.py,sha256=cCkFhBN4GoHsYYNk5GG1Y089eKJh2DH_ZJbYPwLaGyk,5026
|
249
248
|
flwr/server/run_serverapp.py,sha256=v0p6jXj2dFxlRUdoEeF1mnaFd9XRQi6dZCflPY6d3qI,2063
|
@@ -290,7 +289,7 @@ flwr/server/superlink/fleet/grpc_rere/__init__.py,sha256=ahDJJ1e-lDxBpeBMgPk7YZt
|
|
290
289
|
flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py,sha256=X7-z4oReIH5ghMfmMXML3SSpa2bhRsuIvt2OZs82BUk,8675
|
291
290
|
flwr/server/superlink/fleet/grpc_rere/server_interceptor.py,sha256=DrHubsaLgJCwCeeJPYogQTiP0xYqjxwnT9rh7OP7BoU,6984
|
292
291
|
flwr/server/superlink/fleet/message_handler/__init__.py,sha256=fHsRV0KvJ8HtgSA4_YBsEzuhJLjO8p6xx4aCY2oE1p4,731
|
293
|
-
flwr/server/superlink/fleet/message_handler/message_handler.py,sha256=
|
292
|
+
flwr/server/superlink/fleet/message_handler/message_handler.py,sha256=k_okVvuvbQgnBAWtXpOf0UrXcMQmRZtKKTS-as1xjig,8667
|
294
293
|
flwr/server/superlink/fleet/rest_rere/__init__.py,sha256=Lzc93nA7tDqoy-zRUaPG316oqFiZX1HUCL5ELaXY_xw,735
|
295
294
|
flwr/server/superlink/fleet/rest_rere/rest_api.py,sha256=mxWKwGpgHPqd7cGFqd2ASnR-KZduIzLfT-d2yiNCqQ0,9257
|
296
295
|
flwr/server/superlink/fleet/vce/__init__.py,sha256=XOKbAWOzlCqEOQ3M2cBYkH7HKA7PxlbCJMunt-ty-DY,784
|
@@ -306,11 +305,11 @@ flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=E699Ak0jMF3N7i1SIeFRu
|
|
306
305
|
flwr/server/superlink/linkstate/utils.py,sha256=IeLh7iGRCHU5MEWOl7iriaSE4L__8GWOa2OleXadK5M,15444
|
307
306
|
flwr/server/superlink/serverappio/__init__.py,sha256=Fy4zJuoccZe5mZSEIpOmQvU6YeXFBa1M4eZuXXmJcn8,717
|
308
307
|
flwr/server/superlink/serverappio/serverappio_grpc.py,sha256=zcvzDhCAnlFxAwCiJUHNm6IE7-rk5jeZqSmPgjEY3AU,2307
|
309
|
-
flwr/server/superlink/serverappio/serverappio_servicer.py,sha256=
|
308
|
+
flwr/server/superlink/serverappio/serverappio_servicer.py,sha256=mR-ijliBxxrKFyIw5Vpc95QvapD7W8eY9pb-7VDj3gU,18519
|
310
309
|
flwr/server/superlink/simulation/__init__.py,sha256=Ry8DrNaZCMcQXvUc4FoCN2m3dvUQgWjasfp015o3Ec4,718
|
311
310
|
flwr/server/superlink/simulation/simulationio_grpc.py,sha256=VqWKxjpd4bCgPFKsgtIZPk9YcG0kc1EEmr5k20EKty4,2205
|
312
311
|
flwr/server/superlink/simulation/simulationio_servicer.py,sha256=m1T1zvEn81jlfx9hVTqmeWxAu6APCS2YW8l5O0OQvhU,7724
|
313
|
-
flwr/server/superlink/utils.py,sha256=
|
312
|
+
flwr/server/superlink/utils.py,sha256=e_-BZmW19xRuClGwBxK1GNSM_WCDGM4A8TW6fHoLPF0,3532
|
314
313
|
flwr/server/typing.py,sha256=LvO6gq7H6TAWhA9JFx0WyqHxU7FycyvhSsLjBLPgpts,1011
|
315
314
|
flwr/server/utils/__init__.py,sha256=U4gM84-uUFddarODDQkO6SjNUuGhFcsHJZMjSEbezkU,884
|
316
315
|
flwr/server/utils/tensorboard.py,sha256=3z3MeF0cu_U6ghNgRd0UQ5bunyDQKxCLpIpEdGMoCJ0,5466
|
@@ -336,11 +335,13 @@ flwr/supercore/ffs/__init__.py,sha256=U3KXwG_SplEvchat27K0LYPoPHzh-cwwT_NHsGlYMt
|
|
336
335
|
flwr/supercore/ffs/disk_ffs.py,sha256=c5VywSaRnq3XM_zuJptNtsF2HFwsRK0pvBd5-5CNONs,3272
|
337
336
|
flwr/supercore/ffs/ffs.py,sha256=6w7wy71i7tbuJwqEgdeCa49JejXMEof3jujURN_R7Rg,2395
|
338
337
|
flwr/supercore/ffs/ffs_factory.py,sha256=pK-g3LMelvWTV6N9Cd-j-_-FdcGbRFTKNsWaqmlBDSk,1490
|
338
|
+
flwr/supercore/grpc_health/__init__.py,sha256=bK1jWNje-uwxf4_c0vfFsZdVrLzAHQ463OsOcVWERPU,814
|
339
|
+
flwr/supercore/grpc_health/simple_health_servicer.py,sha256=IUWS0NpgLAwxApvd4TpU8eZibpABbPX9w-SbMXDypdE,1521
|
339
340
|
flwr/supercore/license_plugin/__init__.py,sha256=d8OgHTn2BwjoNSPy8jQQxTC_iT3-ENLwKM8yhHKvCRM,820
|
340
341
|
flwr/supercore/license_plugin/license_plugin.py,sha256=BFhlCH5v9KKuY7crVCsi8fuYe98SJfnGxRS0CVc_Y5I,948
|
341
342
|
flwr/supercore/object_store/__init__.py,sha256=cdfPAmjINY6iOp8oI_LdcVh2simg469Mkdl4LLV4kHI,911
|
342
|
-
flwr/supercore/object_store/in_memory_object_store.py,sha256=
|
343
|
-
flwr/supercore/object_store/object_store.py,sha256=
|
343
|
+
flwr/supercore/object_store/in_memory_object_store.py,sha256=CGY43syxDGrUPcdOzRH3hNrfeqmoTOY_wjo3qaAHuNk,9612
|
344
|
+
flwr/supercore/object_store/object_store.py,sha256=wC6Pxq89a7FwmIMJE3ZLPPy2i7Gdss7-8RUapECCAPY,5099
|
344
345
|
flwr/supercore/object_store/object_store_factory.py,sha256=QVwE2ywi7vsj2iKfvWWnNw3N_I7Rz91NUt2RpcbJ7iM,1527
|
345
346
|
flwr/supercore/utils.py,sha256=ebuHMbeA8eXisX0oMPqBK3hk7uVnIE_yiqWVz8YbkpQ,1324
|
346
347
|
flwr/superexec/__init__.py,sha256=YFqER0IJc1XEWfsX6AxZ9LSRq0sawPYrNYki-brvTIc,715
|
@@ -368,7 +369,7 @@ flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca
|
|
368
369
|
flwr/supernode/servicer/clientappio/__init__.py,sha256=7Oy62Y_oijqF7Dxi6tpcUQyOpLc_QpIRZ83NvwmB0Yg,813
|
369
370
|
flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=U-uAJ7Yd_BzEqhbpCSgEG9pxX5Zf4RuPVYKimYDvMbU,7176
|
370
371
|
flwr/supernode/start_client_internal.py,sha256=_ZqSfL_j4qn6Cg-P6sv3k_n1ZG62J_teokBxnWrXrPE,18772
|
371
|
-
flwr_nightly-1.20.0.
|
372
|
-
flwr_nightly-1.20.0.
|
373
|
-
flwr_nightly-1.20.0.
|
374
|
-
flwr_nightly-1.20.0.
|
372
|
+
flwr_nightly-1.20.0.dev20250716.dist-info/METADATA,sha256=bp6v4He7vTM-vNpn-EKkSH-QXj2VZN62mGjFq5yWl7g,15966
|
373
|
+
flwr_nightly-1.20.0.dev20250716.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
374
|
+
flwr_nightly-1.20.0.dev20250716.dist-info/entry_points.txt,sha256=jNpDXGBGgs21RqUxelF_jwGaxtqFwm-MQyfz-ZqSjrA,367
|
375
|
+
flwr_nightly-1.20.0.dev20250716.dist-info/RECORD,,
|
@@ -1,99 +0,0 @@
|
|
1
|
-
# Copyright 2025 Flower Labs GmbH. All Rights Reserved.
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
# ==============================================================================
|
15
|
-
"""InflatableObject REST utils."""
|
16
|
-
|
17
|
-
|
18
|
-
from typing import Callable
|
19
|
-
|
20
|
-
from flwr.proto.message_pb2 import ( # pylint: disable=E0611
|
21
|
-
PullObjectRequest,
|
22
|
-
PullObjectResponse,
|
23
|
-
PushObjectRequest,
|
24
|
-
PushObjectResponse,
|
25
|
-
)
|
26
|
-
from flwr.proto.node_pb2 import Node # pylint: disable=E0611
|
27
|
-
|
28
|
-
from .inflatable_utils import ObjectIdNotPreregisteredError, ObjectUnavailableError
|
29
|
-
|
30
|
-
|
31
|
-
def make_pull_object_fn_rest(
|
32
|
-
pull_object_rest: Callable[[PullObjectRequest], PullObjectResponse],
|
33
|
-
node: Node,
|
34
|
-
run_id: int,
|
35
|
-
) -> Callable[[str], bytes]:
|
36
|
-
"""Create a pull object function that uses REST to pull objects.
|
37
|
-
|
38
|
-
Parameters
|
39
|
-
----------
|
40
|
-
pull_object_rest : Callable[[PullObjectRequest], PullObjectResponse]
|
41
|
-
A function that makes a POST request against the `/push-object` REST endpoint
|
42
|
-
node : Node
|
43
|
-
The node making the request.
|
44
|
-
run_id : int
|
45
|
-
The run ID for the current operation.
|
46
|
-
|
47
|
-
Returns
|
48
|
-
-------
|
49
|
-
Callable[[str], bytes]
|
50
|
-
A function that takes an object ID and returns the object content as bytes.
|
51
|
-
The function raises `ObjectIdNotPreregisteredError` if the object ID is not
|
52
|
-
pre-registered, or `ObjectUnavailableError` if the object is not yet available.
|
53
|
-
"""
|
54
|
-
|
55
|
-
def pull_object_fn(object_id: str) -> bytes:
|
56
|
-
request = PullObjectRequest(node=node, run_id=run_id, object_id=object_id)
|
57
|
-
response: PullObjectResponse = pull_object_rest(request)
|
58
|
-
if not response.object_found:
|
59
|
-
raise ObjectIdNotPreregisteredError(object_id)
|
60
|
-
if not response.object_available:
|
61
|
-
raise ObjectUnavailableError(object_id)
|
62
|
-
return response.object_content
|
63
|
-
|
64
|
-
return pull_object_fn
|
65
|
-
|
66
|
-
|
67
|
-
def make_push_object_fn_rest(
|
68
|
-
push_object_rest: Callable[[PushObjectRequest], PushObjectResponse],
|
69
|
-
node: Node,
|
70
|
-
run_id: int,
|
71
|
-
) -> Callable[[str, bytes], None]:
|
72
|
-
"""Create a push object function that uses REST to push objects.
|
73
|
-
|
74
|
-
Parameters
|
75
|
-
----------
|
76
|
-
push_object_rest : Callable[[PushObjectRequest], PushObjectResponse]
|
77
|
-
A function that makes a POST request against the `/pull-object` REST endpoint
|
78
|
-
node : Node
|
79
|
-
The node making the request.
|
80
|
-
run_id : int
|
81
|
-
The run ID for the current operation.
|
82
|
-
|
83
|
-
Returns
|
84
|
-
-------
|
85
|
-
Callable[[str, bytes], None]
|
86
|
-
A function that takes an object ID and its content as bytes, and pushes it
|
87
|
-
to the servicer. The function raises `ObjectIdNotPreregisteredError` if
|
88
|
-
the object ID is not pre-registered.
|
89
|
-
"""
|
90
|
-
|
91
|
-
def push_object_fn(object_id: str, object_content: bytes) -> None:
|
92
|
-
request = PushObjectRequest(
|
93
|
-
node=node, run_id=run_id, object_id=object_id, object_content=object_content
|
94
|
-
)
|
95
|
-
response: PushObjectResponse = push_object_rest(request)
|
96
|
-
if not response.stored:
|
97
|
-
raise ObjectIdNotPreregisteredError(object_id)
|
98
|
-
|
99
|
-
return push_object_fn
|
{flwr_nightly-1.20.0.dev20250714.dist-info → flwr_nightly-1.20.0.dev20250716.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|