flwr-nightly 1.10.0.dev20240715__py3-none-any.whl → 1.10.0.dev20240717__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of flwr-nightly might be problematic. Click here for more details.
- flwr/cli/build.py +16 -2
- flwr/cli/config_utils.py +23 -15
- flwr/cli/install.py +17 -1
- flwr/cli/new/new.py +4 -3
- flwr/cli/new/templates/app/code/flwr_tune/app.py.tpl +2 -2
- flwr/cli/new/templates/app/code/flwr_tune/server.py.tpl +1 -1
- flwr/cli/new/templates/app/code/server.hf.py.tpl +4 -1
- flwr/cli/new/templates/app/code/server.jax.py.tpl +4 -1
- flwr/cli/new/templates/app/code/server.mlx.py.tpl +4 -1
- flwr/cli/new/templates/app/code/server.numpy.py.tpl +4 -1
- flwr/cli/new/templates/app/code/server.pytorch.py.tpl +4 -1
- flwr/cli/new/templates/app/code/server.sklearn.py.tpl +4 -1
- flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +4 -1
- flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +6 -3
- flwr/cli/new/templates/app/pyproject.hf.toml.tpl +8 -5
- flwr/cli/new/templates/app/pyproject.jax.toml.tpl +8 -5
- flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +8 -5
- flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +8 -5
- flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +8 -5
- flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +8 -5
- flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +8 -5
- flwr/cli/run/run.py +29 -15
- flwr/client/app.py +3 -3
- flwr/client/node_state.py +17 -3
- flwr/client/supernode/app.py +4 -4
- flwr/common/config.py +28 -17
- flwr/server/run_serverapp.py +1 -1
- flwr/server/superlink/fleet/vce/vce_api.py +10 -3
- flwr/simulation/run_simulation.py +148 -14
- flwr/superexec/app.py +1 -1
- flwr/superexec/deployment.py +1 -9
- flwr/superexec/simulation.py +8 -18
- {flwr_nightly-1.10.0.dev20240715.dist-info → flwr_nightly-1.10.0.dev20240717.dist-info}/METADATA +2 -1
- {flwr_nightly-1.10.0.dev20240715.dist-info → flwr_nightly-1.10.0.dev20240717.dist-info}/RECORD +37 -37
- {flwr_nightly-1.10.0.dev20240715.dist-info → flwr_nightly-1.10.0.dev20240717.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.10.0.dev20240715.dist-info → flwr_nightly-1.10.0.dev20240717.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.10.0.dev20240715.dist-info → flwr_nightly-1.10.0.dev20240717.dist-info}/entry_points.txt +0 -0
flwr/cli/build.py
CHANGED
|
@@ -20,6 +20,7 @@ from pathlib import Path
|
|
|
20
20
|
from typing import Optional
|
|
21
21
|
|
|
22
22
|
import pathspec
|
|
23
|
+
import tomli_w
|
|
23
24
|
import typer
|
|
24
25
|
from typing_extensions import Annotated
|
|
25
26
|
|
|
@@ -85,7 +86,7 @@ def build(
|
|
|
85
86
|
|
|
86
87
|
# Set the name of the zip file
|
|
87
88
|
fab_filename = (
|
|
88
|
-
f"{conf['tool']['flwr']['publisher']}"
|
|
89
|
+
f"{conf['tool']['flwr']['app']['publisher']}"
|
|
89
90
|
f".{directory.name}"
|
|
90
91
|
f".{conf['project']['version'].replace('.', '-')}.fab"
|
|
91
92
|
)
|
|
@@ -93,15 +94,28 @@ def build(
|
|
|
93
94
|
|
|
94
95
|
allowed_extensions = {".py", ".toml", ".md"}
|
|
95
96
|
|
|
97
|
+
# Remove the 'federations' field from 'tool.flwr' if it exists
|
|
98
|
+
if (
|
|
99
|
+
"tool" in conf
|
|
100
|
+
and "flwr" in conf["tool"]
|
|
101
|
+
and "federations" in conf["tool"]["flwr"]
|
|
102
|
+
):
|
|
103
|
+
del conf["tool"]["flwr"]["federations"]
|
|
104
|
+
|
|
105
|
+
toml_contents = tomli_w.dumps(conf)
|
|
106
|
+
|
|
96
107
|
with zipfile.ZipFile(fab_filename, "w", zipfile.ZIP_DEFLATED) as fab_file:
|
|
108
|
+
fab_file.writestr("pyproject.toml", toml_contents)
|
|
109
|
+
|
|
110
|
+
# Continue with adding other files
|
|
97
111
|
for root, _, files in os.walk(directory, topdown=True):
|
|
98
|
-
# Filter directories and files based on .gitignore
|
|
99
112
|
files = [
|
|
100
113
|
f
|
|
101
114
|
for f in files
|
|
102
115
|
if not ignore_spec.match_file(Path(root) / f)
|
|
103
116
|
and f != fab_filename
|
|
104
117
|
and Path(f).suffix in allowed_extensions
|
|
118
|
+
and f != "pyproject.toml" # Exclude the original pyproject.toml
|
|
105
119
|
]
|
|
106
120
|
|
|
107
121
|
for file in files:
|
flwr/cli/config_utils.py
CHANGED
|
@@ -60,7 +60,7 @@ def get_fab_metadata(fab_file: Union[Path, bytes]) -> Tuple[str, str]:
|
|
|
60
60
|
|
|
61
61
|
return (
|
|
62
62
|
conf["project"]["version"],
|
|
63
|
-
f"{conf['tool']['flwr']['publisher']}/{conf['project']['name']}",
|
|
63
|
+
f"{conf['tool']['flwr']['app']['publisher']}/{conf['project']['name']}",
|
|
64
64
|
)
|
|
65
65
|
|
|
66
66
|
|
|
@@ -136,20 +136,28 @@ def validate_fields(config: Dict[str, Any]) -> Tuple[bool, List[str], List[str]]
|
|
|
136
136
|
if "authors" not in config["project"]:
|
|
137
137
|
warnings.append('Recommended property "authors" missing in [project]')
|
|
138
138
|
|
|
139
|
-
if
|
|
140
|
-
|
|
139
|
+
if (
|
|
140
|
+
"tool" not in config
|
|
141
|
+
or "flwr" not in config["tool"]
|
|
142
|
+
or "app" not in config["tool"]["flwr"]
|
|
143
|
+
):
|
|
144
|
+
errors.append("Missing [tool.flwr.app] section")
|
|
141
145
|
else:
|
|
142
|
-
if "publisher" not in config["tool"]["flwr"]:
|
|
143
|
-
errors.append('Property "publisher" missing in [tool.flwr]')
|
|
144
|
-
if "config" in config["tool"]["flwr"]:
|
|
145
|
-
_validate_run_config(config["tool"]["flwr"]["config"], errors)
|
|
146
|
-
if "components" not in config["tool"]["flwr"]:
|
|
147
|
-
errors.append("Missing [tool.flwr.components] section")
|
|
146
|
+
if "publisher" not in config["tool"]["flwr"]["app"]:
|
|
147
|
+
errors.append('Property "publisher" missing in [tool.flwr.app]')
|
|
148
|
+
if "config" in config["tool"]["flwr"]["app"]:
|
|
149
|
+
_validate_run_config(config["tool"]["flwr"]["app"]["config"], errors)
|
|
150
|
+
if "components" not in config["tool"]["flwr"]["app"]:
|
|
151
|
+
errors.append("Missing [tool.flwr.app.components] section")
|
|
148
152
|
else:
|
|
149
|
-
if "serverapp" not in config["tool"]["flwr"]["components"]:
|
|
150
|
-
errors.append(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
+
if "serverapp" not in config["tool"]["flwr"]["app"]["components"]:
|
|
154
|
+
errors.append(
|
|
155
|
+
'Property "serverapp" missing in [tool.flwr.app.components]'
|
|
156
|
+
)
|
|
157
|
+
if "clientapp" not in config["tool"]["flwr"]["app"]["components"]:
|
|
158
|
+
errors.append(
|
|
159
|
+
'Property "clientapp" missing in [tool.flwr.app.components]'
|
|
160
|
+
)
|
|
153
161
|
|
|
154
162
|
return len(errors) == 0, errors, warnings
|
|
155
163
|
|
|
@@ -165,14 +173,14 @@ def validate(
|
|
|
165
173
|
|
|
166
174
|
# Validate serverapp
|
|
167
175
|
is_valid, reason = object_ref.validate(
|
|
168
|
-
config["tool"]["flwr"]["components"]["serverapp"], check_module
|
|
176
|
+
config["tool"]["flwr"]["app"]["components"]["serverapp"], check_module
|
|
169
177
|
)
|
|
170
178
|
if not is_valid and isinstance(reason, str):
|
|
171
179
|
return False, [reason], []
|
|
172
180
|
|
|
173
181
|
# Validate clientapp
|
|
174
182
|
is_valid, reason = object_ref.validate(
|
|
175
|
-
config["tool"]["flwr"]["components"]["clientapp"], check_module
|
|
183
|
+
config["tool"]["flwr"]["app"]["components"]["clientapp"], check_module
|
|
176
184
|
)
|
|
177
185
|
|
|
178
186
|
if not is_valid and isinstance(reason, str):
|
flwr/cli/install.py
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
import shutil
|
|
19
|
+
import subprocess
|
|
19
20
|
import tempfile
|
|
20
21
|
import zipfile
|
|
21
22
|
from io import BytesIO
|
|
@@ -149,7 +150,7 @@ def validate_and_install(
|
|
|
149
150
|
)
|
|
150
151
|
raise typer.Exit(code=1)
|
|
151
152
|
|
|
152
|
-
publisher = config["tool"]["flwr"]["publisher"]
|
|
153
|
+
publisher = config["tool"]["flwr"]["app"]["publisher"]
|
|
153
154
|
project_name = config["project"]["name"]
|
|
154
155
|
version = config["project"]["version"]
|
|
155
156
|
|
|
@@ -192,6 +193,21 @@ def validate_and_install(
|
|
|
192
193
|
else:
|
|
193
194
|
shutil.copy2(item, install_dir / item.name)
|
|
194
195
|
|
|
196
|
+
try:
|
|
197
|
+
subprocess.run(
|
|
198
|
+
["pip", "install", "-e", install_dir, "--no-deps"],
|
|
199
|
+
capture_output=True,
|
|
200
|
+
text=True,
|
|
201
|
+
check=True,
|
|
202
|
+
)
|
|
203
|
+
except subprocess.CalledProcessError as e:
|
|
204
|
+
typer.secho(
|
|
205
|
+
f"❌ Failed to `pip install` package(s) from {install_dir}:\n{e.stderr}",
|
|
206
|
+
fg=typer.colors.RED,
|
|
207
|
+
bold=True,
|
|
208
|
+
)
|
|
209
|
+
raise typer.Exit(code=1) from e
|
|
210
|
+
|
|
195
211
|
typer.secho(
|
|
196
212
|
f"🎊 Successfully installed {project_name} to {install_dir}.",
|
|
197
213
|
fg=typer.colors.GREEN,
|
flwr/cli/new/new.py
CHANGED
|
@@ -136,6 +136,7 @@ def new(
|
|
|
136
136
|
|
|
137
137
|
framework_str = framework_str.lower()
|
|
138
138
|
|
|
139
|
+
llm_challenge_str = None
|
|
139
140
|
if framework_str == "flowertune":
|
|
140
141
|
llm_challenge_value = prompt_options(
|
|
141
142
|
"Please select LLM challenge by typing in the number",
|
|
@@ -171,7 +172,7 @@ def new(
|
|
|
171
172
|
}
|
|
172
173
|
|
|
173
174
|
# List of files to render
|
|
174
|
-
if
|
|
175
|
+
if llm_challenge_str:
|
|
175
176
|
files = {
|
|
176
177
|
".gitignore": {"template": "app/.gitignore.tpl"},
|
|
177
178
|
"pyproject.toml": {"template": f"app/pyproject.{framework_str}.toml.tpl"},
|
|
@@ -228,10 +229,10 @@ def new(
|
|
|
228
229
|
"README.md": {"template": "app/README.md.tpl"},
|
|
229
230
|
"pyproject.toml": {"template": f"app/pyproject.{framework_str}.toml.tpl"},
|
|
230
231
|
f"{import_name}/__init__.py": {"template": "app/code/__init__.py.tpl"},
|
|
231
|
-
f"{import_name}/
|
|
232
|
+
f"{import_name}/server_app.py": {
|
|
232
233
|
"template": f"app/code/server.{framework_str}.py.tpl"
|
|
233
234
|
},
|
|
234
|
-
f"{import_name}/
|
|
235
|
+
f"{import_name}/client_app.py": {
|
|
235
236
|
"template": f"app/code/client.{framework_str}.py.tpl"
|
|
236
237
|
},
|
|
237
238
|
}
|
|
@@ -12,10 +12,10 @@ from flwr.client import ClientApp
|
|
|
12
12
|
from flwr.common import ndarrays_to_parameters
|
|
13
13
|
from flwr.server import ServerApp, ServerConfig
|
|
14
14
|
|
|
15
|
-
from $import_name.
|
|
15
|
+
from $import_name.client_app import gen_client_fn, get_parameters
|
|
16
16
|
from $import_name.dataset import get_tokenizer_and_data_collator_and_propt_formatting
|
|
17
17
|
from $import_name.models import get_model
|
|
18
|
-
from $import_name.
|
|
18
|
+
from $import_name.server_app import fit_weighted_average, get_evaluate_fn, get_on_fit_config
|
|
19
19
|
|
|
20
20
|
# Avoid warnings
|
|
21
21
|
warnings.filterwarnings("ignore", category=UserWarning)
|
|
@@ -6,12 +6,15 @@ from flwr.server import ServerApp, ServerAppComponents, ServerConfig
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def server_fn(context: Context):
|
|
9
|
+
# Read from config
|
|
10
|
+
num_rounds = int(context.run_config["num-server-rounds"])
|
|
11
|
+
|
|
9
12
|
# Define strategy
|
|
10
13
|
strategy = FedAvg(
|
|
11
14
|
fraction_fit=1.0,
|
|
12
15
|
fraction_evaluate=1.0,
|
|
13
16
|
)
|
|
14
|
-
config = ServerConfig(num_rounds=
|
|
17
|
+
config = ServerConfig(num_rounds=num_rounds)
|
|
15
18
|
|
|
16
19
|
return ServerAppComponents(strategy=strategy, config=config)
|
|
17
20
|
|
|
@@ -6,9 +6,12 @@ from flwr.server import ServerApp, ServerAppComponents, ServerConfig
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def server_fn(context: Context):
|
|
9
|
+
# Read from config
|
|
10
|
+
num_rounds = int(context.run_config["num-server-rounds"])
|
|
11
|
+
|
|
9
12
|
# Define strategy
|
|
10
13
|
strategy = FedAvg()
|
|
11
|
-
config = ServerConfig(num_rounds=
|
|
14
|
+
config = ServerConfig(num_rounds=num_rounds)
|
|
12
15
|
|
|
13
16
|
return ServerAppComponents(strategy=strategy, config=config)
|
|
14
17
|
|
|
@@ -6,9 +6,12 @@ from flwr.server.strategy import FedAvg
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def server_fn(context: Context):
|
|
9
|
+
# Read from config
|
|
10
|
+
num_rounds = int(context.run_config["num-server-rounds"])
|
|
11
|
+
|
|
9
12
|
# Define strategy
|
|
10
13
|
strategy = FedAvg()
|
|
11
|
-
config = ServerConfig(num_rounds=
|
|
14
|
+
config = ServerConfig(num_rounds=num_rounds)
|
|
12
15
|
|
|
13
16
|
return ServerAppComponents(strategy=strategy, config=config)
|
|
14
17
|
|
|
@@ -6,9 +6,12 @@ from flwr.server.strategy import FedAvg
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def server_fn(context: Context):
|
|
9
|
+
# Read from config
|
|
10
|
+
num_rounds = int(context.run_config["num-server-rounds"])
|
|
11
|
+
|
|
9
12
|
# Define strategy
|
|
10
13
|
strategy = FedAvg()
|
|
11
|
-
config = ServerConfig(num_rounds=
|
|
14
|
+
config = ServerConfig(num_rounds=num_rounds)
|
|
12
15
|
|
|
13
16
|
return ServerAppComponents(strategy=strategy, config=config)
|
|
14
17
|
|
|
@@ -12,6 +12,9 @@ ndarrays = get_weights(Net())
|
|
|
12
12
|
parameters = ndarrays_to_parameters(ndarrays)
|
|
13
13
|
|
|
14
14
|
def server_fn(context: Context):
|
|
15
|
+
# Read from config
|
|
16
|
+
num_rounds = int(context.run_config["num-server-rounds"])
|
|
17
|
+
|
|
15
18
|
# Define strategy
|
|
16
19
|
strategy = FedAvg(
|
|
17
20
|
fraction_fit=1.0,
|
|
@@ -19,7 +22,7 @@ def server_fn(context: Context):
|
|
|
19
22
|
min_available_clients=2,
|
|
20
23
|
initial_parameters=parameters,
|
|
21
24
|
)
|
|
22
|
-
config = ServerConfig(num_rounds=
|
|
25
|
+
config = ServerConfig(num_rounds=num_rounds)
|
|
23
26
|
|
|
24
27
|
return ServerAppComponents(strategy=strategy, config=config)
|
|
25
28
|
|
|
@@ -6,13 +6,16 @@ from flwr.server.strategy import FedAvg
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def server_fn(context: Context):
|
|
9
|
+
# Read from config
|
|
10
|
+
num_rounds = int(context.run_config["num-server-rounds"])
|
|
11
|
+
|
|
9
12
|
# Define strategy
|
|
10
13
|
strategy = FedAvg(
|
|
11
14
|
fraction_fit=1.0,
|
|
12
15
|
fraction_evaluate=1.0,
|
|
13
16
|
min_available_clients=2,
|
|
14
17
|
)
|
|
15
|
-
config = ServerConfig(num_rounds=
|
|
18
|
+
config = ServerConfig(num_rounds=num_rounds)
|
|
16
19
|
|
|
17
20
|
return ServerAppComponents(strategy=strategy, config=config)
|
|
18
21
|
|
|
@@ -12,6 +12,9 @@ config = ServerConfig(num_rounds=3)
|
|
|
12
12
|
parameters = ndarrays_to_parameters(load_model().get_weights())
|
|
13
13
|
|
|
14
14
|
def server_fn(context: Context):
|
|
15
|
+
# Read from config
|
|
16
|
+
num_rounds = int(context.run_config["num-server-rounds"])
|
|
17
|
+
|
|
15
18
|
# Define strategy
|
|
16
19
|
strategy = strategy = FedAvg(
|
|
17
20
|
fraction_fit=1.0,
|
|
@@ -19,7 +22,7 @@ def server_fn(context: Context):
|
|
|
19
22
|
min_available_clients=2,
|
|
20
23
|
initial_parameters=parameters,
|
|
21
24
|
)
|
|
22
|
-
config = ServerConfig(num_rounds=
|
|
25
|
+
config = ServerConfig(num_rounds=num_rounds)
|
|
23
26
|
|
|
24
27
|
return ServerAppComponents(strategy=strategy, config=config)
|
|
25
28
|
|
|
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
name = "$package_name"
|
|
7
7
|
version = "1.0.0"
|
|
8
8
|
description = ""
|
|
9
|
-
license =
|
|
9
|
+
license = "Apache-2.0"
|
|
10
10
|
dependencies = [
|
|
11
11
|
"flwr[simulation]>=1.9.0,<2.0",
|
|
12
12
|
"flwr-datasets>=0.1.0,<1.0.0",
|
|
@@ -22,13 +22,16 @@ dependencies = [
|
|
|
22
22
|
[tool.hatch.build.targets.wheel]
|
|
23
23
|
packages = ["."]
|
|
24
24
|
|
|
25
|
-
[tool.flwr]
|
|
25
|
+
[tool.flwr.app]
|
|
26
26
|
publisher = "$username"
|
|
27
27
|
|
|
28
|
-
[tool.flwr.components]
|
|
28
|
+
[tool.flwr.app.components]
|
|
29
29
|
serverapp = "$import_name.app:server"
|
|
30
30
|
clientapp = "$import_name.app:client"
|
|
31
31
|
|
|
32
|
+
[tool.flwr.app.config]
|
|
33
|
+
num-server-rounds = "3"
|
|
34
|
+
|
|
32
35
|
[tool.flwr.federations]
|
|
33
36
|
default = "localhost"
|
|
34
37
|
|
|
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
name = "$package_name"
|
|
7
7
|
version = "1.0.0"
|
|
8
8
|
description = ""
|
|
9
|
-
license =
|
|
9
|
+
license = "Apache-2.0"
|
|
10
10
|
dependencies = [
|
|
11
11
|
"flwr[simulation]>=1.9.0,<2.0",
|
|
12
12
|
"flwr-datasets>=0.0.2,<1.0.0",
|
|
@@ -20,12 +20,15 @@ dependencies = [
|
|
|
20
20
|
[tool.hatch.build.targets.wheel]
|
|
21
21
|
packages = ["."]
|
|
22
22
|
|
|
23
|
-
[tool.flwr]
|
|
23
|
+
[tool.flwr.app]
|
|
24
24
|
publisher = "$username"
|
|
25
25
|
|
|
26
|
-
[tool.flwr.components]
|
|
27
|
-
serverapp = "$import_name.
|
|
28
|
-
clientapp = "$import_name.
|
|
26
|
+
[tool.flwr.app.components]
|
|
27
|
+
serverapp = "$import_name.server_app:app"
|
|
28
|
+
clientapp = "$import_name.client_app:app"
|
|
29
|
+
|
|
30
|
+
[tool.flwr.app.config]
|
|
31
|
+
num-server-rounds = "3"
|
|
29
32
|
|
|
30
33
|
[tool.flwr.federations]
|
|
31
34
|
default = "localhost"
|
|
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
name = "$package_name"
|
|
7
7
|
version = "1.0.0"
|
|
8
8
|
description = ""
|
|
9
|
-
license =
|
|
9
|
+
license = "Apache-2.0"
|
|
10
10
|
dependencies = [
|
|
11
11
|
"flwr[simulation]>=1.9.0,<2.0",
|
|
12
12
|
"jax==0.4.26",
|
|
@@ -17,12 +17,15 @@ dependencies = [
|
|
|
17
17
|
[tool.hatch.build.targets.wheel]
|
|
18
18
|
packages = ["."]
|
|
19
19
|
|
|
20
|
-
[tool.flwr]
|
|
20
|
+
[tool.flwr.app]
|
|
21
21
|
publisher = "$username"
|
|
22
22
|
|
|
23
|
-
[tool.flwr.components]
|
|
24
|
-
serverapp = "$import_name.
|
|
25
|
-
clientapp = "$import_name.
|
|
23
|
+
[tool.flwr.app.components]
|
|
24
|
+
serverapp = "$import_name.server_app:app"
|
|
25
|
+
clientapp = "$import_name.client_app:app"
|
|
26
|
+
|
|
27
|
+
[tool.flwr.app.config]
|
|
28
|
+
num-server-rounds = "3"
|
|
26
29
|
|
|
27
30
|
[tool.flwr.federations]
|
|
28
31
|
default = "localhost"
|
|
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
name = "$package_name"
|
|
7
7
|
version = "1.0.0"
|
|
8
8
|
description = ""
|
|
9
|
-
license =
|
|
9
|
+
license = "Apache-2.0"
|
|
10
10
|
dependencies = [
|
|
11
11
|
"flwr[simulation]>=1.9.0,<2.0",
|
|
12
12
|
"flwr-datasets[vision]>=0.0.2,<1.0.0",
|
|
@@ -17,12 +17,15 @@ dependencies = [
|
|
|
17
17
|
[tool.hatch.build.targets.wheel]
|
|
18
18
|
packages = ["."]
|
|
19
19
|
|
|
20
|
-
[tool.flwr]
|
|
20
|
+
[tool.flwr.app]
|
|
21
21
|
publisher = "$username"
|
|
22
22
|
|
|
23
|
-
[tool.flwr.components]
|
|
24
|
-
serverapp = "$import_name.
|
|
25
|
-
clientapp = "$import_name.
|
|
23
|
+
[tool.flwr.app.components]
|
|
24
|
+
serverapp = "$import_name.server_app:app"
|
|
25
|
+
clientapp = "$import_name.client_app:app"
|
|
26
|
+
|
|
27
|
+
[tool.flwr.app.config]
|
|
28
|
+
num-server-rounds = "3"
|
|
26
29
|
|
|
27
30
|
[tool.flwr.federations]
|
|
28
31
|
default = "localhost"
|
|
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
name = "$package_name"
|
|
7
7
|
version = "1.0.0"
|
|
8
8
|
description = ""
|
|
9
|
-
license =
|
|
9
|
+
license = "Apache-2.0"
|
|
10
10
|
dependencies = [
|
|
11
11
|
"flwr[simulation]>=1.9.0,<2.0",
|
|
12
12
|
"numpy>=1.21.0",
|
|
@@ -15,12 +15,15 @@ dependencies = [
|
|
|
15
15
|
[tool.hatch.build.targets.wheel]
|
|
16
16
|
packages = ["."]
|
|
17
17
|
|
|
18
|
-
[tool.flwr]
|
|
18
|
+
[tool.flwr.app]
|
|
19
19
|
publisher = "$username"
|
|
20
20
|
|
|
21
|
-
[tool.flwr.components]
|
|
22
|
-
serverapp = "$import_name.
|
|
23
|
-
clientapp = "$import_name.
|
|
21
|
+
[tool.flwr.app.components]
|
|
22
|
+
serverapp = "$import_name.server_app:app"
|
|
23
|
+
clientapp = "$import_name.client_app:app"
|
|
24
|
+
|
|
25
|
+
[tool.flwr.app.config]
|
|
26
|
+
num-server-rounds = "3"
|
|
24
27
|
|
|
25
28
|
[tool.flwr.federations]
|
|
26
29
|
default = "localhost"
|
|
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
name = "$package_name"
|
|
7
7
|
version = "1.0.0"
|
|
8
8
|
description = ""
|
|
9
|
-
license =
|
|
9
|
+
license = "Apache-2.0"
|
|
10
10
|
dependencies = [
|
|
11
11
|
"flwr[simulation]>=1.9.0,<2.0",
|
|
12
12
|
"flwr-datasets[vision]>=0.0.2,<1.0.0",
|
|
@@ -17,12 +17,15 @@ dependencies = [
|
|
|
17
17
|
[tool.hatch.build.targets.wheel]
|
|
18
18
|
packages = ["."]
|
|
19
19
|
|
|
20
|
-
[tool.flwr]
|
|
20
|
+
[tool.flwr.app]
|
|
21
21
|
publisher = "$username"
|
|
22
22
|
|
|
23
|
-
[tool.flwr.components]
|
|
24
|
-
serverapp = "$import_name.
|
|
25
|
-
clientapp = "$import_name.
|
|
23
|
+
[tool.flwr.app.components]
|
|
24
|
+
serverapp = "$import_name.server_app:app"
|
|
25
|
+
clientapp = "$import_name.client_app:app"
|
|
26
|
+
|
|
27
|
+
[tool.flwr.app.config]
|
|
28
|
+
num-server-rounds = "3"
|
|
26
29
|
|
|
27
30
|
[tool.flwr.federations]
|
|
28
31
|
default = "localhost"
|
|
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
name = "$package_name"
|
|
7
7
|
version = "1.0.0"
|
|
8
8
|
description = ""
|
|
9
|
-
license =
|
|
9
|
+
license = "Apache-2.0"
|
|
10
10
|
dependencies = [
|
|
11
11
|
"flwr[simulation]>=1.9.0,<2.0",
|
|
12
12
|
"flwr-datasets[vision]>=0.0.2,<1.0.0",
|
|
@@ -16,12 +16,15 @@ dependencies = [
|
|
|
16
16
|
[tool.hatch.build.targets.wheel]
|
|
17
17
|
packages = ["."]
|
|
18
18
|
|
|
19
|
-
[tool.flwr]
|
|
19
|
+
[tool.flwr.app]
|
|
20
20
|
publisher = "$username"
|
|
21
21
|
|
|
22
|
-
[tool.flwr.components]
|
|
23
|
-
serverapp = "$import_name.
|
|
24
|
-
clientapp = "$import_name.
|
|
22
|
+
[tool.flwr.app.components]
|
|
23
|
+
serverapp = "$import_name.server_app:app"
|
|
24
|
+
clientapp = "$import_name.client_app:app"
|
|
25
|
+
|
|
26
|
+
[tool.flwr.app.config]
|
|
27
|
+
num-server-rounds = "3"
|
|
25
28
|
|
|
26
29
|
[tool.flwr.federations]
|
|
27
30
|
default = "localhost"
|
|
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
name = "$package_name"
|
|
7
7
|
version = "1.0.0"
|
|
8
8
|
description = ""
|
|
9
|
-
license =
|
|
9
|
+
license = "Apache-2.0"
|
|
10
10
|
dependencies = [
|
|
11
11
|
"flwr[simulation]>=1.9.0,<2.0",
|
|
12
12
|
"flwr-datasets[vision]>=0.0.2,<1.0.0",
|
|
@@ -16,12 +16,15 @@ dependencies = [
|
|
|
16
16
|
[tool.hatch.build.targets.wheel]
|
|
17
17
|
packages = ["."]
|
|
18
18
|
|
|
19
|
-
[tool.flwr]
|
|
19
|
+
[tool.flwr.app]
|
|
20
20
|
publisher = "$username"
|
|
21
21
|
|
|
22
|
-
[tool.flwr.components]
|
|
23
|
-
serverapp = "$import_name.
|
|
24
|
-
clientapp = "$import_name.
|
|
22
|
+
[tool.flwr.app.components]
|
|
23
|
+
serverapp = "$import_name.server_app:app"
|
|
24
|
+
clientapp = "$import_name.client_app:app"
|
|
25
|
+
|
|
26
|
+
[tool.flwr.app.config]
|
|
27
|
+
num-server-rounds = "3"
|
|
25
28
|
|
|
26
29
|
[tool.flwr.federations]
|
|
27
30
|
default = "localhost"
|
flwr/cli/run/run.py
CHANGED
|
@@ -14,10 +14,11 @@
|
|
|
14
14
|
# ==============================================================================
|
|
15
15
|
"""Flower command line interface `run` command."""
|
|
16
16
|
|
|
17
|
+
import subprocess
|
|
17
18
|
import sys
|
|
18
19
|
from logging import DEBUG
|
|
19
20
|
from pathlib import Path
|
|
20
|
-
from typing import Any, Dict, Optional
|
|
21
|
+
from typing import Any, Dict, List, Optional
|
|
21
22
|
|
|
22
23
|
import typer
|
|
23
24
|
from typing_extensions import Annotated
|
|
@@ -29,7 +30,6 @@ from flwr.common.grpc import GRPC_MAX_MESSAGE_LENGTH, create_channel
|
|
|
29
30
|
from flwr.common.logger import log
|
|
30
31
|
from flwr.proto.exec_pb2 import StartRunRequest # pylint: disable=E0611
|
|
31
32
|
from flwr.proto.exec_pb2_grpc import ExecStub
|
|
32
|
-
from flwr.simulation.run_simulation import _run_simulation
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
# pylint: disable-next=too-many-locals
|
|
@@ -43,7 +43,7 @@ def run(
|
|
|
43
43
|
typer.Argument(help="Name of the federation to run the app on"),
|
|
44
44
|
] = None,
|
|
45
45
|
config_overrides: Annotated[
|
|
46
|
-
Optional[str],
|
|
46
|
+
Optional[List[str]],
|
|
47
47
|
typer.Option(
|
|
48
48
|
"--run-config",
|
|
49
49
|
"-c",
|
|
@@ -94,11 +94,13 @@ def run(
|
|
|
94
94
|
# Validate the federation exists in the configuration
|
|
95
95
|
federation = config["tool"]["flwr"]["federations"].get(federation_name)
|
|
96
96
|
if federation is None:
|
|
97
|
-
available_feds =
|
|
97
|
+
available_feds = {
|
|
98
|
+
fed for fed in config["tool"]["flwr"]["federations"] if fed != "default"
|
|
99
|
+
}
|
|
98
100
|
typer.secho(
|
|
99
101
|
f"❌ There is no `{federation_name}` federation declared in the "
|
|
100
102
|
"`pyproject.toml`.\n The following federations were found:\n\n"
|
|
101
|
-
"\n".join(available_feds)
|
|
103
|
+
+ "\n".join(available_feds),
|
|
102
104
|
fg=typer.colors.RED,
|
|
103
105
|
bold=True,
|
|
104
106
|
)
|
|
@@ -107,13 +109,13 @@ def run(
|
|
|
107
109
|
if "address" in federation:
|
|
108
110
|
_run_with_superexec(federation, directory, config_overrides)
|
|
109
111
|
else:
|
|
110
|
-
_run_without_superexec(
|
|
112
|
+
_run_without_superexec(directory, federation, federation_name, config_overrides)
|
|
111
113
|
|
|
112
114
|
|
|
113
115
|
def _run_with_superexec(
|
|
114
116
|
federation: Dict[str, str],
|
|
115
117
|
directory: Optional[Path],
|
|
116
|
-
config_overrides: Optional[str],
|
|
118
|
+
config_overrides: Optional[List[str]],
|
|
117
119
|
) -> None:
|
|
118
120
|
|
|
119
121
|
def on_channel_state_change(channel_connectivity: str) -> None:
|
|
@@ -169,11 +171,11 @@ def _run_with_superexec(
|
|
|
169
171
|
|
|
170
172
|
|
|
171
173
|
def _run_without_superexec(
|
|
172
|
-
|
|
174
|
+
app_path: Optional[Path],
|
|
175
|
+
federation: Dict[str, Any],
|
|
176
|
+
federation_name: str,
|
|
177
|
+
config_overrides: Optional[List[str]],
|
|
173
178
|
) -> None:
|
|
174
|
-
server_app_ref = config["tool"]["flwr"]["components"]["serverapp"]
|
|
175
|
-
client_app_ref = config["tool"]["flwr"]["components"]["clientapp"]
|
|
176
|
-
|
|
177
179
|
try:
|
|
178
180
|
num_supernodes = federation["options"]["num-supernodes"]
|
|
179
181
|
except KeyError as err:
|
|
@@ -188,8 +190,20 @@ def _run_without_superexec(
|
|
|
188
190
|
)
|
|
189
191
|
raise typer.Exit(code=1) from err
|
|
190
192
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
193
|
+
command = [
|
|
194
|
+
"flower-simulation",
|
|
195
|
+
"--app",
|
|
196
|
+
f"{app_path}",
|
|
197
|
+
"--num-supernodes",
|
|
198
|
+
f"{num_supernodes}",
|
|
199
|
+
]
|
|
200
|
+
|
|
201
|
+
if config_overrides:
|
|
202
|
+
command.extend(["--run-config", f"{config_overrides}"])
|
|
203
|
+
|
|
204
|
+
# Run the simulation
|
|
205
|
+
subprocess.run(
|
|
206
|
+
command,
|
|
207
|
+
check=True,
|
|
208
|
+
text=True,
|
|
195
209
|
)
|