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 +46 -46
- flwr/proto/control_pb2.pyi +4 -1
- flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +3 -1
- flwr/supercore/primitives/asymmetric_ed25519.py +165 -0
- flwr/superlink/servicer/control/control_servicer.py +1 -1
- {flwr_nightly-1.23.0.dev20251024.dist-info → flwr_nightly-1.23.0.dev20251027.dist-info}/METADATA +1 -1
- {flwr_nightly-1.23.0.dev20251024.dist-info → flwr_nightly-1.23.0.dev20251027.dist-info}/RECORD +9 -8
- {flwr_nightly-1.23.0.dev20251024.dist-info → flwr_nightly-1.23.0.dev20251027.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.23.0.dev20251024.dist-info → flwr_nightly-1.23.0.dev20251027.dist-info}/entry_points.txt +0 -0
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\"\
|
|
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=
|
|
35
|
-
_globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=
|
|
36
|
-
_globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=
|
|
37
|
-
_globals['_STARTRUNRESPONSE']._serialized_start=
|
|
38
|
-
_globals['_STARTRUNRESPONSE']._serialized_end=
|
|
39
|
-
_globals['_STREAMLOGSREQUEST']._serialized_start=
|
|
40
|
-
_globals['_STREAMLOGSREQUEST']._serialized_end=
|
|
41
|
-
_globals['_STREAMLOGSRESPONSE']._serialized_start=
|
|
42
|
-
_globals['_STREAMLOGSRESPONSE']._serialized_end=
|
|
43
|
-
_globals['_LISTRUNSREQUEST']._serialized_start=
|
|
44
|
-
_globals['_LISTRUNSREQUEST']._serialized_end=
|
|
45
|
-
_globals['_LISTRUNSRESPONSE']._serialized_start=
|
|
46
|
-
_globals['_LISTRUNSRESPONSE']._serialized_end=
|
|
47
|
-
_globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_start=
|
|
48
|
-
_globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_end=
|
|
49
|
-
_globals['_GETLOGINDETAILSREQUEST']._serialized_start=
|
|
50
|
-
_globals['_GETLOGINDETAILSREQUEST']._serialized_end=
|
|
51
|
-
_globals['_GETLOGINDETAILSRESPONSE']._serialized_start=
|
|
52
|
-
_globals['_GETLOGINDETAILSRESPONSE']._serialized_end=
|
|
53
|
-
_globals['_GETAUTHTOKENSREQUEST']._serialized_start=
|
|
54
|
-
_globals['_GETAUTHTOKENSREQUEST']._serialized_end=
|
|
55
|
-
_globals['_GETAUTHTOKENSRESPONSE']._serialized_start=
|
|
56
|
-
_globals['_GETAUTHTOKENSRESPONSE']._serialized_end=
|
|
57
|
-
_globals['_STOPRUNREQUEST']._serialized_start=
|
|
58
|
-
_globals['_STOPRUNREQUEST']._serialized_end=
|
|
59
|
-
_globals['_STOPRUNRESPONSE']._serialized_start=
|
|
60
|
-
_globals['_STOPRUNRESPONSE']._serialized_end=
|
|
61
|
-
_globals['_PULLARTIFACTSREQUEST']._serialized_start=
|
|
62
|
-
_globals['_PULLARTIFACTSREQUEST']._serialized_end=
|
|
63
|
-
_globals['_PULLARTIFACTSRESPONSE']._serialized_start=
|
|
64
|
-
_globals['_PULLARTIFACTSRESPONSE']._serialized_end=
|
|
65
|
-
_globals['_REGISTERNODEREQUEST']._serialized_start=
|
|
66
|
-
_globals['_REGISTERNODEREQUEST']._serialized_end=
|
|
67
|
-
_globals['_REGISTERNODERESPONSE']._serialized_start=
|
|
68
|
-
_globals['_REGISTERNODERESPONSE']._serialized_end=
|
|
69
|
-
_globals['_UNREGISTERNODEREQUEST']._serialized_start=
|
|
70
|
-
_globals['_UNREGISTERNODEREQUEST']._serialized_end=
|
|
71
|
-
_globals['_UNREGISTERNODERESPONSE']._serialized_start=
|
|
72
|
-
_globals['_UNREGISTERNODERESPONSE']._serialized_end=
|
|
73
|
-
_globals['_LISTNODESREQUEST']._serialized_start=
|
|
74
|
-
_globals['_LISTNODESREQUEST']._serialized_end=
|
|
75
|
-
_globals['_LISTNODESRESPONSE']._serialized_start=
|
|
76
|
-
_globals['_LISTNODESRESPONSE']._serialized_end=
|
|
77
|
-
_globals['_CONTROL']._serialized_start=
|
|
78
|
-
_globals['_CONTROL']._serialized_end=
|
|
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)
|
flwr/proto/control_pb2.pyi
CHANGED
|
@@ -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
|
-
"
|
|
466
|
+
"ListNodes is not available in simulation mode.",
|
|
467
467
|
)
|
|
468
468
|
raise grpc.RpcError() # This line is unreachable
|
|
469
469
|
|
{flwr_nightly-1.23.0.dev20251024.dist-info → flwr_nightly-1.23.0.dev20251027.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: flwr-nightly
|
|
3
|
-
Version: 1.23.0.
|
|
3
|
+
Version: 1.23.0.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
|
{flwr_nightly-1.23.0.dev20251024.dist-info → flwr_nightly-1.23.0.dev20251027.dist-info}/RECORD
RENAMED
|
@@ -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=
|
|
195
|
-
flwr/proto/control_pb2.pyi,sha256=
|
|
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=
|
|
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=
|
|
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.
|
|
436
|
-
flwr_nightly-1.23.0.
|
|
437
|
-
flwr_nightly-1.23.0.
|
|
438
|
-
flwr_nightly-1.23.0.
|
|
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,,
|
{flwr_nightly-1.23.0.dev20251024.dist-info → flwr_nightly-1.23.0.dev20251027.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|