flwr-nightly 1.23.0.dev20251023__py3-none-any.whl → 1.23.0.dev20251027__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/cli/run/run.py CHANGED
@@ -155,7 +155,7 @@ def _run_with_control_api(
155
155
  fab_bytes, fab_hash, config = build_fab(app)
156
156
  fab_id, fab_version = get_metadata_from_config(config)
157
157
 
158
- fab = Fab(fab_hash, fab_bytes)
158
+ fab = Fab(fab_hash, fab_bytes, {})
159
159
 
160
160
  # Construct a `ConfigRecord` out of a flattened `UserConfig`
161
161
  fed_config = flatten_dict(federation_config.get("options", {}))
@@ -36,7 +36,12 @@ from flwr.common.inflatable_protobuf_utils import (
36
36
  from flwr.common.logger import log
37
37
  from flwr.common.message import Message, remove_content_from_message
38
38
  from flwr.common.retry_invoker import RetryInvoker, _wrap_stub
39
- from flwr.common.serde import message_from_proto, message_to_proto, run_from_proto
39
+ from flwr.common.serde import (
40
+ fab_from_proto,
41
+ message_from_proto,
42
+ message_to_proto,
43
+ run_from_proto,
44
+ )
40
45
  from flwr.common.typing import Fab, Run
41
46
  from flwr.proto.fab_pb2 import GetFabRequest, GetFabResponse # pylint: disable=E0611
42
47
  from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
@@ -289,7 +294,7 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
289
294
  get_fab_request = GetFabRequest(node=node, hash_str=fab_hash, run_id=run_id)
290
295
  get_fab_response: GetFabResponse = stub.GetFab(request=get_fab_request)
291
296
 
292
- return Fab(get_fab_response.fab.hash_str, get_fab_response.fab.content)
297
+ return fab_from_proto(get_fab_response.fab)
293
298
 
294
299
  def pull_object(run_id: int, object_id: str) -> bytes:
295
300
  """Pull the object from the SuperLink."""
@@ -37,7 +37,12 @@ from flwr.common.inflatable_protobuf_utils import (
37
37
  from flwr.common.logger import log
38
38
  from flwr.common.message import Message, remove_content_from_message
39
39
  from flwr.common.retry_invoker import RetryInvoker
40
- from flwr.common.serde import message_from_proto, message_to_proto, run_from_proto
40
+ from flwr.common.serde import (
41
+ fab_from_proto,
42
+ message_from_proto,
43
+ message_to_proto,
44
+ run_from_proto,
45
+ )
41
46
  from flwr.common.typing import Fab, Run
42
47
  from flwr.proto.fab_pb2 import GetFabRequest, GetFabResponse # pylint: disable=E0611
43
48
  from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
@@ -398,12 +403,9 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
398
403
  # Send the request
399
404
  res = _request(req, GetFabResponse, PATH_GET_FAB)
400
405
  if res is None:
401
- return Fab("", b"")
406
+ return Fab("", b"", {})
402
407
 
403
- return Fab(
404
- res.fab.hash_str,
405
- res.fab.content,
406
- )
408
+ return fab_from_proto(res.fab)
407
409
 
408
410
  def pull_object(run_id: int, object_id: str) -> bytes:
409
411
  """Pull the object from the SuperLink."""
flwr/common/serde.py CHANGED
@@ -501,12 +501,14 @@ def recorddict_from_proto(recorddict_proto: ProtoRecordDict) -> RecordDict:
501
501
 
502
502
  def fab_to_proto(fab: typing.Fab) -> ProtoFab:
503
503
  """Create a proto Fab object from a Python Fab."""
504
- return ProtoFab(hash_str=fab.hash_str, content=fab.content)
504
+ return ProtoFab(
505
+ hash_str=fab.hash_str, content=fab.content, verifications=fab.verifications
506
+ )
505
507
 
506
508
 
507
509
  def fab_from_proto(fab: ProtoFab) -> typing.Fab:
508
510
  """Create a Python Fab object from a proto Fab."""
509
- return typing.Fab(fab.hash_str, fab.content)
511
+ return typing.Fab(fab.hash_str, fab.content, dict(fab.verifications))
510
512
 
511
513
 
512
514
  # === User configs ===
flwr/common/typing.py CHANGED
@@ -256,6 +256,7 @@ class Fab:
256
256
 
257
257
  hash_str: str
258
258
  content: bytes
259
+ verifications: dict[str, str]
259
260
 
260
261
 
261
262
  class RunNotRunningException(BaseException):
flwr/proto/control_pb2.py CHANGED
@@ -19,7 +19,7 @@ from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2
19
19
  from flwr.proto import node_pb2 as flwr_dot_proto_dot_node__pb2
20
20
 
21
21
 
22
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18\x66lwr/proto/control.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x1b\x66lwr/proto/recorddict.proto\x1a\x14\x66lwr/proto/run.proto\x1a\x15\x66lwr/proto/node.proto\"\xfa\x01\n\x0fStartRunRequest\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fab\x12H\n\x0foverride_config\x18\x02 \x03(\x0b\x32/.flwr.proto.StartRunRequest.OverrideConfigEntry\x12\x34\n\x12\x66\x65\x64\x65ration_options\x18\x03 \x01(\x0b\x32\x18.flwr.proto.ConfigRecord\x1aI\n\x13OverrideConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"2\n\x10StartRunResponse\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"<\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x17\n\x0f\x61\x66ter_timestamp\x18\x02 \x01(\x01\"B\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t\x12\x18\n\x10latest_timestamp\x18\x02 \x01(\x01\"1\n\x0fListRunsRequest\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"\x9d\x01\n\x10ListRunsResponse\x12;\n\x08run_dict\x18\x01 \x03(\x0b\x32).flwr.proto.ListRunsResponse.RunDictEntry\x12\x0b\n\x03now\x18\x02 \x01(\t\x1a?\n\x0cRunDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x1e\n\x05value\x18\x02 \x01(\x0b\x32\x0f.flwr.proto.Run:\x02\x38\x01\"\x18\n\x16GetLoginDetailsRequest\"\x8b\x01\n\x17GetLoginDetailsResponse\x12\x12\n\nauthn_type\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65vice_code\x18\x02 \x01(\t\x12!\n\x19verification_uri_complete\x18\x03 \x01(\t\x12\x12\n\nexpires_in\x18\x04 \x01(\x03\x12\x10\n\x08interval\x18\x05 \x01(\x03\"+\n\x14GetAuthTokensRequest\x12\x13\n\x0b\x64\x65vice_code\x18\x01 \x01(\t\"D\n\x15GetAuthTokensResponse\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x01 \x01(\t\x12\x15\n\rrefresh_token\x18\x02 \x01(\t\" \n\x0eStopRunRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"\"\n\x0fStopRunResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\"&\n\x14PullArtifactsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"1\n\x15PullArtifactsResponse\x12\x10\n\x03url\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x06\n\x04_url\")\n\x13RegisterNodeRequest\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\"8\n\x14RegisterNodeResponse\x12\x14\n\x07node_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\n\n\x08_node_id\"(\n\x15UnregisterNodeRequest\x12\x0f\n\x07node_id\x18\x01 \x01(\x04\"\x18\n\x16UnregisterNodeResponse\"\x12\n\x10ListNodesRequest\"J\n\x11ListNodesResponse\x12(\n\nnodes_info\x18\x01 \x03(\x0b\x32\x14.flwr.proto.NodeInfo\x12\x0b\n\x03now\x18\x02 \x01(\t2\xbc\x06\n\x07\x43ontrol\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\x00\x12\x44\n\x07StopRun\x12\x1a.flwr.proto.StopRunRequest\x1a\x1b.flwr.proto.StopRunResponse\"\x00\x12O\n\nStreamLogs\x12\x1d.flwr.proto.StreamLogsRequest\x1a\x1e.flwr.proto.StreamLogsResponse\"\x00\x30\x01\x12G\n\x08ListRuns\x12\x1b.flwr.proto.ListRunsRequest\x1a\x1c.flwr.proto.ListRunsResponse\"\x00\x12\\\n\x0fGetLoginDetails\x12\".flwr.proto.GetLoginDetailsRequest\x1a#.flwr.proto.GetLoginDetailsResponse\"\x00\x12V\n\rGetAuthTokens\x12 .flwr.proto.GetAuthTokensRequest\x1a!.flwr.proto.GetAuthTokensResponse\"\x00\x12V\n\rPullArtifacts\x12 .flwr.proto.PullArtifactsRequest\x1a!.flwr.proto.PullArtifactsResponse\"\x00\x12S\n\x0cRegisterNode\x12\x1f.flwr.proto.RegisterNodeRequest\x1a .flwr.proto.RegisterNodeResponse\"\x00\x12Y\n\x0eUnregisterNode\x12!.flwr.proto.UnregisterNodeRequest\x1a\".flwr.proto.UnregisterNodeResponse\"\x00\x12J\n\tListNodes\x12\x1c.flwr.proto.ListNodesRequest\x1a\x1d.flwr.proto.ListNodesResponse\"\x00\x62\x06proto3')
22
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18\x66lwr/proto/control.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x1b\x66lwr/proto/recorddict.proto\x1a\x14\x66lwr/proto/run.proto\x1a\x15\x66lwr/proto/node.proto\"\x8a\x02\n\x0fStartRunRequest\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fab\x12H\n\x0foverride_config\x18\x02 \x03(\x0b\x32/.flwr.proto.StartRunRequest.OverrideConfigEntry\x12\x34\n\x12\x66\x65\x64\x65ration_options\x18\x03 \x01(\x0b\x32\x18.flwr.proto.ConfigRecord\x12\x0e\n\x06\x61pp_id\x18\x04 \x01(\t\x1aI\n\x13OverrideConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"2\n\x10StartRunResponse\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"<\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x17\n\x0f\x61\x66ter_timestamp\x18\x02 \x01(\x01\"B\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t\x12\x18\n\x10latest_timestamp\x18\x02 \x01(\x01\"1\n\x0fListRunsRequest\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"\x9d\x01\n\x10ListRunsResponse\x12;\n\x08run_dict\x18\x01 \x03(\x0b\x32).flwr.proto.ListRunsResponse.RunDictEntry\x12\x0b\n\x03now\x18\x02 \x01(\t\x1a?\n\x0cRunDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x1e\n\x05value\x18\x02 \x01(\x0b\x32\x0f.flwr.proto.Run:\x02\x38\x01\"\x18\n\x16GetLoginDetailsRequest\"\x8b\x01\n\x17GetLoginDetailsResponse\x12\x12\n\nauthn_type\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65vice_code\x18\x02 \x01(\t\x12!\n\x19verification_uri_complete\x18\x03 \x01(\t\x12\x12\n\nexpires_in\x18\x04 \x01(\x03\x12\x10\n\x08interval\x18\x05 \x01(\x03\"+\n\x14GetAuthTokensRequest\x12\x13\n\x0b\x64\x65vice_code\x18\x01 \x01(\t\"D\n\x15GetAuthTokensResponse\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x01 \x01(\t\x12\x15\n\rrefresh_token\x18\x02 \x01(\t\" \n\x0eStopRunRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"\"\n\x0fStopRunResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\"&\n\x14PullArtifactsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"1\n\x15PullArtifactsResponse\x12\x10\n\x03url\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x06\n\x04_url\")\n\x13RegisterNodeRequest\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\"8\n\x14RegisterNodeResponse\x12\x14\n\x07node_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\n\n\x08_node_id\"(\n\x15UnregisterNodeRequest\x12\x0f\n\x07node_id\x18\x01 \x01(\x04\"\x18\n\x16UnregisterNodeResponse\"\x12\n\x10ListNodesRequest\"J\n\x11ListNodesResponse\x12(\n\nnodes_info\x18\x01 \x03(\x0b\x32\x14.flwr.proto.NodeInfo\x12\x0b\n\x03now\x18\x02 \x01(\t2\xbc\x06\n\x07\x43ontrol\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\x00\x12\x44\n\x07StopRun\x12\x1a.flwr.proto.StopRunRequest\x1a\x1b.flwr.proto.StopRunResponse\"\x00\x12O\n\nStreamLogs\x12\x1d.flwr.proto.StreamLogsRequest\x1a\x1e.flwr.proto.StreamLogsResponse\"\x00\x30\x01\x12G\n\x08ListRuns\x12\x1b.flwr.proto.ListRunsRequest\x1a\x1c.flwr.proto.ListRunsResponse\"\x00\x12\\\n\x0fGetLoginDetails\x12\".flwr.proto.GetLoginDetailsRequest\x1a#.flwr.proto.GetLoginDetailsResponse\"\x00\x12V\n\rGetAuthTokens\x12 .flwr.proto.GetAuthTokensRequest\x1a!.flwr.proto.GetAuthTokensResponse\"\x00\x12V\n\rPullArtifacts\x12 .flwr.proto.PullArtifactsRequest\x1a!.flwr.proto.PullArtifactsResponse\"\x00\x12S\n\x0cRegisterNode\x12\x1f.flwr.proto.RegisterNodeRequest\x1a .flwr.proto.RegisterNodeResponse\"\x00\x12Y\n\x0eUnregisterNode\x12!.flwr.proto.UnregisterNodeRequest\x1a\".flwr.proto.UnregisterNodeResponse\"\x00\x12J\n\tListNodes\x12\x1c.flwr.proto.ListNodesRequest\x1a\x1d.flwr.proto.ListNodesResponse\"\x00\x62\x06proto3')
23
23
 
24
24
  _globals = globals()
25
25
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -31,49 +31,49 @@ if _descriptor._USE_C_DESCRIPTORS == False:
31
31
  _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._options = None
32
32
  _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_options = b'8\001'
33
33
  _globals['_STARTRUNREQUEST']._serialized_start=165
34
- _globals['_STARTRUNREQUEST']._serialized_end=415
35
- _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=342
36
- _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=415
37
- _globals['_STARTRUNRESPONSE']._serialized_start=417
38
- _globals['_STARTRUNRESPONSE']._serialized_end=467
39
- _globals['_STREAMLOGSREQUEST']._serialized_start=469
40
- _globals['_STREAMLOGSREQUEST']._serialized_end=529
41
- _globals['_STREAMLOGSRESPONSE']._serialized_start=531
42
- _globals['_STREAMLOGSRESPONSE']._serialized_end=597
43
- _globals['_LISTRUNSREQUEST']._serialized_start=599
44
- _globals['_LISTRUNSREQUEST']._serialized_end=648
45
- _globals['_LISTRUNSRESPONSE']._serialized_start=651
46
- _globals['_LISTRUNSRESPONSE']._serialized_end=808
47
- _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_start=745
48
- _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_end=808
49
- _globals['_GETLOGINDETAILSREQUEST']._serialized_start=810
50
- _globals['_GETLOGINDETAILSREQUEST']._serialized_end=834
51
- _globals['_GETLOGINDETAILSRESPONSE']._serialized_start=837
52
- _globals['_GETLOGINDETAILSRESPONSE']._serialized_end=976
53
- _globals['_GETAUTHTOKENSREQUEST']._serialized_start=978
54
- _globals['_GETAUTHTOKENSREQUEST']._serialized_end=1021
55
- _globals['_GETAUTHTOKENSRESPONSE']._serialized_start=1023
56
- _globals['_GETAUTHTOKENSRESPONSE']._serialized_end=1091
57
- _globals['_STOPRUNREQUEST']._serialized_start=1093
58
- _globals['_STOPRUNREQUEST']._serialized_end=1125
59
- _globals['_STOPRUNRESPONSE']._serialized_start=1127
60
- _globals['_STOPRUNRESPONSE']._serialized_end=1161
61
- _globals['_PULLARTIFACTSREQUEST']._serialized_start=1163
62
- _globals['_PULLARTIFACTSREQUEST']._serialized_end=1201
63
- _globals['_PULLARTIFACTSRESPONSE']._serialized_start=1203
64
- _globals['_PULLARTIFACTSRESPONSE']._serialized_end=1252
65
- _globals['_REGISTERNODEREQUEST']._serialized_start=1254
66
- _globals['_REGISTERNODEREQUEST']._serialized_end=1295
67
- _globals['_REGISTERNODERESPONSE']._serialized_start=1297
68
- _globals['_REGISTERNODERESPONSE']._serialized_end=1353
69
- _globals['_UNREGISTERNODEREQUEST']._serialized_start=1355
70
- _globals['_UNREGISTERNODEREQUEST']._serialized_end=1395
71
- _globals['_UNREGISTERNODERESPONSE']._serialized_start=1397
72
- _globals['_UNREGISTERNODERESPONSE']._serialized_end=1421
73
- _globals['_LISTNODESREQUEST']._serialized_start=1423
74
- _globals['_LISTNODESREQUEST']._serialized_end=1441
75
- _globals['_LISTNODESRESPONSE']._serialized_start=1443
76
- _globals['_LISTNODESRESPONSE']._serialized_end=1517
77
- _globals['_CONTROL']._serialized_start=1520
78
- _globals['_CONTROL']._serialized_end=2348
34
+ _globals['_STARTRUNREQUEST']._serialized_end=431
35
+ _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=358
36
+ _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=431
37
+ _globals['_STARTRUNRESPONSE']._serialized_start=433
38
+ _globals['_STARTRUNRESPONSE']._serialized_end=483
39
+ _globals['_STREAMLOGSREQUEST']._serialized_start=485
40
+ _globals['_STREAMLOGSREQUEST']._serialized_end=545
41
+ _globals['_STREAMLOGSRESPONSE']._serialized_start=547
42
+ _globals['_STREAMLOGSRESPONSE']._serialized_end=613
43
+ _globals['_LISTRUNSREQUEST']._serialized_start=615
44
+ _globals['_LISTRUNSREQUEST']._serialized_end=664
45
+ _globals['_LISTRUNSRESPONSE']._serialized_start=667
46
+ _globals['_LISTRUNSRESPONSE']._serialized_end=824
47
+ _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_start=761
48
+ _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_end=824
49
+ _globals['_GETLOGINDETAILSREQUEST']._serialized_start=826
50
+ _globals['_GETLOGINDETAILSREQUEST']._serialized_end=850
51
+ _globals['_GETLOGINDETAILSRESPONSE']._serialized_start=853
52
+ _globals['_GETLOGINDETAILSRESPONSE']._serialized_end=992
53
+ _globals['_GETAUTHTOKENSREQUEST']._serialized_start=994
54
+ _globals['_GETAUTHTOKENSREQUEST']._serialized_end=1037
55
+ _globals['_GETAUTHTOKENSRESPONSE']._serialized_start=1039
56
+ _globals['_GETAUTHTOKENSRESPONSE']._serialized_end=1107
57
+ _globals['_STOPRUNREQUEST']._serialized_start=1109
58
+ _globals['_STOPRUNREQUEST']._serialized_end=1141
59
+ _globals['_STOPRUNRESPONSE']._serialized_start=1143
60
+ _globals['_STOPRUNRESPONSE']._serialized_end=1177
61
+ _globals['_PULLARTIFACTSREQUEST']._serialized_start=1179
62
+ _globals['_PULLARTIFACTSREQUEST']._serialized_end=1217
63
+ _globals['_PULLARTIFACTSRESPONSE']._serialized_start=1219
64
+ _globals['_PULLARTIFACTSRESPONSE']._serialized_end=1268
65
+ _globals['_REGISTERNODEREQUEST']._serialized_start=1270
66
+ _globals['_REGISTERNODEREQUEST']._serialized_end=1311
67
+ _globals['_REGISTERNODERESPONSE']._serialized_start=1313
68
+ _globals['_REGISTERNODERESPONSE']._serialized_end=1369
69
+ _globals['_UNREGISTERNODEREQUEST']._serialized_start=1371
70
+ _globals['_UNREGISTERNODEREQUEST']._serialized_end=1411
71
+ _globals['_UNREGISTERNODERESPONSE']._serialized_start=1413
72
+ _globals['_UNREGISTERNODERESPONSE']._serialized_end=1437
73
+ _globals['_LISTNODESREQUEST']._serialized_start=1439
74
+ _globals['_LISTNODESREQUEST']._serialized_end=1457
75
+ _globals['_LISTNODESRESPONSE']._serialized_start=1459
76
+ _globals['_LISTNODESRESPONSE']._serialized_end=1533
77
+ _globals['_CONTROL']._serialized_start=1536
78
+ _globals['_CONTROL']._serialized_end=2364
79
79
  # @@protoc_insertion_point(module_scope)
@@ -36,20 +36,23 @@ class StartRunRequest(google.protobuf.message.Message):
36
36
  FAB_FIELD_NUMBER: builtins.int
37
37
  OVERRIDE_CONFIG_FIELD_NUMBER: builtins.int
38
38
  FEDERATION_OPTIONS_FIELD_NUMBER: builtins.int
39
+ APP_ID_FIELD_NUMBER: builtins.int
39
40
  @property
40
41
  def fab(self) -> flwr.proto.fab_pb2.Fab: ...
41
42
  @property
42
43
  def override_config(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, flwr.proto.transport_pb2.Scalar]: ...
43
44
  @property
44
45
  def federation_options(self) -> flwr.proto.recorddict_pb2.ConfigRecord: ...
46
+ app_id: typing.Text
45
47
  def __init__(self,
46
48
  *,
47
49
  fab: typing.Optional[flwr.proto.fab_pb2.Fab] = ...,
48
50
  override_config: typing.Optional[typing.Mapping[typing.Text, flwr.proto.transport_pb2.Scalar]] = ...,
49
51
  federation_options: typing.Optional[flwr.proto.recorddict_pb2.ConfigRecord] = ...,
52
+ app_id: typing.Text = ...,
50
53
  ) -> None: ...
51
54
  def HasField(self, field_name: typing_extensions.Literal["fab",b"fab","federation_options",b"federation_options"]) -> builtins.bool: ...
52
- def ClearField(self, field_name: typing_extensions.Literal["fab",b"fab","federation_options",b"federation_options","override_config",b"override_config"]) -> None: ...
55
+ def ClearField(self, field_name: typing_extensions.Literal["app_id",b"app_id","fab",b"fab","federation_options",b"federation_options","override_config",b"override_config"]) -> None: ...
53
56
  global___StartRunRequest = StartRunRequest
54
57
 
55
58
  class StartRunResponse(google.protobuf.message.Message):
flwr/proto/fab_pb2.py CHANGED
@@ -15,17 +15,21 @@ _sym_db = _symbol_database.Default()
15
15
  from flwr.proto import node_pb2 as flwr_dot_proto_dot_node__pb2
16
16
 
17
17
 
18
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/fab.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\"(\n\x03\x46\x61\x62\x12\x10\n\x08hash_str\x18\x01 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x02 \x01(\x0c\"Q\n\rGetFabRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x10\n\x08hash_str\x18\x02 \x01(\t\x12\x0e\n\x06run_id\x18\x03 \x01(\x04\".\n\x0eGetFabResponse\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fabb\x06proto3')
18
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/fab.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\"\x99\x01\n\x03\x46\x61\x62\x12\x10\n\x08hash_str\x18\x01 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x02 \x01(\x0c\x12\x39\n\rverifications\x18\x03 \x03(\x0b\x32\".flwr.proto.Fab.VerificationsEntry\x1a\x34\n\x12VerificationsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"Q\n\rGetFabRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x10\n\x08hash_str\x18\x02 \x01(\t\x12\x0e\n\x06run_id\x18\x03 \x01(\x04\".\n\x0eGetFabResponse\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fabb\x06proto3')
19
19
 
20
20
  _globals = globals()
21
21
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
22
22
  _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.fab_pb2', _globals)
23
23
  if _descriptor._USE_C_DESCRIPTORS == False:
24
24
  DESCRIPTOR._options = None
25
- _globals['_FAB']._serialized_start=59
26
- _globals['_FAB']._serialized_end=99
27
- _globals['_GETFABREQUEST']._serialized_start=101
28
- _globals['_GETFABREQUEST']._serialized_end=182
29
- _globals['_GETFABRESPONSE']._serialized_start=184
30
- _globals['_GETFABRESPONSE']._serialized_end=230
25
+ _globals['_FAB_VERIFICATIONSENTRY']._options = None
26
+ _globals['_FAB_VERIFICATIONSENTRY']._serialized_options = b'8\001'
27
+ _globals['_FAB']._serialized_start=60
28
+ _globals['_FAB']._serialized_end=213
29
+ _globals['_FAB_VERIFICATIONSENTRY']._serialized_start=161
30
+ _globals['_FAB_VERIFICATIONSENTRY']._serialized_end=213
31
+ _globals['_GETFABREQUEST']._serialized_start=215
32
+ _globals['_GETFABREQUEST']._serialized_end=296
33
+ _globals['_GETFABRESPONSE']._serialized_start=298
34
+ _globals['_GETFABRESPONSE']._serialized_end=344
31
35
  # @@protoc_insertion_point(module_scope)
flwr/proto/fab_pb2.pyi CHANGED
@@ -5,6 +5,7 @@ isort:skip_file
5
5
  import builtins
6
6
  import flwr.proto.node_pb2
7
7
  import google.protobuf.descriptor
8
+ import google.protobuf.internal.containers
8
9
  import google.protobuf.message
9
10
  import typing
10
11
  import typing_extensions
@@ -13,8 +14,22 @@ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
13
14
 
14
15
  class Fab(google.protobuf.message.Message):
15
16
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
17
+ class VerificationsEntry(google.protobuf.message.Message):
18
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
19
+ KEY_FIELD_NUMBER: builtins.int
20
+ VALUE_FIELD_NUMBER: builtins.int
21
+ key: typing.Text
22
+ value: typing.Text
23
+ def __init__(self,
24
+ *,
25
+ key: typing.Text = ...,
26
+ value: typing.Text = ...,
27
+ ) -> None: ...
28
+ def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ...
29
+
16
30
  HASH_STR_FIELD_NUMBER: builtins.int
17
31
  CONTENT_FIELD_NUMBER: builtins.int
32
+ VERIFICATIONS_FIELD_NUMBER: builtins.int
18
33
  hash_str: typing.Text
19
34
  """This field is the hash of the data field. It is used to identify the data.
20
35
  The hash is calculated using the SHA-256 algorithm and is represented as a
@@ -24,12 +39,17 @@ class Fab(google.protobuf.message.Message):
24
39
  content: builtins.bytes
25
40
  """This field contains the fab file contents a one bytes blob."""
26
41
 
42
+ @property
43
+ def verifications(self) -> google.protobuf.internal.containers.ScalarMap[typing.Text, typing.Text]:
44
+ """Verifications."""
45
+ pass
27
46
  def __init__(self,
28
47
  *,
29
48
  hash_str: typing.Text = ...,
30
49
  content: builtins.bytes = ...,
50
+ verifications: typing.Optional[typing.Mapping[typing.Text, typing.Text]] = ...,
31
51
  ) -> None: ...
32
- def ClearField(self, field_name: typing_extensions.Literal["content",b"content","hash_str",b"hash_str"]) -> None: ...
52
+ def ClearField(self, field_name: typing_extensions.Literal["content",b"content","hash_str",b"hash_str","verifications",b"verifications"]) -> None: ...
33
53
  global___Fab = Fab
34
54
 
35
55
  class GetFabRequest(google.protobuf.message.Message):
@@ -130,11 +130,13 @@ class FleetServicer(fleet_pb2_grpc.FleetServicer):
130
130
  request=request,
131
131
  state=state,
132
132
  )
133
+ log(
134
+ INFO, "[Fleet.CreateNode] Created node_id=%s", response.node.node_id
135
+ )
133
136
 
134
137
  except ValueError as e:
135
138
  # Public key already in use
136
139
  context.abort(grpc.StatusCode.FAILED_PRECONDITION, str(e))
137
- log(INFO, "[Fleet.CreateNode] Created node_id=%s", response.node.node_id)
138
140
  log(DEBUG, "[Fleet.CreateNode] Response: %s", MessageToDict(response))
139
141
  return response
140
142
 
@@ -210,7 +210,7 @@ def get_fab(
210
210
  raise InvalidRunStatusException(abort_msg)
211
211
 
212
212
  if result := ffs.get(request.hash_str):
213
- fab = Fab(request.hash_str, result[0])
213
+ fab = Fab(request.hash_str, result[0], result[1])
214
214
  return GetFabResponse(fab=fab_to_proto(fab))
215
215
 
216
216
  raise ValueError(f"Found no FAB with hash: {request.hash_str}")
@@ -316,7 +316,7 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
316
316
 
317
317
  ffs: Ffs = self.ffs_factory.ffs()
318
318
  if result := ffs.get(request.hash_str):
319
- fab = Fab(request.hash_str, result[0])
319
+ fab = Fab(request.hash_str, result[0], result[1])
320
320
  return GetFabResponse(fab=fab_to_proto(fab))
321
321
 
322
322
  raise ValueError(f"Found no FAB with hash: {request.hash_str}")
@@ -343,7 +343,7 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
343
343
  fab = None
344
344
  if run and run.fab_hash:
345
345
  if result := ffs.get(run.fab_hash):
346
- fab = Fab(run.fab_hash, result[0])
346
+ fab = Fab(run.fab_hash, result[0], result[1])
347
347
  if run and fab and serverapp_ctxt:
348
348
  # Update run status to STARTING
349
349
  if state.update_run_status(run_id, RunStatus(Status.STARTING, "", "")):
@@ -150,7 +150,7 @@ class SimulationIoServicer(simulationio_pb2_grpc.SimulationIoServicer):
150
150
  fab = None
151
151
  if run and run.fab_hash:
152
152
  if result := ffs.get(run.fab_hash):
153
- fab = Fab(run.fab_hash, result[0])
153
+ fab = Fab(run.fab_hash, result[0], result[1])
154
154
  if run and fab and serverapp_ctxt:
155
155
  # Update run status to STARTING
156
156
  if state.update_run_status(run_id, RunStatus(Status.STARTING, "", "")):
@@ -0,0 +1,165 @@
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
+ """Ed25519-only asymmetric cryptography utilities."""
16
+
17
+ import base64
18
+
19
+ from cryptography.exceptions import InvalidSignature
20
+ from cryptography.hazmat.primitives import serialization
21
+ from cryptography.hazmat.primitives.asymmetric import ed25519
22
+
23
+
24
+ def generate_key_pair() -> tuple[ed25519.Ed25519PrivateKey, ed25519.Ed25519PublicKey]:
25
+ """Generate an Ed25519 private/public key pair.
26
+
27
+ Returns
28
+ -------
29
+ Tuple[Ed25519PrivateKey, Ed25519PublicKey]
30
+ Private and public key pair.
31
+ """
32
+ private_key = ed25519.Ed25519PrivateKey.generate()
33
+ return private_key, private_key.public_key()
34
+
35
+
36
+ def private_key_to_bytes(private_key: ed25519.Ed25519PrivateKey) -> bytes:
37
+ """Serialize an Ed25519 private key to PEM bytes.
38
+
39
+ Parameters
40
+ ----------
41
+ private_key : Ed25519PrivateKey
42
+ The private key to serialize.
43
+
44
+ Returns
45
+ -------
46
+ bytes
47
+ PEM-encoded private key.
48
+ """
49
+ return private_key.private_bytes(
50
+ encoding=serialization.Encoding.PEM,
51
+ format=serialization.PrivateFormat.PKCS8,
52
+ encryption_algorithm=serialization.NoEncryption(),
53
+ )
54
+
55
+
56
+ def bytes_to_private_key(private_key_bytes: bytes) -> ed25519.Ed25519PrivateKey:
57
+ """Deserialize an Ed25519 private key from PEM bytes.
58
+
59
+ Parameters
60
+ ----------
61
+ private_key_bytes : bytes
62
+ PEM-encoded private key.
63
+
64
+ Returns
65
+ -------
66
+ Ed25519PrivateKey
67
+ Deserialized private key.
68
+ """
69
+ return serialization.load_pem_private_key(
70
+ private_key_bytes, password=None
71
+ ) # type: ignore[return-value]
72
+
73
+
74
+ def public_key_to_bytes(public_key: ed25519.Ed25519PublicKey) -> bytes:
75
+ """Serialize an Ed25519 public key to PEM bytes.
76
+
77
+ Parameters
78
+ ----------
79
+ public_key : Ed25519PublicKey
80
+ The public key to serialize.
81
+
82
+ Returns
83
+ -------
84
+ bytes
85
+ PEM-encoded public key.
86
+ """
87
+ return public_key.public_bytes(
88
+ encoding=serialization.Encoding.PEM,
89
+ format=serialization.PublicFormat.SubjectPublicKeyInfo,
90
+ )
91
+
92
+
93
+ def bytes_to_public_key(public_key_bytes: bytes) -> ed25519.Ed25519PublicKey:
94
+ """Deserialize an Ed25519 public key from PEM bytes.
95
+
96
+ Parameters
97
+ ----------
98
+ public_key_bytes : bytes
99
+ PEM-encoded public key.
100
+
101
+ Returns
102
+ -------
103
+ Ed25519PublicKey
104
+ Deserialized public key.
105
+ """
106
+ return serialization.load_pem_public_key(public_key_bytes) # type: ignore[return-value]
107
+
108
+
109
+ def sign_message(private_key: ed25519.Ed25519PrivateKey, message: bytes) -> bytes:
110
+ """Sign a message using an Ed25519 private key.
111
+
112
+ Parameters
113
+ ----------
114
+ private_key : Ed25519PrivateKey
115
+ The private key used for signing.
116
+ message : bytes
117
+ The message to sign.
118
+
119
+ Returns
120
+ -------
121
+ bytes
122
+ The signature of the message.
123
+ """
124
+ return private_key.sign(message)
125
+
126
+
127
+ def verify_signature(
128
+ public_key: ed25519.Ed25519PublicKey, message: bytes, signature: bytes
129
+ ) -> bool:
130
+ """Verify a signature using an Ed25519 public key.
131
+
132
+ Parameters
133
+ ----------
134
+ public_key : Ed25519PublicKey
135
+ The public key used for verification.
136
+ message : bytes
137
+ The original message.
138
+ signature : bytes
139
+ The signature to verify.
140
+
141
+ Returns
142
+ -------
143
+ bool
144
+ True if the signature is valid, False otherwise.
145
+ """
146
+ try:
147
+ public_key.verify(signature, message)
148
+ return True
149
+ except InvalidSignature:
150
+ return False
151
+
152
+
153
+ def create_signed_message(fab_digest: bytes, timestamp: int) -> bytes:
154
+ """Create a canonical message:
155
+ timestamp (8 bytes big-endian) + fab_digest.
156
+ """
157
+ timestamp_bytes = timestamp.to_bytes(8, byteorder="big")
158
+ return timestamp_bytes + fab_digest
159
+
160
+
161
+ def decode_base64url(sig: str) -> bytes:
162
+ """Convert signature to b64 format."""
163
+ # add missing padding (=) to a multiple of 4
164
+ pad = (-len(sig)) % 4
165
+ return base64.urlsafe_b64decode(sig + ("=" * pad))
@@ -129,7 +129,11 @@ class ControlServicer(control_pb2_grpc.ControlServicer):
129
129
  )
130
130
 
131
131
  # Create run
132
- fab = Fab(hashlib.sha256(fab_file).hexdigest(), fab_file)
132
+ fab = Fab(
133
+ hashlib.sha256(fab_file).hexdigest(),
134
+ fab_file,
135
+ dict(request.fab.verifications),
136
+ )
133
137
  fab_hash = ffs.put(fab.content, {})
134
138
  if fab_hash != fab.hash_str:
135
139
  raise RuntimeError(
@@ -459,7 +463,7 @@ class ControlServicer(control_pb2_grpc.ControlServicer):
459
463
  log(ERROR, "ListNodes is not available in simulation mode.")
460
464
  context.abort(
461
465
  grpc.StatusCode.UNIMPLEMENTED,
462
- "ListNodesis not available in simulation mode.",
466
+ "ListNodes is not available in simulation mode.",
463
467
  )
464
468
  raise grpc.RpcError() # This line is unreachable
465
469
 
@@ -151,7 +151,7 @@ class ClientAppIoServicer(clientappio_pb2_grpc.ClientAppIoServicer):
151
151
  # Retrieve context, run and fab for this run
152
152
  context = cast(Context, state.get_context(run_id))
153
153
  run = cast(Run, state.get_run(run_id))
154
- fab = Fab(run.fab_hash, ffs.get(run.fab_hash)[0]) # type: ignore
154
+ fab = Fab(run.fab_hash, ffs.get(run.fab_hash)[0], ffs.get(run.fab_hash)[1]) # type: ignore
155
155
 
156
156
  return PullAppInputsResponse(
157
157
  context=context_to_proto(context),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: flwr-nightly
3
- Version: 1.23.0.dev20251023
3
+ Version: 1.23.0.dev20251027
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
@@ -84,7 +84,7 @@ flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=g7SYiAJr6Uhwg4Zs
84
84
  flwr/cli/new/templates/app/pyproject.xgboost.toml.tpl,sha256=yAJ9jL2q6U_XXYwwUT9fpIqIKFuQR_Kgg82GpWfQ5J8,1661
85
85
  flwr/cli/pull.py,sha256=sT3-f2zf7JcXfB-pHWLXmENrOzJeUDBoqK3oruJxzao,3352
86
86
  flwr/cli/run/__init__.py,sha256=RPyB7KbYTFl6YRiilCch6oezxrLQrl1kijV7BMGkLbA,790
87
- flwr/cli/run/run.py,sha256=ED1mDmO1PnSAgtVOrCeWwzwPm6t3aFYSs3Rh36BJzqk,8161
87
+ flwr/cli/run/run.py,sha256=f5ysmBytcme8E7feroCtvpLe3kEebSFV42dcqoSFzzY,8165
88
88
  flwr/cli/stop.py,sha256=W7ynTYLm0-_1nC5Il4IaZTji6A3GCCm_0R-HQUudAsI,4988
89
89
  flwr/cli/supernode/__init__.py,sha256=DBkjoPo2hS2Y-ghJxwLbrAbCQFBgD82_Itl2_892UBo,917
90
90
  flwr/cli/supernode/ls.py,sha256=OVEs9zPSomxxiwCg1Jz8AN5MkZJDf3xAE-lxCG22zyE,8640
@@ -97,7 +97,7 @@ flwr/client/dpfedavg_numpy_client.py,sha256=3hul067cT2E9jBhzp7bFnFAZ_D2nWcIUEdHY
97
97
  flwr/client/grpc_adapter_client/__init__.py,sha256=RQWP5mFPROLHKgombiRvPXVWSoVrQ81wvZm0-lOuuBA,742
98
98
  flwr/client/grpc_adapter_client/connection.py,sha256=JGv02EjSOAG1E5BRUD4lwXc1LLiYJ0OhInvp31qx1cU,4404
99
99
  flwr/client/grpc_rere_client/__init__.py,sha256=i7iS0Lt8B7q0E2L72e4F_YrKm6ClRKnd71PNA6PW2O0,752
100
- flwr/client/grpc_rere_client/connection.py,sha256=SaBuUcqF6r6ieT1sv0Tg5Isqmpeb8D184R0ayLvCScQ,13091
100
+ flwr/client/grpc_rere_client/connection.py,sha256=3_CI7wx5ZrkGrVCXjDKiUGX9aJP9Zm9yl4iqSBAmH3U,13100
101
101
  flwr/client/grpc_rere_client/grpc_adapter.py,sha256=dLGB5GriszAmtgvuFGuz_F7rIwpzLfDxhJ7T3Un-Ce0,6694
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
@@ -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=y7fhRoMsgHNKfMGHX1IE_uKgseEuD1eR4MgEmw3aXwE,15971
115
+ flwr/client/rest_client/connection.py,sha256=uqcCT6lLgtzb_T2-u6iB60-fVaTz9uE7fy5uvLikQ_I,15962
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
@@ -168,10 +168,10 @@ flwr/common/secure_aggregation/ndarrays_arithmetic.py,sha256=TrggOlizlny3V2KS7-3
168
168
  flwr/common/secure_aggregation/quantization.py,sha256=ssFZpiRyj9ltIh0Ai3vGkDqWFO4SoqgoD1mDU9XqMEM,2400
169
169
  flwr/common/secure_aggregation/secaggplus_constants.py,sha256=dGYhWOBMMDJcQH4_tQNC8-Efqm-ecEUNN9ANz59UnCk,2182
170
170
  flwr/common/secure_aggregation/secaggplus_utils.py,sha256=E_xU-Zd45daO1em7M6C2wOjFXVtJf-6tl7fp-7xq1wo,3214
171
- flwr/common/serde.py,sha256=dx66gumR1BpwK45qDwvDLd_05VoKfzkUzWZ7zuZi1-0,21960
171
+ flwr/common/serde.py,sha256=WdEMQzZ3G3mBh8aAYNNQ8oKSahn9UaHtCwE-qt97EmE,22032
172
172
  flwr/common/serde_utils.py,sha256=krx2C_W31KpfmDqnDCtULoTkT8WKweWTJ7FHYWtF1r4,5815
173
173
  flwr/common/telemetry.py,sha256=xfx3KLFQKy0Qx8P7MAsOQxr5J3sEAQF5Kr5J-4jPz-o,8859
174
- flwr/common/typing.py,sha256=MwHVRa1oPzUCbaz32MZKUIeou-4UuNXrMqZnrQzLNoY,6952
174
+ flwr/common/typing.py,sha256=7tec-6Wa6ygwJl-NkXKgb3QehU9AvYn-IzNrGffli74,6986
175
175
  flwr/common/version.py,sha256=7GAGzPn73Mkh09qhrjbmjZQtcqVhBuzhFBaK4Mk4VRk,1325
176
176
  flwr/compat/__init__.py,sha256=gbfDQKKKMZzi3GswyVRgyLdDlHiWj3wU6dg7y6m5O_s,752
177
177
  flwr/compat/client/__init__.py,sha256=qpbo0lcxdNL4qy5KHqiGm8OLxSxkYgI_-dLh5rwhtcI,746
@@ -191,16 +191,16 @@ flwr/proto/clientappio_pb2.py,sha256=vJjzwWydhg7LruK8cvRAeVQeHPsJztgdIW9nyiPBZF0
191
191
  flwr/proto/clientappio_pb2.pyi,sha256=XbFvpZvvrS7QcH5AFXfpRGl4hQvhd3QdKO6x0oTlCCU,165
192
192
  flwr/proto/clientappio_pb2_grpc.py,sha256=iobNROP0qvn5zddx7k-uIi_dJWP3T_BRp_kbKq086i8,17550
193
193
  flwr/proto/clientappio_pb2_grpc.pyi,sha256=Ytf1O1ktKB0Vsuc3AWLIErGjIJYokzKYzi2uA7mdMeg,4785
194
- flwr/proto/control_pb2.py,sha256=_FqVaMs-LP6eYJ3eDARnbfsq_q66sewTclDskBMOb3c,7707
195
- flwr/proto/control_pb2.pyi,sha256=0vlxyu7uYVtIhqFcjHCDeWPdtuQCCzBRyAEU5VYeaxI,13368
194
+ flwr/proto/control_pb2.py,sha256=2qpywkFGFCkCyjAx9QF4w6VX5UeV7Oe6e82vjmK7e_k,7746
195
+ flwr/proto/control_pb2.pyi,sha256=NyYUnJh-rhP_NBZMhwauV4va2lwI-J6KQWamY8QiYm8,13484
196
196
  flwr/proto/control_pb2_grpc.py,sha256=wLjMi8GNQ5VR7IbNdDbHC0A1QMzA_0CegBzaOO1dlo0,17152
197
197
  flwr/proto/control_pb2_grpc.pyi,sha256=L1HGnIXWu0Q7WQ1ONWffaQ69jHtWQ6cyEUcxINL8_Uc,4801
198
198
  flwr/proto/error_pb2.py,sha256=PQVWrfjVPo88ql_KgV9nCxyQNCcV9PVfmcw7sOzTMro,1084
199
199
  flwr/proto/error_pb2.pyi,sha256=ZNH4HhJTU_KfMXlyCeg8FwU-fcUYxTqEmoJPtWtHikc,734
200
200
  flwr/proto/error_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
201
201
  flwr/proto/error_pb2_grpc.pyi,sha256=ff2TSiLVnG6IVQcTGzb2DIH3XRSoAvAo_RMcvbMFyc0,76
202
- flwr/proto/fab_pb2.py,sha256=2Nu0WaWxDZ8TbutMtctjdcGM7OtXiyP4kmCgg5o7Jjw,1627
203
- flwr/proto/fab_pb2.pyi,sha256=AMXpiDK0fo3nZWjxsC2E4otSaVjyQbU7iiWKrsSZavs,2395
202
+ flwr/proto/fab_pb2.py,sha256=AQAUJmTt31Kq-lJQid3CJpQPrply2-OA_aSHokpVF84,2070
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
206
  flwr/proto/fleet_pb2.py,sha256=xGnNGmBbPds6LeB34HN8_vy4U1oW25-w-r-C6xNpoRo,5190
@@ -305,10 +305,10 @@ 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=Fh28q-M42m83fhLyXRkkfdKg9A8E0cxUkciVNGkPov0,11626
308
+ flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py,sha256=V9CMyaYVc1t5Wt_63H5zcMbs8iC8HD-V31TXLlCPts4,11672
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=ijK-zji1AKkOvJLLIzC2mYQlEh50lI1qPW8QpysNsKk,8751
311
+ flwr/server/superlink/fleet/message_handler/message_handler.py,sha256=GYveEXgKRlyrKRUr2H6kjWPx_g4-fnATrMdJD2G4Gaw,8762
312
312
  flwr/server/superlink/fleet/rest_rere/__init__.py,sha256=Lzc93nA7tDqoy-zRUaPG316oqFiZX1HUCL5ELaXY_xw,735
313
313
  flwr/server/superlink/fleet/rest_rere/rest_api.py,sha256=mxWKwGpgHPqd7cGFqd2ASnR-KZduIzLfT-d2yiNCqQ0,9257
314
314
  flwr/server/superlink/fleet/vce/__init__.py,sha256=XOKbAWOzlCqEOQ3M2cBYkH7HKA7PxlbCJMunt-ty-DY,784
@@ -324,10 +324,10 @@ flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=vmD74L8fphb0xIhArQUg1
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
327
- flwr/server/superlink/serverappio/serverappio_servicer.py,sha256=3C_0boRbYuY1Vlf0DRGzBvTUX-D5UUzxYkFihSMZf-A,20094
327
+ flwr/server/superlink/serverappio/serverappio_servicer.py,sha256=3N1_7wKFzif1e3mBZuzzdORPaaN9Y5F-JrpS7mI3bSM,20116
328
328
  flwr/server/superlink/simulation/__init__.py,sha256=Ry8DrNaZCMcQXvUc4FoCN2m3dvUQgWjasfp015o3Ec4,718
329
329
  flwr/server/superlink/simulation/simulationio_grpc.py,sha256=VqWKxjpd4bCgPFKsgtIZPk9YcG0kc1EEmr5k20EKty4,2205
330
- flwr/server/superlink/simulation/simulationio_servicer.py,sha256=aZp67AeNCGs1zI4mvj_WUOL8noxNcsYu_QIpYKhnHXg,9992
330
+ flwr/server/superlink/simulation/simulationio_servicer.py,sha256=xX-QnSvAL3kp4JKnUKmDSPnR9iD1eDtJL4JfsZx2ua8,10003
331
331
  flwr/server/superlink/utils.py,sha256=zXmyU2o535b9dgz-TvFklzfuQk4irNnMtiK8vT4Dm1c,2454
332
332
  flwr/server/typing.py,sha256=LvO6gq7H6TAWhA9JFx0WyqHxU7FycyvhSsLjBLPgpts,1011
333
333
  flwr/server/utils/__init__.py,sha256=U4gM84-uUFddarODDQkO6SjNUuGhFcsHJZMjSEbezkU,884
@@ -395,6 +395,7 @@ flwr/supercore/object_store/sqlite_object_store.py,sha256=cL0e2I6PkLhWTpXiKFbT7G
395
395
  flwr/supercore/object_store/utils.py,sha256=DcPbrb9PenloAPoQRiKiXX9DrDfpXcSyY0cZpgn4PeQ,1680
396
396
  flwr/supercore/primitives/__init__.py,sha256=Tx8GOjnmMo8Y74RsDGrMpfr-E0Nl8dcUDF784_ge6F8,745
397
397
  flwr/supercore/primitives/asymmetric.py,sha256=wpO0o0G_vStRknFitw2SqyIBSzaBfuXfMc44u-UcxTs,3774
398
+ flwr/supercore/primitives/asymmetric_ed25519.py,sha256=R8ua4NXknm6-2GyR3E4lF_uHexWhtsYi7EIKbzapOVc,4609
398
399
  flwr/supercore/sqlite_mixin.py,sha256=_oVI4cXZ1cV42RtaBJ2gzT2HvMwwsW-e8jBAgrzpWNo,5072
399
400
  flwr/supercore/superexec/__init__.py,sha256=XKX208hZ6a9gZ4KT9kMqfpCtp_8VGxekzKFfHSu2esQ,707
400
401
  flwr/supercore/superexec/plugin/__init__.py,sha256=GNwq8uNdE8RB7ywEFRAvKjLFzgS3YXgz39-HBGsemWw,1035
@@ -417,7 +418,7 @@ flwr/superlink/servicer/control/control_account_auth_interceptor.py,sha256=Tbi4W
417
418
  flwr/superlink/servicer/control/control_event_log_interceptor.py,sha256=5uBl6VcJlUOgCF0d4kmsmJc1Rs1qxyouaZv0-uH2axs,5969
418
419
  flwr/superlink/servicer/control/control_grpc.py,sha256=MRCaX4I2a5ogjKmhtFs6Mj-VdWemxL2h3gU9QbQmvCA,4183
419
420
  flwr/superlink/servicer/control/control_license_interceptor.py,sha256=T3AzmRt-PPwyTq3hrdpmZHQd5_CpPOk7TtnFZrB-JRY,3349
420
- flwr/superlink/servicer/control/control_servicer.py,sha256=52SHq8yPCDjO92jFm9bg_QMjZJ_-kDC0brn7uJAOwnw,19357
421
+ flwr/superlink/servicer/control/control_servicer.py,sha256=93-lZ2pSjbpod-zhu_5ZSOK2ZZVTiBT-0mzl53pFlLw,19454
421
422
  flwr/supernode/__init__.py,sha256=KgeCaVvXWrU3rptNR1y0oBp4YtXbAcrnCcJAiOoWkI4,707
422
423
  flwr/supernode/cli/__init__.py,sha256=JuEMr0-s9zv-PEWKuLB9tj1ocNfroSyNJ-oyv7ati9A,887
423
424
  flwr/supernode/cli/flower_supernode.py,sha256=bmPpg88Zq7NYMDzyyDwBzeZ6_1f26fD_iDdGw1o_4QQ,8334
@@ -430,9 +431,9 @@ flwr/supernode/runtime/__init__.py,sha256=JQdqd2EMTn-ORMeTvewYYh52ls0YKP68jrps1q
430
431
  flwr/supernode/runtime/run_clientapp.py,sha256=BuaAKTzRuFmNX-IJky3kJzoWMmZkz9joHodbz_wmgpA,8771
431
432
  flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca8gxdEo,717
432
433
  flwr/supernode/servicer/clientappio/__init__.py,sha256=7Oy62Y_oijqF7Dxi6tpcUQyOpLc_QpIRZ83NvwmB0Yg,813
433
- flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=nIHRu38EWK-rpNOkcgBRAAKwYQQWFeCwu0lkO7OPZGQ,10239
434
+ flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=ZvKosLV7GN1_fOF-tOmhqFQysYQywCysRc-m23DVIWA,10265
434
435
  flwr/supernode/start_client_internal.py,sha256=wKqh9-_rQYi7JFKpYBLRiUeq9YJUSyUd9b-SnVnuvwI,21567
435
- flwr_nightly-1.23.0.dev20251023.dist-info/METADATA,sha256=K1z9M80b9eL9FsHZ6wAiqXmsLVpCKXNo49s5nC8EgS8,14559
436
- flwr_nightly-1.23.0.dev20251023.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
437
- flwr_nightly-1.23.0.dev20251023.dist-info/entry_points.txt,sha256=hxHD2ixb_vJFDOlZV-zB4Ao32_BQlL34ftsDh1GXv14,420
438
- flwr_nightly-1.23.0.dev20251023.dist-info/RECORD,,
436
+ flwr_nightly-1.23.0.dev20251027.dist-info/METADATA,sha256=PvUk4HrZo9-Ztc5hxec-ihDiAaIq8QFxdrZkid0eNe4,14559
437
+ flwr_nightly-1.23.0.dev20251027.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
438
+ flwr_nightly-1.23.0.dev20251027.dist-info/entry_points.txt,sha256=hxHD2ixb_vJFDOlZV-zB4Ao32_BQlL34ftsDh1GXv14,420
439
+ flwr_nightly-1.23.0.dev20251027.dist-info/RECORD,,