flwr-nightly 1.19.0.dev20250605__py3-none-any.whl → 1.19.0.dev20250606__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 +12 -6
- flwr/common/inflatable_grpc_utils.py +134 -29
- flwr/server/grid/grpc_grid.py +12 -6
- {flwr_nightly-1.19.0.dev20250605.dist-info → flwr_nightly-1.19.0.dev20250606.dist-info}/METADATA +1 -1
- {flwr_nightly-1.19.0.dev20250605.dist-info → flwr_nightly-1.19.0.dev20250606.dist-info}/RECORD +7 -7
- {flwr_nightly-1.19.0.dev20250605.dist-info → flwr_nightly-1.19.0.dev20250606.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.19.0.dev20250605.dist-info → flwr_nightly-1.19.0.dev20250606.dist-info}/entry_points.txt +0 -0
@@ -31,6 +31,8 @@ from flwr.common.constant import HEARTBEAT_CALL_TIMEOUT, HEARTBEAT_DEFAULT_INTER
|
|
31
31
|
from flwr.common.grpc import create_channel, on_channel_state_change
|
32
32
|
from flwr.common.heartbeat import HeartbeatSender
|
33
33
|
from flwr.common.inflatable_grpc_utils import (
|
34
|
+
make_pull_object_fn_grpc,
|
35
|
+
make_push_object_fn_grpc,
|
34
36
|
pull_object_from_servicer,
|
35
37
|
push_object_to_servicer,
|
36
38
|
)
|
@@ -269,9 +271,11 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
269
271
|
Message,
|
270
272
|
pull_object_from_servicer(
|
271
273
|
object_id=message_proto.metadata.message_id,
|
272
|
-
|
273
|
-
|
274
|
-
|
274
|
+
pull_object_fn=make_pull_object_fn_grpc(
|
275
|
+
pull_object_grpc=stub.PullObject,
|
276
|
+
node=node,
|
277
|
+
run_id=message_proto.metadata.run_id,
|
278
|
+
),
|
275
279
|
),
|
276
280
|
)
|
277
281
|
|
@@ -322,9 +326,11 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
322
326
|
objs_to_push = set(response.objects_to_push[message.object_id].object_ids)
|
323
327
|
push_object_to_servicer(
|
324
328
|
message,
|
325
|
-
|
326
|
-
|
327
|
-
|
329
|
+
push_object_fn=make_push_object_fn_grpc(
|
330
|
+
push_object_grpc=stub.PushObject,
|
331
|
+
node=node,
|
332
|
+
run_id=message.metadata.run_id,
|
333
|
+
),
|
328
334
|
object_ids_to_push=objs_to_push,
|
329
335
|
)
|
330
336
|
log(DEBUG, "Pushed %s objects to servicer.", len(objs_to_push))
|
@@ -16,10 +16,8 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
from time import sleep
|
19
|
-
from typing import
|
19
|
+
from typing import Callable, Optional
|
20
20
|
|
21
|
-
from flwr.client.grpc_rere_client.grpc_adapter import GrpcAdapter
|
22
|
-
from flwr.proto.fleet_pb2_grpc import FleetStub # pylint: disable=E0611
|
23
21
|
from flwr.proto.message_pb2 import ( # pylint: disable=E0611
|
24
22
|
PullObjectRequest,
|
25
23
|
PullObjectResponse,
|
@@ -27,7 +25,6 @@ from flwr.proto.message_pb2 import ( # pylint: disable=E0611
|
|
27
25
|
PushObjectResponse,
|
28
26
|
)
|
29
27
|
from flwr.proto.node_pb2 import Node # pylint: disable=E0611
|
30
|
-
from flwr.proto.serverappio_pb2_grpc import ServerAppIoStub # pylint: disable=E0611
|
31
28
|
|
32
29
|
from .inflatable import (
|
33
30
|
InflatableObject,
|
@@ -48,11 +45,24 @@ inflatable_class_registry: dict[str, type[InflatableObject]] = {
|
|
48
45
|
}
|
49
46
|
|
50
47
|
|
48
|
+
class ObjectUnavailableError(Exception):
|
49
|
+
"""Exception raised when an object has been pre-registered but is not yet
|
50
|
+
available."""
|
51
|
+
|
52
|
+
def __init__(self, object_id: str):
|
53
|
+
super().__init__(f"Object with ID '{object_id}' is not yet available.")
|
54
|
+
|
55
|
+
|
56
|
+
class ObjectIdNotPreregisteredError(Exception):
|
57
|
+
"""Exception raised when an object ID is not pre-registered."""
|
58
|
+
|
59
|
+
def __init__(self, object_id: str):
|
60
|
+
super().__init__(f"Object with ID '{object_id}' could not be found.")
|
61
|
+
|
62
|
+
|
51
63
|
def push_object_to_servicer(
|
52
64
|
obj: InflatableObject,
|
53
|
-
|
54
|
-
node: Node,
|
55
|
-
run_id: int,
|
65
|
+
push_object_fn: Callable[[str, bytes], None],
|
56
66
|
object_ids_to_push: Optional[set[str]] = None,
|
57
67
|
) -> set[str]:
|
58
68
|
"""Recursively deflate an object and push it to the servicer.
|
@@ -60,13 +70,30 @@ def push_object_to_servicer(
|
|
60
70
|
Objects with the same ID are not pushed twice. If `object_ids_to_push` is set,
|
61
71
|
only objects with those IDs are pushed. It returns the set of pushed object
|
62
72
|
IDs.
|
73
|
+
|
74
|
+
Parameters
|
75
|
+
----------
|
76
|
+
obj : InflatableObject
|
77
|
+
The object to push.
|
78
|
+
push_object_fn : Callable[[str, bytes], None]
|
79
|
+
A function that takes an object ID and its content as bytes, and pushes
|
80
|
+
it to the servicer. This function should raise `ObjectIdNotPreregisteredError`
|
81
|
+
if the object ID is not pre-registered.
|
82
|
+
object_ids_to_push : Optional[set[str]] (default: None)
|
83
|
+
A set of object IDs to push. If object ID of the given object is not in this
|
84
|
+
set, the object will not be pushed.
|
85
|
+
|
86
|
+
Returns
|
87
|
+
-------
|
88
|
+
set[str]
|
89
|
+
A set of object IDs that were pushed to the servicer.
|
63
90
|
"""
|
64
91
|
pushed_object_ids: set[str] = set()
|
65
92
|
# Push children if it has any
|
66
93
|
if children := obj.children:
|
67
94
|
for child in children.values():
|
68
95
|
pushed_object_ids |= push_object_to_servicer(
|
69
|
-
child,
|
96
|
+
child, push_object_fn, object_ids_to_push
|
70
97
|
)
|
71
98
|
|
72
99
|
# Deflate object and push
|
@@ -74,14 +101,8 @@ def push_object_to_servicer(
|
|
74
101
|
object_id = get_object_id(object_content)
|
75
102
|
# Push always if no object set is specified, or if the object is in the set
|
76
103
|
if object_ids_to_push is None or object_id in object_ids_to_push:
|
77
|
-
|
78
|
-
|
79
|
-
node=node,
|
80
|
-
run_id=run_id,
|
81
|
-
object_id=object_id,
|
82
|
-
object_content=object_content,
|
83
|
-
)
|
84
|
-
)
|
104
|
+
# The function may raise an error if the object ID is not pre-registered
|
105
|
+
push_object_fn(object_id, object_content)
|
85
106
|
pushed_object_ids.add(object_id)
|
86
107
|
|
87
108
|
return pushed_object_ids
|
@@ -89,20 +110,33 @@ def push_object_to_servicer(
|
|
89
110
|
|
90
111
|
def pull_object_from_servicer(
|
91
112
|
object_id: str,
|
92
|
-
|
93
|
-
node: Node,
|
94
|
-
run_id: int,
|
113
|
+
pull_object_fn: Callable[[str], bytes],
|
95
114
|
) -> InflatableObject:
|
96
|
-
"""Recursively inflate an object by pulling it from the servicer.
|
115
|
+
"""Recursively inflate an object by pulling it from the servicer.
|
116
|
+
|
117
|
+
Parameters
|
118
|
+
----------
|
119
|
+
object_id : str
|
120
|
+
The ID of the object to pull.
|
121
|
+
pull_object_fn : Callable[[str], bytes]
|
122
|
+
A function that takes an object ID and returns the object content as bytes.
|
123
|
+
The function should raise `ObjectUnavailableError` if the object is not yet
|
124
|
+
available, or `ObjectIdNotPreregisteredError` if the object ID is not
|
125
|
+
pre-registered.
|
126
|
+
|
127
|
+
Returns
|
128
|
+
-------
|
129
|
+
InflatableObject
|
130
|
+
The pulled object.
|
131
|
+
"""
|
97
132
|
# Pull object
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
sleep(0.1)
|
133
|
+
while True:
|
134
|
+
try:
|
135
|
+
# The function may raise an error if the object ID is not pre-registered
|
136
|
+
object_content: bytes = pull_object_fn(object_id)
|
137
|
+
break # Exit loop if object is successfully pulled
|
138
|
+
except ObjectUnavailableError:
|
139
|
+
sleep(0.1) # Retry after a short delay
|
106
140
|
|
107
141
|
# Extract object class and object_ids of children
|
108
142
|
obj_type, children_obj_ids, _ = get_object_head_values_from_object_content(
|
@@ -115,8 +149,79 @@ def pull_object_from_servicer(
|
|
115
149
|
children: dict[str, InflatableObject] = {}
|
116
150
|
for child_object_id in children_obj_ids:
|
117
151
|
children[child_object_id] = pull_object_from_servicer(
|
118
|
-
child_object_id,
|
152
|
+
child_object_id, pull_object_fn
|
119
153
|
)
|
120
154
|
|
121
155
|
# Inflate object passing its children
|
122
156
|
return cls_type.inflate(object_content, children=children)
|
157
|
+
|
158
|
+
|
159
|
+
def make_pull_object_fn_grpc(
|
160
|
+
pull_object_grpc: Callable[[PullObjectRequest], PullObjectResponse],
|
161
|
+
node: Node,
|
162
|
+
run_id: int,
|
163
|
+
) -> Callable[[str], bytes]:
|
164
|
+
"""Create a pull object function that uses gRPC to pull objects.
|
165
|
+
|
166
|
+
Parameters
|
167
|
+
----------
|
168
|
+
pull_object_grpc : Callable[[PullObjectRequest], PullObjectResponse]
|
169
|
+
The gRPC function to pull objects, e.g., `FleetStub.PullObject`.
|
170
|
+
node : Node
|
171
|
+
The node making the request.
|
172
|
+
run_id : int
|
173
|
+
The run ID for the current operation.
|
174
|
+
|
175
|
+
Returns
|
176
|
+
-------
|
177
|
+
Callable[[str], bytes]
|
178
|
+
A function that takes an object ID and returns the object content as bytes.
|
179
|
+
The function raises `ObjectIdNotPreregisteredError` if the object ID is not
|
180
|
+
pre-registered, or `ObjectUnavailableError` if the object is not yet available.
|
181
|
+
"""
|
182
|
+
|
183
|
+
def pull_object_fn(object_id: str) -> bytes:
|
184
|
+
request = PullObjectRequest(node=node, run_id=run_id, object_id=object_id)
|
185
|
+
response: PullObjectResponse = pull_object_grpc(request)
|
186
|
+
if not response.object_found:
|
187
|
+
raise ObjectIdNotPreregisteredError(object_id)
|
188
|
+
if not response.object_available:
|
189
|
+
raise ObjectUnavailableError(object_id)
|
190
|
+
return response.object_content
|
191
|
+
|
192
|
+
return pull_object_fn
|
193
|
+
|
194
|
+
|
195
|
+
def make_push_object_fn_grpc(
|
196
|
+
push_object_grpc: Callable[[PushObjectRequest], PushObjectResponse],
|
197
|
+
node: Node,
|
198
|
+
run_id: int,
|
199
|
+
) -> Callable[[str, bytes], None]:
|
200
|
+
"""Create a push object function that uses gRPC to push objects.
|
201
|
+
|
202
|
+
Parameters
|
203
|
+
----------
|
204
|
+
push_object_grpc : Callable[[PushObjectRequest], PushObjectResponse]
|
205
|
+
The gRPC function to push objects, e.g., `FleetStub.PushObject`.
|
206
|
+
node : Node
|
207
|
+
The node making the request.
|
208
|
+
run_id : int
|
209
|
+
The run ID for the current operation.
|
210
|
+
|
211
|
+
Returns
|
212
|
+
-------
|
213
|
+
Callable[[str, bytes], None]
|
214
|
+
A function that takes an object ID and its content as bytes, and pushes it
|
215
|
+
to the servicer. The function raises `ObjectIdNotPreregisteredError` if
|
216
|
+
the object ID is not pre-registered.
|
217
|
+
"""
|
218
|
+
|
219
|
+
def push_object_fn(object_id: str, object_content: bytes) -> None:
|
220
|
+
request = PushObjectRequest(
|
221
|
+
node=node, run_id=run_id, object_id=object_id, object_content=object_content
|
222
|
+
)
|
223
|
+
response: PushObjectResponse = push_object_grpc(request)
|
224
|
+
if not response.stored:
|
225
|
+
raise ObjectIdNotPreregisteredError(object_id)
|
226
|
+
|
227
|
+
return push_object_fn
|
flwr/server/grid/grpc_grid.py
CHANGED
@@ -29,6 +29,8 @@ from flwr.common.constant import (
|
|
29
29
|
)
|
30
30
|
from flwr.common.grpc import create_channel, on_channel_state_change
|
31
31
|
from flwr.common.inflatable_grpc_utils import (
|
32
|
+
make_pull_object_fn_grpc,
|
33
|
+
make_push_object_fn_grpc,
|
32
34
|
pull_object_from_servicer,
|
33
35
|
push_object_to_servicer,
|
34
36
|
)
|
@@ -227,9 +229,11 @@ class GrpcGrid(Grid):
|
|
227
229
|
# Push only object that are not in the store
|
228
230
|
push_object_to_servicer(
|
229
231
|
message,
|
230
|
-
|
231
|
-
|
232
|
-
|
232
|
+
push_object_fn=make_push_object_fn_grpc(
|
233
|
+
push_object_grpc=self._stub.PushObject,
|
234
|
+
node=self.node,
|
235
|
+
run_id=run_id,
|
236
|
+
),
|
233
237
|
object_ids_to_push=obj_ids_to_push,
|
234
238
|
)
|
235
239
|
return msg_id
|
@@ -292,9 +296,11 @@ class GrpcGrid(Grid):
|
|
292
296
|
|
293
297
|
message = pull_object_from_servicer(
|
294
298
|
msg_proto.metadata.message_id,
|
295
|
-
|
296
|
-
|
297
|
-
|
299
|
+
pull_object_fn=make_pull_object_fn_grpc(
|
300
|
+
pull_object_grpc=self._stub.PullObject,
|
301
|
+
node=self.node,
|
302
|
+
run_id=run_id,
|
303
|
+
),
|
298
304
|
)
|
299
305
|
inflated_msgs.append(cast(Message, message))
|
300
306
|
|
{flwr_nightly-1.19.0.dev20250605.dist-info → flwr_nightly-1.19.0.dev20250606.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: flwr-nightly
|
3
|
-
Version: 1.19.0.
|
3
|
+
Version: 1.19.0.dev20250606
|
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
|
{flwr_nightly-1.19.0.dev20250605.dist-info → flwr_nightly-1.19.0.dev20250606.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=6LF9JuAhL4XDHVtPS6MzEYm-Nrer-5iM7fEjR5XaGzM,13658
|
88
88
|
flwr/client/grpc_rere_client/grpc_adapter.py,sha256=JvMZ7vCFTaTEo6AzKYh3zDmeQAU7VSjdysbC6t3ufWg,6351
|
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
|
@@ -123,7 +123,7 @@ flwr/common/exit_handlers.py,sha256=IaqJ60fXZuu7McaRYnoYKtlbH9t4Yl9goNExKqtmQbs,
|
|
123
123
|
flwr/common/grpc.py,sha256=manTaHaPiyYngUq1ErZvvV2B2GxlXUUUGRy3jc3TBIQ,9798
|
124
124
|
flwr/common/heartbeat.py,sha256=SyEpNDnmJ0lni0cWO67rcoJVKasCLmkNHm3dKLeNrLU,5749
|
125
125
|
flwr/common/inflatable.py,sha256=9yPsSFOfNM2OIb15JQ6-wY5kblwXiC5zNX-tsp2ZwW0,7017
|
126
|
-
flwr/common/inflatable_grpc_utils.py,sha256=
|
126
|
+
flwr/common/inflatable_grpc_utils.py,sha256=3M3_334GM-BrjLysilPXEbkDAErh_dXVgkcmcFSQYWg,8017
|
127
127
|
flwr/common/logger.py,sha256=JbRf6E2vQxXzpDBq1T8IDUJo_usu3gjWEBPQ6uKcmdg,13049
|
128
128
|
flwr/common/message.py,sha256=ZdH35PznYhIzfNKPzHTL1YS5z-flTpHnjdNpQR6B8x0,19953
|
129
129
|
flwr/common/object_ref.py,sha256=p3SfTeqo3Aj16SkB-vsnNn01zswOPdGNBitcbRnqmUk,9134
|
@@ -236,7 +236,7 @@ flwr/server/criterion.py,sha256=G4e-6B48Pc7d5rmGVUpIzNKb6UF88O3VmTRuUltgjzM,1061
|
|
236
236
|
flwr/server/fleet_event_log_interceptor.py,sha256=AkL7Y5d3xm2vRhL3ahmEVVoOvAP7PA7dRgB-je4v-Ys,3774
|
237
237
|
flwr/server/grid/__init__.py,sha256=aWZHezoR2UGMJISB_gPMCm2N_2GSbm97A3lAp7ruhRQ,888
|
238
238
|
flwr/server/grid/grid.py,sha256=naGCYt5J6dnmUvrcGkdNyKPe3MBd-0awGm1ALmgahqY,6625
|
239
|
-
flwr/server/grid/grpc_grid.py,sha256=
|
239
|
+
flwr/server/grid/grpc_grid.py,sha256=o9oXBsAc9jp2RneY1AhOOyOO8B4sRJKP_l1UyC0j5_M,12692
|
240
240
|
flwr/server/grid/inmemory_grid.py,sha256=RjejYT-d-hHuTs1KSs_5wvOdAWKLus8w5_UAcnGt4iw,6168
|
241
241
|
flwr/server/history.py,sha256=cCkFhBN4GoHsYYNk5GG1Y089eKJh2DH_ZJbYPwLaGyk,5026
|
242
242
|
flwr/server/run_serverapp.py,sha256=v0p6jXj2dFxlRUdoEeF1mnaFd9XRQi6dZCflPY6d3qI,2063
|
@@ -357,7 +357,7 @@ flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca
|
|
357
357
|
flwr/supernode/servicer/clientappio/__init__.py,sha256=vJyOjO2FXZ2URbnthmdsgs6948wbYfdq1L1V8Um-Lr8,895
|
358
358
|
flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=LmzkxtNQBn5vVrHc0Bhq2WqaK6-LM2v4kfLBN0PiNNM,8522
|
359
359
|
flwr/supernode/start_client_internal.py,sha256=5CwTNV-XmIhwR1jv3G7aQAXGhf6OFWS6U-vmxY1iKGA,16984
|
360
|
-
flwr_nightly-1.19.0.
|
361
|
-
flwr_nightly-1.19.0.
|
362
|
-
flwr_nightly-1.19.0.
|
363
|
-
flwr_nightly-1.19.0.
|
360
|
+
flwr_nightly-1.19.0.dev20250606.dist-info/METADATA,sha256=OBd3qXqNO4F-2bqFuBUM8HZ1hKilS8QDmf0fH12imYs,15910
|
361
|
+
flwr_nightly-1.19.0.dev20250606.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
362
|
+
flwr_nightly-1.19.0.dev20250606.dist-info/entry_points.txt,sha256=jNpDXGBGgs21RqUxelF_jwGaxtqFwm-MQyfz-ZqSjrA,367
|
363
|
+
flwr_nightly-1.19.0.dev20250606.dist-info/RECORD,,
|
{flwr_nightly-1.19.0.dev20250605.dist-info → flwr_nightly-1.19.0.dev20250606.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|