diff --git a/src/py/flwr/client/app.py b/src/py/flwr/client/app.py index 348ef8910dd3..127bb423851f 100644 --- a/src/py/flwr/client/app.py +++ b/src/py/flwr/client/app.py @@ -195,7 +195,7 @@ def _start_client_internal( ] = None, max_retries: Optional[int] = None, max_wait_time: Optional[float] = None, - flwr_dir: Optional[Path] = None, + flwr_path: Optional[Path] = None, ) -> None: """Start a Flower client node which connects to a Flower server. @@ -241,7 +241,7 @@ class `flwr.client.Client` (default: None) The maximum duration before the client stops trying to connect to the server in case of connection error. If set to None, there is no limit to the total time. - flwr_dir: Optional[Path] (default: None) + flwr_path: Optional[Path] (default: None) The fully resolved path containing installed Flower Apps. """ if insecure is None: @@ -402,7 +402,7 @@ def _on_backoff(retry_state: RetryState) -> None: # Register context for this run node_state.register_context( - run_id=run_id, run=runs[run_id], flwr_dir=flwr_dir + run_id=run_id, run=runs[run_id], flwr_path=flwr_path ) # Retrieve context for this run diff --git a/src/py/flwr/client/node_state.py b/src/py/flwr/client/node_state.py index 393ca4564a35..08c19967ea3d 100644 --- a/src/py/flwr/client/node_state.py +++ b/src/py/flwr/client/node_state.py @@ -20,7 +20,7 @@ from typing import Dict, Optional from flwr.common import Context, RecordSet -from flwr.common.config import get_fused_config +from flwr.common.config import get_fused_config, get_fused_config_from_dir from flwr.common.typing import Run @@ -48,11 +48,25 @@ def register_context( self, run_id: int, run: Optional[Run] = None, - flwr_dir: Optional[Path] = None, + flwr_path: Optional[Path] = None, + app_dir: Optional[str] = None, ) -> None: """Register new run context for this node.""" if run_id not in self.run_infos: - initial_run_config = get_fused_config(run, flwr_dir) if run else {} + initial_run_config = {} + if app_dir: + # Load from app directory + app_path = Path(app_dir) + if app_path.is_dir(): + override_config = run.override_config if run else {} + initial_run_config = get_fused_config_from_dir( + app_path, override_config + ) + else: + raise ValueError("The specified `app_dir` must be a directory.") + else: + # Load from .fab + initial_run_config = get_fused_config(run, flwr_path) if run else {} self.run_infos[run_id] = RunInfo( initial_run_config=initial_run_config, context=Context( diff --git a/src/py/flwr/client/supernode/app.py b/src/py/flwr/client/supernode/app.py index 027c3376b7f3..a364318c766c 100644 --- a/src/py/flwr/client/supernode/app.py +++ b/src/py/flwr/client/supernode/app.py @@ -78,7 +78,7 @@ def run_supernode() -> None: max_retries=args.max_retries, max_wait_time=args.max_wait_time, node_config=parse_config_args(args.node_config), - flwr_dir=get_flwr_dir(args.flwr_dir), + flwr_path=get_flwr_dir(args.flwr_dir), ) # Graceful shutdown