flwr-nightly 1.13.0.dev20241111__py3-none-any.whl → 1.13.0.dev20241117__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.

Files changed (41) hide show
  1. flwr/cli/app.py +2 -0
  2. flwr/cli/build.py +37 -0
  3. flwr/cli/install.py +5 -3
  4. flwr/cli/ls.py +228 -0
  5. flwr/client/app.py +58 -13
  6. flwr/client/clientapp/app.py +34 -23
  7. flwr/client/grpc_rere_client/connection.py +2 -12
  8. flwr/client/rest_client/connection.py +4 -14
  9. flwr/client/supernode/app.py +57 -53
  10. flwr/common/args.py +72 -7
  11. flwr/common/constant.py +21 -6
  12. flwr/common/date.py +18 -0
  13. flwr/common/serde.py +10 -0
  14. flwr/common/typing.py +31 -10
  15. flwr/proto/exec_pb2.py +22 -13
  16. flwr/proto/exec_pb2.pyi +44 -0
  17. flwr/proto/exec_pb2_grpc.py +34 -0
  18. flwr/proto/exec_pb2_grpc.pyi +13 -0
  19. flwr/proto/run_pb2.py +30 -30
  20. flwr/proto/run_pb2.pyi +18 -1
  21. flwr/server/app.py +39 -68
  22. flwr/server/driver/grpc_driver.py +4 -14
  23. flwr/server/run_serverapp.py +8 -238
  24. flwr/server/serverapp/app.py +34 -23
  25. flwr/server/superlink/fleet/rest_rere/rest_api.py +10 -9
  26. flwr/server/superlink/linkstate/in_memory_linkstate.py +71 -46
  27. flwr/server/superlink/linkstate/linkstate.py +19 -5
  28. flwr/server/superlink/linkstate/sqlite_linkstate.py +81 -113
  29. flwr/server/superlink/linkstate/utils.py +193 -3
  30. flwr/simulation/app.py +6 -41
  31. flwr/simulation/legacy_app.py +21 -1
  32. flwr/simulation/run_simulation.py +7 -18
  33. flwr/simulation/simulationio_connection.py +2 -2
  34. flwr/superexec/deployment.py +12 -6
  35. flwr/superexec/exec_servicer.py +31 -2
  36. flwr/superexec/simulation.py +11 -46
  37. {flwr_nightly-1.13.0.dev20241111.dist-info → flwr_nightly-1.13.0.dev20241117.dist-info}/METADATA +6 -4
  38. {flwr_nightly-1.13.0.dev20241111.dist-info → flwr_nightly-1.13.0.dev20241117.dist-info}/RECORD +41 -40
  39. {flwr_nightly-1.13.0.dev20241111.dist-info → flwr_nightly-1.13.0.dev20241117.dist-info}/LICENSE +0 -0
  40. {flwr_nightly-1.13.0.dev20241111.dist-info → flwr_nightly-1.13.0.dev20241117.dist-info}/WHEEL +0 -0
  41. {flwr_nightly-1.13.0.dev20241111.dist-info → flwr_nightly-1.13.0.dev20241117.dist-info}/entry_points.txt +0 -0
flwr/proto/run_pb2.py CHANGED
@@ -18,7 +18,7 @@ from flwr.proto import recordset_pb2 as flwr_dot_proto_dot_recordset__pb2
18
18
  from flwr.proto import transport_pb2 as flwr_dot_proto_dot_transport__pb2
19
19
 
20
20
 
21
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/run.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x1a\x66lwr/proto/recordset.proto\x1a\x1a\x66lwr/proto/transport.proto\"\xd5\x01\n\x03Run\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x0e\n\x06\x66\x61\x62_id\x18\x02 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x03 \x01(\t\x12<\n\x0foverride_config\x18\x04 \x03(\x0b\x32#.flwr.proto.Run.OverrideConfigEntry\x12\x10\n\x08\x66\x61\x62_hash\x18\x05 \x01(\t\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\tRunStatus\x12\x0e\n\x06status\x18\x01 \x01(\t\x12\x12\n\nsub_status\x18\x02 \x01(\t\x12\x0f\n\x07\x64\x65tails\x18\x03 \x01(\t\"\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(\x04\"?\n\rGetRunRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0e\n\x06run_id\x18\x02 \x01(\x04\".\n\x0eGetRunResponse\x12\x1c\n\x03run\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Run\"S\n\x16UpdateRunStatusRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12)\n\nrun_status\x18\x02 \x01(\x0b\x32\x15.flwr.proto.RunStatus\"\x19\n\x17UpdateRunStatusResponse\"F\n\x13GetRunStatusRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0f\n\x07run_ids\x18\x02 \x03(\x04\"\xb1\x01\n\x14GetRunStatusResponse\x12L\n\x0frun_status_dict\x18\x01 \x03(\x0b\x32\x33.flwr.proto.GetRunStatusResponse.RunStatusDictEntry\x1aK\n\x12RunStatusDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.flwr.proto.RunStatus:\x02\x38\x01\"-\n\x1bGetFederationOptionsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"U\n\x1cGetFederationOptionsResponse\x12\x35\n\x12\x66\x65\x64\x65ration_options\x18\x01 \x01(\x0b\x32\x19.flwr.proto.ConfigsRecordb\x06proto3')
21
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/run.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x1a\x66lwr/proto/recordset.proto\x1a\x1a\x66lwr/proto/transport.proto\"\xce\x02\n\x03Run\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x0e\n\x06\x66\x61\x62_id\x18\x02 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x03 \x01(\t\x12<\n\x0foverride_config\x18\x04 \x03(\x0b\x32#.flwr.proto.Run.OverrideConfigEntry\x12\x10\n\x08\x66\x61\x62_hash\x18\x05 \x01(\t\x12\x12\n\npending_at\x18\x06 \x01(\t\x12\x13\n\x0bstarting_at\x18\x07 \x01(\t\x12\x12\n\nrunning_at\x18\x08 \x01(\t\x12\x13\n\x0b\x66inished_at\x18\t \x01(\t\x12%\n\x06status\x18\n \x01(\x0b\x32\x15.flwr.proto.RunStatus\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\tRunStatus\x12\x0e\n\x06status\x18\x01 \x01(\t\x12\x12\n\nsub_status\x18\x02 \x01(\t\x12\x0f\n\x07\x64\x65tails\x18\x03 \x01(\t\"\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(\x04\"?\n\rGetRunRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0e\n\x06run_id\x18\x02 \x01(\x04\".\n\x0eGetRunResponse\x12\x1c\n\x03run\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Run\"S\n\x16UpdateRunStatusRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12)\n\nrun_status\x18\x02 \x01(\x0b\x32\x15.flwr.proto.RunStatus\"\x19\n\x17UpdateRunStatusResponse\"F\n\x13GetRunStatusRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0f\n\x07run_ids\x18\x02 \x03(\x04\"\xb1\x01\n\x14GetRunStatusResponse\x12L\n\x0frun_status_dict\x18\x01 \x03(\x0b\x32\x33.flwr.proto.GetRunStatusResponse.RunStatusDictEntry\x1aK\n\x12RunStatusDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.flwr.proto.RunStatus:\x02\x38\x01\"-\n\x1bGetFederationOptionsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"U\n\x1cGetFederationOptionsResponse\x12\x35\n\x12\x66\x65\x64\x65ration_options\x18\x01 \x01(\x0b\x32\x19.flwr.proto.ConfigsRecordb\x06proto3')
22
22
 
23
23
  _globals = globals()
24
24
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -32,33 +32,33 @@ if _descriptor._USE_C_DESCRIPTORS == False:
32
32
  _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._options = None
33
33
  _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_options = b'8\001'
34
34
  _globals['_RUN']._serialized_start=138
35
- _globals['_RUN']._serialized_end=351
36
- _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_start=278
37
- _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_end=351
38
- _globals['_RUNSTATUS']._serialized_start=353
39
- _globals['_RUNSTATUS']._serialized_end=417
40
- _globals['_CREATERUNREQUEST']._serialized_start=420
41
- _globals['_CREATERUNREQUEST']._serialized_end=655
42
- _globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=278
43
- _globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=351
44
- _globals['_CREATERUNRESPONSE']._serialized_start=657
45
- _globals['_CREATERUNRESPONSE']._serialized_end=692
46
- _globals['_GETRUNREQUEST']._serialized_start=694
47
- _globals['_GETRUNREQUEST']._serialized_end=757
48
- _globals['_GETRUNRESPONSE']._serialized_start=759
49
- _globals['_GETRUNRESPONSE']._serialized_end=805
50
- _globals['_UPDATERUNSTATUSREQUEST']._serialized_start=807
51
- _globals['_UPDATERUNSTATUSREQUEST']._serialized_end=890
52
- _globals['_UPDATERUNSTATUSRESPONSE']._serialized_start=892
53
- _globals['_UPDATERUNSTATUSRESPONSE']._serialized_end=917
54
- _globals['_GETRUNSTATUSREQUEST']._serialized_start=919
55
- _globals['_GETRUNSTATUSREQUEST']._serialized_end=989
56
- _globals['_GETRUNSTATUSRESPONSE']._serialized_start=992
57
- _globals['_GETRUNSTATUSRESPONSE']._serialized_end=1169
58
- _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_start=1094
59
- _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_end=1169
60
- _globals['_GETFEDERATIONOPTIONSREQUEST']._serialized_start=1171
61
- _globals['_GETFEDERATIONOPTIONSREQUEST']._serialized_end=1216
62
- _globals['_GETFEDERATIONOPTIONSRESPONSE']._serialized_start=1218
63
- _globals['_GETFEDERATIONOPTIONSRESPONSE']._serialized_end=1303
35
+ _globals['_RUN']._serialized_end=472
36
+ _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_start=399
37
+ _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_end=472
38
+ _globals['_RUNSTATUS']._serialized_start=474
39
+ _globals['_RUNSTATUS']._serialized_end=538
40
+ _globals['_CREATERUNREQUEST']._serialized_start=541
41
+ _globals['_CREATERUNREQUEST']._serialized_end=776
42
+ _globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=399
43
+ _globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=472
44
+ _globals['_CREATERUNRESPONSE']._serialized_start=778
45
+ _globals['_CREATERUNRESPONSE']._serialized_end=813
46
+ _globals['_GETRUNREQUEST']._serialized_start=815
47
+ _globals['_GETRUNREQUEST']._serialized_end=878
48
+ _globals['_GETRUNRESPONSE']._serialized_start=880
49
+ _globals['_GETRUNRESPONSE']._serialized_end=926
50
+ _globals['_UPDATERUNSTATUSREQUEST']._serialized_start=928
51
+ _globals['_UPDATERUNSTATUSREQUEST']._serialized_end=1011
52
+ _globals['_UPDATERUNSTATUSRESPONSE']._serialized_start=1013
53
+ _globals['_UPDATERUNSTATUSRESPONSE']._serialized_end=1038
54
+ _globals['_GETRUNSTATUSREQUEST']._serialized_start=1040
55
+ _globals['_GETRUNSTATUSREQUEST']._serialized_end=1110
56
+ _globals['_GETRUNSTATUSRESPONSE']._serialized_start=1113
57
+ _globals['_GETRUNSTATUSRESPONSE']._serialized_end=1290
58
+ _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_start=1215
59
+ _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_end=1290
60
+ _globals['_GETFEDERATIONOPTIONSREQUEST']._serialized_start=1292
61
+ _globals['_GETFEDERATIONOPTIONSREQUEST']._serialized_end=1337
62
+ _globals['_GETFEDERATIONOPTIONSRESPONSE']._serialized_start=1339
63
+ _globals['_GETFEDERATIONOPTIONSRESPONSE']._serialized_end=1424
64
64
  # @@protoc_insertion_point(module_scope)
flwr/proto/run_pb2.pyi CHANGED
@@ -37,12 +37,23 @@ class Run(google.protobuf.message.Message):
37
37
  FAB_VERSION_FIELD_NUMBER: builtins.int
38
38
  OVERRIDE_CONFIG_FIELD_NUMBER: builtins.int
39
39
  FAB_HASH_FIELD_NUMBER: builtins.int
40
+ PENDING_AT_FIELD_NUMBER: builtins.int
41
+ STARTING_AT_FIELD_NUMBER: builtins.int
42
+ RUNNING_AT_FIELD_NUMBER: builtins.int
43
+ FINISHED_AT_FIELD_NUMBER: builtins.int
44
+ STATUS_FIELD_NUMBER: builtins.int
40
45
  run_id: builtins.int
41
46
  fab_id: typing.Text
42
47
  fab_version: typing.Text
43
48
  @property
44
49
  def override_config(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, flwr.proto.transport_pb2.Scalar]: ...
45
50
  fab_hash: typing.Text
51
+ pending_at: typing.Text
52
+ starting_at: typing.Text
53
+ running_at: typing.Text
54
+ finished_at: typing.Text
55
+ @property
56
+ def status(self) -> global___RunStatus: ...
46
57
  def __init__(self,
47
58
  *,
48
59
  run_id: builtins.int = ...,
@@ -50,8 +61,14 @@ class Run(google.protobuf.message.Message):
50
61
  fab_version: typing.Text = ...,
51
62
  override_config: typing.Optional[typing.Mapping[typing.Text, flwr.proto.transport_pb2.Scalar]] = ...,
52
63
  fab_hash: typing.Text = ...,
64
+ pending_at: typing.Text = ...,
65
+ starting_at: typing.Text = ...,
66
+ running_at: typing.Text = ...,
67
+ finished_at: typing.Text = ...,
68
+ status: typing.Optional[global___RunStatus] = ...,
53
69
  ) -> None: ...
54
- def ClearField(self, field_name: typing_extensions.Literal["fab_hash",b"fab_hash","fab_id",b"fab_id","fab_version",b"fab_version","override_config",b"override_config","run_id",b"run_id"]) -> None: ...
70
+ def HasField(self, field_name: typing_extensions.Literal["status",b"status"]) -> builtins.bool: ...
71
+ def ClearField(self, field_name: typing_extensions.Literal["fab_hash",b"fab_hash","fab_id",b"fab_id","fab_version",b"fab_version","finished_at",b"finished_at","override_config",b"override_config","pending_at",b"pending_at","run_id",b"run_id","running_at",b"running_at","starting_at",b"starting_at","status",b"status"]) -> None: ...
55
72
  global___Run = Run
56
73
 
57
74
  class RunStatus(google.protobuf.message.Message):
flwr/server/app.py CHANGED
@@ -22,7 +22,6 @@ import sys
22
22
  import threading
23
23
  from collections.abc import Sequence
24
24
  from logging import DEBUG, INFO, WARN
25
- from os.path import isfile
26
25
  from pathlib import Path
27
26
  from time import sleep
28
27
  from typing import Optional
@@ -37,23 +36,26 @@ from cryptography.hazmat.primitives.serialization import (
37
36
 
38
37
  from flwr.common import GRPC_MAX_MESSAGE_LENGTH, EventType, event
39
38
  from flwr.common.address import parse_address
39
+ from flwr.common.args import try_obtain_server_certificates
40
40
  from flwr.common.config import get_flwr_dir, parse_config_args
41
41
  from flwr.common.constant import (
42
- EXEC_API_DEFAULT_ADDRESS,
42
+ CLIENT_OCTET,
43
+ EXEC_API_DEFAULT_SERVER_ADDRESS,
43
44
  FLEET_API_GRPC_BIDI_DEFAULT_ADDRESS,
44
45
  FLEET_API_GRPC_RERE_DEFAULT_ADDRESS,
45
46
  FLEET_API_REST_DEFAULT_ADDRESS,
46
47
  ISOLATION_MODE_PROCESS,
47
48
  ISOLATION_MODE_SUBPROCESS,
48
49
  MISSING_EXTRA_REST,
49
- SERVERAPPIO_API_DEFAULT_ADDRESS,
50
- SIMULATIONIO_API_DEFAULT_ADDRESS,
50
+ SERVER_OCTET,
51
+ SERVERAPPIO_API_DEFAULT_SERVER_ADDRESS,
52
+ SIMULATIONIO_API_DEFAULT_SERVER_ADDRESS,
51
53
  TRANSPORT_TYPE_GRPC_ADAPTER,
52
54
  TRANSPORT_TYPE_GRPC_RERE,
53
55
  TRANSPORT_TYPE_REST,
54
56
  )
55
57
  from flwr.common.exit_handlers import register_exit_handlers
56
- from flwr.common.logger import log
58
+ from flwr.common.logger import log, warn_deprecated_feature
57
59
  from flwr.common.secure_aggregation.crypto.symmetric_encryption import (
58
60
  private_key_to_bytes,
59
61
  public_key_to_bytes,
@@ -99,6 +101,11 @@ def start_server( # pylint: disable=too-many-arguments,too-many-locals
99
101
  ) -> History:
100
102
  """Start a Flower server using the gRPC transport layer.
101
103
 
104
+ Warning
105
+ -------
106
+ This function is deprecated since 1.13.0. Use the :code:`flower-superlink` command
107
+ instead to start a SuperLink.
108
+
102
109
  Parameters
103
110
  ----------
104
111
  server_address : Optional[str]
@@ -156,6 +163,17 @@ def start_server( # pylint: disable=too-many-arguments,too-many-locals
156
163
  >>> )
157
164
  >>> )
158
165
  """
166
+ msg = (
167
+ "flwr.server.start_server() is deprecated."
168
+ "\n\tInstead, use the `flower-superlink` CLI command to start a SuperLink "
169
+ "as shown below:"
170
+ "\n\n\t\t$ flower-superlink --insecure"
171
+ "\n\n\tTo view usage and all available options, run:"
172
+ "\n\n\t\t$ flower-superlink --help"
173
+ "\n\n\tUsing `start_server()` is deprecated."
174
+ )
175
+ warn_deprecated_feature(name=msg)
176
+
159
177
  event(EventType.START_SERVER_ENTER)
160
178
 
161
179
  # Parse IP address
@@ -227,7 +245,7 @@ def run_superlink() -> None:
227
245
  simulationio_address, _, _ = _format_address(args.simulationio_api_address)
228
246
 
229
247
  # Obtain certificates
230
- certificates = _try_obtain_certificates(args)
248
+ certificates = try_obtain_server_certificates(args, args.fleet_api_type)
231
249
 
232
250
  # Initialize StateFactory
233
251
  state_factory = LinkStateFactory(args.database)
@@ -367,7 +385,11 @@ def run_superlink() -> None:
367
385
 
368
386
  if args.isolation == ISOLATION_MODE_SUBPROCESS:
369
387
 
370
- address = simulationio_address if sim_exec else serverappio_address
388
+ _octet, _colon, _port = serverappio_address.rpartition(":")
389
+ io_address = (
390
+ f"{CLIENT_OCTET}:{_port}" if _octet == SERVER_OCTET else serverappio_address
391
+ )
392
+ address = simulationio_address if sim_exec else io_address
371
393
  cmd = "flwr-simulation" if sim_exec else "flwr-serverapp"
372
394
 
373
395
  # Scheduler thread
@@ -426,7 +448,7 @@ def _flwr_scheduler(
426
448
  command = [
427
449
  cmd,
428
450
  "--run-once",
429
- "--superlink",
451
+ "--serverappio-api-address",
430
452
  io_api_address,
431
453
  ]
432
454
  if ssl_ca_certfile:
@@ -540,60 +562,6 @@ def _try_setup_node_authentication(
540
562
  )
541
563
 
542
564
 
543
- def _try_obtain_certificates(
544
- args: argparse.Namespace,
545
- ) -> Optional[tuple[bytes, bytes, bytes]]:
546
- # Obtain certificates
547
- if args.insecure:
548
- log(WARN, "Option `--insecure` was set. Starting insecure HTTP server.")
549
- return None
550
- # Check if certificates are provided
551
- if args.fleet_api_type in [TRANSPORT_TYPE_GRPC_RERE, TRANSPORT_TYPE_GRPC_ADAPTER]:
552
- if args.ssl_certfile and args.ssl_keyfile and args.ssl_ca_certfile:
553
- if not isfile(args.ssl_ca_certfile):
554
- sys.exit("Path argument `--ssl-ca-certfile` does not point to a file.")
555
- if not isfile(args.ssl_certfile):
556
- sys.exit("Path argument `--ssl-certfile` does not point to a file.")
557
- if not isfile(args.ssl_keyfile):
558
- sys.exit("Path argument `--ssl-keyfile` does not point to a file.")
559
- certificates = (
560
- Path(args.ssl_ca_certfile).read_bytes(), # CA certificate
561
- Path(args.ssl_certfile).read_bytes(), # server certificate
562
- Path(args.ssl_keyfile).read_bytes(), # server private key
563
- )
564
- return certificates
565
- if args.ssl_certfile or args.ssl_keyfile or args.ssl_ca_certfile:
566
- sys.exit(
567
- "You need to provide valid file paths to `--ssl-certfile`, "
568
- "`--ssl-keyfile`, and `—-ssl-ca-certfile` to create a secure "
569
- "connection in Fleet API server (gRPC-rere)."
570
- )
571
- if args.fleet_api_type == TRANSPORT_TYPE_REST:
572
- if args.ssl_certfile and args.ssl_keyfile:
573
- if not isfile(args.ssl_certfile):
574
- sys.exit("Path argument `--ssl-certfile` does not point to a file.")
575
- if not isfile(args.ssl_keyfile):
576
- sys.exit("Path argument `--ssl-keyfile` does not point to a file.")
577
- certificates = (
578
- b"",
579
- Path(args.ssl_certfile).read_bytes(), # server certificate
580
- Path(args.ssl_keyfile).read_bytes(), # server private key
581
- )
582
- return certificates
583
- if args.ssl_certfile or args.ssl_keyfile:
584
- sys.exit(
585
- "You need to provide valid file paths to `--ssl-certfile` "
586
- "and `--ssl-keyfile` to create a secure connection "
587
- "in Fleet API server (REST, experimental)."
588
- )
589
- sys.exit(
590
- "Certificates are required unless running in insecure mode. "
591
- "Please provide certificate paths to `--ssl-certfile`, "
592
- "`--ssl-keyfile`, and `—-ssl-ca-certfile` or run the server "
593
- "in insecure mode using '--insecure' if you understand the risks."
594
- )
595
-
596
-
597
565
  def _run_fleet_api_grpc_rere(
598
566
  address: str,
599
567
  state_factory: LinkStateFactory,
@@ -786,8 +754,9 @@ def _add_args_common(parser: argparse.ArgumentParser) -> None:
786
754
  def _add_args_serverappio_api(parser: argparse.ArgumentParser) -> None:
787
755
  parser.add_argument(
788
756
  "--serverappio-api-address",
789
- help="ServerAppIo API (gRPC) server address (IPv4, IPv6, or a domain name).",
790
- default=SERVERAPPIO_API_DEFAULT_ADDRESS,
757
+ default=SERVERAPPIO_API_DEFAULT_SERVER_ADDRESS,
758
+ help="ServerAppIo API (gRPC) server address (IPv4, IPv6, or a domain name). "
759
+ f"By default, it is set to {SERVERAPPIO_API_DEFAULT_SERVER_ADDRESS}.",
791
760
  )
792
761
 
793
762
 
@@ -820,8 +789,9 @@ def _add_args_exec_api(parser: argparse.ArgumentParser) -> None:
820
789
  """Add command line arguments for Exec API."""
821
790
  parser.add_argument(
822
791
  "--exec-api-address",
823
- help="Exec API server address (IPv4, IPv6, or a domain name)",
824
- default=EXEC_API_DEFAULT_ADDRESS,
792
+ help="Exec API server address (IPv4, IPv6, or a domain name) "
793
+ f"By default, it is set to {EXEC_API_DEFAULT_SERVER_ADDRESS}.",
794
+ default=EXEC_API_DEFAULT_SERVER_ADDRESS,
825
795
  )
826
796
  parser.add_argument(
827
797
  "--executor",
@@ -845,6 +815,7 @@ def _add_args_exec_api(parser: argparse.ArgumentParser) -> None:
845
815
  def _add_args_simulationio_api(parser: argparse.ArgumentParser) -> None:
846
816
  parser.add_argument(
847
817
  "--simulationio-api-address",
848
- help="SimulationIo API (gRPC) server address (IPv4, IPv6, or a domain name).",
849
- default=SIMULATIONIO_API_DEFAULT_ADDRESS,
818
+ default=SIMULATIONIO_API_DEFAULT_SERVER_ADDRESS,
819
+ help="SimulationIo API (gRPC) server address (IPv4, IPv6, or a domain name)."
820
+ f"By default, it is set to {SIMULATIONIO_API_DEFAULT_SERVER_ADDRESS}.",
850
821
  )
@@ -23,14 +23,10 @@ from typing import Optional, cast
23
23
  import grpc
24
24
 
25
25
  from flwr.common import DEFAULT_TTL, Message, Metadata, RecordSet
26
- from flwr.common.constant import SERVERAPPIO_API_DEFAULT_ADDRESS
26
+ from flwr.common.constant import SERVERAPPIO_API_DEFAULT_CLIENT_ADDRESS
27
27
  from flwr.common.grpc import create_channel
28
28
  from flwr.common.logger import log
29
- from flwr.common.serde import (
30
- message_from_taskres,
31
- message_to_taskins,
32
- user_config_from_proto,
33
- )
29
+ from flwr.common.serde import message_from_taskres, message_to_taskins, run_from_proto
34
30
  from flwr.common.typing import Run
35
31
  from flwr.proto.node_pb2 import Node # pylint: disable=E0611
36
32
  from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611
@@ -70,7 +66,7 @@ class GrpcDriver(Driver):
70
66
 
71
67
  def __init__( # pylint: disable=too-many-arguments
72
68
  self,
73
- serverappio_service_address: str = SERVERAPPIO_API_DEFAULT_ADDRESS,
69
+ serverappio_service_address: str = SERVERAPPIO_API_DEFAULT_CLIENT_ADDRESS,
74
70
  root_certificates: Optional[bytes] = None,
75
71
  ) -> None:
76
72
  self._addr = serverappio_service_address
@@ -119,13 +115,7 @@ class GrpcDriver(Driver):
119
115
  res: GetRunResponse = self._stub.GetRun(req)
120
116
  if not res.HasField("run"):
121
117
  raise RuntimeError(f"Cannot find the run with ID: {run_id}")
122
- self._run = Run(
123
- run_id=res.run.run_id,
124
- fab_id=res.run.fab_id,
125
- fab_version=res.run.fab_version,
126
- fab_hash=res.run.fab_hash,
127
- override_config=user_config_from_proto(res.run.override_config),
128
- )
118
+ self._run = run_from_proto(res.run)
129
119
 
130
120
  @property
131
121
  def run(self) -> Run:
@@ -15,33 +15,15 @@
15
15
  """Run ServerApp."""
16
16
 
17
17
 
18
- import argparse
19
18
  import sys
20
- from logging import DEBUG, INFO, WARN
21
- from pathlib import Path
19
+ from logging import DEBUG, ERROR
22
20
  from typing import Optional
23
21
 
24
- from flwr.cli.config_utils import get_fab_metadata
25
- from flwr.cli.install import install_from_fab
26
- from flwr.common import Context, EventType, RecordSet, event
27
- from flwr.common.config import (
28
- get_flwr_dir,
29
- get_fused_config_from_dir,
30
- get_metadata_from_config,
31
- get_project_config,
32
- get_project_dir,
33
- )
34
- from flwr.common.constant import SERVERAPPIO_API_DEFAULT_ADDRESS
35
- from flwr.common.logger import log, update_console_handler, warn_deprecated_feature
22
+ from flwr.common import Context
23
+ from flwr.common.logger import log, warn_unsupported_feature
36
24
  from flwr.common.object_ref import load_app
37
- from flwr.proto.fab_pb2 import GetFabRequest, GetFabResponse # pylint: disable=E0611
38
- from flwr.proto.run_pb2 import ( # pylint: disable=E0611
39
- CreateRunRequest,
40
- CreateRunResponse,
41
- )
42
25
 
43
26
  from .driver import Driver
44
- from .driver.grpc_driver import GrpcDriver
45
27
  from .server_app import LoadServerAppError, ServerApp
46
28
 
47
29
 
@@ -87,221 +69,9 @@ def run(
87
69
  # pylint: disable-next=too-many-branches,too-many-statements,too-many-locals
88
70
  def run_server_app() -> None:
89
71
  """Run Flower server app."""
90
- event(EventType.RUN_SERVER_APP_ENTER)
91
-
92
- args = _parse_args_run_server_app().parse_args()
93
-
94
- # Check if the server app reference is passed.
95
- # Since Flower 1.11, passing a reference is not allowed.
96
- app_path: Optional[str] = args.app
97
- # If the provided app_path doesn't exist, and contains a ":",
98
- # it is likely to be a server app reference instead of a path.
99
- if app_path is not None and not Path(app_path).exists() and ":" in app_path:
100
- sys.exit(
101
- "It appears you've passed a reference like `server:app`.\n\n"
102
- "Note that since version `1.11.0`, `flower-server-app` no longer supports "
103
- "passing a reference to a `ServerApp` attribute. Instead, you need to pass "
104
- "the path to Flower app via the argument `--app`. This is the path to a "
105
- "directory containing a `pyproject.toml`. You can create a valid Flower "
106
- "app by executing `flwr new` and following the prompt."
107
- )
108
-
109
- if args.server != SERVERAPPIO_API_DEFAULT_ADDRESS:
110
- warn = "Passing flag --server is deprecated. Use --superlink instead."
111
- warn_deprecated_feature(warn)
112
-
113
- if args.superlink != SERVERAPPIO_API_DEFAULT_ADDRESS:
114
- # if `--superlink` also passed, then
115
- # warn user that this argument overrides what was passed with `--server`
116
- log(
117
- WARN,
118
- "Both `--server` and `--superlink` were passed. "
119
- "`--server` will be ignored. Connecting to the "
120
- "SuperLink ServerAppIo API at %s.",
121
- args.superlink,
122
- )
123
- else:
124
- args.superlink = args.server
125
-
126
- update_console_handler(
127
- level=DEBUG if args.verbose else INFO,
128
- timestamps=args.verbose,
129
- colored=True,
130
- )
131
-
132
- # Obtain certificates
133
- if args.insecure:
134
- if args.root_certificates is not None:
135
- sys.exit(
136
- "Conflicting options: The '--insecure' flag disables HTTPS, "
137
- "but '--root-certificates' was also specified. Please remove "
138
- "the '--root-certificates' option when running in insecure mode, "
139
- "or omit '--insecure' to use HTTPS."
140
- )
141
- log(
142
- WARN,
143
- "Option `--insecure` was set. "
144
- "Starting insecure HTTP client connected to %s.",
145
- args.superlink,
146
- )
147
- root_certificates = None
148
- else:
149
- # Load the certificates if provided, or load the system certificates
150
- cert_path = args.root_certificates
151
- if cert_path is None:
152
- root_certificates = None
153
- else:
154
- root_certificates = Path(cert_path).read_bytes()
155
- log(
156
- DEBUG,
157
- "Starting secure HTTPS client connected to %s "
158
- "with the following certificates: %s.",
159
- args.superlink,
160
- cert_path,
161
- )
162
-
163
- if not (app_path is None) ^ (args.run_id is None):
164
- raise sys.exit(
165
- "Please provide either a Flower App path or a Run ID, but not both. "
166
- "For more details, use: ``flower-server-app -h``"
167
- )
168
-
169
- # Initialize GrpcDriver
170
- if app_path is None:
171
- # User provided `--run-id`, but not `app_dir`
172
- driver = GrpcDriver(
173
- serverappio_service_address=args.superlink,
174
- root_certificates=root_certificates,
175
- )
176
- flwr_dir = get_flwr_dir(args.flwr_dir)
177
- driver.set_run(args.run_id)
178
- run_ = driver.run
179
- if not run_.fab_hash:
180
- raise ValueError("FAB hash not provided.")
181
- fab_req = GetFabRequest(hash_str=run_.fab_hash)
182
- # pylint: disable-next=W0212
183
- fab_res: GetFabResponse = driver._stub.GetFab(fab_req)
184
- if fab_res.fab.hash_str != run_.fab_hash:
185
- raise ValueError("FAB hashes don't match.")
186
- install_from_fab(fab_res.fab.content, flwr_dir, True)
187
- fab_id, fab_version = get_fab_metadata(fab_res.fab.content)
188
-
189
- app_path = str(get_project_dir(fab_id, fab_version, run_.fab_hash, flwr_dir))
190
- config = get_project_config(app_path)
191
- run_id = run_.run_id
192
- else:
193
- # User provided `app_dir`, but not `--run-id`
194
- # Create run if run_id is not provided
195
- driver = GrpcDriver(
196
- serverappio_service_address=args.superlink,
197
- root_certificates=root_certificates,
198
- )
199
- # Load config from the project directory
200
- config = get_project_config(app_path)
201
- fab_version, fab_id = get_metadata_from_config(config)
202
-
203
- # Create run
204
- req = CreateRunRequest(fab_id=fab_id, fab_version=fab_version)
205
- res: CreateRunResponse = driver._stub.CreateRun(req) # pylint: disable=W0212
206
- # Fetch full `Run` using `run_id`
207
- driver.set_run(res.run_id) # pylint: disable=W0212
208
- run_id = res.run_id
209
-
210
- # Obtain server app reference and the run config
211
- server_app_attr = config["tool"]["flwr"]["app"]["components"]["serverapp"]
212
- server_app_run_config = get_fused_config_from_dir(
213
- Path(app_path), driver.run.override_config
72
+ warn_unsupported_feature(
73
+ "The command `flower-server-app` is deprecated and no longer in use. "
74
+ "Use the `flwr-serverapp` exclusively instead."
214
75
  )
215
-
216
- log(DEBUG, "Flower will load ServerApp `%s` in %s", server_app_attr, app_path)
217
-
218
- log(
219
- DEBUG,
220
- "root_certificates: `%s`",
221
- root_certificates,
222
- )
223
-
224
- # Initialize Context
225
- context = Context(
226
- run_id=run_id,
227
- node_id=0,
228
- node_config={},
229
- state=RecordSet(),
230
- run_config=server_app_run_config,
231
- )
232
-
233
- # Run the ServerApp with the Driver
234
- run(
235
- driver=driver,
236
- context=context,
237
- server_app_dir=app_path,
238
- server_app_attr=server_app_attr,
239
- )
240
-
241
- # Clean up
242
- driver.close()
243
-
244
- event(EventType.RUN_SERVER_APP_LEAVE)
245
-
246
-
247
- def _parse_args_run_server_app() -> argparse.ArgumentParser:
248
- """Parse flower-server-app command line arguments."""
249
- parser = argparse.ArgumentParser(
250
- description="Start a Flower server app",
251
- )
252
-
253
- parser.add_argument(
254
- "app",
255
- nargs="?",
256
- default=None,
257
- help="Load and run the `ServerApp` from the specified Flower App path. "
258
- "The `pyproject.toml` file must be located in the root of this path.",
259
- )
260
- parser.add_argument(
261
- "--insecure",
262
- action="store_true",
263
- help="Run the `ServerApp` without HTTPS. By default, the app runs with "
264
- "HTTPS enabled. Use this flag only if you understand the risks.",
265
- )
266
- parser.add_argument(
267
- "--verbose",
268
- action="store_true",
269
- help="Set the logging to `DEBUG`.",
270
- )
271
- parser.add_argument(
272
- "--root-certificates",
273
- metavar="ROOT_CERT",
274
- type=str,
275
- help="Specifies the path to the PEM-encoded root certificate file for "
276
- "establishing secure HTTPS connections.",
277
- )
278
- parser.add_argument(
279
- "--server",
280
- default=SERVERAPPIO_API_DEFAULT_ADDRESS,
281
- help="Server address",
282
- )
283
- parser.add_argument(
284
- "--superlink",
285
- default=SERVERAPPIO_API_DEFAULT_ADDRESS,
286
- help="SuperLink ServerAppIo API (gRPC-rere) address "
287
- "(IPv4, IPv6, or a domain name)",
288
- )
289
- parser.add_argument(
290
- "--run-id",
291
- default=None,
292
- type=int,
293
- help="The identifier of the run.",
294
- )
295
- parser.add_argument(
296
- "--flwr-dir",
297
- default=None,
298
- help="""The path containing installed Flower Apps.
299
- By default, this value is equal to:
300
-
301
- - `$FLWR_HOME/` if `$FLWR_HOME` is defined
302
- - `$XDG_DATA_HOME/.flwr/` if `$XDG_DATA_HOME` is defined
303
- - `$HOME/.flwr/` in all other cases
304
- """,
305
- )
306
-
307
- return parser
76
+ log(ERROR, "`flower-server-app` used.")
77
+ sys.exit()