flwr-nightly 1.23.0.dev20251029__py3-none-any.whl → 1.23.0.dev20251030__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.
Potentially problematic release.
This version of flwr-nightly might be problematic. Click here for more details.
- flwr/common/constant.py +3 -1
- flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +98 -33
- flwr/server/superlink/fleet/message_handler/message_handler.py +72 -1
- flwr/server/superlink/fleet/rest_rere/rest_api.py +20 -4
- flwr/server/superlink/fleet/vce/vce_api.py +3 -3
- flwr/server/superlink/linkstate/in_memory_linkstate.py +2 -2
- flwr/server/superlink/linkstate/sqlite_linkstate.py +2 -2
- {flwr_nightly-1.23.0.dev20251029.dist-info → flwr_nightly-1.23.0.dev20251030.dist-info}/METADATA +1 -1
- {flwr_nightly-1.23.0.dev20251029.dist-info → flwr_nightly-1.23.0.dev20251030.dist-info}/RECORD +11 -11
- {flwr_nightly-1.23.0.dev20251029.dist-info → flwr_nightly-1.23.0.dev20251030.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.23.0.dev20251029.dist-info → flwr_nightly-1.23.0.dev20251030.dist-info}/entry_points.txt +0 -0
flwr/common/constant.py
CHANGED
|
@@ -62,7 +62,9 @@ HEARTBEAT_DEFAULT_INTERVAL = 30
|
|
|
62
62
|
HEARTBEAT_CALL_TIMEOUT = 5
|
|
63
63
|
HEARTBEAT_BASE_MULTIPLIER = 0.8
|
|
64
64
|
HEARTBEAT_RANDOM_RANGE = (-0.1, 0.1)
|
|
65
|
-
|
|
65
|
+
HEARTBEAT_MIN_INTERVAL = 10
|
|
66
|
+
HEARTBEAT_MAX_INTERVAL = 1800 # 30 minutes
|
|
67
|
+
HEARTBEAT_INTERVAL_INF = 1e300 # Large value, disabling heartbeats
|
|
66
68
|
HEARTBEAT_PATIENCE = 2
|
|
67
69
|
RUN_FAILURE_DETAILS_NO_HEARTBEAT = "No heartbeat received from the run."
|
|
68
70
|
|
|
@@ -21,7 +21,10 @@ from logging import DEBUG, ERROR, INFO
|
|
|
21
21
|
import grpc
|
|
22
22
|
from google.protobuf.json_format import MessageToDict
|
|
23
23
|
|
|
24
|
-
from flwr.common.constant import
|
|
24
|
+
from flwr.common.constant import (
|
|
25
|
+
PUBLIC_KEY_ALREADY_IN_USE_MESSAGE,
|
|
26
|
+
SUPERNODE_NOT_CREATED_FROM_CLI_MESSAGE,
|
|
27
|
+
)
|
|
25
28
|
from flwr.common.inflatable import UnexpectedObjectContentError
|
|
26
29
|
from flwr.common.logger import log
|
|
27
30
|
from flwr.common.typing import InvalidRunStatusException
|
|
@@ -151,46 +154,100 @@ class FleetServicer(fleet_pb2_grpc.FleetServicer):
|
|
|
151
154
|
def RegisterNode(
|
|
152
155
|
self, request: RegisterNodeFleetRequest, context: grpc.ServicerContext
|
|
153
156
|
) -> RegisterNodeFleetResponse:
|
|
154
|
-
"""Register a node
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
157
|
+
"""Register a node."""
|
|
158
|
+
# Prevent registration when SuperNode authentication is enabled
|
|
159
|
+
if self.enable_supernode_auth:
|
|
160
|
+
log(ERROR, "SuperNode registration is disabled through Fleet API.")
|
|
161
|
+
context.abort(
|
|
162
|
+
grpc.StatusCode.FAILED_PRECONDITION,
|
|
163
|
+
"SuperNode authentication is enabled. "
|
|
164
|
+
"All SuperNodes must be registered via the CLI.",
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
try:
|
|
168
|
+
return message_handler.register_node(
|
|
169
|
+
request=request,
|
|
170
|
+
state=self.state_factory.state(),
|
|
171
|
+
)
|
|
172
|
+
except ValueError:
|
|
173
|
+
# Public key already in use
|
|
174
|
+
log(ERROR, PUBLIC_KEY_ALREADY_IN_USE_MESSAGE)
|
|
175
|
+
context.abort(
|
|
176
|
+
grpc.StatusCode.FAILED_PRECONDITION, PUBLIC_KEY_ALREADY_IN_USE_MESSAGE
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
raise RuntimeError # Make mypy happy
|
|
161
180
|
|
|
162
181
|
def ActivateNode(
|
|
163
182
|
self, request: ActivateNodeRequest, context: grpc.ServicerContext
|
|
164
183
|
) -> ActivateNodeResponse:
|
|
165
|
-
"""Activate a node
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
184
|
+
"""Activate a node."""
|
|
185
|
+
try:
|
|
186
|
+
response = message_handler.activate_node(
|
|
187
|
+
request=request,
|
|
188
|
+
state=self.state_factory.state(),
|
|
189
|
+
)
|
|
190
|
+
log(INFO, "[Fleet.ActivateNode] Activated node_id=%s", response.node_id)
|
|
191
|
+
return response
|
|
192
|
+
except message_handler.InvalidHeartbeatIntervalError:
|
|
193
|
+
# Heartbeat interval is invalid
|
|
194
|
+
log(ERROR, "[Fleet.ActivateNode] Invalid heartbeat interval")
|
|
195
|
+
context.abort(
|
|
196
|
+
grpc.StatusCode.INVALID_ARGUMENT, "Invalid heartbeat interval"
|
|
197
|
+
)
|
|
198
|
+
except ValueError as e:
|
|
199
|
+
log(ERROR, "[Fleet.ActivateNode] Activation failed: %s", str(e))
|
|
200
|
+
context.abort(grpc.StatusCode.FAILED_PRECONDITION, str(e))
|
|
201
|
+
|
|
202
|
+
raise RuntimeError # Make mypy happy
|
|
172
203
|
|
|
173
204
|
def DeactivateNode(
|
|
174
205
|
self, request: DeactivateNodeRequest, context: grpc.ServicerContext
|
|
175
206
|
) -> DeactivateNodeResponse:
|
|
176
|
-
"""Deactivate a node
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
207
|
+
"""Deactivate a node."""
|
|
208
|
+
try:
|
|
209
|
+
response = message_handler.deactivate_node(
|
|
210
|
+
request=request,
|
|
211
|
+
state=self.state_factory.state(),
|
|
212
|
+
)
|
|
213
|
+
log(INFO, "[Fleet.DeactivateNode] Deactivated node_id=%s", request.node_id)
|
|
214
|
+
return response
|
|
215
|
+
except ValueError as e:
|
|
216
|
+
log(ERROR, "[Fleet.DeactivateNode] Deactivation failed: %s", str(e))
|
|
217
|
+
context.abort(grpc.StatusCode.FAILED_PRECONDITION, str(e))
|
|
218
|
+
|
|
219
|
+
raise RuntimeError # Make mypy happy
|
|
183
220
|
|
|
184
221
|
def UnregisterNode(
|
|
185
222
|
self, request: UnregisterNodeFleetRequest, context: grpc.ServicerContext
|
|
186
223
|
) -> UnregisterNodeFleetResponse:
|
|
187
|
-
"""Unregister a node
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
224
|
+
"""Unregister a node."""
|
|
225
|
+
# Prevent unregistration when SuperNode authentication is enabled
|
|
226
|
+
if self.enable_supernode_auth:
|
|
227
|
+
log(ERROR, "SuperNode unregistration is disabled through Fleet API.")
|
|
228
|
+
context.abort(
|
|
229
|
+
grpc.StatusCode.FAILED_PRECONDITION,
|
|
230
|
+
"SuperNode authentication is enabled. "
|
|
231
|
+
"All SuperNodes must be unregistered via the CLI.",
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
try:
|
|
235
|
+
response = message_handler.unregister_node(
|
|
236
|
+
request=request,
|
|
237
|
+
state=self.state_factory.state(),
|
|
238
|
+
)
|
|
239
|
+
log(
|
|
240
|
+
DEBUG, "[Fleet.UnregisterNode] Unregistered node_id=%s", request.node_id
|
|
241
|
+
)
|
|
242
|
+
return response
|
|
243
|
+
except ValueError as e:
|
|
244
|
+
log(
|
|
245
|
+
ERROR,
|
|
246
|
+
"[Fleet.UnregisterNode] Unregistration failed: %s",
|
|
247
|
+
str(e),
|
|
248
|
+
)
|
|
249
|
+
context.abort(grpc.StatusCode.FAILED_PRECONDITION, str(e))
|
|
250
|
+
raise RuntimeError from None # Make mypy happy
|
|
194
251
|
|
|
195
252
|
def DeleteNode(
|
|
196
253
|
self, request: DeleteNodeRequest, context: grpc.ServicerContext
|
|
@@ -220,10 +277,18 @@ class FleetServicer(fleet_pb2_grpc.FleetServicer):
|
|
|
220
277
|
) -> SendNodeHeartbeatResponse:
|
|
221
278
|
"""."""
|
|
222
279
|
log(DEBUG, "[Fleet.SendNodeHeartbeat] Request: %s", MessageToDict(request))
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
280
|
+
try:
|
|
281
|
+
return message_handler.send_node_heartbeat(
|
|
282
|
+
request=request,
|
|
283
|
+
state=self.state_factory.state(),
|
|
284
|
+
)
|
|
285
|
+
except message_handler.InvalidHeartbeatIntervalError:
|
|
286
|
+
# Heartbeat interval is invalid
|
|
287
|
+
log(ERROR, "[Fleet.SendNodeHeartbeat] Invalid heartbeat interval")
|
|
288
|
+
context.abort(
|
|
289
|
+
grpc.StatusCode.INVALID_ARGUMENT, "Invalid heartbeat interval"
|
|
290
|
+
)
|
|
291
|
+
raise RuntimeError # Make mypy happy
|
|
227
292
|
|
|
228
293
|
def PullMessages(
|
|
229
294
|
self, request: PullMessagesRequest, context: grpc.ServicerContext
|
|
@@ -18,7 +18,12 @@ from logging import ERROR
|
|
|
18
18
|
from typing import Optional
|
|
19
19
|
|
|
20
20
|
from flwr.common import Message, log
|
|
21
|
-
from flwr.common.constant import
|
|
21
|
+
from flwr.common.constant import (
|
|
22
|
+
HEARTBEAT_MAX_INTERVAL,
|
|
23
|
+
HEARTBEAT_MIN_INTERVAL,
|
|
24
|
+
NOOP_FLWR_AID,
|
|
25
|
+
Status,
|
|
26
|
+
)
|
|
22
27
|
from flwr.common.inflatable import UnexpectedObjectContentError
|
|
23
28
|
from flwr.common.serde import (
|
|
24
29
|
fab_to_proto,
|
|
@@ -29,8 +34,12 @@ from flwr.common.serde import (
|
|
|
29
34
|
from flwr.common.typing import Fab, InvalidRunStatusException
|
|
30
35
|
from flwr.proto.fab_pb2 import GetFabRequest, GetFabResponse # pylint: disable=E0611
|
|
31
36
|
from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
|
|
37
|
+
ActivateNodeRequest,
|
|
38
|
+
ActivateNodeResponse,
|
|
32
39
|
CreateNodeRequest,
|
|
33
40
|
CreateNodeResponse,
|
|
41
|
+
DeactivateNodeRequest,
|
|
42
|
+
DeactivateNodeResponse,
|
|
34
43
|
DeleteNodeRequest,
|
|
35
44
|
DeleteNodeResponse,
|
|
36
45
|
PullMessagesRequest,
|
|
@@ -38,6 +47,10 @@ from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
|
|
|
38
47
|
PushMessagesRequest,
|
|
39
48
|
PushMessagesResponse,
|
|
40
49
|
Reconnect,
|
|
50
|
+
RegisterNodeFleetRequest,
|
|
51
|
+
RegisterNodeFleetResponse,
|
|
52
|
+
UnregisterNodeFleetRequest,
|
|
53
|
+
UnregisterNodeFleetResponse,
|
|
41
54
|
)
|
|
42
55
|
from flwr.proto.heartbeat_pb2 import ( # pylint: disable=E0611
|
|
43
56
|
SendNodeHeartbeatRequest,
|
|
@@ -64,6 +77,10 @@ from flwr.supercore.object_store import NoObjectInStoreError, ObjectStore
|
|
|
64
77
|
from flwr.supercore.object_store.utils import store_mapping_and_register_objects
|
|
65
78
|
|
|
66
79
|
|
|
80
|
+
class InvalidHeartbeatIntervalError(Exception):
|
|
81
|
+
"""Invalid heartbeat interval exception."""
|
|
82
|
+
|
|
83
|
+
|
|
67
84
|
def create_node(
|
|
68
85
|
request: CreateNodeRequest, # pylint: disable=unused-argument
|
|
69
86
|
state: LinkState,
|
|
@@ -87,11 +104,56 @@ def delete_node(request: DeleteNodeRequest, state: LinkState) -> DeleteNodeRespo
|
|
|
87
104
|
return DeleteNodeResponse()
|
|
88
105
|
|
|
89
106
|
|
|
107
|
+
def register_node(
|
|
108
|
+
request: RegisterNodeFleetRequest,
|
|
109
|
+
state: LinkState,
|
|
110
|
+
) -> RegisterNodeFleetResponse:
|
|
111
|
+
"""Register a node (Fleet API only)."""
|
|
112
|
+
state.create_node(NOOP_FLWR_AID, request.public_key, 0)
|
|
113
|
+
return RegisterNodeFleetResponse()
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def activate_node(
|
|
117
|
+
request: ActivateNodeRequest,
|
|
118
|
+
state: LinkState,
|
|
119
|
+
) -> ActivateNodeResponse:
|
|
120
|
+
"""Activate a node."""
|
|
121
|
+
node_id = state.get_node_id_by_public_key(request.public_key)
|
|
122
|
+
if node_id is None:
|
|
123
|
+
raise ValueError("No SuperNode found with the given public key.")
|
|
124
|
+
_validate_heartbeat_interval(request.heartbeat_interval)
|
|
125
|
+
if not state.activate_node(node_id, request.heartbeat_interval):
|
|
126
|
+
raise ValueError(f"SuperNode with node ID {node_id} could not be activated.")
|
|
127
|
+
return ActivateNodeResponse(node_id=node_id)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def deactivate_node(
|
|
131
|
+
request: DeactivateNodeRequest,
|
|
132
|
+
state: LinkState,
|
|
133
|
+
) -> DeactivateNodeResponse:
|
|
134
|
+
"""Deactivate a node."""
|
|
135
|
+
if not state.deactivate_node(request.node_id):
|
|
136
|
+
raise ValueError(
|
|
137
|
+
f"SuperNode with node ID {request.node_id} could not be deactivated."
|
|
138
|
+
)
|
|
139
|
+
return DeactivateNodeResponse()
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def unregister_node(
|
|
143
|
+
request: UnregisterNodeFleetRequest,
|
|
144
|
+
state: LinkState,
|
|
145
|
+
) -> UnregisterNodeFleetResponse:
|
|
146
|
+
"""Unregister a node (Fleet API only)."""
|
|
147
|
+
state.delete_node(NOOP_FLWR_AID, request.node_id)
|
|
148
|
+
return UnregisterNodeFleetResponse()
|
|
149
|
+
|
|
150
|
+
|
|
90
151
|
def send_node_heartbeat(
|
|
91
152
|
request: SendNodeHeartbeatRequest, # pylint: disable=unused-argument
|
|
92
153
|
state: LinkState, # pylint: disable=unused-argument
|
|
93
154
|
) -> SendNodeHeartbeatResponse:
|
|
94
155
|
"""."""
|
|
156
|
+
_validate_heartbeat_interval(request.heartbeat_interval)
|
|
95
157
|
res = state.acknowledge_node_heartbeat(
|
|
96
158
|
request.node.node_id, request.heartbeat_interval
|
|
97
159
|
)
|
|
@@ -286,3 +348,12 @@ def confirm_message_received(
|
|
|
286
348
|
store.delete(request.message_object_id)
|
|
287
349
|
|
|
288
350
|
return ConfirmMessageReceivedResponse()
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def _validate_heartbeat_interval(interval: float) -> None:
|
|
354
|
+
"""Raise if heartbeat interval is out of bounds."""
|
|
355
|
+
if not HEARTBEAT_MIN_INTERVAL <= interval <= HEARTBEAT_MAX_INTERVAL:
|
|
356
|
+
raise InvalidHeartbeatIntervalError(
|
|
357
|
+
f"Heartbeat interval {interval} is out of bounds "
|
|
358
|
+
f"[{HEARTBEAT_MIN_INTERVAL}, {HEARTBEAT_MAX_INTERVAL}]."
|
|
359
|
+
)
|
|
@@ -135,7 +135,11 @@ async def register_node(
|
|
|
135
135
|
request: RegisterNodeFleetRequest,
|
|
136
136
|
) -> RegisterNodeFleetResponse:
|
|
137
137
|
"""Register a node (Fleet API only)."""
|
|
138
|
-
|
|
138
|
+
# Get state from app
|
|
139
|
+
state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
|
|
140
|
+
|
|
141
|
+
# Handle message
|
|
142
|
+
return message_handler.register_node(request=request, state=state)
|
|
139
143
|
|
|
140
144
|
|
|
141
145
|
@rest_request_response(ActivateNodeRequest)
|
|
@@ -143,7 +147,11 @@ async def activate_node(
|
|
|
143
147
|
request: ActivateNodeRequest,
|
|
144
148
|
) -> ActivateNodeResponse:
|
|
145
149
|
"""Activate a node."""
|
|
146
|
-
|
|
150
|
+
# Get state from app
|
|
151
|
+
state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
|
|
152
|
+
|
|
153
|
+
# Handle message
|
|
154
|
+
return message_handler.activate_node(request=request, state=state)
|
|
147
155
|
|
|
148
156
|
|
|
149
157
|
@rest_request_response(DeactivateNodeRequest)
|
|
@@ -151,7 +159,11 @@ async def deactivate_node(
|
|
|
151
159
|
request: DeactivateNodeRequest,
|
|
152
160
|
) -> DeactivateNodeResponse:
|
|
153
161
|
"""Deactivate a node."""
|
|
154
|
-
|
|
162
|
+
# Get state from app
|
|
163
|
+
state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
|
|
164
|
+
|
|
165
|
+
# Handle message
|
|
166
|
+
return message_handler.deactivate_node(request=request, state=state)
|
|
155
167
|
|
|
156
168
|
|
|
157
169
|
@rest_request_response(UnregisterNodeFleetRequest)
|
|
@@ -159,7 +171,11 @@ async def unregister_node(
|
|
|
159
171
|
request: UnregisterNodeFleetRequest,
|
|
160
172
|
) -> UnregisterNodeFleetResponse:
|
|
161
173
|
"""Unregister a node (Fleet API only)."""
|
|
162
|
-
|
|
174
|
+
# Get state from app
|
|
175
|
+
state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
|
|
176
|
+
|
|
177
|
+
# Handle message
|
|
178
|
+
return message_handler.unregister_node(request=request, state=state)
|
|
163
179
|
|
|
164
180
|
|
|
165
181
|
@rest_request_response(PullMessagesRequest)
|
|
@@ -33,7 +33,7 @@ from flwr.clientapp.client_app import ClientApp, ClientAppException, LoadClientA
|
|
|
33
33
|
from flwr.clientapp.utils import get_load_client_app_fn
|
|
34
34
|
from flwr.common import Message
|
|
35
35
|
from flwr.common.constant import (
|
|
36
|
-
|
|
36
|
+
HEARTBEAT_INTERVAL_INF,
|
|
37
37
|
NOOP_FLWR_AID,
|
|
38
38
|
NUM_PARTITIONS_KEY,
|
|
39
39
|
PARTITION_ID_KEY,
|
|
@@ -62,10 +62,10 @@ def _register_nodes(
|
|
|
62
62
|
# use random bytes as public key
|
|
63
63
|
NOOP_FLWR_AID,
|
|
64
64
|
secrets.token_bytes(32),
|
|
65
|
-
heartbeat_interval=
|
|
65
|
+
heartbeat_interval=HEARTBEAT_INTERVAL_INF,
|
|
66
66
|
)
|
|
67
67
|
state.acknowledge_node_heartbeat(
|
|
68
|
-
node_id=node_id, heartbeat_interval=
|
|
68
|
+
node_id=node_id, heartbeat_interval=HEARTBEAT_INTERVAL_INF
|
|
69
69
|
)
|
|
70
70
|
nodes_mapping[node_id] = i
|
|
71
71
|
log(DEBUG, "Registered %i nodes", len(nodes_mapping))
|
|
@@ -28,7 +28,7 @@ from typing import Optional
|
|
|
28
28
|
from flwr.common import Context, Message, log, now
|
|
29
29
|
from flwr.common.constant import (
|
|
30
30
|
FLWR_APP_TOKEN_LENGTH,
|
|
31
|
-
|
|
31
|
+
HEARTBEAT_INTERVAL_INF,
|
|
32
32
|
HEARTBEAT_PATIENCE,
|
|
33
33
|
MESSAGE_TTL_TOLERANCE,
|
|
34
34
|
NODE_ID_NUM_BYTES,
|
|
@@ -641,7 +641,7 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
|
|
|
641
641
|
current = now()
|
|
642
642
|
run_record = self.run_ids[run_id]
|
|
643
643
|
if new_status.status in (Status.STARTING, Status.RUNNING):
|
|
644
|
-
run_record.heartbeat_interval =
|
|
644
|
+
run_record.heartbeat_interval = HEARTBEAT_INTERVAL_INF
|
|
645
645
|
run_record.active_until = (
|
|
646
646
|
current.timestamp() + run_record.heartbeat_interval
|
|
647
647
|
)
|
|
@@ -27,7 +27,7 @@ from typing import Any, Optional, Union, cast
|
|
|
27
27
|
from flwr.common import Context, Message, Metadata, log, now
|
|
28
28
|
from flwr.common.constant import (
|
|
29
29
|
FLWR_APP_TOKEN_LENGTH,
|
|
30
|
-
|
|
30
|
+
HEARTBEAT_INTERVAL_INF,
|
|
31
31
|
HEARTBEAT_PATIENCE,
|
|
32
32
|
MESSAGE_TTL_TOLERANCE,
|
|
33
33
|
NODE_ID_NUM_BYTES,
|
|
@@ -982,7 +982,7 @@ class SqliteLinkState(LinkState, SqliteMixin): # pylint: disable=R0904
|
|
|
982
982
|
# when switching to starting or running
|
|
983
983
|
current = now()
|
|
984
984
|
if new_status.status in (Status.STARTING, Status.RUNNING):
|
|
985
|
-
heartbeat_interval =
|
|
985
|
+
heartbeat_interval = HEARTBEAT_INTERVAL_INF
|
|
986
986
|
active_until = current.timestamp() + heartbeat_interval
|
|
987
987
|
else:
|
|
988
988
|
heartbeat_interval = 0
|
{flwr_nightly-1.23.0.dev20251029.dist-info → flwr_nightly-1.23.0.dev20251030.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: flwr-nightly
|
|
3
|
-
Version: 1.23.0.
|
|
3
|
+
Version: 1.23.0.dev20251030
|
|
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.23.0.dev20251029.dist-info → flwr_nightly-1.23.0.dev20251030.dist-info}/RECORD
RENAMED
|
@@ -126,7 +126,7 @@ flwr/common/__init__.py,sha256=5GCLVk399Az_rTJHNticRlL0Sl_oPw_j5_LuFKfX7-M,4171
|
|
|
126
126
|
flwr/common/address.py,sha256=9JucdTwlc-jpeJkRKeUboZoacUtErwSVtnDR9kAtLqE,4119
|
|
127
127
|
flwr/common/args.py,sha256=Nq2u4yePbkSY0CWFamn0hZY6Rms8G1xYDeDGIcLIITE,5849
|
|
128
128
|
flwr/common/config.py,sha256=glcZDjco-amw1YfQcYTFJ4S1pt9APoexT-mf1QscuHs,13960
|
|
129
|
-
flwr/common/constant.py,sha256=
|
|
129
|
+
flwr/common/constant.py,sha256=du408_dylfRx6H-YXzpc_2BvpI1bnFUcz0RiQryM_n8,10254
|
|
130
130
|
flwr/common/context.py,sha256=Be8obQR_OvEDy1OmshuUKxGRQ7Qx89mf5F4xlhkR10s,2407
|
|
131
131
|
flwr/common/date.py,sha256=1ZT2cRSpC2DJqprOVTLXYCR_O2_OZR0zXO_brJ3LqWc,1554
|
|
132
132
|
flwr/common/differential_privacy.py,sha256=FdlpdpPl_H_2HJa8CQM1iCUGBBQ5Dc8CzxmHERM-EoE,6148
|
|
@@ -305,22 +305,22 @@ flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py,sha256=KouR9PUcrPmMtoLooF4O
|
|
|
305
305
|
flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py,sha256=iSf0mbBAlig7G6subQwBSVjcUCgSihONKdZ1RmQPTOk,4887
|
|
306
306
|
flwr/server/superlink/fleet/grpc_bidi/grpc_server.py,sha256=OsS-6GgCIzMMZDVu5Y-OKjynHVUrpdc_5OrtuB-IbU0,5174
|
|
307
307
|
flwr/server/superlink/fleet/grpc_rere/__init__.py,sha256=ahDJJ1e-lDxBpeBMgPk7YZt2wB38_QltcpOC0gLbpFs,758
|
|
308
|
-
flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py,sha256=
|
|
308
|
+
flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py,sha256=j81X6yVdhWZpdAOKEr3DQpCrd4ETnmdniQ12IMThymU,16226
|
|
309
309
|
flwr/server/superlink/fleet/grpc_rere/node_auth_server_interceptor.py,sha256=UWeFQNBW2pGBRVN36HodHcv7bKTgMmdToh96Lhqip1M,5411
|
|
310
310
|
flwr/server/superlink/fleet/message_handler/__init__.py,sha256=fHsRV0KvJ8HtgSA4_YBsEzuhJLjO8p6xx4aCY2oE1p4,731
|
|
311
|
-
flwr/server/superlink/fleet/message_handler/message_handler.py,sha256=
|
|
311
|
+
flwr/server/superlink/fleet/message_handler/message_handler.py,sha256=_ZTKTloYgC3axwJYnKUZ9v6Va6psH_PEux-UPVtArzg,11021
|
|
312
312
|
flwr/server/superlink/fleet/rest_rere/__init__.py,sha256=Lzc93nA7tDqoy-zRUaPG316oqFiZX1HUCL5ELaXY_xw,735
|
|
313
|
-
flwr/server/superlink/fleet/rest_rere/rest_api.py,sha256=
|
|
313
|
+
flwr/server/superlink/fleet/rest_rere/rest_api.py,sha256=Xcm_o41j0iHCBraLglZc2dY47FSiY8egmcznWUsrLYY,10383
|
|
314
314
|
flwr/server/superlink/fleet/vce/__init__.py,sha256=XOKbAWOzlCqEOQ3M2cBYkH7HKA7PxlbCJMunt-ty-DY,784
|
|
315
315
|
flwr/server/superlink/fleet/vce/backend/__init__.py,sha256=PPH89Yqd1XKm-sRJN6R0WQlKT_b4v54Kzl2yzHAFzM8,1437
|
|
316
316
|
flwr/server/superlink/fleet/vce/backend/backend.py,sha256=cSrHZ5SjCCvy4vI0pgsyjtx3cDMuMQve8KcKkK-dWWo,2196
|
|
317
317
|
flwr/server/superlink/fleet/vce/backend/raybackend.py,sha256=cBZYTmfiAsb1HmVUmOQXYLU-UJmJTFWkj1wW4RYRDuc,7218
|
|
318
|
-
flwr/server/superlink/fleet/vce/vce_api.py,sha256=
|
|
318
|
+
flwr/server/superlink/fleet/vce/vce_api.py,sha256=7dJdxRjXttXfZSflZHd-TwX9278ZzrdJxmmWbRiEH_I,13389
|
|
319
319
|
flwr/server/superlink/linkstate/__init__.py,sha256=OtsgvDTnZLU3k0sUbkHbqoVwW6ql2FDmb6uT6DbNkZo,1064
|
|
320
|
-
flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=
|
|
320
|
+
flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=l3n1HJfIOYYSAuSeD-HHDjnL490HxH5NTSj962OSDAk,31829
|
|
321
321
|
flwr/server/superlink/linkstate/linkstate.py,sha256=DabTgFFissJhT_MCPiluz5eFrS3c412q8FnRqQrAidY,15945
|
|
322
322
|
flwr/server/superlink/linkstate/linkstate_factory.py,sha256=KVBpc8UxVrJCQ7IkOjVZVWb-kqWx08AGVi7qXzZS190,2126
|
|
323
|
-
flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=
|
|
323
|
+
flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=Herm-aUM9Wmpg9IV7c25UdXGmPqL8sWdVOOCrWxha_k,47528
|
|
324
324
|
flwr/server/superlink/linkstate/utils.py,sha256=ZtyqSo4HzGrHXW3Wn_4irYMpIiq4onNI2XCIVOOJmJM,13971
|
|
325
325
|
flwr/server/superlink/serverappio/__init__.py,sha256=Fy4zJuoccZe5mZSEIpOmQvU6YeXFBa1M4eZuXXmJcn8,717
|
|
326
326
|
flwr/server/superlink/serverappio/serverappio_grpc.py,sha256=-I7kBbr4w4ZVYwBZoAIle-xHKthFnZrsVfxa6WR8uxA,2310
|
|
@@ -433,7 +433,7 @@ flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca
|
|
|
433
433
|
flwr/supernode/servicer/clientappio/__init__.py,sha256=7Oy62Y_oijqF7Dxi6tpcUQyOpLc_QpIRZ83NvwmB0Yg,813
|
|
434
434
|
flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=ZvKosLV7GN1_fOF-tOmhqFQysYQywCysRc-m23DVIWA,10265
|
|
435
435
|
flwr/supernode/start_client_internal.py,sha256=wKqh9-_rQYi7JFKpYBLRiUeq9YJUSyUd9b-SnVnuvwI,21567
|
|
436
|
-
flwr_nightly-1.23.0.
|
|
437
|
-
flwr_nightly-1.23.0.
|
|
438
|
-
flwr_nightly-1.23.0.
|
|
439
|
-
flwr_nightly-1.23.0.
|
|
436
|
+
flwr_nightly-1.23.0.dev20251030.dist-info/METADATA,sha256=yDbmaIH946MJMvXaMPddPZREsfS76qhbPVOMP8JA2b4,14559
|
|
437
|
+
flwr_nightly-1.23.0.dev20251030.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
438
|
+
flwr_nightly-1.23.0.dev20251030.dist-info/entry_points.txt,sha256=hxHD2ixb_vJFDOlZV-zB4Ao32_BQlL34ftsDh1GXv14,420
|
|
439
|
+
flwr_nightly-1.23.0.dev20251030.dist-info/RECORD,,
|
{flwr_nightly-1.23.0.dev20251029.dist-info → flwr_nightly-1.23.0.dev20251030.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|