flwr-nightly 1.19.0.dev20250515__py3-none-any.whl → 1.19.0.dev20250520__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.
- flwr/app/__init__.py +15 -0
- flwr/app/error.py +68 -0
- flwr/app/metadata.py +223 -0
- flwr/client/app.py +1 -1
- flwr/client/client_app.py +1 -1
- flwr/client/clientapp/app.py +1 -1
- flwr/client/grpc_rere_client/connection.py +2 -1
- flwr/client/rest_client/connection.py +2 -1
- flwr/clientapp/__init__.py +15 -0
- flwr/common/__init__.py +2 -2
- flwr/common/constant.py +1 -1
- flwr/common/inflatable.py +41 -12
- flwr/common/inflatable_grpc_utils.py +97 -0
- flwr/common/message.py +4 -243
- flwr/common/record/array.py +2 -2
- flwr/common/record/arrayrecord.py +1 -1
- flwr/common/record/configrecord.py +2 -2
- flwr/common/record/metricrecord.py +1 -1
- flwr/common/record/recorddict.py +1 -1
- flwr/common/serde.py +4 -1
- flwr/compat/__init__.py +15 -0
- flwr/compat/client/__init__.py +15 -0
- flwr/compat/common/__init__.py +15 -0
- flwr/compat/server/__init__.py +15 -0
- flwr/compat/simulation/__init__.py +15 -0
- flwr/server/superlink/fleet/vce/vce_api.py +1 -1
- flwr/serverapp/__init__.py +15 -0
- flwr/supercore/__init__.py +15 -0
- flwr/superlink/__init__.py +15 -0
- flwr/supernode/__init__.py +15 -0
- {flwr_nightly-1.19.0.dev20250515.dist-info → flwr_nightly-1.19.0.dev20250520.dist-info}/METADATA +1 -1
- {flwr_nightly-1.19.0.dev20250515.dist-info → flwr_nightly-1.19.0.dev20250520.dist-info}/RECORD +34 -20
- {flwr_nightly-1.19.0.dev20250515.dist-info → flwr_nightly-1.19.0.dev20250520.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.19.0.dev20250515.dist-info → flwr_nightly-1.19.0.dev20250520.dist-info}/entry_points.txt +0 -0
flwr/common/message.py
CHANGED
@@ -18,12 +18,14 @@
|
|
18
18
|
from __future__ import annotations
|
19
19
|
|
20
20
|
from logging import WARNING
|
21
|
-
from typing import Any,
|
21
|
+
from typing import Any, cast, overload
|
22
22
|
|
23
23
|
from flwr.common.date import now
|
24
24
|
from flwr.common.logger import warn_deprecated_feature
|
25
25
|
|
26
|
-
from .
|
26
|
+
from ..app.error import Error
|
27
|
+
from ..app.metadata import Metadata
|
28
|
+
from .constant import MESSAGE_TTL_TOLERANCE
|
27
29
|
from .logger import log
|
28
30
|
from .record import RecordDict
|
29
31
|
|
@@ -56,202 +58,6 @@ class MessageInitializationError(TypeError):
|
|
56
58
|
super().__init__(message or MESSAGE_INIT_ERROR_MESSAGE)
|
57
59
|
|
58
60
|
|
59
|
-
class Metadata: # pylint: disable=too-many-instance-attributes
|
60
|
-
"""The class representing metadata associated with the current message.
|
61
|
-
|
62
|
-
Parameters
|
63
|
-
----------
|
64
|
-
run_id : int
|
65
|
-
An identifier for the current run.
|
66
|
-
message_id : str
|
67
|
-
An identifier for the current message.
|
68
|
-
src_node_id : int
|
69
|
-
An identifier for the node sending this message.
|
70
|
-
dst_node_id : int
|
71
|
-
An identifier for the node receiving this message.
|
72
|
-
reply_to_message_id : str
|
73
|
-
An identifier for the message to which this message is a reply.
|
74
|
-
group_id : str
|
75
|
-
An identifier for grouping messages. In some settings,
|
76
|
-
this is used as the FL round.
|
77
|
-
created_at : float
|
78
|
-
Unix timestamp when the message was created.
|
79
|
-
ttl : float
|
80
|
-
Time-to-live for this message in seconds.
|
81
|
-
message_type : str
|
82
|
-
A string that encodes the action to be executed on
|
83
|
-
the receiving end.
|
84
|
-
"""
|
85
|
-
|
86
|
-
def __init__( # pylint: disable=too-many-arguments,too-many-positional-arguments
|
87
|
-
self,
|
88
|
-
run_id: int,
|
89
|
-
message_id: str,
|
90
|
-
src_node_id: int,
|
91
|
-
dst_node_id: int,
|
92
|
-
reply_to_message_id: str,
|
93
|
-
group_id: str,
|
94
|
-
created_at: float,
|
95
|
-
ttl: float,
|
96
|
-
message_type: str,
|
97
|
-
) -> None:
|
98
|
-
var_dict = {
|
99
|
-
"_run_id": run_id,
|
100
|
-
"_message_id": message_id,
|
101
|
-
"_src_node_id": src_node_id,
|
102
|
-
"_dst_node_id": dst_node_id,
|
103
|
-
"_reply_to_message_id": reply_to_message_id,
|
104
|
-
"_group_id": group_id,
|
105
|
-
"_created_at": created_at,
|
106
|
-
"_ttl": ttl,
|
107
|
-
"_message_type": message_type,
|
108
|
-
}
|
109
|
-
self.__dict__.update(var_dict)
|
110
|
-
self.message_type = message_type # Trigger validation
|
111
|
-
|
112
|
-
@property
|
113
|
-
def run_id(self) -> int:
|
114
|
-
"""An identifier for the current run."""
|
115
|
-
return cast(int, self.__dict__["_run_id"])
|
116
|
-
|
117
|
-
@property
|
118
|
-
def message_id(self) -> str:
|
119
|
-
"""An identifier for the current message."""
|
120
|
-
return cast(str, self.__dict__["_message_id"])
|
121
|
-
|
122
|
-
@property
|
123
|
-
def src_node_id(self) -> int:
|
124
|
-
"""An identifier for the node sending this message."""
|
125
|
-
return cast(int, self.__dict__["_src_node_id"])
|
126
|
-
|
127
|
-
@property
|
128
|
-
def reply_to_message_id(self) -> str:
|
129
|
-
"""An identifier for the message to which this message is a reply."""
|
130
|
-
return cast(str, self.__dict__["_reply_to_message_id"])
|
131
|
-
|
132
|
-
@property
|
133
|
-
def dst_node_id(self) -> int:
|
134
|
-
"""An identifier for the node receiving this message."""
|
135
|
-
return cast(int, self.__dict__["_dst_node_id"])
|
136
|
-
|
137
|
-
@dst_node_id.setter
|
138
|
-
def dst_node_id(self, value: int) -> None:
|
139
|
-
"""Set dst_node_id."""
|
140
|
-
self.__dict__["_dst_node_id"] = value
|
141
|
-
|
142
|
-
@property
|
143
|
-
def group_id(self) -> str:
|
144
|
-
"""An identifier for grouping messages."""
|
145
|
-
return cast(str, self.__dict__["_group_id"])
|
146
|
-
|
147
|
-
@group_id.setter
|
148
|
-
def group_id(self, value: str) -> None:
|
149
|
-
"""Set group_id."""
|
150
|
-
self.__dict__["_group_id"] = value
|
151
|
-
|
152
|
-
@property
|
153
|
-
def created_at(self) -> float:
|
154
|
-
"""Unix timestamp when the message was created."""
|
155
|
-
return cast(float, self.__dict__["_created_at"])
|
156
|
-
|
157
|
-
@created_at.setter
|
158
|
-
def created_at(self, value: float) -> None:
|
159
|
-
"""Set creation timestamp of this message."""
|
160
|
-
self.__dict__["_created_at"] = value
|
161
|
-
|
162
|
-
@property
|
163
|
-
def delivered_at(self) -> str:
|
164
|
-
"""Unix timestamp when the message was delivered."""
|
165
|
-
return cast(str, self.__dict__["_delivered_at"])
|
166
|
-
|
167
|
-
@delivered_at.setter
|
168
|
-
def delivered_at(self, value: str) -> None:
|
169
|
-
"""Set delivery timestamp of this message."""
|
170
|
-
self.__dict__["_delivered_at"] = value
|
171
|
-
|
172
|
-
@property
|
173
|
-
def ttl(self) -> float:
|
174
|
-
"""Time-to-live for this message."""
|
175
|
-
return cast(float, self.__dict__["_ttl"])
|
176
|
-
|
177
|
-
@ttl.setter
|
178
|
-
def ttl(self, value: float) -> None:
|
179
|
-
"""Set ttl."""
|
180
|
-
self.__dict__["_ttl"] = value
|
181
|
-
|
182
|
-
@property
|
183
|
-
def message_type(self) -> str:
|
184
|
-
"""A string that encodes the action to be executed on the receiving end."""
|
185
|
-
return cast(str, self.__dict__["_message_type"])
|
186
|
-
|
187
|
-
@message_type.setter
|
188
|
-
def message_type(self, value: str) -> None:
|
189
|
-
"""Set message_type."""
|
190
|
-
# Validate message type
|
191
|
-
if validate_legacy_message_type(value):
|
192
|
-
pass # Backward compatibility for legacy message types
|
193
|
-
elif not validate_message_type(value):
|
194
|
-
raise ValueError(
|
195
|
-
f"Invalid message type: '{value}'. "
|
196
|
-
"Expected format: '<category>' or '<category>.<action>', "
|
197
|
-
"where <category> must be 'train', 'evaluate', or 'query', "
|
198
|
-
"and <action> must be a valid Python identifier."
|
199
|
-
)
|
200
|
-
|
201
|
-
self.__dict__["_message_type"] = value
|
202
|
-
|
203
|
-
def __repr__(self) -> str:
|
204
|
-
"""Return a string representation of this instance."""
|
205
|
-
view = ", ".join([f"{k.lstrip('_')}={v!r}" for k, v in self.__dict__.items()])
|
206
|
-
return f"{self.__class__.__qualname__}({view})"
|
207
|
-
|
208
|
-
def __eq__(self, other: object) -> bool:
|
209
|
-
"""Compare two instances of the class."""
|
210
|
-
if not isinstance(other, self.__class__):
|
211
|
-
raise NotImplementedError
|
212
|
-
return self.__dict__ == other.__dict__
|
213
|
-
|
214
|
-
|
215
|
-
class Error:
|
216
|
-
"""The class storing information about an error that occurred.
|
217
|
-
|
218
|
-
Parameters
|
219
|
-
----------
|
220
|
-
code : int
|
221
|
-
An identifier for the error.
|
222
|
-
reason : Optional[str]
|
223
|
-
A reason for why the error arose (e.g. an exception stack-trace)
|
224
|
-
"""
|
225
|
-
|
226
|
-
def __init__(self, code: int, reason: str | None = None) -> None:
|
227
|
-
var_dict = {
|
228
|
-
"_code": code,
|
229
|
-
"_reason": reason,
|
230
|
-
}
|
231
|
-
self.__dict__.update(var_dict)
|
232
|
-
|
233
|
-
@property
|
234
|
-
def code(self) -> int:
|
235
|
-
"""Error code."""
|
236
|
-
return cast(int, self.__dict__["_code"])
|
237
|
-
|
238
|
-
@property
|
239
|
-
def reason(self) -> str | None:
|
240
|
-
"""Reason reported about the error."""
|
241
|
-
return cast(Optional[str], self.__dict__["_reason"])
|
242
|
-
|
243
|
-
def __repr__(self) -> str:
|
244
|
-
"""Return a string representation of this instance."""
|
245
|
-
view = ", ".join([f"{k.lstrip('_')}={v!r}" for k, v in self.__dict__.items()])
|
246
|
-
return f"{self.__class__.__qualname__}({view})"
|
247
|
-
|
248
|
-
def __eq__(self, other: object) -> bool:
|
249
|
-
"""Compare two instances of the class."""
|
250
|
-
if not isinstance(other, self.__class__):
|
251
|
-
raise NotImplementedError
|
252
|
-
return self.__dict__ == other.__dict__
|
253
|
-
|
254
|
-
|
255
61
|
class Message:
|
256
62
|
"""Represents a message exchanged between ClientApp and ServerApp.
|
257
63
|
|
@@ -614,48 +420,3 @@ def _check_arg_types( # pylint: disable=too-many-arguments, R0917
|
|
614
420
|
):
|
615
421
|
return
|
616
422
|
raise MessageInitializationError()
|
617
|
-
|
618
|
-
|
619
|
-
def validate_message_type(message_type: str) -> bool:
|
620
|
-
"""Validate if the message type is valid.
|
621
|
-
|
622
|
-
A valid message type format must be one of the following:
|
623
|
-
|
624
|
-
- "<category>"
|
625
|
-
- "<category>.<action>"
|
626
|
-
|
627
|
-
where `category` must be one of "train", "evaluate", or "query",
|
628
|
-
and `action` must be a valid Python identifier.
|
629
|
-
"""
|
630
|
-
# Check if conforming to the format "<category>"
|
631
|
-
valid_types = {
|
632
|
-
MessageType.TRAIN,
|
633
|
-
MessageType.EVALUATE,
|
634
|
-
MessageType.QUERY,
|
635
|
-
MessageType.SYSTEM,
|
636
|
-
}
|
637
|
-
if message_type in valid_types:
|
638
|
-
return True
|
639
|
-
|
640
|
-
# Check if conforming to the format "<category>.<action>"
|
641
|
-
if message_type.count(".") != 1:
|
642
|
-
return False
|
643
|
-
|
644
|
-
category, action = message_type.split(".")
|
645
|
-
if category in valid_types and action.isidentifier():
|
646
|
-
return True
|
647
|
-
|
648
|
-
return False
|
649
|
-
|
650
|
-
|
651
|
-
def validate_legacy_message_type(message_type: str) -> bool:
|
652
|
-
"""Validate if the legacy message type is valid."""
|
653
|
-
# Backward compatibility for legacy message types
|
654
|
-
if message_type in (
|
655
|
-
MessageTypeLegacy.GET_PARAMETERS,
|
656
|
-
MessageTypeLegacy.GET_PROPERTIES,
|
657
|
-
"reconnect",
|
658
|
-
):
|
659
|
-
return True
|
660
|
-
|
661
|
-
return False
|
flwr/common/record/array.py
CHANGED
@@ -262,7 +262,7 @@ class Array(InflatableObject):
|
|
262
262
|
)
|
263
263
|
|
264
264
|
obj_body = array_proto.SerializeToString(deterministic=True)
|
265
|
-
return add_header_to_object_body(object_body=obj_body,
|
265
|
+
return add_header_to_object_body(object_body=obj_body, obj=self)
|
266
266
|
|
267
267
|
@classmethod
|
268
268
|
def inflate(
|
@@ -284,7 +284,7 @@ class Array(InflatableObject):
|
|
284
284
|
Array
|
285
285
|
The inflated Array.
|
286
286
|
"""
|
287
|
-
if children
|
287
|
+
if children:
|
288
288
|
raise ValueError("`Array` objects do not have children.")
|
289
289
|
|
290
290
|
obj_body = get_object_body(object_content, cls)
|
@@ -382,7 +382,7 @@ class ArrayRecord(TypedDict[str, Array], InflatableObject):
|
|
382
382
|
|
383
383
|
# Serialize references dict
|
384
384
|
object_body = json.dumps(array_refs).encode("utf-8")
|
385
|
-
return add_header_to_object_body(object_body=object_body,
|
385
|
+
return add_header_to_object_body(object_body=object_body, obj=self)
|
386
386
|
|
387
387
|
@classmethod
|
388
388
|
def inflate(
|
@@ -182,7 +182,7 @@ class ConfigRecord(TypedDict[str, ConfigRecordValues], InflatableObject):
|
|
182
182
|
ProtoConfigRecordValue,
|
183
183
|
)
|
184
184
|
).SerializeToString(deterministic=True)
|
185
|
-
return add_header_to_object_body(object_body=obj_body,
|
185
|
+
return add_header_to_object_body(object_body=obj_body, obj=self)
|
186
186
|
|
187
187
|
@classmethod
|
188
188
|
def inflate(
|
@@ -204,7 +204,7 @@ class ConfigRecord(TypedDict[str, ConfigRecordValues], InflatableObject):
|
|
204
204
|
ConfigRecord
|
205
205
|
The inflated ConfigRecord.
|
206
206
|
"""
|
207
|
-
if children
|
207
|
+
if children:
|
208
208
|
raise ValueError("`ConfigRecord` objects do not have children.")
|
209
209
|
|
210
210
|
obj_body = get_object_body(object_content, cls)
|
@@ -157,7 +157,7 @@ class MetricRecord(TypedDict[str, MetricRecordValues], InflatableObject):
|
|
157
157
|
obj_body = ProtoMetricRecord(
|
158
158
|
data=record_value_dict_to_proto(self, [float, int], ProtoMetricRecordValue)
|
159
159
|
).SerializeToString(deterministic=True)
|
160
|
-
return add_header_to_object_body(object_body=obj_body,
|
160
|
+
return add_header_to_object_body(object_body=obj_body, obj=self)
|
161
161
|
|
162
162
|
@classmethod
|
163
163
|
def inflate(
|
flwr/common/record/recorddict.py
CHANGED
@@ -303,7 +303,7 @@ class RecordDict(TypedDict[str, RecordType], InflatableObject):
|
|
303
303
|
|
304
304
|
# Serialize references dict
|
305
305
|
object_body = json.dumps(record_refs).encode("utf-8")
|
306
|
-
return add_header_to_object_body(object_body=object_body,
|
306
|
+
return add_header_to_object_body(object_body=object_body, obj=self)
|
307
307
|
|
308
308
|
@classmethod
|
309
309
|
def inflate(
|
flwr/common/serde.py
CHANGED
@@ -44,6 +44,9 @@ from flwr.proto.transport_pb2 import (
|
|
44
44
|
Status,
|
45
45
|
)
|
46
46
|
|
47
|
+
from ..app.error import Error
|
48
|
+
from ..app.metadata import Metadata
|
49
|
+
|
47
50
|
# pylint: enable=E0611
|
48
51
|
from . import (
|
49
52
|
Array,
|
@@ -55,7 +58,7 @@ from . import (
|
|
55
58
|
typing,
|
56
59
|
)
|
57
60
|
from .constant import INT64_MAX_VALUE
|
58
|
-
from .message import
|
61
|
+
from .message import Message, make_message
|
59
62
|
from .serde_utils import record_value_dict_from_proto, record_value_dict_to_proto
|
60
63
|
|
61
64
|
# === Parameters message ===
|
flwr/compat/__init__.py
ADDED
@@ -0,0 +1,15 @@
|
|
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
|
+
"""Compatibility package containing deprecated legacy components."""
|
@@ -0,0 +1,15 @@
|
|
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
|
+
"""Legacy components previously located in ``flwr.client``."""
|
@@ -0,0 +1,15 @@
|
|
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
|
+
"""Legacy components previously located in ``flwr.common``."""
|
@@ -0,0 +1,15 @@
|
|
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
|
+
"""Legacy components previously located in ``flwr.server``."""
|
@@ -0,0 +1,15 @@
|
|
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
|
+
"""Legacy components previously located in ``flwr.simulation``."""
|
@@ -26,6 +26,7 @@ from queue import Empty, Queue
|
|
26
26
|
from time import sleep
|
27
27
|
from typing import Callable, Optional
|
28
28
|
|
29
|
+
from flwr.app.error import Error
|
29
30
|
from flwr.client.client_app import ClientApp, ClientAppException, LoadClientAppError
|
30
31
|
from flwr.client.clientapp.utils import get_load_client_app_fn
|
31
32
|
from flwr.client.run_info_store import DeprecatedRunInfoStore
|
@@ -37,7 +38,6 @@ from flwr.common.constant import (
|
|
37
38
|
ErrorCode,
|
38
39
|
)
|
39
40
|
from flwr.common.logger import log
|
40
|
-
from flwr.common.message import Error
|
41
41
|
from flwr.common.typing import Run
|
42
42
|
from flwr.server.superlink.linkstate import LinkState, LinkStateFactory
|
43
43
|
|
@@ -0,0 +1,15 @@
|
|
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
|
+
"""Public Flower ServerApp APIs."""
|
@@ -0,0 +1,15 @@
|
|
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
|
+
"""Infrastructure components shared between SuperLink and SuperNode."""
|
@@ -0,0 +1,15 @@
|
|
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
|
+
"""Flower SuperLink."""
|
@@ -0,0 +1,15 @@
|
|
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
|
+
"""Flower SuperNode."""
|
{flwr_nightly-1.19.0.dev20250515.dist-info → flwr_nightly-1.19.0.dev20250520.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: flwr-nightly
|
3
|
-
Version: 1.19.0.
|
3
|
+
Version: 1.19.0.dev20250520
|
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
|