diff --git a/src/py/flwr/server/app.py b/src/py/flwr/server/app.py index 01b1f622212..e04cfb37e11 100644 --- a/src/py/flwr/server/app.py +++ b/src/py/flwr/server/app.py @@ -365,7 +365,7 @@ def run_superlink() -> None: client_app_attr=args.client_app, backend_name=args.backend, backend_config_json_stream=args.backend_config, - working_dir=args.dir, + app_dir=args.app_dir, state_factory=state_factory, f_stop=f_stop, ) @@ -441,7 +441,7 @@ def _run_fleet_api_vce( client_app_attr: str, backend_name: str, backend_config_json_stream: str, - working_dir: str, + app_dir: str, state_factory: StateFactory, f_stop: asyncio.Event, ) -> None: @@ -453,7 +453,7 @@ def _run_fleet_api_vce( backend_name=backend_name, backend_config_json_stream=backend_config_json_stream, state_factory=state_factory, - working_dir=working_dir, + app_dir=app_dir, f_stop=f_stop, ) @@ -705,7 +705,7 @@ def _add_args_fleet_api(parser: argparse.ArgumentParser) -> None: "`flwr.common.typing.ConfigsRecordValues`. ", ) parser.add_argument( - "--dir", + "--app-dir", default="", help="Add specified directory to the PYTHONPATH and load" "ClientApp from there." diff --git a/src/py/flwr/server/superlink/fleet/vce/vce_api.py b/src/py/flwr/server/superlink/fleet/vce/vce_api.py index d42379960a6..225c6155774 100644 --- a/src/py/flwr/server/superlink/fleet/vce/vce_api.py +++ b/src/py/flwr/server/superlink/fleet/vce/vce_api.py @@ -221,7 +221,7 @@ async def run( def start_vce( backend_name: str, backend_config_json_stream: str, - working_dir: str, + app_dir: str, f_stop: asyncio.Event, client_app: Optional[ClientApp] = None, client_app_attr: Optional[str] = None, @@ -297,7 +297,7 @@ def start_vce( def backend_fn() -> Backend: """Instantiate a Backend.""" - return backend_type(backend_config, work_dir=working_dir) + return backend_type(backend_config, work_dir=app_dir) log(INFO, "client_app_attr = %s", client_app_attr) diff --git a/src/py/flwr/server/superlink/fleet/vce/vce_api_test.py b/src/py/flwr/server/superlink/fleet/vce/vce_api_test.py index 16cb45c1262..72e9c07ebcc 100644 --- a/src/py/flwr/server/superlink/fleet/vce/vce_api_test.py +++ b/src/py/flwr/server/superlink/fleet/vce/vce_api_test.py @@ -119,21 +119,21 @@ def register_messages_into_state( return expected_results -def _autoresolve_working_dir(rel_client_app_dir: str = "backend") -> str: - """Correctly resolve working directory.""" +def _autoresolve_app_dir(rel_client_app_dir: str = "backend") -> str: + """Correctly resolve working directory for the app.""" file_path = Path(__file__) - working_dir = Path.cwd() - rel_workdir = file_path.relative_to(working_dir) + app_dir = Path.cwd() + rel_app_dir = file_path.relative_to(app_dir) # Susbtract lats element and append "backend/test" (wher the client module is.) - return str(rel_workdir.parent / rel_client_app_dir) + return str(rel_app_dir.parent / rel_client_app_dir) # pylint: disable=too-many-arguments def start_and_shutdown( backend: str = "ray", client_app_attr: str = "raybackend_test:client_app", - working_dir: str = "", + app_dir: str = "", num_supernodes: Optional[int] = None, state_factory: Optional[StateFactory] = None, nodes_mapping: Optional[NodeToPartitionMapping] = None, @@ -157,8 +157,8 @@ def start_and_shutdown( termination_th.start() # Resolve working directory if not passed - if not working_dir: - working_dir = _autoresolve_working_dir() + if not app_dir: + app_dir = _autoresolve_app_dir() start_vce( num_supernodes=num_supernodes, @@ -166,7 +166,7 @@ def start_and_shutdown( backend_name=backend, backend_config_json_stream=backend_config, state_factory=state_factory, - working_dir=working_dir, + app_dir=app_dir, f_stop=f_stop, existing_nodes_mapping=nodes_mapping, ) diff --git a/src/py/flwr/simulation/run_simulation.py b/src/py/flwr/simulation/run_simulation.py index cb68221ea58..31884f2edc6 100644 --- a/src/py/flwr/simulation/run_simulation.py +++ b/src/py/flwr/simulation/run_simulation.py @@ -54,7 +54,7 @@ def run_simulation_from_cli() -> None: num_supernodes=args.num_supernodes, backend_name=args.backend, backend_config=backend_config_dict, - working_dir=args.dir, + app_dir=args.app_dir, driver_api_address=args.driver_api_address, enable_tf_gpu_growth=args.enable_tf_gpu_growth, verbose_logging=args.verbose, @@ -125,7 +125,7 @@ def run_serverapp_th( server_app_attr: Optional[str], server_app: Optional[ServerApp], driver: Driver, - server_app_dir: str, + app_dir: str, f_stop: asyncio.Event, enable_tf_gpu_growth: bool, delay_launch: int = 3, @@ -163,7 +163,7 @@ def server_th_with_start_checks( # type: ignore "server_app_attr": server_app_attr, "loaded_server_app": server_app, "driver": driver, - "server_app_dir": server_app_dir, + "server_app_dir": app_dir, }, ) sleep(delay_launch) @@ -177,7 +177,7 @@ def _main_loop( backend_name: str, backend_config_stream: str, driver_api_address: str, - working_dir: str, + app_dir: str, enable_tf_gpu_growth: bool, client_app: Optional[ClientApp] = None, client_app_attr: Optional[str] = None, @@ -214,7 +214,7 @@ def _main_loop( server_app_attr=server_app_attr, server_app=server_app, driver=driver, - server_app_dir=working_dir, + app_dir=app_dir, f_stop=f_stop, enable_tf_gpu_growth=enable_tf_gpu_growth, ) @@ -227,7 +227,7 @@ def _main_loop( client_app=client_app, backend_name=backend_name, backend_config_json_stream=backend_config_stream, - working_dir=working_dir, + app_dir=app_dir, state_factory=state_factory, f_stop=f_stop, ) @@ -260,7 +260,7 @@ def _run_simulation( backend_config: Optional[Dict[str, ConfigsRecordValues]] = None, client_app_attr: Optional[str] = None, server_app_attr: Optional[str] = None, - working_dir: str = "", + app_dir: str = "", driver_api_address: str = "0.0.0.0:9091", enable_tf_gpu_growth: bool = False, verbose_logging: bool = False, @@ -297,7 +297,7 @@ def _run_simulation( A path to a `ServerApp` module to be loaded: For example: `server:app` or `project.package.module:wrapper.app`." - working_dir : str + app_dir : str Add specified directory to the PYTHONPATH and load `ClientApp` from there. (Default: current working directory.) @@ -340,7 +340,7 @@ def _run_simulation( backend_name, backend_config_stream, driver_api_address, - working_dir, + app_dir, enable_tf_gpu_growth, client_app, client_app_attr, @@ -378,15 +378,21 @@ def _parse_args_run_simulation() -> argparse.ArgumentParser: parser = argparse.ArgumentParser( description="Start a Flower simulation", ) + parser.add_argument( + "--server-app", + required=True, + help="For example: `server:app` or `project.package.module:wrapper.app`", + ) parser.add_argument( "--client-app", required=True, help="For example: `client:app` or `project.package.module:wrapper.app`", ) parser.add_argument( - "--server-app", + "--num-supernodes", + type=int, required=True, - help="For example: `server:app` or `project.package.module:wrapper.app`", + help="Number of simulated SuperNodes.", ) parser.add_argument( "--driver-api-address", @@ -394,18 +400,20 @@ def _parse_args_run_simulation() -> argparse.ArgumentParser: type=str, help="For example: `server:app` or `project.package.module:wrapper.app`", ) - parser.add_argument( - "--num-supernodes", - type=int, - required=True, - help="Number of simulated SuperNodes.", - ) parser.add_argument( "--backend", default="ray", type=str, help="Simulation backend that executes the ClientApp.", ) + parser.add_argument( + "--backend-config", + type=str, + default='{"client_resources": {"num_cpus":2, "num_gpus":0.0}, "tensorflow": 0}', + help='A JSON formatted stream, e.g \'{"":, "":}\' to ' + "configure a backend. Values supported in are those included by " + "`flwr.common.typing.ConfigsRecordValues`. ", + ) parser.add_argument( "--enable-tf-gpu-growth", action="store_true", @@ -417,26 +425,17 @@ def _parse_args_run_simulation() -> argparse.ArgumentParser: "the TensorFlow documentation: https://www.tensorflow.org/api/stable.", ) parser.add_argument( - "--backend-config", - type=str, - default='{"client_resources": {"num_cpus":2, "num_gpus":0.0}, "tensorflow": 0}', - help='A JSON formatted stream, e.g \'{"":, "":}\' to ' - "configure a backend. Values supported in are those included by " - "`flwr.common.typing.ConfigsRecordValues`. ", + "--verbose", + action="store_true", + help="When unset, only INFO, WARNING and ERROR log messages will be shown. " + "If set, DEBUG-level logs will be displayed. ", ) parser.add_argument( - "--dir", + "--app-dir", default="", help="Add specified directory to the PYTHONPATH and load" "ClientApp and ServerApp from there." " Default: current working directory.", ) - parser.add_argument( - "--verbose", - action="store_true", - help="When unset, only INFO, WARNING and ERROR log messages will be shown. " - "If set, DEBUG-level logs will be displayed. ", - ) - return parser