flwr-nightly 1.11.0.dev20240724__py3-none-any.whl → 1.11.0.dev20240811__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 +22 -20
- flwr/cli/config_utils.py +27 -8
- flwr/cli/new/new.py +23 -22
- flwr/cli/new/templates/app/README.md.tpl +1 -1
- flwr/cli/new/templates/app/code/__init__.py.tpl +1 -1
- flwr/cli/new/templates/app/code/client.huggingface.py.tpl +1 -1
- flwr/cli/new/templates/app/code/client.jax.py.tpl +1 -1
- flwr/cli/new/templates/app/code/client.mlx.py.tpl +1 -1
- flwr/cli/new/templates/app/code/client.numpy.py.tpl +1 -1
- flwr/cli/new/templates/app/code/client.pytorch.py.tpl +9 -8
- flwr/cli/new/templates/app/code/client.sklearn.py.tpl +1 -1
- flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +5 -8
- flwr/cli/new/templates/app/code/server.huggingface.py.tpl +1 -1
- flwr/cli/new/templates/app/code/server.jax.py.tpl +1 -1
- flwr/cli/new/templates/app/code/server.mlx.py.tpl +1 -1
- flwr/cli/new/templates/app/code/server.numpy.py.tpl +1 -1
- flwr/cli/new/templates/app/code/server.pytorch.py.tpl +7 -6
- flwr/cli/new/templates/app/code/server.sklearn.py.tpl +1 -1
- flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +4 -5
- flwr/cli/new/templates/app/code/task.huggingface.py.tpl +1 -1
- flwr/cli/new/templates/app/code/task.jax.py.tpl +2 -2
- flwr/cli/new/templates/app/code/task.mlx.py.tpl +2 -1
- flwr/cli/new/templates/app/code/task.pytorch.py.tpl +14 -20
- flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +16 -4
- flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +2 -2
- flwr/cli/new/templates/app/pyproject.jax.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +3 -3
- flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +3 -2
- flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +2 -2
- flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +2 -2
- flwr/cli/run/run.py +15 -12
- flwr/client/grpc_rere_client/grpc_adapter.py +7 -0
- flwr/client/supernode/app.py +36 -28
- flwr/common/config.py +30 -0
- flwr/common/typing.py +8 -0
- flwr/proto/driver_pb2.py +22 -21
- flwr/proto/driver_pb2.pyi +7 -1
- flwr/proto/driver_pb2_grpc.py +35 -0
- flwr/proto/driver_pb2_grpc.pyi +14 -0
- flwr/proto/fab_pb2.py +6 -6
- flwr/proto/fab_pb2.pyi +8 -8
- flwr/proto/fleet_pb2.py +28 -27
- flwr/proto/fleet_pb2_grpc.py +35 -0
- flwr/proto/fleet_pb2_grpc.pyi +14 -0
- flwr/proto/run_pb2.py +8 -8
- flwr/proto/run_pb2.pyi +4 -1
- flwr/server/run_serverapp.py +28 -46
- flwr/server/superlink/driver/driver_servicer.py +7 -0
- flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +7 -0
- flwr/server/superlink/fleet/vce/backend/backend.py +1 -1
- flwr/server/superlink/fleet/vce/backend/raybackend.py +4 -35
- flwr/server/superlink/fleet/vce/vce_api.py +3 -3
- flwr/superexec/simulation.py +15 -3
- {flwr_nightly-1.11.0.dev20240724.dist-info → flwr_nightly-1.11.0.dev20240811.dist-info}/METADATA +2 -2
- {flwr_nightly-1.11.0.dev20240724.dist-info → flwr_nightly-1.11.0.dev20240811.dist-info}/RECORD +59 -59
- {flwr_nightly-1.11.0.dev20240724.dist-info → flwr_nightly-1.11.0.dev20240811.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.11.0.dev20240724.dist-info → flwr_nightly-1.11.0.dev20240811.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.11.0.dev20240724.dist-info → flwr_nightly-1.11.0.dev20240811.dist-info}/entry_points.txt +0 -0
|
@@ -8,9 +8,9 @@ version = "1.0.0"
|
|
|
8
8
|
description = ""
|
|
9
9
|
license = "Apache-2.0"
|
|
10
10
|
dependencies = [
|
|
11
|
-
"flwr[simulation]>=1.
|
|
12
|
-
"flwr-datasets[vision]>=0.
|
|
13
|
-
"mlx==0.
|
|
11
|
+
"flwr[simulation]>=1.10.0",
|
|
12
|
+
"flwr-datasets[vision]>=0.3.0",
|
|
13
|
+
"mlx==0.16.1",
|
|
14
14
|
"numpy==1.24.4",
|
|
15
15
|
]
|
|
16
16
|
|
|
@@ -8,8 +8,8 @@ version = "1.0.0"
|
|
|
8
8
|
description = ""
|
|
9
9
|
license = "Apache-2.0"
|
|
10
10
|
dependencies = [
|
|
11
|
-
"flwr[simulation]>=1.
|
|
12
|
-
"flwr-datasets[vision]>=0.
|
|
11
|
+
"flwr[simulation]>=1.10.0",
|
|
12
|
+
"flwr-datasets[vision]>=0.3.0",
|
|
13
13
|
"torch==2.2.1",
|
|
14
14
|
"torchvision==0.17.1",
|
|
15
15
|
]
|
|
@@ -26,6 +26,7 @@ clientapp = "$import_name.client_app:app"
|
|
|
26
26
|
|
|
27
27
|
[tool.flwr.app.config]
|
|
28
28
|
num-server-rounds = 3
|
|
29
|
+
fraction-fit = 0.5
|
|
29
30
|
local-epochs = 1
|
|
30
31
|
|
|
31
32
|
[tool.flwr.federations]
|
flwr/cli/run/run.py
CHANGED
|
@@ -35,9 +35,9 @@ from flwr.proto.exec_pb2_grpc import ExecStub
|
|
|
35
35
|
|
|
36
36
|
# pylint: disable-next=too-many-locals
|
|
37
37
|
def run(
|
|
38
|
-
|
|
38
|
+
app: Annotated[
|
|
39
39
|
Path,
|
|
40
|
-
typer.Argument(help="Path of the Flower
|
|
40
|
+
typer.Argument(help="Path of the Flower App to run."),
|
|
41
41
|
] = Path("."),
|
|
42
42
|
federation: Annotated[
|
|
43
43
|
Optional[str],
|
|
@@ -55,10 +55,10 @@ def run(
|
|
|
55
55
|
),
|
|
56
56
|
] = None,
|
|
57
57
|
) -> None:
|
|
58
|
-
"""Run Flower
|
|
58
|
+
"""Run Flower App."""
|
|
59
59
|
typer.secho("Loading project configuration... ", fg=typer.colors.BLUE)
|
|
60
60
|
|
|
61
|
-
pyproject_path =
|
|
61
|
+
pyproject_path = app / "pyproject.toml" if app else None
|
|
62
62
|
config, errors, warnings = load_and_validate(path=pyproject_path)
|
|
63
63
|
|
|
64
64
|
if config is None:
|
|
@@ -109,14 +109,14 @@ def run(
|
|
|
109
109
|
raise typer.Exit(code=1)
|
|
110
110
|
|
|
111
111
|
if "address" in federation_config:
|
|
112
|
-
_run_with_superexec(
|
|
112
|
+
_run_with_superexec(app, federation_config, config_overrides)
|
|
113
113
|
else:
|
|
114
|
-
_run_without_superexec(
|
|
114
|
+
_run_without_superexec(app, federation_config, config_overrides, federation)
|
|
115
115
|
|
|
116
116
|
|
|
117
117
|
def _run_with_superexec(
|
|
118
|
+
app: Optional[Path],
|
|
118
119
|
federation_config: Dict[str, Any],
|
|
119
|
-
app_dir: Optional[Path],
|
|
120
120
|
config_overrides: Optional[List[str]],
|
|
121
121
|
) -> None:
|
|
122
122
|
|
|
@@ -162,10 +162,10 @@ def _run_with_superexec(
|
|
|
162
162
|
channel.subscribe(on_channel_state_change)
|
|
163
163
|
stub = ExecStub(channel)
|
|
164
164
|
|
|
165
|
-
fab_path = build(
|
|
165
|
+
fab_path = Path(build(app))
|
|
166
166
|
|
|
167
167
|
req = StartRunRequest(
|
|
168
|
-
fab_file=
|
|
168
|
+
fab_file=fab_path.read_bytes(),
|
|
169
169
|
override_config=user_config_to_proto(
|
|
170
170
|
parse_config_args(config_overrides, separator=",")
|
|
171
171
|
),
|
|
@@ -174,14 +174,17 @@ def _run_with_superexec(
|
|
|
174
174
|
),
|
|
175
175
|
)
|
|
176
176
|
res = stub.StartRun(req)
|
|
177
|
+
|
|
178
|
+
# Delete FAB file once it has been sent to the SuperExec
|
|
179
|
+
fab_path.unlink()
|
|
177
180
|
typer.secho(f"🎊 Successfully started run {res.run_id}", fg=typer.colors.GREEN)
|
|
178
181
|
|
|
179
182
|
|
|
180
183
|
def _run_without_superexec(
|
|
181
|
-
|
|
184
|
+
app: Optional[Path],
|
|
182
185
|
federation_config: Dict[str, Any],
|
|
183
|
-
federation: str,
|
|
184
186
|
config_overrides: Optional[List[str]],
|
|
187
|
+
federation: str,
|
|
185
188
|
) -> None:
|
|
186
189
|
try:
|
|
187
190
|
num_supernodes = federation_config["options"]["num-supernodes"]
|
|
@@ -200,7 +203,7 @@ def _run_without_superexec(
|
|
|
200
203
|
command = [
|
|
201
204
|
"flower-simulation",
|
|
202
205
|
"--app",
|
|
203
|
-
f"{
|
|
206
|
+
f"{app}",
|
|
204
207
|
"--num-supernodes",
|
|
205
208
|
f"{num_supernodes}",
|
|
206
209
|
]
|
|
@@ -28,6 +28,7 @@ from flwr.common.constant import (
|
|
|
28
28
|
GRPC_ADAPTER_METADATA_SHOULD_EXIT_KEY,
|
|
29
29
|
)
|
|
30
30
|
from flwr.common.version import package_version
|
|
31
|
+
from flwr.proto.fab_pb2 import GetFabRequest, GetFabResponse # pylint: disable=E0611
|
|
31
32
|
from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
|
|
32
33
|
CreateNodeRequest,
|
|
33
34
|
CreateNodeResponse,
|
|
@@ -131,3 +132,9 @@ class GrpcAdapter:
|
|
|
131
132
|
) -> GetRunResponse:
|
|
132
133
|
"""."""
|
|
133
134
|
return self._send_and_receive(request, GetRunResponse, **kwargs)
|
|
135
|
+
|
|
136
|
+
def GetFab( # pylint: disable=C0103
|
|
137
|
+
self, request: GetFabRequest, **kwargs: Any
|
|
138
|
+
) -> GetFabResponse:
|
|
139
|
+
"""."""
|
|
140
|
+
return self._send_and_receive(request, GetFabResponse, **kwargs)
|
flwr/client/supernode/app.py
CHANGED
|
@@ -31,6 +31,7 @@ from flwr.client.client_app import ClientApp, LoadClientAppError
|
|
|
31
31
|
from flwr.common import EventType, event
|
|
32
32
|
from flwr.common.config import (
|
|
33
33
|
get_flwr_dir,
|
|
34
|
+
get_metadata_from_config,
|
|
34
35
|
get_project_config,
|
|
35
36
|
get_project_dir,
|
|
36
37
|
parse_config_args,
|
|
@@ -61,8 +62,8 @@ def run_supernode() -> None:
|
|
|
61
62
|
|
|
62
63
|
root_certificates = _get_certificates(args)
|
|
63
64
|
load_fn = _get_load_client_app_fn(
|
|
64
|
-
default_app_ref=
|
|
65
|
-
|
|
65
|
+
default_app_ref="",
|
|
66
|
+
app_path=args.app,
|
|
66
67
|
flwr_dir=args.flwr_dir,
|
|
67
68
|
multi_app=True,
|
|
68
69
|
)
|
|
@@ -100,7 +101,7 @@ def run_client_app() -> None:
|
|
|
100
101
|
root_certificates = _get_certificates(args)
|
|
101
102
|
load_fn = _get_load_client_app_fn(
|
|
102
103
|
default_app_ref=getattr(args, "client-app"),
|
|
103
|
-
|
|
104
|
+
app_path=args.dir,
|
|
104
105
|
multi_app=False,
|
|
105
106
|
)
|
|
106
107
|
authentication_keys = _try_setup_client_authentication(args)
|
|
@@ -176,7 +177,7 @@ def _get_certificates(args: argparse.Namespace) -> Optional[bytes]:
|
|
|
176
177
|
|
|
177
178
|
def _get_load_client_app_fn(
|
|
178
179
|
default_app_ref: str,
|
|
179
|
-
|
|
180
|
+
app_path: Optional[str],
|
|
180
181
|
multi_app: bool,
|
|
181
182
|
flwr_dir: Optional[str] = None,
|
|
182
183
|
) -> Callable[[str, str], ClientApp]:
|
|
@@ -196,34 +197,39 @@ def _get_load_client_app_fn(
|
|
|
196
197
|
default_app_ref,
|
|
197
198
|
)
|
|
198
199
|
|
|
199
|
-
valid, error_msg = validate(default_app_ref, project_dir=
|
|
200
|
+
valid, error_msg = validate(default_app_ref, project_dir=app_path)
|
|
200
201
|
if not valid and error_msg:
|
|
201
202
|
raise LoadClientAppError(error_msg) from None
|
|
202
203
|
|
|
203
204
|
def _load(fab_id: str, fab_version: str) -> ClientApp:
|
|
204
|
-
|
|
205
|
+
runtime_app_dir = Path(app_path if app_path else "").absolute()
|
|
205
206
|
# If multi-app feature is disabled
|
|
206
207
|
if not multi_app:
|
|
207
208
|
# Set app reference
|
|
208
209
|
client_app_ref = default_app_ref
|
|
209
|
-
# If multi-app feature is enabled but
|
|
210
|
-
elif
|
|
211
|
-
|
|
210
|
+
# If multi-app feature is enabled but app directory is provided
|
|
211
|
+
elif app_path is not None:
|
|
212
|
+
config = get_project_config(runtime_app_dir)
|
|
213
|
+
this_fab_version, this_fab_id = get_metadata_from_config(config)
|
|
214
|
+
|
|
215
|
+
if this_fab_version != fab_version or this_fab_id != fab_id:
|
|
212
216
|
raise LoadClientAppError(
|
|
213
|
-
"
|
|
217
|
+
f"FAB ID or version mismatch: Expected FAB ID '{this_fab_id}' and "
|
|
218
|
+
f"FAB version '{this_fab_version}', but received FAB ID '{fab_id}' "
|
|
219
|
+
f"and FAB version '{fab_version}'.",
|
|
214
220
|
) from None
|
|
215
221
|
|
|
216
|
-
log(WARN, "FAB ID is not provided; the default ClientApp will be loaded.")
|
|
222
|
+
# log(WARN, "FAB ID is not provided; the default ClientApp will be loaded.")
|
|
217
223
|
|
|
218
224
|
# Set app reference
|
|
219
|
-
client_app_ref =
|
|
225
|
+
client_app_ref = config["tool"]["flwr"]["app"]["components"]["clientapp"]
|
|
220
226
|
# If multi-app feature is enabled
|
|
221
227
|
else:
|
|
222
228
|
try:
|
|
223
|
-
|
|
229
|
+
runtime_app_dir = get_project_dir(
|
|
224
230
|
fab_id, fab_version, get_flwr_dir(flwr_dir)
|
|
225
231
|
)
|
|
226
|
-
config = get_project_config(
|
|
232
|
+
config = get_project_config(runtime_app_dir)
|
|
227
233
|
except Exception as e:
|
|
228
234
|
raise LoadClientAppError("Failed to load ClientApp") from e
|
|
229
235
|
|
|
@@ -236,7 +242,7 @@ def _get_load_client_app_fn(
|
|
|
236
242
|
"Loading ClientApp `%s`",
|
|
237
243
|
client_app_ref,
|
|
238
244
|
)
|
|
239
|
-
client_app = load_app(client_app_ref, LoadClientAppError,
|
|
245
|
+
client_app = load_app(client_app_ref, LoadClientAppError, runtime_app_dir)
|
|
240
246
|
|
|
241
247
|
if not isinstance(client_app, ClientApp):
|
|
242
248
|
raise LoadClientAppError(
|
|
@@ -255,13 +261,15 @@ def _parse_args_run_supernode() -> argparse.ArgumentParser:
|
|
|
255
261
|
)
|
|
256
262
|
|
|
257
263
|
parser.add_argument(
|
|
258
|
-
"
|
|
264
|
+
"app",
|
|
259
265
|
nargs="?",
|
|
260
|
-
default=
|
|
261
|
-
help="
|
|
262
|
-
"
|
|
263
|
-
"
|
|
264
|
-
"
|
|
266
|
+
default=None,
|
|
267
|
+
help="Specify the path of the Flower App to load and run the `ClientApp`. "
|
|
268
|
+
"The `pyproject.toml` file must be located in the root of this path. "
|
|
269
|
+
"When this argument is provided, the SuperNode will exclusively respond to "
|
|
270
|
+
"messages from the corresponding `ServerApp` by matching the FAB ID and FAB "
|
|
271
|
+
"version. An error will be raised if a message is received from any other "
|
|
272
|
+
"`ServerApp`.",
|
|
265
273
|
)
|
|
266
274
|
_parse_args_common(parser)
|
|
267
275
|
parser.add_argument(
|
|
@@ -290,6 +298,13 @@ def _parse_args_run_client_app() -> argparse.ArgumentParser:
|
|
|
290
298
|
help="For example: `client:app` or `project.package.module:wrapper.app`",
|
|
291
299
|
)
|
|
292
300
|
_parse_args_common(parser=parser)
|
|
301
|
+
parser.add_argument(
|
|
302
|
+
"--dir",
|
|
303
|
+
default="",
|
|
304
|
+
help="Add specified directory to the PYTHONPATH and load Flower "
|
|
305
|
+
"app from there."
|
|
306
|
+
" Default: current working directory.",
|
|
307
|
+
)
|
|
293
308
|
|
|
294
309
|
return parser
|
|
295
310
|
|
|
@@ -357,13 +372,6 @@ def _parse_args_common(parser: argparse.ArgumentParser) -> None:
|
|
|
357
372
|
"connect to the SuperLink in case of connection error. By default, it"
|
|
358
373
|
"is set to None, meaning there is no limit to the total time.",
|
|
359
374
|
)
|
|
360
|
-
parser.add_argument(
|
|
361
|
-
"--dir",
|
|
362
|
-
default="",
|
|
363
|
-
help="Add specified directory to the PYTHONPATH and load Flower "
|
|
364
|
-
"app from there."
|
|
365
|
-
" Default: current working directory.",
|
|
366
|
-
)
|
|
367
375
|
parser.add_argument(
|
|
368
376
|
"--auth-supernode-private-key",
|
|
369
377
|
type=str,
|
flwr/common/config.py
CHANGED
|
@@ -105,11 +105,16 @@ def get_fused_config(run: Run, flwr_dir: Optional[Path]) -> UserConfig:
|
|
|
105
105
|
Get the config using the fab_id and the fab_version, remove the nesting by adding
|
|
106
106
|
the nested keys as prefixes separated by dots, and fuse it with the override dict.
|
|
107
107
|
"""
|
|
108
|
+
# Return empty dict if fab_id or fab_version is empty
|
|
108
109
|
if not run.fab_id or not run.fab_version:
|
|
109
110
|
return {}
|
|
110
111
|
|
|
111
112
|
project_dir = get_project_dir(run.fab_id, run.fab_version, flwr_dir)
|
|
112
113
|
|
|
114
|
+
# Return empty dict if project directory does not exist
|
|
115
|
+
if not project_dir.is_dir():
|
|
116
|
+
return {}
|
|
117
|
+
|
|
113
118
|
return get_fused_config_from_dir(project_dir, run.override_config)
|
|
114
119
|
|
|
115
120
|
|
|
@@ -136,6 +141,23 @@ def flatten_dict(
|
|
|
136
141
|
return dict(items)
|
|
137
142
|
|
|
138
143
|
|
|
144
|
+
def unflatten_dict(flat_dict: Dict[str, Any]) -> Dict[str, Any]:
|
|
145
|
+
"""Unflatten a dict with keys containing separators into a nested dict."""
|
|
146
|
+
unflattened_dict: Dict[str, Any] = {}
|
|
147
|
+
separator: str = "."
|
|
148
|
+
|
|
149
|
+
for key, value in flat_dict.items():
|
|
150
|
+
parts = key.split(separator)
|
|
151
|
+
d = unflattened_dict
|
|
152
|
+
for part in parts[:-1]:
|
|
153
|
+
if part not in d:
|
|
154
|
+
d[part] = {}
|
|
155
|
+
d = d[part]
|
|
156
|
+
d[parts[-1]] = value
|
|
157
|
+
|
|
158
|
+
return unflattened_dict
|
|
159
|
+
|
|
160
|
+
|
|
139
161
|
def parse_config_args(
|
|
140
162
|
config: Optional[List[str]],
|
|
141
163
|
separator: str = ",",
|
|
@@ -161,3 +183,11 @@ def parse_config_args(
|
|
|
161
183
|
overrides.update(tomli.loads(toml_str))
|
|
162
184
|
|
|
163
185
|
return overrides
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def get_metadata_from_config(config: Dict[str, Any]) -> Tuple[str, str]:
|
|
189
|
+
"""Extract `fab_version` and `fab_id` from a project config."""
|
|
190
|
+
return (
|
|
191
|
+
config["project"]["version"],
|
|
192
|
+
f"{config['tool']['flwr']['app']['publisher']}/{config['project']['name']}",
|
|
193
|
+
)
|
flwr/common/typing.py
CHANGED
flwr/proto/driver_pb2.py
CHANGED
|
@@ -15,10 +15,11 @@ _sym_db = _symbol_database.Default()
|
|
|
15
15
|
from flwr.proto import node_pb2 as flwr_dot_proto_dot_node__pb2
|
|
16
16
|
from flwr.proto import task_pb2 as flwr_dot_proto_dot_task__pb2
|
|
17
17
|
from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2
|
|
18
|
+
from flwr.proto import fab_pb2 as flwr_dot_proto_dot_fab__pb2
|
|
18
19
|
from flwr.proto import transport_pb2 as flwr_dot_proto_dot_transport__pb2
|
|
19
20
|
|
|
20
21
|
|
|
21
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17\x66lwr/proto/driver.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x15\x66lwr/proto/task.proto\x1a\x14\x66lwr/proto/run.proto\x1a\x1a\x66lwr/proto/transport.proto\"\
|
|
22
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17\x66lwr/proto/driver.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x15\x66lwr/proto/task.proto\x1a\x14\x66lwr/proto/run.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\"\xeb\x01\n\x10\x43reateRunRequest\x12\x0e\n\x06\x66\x61\x62_id\x18\x01 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x02 \x01(\t\x12I\n\x0foverride_config\x18\x03 \x03(\x0b\x32\x30.flwr.proto.CreateRunRequest.OverrideConfigEntry\x12\x1c\n\x03\x66\x61\x62\x18\x04 \x01(\x0b\x32\x0f.flwr.proto.Fab\x1aI\n\x13OverrideConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"#\n\x11\x43reateRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"!\n\x0fGetNodesRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"3\n\x10GetNodesResponse\x12\x1f\n\x05nodes\x18\x01 \x03(\x0b\x32\x10.flwr.proto.Node\"@\n\x12PushTaskInsRequest\x12*\n\rtask_ins_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskIns\"\'\n\x13PushTaskInsResponse\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"F\n\x12PullTaskResRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"A\n\x13PullTaskResResponse\x12*\n\rtask_res_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskRes2\xc7\x03\n\x06\x44river\x12J\n\tCreateRun\x12\x1c.flwr.proto.CreateRunRequest\x1a\x1d.flwr.proto.CreateRunResponse\"\x00\x12G\n\x08GetNodes\x12\x1b.flwr.proto.GetNodesRequest\x1a\x1c.flwr.proto.GetNodesResponse\"\x00\x12P\n\x0bPushTaskIns\x12\x1e.flwr.proto.PushTaskInsRequest\x1a\x1f.flwr.proto.PushTaskInsResponse\"\x00\x12P\n\x0bPullTaskRes\x12\x1e.flwr.proto.PullTaskResRequest\x1a\x1f.flwr.proto.PullTaskResResponse\"\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\x62\x06proto3')
|
|
22
23
|
|
|
23
24
|
_globals = globals()
|
|
24
25
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
@@ -27,24 +28,24 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
|
|
27
28
|
DESCRIPTOR._options = None
|
|
28
29
|
_globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._options = None
|
|
29
30
|
_globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_options = b'8\001'
|
|
30
|
-
_globals['_CREATERUNREQUEST']._serialized_start=
|
|
31
|
-
_globals['_CREATERUNREQUEST']._serialized_end=
|
|
32
|
-
_globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=
|
|
33
|
-
_globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=
|
|
34
|
-
_globals['_CREATERUNRESPONSE']._serialized_start=
|
|
35
|
-
_globals['_CREATERUNRESPONSE']._serialized_end=
|
|
36
|
-
_globals['_GETNODESREQUEST']._serialized_start=
|
|
37
|
-
_globals['_GETNODESREQUEST']._serialized_end=
|
|
38
|
-
_globals['_GETNODESRESPONSE']._serialized_start=
|
|
39
|
-
_globals['_GETNODESRESPONSE']._serialized_end=
|
|
40
|
-
_globals['_PUSHTASKINSREQUEST']._serialized_start=
|
|
41
|
-
_globals['_PUSHTASKINSREQUEST']._serialized_end=
|
|
42
|
-
_globals['_PUSHTASKINSRESPONSE']._serialized_start=
|
|
43
|
-
_globals['_PUSHTASKINSRESPONSE']._serialized_end=
|
|
44
|
-
_globals['_PULLTASKRESREQUEST']._serialized_start=
|
|
45
|
-
_globals['_PULLTASKRESREQUEST']._serialized_end=
|
|
46
|
-
_globals['_PULLTASKRESRESPONSE']._serialized_start=
|
|
47
|
-
_globals['_PULLTASKRESRESPONSE']._serialized_end=
|
|
48
|
-
_globals['_DRIVER']._serialized_start=
|
|
49
|
-
_globals['_DRIVER']._serialized_end=
|
|
31
|
+
_globals['_CREATERUNREQUEST']._serialized_start=158
|
|
32
|
+
_globals['_CREATERUNREQUEST']._serialized_end=393
|
|
33
|
+
_globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=320
|
|
34
|
+
_globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=393
|
|
35
|
+
_globals['_CREATERUNRESPONSE']._serialized_start=395
|
|
36
|
+
_globals['_CREATERUNRESPONSE']._serialized_end=430
|
|
37
|
+
_globals['_GETNODESREQUEST']._serialized_start=432
|
|
38
|
+
_globals['_GETNODESREQUEST']._serialized_end=465
|
|
39
|
+
_globals['_GETNODESRESPONSE']._serialized_start=467
|
|
40
|
+
_globals['_GETNODESRESPONSE']._serialized_end=518
|
|
41
|
+
_globals['_PUSHTASKINSREQUEST']._serialized_start=520
|
|
42
|
+
_globals['_PUSHTASKINSREQUEST']._serialized_end=584
|
|
43
|
+
_globals['_PUSHTASKINSRESPONSE']._serialized_start=586
|
|
44
|
+
_globals['_PUSHTASKINSRESPONSE']._serialized_end=625
|
|
45
|
+
_globals['_PULLTASKRESREQUEST']._serialized_start=627
|
|
46
|
+
_globals['_PULLTASKRESREQUEST']._serialized_end=697
|
|
47
|
+
_globals['_PULLTASKRESRESPONSE']._serialized_start=699
|
|
48
|
+
_globals['_PULLTASKRESRESPONSE']._serialized_end=764
|
|
49
|
+
_globals['_DRIVER']._serialized_start=767
|
|
50
|
+
_globals['_DRIVER']._serialized_end=1222
|
|
50
51
|
# @@protoc_insertion_point(module_scope)
|
flwr/proto/driver_pb2.pyi
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
isort:skip_file
|
|
4
4
|
"""
|
|
5
5
|
import builtins
|
|
6
|
+
import flwr.proto.fab_pb2
|
|
6
7
|
import flwr.proto.node_pb2
|
|
7
8
|
import flwr.proto.task_pb2
|
|
8
9
|
import flwr.proto.transport_pb2
|
|
@@ -35,17 +36,22 @@ class CreateRunRequest(google.protobuf.message.Message):
|
|
|
35
36
|
FAB_ID_FIELD_NUMBER: builtins.int
|
|
36
37
|
FAB_VERSION_FIELD_NUMBER: builtins.int
|
|
37
38
|
OVERRIDE_CONFIG_FIELD_NUMBER: builtins.int
|
|
39
|
+
FAB_FIELD_NUMBER: builtins.int
|
|
38
40
|
fab_id: typing.Text
|
|
39
41
|
fab_version: typing.Text
|
|
40
42
|
@property
|
|
41
43
|
def override_config(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, flwr.proto.transport_pb2.Scalar]: ...
|
|
44
|
+
@property
|
|
45
|
+
def fab(self) -> flwr.proto.fab_pb2.Fab: ...
|
|
42
46
|
def __init__(self,
|
|
43
47
|
*,
|
|
44
48
|
fab_id: typing.Text = ...,
|
|
45
49
|
fab_version: typing.Text = ...,
|
|
46
50
|
override_config: typing.Optional[typing.Mapping[typing.Text, flwr.proto.transport_pb2.Scalar]] = ...,
|
|
51
|
+
fab: typing.Optional[flwr.proto.fab_pb2.Fab] = ...,
|
|
47
52
|
) -> None: ...
|
|
48
|
-
def
|
|
53
|
+
def HasField(self, field_name: typing_extensions.Literal["fab",b"fab"]) -> builtins.bool: ...
|
|
54
|
+
def ClearField(self, field_name: typing_extensions.Literal["fab",b"fab","fab_id",b"fab_id","fab_version",b"fab_version","override_config",b"override_config"]) -> None: ...
|
|
49
55
|
global___CreateRunRequest = CreateRunRequest
|
|
50
56
|
|
|
51
57
|
class CreateRunResponse(google.protobuf.message.Message):
|
flwr/proto/driver_pb2_grpc.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import grpc
|
|
4
4
|
|
|
5
5
|
from flwr.proto import driver_pb2 as flwr_dot_proto_dot_driver__pb2
|
|
6
|
+
from flwr.proto import fab_pb2 as flwr_dot_proto_dot_fab__pb2
|
|
6
7
|
from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2
|
|
7
8
|
|
|
8
9
|
|
|
@@ -40,6 +41,11 @@ class DriverStub(object):
|
|
|
40
41
|
request_serializer=flwr_dot_proto_dot_run__pb2.GetRunRequest.SerializeToString,
|
|
41
42
|
response_deserializer=flwr_dot_proto_dot_run__pb2.GetRunResponse.FromString,
|
|
42
43
|
)
|
|
44
|
+
self.GetFab = channel.unary_unary(
|
|
45
|
+
'/flwr.proto.Driver/GetFab',
|
|
46
|
+
request_serializer=flwr_dot_proto_dot_fab__pb2.GetFabRequest.SerializeToString,
|
|
47
|
+
response_deserializer=flwr_dot_proto_dot_fab__pb2.GetFabResponse.FromString,
|
|
48
|
+
)
|
|
43
49
|
|
|
44
50
|
|
|
45
51
|
class DriverServicer(object):
|
|
@@ -80,6 +86,13 @@ class DriverServicer(object):
|
|
|
80
86
|
context.set_details('Method not implemented!')
|
|
81
87
|
raise NotImplementedError('Method not implemented!')
|
|
82
88
|
|
|
89
|
+
def GetFab(self, request, context):
|
|
90
|
+
"""Get FAB
|
|
91
|
+
"""
|
|
92
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
93
|
+
context.set_details('Method not implemented!')
|
|
94
|
+
raise NotImplementedError('Method not implemented!')
|
|
95
|
+
|
|
83
96
|
|
|
84
97
|
def add_DriverServicer_to_server(servicer, server):
|
|
85
98
|
rpc_method_handlers = {
|
|
@@ -108,6 +121,11 @@ def add_DriverServicer_to_server(servicer, server):
|
|
|
108
121
|
request_deserializer=flwr_dot_proto_dot_run__pb2.GetRunRequest.FromString,
|
|
109
122
|
response_serializer=flwr_dot_proto_dot_run__pb2.GetRunResponse.SerializeToString,
|
|
110
123
|
),
|
|
124
|
+
'GetFab': grpc.unary_unary_rpc_method_handler(
|
|
125
|
+
servicer.GetFab,
|
|
126
|
+
request_deserializer=flwr_dot_proto_dot_fab__pb2.GetFabRequest.FromString,
|
|
127
|
+
response_serializer=flwr_dot_proto_dot_fab__pb2.GetFabResponse.SerializeToString,
|
|
128
|
+
),
|
|
111
129
|
}
|
|
112
130
|
generic_handler = grpc.method_handlers_generic_handler(
|
|
113
131
|
'flwr.proto.Driver', rpc_method_handlers)
|
|
@@ -202,3 +220,20 @@ class Driver(object):
|
|
|
202
220
|
flwr_dot_proto_dot_run__pb2.GetRunResponse.FromString,
|
|
203
221
|
options, channel_credentials,
|
|
204
222
|
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
|
223
|
+
|
|
224
|
+
@staticmethod
|
|
225
|
+
def GetFab(request,
|
|
226
|
+
target,
|
|
227
|
+
options=(),
|
|
228
|
+
channel_credentials=None,
|
|
229
|
+
call_credentials=None,
|
|
230
|
+
insecure=False,
|
|
231
|
+
compression=None,
|
|
232
|
+
wait_for_ready=None,
|
|
233
|
+
timeout=None,
|
|
234
|
+
metadata=None):
|
|
235
|
+
return grpc.experimental.unary_unary(request, target, '/flwr.proto.Driver/GetFab',
|
|
236
|
+
flwr_dot_proto_dot_fab__pb2.GetFabRequest.SerializeToString,
|
|
237
|
+
flwr_dot_proto_dot_fab__pb2.GetFabResponse.FromString,
|
|
238
|
+
options, channel_credentials,
|
|
239
|
+
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
flwr/proto/driver_pb2_grpc.pyi
CHANGED
|
@@ -4,6 +4,7 @@ isort:skip_file
|
|
|
4
4
|
"""
|
|
5
5
|
import abc
|
|
6
6
|
import flwr.proto.driver_pb2
|
|
7
|
+
import flwr.proto.fab_pb2
|
|
7
8
|
import flwr.proto.run_pb2
|
|
8
9
|
import grpc
|
|
9
10
|
|
|
@@ -34,6 +35,11 @@ class DriverStub:
|
|
|
34
35
|
flwr.proto.run_pb2.GetRunResponse]
|
|
35
36
|
"""Get run details"""
|
|
36
37
|
|
|
38
|
+
GetFab: grpc.UnaryUnaryMultiCallable[
|
|
39
|
+
flwr.proto.fab_pb2.GetFabRequest,
|
|
40
|
+
flwr.proto.fab_pb2.GetFabResponse]
|
|
41
|
+
"""Get FAB"""
|
|
42
|
+
|
|
37
43
|
|
|
38
44
|
class DriverServicer(metaclass=abc.ABCMeta):
|
|
39
45
|
@abc.abstractmethod
|
|
@@ -76,5 +82,13 @@ class DriverServicer(metaclass=abc.ABCMeta):
|
|
|
76
82
|
"""Get run details"""
|
|
77
83
|
pass
|
|
78
84
|
|
|
85
|
+
@abc.abstractmethod
|
|
86
|
+
def GetFab(self,
|
|
87
|
+
request: flwr.proto.fab_pb2.GetFabRequest,
|
|
88
|
+
context: grpc.ServicerContext,
|
|
89
|
+
) -> flwr.proto.fab_pb2.GetFabResponse:
|
|
90
|
+
"""Get FAB"""
|
|
91
|
+
pass
|
|
92
|
+
|
|
79
93
|
|
|
80
94
|
def add_DriverServicer_to_server(servicer: DriverServicer, server: grpc.Server) -> None: ...
|
flwr/proto/fab_pb2.py
CHANGED
|
@@ -14,7 +14,7 @@ _sym_db = _symbol_database.Default()
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/fab.proto\x12\nflwr.proto\"
|
|
17
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/fab.proto\x12\nflwr.proto\"(\n\x03\x46\x61\x62\x12\x10\n\x08hash_str\x18\x01 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x02 \x01(\x0c\"!\n\rGetFabRequest\x12\x10\n\x08hash_str\x18\x01 \x01(\t\".\n\x0eGetFabResponse\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fabb\x06proto3')
|
|
18
18
|
|
|
19
19
|
_globals = globals()
|
|
20
20
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
@@ -22,9 +22,9 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.fab_pb2', _globa
|
|
|
22
22
|
if _descriptor._USE_C_DESCRIPTORS == False:
|
|
23
23
|
DESCRIPTOR._options = None
|
|
24
24
|
_globals['_FAB']._serialized_start=36
|
|
25
|
-
_globals['_FAB']._serialized_end=
|
|
26
|
-
_globals['_GETFABREQUEST']._serialized_start=
|
|
27
|
-
_globals['_GETFABREQUEST']._serialized_end=
|
|
28
|
-
_globals['_GETFABRESPONSE']._serialized_start=
|
|
29
|
-
_globals['_GETFABRESPONSE']._serialized_end=
|
|
25
|
+
_globals['_FAB']._serialized_end=76
|
|
26
|
+
_globals['_GETFABREQUEST']._serialized_start=78
|
|
27
|
+
_globals['_GETFABREQUEST']._serialized_end=111
|
|
28
|
+
_globals['_GETFABRESPONSE']._serialized_start=113
|
|
29
|
+
_globals['_GETFABRESPONSE']._serialized_end=159
|
|
30
30
|
# @@protoc_insertion_point(module_scope)
|
flwr/proto/fab_pb2.pyi
CHANGED
|
@@ -12,9 +12,9 @@ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
|
|
12
12
|
|
|
13
13
|
class Fab(google.protobuf.message.Message):
|
|
14
14
|
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
|
15
|
-
|
|
15
|
+
HASH_STR_FIELD_NUMBER: builtins.int
|
|
16
16
|
CONTENT_FIELD_NUMBER: builtins.int
|
|
17
|
-
|
|
17
|
+
hash_str: typing.Text
|
|
18
18
|
"""This field is the hash of the data field. It is used to identify the data.
|
|
19
19
|
The hash is calculated using the SHA-256 algorithm and is represented as a
|
|
20
20
|
hex string (sha256hex).
|
|
@@ -25,21 +25,21 @@ class Fab(google.protobuf.message.Message):
|
|
|
25
25
|
|
|
26
26
|
def __init__(self,
|
|
27
27
|
*,
|
|
28
|
-
|
|
28
|
+
hash_str: typing.Text = ...,
|
|
29
29
|
content: builtins.bytes = ...,
|
|
30
30
|
) -> None: ...
|
|
31
|
-
def ClearField(self, field_name: typing_extensions.Literal["content",b"content","
|
|
31
|
+
def ClearField(self, field_name: typing_extensions.Literal["content",b"content","hash_str",b"hash_str"]) -> None: ...
|
|
32
32
|
global___Fab = Fab
|
|
33
33
|
|
|
34
34
|
class GetFabRequest(google.protobuf.message.Message):
|
|
35
35
|
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
HASH_STR_FIELD_NUMBER: builtins.int
|
|
37
|
+
hash_str: typing.Text
|
|
38
38
|
def __init__(self,
|
|
39
39
|
*,
|
|
40
|
-
|
|
40
|
+
hash_str: typing.Text = ...,
|
|
41
41
|
) -> None: ...
|
|
42
|
-
def ClearField(self, field_name: typing_extensions.Literal["
|
|
42
|
+
def ClearField(self, field_name: typing_extensions.Literal["hash_str",b"hash_str"]) -> None: ...
|
|
43
43
|
global___GetFabRequest = GetFabRequest
|
|
44
44
|
|
|
45
45
|
class GetFabResponse(google.protobuf.message.Message):
|