flwr-nightly 1.23.0.dev20251029__py3-none-any.whl → 1.23.0.dev20251031__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.

Files changed (26) hide show
  1. flwr/cli/new/new.py +187 -35
  2. flwr/client/grpc_adapter_client/connection.py +4 -6
  3. flwr/client/grpc_rere_client/connection.py +47 -24
  4. flwr/client/grpc_rere_client/grpc_adapter.py +0 -16
  5. flwr/client/rest_client/connection.py +70 -33
  6. flwr/common/constant.py +3 -1
  7. flwr/proto/fleet_pb2.py +31 -39
  8. flwr/proto/fleet_pb2.pyi +0 -48
  9. flwr/proto/fleet_pb2_grpc.py +0 -66
  10. flwr/proto/fleet_pb2_grpc.pyi +0 -20
  11. flwr/server/app.py +30 -16
  12. flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +0 -6
  13. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +92 -124
  14. flwr/server/superlink/fleet/grpc_rere/node_auth_server_interceptor.py +14 -5
  15. flwr/server/superlink/fleet/message_handler/message_handler.py +66 -23
  16. flwr/server/superlink/fleet/rest_rere/rest_api.py +20 -28
  17. flwr/server/superlink/fleet/vce/vce_api.py +3 -3
  18. flwr/server/superlink/linkstate/in_memory_linkstate.py +4 -3
  19. flwr/server/superlink/linkstate/sqlite_linkstate.py +4 -4
  20. flwr/supercore/constant.py +4 -0
  21. flwr/supernode/cli/flower_supernode.py +7 -0
  22. flwr/supernode/start_client_internal.py +3 -9
  23. {flwr_nightly-1.23.0.dev20251029.dist-info → flwr_nightly-1.23.0.dev20251031.dist-info}/METADATA +1 -1
  24. {flwr_nightly-1.23.0.dev20251029.dist-info → flwr_nightly-1.23.0.dev20251031.dist-info}/RECORD +26 -26
  25. {flwr_nightly-1.23.0.dev20251029.dist-info → flwr_nightly-1.23.0.dev20251031.dist-info}/WHEEL +0 -0
  26. {flwr_nightly-1.23.0.dev20251029.dist-info → flwr_nightly-1.23.0.dev20251031.dist-info}/entry_points.txt +0 -0
@@ -29,7 +29,10 @@ from flwr.common.constant import (
29
29
  TIMESTAMP_HEADER,
30
30
  TIMESTAMP_TOLERANCE,
31
31
  )
32
- from flwr.proto.fleet_pb2 import CreateNodeRequest # pylint: disable=E0611
32
+ from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
33
+ ActivateNodeRequest,
34
+ RegisterNodeFleetRequest,
35
+ )
33
36
  from flwr.server.superlink.linkstate import LinkStateFactory
34
37
  from flwr.supercore.primitives.asymmetric import bytes_to_public_key, verify_signature
35
38
 
@@ -110,15 +113,21 @@ class NodeAuthServerInterceptor(grpc.ServerInterceptor): # type: ignore
110
113
  request: GrpcMessage,
111
114
  context: grpc.ServicerContext,
112
115
  ) -> GrpcMessage:
116
+ # Note: This function runs in a different thread
117
+ # than the `intercept_service` function.
118
+
113
119
  # Retrieve the public key
114
- if isinstance(request, CreateNodeRequest):
120
+ if isinstance(request, (RegisterNodeFleetRequest, ActivateNodeRequest)):
115
121
  actual_public_key = request.public_key
116
122
  else:
117
- # Note: This function runs in a different thread
118
- # than the `intercept_service` function.
123
+ if hasattr(request, "node"):
124
+ node_id = request.node.node_id
125
+ else:
126
+ node_id = request.node_id # type: ignore[attr-defined]
119
127
  actual_public_key = self.state_factory.state().get_node_public_key(
120
- request.node.node_id # type: ignore
128
+ node_id
121
129
  )
130
+
122
131
  # Verify the public key
123
132
  if actual_public_key != expected_public_key:
124
133
  context.abort(grpc.StatusCode.UNAUTHENTICATED, "Invalid node ID")
@@ -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 NOOP_FLWR_AID, Status
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,15 +34,19 @@ 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
32
- CreateNodeRequest,
33
- CreateNodeResponse,
34
- DeleteNodeRequest,
35
- DeleteNodeResponse,
37
+ ActivateNodeRequest,
38
+ ActivateNodeResponse,
39
+ DeactivateNodeRequest,
40
+ DeactivateNodeResponse,
36
41
  PullMessagesRequest,
37
42
  PullMessagesResponse,
38
43
  PushMessagesRequest,
39
44
  PushMessagesResponse,
40
45
  Reconnect,
46
+ RegisterNodeFleetRequest,
47
+ RegisterNodeFleetResponse,
48
+ UnregisterNodeFleetRequest,
49
+ UnregisterNodeFleetResponse,
41
50
  )
42
51
  from flwr.proto.heartbeat_pb2 import ( # pylint: disable=E0611
43
52
  SendNodeHeartbeatRequest,
@@ -51,7 +60,6 @@ from flwr.proto.message_pb2 import ( # pylint: disable=E0611
51
60
  PushObjectRequest,
52
61
  PushObjectResponse,
53
62
  )
54
- from flwr.proto.node_pb2 import Node # pylint: disable=E0611
55
63
  from flwr.proto.run_pb2 import ( # pylint: disable=E0611
56
64
  GetRunRequest,
57
65
  GetRunResponse,
@@ -64,27 +72,52 @@ from flwr.supercore.object_store import NoObjectInStoreError, ObjectStore
64
72
  from flwr.supercore.object_store.utils import store_mapping_and_register_objects
65
73
 
66
74
 
67
- def create_node(
68
- request: CreateNodeRequest, # pylint: disable=unused-argument
75
+ class InvalidHeartbeatIntervalError(Exception):
76
+ """Invalid heartbeat interval exception."""
77
+
78
+
79
+ def register_node(
80
+ request: RegisterNodeFleetRequest,
69
81
  state: LinkState,
70
- ) -> CreateNodeResponse:
71
- """."""
72
- # Create node
73
- node_id = state.create_node(
74
- NOOP_FLWR_AID, request.public_key, request.heartbeat_interval
75
- )
76
- return CreateNodeResponse(node=Node(node_id=node_id))
82
+ ) -> RegisterNodeFleetResponse:
83
+ """Register a node (Fleet API only)."""
84
+ state.create_node(NOOP_FLWR_AID, request.public_key, 0)
85
+ return RegisterNodeFleetResponse()
77
86
 
78
87
 
79
- def delete_node(request: DeleteNodeRequest, state: LinkState) -> DeleteNodeResponse:
80
- """."""
81
- # Validate node_id
82
- if request.node.node_id == 0: # i.e. unset `node_id`
83
- return DeleteNodeResponse()
88
+ def activate_node(
89
+ request: ActivateNodeRequest,
90
+ state: LinkState,
91
+ ) -> ActivateNodeResponse:
92
+ """Activate a node."""
93
+ node_id = state.get_node_id_by_public_key(request.public_key)
94
+ if node_id is None:
95
+ raise ValueError("No SuperNode found with the given public key.")
96
+ _validate_heartbeat_interval(request.heartbeat_interval)
97
+ if not state.activate_node(node_id, request.heartbeat_interval):
98
+ raise ValueError(f"SuperNode with node ID {node_id} could not be activated.")
99
+ return ActivateNodeResponse(node_id=node_id)
100
+
101
+
102
+ def deactivate_node(
103
+ request: DeactivateNodeRequest,
104
+ state: LinkState,
105
+ ) -> DeactivateNodeResponse:
106
+ """Deactivate a node."""
107
+ if not state.deactivate_node(request.node_id):
108
+ raise ValueError(
109
+ f"SuperNode with node ID {request.node_id} could not be deactivated."
110
+ )
111
+ return DeactivateNodeResponse()
84
112
 
85
- # Update state
86
- state.delete_node(NOOP_FLWR_AID, node_id=request.node.node_id)
87
- return DeleteNodeResponse()
113
+
114
+ def unregister_node(
115
+ request: UnregisterNodeFleetRequest,
116
+ state: LinkState,
117
+ ) -> UnregisterNodeFleetResponse:
118
+ """Unregister a node (Fleet API only)."""
119
+ state.delete_node(NOOP_FLWR_AID, request.node_id)
120
+ return UnregisterNodeFleetResponse()
88
121
 
89
122
 
90
123
  def send_node_heartbeat(
@@ -92,6 +125,7 @@ def send_node_heartbeat(
92
125
  state: LinkState, # pylint: disable=unused-argument
93
126
  ) -> SendNodeHeartbeatResponse:
94
127
  """."""
128
+ _validate_heartbeat_interval(request.heartbeat_interval)
95
129
  res = state.acknowledge_node_heartbeat(
96
130
  request.node.node_id, request.heartbeat_interval
97
131
  )
@@ -286,3 +320,12 @@ def confirm_message_received(
286
320
  store.delete(request.message_object_id)
287
321
 
288
322
  return ConfirmMessageReceivedResponse()
323
+
324
+
325
+ def _validate_heartbeat_interval(interval: float) -> None:
326
+ """Raise if heartbeat interval is out of bounds."""
327
+ if not HEARTBEAT_MIN_INTERVAL <= interval <= HEARTBEAT_MAX_INTERVAL:
328
+ raise InvalidHeartbeatIntervalError(
329
+ f"Heartbeat interval {interval} is out of bounds "
330
+ f"[{HEARTBEAT_MIN_INTERVAL}, {HEARTBEAT_MAX_INTERVAL}]."
331
+ )
@@ -27,12 +27,8 @@ from flwr.proto.fab_pb2 import GetFabRequest, GetFabResponse # pylint: disable=
27
27
  from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
28
28
  ActivateNodeRequest,
29
29
  ActivateNodeResponse,
30
- CreateNodeRequest,
31
- CreateNodeResponse,
32
30
  DeactivateNodeRequest,
33
31
  DeactivateNodeResponse,
34
- DeleteNodeRequest,
35
- DeleteNodeResponse,
36
32
  PullMessagesRequest,
37
33
  PullMessagesResponse,
38
34
  PushMessagesRequest,
@@ -110,32 +106,16 @@ def rest_request_response(
110
106
  return decorator
111
107
 
112
108
 
113
- @rest_request_response(CreateNodeRequest)
114
- async def create_node(request: CreateNodeRequest) -> CreateNodeResponse:
115
- """Create Node."""
116
- # Get state from app
117
- state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
118
-
119
- # Handle message
120
- return message_handler.create_node(request=request, state=state)
121
-
122
-
123
- @rest_request_response(DeleteNodeRequest)
124
- async def delete_node(request: DeleteNodeRequest) -> DeleteNodeResponse:
125
- """Delete Node Id."""
126
- # Get state from app
127
- state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
128
-
129
- # Handle message
130
- return message_handler.delete_node(request=request, state=state)
131
-
132
-
133
109
  @rest_request_response(RegisterNodeFleetRequest)
134
110
  async def register_node(
135
111
  request: RegisterNodeFleetRequest,
136
112
  ) -> RegisterNodeFleetResponse:
137
113
  """Register a node (Fleet API only)."""
138
- raise NotImplementedError("RegisterNode is not yet implemented.")
114
+ # Get state from app
115
+ state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
116
+
117
+ # Handle message
118
+ return message_handler.register_node(request=request, state=state)
139
119
 
140
120
 
141
121
  @rest_request_response(ActivateNodeRequest)
@@ -143,7 +123,11 @@ async def activate_node(
143
123
  request: ActivateNodeRequest,
144
124
  ) -> ActivateNodeResponse:
145
125
  """Activate a node."""
146
- raise NotImplementedError("ActivateNode is not yet implemented.")
126
+ # Get state from app
127
+ state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
128
+
129
+ # Handle message
130
+ return message_handler.activate_node(request=request, state=state)
147
131
 
148
132
 
149
133
  @rest_request_response(DeactivateNodeRequest)
@@ -151,7 +135,11 @@ async def deactivate_node(
151
135
  request: DeactivateNodeRequest,
152
136
  ) -> DeactivateNodeResponse:
153
137
  """Deactivate a node."""
154
- raise NotImplementedError("DeactivateNode is not yet implemented.")
138
+ # Get state from app
139
+ state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
140
+
141
+ # Handle message
142
+ return message_handler.deactivate_node(request=request, state=state)
155
143
 
156
144
 
157
145
  @rest_request_response(UnregisterNodeFleetRequest)
@@ -159,7 +147,11 @@ async def unregister_node(
159
147
  request: UnregisterNodeFleetRequest,
160
148
  ) -> UnregisterNodeFleetResponse:
161
149
  """Unregister a node (Fleet API only)."""
162
- raise NotImplementedError("UnregisterNode is not yet implemented.")
150
+ # Get state from app
151
+ state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
152
+
153
+ # Handle message
154
+ return message_handler.unregister_node(request=request, state=state)
163
155
 
164
156
 
165
157
  @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
- HEARTBEAT_MAX_INTERVAL,
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=HEARTBEAT_MAX_INTERVAL,
65
+ heartbeat_interval=HEARTBEAT_INTERVAL_INF,
66
66
  )
67
67
  state.acknowledge_node_heartbeat(
68
- node_id=node_id, heartbeat_interval=HEARTBEAT_MAX_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
- HEARTBEAT_MAX_INTERVAL,
31
+ HEARTBEAT_INTERVAL_INF,
32
32
  HEARTBEAT_PATIENCE,
33
33
  MESSAGE_TTL_TOLERANCE,
34
34
  NODE_ID_NUM_BYTES,
@@ -117,7 +117,8 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
117
117
  )
118
118
  return None
119
119
  # Validate destination node ID
120
- if message.metadata.dst_node_id not in self.nodes:
120
+ dst_node = self.nodes.get(message.metadata.dst_node_id)
121
+ if dst_node is None or dst_node.status == NodeStatus.UNREGISTERED:
121
122
  log(
122
123
  ERROR,
123
124
  "Invalid destination node ID for Message: %s",
@@ -641,7 +642,7 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
641
642
  current = now()
642
643
  run_record = self.run_ids[run_id]
643
644
  if new_status.status in (Status.STARTING, Status.RUNNING):
644
- run_record.heartbeat_interval = HEARTBEAT_MAX_INTERVAL
645
+ run_record.heartbeat_interval = HEARTBEAT_INTERVAL_INF
645
646
  run_record.active_until = (
646
647
  current.timestamp() + run_record.heartbeat_interval
647
648
  )
@@ -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
- HEARTBEAT_MAX_INTERVAL,
30
+ HEARTBEAT_INTERVAL_INF,
31
31
  HEARTBEAT_PATIENCE,
32
32
  MESSAGE_TTL_TOLERANCE,
33
33
  NODE_ID_NUM_BYTES,
@@ -239,8 +239,8 @@ class SqliteLinkState(LinkState, SqliteMixin): # pylint: disable=R0904
239
239
  return None
240
240
 
241
241
  # Validate destination node ID
242
- query = "SELECT node_id FROM node WHERE node_id = ?;"
243
- if not self.query(query, (data[0]["dst_node_id"],)):
242
+ query = "SELECT node_id FROM node WHERE node_id = ? AND status != ?;"
243
+ if not self.query(query, (data[0]["dst_node_id"], NodeStatus.UNREGISTERED)):
244
244
  log(
245
245
  ERROR,
246
246
  "Invalid destination node ID for Message: %s",
@@ -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 = HEARTBEAT_MAX_INTERVAL
985
+ heartbeat_interval = HEARTBEAT_INTERVAL_INF
986
986
  active_until = current.timestamp() + heartbeat_interval
987
987
  else:
988
988
  heartbeat_interval = 0
@@ -23,6 +23,10 @@ EXEC_PLUGIN_SECTION = "exec_plugin"
23
23
  # Flower in-memory Python-based database name
24
24
  FLWR_IN_MEMORY_DB_NAME = ":flwr-in-memory:"
25
25
 
26
+ # Constants for Hub
27
+ APP_ID_PATTERN = r"^@(?P<user>[^/]+)/(?P<app>[^/]+)$"
28
+ PLATFORM_API_URL = "https://api.flower.ai/v1"
29
+
26
30
 
27
31
  class NodeStatus:
28
32
  """Event log writer types."""
@@ -61,6 +61,13 @@ def flower_supernode() -> None:
61
61
  root_certificates = try_obtain_root_certificates(args, args.superlink)
62
62
  authentication_keys = _try_setup_client_authentication(args)
63
63
 
64
+ # Warn if authentication keys are provided but transport is not grpc-rere
65
+ if authentication_keys is not None and args.transport != TRANSPORT_TYPE_GRPC_RERE:
66
+ log(
67
+ WARN,
68
+ "SuperNode Authentication is only supported with the grpc-rere transport.",
69
+ )
70
+
64
71
  log(DEBUG, "Isolation mode: %s", args.isolation)
65
72
 
66
73
  start_client_internal(
@@ -207,21 +207,16 @@ def start_client_internal(
207
207
  max_wait_time=max_wait_time,
208
208
  ) as conn:
209
209
  (
210
+ node_id,
210
211
  receive,
211
212
  send,
212
- create_node,
213
- _,
214
213
  get_run,
215
214
  get_fab,
216
215
  pull_object,
217
216
  push_object,
218
217
  confirm_message_received,
219
218
  ) = conn
220
-
221
- # Call create_node fn to register node
222
- # and store node_id in state
223
- if (node_id := create_node()) is None:
224
- raise ValueError("Failed to register SuperNode with the SuperLink")
219
+ # Store node_id in state
225
220
  state.set_node_id(node_id)
226
221
 
227
222
  # pylint: disable=too-many-nested-blocks
@@ -457,10 +452,9 @@ def _init_connection( # pylint: disable=too-many-positional-arguments
457
452
  max_wait_time: Optional[float] = None,
458
453
  ) -> Iterator[
459
454
  tuple[
455
+ int,
460
456
  Callable[[], Optional[tuple[Message, ObjectTree]]],
461
457
  Callable[[Message, ObjectTree], set[str]],
462
- Callable[[], Optional[int]],
463
- Callable[[], None],
464
458
  Callable[[int], Run],
465
459
  Callable[[str, int], Fab],
466
460
  Callable[[int, str], bytes],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: flwr-nightly
3
- Version: 1.23.0.dev20251029
3
+ Version: 1.23.0.dev20251031
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
@@ -20,7 +20,7 @@ flwr/cli/login/__init__.py,sha256=B1SXKU3HCQhWfFDMJhlC7FOl8UsvH4mxysxeBnrfyUE,80
20
20
  flwr/cli/login/login.py,sha256=XeA6K9rZn3CBvtiFP3XWTAk7s8766BCqHvCsO_tJEuY,4558
21
21
  flwr/cli/ls.py,sha256=MUlWSjO0yhVTupN5Fr0zvdvRqfRBGWliuoyWA0D-Pzg,11107
22
22
  flwr/cli/new/__init__.py,sha256=QA1E2QtzPvFCjLTUHnFnJbufuFiGyT_0Y53Wpbvg1F0,790
23
- flwr/cli/new/new.py,sha256=nIuUrQSGDjI4kqnymlq-rOT0RU3AHwZrat3abqHhCwM,10598
23
+ flwr/cli/new/new.py,sha256=NOzI72lLAk1U9-g54Re04DBpgK81JOqMiXHRE5l-_Fo,15301
24
24
  flwr/cli/new/templates/__init__.py,sha256=FpjWCfIySU2DB4kh0HOXLAjlZNNFDTVU4w3HoE2TzcI,725
25
25
  flwr/cli/new/templates/app/.gitignore.tpl,sha256=HZJcGQoxp7aUzaPg8Uqch3kNrIESwr9yjimDxJYgXVY,3104
26
26
  flwr/cli/new/templates/app/LICENSE.tpl,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
@@ -95,10 +95,10 @@ flwr/client/__init__.py,sha256=Q0MIF442vLIGSkcwHKq_sIfECQynLARJrumAscq2Q6E,1241
95
95
  flwr/client/client.py,sha256=3HAchxvknKG9jYbB7swNyDj-e5vUWDuMKoLvbT7jCVM,7895
96
96
  flwr/client/dpfedavg_numpy_client.py,sha256=3hul067cT2E9jBhzp7bFnFAZ_D2nWcIUEdHYE05FpzU,7404
97
97
  flwr/client/grpc_adapter_client/__init__.py,sha256=RQWP5mFPROLHKgombiRvPXVWSoVrQ81wvZm0-lOuuBA,742
98
- flwr/client/grpc_adapter_client/connection.py,sha256=JGv02EjSOAG1E5BRUD4lwXc1LLiYJ0OhInvp31qx1cU,4404
98
+ flwr/client/grpc_adapter_client/connection.py,sha256=jCwvteuzGfCjasBtsq1e_GSBvJ5fAp_ci0l5wM99kRw,4305
99
99
  flwr/client/grpc_rere_client/__init__.py,sha256=i7iS0Lt8B7q0E2L72e4F_YrKm6ClRKnd71PNA6PW2O0,752
100
- flwr/client/grpc_rere_client/connection.py,sha256=3_CI7wx5ZrkGrVCXjDKiUGX9aJP9Zm9yl4iqSBAmH3U,13100
101
- flwr/client/grpc_rere_client/grpc_adapter.py,sha256=YwsZOvFgCd1JdiHnl1Cc18vKOiGwWSSJ_9-ZXwlGZvs,7900
100
+ flwr/client/grpc_rere_client/connection.py,sha256=LqRbo_rkZsPIiIT1goclNYDIsdsEfIz3qrQGPU6QNoY,13771
101
+ flwr/client/grpc_rere_client/grpc_adapter.py,sha256=1s1suFIGxAbx6UiIZH-VtLpZlkct5FI4OF4bb589A0o,7358
102
102
  flwr/client/grpc_rere_client/node_auth_client_interceptor.py,sha256=EdTyb5ThFrpkeyXy9_nTKH7E9GnfAdXjcNZ_-uxt1AA,2410
103
103
  flwr/client/message_handler/__init__.py,sha256=0lyljDVqre3WljiZbPcwCCf8GiIaSVI_yo_ylEyPwSE,719
104
104
  flwr/client/message_handler/message_handler.py,sha256=X9SXX6et97Lw9_DGD93HKsEBGNjXClcFgc_5aLK0oiU,6541
@@ -112,7 +112,7 @@ flwr/client/mod/secure_aggregation/secaggplus_mod.py,sha256=Ib-HlhZOXB6-hAWGZ0Ip
112
112
  flwr/client/mod/utils.py,sha256=FUgD2TfcWqSeF6jUKZ4i6Ke56U4Nrv85AeVb93s6R9g,1201
113
113
  flwr/client/numpy_client.py,sha256=Qq6ghsIAop2slKqAfgiI5NiHJ4LIxGmrik3Ror4_XVc,9581
114
114
  flwr/client/rest_client/__init__.py,sha256=MBiuK62hj439m9rtwSwI184Hth6Tt5GbmpNMyl3zkZY,735
115
- flwr/client/rest_client/connection.py,sha256=uqcCT6lLgtzb_T2-u6iB60-fVaTz9uE7fy5uvLikQ_I,15962
115
+ flwr/client/rest_client/connection.py,sha256=HtEHtKuX32ff4W86NZiqtTU3PbCtcTYcPUs6jp84Ghw,17501
116
116
  flwr/client/run_info_store.py,sha256=MaJ3UQ-07hWtK67wnWu0zR29jrk0fsfgJX506dvEOfE,4042
117
117
  flwr/client/typing.py,sha256=Jw3rawDzI_-ZDcRmEQcs5gZModY7oeQlEeltYsdOhlU,1048
118
118
  flwr/clientapp/__init__.py,sha256=dsXH29kvCk1meJj9UYMCIak8zehuuhVp0uDJ2COU_1c,829
@@ -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=EjVoFZZgkxREzd312A2K4LlNk8H27rU4hWGW-CZ9qCI,10145
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
@@ -203,10 +203,10 @@ flwr/proto/fab_pb2.py,sha256=AQAUJmTt31Kq-lJQid3CJpQPrply2-OA_aSHokpVF84,2070
203
203
  flwr/proto/fab_pb2.pyi,sha256=GOxeDi-UYzQVwIEzRk9YkzkriowmNdibZu3jMMtBPFo,3273
204
204
  flwr/proto/fab_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
205
205
  flwr/proto/fab_pb2_grpc.pyi,sha256=ff2TSiLVnG6IVQcTGzb2DIH3XRSoAvAo_RMcvbMFyc0,76
206
- flwr/proto/fleet_pb2.py,sha256=FyQJ-FCsYJLwQZeYrs_p6Y_OgA9jPoxGHyIvWeukXxU,7171
207
- flwr/proto/fleet_pb2.pyi,sha256=-cKglysTm0FPkAqdD2cKzfxFhb1rP_z5aOD5RSPrFxU,11209
208
- flwr/proto/fleet_pb2_grpc.py,sha256=ss_fFtTJuVSzYLxWsW5Fn6XfUBnJIKV7BTBX5vyhPMY,24083
209
- flwr/proto/fleet_pb2_grpc.pyi,sha256=WJIV7EmoePxY6CaYF1cj3oZ2ss6E1pt7Zs5C6ehz69c,6461
206
+ flwr/proto/fleet_pb2.py,sha256=wl1uxtBDEZulKo8pBMv3Q0AZy0_I1YY-_6Bf33mGQJk,6198
207
+ flwr/proto/fleet_pb2.pyi,sha256=F41lGrsI64MYwj7yCzEviU1BrN0abOR7K88vqwhSwyE,9168
208
+ flwr/proto/fleet_pb2_grpc.py,sha256=GKBHMa6j__vpArCgALT_1p47FVuPurgpYDG7ZjFgjls,20853
209
+ flwr/proto/fleet_pb2_grpc.pyi,sha256=uO5EmcGdzw6VDsifmb5rCbs7FmyyOGs4bNfitFNONik,5773
210
210
  flwr/proto/grpcadapter_pb2.py,sha256=PJ8DtfeV29g_y4Z3aNZlSZocLqSxeLmTsYCdOZDYCiE,1843
211
211
  flwr/proto/grpcadapter_pb2.pyi,sha256=AR77gDsF6f8zqSIQp3877DUd7S8lP95lFak5Ir_WPkw,1716
212
212
  flwr/proto/grpcadapter_pb2_grpc.py,sha256=rRNuNES5nBugUZWfeA8oAy8dMHgzqU_PF1srTseo3b8,2634
@@ -249,7 +249,7 @@ flwr/proto/transport_pb2_grpc.py,sha256=vLN3EHtx2aEEMCO4f1Upu-l27BPzd3-5pV-u8wPc
249
249
  flwr/proto/transport_pb2_grpc.pyi,sha256=AGXf8RiIiW2J5IKMlm_3qT3AzcDa4F3P5IqUjve_esA,766
250
250
  flwr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
251
251
  flwr/server/__init__.py,sha256=LQQHiuL2jy7TpNaKastRdGsexlxSt5ZWAQNVqitDnrY,1598
252
- flwr/server/app.py,sha256=8TTbv6W4qnEYuZMzdDWRb0ajFksGvZtgiA195onHyJQ,30330
252
+ flwr/server/app.py,sha256=vnRG6PxZYOqi6VKbDxD0wRaDoNq2Ip3TYV3HjDew1I0,30940
253
253
  flwr/server/client_manager.py,sha256=5jCGavVli7XdupvWWo7ru3PdFTlRU8IGvHFSSoUVLRs,6227
254
254
  flwr/server/client_proxy.py,sha256=sv0E9AldBYOvc3pusqFh-GnyreeMfsXQ1cuTtxTq_wY,2399
255
255
  flwr/server/compat/__init__.py,sha256=0IsttWvY15qO98_1GyzVC-vR1e_ZPXOdu2qUlOkYMPE,886
@@ -298,29 +298,29 @@ flwr/server/strategy/strategy.py,sha256=n4r52i5gK4KGToZvcJUeWuEif1tuI0HZUT3YJPTC
298
298
  flwr/server/superlink/__init__.py,sha256=GNSuJ4-N6Z8wun2iZNlXqENt5beUyzC0Gi_tN396bbM,707
299
299
  flwr/server/superlink/fleet/__init__.py,sha256=Uiwr33yfW_eL-pEfj80c_JUhIKRkCPsN1JSs2v4aglU,711
300
300
  flwr/server/superlink/fleet/grpc_adapter/__init__.py,sha256=fUu1V63YrzjxAOZnBJx99WjuD4Mro7dJIFH-1V4NLV8,742
301
- flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py,sha256=zFWNbVnT-HMHJiZO154ciaT2GeA8TcFpwEJuNI793eU,5879
301
+ flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py,sha256=1XGkP6DKEKf-GehK8lGhPIACmHz4wsbOXx9wLaxaj44,5527
302
302
  flwr/server/superlink/fleet/grpc_bidi/__init__.py,sha256=dOM49q1b9MrtUr5jldjEnQ38NhcUyYs-zC3gsJb1TtI,735
303
303
  flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py,sha256=UKEp-3YBaTvNt7vKZW7KLgK5xsAiO7jxU-omG7CaO_s,6021
304
304
  flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py,sha256=KouR9PUcrPmMtoLooF4O9SRAwIvfiroo8mPmqUc2EZc,6485
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=0HwtOgCuQ1x8YCZXMFN6a2Y7agR4TR5e6rruBuxqqrI,13620
309
- flwr/server/superlink/fleet/grpc_rere/node_auth_server_interceptor.py,sha256=UWeFQNBW2pGBRVN36HodHcv7bKTgMmdToh96Lhqip1M,5411
308
+ flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py,sha256=Rit-x6l7EhhyZX_RWxGNaeKIyFTDjKelBKZ2q-vfVOo,12181
309
+ flwr/server/superlink/fleet/grpc_rere/node_auth_server_interceptor.py,sha256=Q1t2cGLPrp_jw0_x3BZTc-SxeLP6BzRaEJZQFH075dA,5641
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=GYveEXgKRlyrKRUr2H6kjWPx_g4-fnATrMdJD2G4Gaw,8762
311
+ flwr/server/superlink/fleet/message_handler/message_handler.py,sha256=HatVb3UuutXb9coJ9D6as6HQIMiu1UF0KIOvJO4hPKw,10200
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=HzLx_3sY2_EXBLzLA_ZvKgZrgFDzIh0wesDfLrqyxvU,9875
313
+ flwr/server/superlink/fleet/rest_rere/rest_api.py,sha256=FK-xehmTfOBNjOLSeTYv-YDeyPvkiQI4UQhbwyYWt60,9616
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=sgsAx7dgIADA-Ae71s5dwoPY0bw3-qA7RukJgnh8pgc,13389
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=STJs4CNgdRknGFvreCdumBSDfUxqW8X0hpCun1wcROM,31829
320
+ flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=1qMnE9j3gdHaCTVDBjGX1rLP7b0cesJovM0H-0yBhmk,31909
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=5KJnrqDz1bNphLhJI9iZz2_mrbl1_DsTOSbwfncsE1E,47528
323
+ flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=TYNqEkhBaklv2hvjW8zF17GUcfjbJBrAKxbW8-6If_8,47568
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
@@ -375,7 +375,7 @@ flwr/supercore/__init__.py,sha256=pqkFoow_E6UhbBlhmoD1gmTH-33yJRhBsIZqxRPFZ7U,75
375
375
  flwr/supercore/app_utils.py,sha256=K76Zt6R670b1hUmxOsNc1WUCVYvF7lejXPcCO9K0Q0g,1753
376
376
  flwr/supercore/cli/__init__.py,sha256=EDl2aO-fuQfxSbL-T1W9RAfA2N0hpWHmqX_GSwblJbQ,845
377
377
  flwr/supercore/cli/flower_superexec.py,sha256=JtqYrEWVu3BxLkjavsdohTOwvMwzuFqWP5j4Mo9dqsk,6155
378
- flwr/supercore/constant.py,sha256=38XUpUQwv1tLmfghm0oGWJzz2b0Ns9MrqDbKO9EPyiQ,1253
378
+ flwr/supercore/constant.py,sha256=LZiryorWpCNvry55EiQinPHazPVhIQHmxdSQMaPu_R4,1374
379
379
  flwr/supercore/corestate/__init__.py,sha256=Vau6-L_JG5QzNqtCTa9xCKGGljc09wY8avZmIjSJemg,774
380
380
  flwr/supercore/corestate/corestate.py,sha256=rDAWWeG5DcpCyQso9Z3RhwL4zr2IroPlRMcDzqoSu8s,2328
381
381
  flwr/supercore/ffs/__init__.py,sha256=U3KXwG_SplEvchat27K0LYPoPHzh-cwwT_NHsGlYMt8,908
@@ -421,7 +421,7 @@ flwr/superlink/servicer/control/control_license_interceptor.py,sha256=T3AzmRt-PP
421
421
  flwr/superlink/servicer/control/control_servicer.py,sha256=93-lZ2pSjbpod-zhu_5ZSOK2ZZVTiBT-0mzl53pFlLw,19454
422
422
  flwr/supernode/__init__.py,sha256=KgeCaVvXWrU3rptNR1y0oBp4YtXbAcrnCcJAiOoWkI4,707
423
423
  flwr/supernode/cli/__init__.py,sha256=JuEMr0-s9zv-PEWKuLB9tj1ocNfroSyNJ-oyv7ati9A,887
424
- flwr/supernode/cli/flower_supernode.py,sha256=bmPpg88Zq7NYMDzyyDwBzeZ6_1f26fD_iDdGw1o_4QQ,8334
424
+ flwr/supernode/cli/flower_supernode.py,sha256=3XJ_VRGSiQIwIcDp62B3J7aFvKQyGRzTGiq9JMXFF8Y,8629
425
425
  flwr/supernode/cli/flwr_clientapp.py,sha256=W3tAyqSfeHbPhqBC4Pfo9bsyFdkBKPqdKlhGmeUKwKg,3173
426
426
  flwr/supernode/nodestate/__init__.py,sha256=CyLLObbmmVgfRO88UCM0VMait1dL57mUauUDfuSHsbU,976
427
427
  flwr/supernode/nodestate/in_memory_nodestate.py,sha256=rr_tg7YXhf_seYFipSB59TAfheKPratx3rrvHUOJ80g,7343
@@ -432,8 +432,8 @@ flwr/supernode/runtime/run_clientapp.py,sha256=BuaAKTzRuFmNX-IJky3kJzoWMmZkz9joH
432
432
  flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca8gxdEo,717
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
- flwr/supernode/start_client_internal.py,sha256=wKqh9-_rQYi7JFKpYBLRiUeq9YJUSyUd9b-SnVnuvwI,21567
436
- flwr_nightly-1.23.0.dev20251029.dist-info/METADATA,sha256=IbVE7qYkOpvhbjaQ8hYXUx3el8wwZN8UQKbeTKeKrjE,14559
437
- flwr_nightly-1.23.0.dev20251029.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
438
- flwr_nightly-1.23.0.dev20251029.dist-info/entry_points.txt,sha256=hxHD2ixb_vJFDOlZV-zB4Ao32_BQlL34ftsDh1GXv14,420
439
- flwr_nightly-1.23.0.dev20251029.dist-info/RECORD,,
435
+ flwr/supernode/start_client_internal.py,sha256=opgc3fQPNbCRKQJ39NNYHWsygx6WDsc-n_1t6nvRmdc,21317
436
+ flwr_nightly-1.23.0.dev20251031.dist-info/METADATA,sha256=7rjulx0S0gaQBaaDEw_o8roftwZy4H9giVDefS4AF0M,14559
437
+ flwr_nightly-1.23.0.dev20251031.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
438
+ flwr_nightly-1.23.0.dev20251031.dist-info/entry_points.txt,sha256=hxHD2ixb_vJFDOlZV-zB4Ao32_BQlL34ftsDh1GXv14,420
439
+ flwr_nightly-1.23.0.dev20251031.dist-info/RECORD,,