flwr-nightly 1.20.0.dev20250725__py3-none-any.whl → 1.21.0.dev20250729__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/cli/new/new.py +12 -4
- flwr/cli/new/templates/app/README.flowertune.md.tpl +2 -0
- flwr/cli/new/templates/app/README.md.tpl +5 -0
- flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +14 -3
- flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +13 -1
- flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +21 -2
- flwr/cli/new/templates/app/pyproject.jax.toml.tpl +18 -1
- flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +19 -2
- flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +18 -1
- flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +20 -3
- flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +18 -1
- flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +18 -1
- flwr/cli/utils.py +11 -3
- flwr/client/grpc_rere_client/connection.py +1 -2
- flwr/client/rest_client/connection.py +1 -2
- flwr/common/inflatable_utils.py +49 -6
- flwr/proto/appio_pb2.py +15 -19
- flwr/proto/appio_pb2.pyi +2 -17
- flwr/proto/fleet_pb2.py +8 -12
- flwr/proto/fleet_pb2.pyi +2 -17
- flwr/server/grid/grpc_grid.py +26 -24
- flwr/server/serverapp/app.py +6 -0
- flwr/simulation/app.py +8 -0
- flwr/simulation/run_simulation.py +17 -0
- flwr/supercore/object_store/utils.py +5 -10
- flwr/supernode/runtime/run_clientapp.py +1 -3
- {flwr_nightly-1.20.0.dev20250725.dist-info → flwr_nightly-1.21.0.dev20250729.dist-info}/METADATA +1 -1
- {flwr_nightly-1.20.0.dev20250725.dist-info → flwr_nightly-1.21.0.dev20250729.dist-info}/RECORD +30 -30
- {flwr_nightly-1.20.0.dev20250725.dist-info → flwr_nightly-1.21.0.dev20250729.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.20.0.dev20250725.dist-info → flwr_nightly-1.21.0.dev20250729.dist-info}/entry_points.txt +0 -0
flwr/cli/new/new.py
CHANGED
@@ -271,28 +271,36 @@ def new(
|
|
271
271
|
|
272
272
|
prompt = typer.style(
|
273
273
|
"🎊 Flower App creation successful.\n\n"
|
274
|
-
"To run your Flower App,
|
274
|
+
"To run your Flower App, first install its dependencies:\n\n",
|
275
275
|
fg=typer.colors.GREEN,
|
276
276
|
bold=True,
|
277
277
|
)
|
278
278
|
|
279
279
|
_add = " huggingface-cli login\n" if llm_challenge_str else ""
|
280
|
+
|
280
281
|
prompt += typer.style(
|
281
|
-
|
282
|
+
f" cd {package_name} && pip install -e .\n" + _add + "\n",
|
282
283
|
fg=typer.colors.BRIGHT_CYAN,
|
283
284
|
bold=True,
|
284
285
|
)
|
285
286
|
|
286
287
|
prompt += typer.style(
|
287
|
-
"
|
288
|
+
"then, run the app:\n\n ",
|
288
289
|
fg=typer.colors.GREEN,
|
289
290
|
bold=True,
|
290
291
|
)
|
291
292
|
|
292
293
|
prompt += typer.style(
|
293
|
-
|
294
|
+
"\tflwr run .\n\n",
|
294
295
|
fg=typer.colors.BRIGHT_CYAN,
|
295
296
|
bold=True,
|
296
297
|
)
|
297
298
|
|
299
|
+
prompt += typer.style(
|
300
|
+
"💡 Check the README in your app directory to learn how to\n"
|
301
|
+
"customize it and how to run it using the Deployment Runtime.\n",
|
302
|
+
fg=typer.colors.GREEN,
|
303
|
+
bold=True,
|
304
|
+
)
|
305
|
+
|
298
306
|
print(prompt)
|
@@ -21,6 +21,8 @@ Project dependencies are defined in `pyproject.toml`. Install them in an activat
|
|
21
21
|
pip install -e .
|
22
22
|
```
|
23
23
|
|
24
|
+
> **Tip:** Learn how to configure your `pyproject.toml` file for Flower apps in [this guide](https://flower.ai/docs/framework/how-to-configure-pyproject-toml.html).
|
25
|
+
|
24
26
|
## Experimental setup
|
25
27
|
|
26
28
|
The dataset is divided into $num_clients partitions in an IID fashion, a partition is assigned to each ClientApp.
|
@@ -2,10 +2,15 @@
|
|
2
2
|
|
3
3
|
## Install dependencies and project
|
4
4
|
|
5
|
+
The dependencies are listed in the `pyproject.toml` and you can install them as follows:
|
6
|
+
|
5
7
|
```bash
|
6
8
|
pip install -e .
|
7
9
|
```
|
8
10
|
|
11
|
+
> **Tip:** Your `pyproject.toml` file can define more than just the dependencies of your Flower app. You can also use it to specify hyperparameters for your runs and control which Flower Runtime is used. By default, it uses the Simulation Runtime, but you can switch to the Deployment Runtime when needed.
|
12
|
+
> Learn more in the [TOML configuration guide](https://flower.ai/docs/framework/how-to-configure-pyproject-toml.html).
|
13
|
+
|
9
14
|
## Run with the Simulation Engine
|
10
15
|
|
11
16
|
In the `$project_name` directory, use `flwr run` to run a local simulation:
|
@@ -1,3 +1,8 @@
|
|
1
|
+
# =====================================================================
|
2
|
+
# For a full TOML configuration guide, check the Flower docs:
|
3
|
+
# https://flower.ai/docs/framework/how-to-configure-pyproject-toml.html
|
4
|
+
# =====================================================================
|
5
|
+
|
1
6
|
[build-system]
|
2
7
|
requires = ["hatchling"]
|
3
8
|
build-backend = "hatchling.build"
|
@@ -7,11 +12,12 @@ name = "$package_name"
|
|
7
12
|
version = "1.0.0"
|
8
13
|
description = ""
|
9
14
|
license = "Apache-2.0"
|
15
|
+
# Dependencies for your Flower App
|
10
16
|
dependencies = [
|
11
|
-
"flwr[simulation]>=1.
|
17
|
+
"flwr[simulation]>=1.21.0",
|
12
18
|
"flwr-datasets[vision]>=0.5.0",
|
13
|
-
"torch==2.
|
14
|
-
"torchvision==0.
|
19
|
+
"torch==2.7.1",
|
20
|
+
"torchvision==0.22.1",
|
15
21
|
]
|
16
22
|
|
17
23
|
[tool.hatch.metadata]
|
@@ -117,18 +123,23 @@ packages = ["."]
|
|
117
123
|
[tool.flwr.app]
|
118
124
|
publisher = "$username"
|
119
125
|
|
126
|
+
# Point to your ServerApp and ClientApp objects
|
127
|
+
# Format: "<module>:<object>"
|
120
128
|
[tool.flwr.app.components]
|
121
129
|
serverapp = "$import_name.server_app:app"
|
122
130
|
clientapp = "$import_name.client_app:app"
|
123
131
|
|
132
|
+
# Custom config values accessible via `context.run_config`
|
124
133
|
[tool.flwr.app.config]
|
125
134
|
num-server-rounds = 3
|
126
135
|
fraction-fit = 0.5
|
127
136
|
local-epochs = 1
|
128
137
|
|
138
|
+
# Default federation to use when running the app
|
129
139
|
[tool.flwr.federations]
|
130
140
|
default = "local-simulation"
|
131
141
|
|
142
|
+
# Local simulation federation with 10 virtual SuperNodes
|
132
143
|
[tool.flwr.federations.local-simulation]
|
133
144
|
options.num-supernodes = 10
|
134
145
|
options.backend.client-resources.num-cpus = 2
|
@@ -1,3 +1,8 @@
|
|
1
|
+
# =====================================================================
|
2
|
+
# For a full TOML configuration guide, check the Flower docs:
|
3
|
+
# https://flower.ai/docs/framework/how-to-configure-pyproject-toml.html
|
4
|
+
# =====================================================================
|
5
|
+
|
1
6
|
[build-system]
|
2
7
|
requires = ["hatchling"]
|
3
8
|
build-backend = "hatchling.build"
|
@@ -7,8 +12,9 @@ name = "$package_name"
|
|
7
12
|
version = "1.0.0"
|
8
13
|
description = ""
|
9
14
|
license = "Apache-2.0"
|
15
|
+
# Dependencies for your Flower App
|
10
16
|
dependencies = [
|
11
|
-
"flwr[simulation]>=1.
|
17
|
+
"flwr[simulation]>=1.21.0",
|
12
18
|
"flwr-datasets>=0.5.0",
|
13
19
|
"torch==2.4.0",
|
14
20
|
"trl==0.8.1",
|
@@ -27,10 +33,13 @@ packages = ["."]
|
|
27
33
|
[tool.flwr.app]
|
28
34
|
publisher = "$username"
|
29
35
|
|
36
|
+
# Point to your ServerApp and ClientApp objects
|
37
|
+
# Format: "<module>:<object>"
|
30
38
|
[tool.flwr.app.components]
|
31
39
|
serverapp = "$import_name.server_app:app"
|
32
40
|
clientapp = "$import_name.client_app:app"
|
33
41
|
|
42
|
+
# Custom config values accessible via `context.run_config`
|
34
43
|
[tool.flwr.app.config]
|
35
44
|
model.name = "mistralai/Mistral-7B-v0.3"
|
36
45
|
model.quantization = 4
|
@@ -56,12 +65,15 @@ strategy.fraction-fit = $fraction_fit
|
|
56
65
|
strategy.fraction-evaluate = 0.0
|
57
66
|
num-server-rounds = 200
|
58
67
|
|
68
|
+
# Dataset config (static for FlowerTune LLM Leaderboard)
|
59
69
|
[tool.flwr.app.config.static]
|
60
70
|
dataset.name = "$dataset_name"
|
61
71
|
|
72
|
+
# Default federation to use when running the app
|
62
73
|
[tool.flwr.federations]
|
63
74
|
default = "local-simulation"
|
64
75
|
|
76
|
+
# Local simulation federation with $num_clients virtual SuperNodes
|
65
77
|
[tool.flwr.federations.local-simulation]
|
66
78
|
options.num-supernodes = $num_clients
|
67
79
|
options.backend.client-resources.num-cpus = 6
|
@@ -1,3 +1,8 @@
|
|
1
|
+
# =====================================================================
|
2
|
+
# For a full TOML configuration guide, check the Flower docs:
|
3
|
+
# https://flower.ai/docs/framework/how-to-configure-pyproject-toml.html
|
4
|
+
# =====================================================================
|
5
|
+
|
1
6
|
[build-system]
|
2
7
|
requires = ["hatchling"]
|
3
8
|
build-backend = "hatchling.build"
|
@@ -7,10 +12,11 @@ name = "$package_name"
|
|
7
12
|
version = "1.0.0"
|
8
13
|
description = ""
|
9
14
|
license = "Apache-2.0"
|
15
|
+
# Dependencies for your Flower App
|
10
16
|
dependencies = [
|
11
|
-
"flwr[simulation]>=1.
|
17
|
+
"flwr[simulation]>=1.21.0",
|
12
18
|
"flwr-datasets>=0.5.0",
|
13
|
-
"torch==2.
|
19
|
+
"torch==2.7.1",
|
14
20
|
"transformers>=4.30.0,<5.0",
|
15
21
|
"evaluate>=0.4.0,<1.0",
|
16
22
|
"datasets>=2.0.0, <3.0",
|
@@ -23,10 +29,13 @@ packages = ["."]
|
|
23
29
|
[tool.flwr.app]
|
24
30
|
publisher = "$username"
|
25
31
|
|
32
|
+
# Point to your ServerApp and ClientApp objects
|
33
|
+
# Format: "<module>:<object>"
|
26
34
|
[tool.flwr.app.components]
|
27
35
|
serverapp = "$import_name.server_app:app"
|
28
36
|
clientapp = "$import_name.client_app:app"
|
29
37
|
|
38
|
+
# Custom config values accessible via `context.run_config`
|
30
39
|
[tool.flwr.app.config]
|
31
40
|
num-server-rounds = 3
|
32
41
|
fraction-fit = 0.5
|
@@ -34,13 +43,23 @@ local-epochs = 1
|
|
34
43
|
model-name = "prajjwal1/bert-tiny" # Set a larger model if you have access to more GPU resources
|
35
44
|
num-labels = 2
|
36
45
|
|
46
|
+
# Default federation to use when running the app
|
37
47
|
[tool.flwr.federations]
|
38
48
|
default = "localhost"
|
39
49
|
|
50
|
+
# Local simulation federation with 10 virtual SuperNodes
|
40
51
|
[tool.flwr.federations.localhost]
|
41
52
|
options.num-supernodes = 10
|
42
53
|
|
54
|
+
# Local simulation federation with 10 virtual SuperNodes
|
55
|
+
# making use of GPUs
|
43
56
|
[tool.flwr.federations.localhost-gpu]
|
44
57
|
options.num-supernodes = 10
|
45
58
|
options.backend.client-resources.num-cpus = 4 # each ClientApp assumes to use 4CPUs
|
46
59
|
options.backend.client-resources.num-gpus = 0.25 # at most 4 ClientApps will run in a given GPU
|
60
|
+
|
61
|
+
# Remote federation example for use with SuperLink
|
62
|
+
[tool.flwr.federations.remote-federation]
|
63
|
+
address = "<SUPERLINK-ADDRESS>:<PORT>"
|
64
|
+
insecure = true # Remove this line to enable TLS
|
65
|
+
# root-certificates = "<PATH/TO/ca.crt>" # For TLS setup
|
@@ -1,3 +1,8 @@
|
|
1
|
+
# =====================================================================
|
2
|
+
# For a full TOML configuration guide, check the Flower docs:
|
3
|
+
# https://flower.ai/docs/framework/how-to-configure-pyproject-toml.html
|
4
|
+
# =====================================================================
|
5
|
+
|
1
6
|
[build-system]
|
2
7
|
requires = ["hatchling"]
|
3
8
|
build-backend = "hatchling.build"
|
@@ -7,8 +12,9 @@ name = "$package_name"
|
|
7
12
|
version = "1.0.0"
|
8
13
|
description = ""
|
9
14
|
license = "Apache-2.0"
|
15
|
+
# Dependencies for your Flower App
|
10
16
|
dependencies = [
|
11
|
-
"flwr[simulation]>=1.
|
17
|
+
"flwr[simulation]>=1.21.0",
|
12
18
|
"jax==0.4.30",
|
13
19
|
"jaxlib==0.4.30",
|
14
20
|
"scikit-learn==1.6.1",
|
@@ -20,16 +26,27 @@ packages = ["."]
|
|
20
26
|
[tool.flwr.app]
|
21
27
|
publisher = "$username"
|
22
28
|
|
29
|
+
# Point to your ServerApp and ClientApp objects
|
30
|
+
# Format: "<module>:<object>"
|
23
31
|
[tool.flwr.app.components]
|
24
32
|
serverapp = "$import_name.server_app:app"
|
25
33
|
clientapp = "$import_name.client_app:app"
|
26
34
|
|
35
|
+
# Custom config values accessible via `context.run_config`
|
27
36
|
[tool.flwr.app.config]
|
28
37
|
num-server-rounds = 3
|
29
38
|
input-dim = 3
|
30
39
|
|
40
|
+
# Default federation to use when running the app
|
31
41
|
[tool.flwr.federations]
|
32
42
|
default = "local-simulation"
|
33
43
|
|
44
|
+
# Local simulation federation with 10 virtual SuperNodes
|
34
45
|
[tool.flwr.federations.local-simulation]
|
35
46
|
options.num-supernodes = 10
|
47
|
+
|
48
|
+
# Remote federation example for use with SuperLink
|
49
|
+
[tool.flwr.federations.remote-federation]
|
50
|
+
address = "<SUPERLINK-ADDRESS>:<PORT>"
|
51
|
+
insecure = true # Remove this line to enable TLS
|
52
|
+
# root-certificates = "<PATH/TO/ca.crt>" # For TLS setup
|
@@ -1,3 +1,8 @@
|
|
1
|
+
# =====================================================================
|
2
|
+
# For a full TOML configuration guide, check the Flower docs:
|
3
|
+
# https://flower.ai/docs/framework/how-to-configure-pyproject-toml.html
|
4
|
+
# =====================================================================
|
5
|
+
|
1
6
|
[build-system]
|
2
7
|
requires = ["hatchling"]
|
3
8
|
build-backend = "hatchling.build"
|
@@ -7,10 +12,11 @@ name = "$package_name"
|
|
7
12
|
version = "1.0.0"
|
8
13
|
description = ""
|
9
14
|
license = "Apache-2.0"
|
15
|
+
# Dependencies for your Flower App
|
10
16
|
dependencies = [
|
11
|
-
"flwr[simulation]>=1.
|
17
|
+
"flwr[simulation]>=1.21.0",
|
12
18
|
"flwr-datasets[vision]>=0.5.0",
|
13
|
-
"mlx==0.
|
19
|
+
"mlx==0.26.5",
|
14
20
|
]
|
15
21
|
|
16
22
|
[tool.hatch.build.targets.wheel]
|
@@ -19,10 +25,13 @@ packages = ["."]
|
|
19
25
|
[tool.flwr.app]
|
20
26
|
publisher = "$username"
|
21
27
|
|
28
|
+
# Point to your ServerApp and ClientApp objects
|
29
|
+
# Format: "<module>:<object>"
|
22
30
|
[tool.flwr.app.components]
|
23
31
|
serverapp = "$import_name.server_app:app"
|
24
32
|
clientapp = "$import_name.client_app:app"
|
25
33
|
|
34
|
+
# Custom config values accessible via `context.run_config`
|
26
35
|
[tool.flwr.app.config]
|
27
36
|
num-server-rounds = 3
|
28
37
|
local-epochs = 1
|
@@ -32,8 +41,16 @@ hidden-dim = 32
|
|
32
41
|
batch-size = 256
|
33
42
|
lr = 0.1
|
34
43
|
|
44
|
+
# Default federation to use when running the app
|
35
45
|
[tool.flwr.federations]
|
36
46
|
default = "local-simulation"
|
37
47
|
|
48
|
+
# Local simulation federation with 10 virtual SuperNodes
|
38
49
|
[tool.flwr.federations.local-simulation]
|
39
50
|
options.num-supernodes = 10
|
51
|
+
|
52
|
+
# Remote federation example for use with SuperLink
|
53
|
+
[tool.flwr.federations.remote-federation]
|
54
|
+
address = "<SUPERLINK-ADDRESS>:<PORT>"
|
55
|
+
insecure = true # Remove this line to enable TLS
|
56
|
+
# root-certificates = "<PATH/TO/ca.crt>" # For TLS setup
|
@@ -1,3 +1,8 @@
|
|
1
|
+
# =====================================================================
|
2
|
+
# For a full TOML configuration guide, check the Flower docs:
|
3
|
+
# https://flower.ai/docs/framework/how-to-configure-pyproject-toml.html
|
4
|
+
# =====================================================================
|
5
|
+
|
1
6
|
[build-system]
|
2
7
|
requires = ["hatchling"]
|
3
8
|
build-backend = "hatchling.build"
|
@@ -7,8 +12,9 @@ name = "$package_name"
|
|
7
12
|
version = "1.0.0"
|
8
13
|
description = ""
|
9
14
|
license = "Apache-2.0"
|
15
|
+
# Dependencies for your Flower App
|
10
16
|
dependencies = [
|
11
|
-
"flwr[simulation]>=1.
|
17
|
+
"flwr[simulation]>=1.21.0",
|
12
18
|
"numpy>=2.0.2",
|
13
19
|
]
|
14
20
|
|
@@ -18,15 +24,26 @@ packages = ["."]
|
|
18
24
|
[tool.flwr.app]
|
19
25
|
publisher = "$username"
|
20
26
|
|
27
|
+
# Point to your ServerApp and ClientApp objects
|
28
|
+
# Format: "<module>:<object>"
|
21
29
|
[tool.flwr.app.components]
|
22
30
|
serverapp = "$import_name.server_app:app"
|
23
31
|
clientapp = "$import_name.client_app:app"
|
24
32
|
|
33
|
+
# Custom config values accessible via `context.run_config`
|
25
34
|
[tool.flwr.app.config]
|
26
35
|
num-server-rounds = 3
|
27
36
|
|
37
|
+
# Default federation to use when running the app
|
28
38
|
[tool.flwr.federations]
|
29
39
|
default = "local-simulation"
|
30
40
|
|
41
|
+
# Local simulation federation with 10 virtual SuperNodes
|
31
42
|
[tool.flwr.federations.local-simulation]
|
32
43
|
options.num-supernodes = 10
|
44
|
+
|
45
|
+
# Remote federation example for use with SuperLink
|
46
|
+
[tool.flwr.federations.remote-federation]
|
47
|
+
address = "<SUPERLINK-ADDRESS>:<PORT>"
|
48
|
+
insecure = true # Remove this line to enable TLS
|
49
|
+
# root-certificates = "<PATH/TO/ca.crt>" # For TLS setup
|
@@ -1,3 +1,8 @@
|
|
1
|
+
# =====================================================================
|
2
|
+
# For a full TOML configuration guide, check the Flower docs:
|
3
|
+
# https://flower.ai/docs/framework/how-to-configure-pyproject-toml.html
|
4
|
+
# =====================================================================
|
5
|
+
|
1
6
|
[build-system]
|
2
7
|
requires = ["hatchling"]
|
3
8
|
build-backend = "hatchling.build"
|
@@ -7,11 +12,12 @@ name = "$package_name"
|
|
7
12
|
version = "1.0.0"
|
8
13
|
description = ""
|
9
14
|
license = "Apache-2.0"
|
15
|
+
# Dependencies for your Flower App
|
10
16
|
dependencies = [
|
11
|
-
"flwr[simulation]>=1.
|
17
|
+
"flwr[simulation]>=1.21.0",
|
12
18
|
"flwr-datasets[vision]>=0.5.0",
|
13
|
-
"torch==2.
|
14
|
-
"torchvision==0.
|
19
|
+
"torch==2.7.1",
|
20
|
+
"torchvision==0.22.1",
|
15
21
|
]
|
16
22
|
|
17
23
|
[tool.hatch.build.targets.wheel]
|
@@ -20,17 +26,28 @@ packages = ["."]
|
|
20
26
|
[tool.flwr.app]
|
21
27
|
publisher = "$username"
|
22
28
|
|
29
|
+
# Point to your ServerApp and ClientApp objects
|
30
|
+
# Format: "<module>:<object>"
|
23
31
|
[tool.flwr.app.components]
|
24
32
|
serverapp = "$import_name.server_app:app"
|
25
33
|
clientapp = "$import_name.client_app:app"
|
26
34
|
|
35
|
+
# Custom config values accessible via `context.run_config`
|
27
36
|
[tool.flwr.app.config]
|
28
37
|
num-server-rounds = 3
|
29
38
|
fraction-fit = 0.5
|
30
39
|
local-epochs = 1
|
31
40
|
|
41
|
+
# Default federation to use when running the app
|
32
42
|
[tool.flwr.federations]
|
33
43
|
default = "local-simulation"
|
34
44
|
|
45
|
+
# Local simulation federation with 10 virtual SuperNodes
|
35
46
|
[tool.flwr.federations.local-simulation]
|
36
47
|
options.num-supernodes = 10
|
48
|
+
|
49
|
+
# Remote federation example for use with SuperLink
|
50
|
+
[tool.flwr.federations.remote-federation]
|
51
|
+
address = "<SUPERLINK-ADDRESS>:<PORT>"
|
52
|
+
insecure = true # Remove this line to enable TLS
|
53
|
+
# root-certificates = "<PATH/TO/ca.crt>" # For TLS setup
|
@@ -1,3 +1,8 @@
|
|
1
|
+
# =====================================================================
|
2
|
+
# For a full TOML configuration guide, check the Flower docs:
|
3
|
+
# https://flower.ai/docs/framework/how-to-configure-pyproject-toml.html
|
4
|
+
# =====================================================================
|
5
|
+
|
1
6
|
[build-system]
|
2
7
|
requires = ["hatchling"]
|
3
8
|
build-backend = "hatchling.build"
|
@@ -7,8 +12,9 @@ name = "$package_name"
|
|
7
12
|
version = "1.0.0"
|
8
13
|
description = ""
|
9
14
|
license = "Apache-2.0"
|
15
|
+
# Dependencies for your Flower App
|
10
16
|
dependencies = [
|
11
|
-
"flwr[simulation]>=1.
|
17
|
+
"flwr[simulation]>=1.21.0",
|
12
18
|
"flwr-datasets[vision]>=0.5.0",
|
13
19
|
"scikit-learn>=1.6.1",
|
14
20
|
]
|
@@ -19,17 +25,28 @@ packages = ["."]
|
|
19
25
|
[tool.flwr.app]
|
20
26
|
publisher = "$username"
|
21
27
|
|
28
|
+
# Point to your ServerApp and ClientApp objects
|
29
|
+
# Format: "<module>:<object>"
|
22
30
|
[tool.flwr.app.components]
|
23
31
|
serverapp = "$import_name.server_app:app"
|
24
32
|
clientapp = "$import_name.client_app:app"
|
25
33
|
|
34
|
+
# Custom config values accessible via `context.run_config`
|
26
35
|
[tool.flwr.app.config]
|
27
36
|
num-server-rounds = 3
|
28
37
|
penalty = "l2"
|
29
38
|
local-epochs = 1
|
30
39
|
|
40
|
+
# Default federation to use when running the app
|
31
41
|
[tool.flwr.federations]
|
32
42
|
default = "local-simulation"
|
33
43
|
|
44
|
+
# Local simulation federation with 10 virtual SuperNodes
|
34
45
|
[tool.flwr.federations.local-simulation]
|
35
46
|
options.num-supernodes = 10
|
47
|
+
|
48
|
+
# Remote federation example for use with SuperLink
|
49
|
+
[tool.flwr.federations.remote-federation]
|
50
|
+
address = "<SUPERLINK-ADDRESS>:<PORT>"
|
51
|
+
insecure = true # Remove this line to enable TLS
|
52
|
+
# root-certificates = "<PATH/TO/ca.crt>" # For TLS setup
|
@@ -1,3 +1,8 @@
|
|
1
|
+
# =====================================================================
|
2
|
+
# For a full TOML configuration guide, check the Flower docs:
|
3
|
+
# https://flower.ai/docs/framework/how-to-configure-pyproject-toml.html
|
4
|
+
# =====================================================================
|
5
|
+
|
1
6
|
[build-system]
|
2
7
|
requires = ["hatchling"]
|
3
8
|
build-backend = "hatchling.build"
|
@@ -7,8 +12,9 @@ name = "$package_name"
|
|
7
12
|
version = "1.0.0"
|
8
13
|
description = ""
|
9
14
|
license = "Apache-2.0"
|
15
|
+
# Dependencies for your Flower App
|
10
16
|
dependencies = [
|
11
|
-
"flwr[simulation]>=1.
|
17
|
+
"flwr[simulation]>=1.21.0",
|
12
18
|
"flwr-datasets[vision]>=0.5.0",
|
13
19
|
"tensorflow>=2.11.1,<2.18.0",
|
14
20
|
]
|
@@ -19,18 +25,29 @@ packages = ["."]
|
|
19
25
|
[tool.flwr.app]
|
20
26
|
publisher = "$username"
|
21
27
|
|
28
|
+
# Point to your ServerApp and ClientApp objects
|
29
|
+
# Format: "<module>:<object>"
|
22
30
|
[tool.flwr.app.components]
|
23
31
|
serverapp = "$import_name.server_app:app"
|
24
32
|
clientapp = "$import_name.client_app:app"
|
25
33
|
|
34
|
+
# Custom config values accessible via `context.run_config`
|
26
35
|
[tool.flwr.app.config]
|
27
36
|
num-server-rounds = 3
|
28
37
|
local-epochs = 1
|
29
38
|
batch-size = 32
|
30
39
|
verbose = false
|
31
40
|
|
41
|
+
# Default federation to use when running the app
|
32
42
|
[tool.flwr.federations]
|
33
43
|
default = "local-simulation"
|
34
44
|
|
45
|
+
# Local simulation federation with 10 virtual SuperNodes
|
35
46
|
[tool.flwr.federations.local-simulation]
|
36
47
|
options.num-supernodes = 10
|
48
|
+
|
49
|
+
# Remote federation example for use with SuperLink
|
50
|
+
[tool.flwr.federations.remote-federation]
|
51
|
+
address = "<SUPERLINK-ADDRESS>:<PORT>"
|
52
|
+
insecure = true # Remove this line to enable TLS
|
53
|
+
# root-certificates = "<PATH/TO/ca.crt>" # For TLS setup
|
flwr/cli/utils.py
CHANGED
@@ -296,9 +296,9 @@ def init_channel(
|
|
296
296
|
def flwr_cli_grpc_exc_handler() -> Iterator[None]:
|
297
297
|
"""Context manager to handle specific gRPC errors.
|
298
298
|
|
299
|
-
It catches grpc.RpcError exceptions with UNAUTHENTICATED, UNIMPLEMENTED,
|
300
|
-
PERMISSION_DENIED statuses, informs the user, and exits the
|
301
|
-
exceptions will be allowed to escape.
|
299
|
+
It catches grpc.RpcError exceptions with UNAUTHENTICATED, UNIMPLEMENTED,
|
300
|
+
UNAVAILABLE, and PERMISSION_DENIED statuses, informs the user, and exits the
|
301
|
+
application. All other exceptions will be allowed to escape.
|
302
302
|
"""
|
303
303
|
try:
|
304
304
|
yield
|
@@ -327,6 +327,14 @@ def flwr_cli_grpc_exc_handler() -> Iterator[None]:
|
|
327
327
|
# pylint: disable=E1101
|
328
328
|
typer.secho(e.details(), fg=typer.colors.RED, bold=True)
|
329
329
|
raise typer.Exit(code=1) from None
|
330
|
+
if e.code() == grpc.StatusCode.UNAVAILABLE:
|
331
|
+
typer.secho(
|
332
|
+
"Connection to the SuperLink is unavailable. Please check your network "
|
333
|
+
"connection and 'address' in the federation configuration.",
|
334
|
+
fg=typer.colors.RED,
|
335
|
+
bold=True,
|
336
|
+
)
|
337
|
+
raise typer.Exit(code=1) from None
|
330
338
|
if (
|
331
339
|
e.code() == grpc.StatusCode.NOT_FOUND
|
332
340
|
and e.details() == RUN_ID_NOT_FOUND_MESSAGE
|
@@ -285,8 +285,7 @@ def grpc_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
285
285
|
response: PushMessagesResponse = stub.PushMessages(request=request)
|
286
286
|
|
287
287
|
# Get and return the object IDs to push
|
288
|
-
|
289
|
-
return set(object_ids_to_push.object_ids)
|
288
|
+
return set(response.objects_to_push)
|
290
289
|
|
291
290
|
def get_run(run_id: int) -> Run:
|
292
291
|
# Call FleetAPI
|
@@ -369,8 +369,7 @@ def http_request_response( # pylint: disable=R0913,R0914,R0915,R0917
|
|
369
369
|
raise ValueError("PushMessagesResponse is None.")
|
370
370
|
|
371
371
|
# Get and return the object IDs to push
|
372
|
-
|
373
|
-
return set(object_ids_to_push.object_ids)
|
372
|
+
return set(res.objects_to_push)
|
374
373
|
|
375
374
|
def get_run(run_id: int) -> Run:
|
376
375
|
# Construct the request
|
flwr/common/inflatable_utils.py
CHANGED
@@ -34,6 +34,7 @@ from .constant import (
|
|
34
34
|
PULL_MAX_TIME,
|
35
35
|
PULL_MAX_TRIES_PER_OBJECT,
|
36
36
|
)
|
37
|
+
from .exit_handlers import add_exit_handler
|
37
38
|
from .inflatable import (
|
38
39
|
InflatableObject,
|
39
40
|
UnexpectedObjectContentError,
|
@@ -61,6 +62,34 @@ inflatable_class_registry: dict[str, type[InflatableObject]] = {
|
|
61
62
|
T = TypeVar("T", bound=InflatableObject)
|
62
63
|
|
63
64
|
|
65
|
+
# Allow thread pool executors to be shut down gracefully
|
66
|
+
_thread_pool_executors: set[concurrent.futures.ThreadPoolExecutor] = set()
|
67
|
+
_lock = threading.Lock()
|
68
|
+
|
69
|
+
|
70
|
+
def _shutdown_thread_pool_executors() -> None:
|
71
|
+
"""Shutdown all thread pool executors gracefully."""
|
72
|
+
with _lock:
|
73
|
+
for executor in _thread_pool_executors:
|
74
|
+
executor.shutdown(wait=False, cancel_futures=True)
|
75
|
+
_thread_pool_executors.clear()
|
76
|
+
|
77
|
+
|
78
|
+
def _track_executor(executor: concurrent.futures.ThreadPoolExecutor) -> None:
|
79
|
+
"""Track a thread pool executor for graceful shutdown."""
|
80
|
+
with _lock:
|
81
|
+
_thread_pool_executors.add(executor)
|
82
|
+
|
83
|
+
|
84
|
+
def _untrack_executor(executor: concurrent.futures.ThreadPoolExecutor) -> None:
|
85
|
+
"""Untrack a thread pool executor."""
|
86
|
+
with _lock:
|
87
|
+
_thread_pool_executors.discard(executor)
|
88
|
+
|
89
|
+
|
90
|
+
add_exit_handler(_shutdown_thread_pool_executors)
|
91
|
+
|
92
|
+
|
64
93
|
class ObjectUnavailableError(Exception):
|
65
94
|
"""Exception raised when an object has been pre-registered but is not yet
|
66
95
|
available."""
|
@@ -165,7 +194,16 @@ def push_object_contents_from_iterable(
|
|
165
194
|
# Push all object contents concurrently
|
166
195
|
num_workers = get_num_workers(max_concurrent_pushes)
|
167
196
|
with concurrent.futures.ThreadPoolExecutor(max_workers=num_workers) as executor:
|
168
|
-
|
197
|
+
# Ensure that the thread pool executors are tracked for graceful shutdown
|
198
|
+
_track_executor(executor)
|
199
|
+
|
200
|
+
# Submit push tasks for each object content
|
201
|
+
executor.map(push, object_contents) # Non-blocking map
|
202
|
+
|
203
|
+
# The context manager will block until all submitted tasks have completed
|
204
|
+
|
205
|
+
# Remove the executor from the list of tracked executors
|
206
|
+
_untrack_executor(executor)
|
169
207
|
|
170
208
|
|
171
209
|
def pull_objects( # pylint: disable=too-many-arguments,too-many-locals
|
@@ -262,13 +300,18 @@ def pull_objects( # pylint: disable=too-many-arguments,too-many-locals
|
|
262
300
|
# Submit all pull tasks concurrently
|
263
301
|
num_workers = get_num_workers(max_concurrent_pulls)
|
264
302
|
with concurrent.futures.ThreadPoolExecutor(max_workers=num_workers) as executor:
|
265
|
-
|
266
|
-
|
267
|
-
|
303
|
+
# Ensure that the thread pool executors are tracked for graceful shutdown
|
304
|
+
_track_executor(executor)
|
305
|
+
|
306
|
+
# Submit pull tasks for each object ID
|
307
|
+
executor.map(pull_with_retries, object_ids) # Non-blocking map
|
308
|
+
|
309
|
+
# The context manager will block until all submitted tasks have completed
|
268
310
|
|
269
|
-
|
270
|
-
|
311
|
+
# Remove the executor from the list of tracked executors
|
312
|
+
_untrack_executor(executor)
|
271
313
|
|
314
|
+
# If an error occurred during pulling, raise it
|
272
315
|
if err_to_raise is not None:
|
273
316
|
raise err_to_raise
|
274
317
|
|
flwr/proto/appio_pb2.py
CHANGED
@@ -17,31 +17,27 @@ from flwr.proto import fab_pb2 as flwr_dot_proto_dot_fab__pb2
|
|
17
17
|
from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2
|
18
18
|
|
19
19
|
|
20
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x66lwr/proto/appio.proto\x12\nflwr.proto\x1a\x18\x66lwr/proto/message.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x14\x66lwr/proto/run.proto\"\x99\x01\n\x16PushAppMessagesRequest\x12\r\n\x05token\x18\x01 \x01(\t\x12*\n\rmessages_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.Message\x12\x0e\n\x06run_id\x18\x03 \x01(\x04\x12\x34\n\x14message_object_trees\x18\x04 \x03(\x0b\x32\x16.flwr.proto.ObjectTree\"\
|
20
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x66lwr/proto/appio.proto\x12\nflwr.proto\x1a\x18\x66lwr/proto/message.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x14\x66lwr/proto/run.proto\"\x99\x01\n\x16PushAppMessagesRequest\x12\r\n\x05token\x18\x01 \x01(\t\x12*\n\rmessages_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.Message\x12\x0e\n\x06run_id\x18\x03 \x01(\x04\x12\x34\n\x14message_object_trees\x18\x04 \x03(\x0b\x32\x16.flwr.proto.ObjectTree\"G\n\x17PushAppMessagesResponse\x12\x13\n\x0bmessage_ids\x18\x01 \x03(\t\x12\x17\n\x0fobjects_to_push\x18\x02 \x03(\t\"L\n\x16PullAppMessagesRequest\x12\r\n\x05token\x18\x01 \x01(\t\x12\x13\n\x0bmessage_ids\x18\x02 \x03(\t\x12\x0e\n\x06run_id\x18\x03 \x01(\x04\"{\n\x17PullAppMessagesResponse\x12*\n\rmessages_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.Message\x12\x34\n\x14message_object_trees\x18\x02 \x03(\x0b\x32\x16.flwr.proto.ObjectTree\"%\n\x14PullAppInputsRequest\x12\r\n\x05token\x18\x01 \x01(\t\"y\n\x15PullAppInputsResponse\x12$\n\x07\x63ontext\x18\x01 \x01(\x0b\x32\x13.flwr.proto.Context\x12\x1c\n\x03run\x18\x02 \x01(\x0b\x32\x0f.flwr.proto.Run\x12\x1c\n\x03\x66\x61\x62\x18\x03 \x01(\x0b\x32\x0f.flwr.proto.Fab\"\\\n\x15PushAppOutputsRequest\x12\r\n\x05token\x18\x01 \x01(\t\x12\x0e\n\x06run_id\x18\x02 \x01(\x04\x12$\n\x07\x63ontext\x18\x03 \x01(\x0b\x32\x13.flwr.proto.Context\"\x18\n\x16PushAppOutputsResponseb\x06proto3')
|
21
21
|
|
22
22
|
_globals = globals()
|
23
23
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
24
24
|
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.appio_pb2', _globals)
|
25
25
|
if _descriptor._USE_C_DESCRIPTORS == False:
|
26
26
|
DESCRIPTOR._options = None
|
27
|
-
_globals['_PUSHAPPMESSAGESRESPONSE_OBJECTSTOPUSHENTRY']._options = None
|
28
|
-
_globals['_PUSHAPPMESSAGESRESPONSE_OBJECTSTOPUSHENTRY']._serialized_options = b'8\001'
|
29
27
|
_globals['_PUSHAPPMESSAGESREQUEST']._serialized_start=109
|
30
28
|
_globals['_PUSHAPPMESSAGESREQUEST']._serialized_end=262
|
31
|
-
_globals['_PUSHAPPMESSAGESRESPONSE']._serialized_start=
|
32
|
-
_globals['_PUSHAPPMESSAGESRESPONSE']._serialized_end=
|
33
|
-
_globals['
|
34
|
-
_globals['
|
35
|
-
_globals['
|
36
|
-
_globals['
|
37
|
-
_globals['
|
38
|
-
_globals['
|
39
|
-
_globals['
|
40
|
-
_globals['
|
41
|
-
_globals['
|
42
|
-
_globals['
|
43
|
-
_globals['
|
44
|
-
_globals['
|
45
|
-
_globals['_PUSHAPPOUTPUTSRESPONSE']._serialized_start=930
|
46
|
-
_globals['_PUSHAPPOUTPUTSRESPONSE']._serialized_end=954
|
29
|
+
_globals['_PUSHAPPMESSAGESRESPONSE']._serialized_start=264
|
30
|
+
_globals['_PUSHAPPMESSAGESRESPONSE']._serialized_end=335
|
31
|
+
_globals['_PULLAPPMESSAGESREQUEST']._serialized_start=337
|
32
|
+
_globals['_PULLAPPMESSAGESREQUEST']._serialized_end=413
|
33
|
+
_globals['_PULLAPPMESSAGESRESPONSE']._serialized_start=415
|
34
|
+
_globals['_PULLAPPMESSAGESRESPONSE']._serialized_end=538
|
35
|
+
_globals['_PULLAPPINPUTSREQUEST']._serialized_start=540
|
36
|
+
_globals['_PULLAPPINPUTSREQUEST']._serialized_end=577
|
37
|
+
_globals['_PULLAPPINPUTSRESPONSE']._serialized_start=579
|
38
|
+
_globals['_PULLAPPINPUTSRESPONSE']._serialized_end=700
|
39
|
+
_globals['_PUSHAPPOUTPUTSREQUEST']._serialized_start=702
|
40
|
+
_globals['_PUSHAPPOUTPUTSREQUEST']._serialized_end=794
|
41
|
+
_globals['_PUSHAPPOUTPUTSRESPONSE']._serialized_start=796
|
42
|
+
_globals['_PUSHAPPOUTPUTSRESPONSE']._serialized_end=820
|
47
43
|
# @@protoc_insertion_point(module_scope)
|
flwr/proto/appio_pb2.pyi
CHANGED
@@ -42,31 +42,16 @@ global___PushAppMessagesRequest = PushAppMessagesRequest
|
|
42
42
|
|
43
43
|
class PushAppMessagesResponse(google.protobuf.message.Message):
|
44
44
|
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
45
|
-
class ObjectsToPushEntry(google.protobuf.message.Message):
|
46
|
-
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
47
|
-
KEY_FIELD_NUMBER: builtins.int
|
48
|
-
VALUE_FIELD_NUMBER: builtins.int
|
49
|
-
key: typing.Text
|
50
|
-
@property
|
51
|
-
def value(self) -> flwr.proto.message_pb2.ObjectIDs: ...
|
52
|
-
def __init__(self,
|
53
|
-
*,
|
54
|
-
key: typing.Text = ...,
|
55
|
-
value: typing.Optional[flwr.proto.message_pb2.ObjectIDs] = ...,
|
56
|
-
) -> None: ...
|
57
|
-
def HasField(self, field_name: typing_extensions.Literal["value",b"value"]) -> builtins.bool: ...
|
58
|
-
def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ...
|
59
|
-
|
60
45
|
MESSAGE_IDS_FIELD_NUMBER: builtins.int
|
61
46
|
OBJECTS_TO_PUSH_FIELD_NUMBER: builtins.int
|
62
47
|
@property
|
63
48
|
def message_ids(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[typing.Text]: ...
|
64
49
|
@property
|
65
|
-
def objects_to_push(self) -> google.protobuf.internal.containers.
|
50
|
+
def objects_to_push(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[typing.Text]: ...
|
66
51
|
def __init__(self,
|
67
52
|
*,
|
68
53
|
message_ids: typing.Optional[typing.Iterable[typing.Text]] = ...,
|
69
|
-
objects_to_push: typing.Optional[typing.
|
54
|
+
objects_to_push: typing.Optional[typing.Iterable[typing.Text]] = ...,
|
70
55
|
) -> None: ...
|
71
56
|
def ClearField(self, field_name: typing_extensions.Literal["message_ids",b"message_ids","objects_to_push",b"objects_to_push"]) -> None: ...
|
72
57
|
global___PushAppMessagesResponse = PushAppMessagesResponse
|
flwr/proto/fleet_pb2.py
CHANGED
@@ -19,7 +19,7 @@ from flwr.proto import fab_pb2 as flwr_dot_proto_dot_fab__pb2
|
|
19
19
|
from flwr.proto import message_pb2 as flwr_dot_proto_dot_message__pb2
|
20
20
|
|
21
21
|
|
22
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x66lwr/proto/fleet.proto\x12\nflwr.proto\x1a\x1a\x66lwr/proto/heartbeat.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x14\x66lwr/proto/run.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x18\x66lwr/proto/message.proto\"/\n\x11\x43reateNodeRequest\x12\x1a\n\x12heartbeat_interval\x18\x01 \x01(\x01\"4\n\x12\x43reateNodeResponse\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"3\n\x11\x44\x65leteNodeRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"\x14\n\x12\x44\x65leteNodeResponse\"J\n\x13PullMessagesRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x13\n\x0bmessage_ids\x18\x02 \x03(\t\"\xa2\x01\n\x14PullMessagesResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12*\n\rmessages_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.Message\x12\x34\n\x14message_object_trees\x18\x03 \x03(\x0b\x32\x16.flwr.proto.ObjectTree\"\x97\x01\n\x13PushMessagesRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12*\n\rmessages_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.Message\x12\x34\n\x14message_object_trees\x18\x03 \x03(\x0b\x32\x16.flwr.proto.ObjectTree\"\
|
22
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x66lwr/proto/fleet.proto\x12\nflwr.proto\x1a\x1a\x66lwr/proto/heartbeat.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x14\x66lwr/proto/run.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x18\x66lwr/proto/message.proto\"/\n\x11\x43reateNodeRequest\x12\x1a\n\x12heartbeat_interval\x18\x01 \x01(\x01\"4\n\x12\x43reateNodeResponse\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"3\n\x11\x44\x65leteNodeRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"\x14\n\x12\x44\x65leteNodeResponse\"J\n\x13PullMessagesRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x13\n\x0bmessage_ids\x18\x02 \x03(\t\"\xa2\x01\n\x14PullMessagesResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12*\n\rmessages_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.Message\x12\x34\n\x14message_object_trees\x18\x03 \x03(\x0b\x32\x16.flwr.proto.ObjectTree\"\x97\x01\n\x13PushMessagesRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12*\n\rmessages_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.Message\x12\x34\n\x14message_object_trees\x18\x03 \x03(\x0b\x32\x16.flwr.proto.ObjectTree\"\xc9\x01\n\x14PushMessagesResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12>\n\x07results\x18\x02 \x03(\x0b\x32-.flwr.proto.PushMessagesResponse.ResultsEntry\x12\x17\n\x0fobjects_to_push\x18\x03 \x03(\t\x1a.\n\x0cResultsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\r:\x02\x38\x01\"\x1e\n\tReconnect\x12\x11\n\treconnect\x18\x01 \x01(\x04\x32\xca\x06\n\x05\x46leet\x12M\n\nCreateNode\x12\x1d.flwr.proto.CreateNodeRequest\x1a\x1e.flwr.proto.CreateNodeResponse\"\x00\x12M\n\nDeleteNode\x12\x1d.flwr.proto.DeleteNodeRequest\x1a\x1e.flwr.proto.DeleteNodeResponse\"\x00\x12\x62\n\x11SendNodeHeartbeat\x12$.flwr.proto.SendNodeHeartbeatRequest\x1a%.flwr.proto.SendNodeHeartbeatResponse\"\x00\x12S\n\x0cPullMessages\x12\x1f.flwr.proto.PullMessagesRequest\x1a .flwr.proto.PullMessagesResponse\"\x00\x12S\n\x0cPushMessages\x12\x1f.flwr.proto.PushMessagesRequest\x1a .flwr.proto.PushMessagesResponse\"\x00\x12\x41\n\x06GetRun\x12\x19.flwr.proto.GetRunRequest\x1a\x1a.flwr.proto.GetRunResponse\"\x00\x12\x41\n\x06GetFab\x12\x19.flwr.proto.GetFabRequest\x1a\x1a.flwr.proto.GetFabResponse\"\x00\x12M\n\nPushObject\x12\x1d.flwr.proto.PushObjectRequest\x1a\x1e.flwr.proto.PushObjectResponse\"\x00\x12M\n\nPullObject\x12\x1d.flwr.proto.PullObjectRequest\x1a\x1e.flwr.proto.PullObjectResponse\"\x00\x12q\n\x16\x43onfirmMessageReceived\x12).flwr.proto.ConfirmMessageReceivedRequest\x1a*.flwr.proto.ConfirmMessageReceivedResponse\"\x00\x62\x06proto3')
|
23
23
|
|
24
24
|
_globals = globals()
|
25
25
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
@@ -28,8 +28,6 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
|
28
28
|
DESCRIPTOR._options = None
|
29
29
|
_globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._options = None
|
30
30
|
_globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_options = b'8\001'
|
31
|
-
_globals['_PUSHMESSAGESRESPONSE_OBJECTSTOPUSHENTRY']._options = None
|
32
|
-
_globals['_PUSHMESSAGESRESPONSE_OBJECTSTOPUSHENTRY']._serialized_options = b'8\001'
|
33
31
|
_globals['_CREATENODEREQUEST']._serialized_start=159
|
34
32
|
_globals['_CREATENODEREQUEST']._serialized_end=206
|
35
33
|
_globals['_CREATENODERESPONSE']._serialized_start=208
|
@@ -45,13 +43,11 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
|
45
43
|
_globals['_PUSHMESSAGESREQUEST']._serialized_start=579
|
46
44
|
_globals['_PUSHMESSAGESREQUEST']._serialized_end=730
|
47
45
|
_globals['_PUSHMESSAGESRESPONSE']._serialized_start=733
|
48
|
-
_globals['_PUSHMESSAGESRESPONSE']._serialized_end=
|
49
|
-
_globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_start=
|
50
|
-
_globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_end=
|
51
|
-
_globals['
|
52
|
-
_globals['
|
53
|
-
_globals['
|
54
|
-
_globals['
|
55
|
-
_globals['_FLEET']._serialized_start=1099
|
56
|
-
_globals['_FLEET']._serialized_end=1941
|
46
|
+
_globals['_PUSHMESSAGESRESPONSE']._serialized_end=934
|
47
|
+
_globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_start=888
|
48
|
+
_globals['_PUSHMESSAGESRESPONSE_RESULTSENTRY']._serialized_end=934
|
49
|
+
_globals['_RECONNECT']._serialized_start=936
|
50
|
+
_globals['_RECONNECT']._serialized_end=966
|
51
|
+
_globals['_FLEET']._serialized_start=969
|
52
|
+
_globals['_FLEET']._serialized_end=1811
|
57
53
|
# @@protoc_insertion_point(module_scope)
|
flwr/proto/fleet_pb2.pyi
CHANGED
@@ -134,21 +134,6 @@ class PushMessagesResponse(google.protobuf.message.Message):
|
|
134
134
|
) -> None: ...
|
135
135
|
def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ...
|
136
136
|
|
137
|
-
class ObjectsToPushEntry(google.protobuf.message.Message):
|
138
|
-
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
139
|
-
KEY_FIELD_NUMBER: builtins.int
|
140
|
-
VALUE_FIELD_NUMBER: builtins.int
|
141
|
-
key: typing.Text
|
142
|
-
@property
|
143
|
-
def value(self) -> flwr.proto.message_pb2.ObjectIDs: ...
|
144
|
-
def __init__(self,
|
145
|
-
*,
|
146
|
-
key: typing.Text = ...,
|
147
|
-
value: typing.Optional[flwr.proto.message_pb2.ObjectIDs] = ...,
|
148
|
-
) -> None: ...
|
149
|
-
def HasField(self, field_name: typing_extensions.Literal["value",b"value"]) -> builtins.bool: ...
|
150
|
-
def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ...
|
151
|
-
|
152
137
|
RECONNECT_FIELD_NUMBER: builtins.int
|
153
138
|
RESULTS_FIELD_NUMBER: builtins.int
|
154
139
|
OBJECTS_TO_PUSH_FIELD_NUMBER: builtins.int
|
@@ -157,12 +142,12 @@ class PushMessagesResponse(google.protobuf.message.Message):
|
|
157
142
|
@property
|
158
143
|
def results(self) -> google.protobuf.internal.containers.ScalarMap[typing.Text, builtins.int]: ...
|
159
144
|
@property
|
160
|
-
def objects_to_push(self) -> google.protobuf.internal.containers.
|
145
|
+
def objects_to_push(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[typing.Text]: ...
|
161
146
|
def __init__(self,
|
162
147
|
*,
|
163
148
|
reconnect: typing.Optional[global___Reconnect] = ...,
|
164
149
|
results: typing.Optional[typing.Mapping[typing.Text, builtins.int]] = ...,
|
165
|
-
objects_to_push: typing.Optional[typing.
|
150
|
+
objects_to_push: typing.Optional[typing.Iterable[typing.Text]] = ...,
|
166
151
|
) -> None: ...
|
167
152
|
def HasField(self, field_name: typing_extensions.Literal["reconnect",b"reconnect"]) -> builtins.bool: ...
|
168
153
|
def ClearField(self, field_name: typing_extensions.Literal["objects_to_push",b"objects_to_push","reconnect",b"reconnect","results",b"results"]) -> None: ...
|
flwr/server/grid/grpc_grid.py
CHANGED
@@ -32,6 +32,7 @@ from flwr.common.constant import (
|
|
32
32
|
)
|
33
33
|
from flwr.common.grpc import create_channel, on_channel_state_change
|
34
34
|
from flwr.common.inflatable import (
|
35
|
+
InflatableObject,
|
35
36
|
get_all_nested_objects,
|
36
37
|
get_object_tree,
|
37
38
|
iterate_object_tree,
|
@@ -222,37 +223,38 @@ class GrpcGrid(Grid):
|
|
222
223
|
)
|
223
224
|
return [node.node_id for node in res.nodes]
|
224
225
|
|
225
|
-
def
|
226
|
-
"""Push
|
227
|
-
#
|
228
|
-
|
229
|
-
|
230
|
-
|
226
|
+
def _try_push_messages(self, run_id: int, messages: Iterable[Message]) -> list[str]:
|
227
|
+
"""Push all messages and its associated objects."""
|
228
|
+
# Prepare all Messages to be sent in a single request
|
229
|
+
proto_messages = []
|
230
|
+
object_trees = []
|
231
|
+
all_objects: dict[str, InflatableObject] = {}
|
232
|
+
for msg in messages:
|
233
|
+
proto_messages.append(message_to_proto(remove_content_from_message(msg)))
|
234
|
+
all_objects.update(get_all_nested_objects(msg))
|
235
|
+
object_trees.append(get_object_tree(msg))
|
236
|
+
del msg
|
231
237
|
|
232
238
|
# Call GrpcServerAppIoStub method
|
233
239
|
res: PushAppMessagesResponse = self._stub.PushMessages(
|
234
240
|
PushAppMessagesRequest(
|
235
|
-
messages_list=
|
241
|
+
messages_list=proto_messages,
|
236
242
|
run_id=run_id,
|
237
|
-
message_object_trees=
|
243
|
+
message_object_trees=object_trees,
|
238
244
|
)
|
239
245
|
)
|
240
246
|
|
241
247
|
# Push objects
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
),
|
253
|
-
object_ids_to_push=obj_ids_to_push,
|
254
|
-
)
|
255
|
-
return msg_id
|
248
|
+
push_objects(
|
249
|
+
all_objects,
|
250
|
+
push_object_fn=make_push_object_fn_protobuf(
|
251
|
+
push_object_protobuf=self._stub.PushObject,
|
252
|
+
node=self.node,
|
253
|
+
run_id=run_id,
|
254
|
+
),
|
255
|
+
object_ids_to_push=set(res.objects_to_push),
|
256
|
+
)
|
257
|
+
return cast(list[str], res.message_ids)
|
256
258
|
|
257
259
|
def push_messages(self, messages: Iterable[Message]) -> Iterable[str]:
|
258
260
|
"""Push messages to specified node IDs.
|
@@ -272,8 +274,8 @@ class GrpcGrid(Grid):
|
|
272
274
|
msg.metadata.__dict__["_message_id"] = msg.object_id
|
273
275
|
# Check message
|
274
276
|
self._check_message(msg)
|
275
|
-
|
276
|
-
|
277
|
+
# Try pushing messages and their objects
|
278
|
+
message_ids = self._try_push_messages(run_id, messages)
|
277
279
|
|
278
280
|
except grpc.RpcError as e:
|
279
281
|
if e.code() == grpc.StatusCode.RESOURCE_EXHAUSTED: # pylint: disable=E1101
|
flwr/server/serverapp/app.py
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
import argparse
|
19
|
+
import gc
|
19
20
|
from logging import DEBUG, ERROR, INFO
|
20
21
|
from pathlib import Path
|
21
22
|
from queue import Queue
|
@@ -115,6 +116,7 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915
|
|
115
116
|
run_status = None
|
116
117
|
heartbeat_sender = None
|
117
118
|
grid = None
|
119
|
+
context = None
|
118
120
|
while True:
|
119
121
|
|
120
122
|
try:
|
@@ -248,6 +250,10 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915
|
|
248
250
|
if grid:
|
249
251
|
grid.close()
|
250
252
|
|
253
|
+
# Clean up the Context
|
254
|
+
context = None
|
255
|
+
gc.collect()
|
256
|
+
|
251
257
|
event(
|
252
258
|
EventType.FLWR_SERVERAPP_RUN_LEAVE,
|
253
259
|
event_details={"run-id-hash": hash_run_id, "success": success},
|
flwr/simulation/app.py
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
import argparse
|
19
|
+
import gc
|
19
20
|
from logging import DEBUG, ERROR, INFO
|
20
21
|
from queue import Queue
|
21
22
|
from time import sleep
|
@@ -271,6 +272,13 @@ def run_simulation_process( # pylint: disable=R0914, disable=W0212, disable=R09
|
|
271
272
|
)
|
272
273
|
)
|
273
274
|
|
275
|
+
# Clean up the Context if it exists
|
276
|
+
try:
|
277
|
+
del updated_context
|
278
|
+
except NameError:
|
279
|
+
pass
|
280
|
+
gc.collect()
|
281
|
+
|
274
282
|
# Stop the loop if `flwr-simulation` is expected to process a single run
|
275
283
|
if run_once:
|
276
284
|
break
|
@@ -19,6 +19,7 @@ import argparse
|
|
19
19
|
import asyncio
|
20
20
|
import json
|
21
21
|
import logging
|
22
|
+
import platform
|
22
23
|
import sys
|
23
24
|
import threading
|
24
25
|
import traceback
|
@@ -63,6 +64,18 @@ def _replace_keys(d: Any, match: str, target: str) -> Any:
|
|
63
64
|
return d
|
64
65
|
|
65
66
|
|
67
|
+
def _check_ray_support(backend_name: str) -> None:
|
68
|
+
if backend_name.lower() == "ray":
|
69
|
+
if platform.system() == "Windows":
|
70
|
+
log(
|
71
|
+
WARNING,
|
72
|
+
"Ray support on Windows is experimental "
|
73
|
+
"and may not work as expected. "
|
74
|
+
"On Windows, Flower Simulations run best in WSL2: "
|
75
|
+
"https://learn.microsoft.com/en-us/windows/wsl/about",
|
76
|
+
)
|
77
|
+
|
78
|
+
|
66
79
|
# Entry point from CLI
|
67
80
|
# pylint: disable=too-many-locals
|
68
81
|
def run_simulation_from_cli() -> None:
|
@@ -82,6 +95,8 @@ def run_simulation_from_cli() -> None:
|
|
82
95
|
code_example='TF_FORCE_GPU_ALLOW_GROWTH="true" flower-simulation <...>',
|
83
96
|
)
|
84
97
|
|
98
|
+
_check_ray_support(args.backend)
|
99
|
+
|
85
100
|
# Load JSON config
|
86
101
|
backend_config_dict = json.loads(args.backend_config)
|
87
102
|
|
@@ -208,6 +223,8 @@ def run_simulation(
|
|
208
223
|
"\n\tflwr.simulation.run_simulationt(...)",
|
209
224
|
)
|
210
225
|
|
226
|
+
_check_ray_support(backend_name)
|
227
|
+
|
211
228
|
_ = _run_simulation(
|
212
229
|
num_supernodes=num_supernodes,
|
213
230
|
client_app=client_app,
|
@@ -19,30 +19,25 @@ from typing import Union
|
|
19
19
|
|
20
20
|
from flwr.proto.appio_pb2 import PushAppMessagesRequest # pylint: disable=E0611
|
21
21
|
from flwr.proto.fleet_pb2 import PushMessagesRequest # pylint: disable=E0611
|
22
|
-
from flwr.proto.message_pb2 import ObjectIDs # pylint: disable=E0611
|
23
22
|
|
24
23
|
from . import ObjectStore
|
25
24
|
|
26
25
|
|
27
26
|
def store_mapping_and_register_objects(
|
28
27
|
store: ObjectStore, request: Union[PushAppMessagesRequest, PushMessagesRequest]
|
29
|
-
) ->
|
28
|
+
) -> set[str]:
|
30
29
|
"""Store Message object to descendants mapping and preregister objects."""
|
31
30
|
if not request.messages_list:
|
32
|
-
return
|
33
|
-
|
34
|
-
objects_to_push: dict[str, ObjectIDs] = {}
|
35
|
-
|
31
|
+
return set()
|
32
|
+
objects_to_push: set[str] = set()
|
36
33
|
# Get run_id from the first message in the list
|
37
34
|
# All messages of a request should in the same run
|
38
35
|
run_id = request.messages_list[0].metadata.run_id
|
39
36
|
|
40
37
|
for object_tree in request.message_object_trees:
|
41
38
|
# Preregister
|
42
|
-
|
39
|
+
unavailable_obj_ids = store.preregister(run_id, object_tree)
|
43
40
|
# Keep track of objects that need to be pushed
|
44
|
-
objects_to_push
|
45
|
-
object_ids=object_ids_just_registered
|
46
|
-
)
|
41
|
+
objects_to_push |= set(unavailable_obj_ids)
|
47
42
|
|
48
43
|
return objects_to_push
|
@@ -278,9 +278,7 @@ def push_clientappoutputs(
|
|
278
278
|
del proto_message
|
279
279
|
|
280
280
|
# Retrieve the object IDs to push
|
281
|
-
object_ids_to_push = set(
|
282
|
-
push_msg_res.objects_to_push[object_tree.object_id].object_ids
|
283
|
-
)
|
281
|
+
object_ids_to_push = set(push_msg_res.objects_to_push)
|
284
282
|
|
285
283
|
# Push all objects
|
286
284
|
all_objects = get_all_nested_objects(message)
|
{flwr_nightly-1.20.0.dev20250725.dist-info → flwr_nightly-1.21.0.dev20250729.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.21.0.dev20250729
|
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.20.0.dev20250725.dist-info → flwr_nightly-1.21.0.dev20250729.dist-info}/RECORD
RENAMED
@@ -17,13 +17,13 @@ flwr/cli/login/__init__.py,sha256=B1SXKU3HCQhWfFDMJhlC7FOl8UsvH4mxysxeBnrfyUE,80
|
|
17
17
|
flwr/cli/login/login.py,sha256=pDkx5o4XBFBi7aGp_0Ys2FUMKmcWjzwWdoQRumXUsd8,4297
|
18
18
|
flwr/cli/ls.py,sha256=zBBO3Yom3DIYwIJg09OSxy347wiYffOviqh-c2U4A04,10939
|
19
19
|
flwr/cli/new/__init__.py,sha256=QA1E2QtzPvFCjLTUHnFnJbufuFiGyT_0Y53Wpbvg1F0,790
|
20
|
-
flwr/cli/new/new.py,sha256=
|
20
|
+
flwr/cli/new/new.py,sha256=Y8m4t8SmI_myr1tAcncHPE1_-y-dpn6BwKIVW1wj8xk,10071
|
21
21
|
flwr/cli/new/templates/__init__.py,sha256=FpjWCfIySU2DB4kh0HOXLAjlZNNFDTVU4w3HoE2TzcI,725
|
22
22
|
flwr/cli/new/templates/app/.gitignore.tpl,sha256=HZJcGQoxp7aUzaPg8Uqch3kNrIESwr9yjimDxJYgXVY,3104
|
23
23
|
flwr/cli/new/templates/app/LICENSE.tpl,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
24
24
|
flwr/cli/new/templates/app/README.baseline.md.tpl,sha256=oClo5eR0iLuPzBT7uS3ikhNRAnySz_lhkHFElixKyJM,9640
|
25
|
-
flwr/cli/new/templates/app/README.flowertune.md.tpl,sha256=
|
26
|
-
flwr/cli/new/templates/app/README.md.tpl,sha256=
|
25
|
+
flwr/cli/new/templates/app/README.flowertune.md.tpl,sha256=sZFKxfvWvCopsTA_z0w5mvwepP0ksVslr5R-43SRBAI,3492
|
26
|
+
flwr/cli/new/templates/app/README.md.tpl,sha256=uI8vUMCEGA1-WJ8-9EUFCnNtofWFkJNOxaR1V6r_Su4,1908
|
27
27
|
flwr/cli/new/templates/app/__init__.py,sha256=LbR0ksGiF566JcHM_H5m1Tc4-oYUEilWFlcXR-Oe6bI,729
|
28
28
|
flwr/cli/new/templates/app/code/__init__.baseline.py.tpl,sha256=YkHAgppUeD2BnBoGfVB6dEvBfjuIPGsU1gw4CiUi3qA,40
|
29
29
|
flwr/cli/new/templates/app/code/__init__.py,sha256=zXa2YU1swzHxOKDQbwlDMEwVPOUswVeosjkiXNMTgFo,736
|
@@ -61,19 +61,19 @@ flwr/cli/new/templates/app/code/task.pytorch.py.tpl,sha256=XlJqA4Ix_PloO_zJLhjiN
|
|
61
61
|
flwr/cli/new/templates/app/code/task.sklearn.py.tpl,sha256=vHdhtMp0FHxbYafXyhDT9aKmmmA0Jvpx5Oum1Yu9lWY,1850
|
62
62
|
flwr/cli/new/templates/app/code/task.tensorflow.py.tpl,sha256=SKXAZdgBnPpbAbJ90Rb7oQ5ilnopBx_j_JNFoUDeEAI,1732
|
63
63
|
flwr/cli/new/templates/app/code/utils.baseline.py.tpl,sha256=YkHAgppUeD2BnBoGfVB6dEvBfjuIPGsU1gw4CiUi3qA,40
|
64
|
-
flwr/cli/new/templates/app/pyproject.baseline.toml.tpl,sha256=
|
65
|
-
flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=
|
66
|
-
flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl,sha256=
|
67
|
-
flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=
|
68
|
-
flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=
|
69
|
-
flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=
|
70
|
-
flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=
|
71
|
-
flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=
|
72
|
-
flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=
|
64
|
+
flwr/cli/new/templates/app/pyproject.baseline.toml.tpl,sha256=o7WJPF7lH_azNTiUrvTtLfXKyAY3_xTzwvUpkp3suUI,3180
|
65
|
+
flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=zDNuDkvgVI7SNK7RLSlaFs2LhSW1-THDKNBJVw1_y78,2497
|
66
|
+
flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl,sha256=dsjlA0aS-U7xzB7YCYMOGVb7a0XJTB5bsemFzwUPkPg,2019
|
67
|
+
flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=BHGb2N57Xm2scO1mqDSNgK_aiI68mRh6u4Y9TLL5bZE,1471
|
68
|
+
flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=O6eN6Zqx2ieh-WbaiMYmxfhCrLKJjwymn_nhUDEOldM,1542
|
69
|
+
flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=oMTI8qXSgQsGlZextUpkWFvNOMlnWbzn2EocPSwDrtw,1409
|
70
|
+
flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=bu65oSrM85fP_H0-RlMS2i8XgL_8O5TfSHLW87lb30s,1508
|
71
|
+
flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=mAEPeBfGyrINgRuP6-nX_KJNTQjC4E5N1Nrcddxiffs,1484
|
72
|
+
flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=mK8wOWqoQOVxZG6-OVwA2ChmKxexC7TfQV0ztPE4BWY,1508
|
73
73
|
flwr/cli/run/__init__.py,sha256=RPyB7KbYTFl6YRiilCch6oezxrLQrl1kijV7BMGkLbA,790
|
74
74
|
flwr/cli/run/run.py,sha256=psmr215gkV0e0QtX9NFp7KUwKSA_ZwekdJmoL1zFyfw,8478
|
75
75
|
flwr/cli/stop.py,sha256=l8DcRkA---CESVJgc7iTHLWIBAPGxWIfoem8qSU3lZQ,4972
|
76
|
-
flwr/cli/utils.py,sha256=
|
76
|
+
flwr/cli/utils.py,sha256=Ca2jnbzqGsQWAHV_ztrGi32DpE-lf0gR90DOL76bR6c,12346
|
77
77
|
flwr/client/__init__.py,sha256=boIhKaK6I977zrILmoTutNx94x5jB0e6F1gnAjaRJnI,1250
|
78
78
|
flwr/client/client.py,sha256=3HAchxvknKG9jYbB7swNyDj-e5vUWDuMKoLvbT7jCVM,7895
|
79
79
|
flwr/client/client_app.py,sha256=zVhi-l3chAb06ozFsKwix3hU_RpOLjST13Ha50AVIPE,16918
|
@@ -84,7 +84,7 @@ flwr/client/grpc_adapter_client/__init__.py,sha256=RQWP5mFPROLHKgombiRvPXVWSoVrQ
|
|
84
84
|
flwr/client/grpc_adapter_client/connection.py,sha256=JGv02EjSOAG1E5BRUD4lwXc1LLiYJ0OhInvp31qx1cU,4404
|
85
85
|
flwr/client/grpc_rere_client/__init__.py,sha256=i7iS0Lt8B7q0E2L72e4F_YrKm6ClRKnd71PNA6PW2O0,752
|
86
86
|
flwr/client/grpc_rere_client/client_interceptor.py,sha256=zFaVHw6AxeNO-7eCKKb-RxrPa7zbM5Z-2-1Efc4adQY,2451
|
87
|
-
flwr/client/grpc_rere_client/connection.py,sha256=
|
87
|
+
flwr/client/grpc_rere_client/connection.py,sha256=3P7hyu79th3ZtMbBLgGLODuTzwiO4fV6HmtoekNMifE,13521
|
88
88
|
flwr/client/grpc_rere_client/grpc_adapter.py,sha256=dLGB5GriszAmtgvuFGuz_F7rIwpzLfDxhJ7T3Un-Ce0,6694
|
89
89
|
flwr/client/message_handler/__init__.py,sha256=0lyljDVqre3WljiZbPcwCCf8GiIaSVI_yo_ylEyPwSE,719
|
90
90
|
flwr/client/message_handler/message_handler.py,sha256=X9SXX6et97Lw9_DGD93HKsEBGNjXClcFgc_5aLK0oiU,6541
|
@@ -98,7 +98,7 @@ flwr/client/mod/secure_aggregation/secaggplus_mod.py,sha256=aKqjZCrikF73y3E-7h40
|
|
98
98
|
flwr/client/mod/utils.py,sha256=FUgD2TfcWqSeF6jUKZ4i6Ke56U4Nrv85AeVb93s6R9g,1201
|
99
99
|
flwr/client/numpy_client.py,sha256=Qq6ghsIAop2slKqAfgiI5NiHJ4LIxGmrik3Ror4_XVc,9581
|
100
100
|
flwr/client/rest_client/__init__.py,sha256=MBiuK62hj439m9rtwSwI184Hth6Tt5GbmpNMyl3zkZY,735
|
101
|
-
flwr/client/rest_client/connection.py,sha256=
|
101
|
+
flwr/client/rest_client/connection.py,sha256=NsENBljtBCd6ToIVmAhBbVC6kTmtuArxb2LnE6-lIGY,15656
|
102
102
|
flwr/client/run_info_store.py,sha256=MaJ3UQ-07hWtK67wnWu0zR29jrk0fsfgJX506dvEOfE,4042
|
103
103
|
flwr/client/typing.py,sha256=Jw3rawDzI_-ZDcRmEQcs5gZModY7oeQlEeltYsdOhlU,1048
|
104
104
|
flwr/clientapp/__init__.py,sha256=zGW4z49Ojzoi1hDiRC7kyhLjijUilc6fqHhtM_ATRVA,719
|
@@ -124,7 +124,7 @@ flwr/common/grpc.py,sha256=y70hUFvXkIf3l03xOhlb7qhS6W1UJZRSZqCdB0ir0v8,10381
|
|
124
124
|
flwr/common/heartbeat.py,sha256=SyEpNDnmJ0lni0cWO67rcoJVKasCLmkNHm3dKLeNrLU,5749
|
125
125
|
flwr/common/inflatable.py,sha256=GDL9oBKs16_yyVdlH6kBf493O5xll_h9V7XB5Mpx1Hc,9524
|
126
126
|
flwr/common/inflatable_protobuf_utils.py,sha256=JtRqp-fV47goDM2y8JRQ7AmwwjeGaWexwoMWLcxX5gE,5056
|
127
|
-
flwr/common/inflatable_utils.py,sha256=
|
127
|
+
flwr/common/inflatable_utils.py,sha256=OcNW8_CfHNuJhHekwRtnrDJZ4vbhujw2w7SG7Y0TuSI,18955
|
128
128
|
flwr/common/logger.py,sha256=JbRf6E2vQxXzpDBq1T8IDUJo_usu3gjWEBPQ6uKcmdg,13049
|
129
129
|
flwr/common/message.py,sha256=xAL7iZN5-n-xPQpgoSFvxNrzs8fmiiPfoU0DjNQEhRw,19953
|
130
130
|
flwr/common/object_ref.py,sha256=p3SfTeqo3Aj16SkB-vsnNn01zswOPdGNBitcbRnqmUk,9134
|
@@ -164,8 +164,8 @@ flwr/compat/server/__init__.py,sha256=TGVSoOTuf5T5JHUVrK5wuorQF7L6Wvdem8B4uufvMJ
|
|
164
164
|
flwr/compat/server/app.py,sha256=_lIe7Q4KUk-olq9PYBxIsO3UaOn6N92CWgWQ4hRcAZw,6490
|
165
165
|
flwr/compat/simulation/__init__.py,sha256=MApGa-tysDDw34iSdxZ7TWOKtGJM-z3i8fIRJa0qbZ8,750
|
166
166
|
flwr/proto/__init__.py,sha256=S3VbQzVwNC1P-3_9EdrXuwgptO-BVuuAe20Z_OUc1cQ,683
|
167
|
-
flwr/proto/appio_pb2.py,sha256=
|
168
|
-
flwr/proto/appio_pb2.pyi,sha256=
|
167
|
+
flwr/proto/appio_pb2.py,sha256=3Mwzq1d__hYMfhCEkERZ6XwCpcd328zB6jg-WH4IX8o,3326
|
168
|
+
flwr/proto/appio_pb2.pyi,sha256=PNPX6hu9J-pnVoFOULuQNjILR3xzdk0Q3cz10p2u2GU,6978
|
169
169
|
flwr/proto/appio_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
|
170
170
|
flwr/proto/appio_pb2_grpc.pyi,sha256=ff2TSiLVnG6IVQcTGzb2DIH3XRSoAvAo_RMcvbMFyc0,76
|
171
171
|
flwr/proto/clientappio_pb2.py,sha256=3b87t4_AFgeDopgpYhhOVBrdh1HG74W2HC-y0C0q_eY,3349
|
@@ -184,8 +184,8 @@ flwr/proto/fab_pb2.py,sha256=2Nu0WaWxDZ8TbutMtctjdcGM7OtXiyP4kmCgg5o7Jjw,1627
|
|
184
184
|
flwr/proto/fab_pb2.pyi,sha256=AMXpiDK0fo3nZWjxsC2E4otSaVjyQbU7iiWKrsSZavs,2395
|
185
185
|
flwr/proto/fab_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
|
186
186
|
flwr/proto/fab_pb2_grpc.pyi,sha256=ff2TSiLVnG6IVQcTGzb2DIH3XRSoAvAo_RMcvbMFyc0,76
|
187
|
-
flwr/proto/fleet_pb2.py,sha256=
|
188
|
-
flwr/proto/fleet_pb2.pyi,sha256=
|
187
|
+
flwr/proto/fleet_pb2.py,sha256=VZO6c1Vom-zfdRHgkuHROvsFdt4MOA8-R6p1TT-QXRo,5150
|
188
|
+
flwr/proto/fleet_pb2.pyi,sha256=0aKdrVaugxVI1ySWiy86aan1cjw9RJkDv1mTcMPyW4I,7797
|
189
189
|
flwr/proto/fleet_pb2_grpc.py,sha256=NmzrDYxyM3MQNh3vwYczQNuFimZz3prU6ke3E-fKk_g,17539
|
190
190
|
flwr/proto/fleet_pb2_grpc.pyi,sha256=PDERhzOrBCMAytTLS65Qck8A45bTIYni7Lotq6_I0sM,4721
|
191
191
|
flwr/proto/grpcadapter_pb2.py,sha256=PJ8DtfeV29g_y4Z3aNZlSZocLqSxeLmTsYCdOZDYCiE,1843
|
@@ -242,7 +242,7 @@ flwr/server/criterion.py,sha256=G4e-6B48Pc7d5rmGVUpIzNKb6UF88O3VmTRuUltgjzM,1061
|
|
242
242
|
flwr/server/fleet_event_log_interceptor.py,sha256=gtVPr2yQp3U2GnabIdFnuok18VerEcidKj1lKmDYGoY,3950
|
243
243
|
flwr/server/grid/__init__.py,sha256=aWZHezoR2UGMJISB_gPMCm2N_2GSbm97A3lAp7ruhRQ,888
|
244
244
|
flwr/server/grid/grid.py,sha256=naGCYt5J6dnmUvrcGkdNyKPe3MBd-0awGm1ALmgahqY,6625
|
245
|
-
flwr/server/grid/grpc_grid.py,sha256=
|
245
|
+
flwr/server/grid/grpc_grid.py,sha256=B7_F04Nh0EWX_xXptfCNxFLGS3enzWj2a4oMU0fyACs,15298
|
246
246
|
flwr/server/grid/inmemory_grid.py,sha256=RjejYT-d-hHuTs1KSs_5wvOdAWKLus8w5_UAcnGt4iw,6168
|
247
247
|
flwr/server/history.py,sha256=cCkFhBN4GoHsYYNk5GG1Y089eKJh2DH_ZJbYPwLaGyk,5026
|
248
248
|
flwr/server/run_serverapp.py,sha256=v0p6jXj2dFxlRUdoEeF1mnaFd9XRQi6dZCflPY6d3qI,2063
|
@@ -250,7 +250,7 @@ flwr/server/server.py,sha256=39m4FSN2T-uVA-no9nstN0eWW0co-IUUAIMmpd3V7Jc,17893
|
|
250
250
|
flwr/server/server_app.py,sha256=8uagoZX-3CY3tazPqkIV9jY-cN0YrRRrDmVe23o0AV0,9515
|
251
251
|
flwr/server/server_config.py,sha256=e_6ddh0riwOJsdNn2BFev344uMWfDk9n7dyjNpPgm1w,1349
|
252
252
|
flwr/server/serverapp/__init__.py,sha256=xcC0T_MQSMS9cicUzUUpMNCOsF2d8Oh_8jvnoBLuZvo,800
|
253
|
-
flwr/server/serverapp/app.py,sha256=
|
253
|
+
flwr/server/serverapp/app.py,sha256=k0wAdZiMAEz7WsUigxv038I5Eel3vXwuSqGGj2HtX3c,9524
|
254
254
|
flwr/server/serverapp_components.py,sha256=dfSqmrsVy3arKXpl3ZIBQWdV8rehfIms8aJooyzdmEM,2118
|
255
255
|
flwr/server/strategy/__init__.py,sha256=HhsSWMWaC7oCb2g7Kqn1MBKdrfvgi8VxACy9ZL706Q0,2836
|
256
256
|
flwr/server/strategy/aggregate.py,sha256=smlKKy-uFUuuFR12vlclucnwSQWRz78R79-Km4RWqbw,13978
|
@@ -322,13 +322,13 @@ flwr/server/workflow/secure_aggregation/secagg_workflow.py,sha256=b_pKk7gmbahwyj
|
|
322
322
|
flwr/server/workflow/secure_aggregation/secaggplus_workflow.py,sha256=DkayCsnlAya6Y2PZsueLgoUCMRtV-GbnW08RfWx_SXM,29460
|
323
323
|
flwr/serverapp/__init__.py,sha256=HPvC_ZvMS7GCM7ALVrG_Wwm4bSDr4DZETeC561v3T9w,719
|
324
324
|
flwr/simulation/__init__.py,sha256=Gg6OsP1Z-ixc3-xxzvl7j7rz2Fijy9rzyEPpxgAQCeM,1556
|
325
|
-
flwr/simulation/app.py,sha256=
|
325
|
+
flwr/simulation/app.py,sha256=hP7vP29qZOA_3dipzUdmkRXP25eS8RlF1MT-S09t3oc,10625
|
326
326
|
flwr/simulation/legacy_app.py,sha256=nMISQqW0otJL1-2Kfd94O6BLlGS2IEmEPKTM2WGKrIs,15861
|
327
327
|
flwr/simulation/ray_transport/__init__.py,sha256=ogd-0AMv2U-wBZ1r3sHWaDIOIrVqr88Xi6C8o4Dviy0,734
|
328
328
|
flwr/simulation/ray_transport/ray_actor.py,sha256=JN3xTqFIr5Z750k92CcA_uavzOHhSWDwE2WCaecvpks,19147
|
329
329
|
flwr/simulation/ray_transport/ray_client_proxy.py,sha256=2kVUDrJe2ViOJEuB0v_Xb3XUwK9yKNwDwrYQXTJDdco,7506
|
330
330
|
flwr/simulation/ray_transport/utils.py,sha256=KrexpWYCF-dAF3UHc9yDbPQWO-ahMT-BbD8nURLgiHk,2393
|
331
|
-
flwr/simulation/run_simulation.py,sha256
|
331
|
+
flwr/simulation/run_simulation.py,sha256=-sp3dNZcp7MCAH0BlmZpVcFAGvozRdYXRdDYcH_2Zxk,20838
|
332
332
|
flwr/simulation/simulationio_connection.py,sha256=mzS1C6EEREwQDPceDo30anAasmTDLb9qqV2tXlBhOUA,3494
|
333
333
|
flwr/supercore/__init__.py,sha256=pqkFoow_E6UhbBlhmoD1gmTH-33yJRhBsIZqxRPFZ7U,755
|
334
334
|
flwr/supercore/ffs/__init__.py,sha256=U3KXwG_SplEvchat27K0LYPoPHzh-cwwT_NHsGlYMt8,908
|
@@ -343,7 +343,7 @@ flwr/supercore/object_store/__init__.py,sha256=cdfPAmjINY6iOp8oI_LdcVh2simg469Mk
|
|
343
343
|
flwr/supercore/object_store/in_memory_object_store.py,sha256=CGY43syxDGrUPcdOzRH3hNrfeqmoTOY_wjo3qaAHuNk,9612
|
344
344
|
flwr/supercore/object_store/object_store.py,sha256=J-rI3X7ET-F6dqOyM-UfHKCCQtPJ_EnYW62H_1txts0,5252
|
345
345
|
flwr/supercore/object_store/object_store_factory.py,sha256=QVwE2ywi7vsj2iKfvWWnNw3N_I7Rz91NUt2RpcbJ7iM,1527
|
346
|
-
flwr/supercore/object_store/utils.py,sha256
|
346
|
+
flwr/supercore/object_store/utils.py,sha256=DcPbrb9PenloAPoQRiKiXX9DrDfpXcSyY0cZpgn4PeQ,1680
|
347
347
|
flwr/supercore/scheduler/__init__.py,sha256=E4GviiNJoZKz1dOao8ZGRHExsiM23GtOrkpMrTHy3n8,787
|
348
348
|
flwr/supercore/scheduler/plugin.py,sha256=kIv0JUrHP-ghrcGT-pbporL9A2mUz8PxASw6KgxCRv8,2460
|
349
349
|
flwr/supercore/utils.py,sha256=ebuHMbeA8eXisX0oMPqBK3hk7uVnIE_yiqWVz8YbkpQ,1324
|
@@ -367,14 +367,14 @@ flwr/supernode/nodestate/in_memory_nodestate.py,sha256=LF3AbaW0bcZHY5yKWwUJSU2RZ
|
|
367
367
|
flwr/supernode/nodestate/nodestate.py,sha256=kkGFxYnLIwT4-UmlPnf6HvAUpPey2urUNrweGybAIY4,6398
|
368
368
|
flwr/supernode/nodestate/nodestate_factory.py,sha256=UYTDCcwK_baHUmkzkJDxL0UEqvtTfOMlQRrROMCd0Xo,1430
|
369
369
|
flwr/supernode/runtime/__init__.py,sha256=JQdqd2EMTn-ORMeTvewYYh52ls0YKP68jrps1qioxu4,718
|
370
|
-
flwr/supernode/runtime/run_clientapp.py,sha256=
|
370
|
+
flwr/supernode/runtime/run_clientapp.py,sha256=0ysvN07xPDysFVViu2QyRR7BUI4Hv8ZcacmaADagvdQ,10701
|
371
371
|
flwr/supernode/scheduler/__init__.py,sha256=nQLi5ROVCMz8ii_WsZn4MAqKHXI40Eb3tq5-9zZbmpg,850
|
372
372
|
flwr/supernode/scheduler/simple_clientapp_scheduler_plugin.py,sha256=nnNuKhelrAEGCnWZ3aAkqJrhPu7xlVQ-oO1Eih9shTU,2000
|
373
373
|
flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca8gxdEo,717
|
374
374
|
flwr/supernode/servicer/clientappio/__init__.py,sha256=7Oy62Y_oijqF7Dxi6tpcUQyOpLc_QpIRZ83NvwmB0Yg,813
|
375
375
|
flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=ClPoKco7Tjj_cxRPhZlQSrOvcGa8sJwGs26LUNZnI3Y,10608
|
376
376
|
flwr/supernode/start_client_internal.py,sha256=VC7rV4QaX5Vk4Lw0DDodhwsKvGiHbr0mqrV0H77h1UI,21999
|
377
|
-
flwr_nightly-1.
|
378
|
-
flwr_nightly-1.
|
379
|
-
flwr_nightly-1.
|
380
|
-
flwr_nightly-1.
|
377
|
+
flwr_nightly-1.21.0.dev20250729.dist-info/METADATA,sha256=GHFlQXdDz-wfpA4HvkHCNFyBN-mRXY1F85QgYuKUE_c,15966
|
378
|
+
flwr_nightly-1.21.0.dev20250729.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
379
|
+
flwr_nightly-1.21.0.dev20250729.dist-info/entry_points.txt,sha256=jNpDXGBGgs21RqUxelF_jwGaxtqFwm-MQyfz-ZqSjrA,367
|
380
|
+
flwr_nightly-1.21.0.dev20250729.dist-info/RECORD,,
|
{flwr_nightly-1.20.0.dev20250725.dist-info → flwr_nightly-1.21.0.dev20250729.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|