flwr-nightly 1.21.0.dev20250908__py3-none-any.whl → 1.22.0.dev20250910__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/exception.py +2 -2
- flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.jax.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.pytorch_msg_api.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +1 -1
- flwr/clientapp/__init__.py +1 -3
- flwr/clientapp/mod/__init__.py +26 -0
- flwr/serverapp/strategy/strategy_utils.py +3 -1
- flwr/serverapp/strategy/strategy_utils_tests.py +28 -1
- flwr/supercore/cli/flower_superexec.py +23 -1
- {flwr_nightly-1.21.0.dev20250908.dist-info → flwr_nightly-1.22.0.dev20250910.dist-info}/METADATA +1 -1
- {flwr_nightly-1.21.0.dev20250908.dist-info → flwr_nightly-1.22.0.dev20250910.dist-info}/RECORD +21 -20
- /flwr/clientapp/{centraldp_mods.py → mod/centraldp_mods.py} +0 -0
- {flwr_nightly-1.21.0.dev20250908.dist-info → flwr_nightly-1.22.0.dev20250910.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.21.0.dev20250908.dist-info → flwr_nightly-1.22.0.dev20250910.dist-info}/entry_points.txt +0 -0
flwr/app/exception.py
CHANGED
@@ -15,11 +15,11 @@
|
|
15
15
|
"""Flower application exceptions."""
|
16
16
|
|
17
17
|
|
18
|
-
class AppExitException(
|
18
|
+
class AppExitException(BaseException):
|
19
19
|
"""Base exception for all application-level errors in ServerApp and ClientApp.
|
20
20
|
|
21
21
|
When raised, the process will exit and report a telemetry event with the associated
|
22
|
-
exit code.
|
22
|
+
exit code. This is not intended to be caught by user code.
|
23
23
|
"""
|
24
24
|
|
25
25
|
# Default exit code — subclasses must override
|
flwr/clientapp/__init__.py
CHANGED
@@ -15,13 +15,11 @@
|
|
15
15
|
"""Public Flower ClientApp APIs."""
|
16
16
|
|
17
17
|
|
18
|
-
from flwr.client import mod
|
19
18
|
from flwr.client.client_app import ClientApp
|
20
19
|
|
21
|
-
from .
|
20
|
+
from . import mod
|
22
21
|
|
23
22
|
__all__ = [
|
24
23
|
"ClientApp",
|
25
|
-
"fixedclipping_mod",
|
26
24
|
"mod",
|
27
25
|
]
|
@@ -0,0 +1,26 @@
|
|
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 Built-in Mods."""
|
16
|
+
|
17
|
+
|
18
|
+
from flwr.client.mod.comms_mods import arrays_size_mod, message_size_mod
|
19
|
+
|
20
|
+
from .centraldp_mods import fixedclipping_mod
|
21
|
+
|
22
|
+
__all__ = [
|
23
|
+
"arrays_size_mod",
|
24
|
+
"fixedclipping_mod",
|
25
|
+
"message_size_mod",
|
26
|
+
]
|
@@ -21,6 +21,8 @@ from logging import INFO
|
|
21
21
|
from time import sleep
|
22
22
|
from typing import Optional, cast
|
23
23
|
|
24
|
+
import numpy as np
|
25
|
+
|
24
26
|
from flwr.common import (
|
25
27
|
Array,
|
26
28
|
ArrayRecord,
|
@@ -99,7 +101,7 @@ def aggregate_arrayrecords(
|
|
99
101
|
aggregated_np_arrays[key] += value.numpy() * weight
|
100
102
|
|
101
103
|
return ArrayRecord(
|
102
|
-
OrderedDict({k: Array(v) for k, v in aggregated_np_arrays.items()})
|
104
|
+
OrderedDict({k: Array(np.asarray(v)) for k, v in aggregated_np_arrays.items()})
|
103
105
|
)
|
104
106
|
|
105
107
|
|
@@ -22,8 +22,8 @@ import pytest
|
|
22
22
|
from parameterized import parameterized
|
23
23
|
|
24
24
|
from flwr.common import Array, ArrayRecord, ConfigRecord, MetricRecord, RecordDict
|
25
|
+
from flwr.serverapp.exception import InconsistentMessageReplies
|
25
26
|
|
26
|
-
from ..exception import InconsistentMessageReplies
|
27
27
|
from .strategy_utils import (
|
28
28
|
aggregate_arrayrecords,
|
29
29
|
aggregate_metricrecords,
|
@@ -71,6 +71,33 @@ def test_arrayrecords_aggregation() -> None:
|
|
71
71
|
assert aggrd.object_id == ArrayRecord(avg_list).object_id
|
72
72
|
|
73
73
|
|
74
|
+
def test_arrayrecords_aggregation_with_ndim_zero() -> None:
|
75
|
+
"""Test aggregation of ArrayRecords with 0-dim arrays."""
|
76
|
+
num_replies = 3
|
77
|
+
weights = [0.25, 0.4, 0.35]
|
78
|
+
np_arrays = [np.array(np.random.randn()) for _ in range(num_replies)]
|
79
|
+
|
80
|
+
# For 0-dimensional arrays, we just compute the weighted average directly
|
81
|
+
avg_list = [np.average(np_arrays, axis=0, weights=weights)]
|
82
|
+
|
83
|
+
# Construct RecordDicts (mimicing replies)
|
84
|
+
records = [
|
85
|
+
RecordDict(
|
86
|
+
{
|
87
|
+
"arrays": ArrayRecord([np_arrays[i]]),
|
88
|
+
"metrics": MetricRecord({"weight": weights[i]}),
|
89
|
+
}
|
90
|
+
)
|
91
|
+
for i in range(num_replies)
|
92
|
+
]
|
93
|
+
# Execute aggregate
|
94
|
+
aggrd = aggregate_arrayrecords(records, weighting_metric_name="weight")
|
95
|
+
|
96
|
+
# Assert consistency
|
97
|
+
assert np.isclose(aggrd.to_numpy_ndarrays()[0], avg_list[0])
|
98
|
+
assert aggrd.object_id == ArrayRecord([np.array(avg_list[0])]).object_id
|
99
|
+
|
100
|
+
|
74
101
|
def test_metricrecords_aggregation() -> None:
|
75
102
|
"""Test aggregation of MetricRecords."""
|
76
103
|
num_replies = 3
|
@@ -17,6 +17,7 @@
|
|
17
17
|
|
18
18
|
import argparse
|
19
19
|
from logging import INFO
|
20
|
+
from typing import Optional
|
20
21
|
|
21
22
|
from flwr.common import EventType, event
|
22
23
|
from flwr.common.constant import ExecPluginType
|
@@ -34,6 +35,25 @@ from flwr.supercore.superexec.plugin import (
|
|
34
35
|
)
|
35
36
|
from flwr.supercore.superexec.run_superexec import run_superexec
|
36
37
|
|
38
|
+
try:
|
39
|
+
from flwr.ee.constant import ExecEePluginType
|
40
|
+
from flwr.ee.exec_plugin import get_ee_plugin_and_stub_class
|
41
|
+
except ImportError:
|
42
|
+
|
43
|
+
class ExecEePluginType: # type: ignore[no-redef]
|
44
|
+
"""SuperExec EE plugin types."""
|
45
|
+
|
46
|
+
@staticmethod
|
47
|
+
def all() -> list[str]:
|
48
|
+
"""Return all SuperExec EE plugin types."""
|
49
|
+
return []
|
50
|
+
|
51
|
+
def get_ee_plugin_and_stub_class( # pylint: disable=unused-argument
|
52
|
+
plugin_type: str,
|
53
|
+
) -> Optional[tuple[type[ExecPlugin], type[object]]]:
|
54
|
+
"""Get the EE plugin class and stub class based on the plugin type."""
|
55
|
+
return None
|
56
|
+
|
37
57
|
|
38
58
|
def flower_superexec() -> None:
|
39
59
|
"""Run `flower-superexec` command."""
|
@@ -73,7 +93,7 @@ def _parse_args() -> argparse.ArgumentParser:
|
|
73
93
|
parser.add_argument(
|
74
94
|
"--plugin-type",
|
75
95
|
type=str,
|
76
|
-
choices=ExecPluginType.all(),
|
96
|
+
choices=ExecPluginType.all() + ExecEePluginType.all(),
|
77
97
|
required=True,
|
78
98
|
help="The type of plugin to use.",
|
79
99
|
)
|
@@ -116,4 +136,6 @@ def _get_plugin_and_stub_class(
|
|
116
136
|
return ServerAppExecPlugin, ServerAppIoStub
|
117
137
|
if plugin_type == ExecPluginType.SIMULATION:
|
118
138
|
return SimulationExecPlugin, SimulationIoStub
|
139
|
+
if ret := get_ee_plugin_and_stub_class(plugin_type):
|
140
|
+
return ret # type: ignore[no-any-return]
|
119
141
|
raise ValueError(f"Unknown plugin type: {plugin_type}")
|
{flwr_nightly-1.21.0.dev20250908.dist-info → flwr_nightly-1.22.0.dev20250910.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: flwr-nightly
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.22.0.dev20250910
|
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.21.0.dev20250908.dist-info → flwr_nightly-1.22.0.dev20250910.dist-info}/RECORD
RENAMED
@@ -1,7 +1,7 @@
|
|
1
1
|
flwr/__init__.py,sha256=CXTKPZSm83CVKTxw9j_ge6AEVnqgd1rlcsm_2kPoVkU,1009
|
2
2
|
flwr/app/__init__.py,sha256=Pqg1iWx_TiBuGYeGJnS1QgYYWcAnPnZ2h4Y5iacNSls,1195
|
3
3
|
flwr/app/error.py,sha256=0PwA-E_CAs5P_nWAA0kksVO1A44t4CNLEf7u-Su-uJ0,2342
|
4
|
-
flwr/app/exception.py,sha256=
|
4
|
+
flwr/app/exception.py,sha256=WX45Yviu_CmYrYd8JHNjRkSsb-g4Br7XvVLKuVxwSdI,1298
|
5
5
|
flwr/app/metadata.py,sha256=rdMBn0zhIOYmCvmGENQWSQqDwcxwsMJzCle4PQdlc_Y,7331
|
6
6
|
flwr/cli/__init__.py,sha256=EfMGmHoobET6P2blBt_eOByXL8299MgFfB7XNdaPQ6I,720
|
7
7
|
flwr/cli/app.py,sha256=AKCP45Dkbpvdil_4Ir9S93L3HP3iUOnHmcZjscoM8uU,1856
|
@@ -66,16 +66,16 @@ flwr/cli/new/templates/app/code/task.pytorch_msg_api.py.tpl,sha256=RKA5lV6O6OnVK
|
|
66
66
|
flwr/cli/new/templates/app/code/task.sklearn.py.tpl,sha256=vHdhtMp0FHxbYafXyhDT9aKmmmA0Jvpx5Oum1Yu9lWY,1850
|
67
67
|
flwr/cli/new/templates/app/code/task.tensorflow.py.tpl,sha256=SKXAZdgBnPpbAbJ90Rb7oQ5ilnopBx_j_JNFoUDeEAI,1732
|
68
68
|
flwr/cli/new/templates/app/code/utils.baseline.py.tpl,sha256=YkHAgppUeD2BnBoGfVB6dEvBfjuIPGsU1gw4CiUi3qA,40
|
69
|
-
flwr/cli/new/templates/app/pyproject.baseline.toml.tpl,sha256=
|
70
|
-
flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=
|
71
|
-
flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl,sha256=
|
72
|
-
flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=
|
73
|
-
flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=
|
74
|
-
flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=
|
75
|
-
flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=
|
76
|
-
flwr/cli/new/templates/app/pyproject.pytorch_msg_api.toml.tpl,sha256=
|
77
|
-
flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=
|
78
|
-
flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=
|
69
|
+
flwr/cli/new/templates/app/pyproject.baseline.toml.tpl,sha256=eoRhBN5n00LQu2y4o29JUw3T03CasO5S1HMxHrnyWWQ,3180
|
70
|
+
flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=oVq52gXoPT69jHji75FSOYZ978xwIG-AVCha-LyuG7k,2497
|
71
|
+
flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl,sha256=lqWlKcwE7n7OFdqNDOrpi759HZuWFLEtkPvSL7jIkZI,2019
|
72
|
+
flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=fdDhwmPoMirJ095cU_vFCBf0ILQlAoa1fdnHb2LM1yk,1471
|
73
|
+
flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=aTvHNL9X3rAiHNgXzDoMbt2UA3xRvVVdga461D59ZPM,1542
|
74
|
+
flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=Kb_O2iQfzwc6FTy3fWqtQYc3FwY6x9SUgQPGqZR_ILg,1409
|
75
|
+
flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=docQbs3MuRR-yT24lVz7N2sQL3Sj49EHuOCuRj_0djQ,1508
|
76
|
+
flwr/cli/new/templates/app/pyproject.pytorch_msg_api.toml.tpl,sha256=SE4H23OFkQbqNU64nYf38igqrT4cJGA7XxEtSnNxJqg,1490
|
77
|
+
flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=apauU_PUmLEbt2rjckKniEbzdRs1EnMri_qgtHtBJZ8,1484
|
78
|
+
flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=LQpDKJTEnRKj5Ygn5FkT44SxlnLVprkPlbrGaFf5Q50,1508
|
79
79
|
flwr/cli/run/__init__.py,sha256=RPyB7KbYTFl6YRiilCch6oezxrLQrl1kijV7BMGkLbA,790
|
80
80
|
flwr/cli/run/run.py,sha256=ECa0kup9dn15O70H74QdgUsEaeErbzDqVX_U0zZO5IM,8173
|
81
81
|
flwr/cli/stop.py,sha256=TR9F61suTxNUzGIktUdoBhXwdRtCdvzGhy3qCuvcfBg,5000
|
@@ -107,8 +107,9 @@ flwr/client/rest_client/__init__.py,sha256=MBiuK62hj439m9rtwSwI184Hth6Tt5GbmpNMy
|
|
107
107
|
flwr/client/rest_client/connection.py,sha256=fyiS1aXTv71jWczx7mSco94LYJTBXgTF-p2PnAk3CL8,15784
|
108
108
|
flwr/client/run_info_store.py,sha256=MaJ3UQ-07hWtK67wnWu0zR29jrk0fsfgJX506dvEOfE,4042
|
109
109
|
flwr/client/typing.py,sha256=Jw3rawDzI_-ZDcRmEQcs5gZModY7oeQlEeltYsdOhlU,1048
|
110
|
-
flwr/clientapp/__init__.py,sha256=
|
111
|
-
flwr/clientapp/
|
110
|
+
flwr/clientapp/__init__.py,sha256=uoTjvIynfGvMhsmc7iYK-5qJ0AdKKjCbx7WTKc0KeSk,828
|
111
|
+
flwr/clientapp/mod/__init__.py,sha256=o8bbHMYb_aiPbGp6guRA-I_gCJaJQ6mCqSRZdfBYYrs,920
|
112
|
+
flwr/clientapp/mod/centraldp_mods.py,sha256=M8vvdrjfLVsFLMd9JXqD_-P08q9jsNOgu_4AAs-X9Zk,4626
|
112
113
|
flwr/common/__init__.py,sha256=5GCLVk399Az_rTJHNticRlL0Sl_oPw_j5_LuFKfX7-M,4171
|
113
114
|
flwr/common/address.py,sha256=9JucdTwlc-jpeJkRKeUboZoacUtErwSVtnDR9kAtLqE,4119
|
114
115
|
flwr/common/args.py,sha256=Nq2u4yePbkSY0CWFamn0hZY6Rms8G1xYDeDGIcLIITE,5849
|
@@ -340,8 +341,8 @@ flwr/serverapp/strategy/fedopt.py,sha256=kqT0uV2IUE93O72XEVa1JJo61dcwbZEoT9KmYTj
|
|
340
341
|
flwr/serverapp/strategy/fedyogi.py,sha256=1Ripr4Hi2cdeTOLiFOXtMKvOxR3BsUQwc7bbTrXN4LM,6653
|
341
342
|
flwr/serverapp/strategy/result.py,sha256=E0Hl2VLnZAgQJjE2GDoKsK7JX-kPPU2KXc47Axt6hGw,4295
|
342
343
|
flwr/serverapp/strategy/strategy.py,sha256=8uJGGm1ROLZERQ_dkRS7Z_rs-yK6XCE0UxXtIdFiEWk,10789
|
343
|
-
flwr/serverapp/strategy/strategy_utils.py,sha256=
|
344
|
-
flwr/serverapp/strategy/strategy_utils_tests.py,sha256=
|
344
|
+
flwr/serverapp/strategy/strategy_utils.py,sha256=9ga93Se21I_k7zYiw343EMC2qCTQ8rUG5ZEm8HVEuFs,9246
|
345
|
+
flwr/serverapp/strategy/strategy_utils_tests.py,sha256=o32XHujd9PLCB-YZMI2AttWLlvUXHe9yuxgiCrCkpgU,10209
|
345
346
|
flwr/simulation/__init__.py,sha256=Gg6OsP1Z-ixc3-xxzvl7j7rz2Fijy9rzyEPpxgAQCeM,1556
|
346
347
|
flwr/simulation/app.py,sha256=LbGLMvN9Ap119yBqsUcNNmVLRnCySnr4VechqcQ1hpA,10401
|
347
348
|
flwr/simulation/legacy_app.py,sha256=nMISQqW0otJL1-2Kfd94O6BLlGS2IEmEPKTM2WGKrIs,15861
|
@@ -354,7 +355,7 @@ flwr/simulation/simulationio_connection.py,sha256=mzS1C6EEREwQDPceDo30anAasmTDLb
|
|
354
355
|
flwr/supercore/__init__.py,sha256=pqkFoow_E6UhbBlhmoD1gmTH-33yJRhBsIZqxRPFZ7U,755
|
355
356
|
flwr/supercore/app_utils.py,sha256=K76Zt6R670b1hUmxOsNc1WUCVYvF7lejXPcCO9K0Q0g,1753
|
356
357
|
flwr/supercore/cli/__init__.py,sha256=EDl2aO-fuQfxSbL-T1W9RAfA2N0hpWHmqX_GSwblJbQ,845
|
357
|
-
flwr/supercore/cli/flower_superexec.py,sha256=
|
358
|
+
flwr/supercore/cli/flower_superexec.py,sha256=kov4uEeihf7QEUAfHEgdEvsL_8nL_fzQI9EePnRM1Ww,5012
|
358
359
|
flwr/supercore/corestate/__init__.py,sha256=Vau6-L_JG5QzNqtCTa9xCKGGljc09wY8avZmIjSJemg,774
|
359
360
|
flwr/supercore/corestate/corestate.py,sha256=rDAWWeG5DcpCyQso9Z3RhwL4zr2IroPlRMcDzqoSu8s,2328
|
360
361
|
flwr/supercore/ffs/__init__.py,sha256=U3KXwG_SplEvchat27K0LYPoPHzh-cwwT_NHsGlYMt8,908
|
@@ -402,7 +403,7 @@ flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca
|
|
402
403
|
flwr/supernode/servicer/clientappio/__init__.py,sha256=7Oy62Y_oijqF7Dxi6tpcUQyOpLc_QpIRZ83NvwmB0Yg,813
|
403
404
|
flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=nIHRu38EWK-rpNOkcgBRAAKwYQQWFeCwu0lkO7OPZGQ,10239
|
404
405
|
flwr/supernode/start_client_internal.py,sha256=Y9S1-QlO2WP6eo4JvWzIpfaCoh2aoE7bjEYyxNNnlyg,20777
|
405
|
-
flwr_nightly-1.
|
406
|
-
flwr_nightly-1.
|
407
|
-
flwr_nightly-1.
|
408
|
-
flwr_nightly-1.
|
406
|
+
flwr_nightly-1.22.0.dev20250910.dist-info/METADATA,sha256=7KsUFI_mYiRdZsLQ8_3IDEu9hn_ysW_R_r3H5Iz_I5g,15967
|
407
|
+
flwr_nightly-1.22.0.dev20250910.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
408
|
+
flwr_nightly-1.22.0.dev20250910.dist-info/entry_points.txt,sha256=hxHD2ixb_vJFDOlZV-zB4Ao32_BQlL34ftsDh1GXv14,420
|
409
|
+
flwr_nightly-1.22.0.dev20250910.dist-info/RECORD,,
|
File without changes
|
{flwr_nightly-1.21.0.dev20250908.dist-info → flwr_nightly-1.22.0.dev20250910.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|