flwr-nightly 1.23.0.dev20251024__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/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):
@@ -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
 
@@ -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))
@@ -463,7 +463,7 @@ class ControlServicer(control_pb2_grpc.ControlServicer):
463
463
  log(ERROR, "ListNodes is not available in simulation mode.")
464
464
  context.abort(
465
465
  grpc.StatusCode.UNIMPLEMENTED,
466
- "ListNodesis not available in simulation mode.",
466
+ "ListNodes is not available in simulation mode.",
467
467
  )
468
468
  raise grpc.RpcError() # This line is unreachable
469
469
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: flwr-nightly
3
- Version: 1.23.0.dev20251024
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
@@ -191,8 +191,8 @@ 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
@@ -305,7 +305,7 @@ 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
311
  flwr/server/superlink/fleet/message_handler/message_handler.py,sha256=GYveEXgKRlyrKRUr2H6kjWPx_g4-fnATrMdJD2G4Gaw,8762
@@ -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=hXKtSKSuhVvgDCPl-n-9OM7MsEz2QhrpKRgJvFTwvL8,19453
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
@@ -432,7 +433,7 @@ flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca
432
433
  flwr/supernode/servicer/clientappio/__init__.py,sha256=7Oy62Y_oijqF7Dxi6tpcUQyOpLc_QpIRZ83NvwmB0Yg,813
433
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.dev20251024.dist-info/METADATA,sha256=aB-IhivK00L-rHkCDzB6ydELRWF9z3kGkwWmthzgoVw,14559
436
- flwr_nightly-1.23.0.dev20251024.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
437
- flwr_nightly-1.23.0.dev20251024.dist-info/entry_points.txt,sha256=hxHD2ixb_vJFDOlZV-zB4Ao32_BQlL34ftsDh1GXv14,420
438
- flwr_nightly-1.23.0.dev20251024.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,,