Skip to content

Commit

Permalink
refactor(framework) Prepare flwr-serverapp functionality (#4388)
Browse files Browse the repository at this point in the history
  • Loading branch information
jafermarq authored Oct 28, 2024
1 parent 323e612 commit c1f0a24
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 21 deletions.
18 changes: 10 additions & 8 deletions src/py/flwr/server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,13 @@
TRANSPORT_TYPE_GRPC_ADAPTER,
TRANSPORT_TYPE_GRPC_RERE,
TRANSPORT_TYPE_REST,
Status,
)
from flwr.common.exit_handlers import register_exit_handlers
from flwr.common.logger import log
from flwr.common.secure_aggregation.crypto.symmetric_encryption import (
private_key_to_bytes,
public_key_to_bytes,
)
from flwr.common.typing import RunStatus
from flwr.proto.fleet_pb2_grpc import ( # pylint: disable=E0611
add_FleetServicer_to_server,
)
Expand Down Expand Up @@ -345,7 +343,7 @@ def run_superlink() -> None:
# Scheduler thread
scheduler_th = threading.Thread(
target=_flwr_serverapp_scheduler,
args=(state_factory, args.driver_api_address),
args=(state_factory, args.driver_api_address, args.ssl_ca_certfile),
)
scheduler_th.start()
bckg_threads.append(scheduler_th)
Expand All @@ -367,7 +365,9 @@ def run_superlink() -> None:


def _flwr_serverapp_scheduler(
state_factory: LinkStateFactory, driver_api_address: str
state_factory: LinkStateFactory,
driver_api_address: str,
ssl_ca_certfile: Optional[str],
) -> None:
log(DEBUG, "Started flwr-serverapp scheduler thread.")

Expand All @@ -380,10 +380,6 @@ def _flwr_serverapp_scheduler(

if pending_run_id:

# Set run as starting
state.update_run_status(
run_id=pending_run_id, new_status=RunStatus(Status.STARTING, "", "")
)
log(
INFO,
"Launching `flwr-serverapp` subprocess with run-id %d. "
Expand All @@ -399,6 +395,12 @@ def _flwr_serverapp_scheduler(
"--run-id",
str(pending_run_id),
]
if ssl_ca_certfile:
command.append("--root-certificates")
command.append(ssl_ca_certfile)
else:
command.append("--insecure")

subprocess.run(
command,
stdout=None,
Expand Down
89 changes: 76 additions & 13 deletions src/py/flwr/server/serverapp/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
"""Flower ServerApp process."""

import argparse
from logging import DEBUG, INFO
import sys
from logging import DEBUG, INFO, WARN
from os.path import isfile
from pathlib import Path
from typing import Optional

from flwr.common.logger import log
Expand All @@ -41,38 +44,98 @@ def flwr_serverapp() -> None:
help="Id of the Run this process should start. If not supplied, this "
"function will request a pending run to the LinkState.",
)
parser.add_argument(
"--flwr-dir",
default=None,
help="""The path containing installed Flower Apps.
By default, this value is equal to:
- `$FLWR_HOME/` if `$FLWR_HOME` is defined
- `$XDG_DATA_HOME/.flwr/` if `$XDG_DATA_HOME` is defined
- `$HOME/.flwr/` in all other cases
""",
)
parser.add_argument(
"--insecure",
action="store_true",
help="Run the server without HTTPS, regardless of whether certificate "
"paths are provided. By default, the server runs with HTTPS enabled. "
"Use this flag only if you understand the risks.",
)
parser.add_argument(
"--root-certificates",
metavar="ROOT_CERT",
type=str,
help="Specifies the path to the PEM-encoded root certificate file for "
"establishing secure HTTPS connections.",
)
args = parser.parse_args()

certificates = _try_obtain_certificates(args)

log(
DEBUG,
"Staring isolated `ServerApp` connected to SuperLink DriverAPI at %s "
"for run-id %s",
args.superlink,
args.run_id,
)
run_serverapp(superlink=args.superlink, run_id=args.run_id)
run_serverapp(
superlink=args.superlink,
run_id=args.run_id,
flwr_dir_=args.flwr_dir,
certificates=certificates,
)


def _try_obtain_certificates(
args: argparse.Namespace,
) -> Optional[bytes]:

if args.insecure:
if args.root_certificates is not None:
sys.exit(
"Conflicting options: The '--insecure' flag disables HTTPS, "
"but '--root-certificates' was also specified. Please remove "
"the '--root-certificates' option when running in insecure mode, "
"or omit '--insecure' to use HTTPS."
)
log(
WARN,
"Option `--insecure` was set. Starting insecure HTTP channel to %s.",
args.superlink,
)
root_certificates = None
else:
# Load the certificates if provided, or load the system certificates
if not isfile(args.root_certificates):
sys.exit("Path argument `--root-certificates` does not point to a file.")
root_certificates = Path(args.root_certificates).read_bytes()
log(
DEBUG,
"Starting secure HTTPS channel to %s "
"with the following certificates: %s.",
args.superlink,
args.root_certificates,
)
return root_certificates


def run_serverapp( # pylint: disable=R0914
superlink: str,
run_id: Optional[int] = None,
flwr_dir_: Optional[str] = None,
certificates: Optional[bytes] = None,
) -> None:
"""Run Flower ServerApp process.
Parameters
----------
superlink : str
Address of SuperLink
run_id : Optional[int] (default: None)
Unique identifier of a Run registered at the LinkState. If not supplied,
this function will request a pending run to the LinkState.
"""
"""Run Flower ServerApp process."""
_ = GrpcDriver(
run_id=run_id if run_id else 0,
driver_service_address=superlink,
root_certificates=None,
root_certificates=certificates,
)

log(INFO, "%s", flwr_dir_)

# Then, GetServerInputs

# Then, run ServerApp

0 comments on commit c1f0a24

Please sign in to comment.