flwr 1.19.0__py3-none-any.whl → 1.21.0__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.
Files changed (167) hide show
  1. flwr/__init__.py +4 -1
  2. flwr/app/__init__.py +28 -0
  3. flwr/app/exception.py +31 -0
  4. flwr/cli/auth_plugin/oidc_cli_plugin.py +4 -4
  5. flwr/cli/build.py +15 -5
  6. flwr/cli/cli_user_auth_interceptor.py +1 -1
  7. flwr/cli/config_utils.py +3 -3
  8. flwr/cli/constant.py +25 -8
  9. flwr/cli/log.py +9 -9
  10. flwr/cli/login/login.py +3 -3
  11. flwr/cli/ls.py +5 -5
  12. flwr/cli/new/new.py +23 -4
  13. flwr/cli/new/templates/app/README.flowertune.md.tpl +2 -0
  14. flwr/cli/new/templates/app/README.md.tpl +5 -0
  15. flwr/cli/new/templates/app/code/__init__.pytorch_msg_api.py.tpl +1 -0
  16. flwr/cli/new/templates/app/code/client.pytorch_msg_api.py.tpl +80 -0
  17. flwr/cli/new/templates/app/code/server.pytorch_msg_api.py.tpl +41 -0
  18. flwr/cli/new/templates/app/code/task.pytorch_msg_api.py.tpl +98 -0
  19. flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +14 -3
  20. flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +13 -1
  21. flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +21 -2
  22. flwr/cli/new/templates/app/pyproject.jax.toml.tpl +18 -1
  23. flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +19 -2
  24. flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +18 -1
  25. flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +20 -3
  26. flwr/cli/new/templates/app/pyproject.pytorch_msg_api.toml.tpl +53 -0
  27. flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +18 -1
  28. flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +18 -1
  29. flwr/cli/run/run.py +53 -50
  30. flwr/cli/stop.py +7 -4
  31. flwr/cli/utils.py +29 -11
  32. flwr/client/grpc_adapter_client/connection.py +11 -4
  33. flwr/client/grpc_rere_client/connection.py +93 -129
  34. flwr/client/rest_client/connection.py +134 -164
  35. flwr/clientapp/__init__.py +10 -0
  36. flwr/clientapp/mod/__init__.py +26 -0
  37. flwr/clientapp/mod/centraldp_mods.py +132 -0
  38. flwr/common/args.py +20 -6
  39. flwr/common/auth_plugin/__init__.py +4 -4
  40. flwr/common/auth_plugin/auth_plugin.py +7 -7
  41. flwr/common/constant.py +26 -5
  42. flwr/common/event_log_plugin/event_log_plugin.py +1 -1
  43. flwr/common/exit/__init__.py +4 -0
  44. flwr/common/exit/exit.py +8 -1
  45. flwr/common/exit/exit_code.py +42 -8
  46. flwr/common/exit/exit_handler.py +62 -0
  47. flwr/common/{exit_handlers.py → exit/signal_handler.py} +20 -37
  48. flwr/common/grpc.py +1 -1
  49. flwr/common/{inflatable_grpc_utils.py → inflatable_protobuf_utils.py} +52 -10
  50. flwr/common/inflatable_utils.py +191 -24
  51. flwr/common/logger.py +1 -1
  52. flwr/common/record/array.py +101 -22
  53. flwr/common/record/arraychunk.py +59 -0
  54. flwr/common/retry_invoker.py +30 -11
  55. flwr/common/serde.py +0 -28
  56. flwr/common/telemetry.py +4 -0
  57. flwr/compat/client/app.py +14 -31
  58. flwr/compat/server/app.py +2 -2
  59. flwr/proto/appio_pb2.py +51 -0
  60. flwr/proto/appio_pb2.pyi +195 -0
  61. flwr/proto/appio_pb2_grpc.py +4 -0
  62. flwr/proto/appio_pb2_grpc.pyi +4 -0
  63. flwr/proto/clientappio_pb2.py +4 -19
  64. flwr/proto/clientappio_pb2.pyi +0 -125
  65. flwr/proto/clientappio_pb2_grpc.py +269 -29
  66. flwr/proto/clientappio_pb2_grpc.pyi +114 -21
  67. flwr/proto/control_pb2.py +62 -0
  68. flwr/proto/{exec_pb2_grpc.py → control_pb2_grpc.py} +54 -54
  69. flwr/proto/{exec_pb2_grpc.pyi → control_pb2_grpc.pyi} +28 -28
  70. flwr/proto/fleet_pb2.py +12 -20
  71. flwr/proto/fleet_pb2.pyi +6 -36
  72. flwr/proto/serverappio_pb2.py +8 -31
  73. flwr/proto/serverappio_pb2.pyi +0 -152
  74. flwr/proto/serverappio_pb2_grpc.py +107 -38
  75. flwr/proto/serverappio_pb2_grpc.pyi +47 -20
  76. flwr/proto/simulationio_pb2.py +4 -11
  77. flwr/proto/simulationio_pb2.pyi +0 -58
  78. flwr/proto/simulationio_pb2_grpc.py +129 -27
  79. flwr/proto/simulationio_pb2_grpc.pyi +52 -13
  80. flwr/server/app.py +130 -153
  81. flwr/server/fleet_event_log_interceptor.py +4 -0
  82. flwr/server/grid/grpc_grid.py +94 -54
  83. flwr/server/grid/inmemory_grid.py +1 -0
  84. flwr/server/serverapp/app.py +165 -144
  85. flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +8 -0
  86. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +1 -1
  87. flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +2 -5
  88. flwr/server/superlink/fleet/message_handler/message_handler.py +10 -16
  89. flwr/server/superlink/fleet/rest_rere/rest_api.py +1 -2
  90. flwr/server/superlink/fleet/vce/backend/raybackend.py +3 -1
  91. flwr/server/superlink/fleet/vce/vce_api.py +6 -6
  92. flwr/server/superlink/linkstate/in_memory_linkstate.py +34 -0
  93. flwr/server/superlink/linkstate/linkstate.py +2 -1
  94. flwr/server/superlink/linkstate/sqlite_linkstate.py +45 -0
  95. flwr/server/superlink/serverappio/serverappio_grpc.py +2 -2
  96. flwr/server/superlink/serverappio/serverappio_servicer.py +95 -48
  97. flwr/server/superlink/simulation/simulationio_grpc.py +1 -1
  98. flwr/server/superlink/simulation/simulationio_servicer.py +98 -22
  99. flwr/server/superlink/utils.py +0 -35
  100. flwr/serverapp/__init__.py +12 -0
  101. flwr/serverapp/dp_fixed_clipping.py +352 -0
  102. flwr/serverapp/exception.py +38 -0
  103. flwr/serverapp/strategy/__init__.py +38 -0
  104. flwr/serverapp/strategy/dp_fixed_clipping.py +352 -0
  105. flwr/serverapp/strategy/fedadagrad.py +162 -0
  106. flwr/serverapp/strategy/fedadam.py +181 -0
  107. flwr/serverapp/strategy/fedavg.py +295 -0
  108. flwr/serverapp/strategy/fedopt.py +218 -0
  109. flwr/serverapp/strategy/fedyogi.py +173 -0
  110. flwr/serverapp/strategy/result.py +105 -0
  111. flwr/serverapp/strategy/strategy.py +285 -0
  112. flwr/serverapp/strategy/strategy_utils.py +251 -0
  113. flwr/serverapp/strategy/strategy_utils_tests.py +304 -0
  114. flwr/simulation/app.py +159 -154
  115. flwr/simulation/run_simulation.py +17 -0
  116. flwr/supercore/app_utils.py +58 -0
  117. flwr/supercore/cli/__init__.py +22 -0
  118. flwr/supercore/cli/flower_superexec.py +141 -0
  119. flwr/supercore/corestate/__init__.py +22 -0
  120. flwr/supercore/corestate/corestate.py +81 -0
  121. flwr/{server/superlink → supercore}/ffs/disk_ffs.py +1 -1
  122. flwr/supercore/grpc_health/__init__.py +25 -0
  123. flwr/supercore/grpc_health/health_server.py +53 -0
  124. flwr/supercore/grpc_health/simple_health_servicer.py +38 -0
  125. flwr/supercore/license_plugin/__init__.py +22 -0
  126. flwr/supercore/license_plugin/license_plugin.py +26 -0
  127. flwr/supercore/object_store/in_memory_object_store.py +31 -31
  128. flwr/supercore/object_store/object_store.py +20 -42
  129. flwr/supercore/object_store/utils.py +43 -0
  130. flwr/{superexec → supercore/superexec}/__init__.py +1 -1
  131. flwr/supercore/superexec/plugin/__init__.py +28 -0
  132. flwr/supercore/superexec/plugin/base_exec_plugin.py +53 -0
  133. flwr/supercore/superexec/plugin/clientapp_exec_plugin.py +28 -0
  134. flwr/supercore/superexec/plugin/exec_plugin.py +71 -0
  135. flwr/supercore/superexec/plugin/serverapp_exec_plugin.py +28 -0
  136. flwr/supercore/superexec/plugin/simulation_exec_plugin.py +28 -0
  137. flwr/supercore/superexec/run_superexec.py +185 -0
  138. flwr/supercore/utils.py +32 -0
  139. flwr/superlink/servicer/__init__.py +15 -0
  140. flwr/superlink/servicer/control/__init__.py +22 -0
  141. flwr/{superexec/exec_event_log_interceptor.py → superlink/servicer/control/control_event_log_interceptor.py} +9 -5
  142. flwr/{superexec/exec_grpc.py → superlink/servicer/control/control_grpc.py} +39 -28
  143. flwr/superlink/servicer/control/control_license_interceptor.py +82 -0
  144. flwr/{superexec/exec_servicer.py → superlink/servicer/control/control_servicer.py} +79 -31
  145. flwr/{superexec/exec_user_auth_interceptor.py → superlink/servicer/control/control_user_auth_interceptor.py} +18 -10
  146. flwr/supernode/cli/flower_supernode.py +3 -7
  147. flwr/supernode/cli/flwr_clientapp.py +20 -16
  148. flwr/supernode/nodestate/in_memory_nodestate.py +13 -4
  149. flwr/supernode/nodestate/nodestate.py +3 -44
  150. flwr/supernode/runtime/run_clientapp.py +129 -115
  151. flwr/supernode/servicer/clientappio/__init__.py +1 -3
  152. flwr/supernode/servicer/clientappio/clientappio_servicer.py +217 -165
  153. flwr/supernode/start_client_internal.py +205 -148
  154. {flwr-1.19.0.dist-info → flwr-1.21.0.dist-info}/METADATA +5 -3
  155. {flwr-1.19.0.dist-info → flwr-1.21.0.dist-info}/RECORD +161 -117
  156. {flwr-1.19.0.dist-info → flwr-1.21.0.dist-info}/entry_points.txt +1 -0
  157. flwr/common/inflatable_rest_utils.py +0 -99
  158. flwr/proto/exec_pb2.py +0 -62
  159. flwr/superexec/app.py +0 -45
  160. flwr/superexec/deployment.py +0 -192
  161. flwr/superexec/executor.py +0 -100
  162. flwr/superexec/simulation.py +0 -130
  163. /flwr/proto/{exec_pb2.pyi → control_pb2.pyi} +0 -0
  164. /flwr/{server/superlink → supercore}/ffs/__init__.py +0 -0
  165. /flwr/{server/superlink → supercore}/ffs/ffs.py +0 -0
  166. /flwr/{server/superlink → supercore}/ffs/ffs_factory.py +0 -0
  167. {flwr-1.19.0.dist-info → flwr-1.21.0.dist-info}/WHEEL +0 -0
flwr/server/app.py CHANGED
@@ -18,9 +18,8 @@
18
18
  import argparse
19
19
  import csv
20
20
  import importlib.util
21
- import multiprocessing
22
- import multiprocessing.context
23
21
  import os
22
+ import subprocess
24
23
  import sys
25
24
  import threading
26
25
  from collections.abc import Sequence
@@ -37,13 +36,13 @@ from cryptography.hazmat.primitives.serialization import load_ssh_public_key
37
36
  from flwr.common import GRPC_MAX_MESSAGE_LENGTH, EventType, event
38
37
  from flwr.common.address import parse_address
39
38
  from flwr.common.args import try_obtain_server_certificates
40
- from flwr.common.auth_plugin import ExecAuthPlugin, ExecAuthzPlugin
41
- from flwr.common.config import get_flwr_dir, parse_config_args
39
+ from flwr.common.auth_plugin import ControlAuthPlugin, ControlAuthzPlugin
40
+ from flwr.common.config import get_flwr_dir
42
41
  from flwr.common.constant import (
43
42
  AUTH_TYPE_YAML_KEY,
44
43
  AUTHZ_TYPE_YAML_KEY,
45
44
  CLIENT_OCTET,
46
- EXEC_API_DEFAULT_SERVER_ADDRESS,
45
+ CONTROL_API_DEFAULT_SERVER_ADDRESS,
47
46
  FLEET_API_GRPC_RERE_DEFAULT_ADDRESS,
48
47
  FLEET_API_REST_DEFAULT_ADDRESS,
49
48
  ISOLATION_MODE_PROCESS,
@@ -55,10 +54,10 @@ from flwr.common.constant import (
55
54
  TRANSPORT_TYPE_GRPC_RERE,
56
55
  TRANSPORT_TYPE_REST,
57
56
  EventLogWriterType,
57
+ ExecPluginType,
58
58
  )
59
59
  from flwr.common.event_log_plugin import EventLogWriterPlugin
60
- from flwr.common.exit import ExitCode, flwr_exit
61
- from flwr.common.exit_handlers import register_exit_handlers
60
+ from flwr.common.exit import ExitCode, flwr_exit, register_signal_handlers
62
61
  from flwr.common.grpc import generic_create_grpc_server
63
62
  from flwr.common.logger import log
64
63
  from flwr.common.secure_aggregation.crypto.symmetric_encryption import (
@@ -69,13 +68,11 @@ from flwr.proto.fleet_pb2_grpc import ( # pylint: disable=E0611
69
68
  )
70
69
  from flwr.proto.grpcadapter_pb2_grpc import add_GrpcAdapterServicer_to_server
71
70
  from flwr.server.fleet_event_log_interceptor import FleetEventLogInterceptor
72
- from flwr.server.serverapp.app import flwr_serverapp
73
- from flwr.simulation.app import flwr_simulation
71
+ from flwr.supercore.ffs import FfsFactory
72
+ from flwr.supercore.grpc_health import add_args_health, run_health_server_grpc_no_tls
74
73
  from flwr.supercore.object_store import ObjectStoreFactory
75
- from flwr.superexec.app import load_executor
76
- from flwr.superexec.exec_grpc import run_exec_api_grpc
74
+ from flwr.superlink.servicer.control import run_control_api_grpc
77
75
 
78
- from .superlink.ffs.ffs_factory import FfsFactory
79
76
  from .superlink.fleet.grpc_adapter.grpc_adapter_servicer import GrpcAdapterServicer
80
77
  from .superlink.fleet.grpc_rere.fleet_servicer import FleetServicer
81
78
  from .superlink.fleet.grpc_rere.server_interceptor import AuthenticateServerInterceptor
@@ -85,15 +82,15 @@ from .superlink.simulation.simulationio_grpc import run_simulationio_api_grpc
85
82
 
86
83
  DATABASE = ":flwr-in-memory-state:"
87
84
  BASE_DIR = get_flwr_dir() / "superlink" / "ffs"
88
- P = TypeVar("P", ExecAuthPlugin, ExecAuthzPlugin)
85
+ P = TypeVar("P", ControlAuthPlugin, ControlAuthzPlugin)
89
86
 
90
87
 
91
88
  try:
92
89
  from flwr.ee import (
93
90
  add_ee_args_superlink,
94
- get_exec_auth_plugins,
95
- get_exec_authz_plugins,
96
- get_exec_event_log_writer_plugins,
91
+ get_control_auth_plugins,
92
+ get_control_authz_plugins,
93
+ get_control_event_log_writer_plugins,
97
94
  get_fleet_event_log_writer_plugins,
98
95
  )
99
96
  except ImportError:
@@ -102,16 +99,16 @@ except ImportError:
102
99
  def add_ee_args_superlink(parser: argparse.ArgumentParser) -> None:
103
100
  """Add EE-specific arguments to the parser."""
104
101
 
105
- def get_exec_auth_plugins() -> dict[str, type[ExecAuthPlugin]]:
106
- """Return all Exec API authentication plugins."""
102
+ def get_control_auth_plugins() -> dict[str, type[ControlAuthPlugin]]:
103
+ """Return all Control API authentication plugins."""
107
104
  raise NotImplementedError("No authentication plugins are currently supported.")
108
105
 
109
- def get_exec_authz_plugins() -> dict[str, type[ExecAuthzPlugin]]:
110
- """Return all Exec API authorization plugins."""
106
+ def get_control_authz_plugins() -> dict[str, type[ControlAuthzPlugin]]:
107
+ """Return all Control API authorization plugins."""
111
108
  raise NotImplementedError("No authorization plugins are currently supported.")
112
109
 
113
- def get_exec_event_log_writer_plugins() -> dict[str, type[EventLogWriterPlugin]]:
114
- """Return all Exec API event log writer plugins."""
110
+ def get_control_event_log_writer_plugins() -> dict[str, type[EventLogWriterPlugin]]:
111
+ """Return all Control API event log writer plugins."""
115
112
  raise NotImplementedError(
116
113
  "No event log writer plugins are currently supported."
117
114
  )
@@ -138,10 +135,50 @@ def run_superlink() -> None:
138
135
  WARN, "The `--flwr-dir` option is currently not in use and will be ignored."
139
136
  )
140
137
 
138
+ # Detect if `--executor*` arguments were set
139
+ if args.executor or args.executor_dir or args.executor_config:
140
+ flwr_exit(
141
+ ExitCode.SUPERLINK_INVALID_ARGS,
142
+ "The arguments `--executor`, `--executor-dir`, and `--executor-config` are "
143
+ "deprecated and will be removed in a future release. To run SuperLink with "
144
+ "the SimulationIo API, please use `--simulation`.",
145
+ )
146
+
147
+ # Detect if both Control API and Exec API addresses were set explicitly
148
+ explicit_args = set()
149
+ for arg in sys.argv[1:]:
150
+ if arg.startswith("--"):
151
+ explicit_args.add(
152
+ arg.split("=")[0]
153
+ ) # handles both `--arg val` and `--arg=val`
154
+
155
+ control_api_set = "--control-api-address" in explicit_args
156
+ exec_api_set = "--exec-api-address" in explicit_args
157
+
158
+ if control_api_set and exec_api_set:
159
+ flwr_exit(
160
+ ExitCode.SUPERLINK_INVALID_ARGS,
161
+ "Both `--control-api-address` and `--exec-api-address` are set. "
162
+ "Please use only `--control-api-address` as `--exec-api-address` is "
163
+ "deprecated.",
164
+ )
165
+
166
+ # Warn deprecated `--exec-api-address` argument
167
+ if args.exec_api_address is not None:
168
+ log(
169
+ WARN,
170
+ "The `--exec-api-address` argument is deprecated and will be removed in a "
171
+ "future release. Use `--control-api-address` instead.",
172
+ )
173
+ args.control_api_address = args.exec_api_address
174
+
141
175
  # Parse IP addresses
142
176
  serverappio_address, _, _ = _format_address(args.serverappio_api_address)
143
- exec_address, _, _ = _format_address(args.exec_api_address)
177
+ control_address, _, _ = _format_address(args.control_api_address)
144
178
  simulationio_address, _, _ = _format_address(args.simulationio_api_address)
179
+ health_server_address = None
180
+ if args.health_server_address is not None:
181
+ health_server_address, _, _ = _format_address(args.health_server_address)
145
182
 
146
183
  # Obtain certificates
147
184
  certificates = try_obtain_server_certificates(args)
@@ -150,17 +187,17 @@ def run_superlink() -> None:
150
187
  # provided
151
188
  verify_tls_cert = not getattr(args, "disable_oidc_tls_cert_verification", None)
152
189
 
153
- auth_plugin: Optional[ExecAuthPlugin] = None
154
- authz_plugin: Optional[ExecAuthzPlugin] = None
190
+ auth_plugin: Optional[ControlAuthPlugin] = None
191
+ authz_plugin: Optional[ControlAuthzPlugin] = None
155
192
  event_log_plugin: Optional[EventLogWriterPlugin] = None
156
193
  # Load the auth plugin if the args.user_auth_config is provided
157
194
  if cfg_path := getattr(args, "user_auth_config", None):
158
- auth_plugin, authz_plugin = _try_obtain_exec_auth_plugins(
195
+ auth_plugin, authz_plugin = _try_obtain_control_auth_plugins(
159
196
  Path(cfg_path), verify_tls_cert
160
197
  )
161
198
  # Enable event logging if the args.enable_event_log is True
162
199
  if args.enable_event_log:
163
- event_log_plugin = _try_obtain_exec_event_log_writer_plugin()
200
+ event_log_plugin = _try_obtain_control_event_log_writer_plugin()
164
201
 
165
202
  # Initialize StateFactory
166
203
  state_factory = LinkStateFactory(args.database)
@@ -171,30 +208,23 @@ def run_superlink() -> None:
171
208
  # Initialize ObjectStoreFactory
172
209
  objectstore_factory = ObjectStoreFactory()
173
210
 
174
- # Start Exec API
175
- executor = load_executor(args)
176
- exec_server: grpc.Server = run_exec_api_grpc(
177
- address=exec_address,
211
+ # Start Control API
212
+ is_simulation = args.simulation
213
+ control_server: grpc.Server = run_control_api_grpc(
214
+ address=control_address,
178
215
  state_factory=state_factory,
179
216
  ffs_factory=ffs_factory,
180
217
  objectstore_factory=objectstore_factory,
181
- executor=executor,
182
218
  certificates=certificates,
183
- config=parse_config_args(
184
- [args.executor_config] if args.executor_config else args.executor_config
185
- ),
219
+ is_simulation=is_simulation,
186
220
  auth_plugin=auth_plugin,
187
221
  authz_plugin=authz_plugin,
188
222
  event_log_plugin=event_log_plugin,
189
223
  )
190
- grpc_servers = [exec_server]
191
-
192
- # Determine Exec plugin
193
- # If simulation is used, don't start ServerAppIo and Fleet APIs
194
- sim_exec = executor.__class__.__qualname__ == "SimulationEngine"
224
+ grpc_servers = [control_server]
195
225
  bckg_threads: list[threading.Thread] = []
196
226
 
197
- if sim_exec:
227
+ if is_simulation:
198
228
  simulationio_server: grpc.Server = run_simulationio_api_grpc(
199
229
  address=simulationio_address,
200
230
  state_factory=state_factory,
@@ -312,28 +342,26 @@ def run_superlink() -> None:
312
342
  io_address = (
313
343
  f"{CLIENT_OCTET}:{_port}" if _octet == SERVER_OCTET else serverappio_address
314
344
  )
315
- address_arg = (
316
- "--simulationio-api-address" if sim_exec else "--serverappio-api-address"
317
- )
318
- address = simulationio_address if sim_exec else io_address
319
- cmd = "flwr-simulation" if sim_exec else "flwr-serverapp"
320
-
321
- # Scheduler thread
322
- scheduler_th = threading.Thread(
323
- target=_flwr_scheduler,
324
- args=(
325
- state_factory,
326
- address_arg,
327
- address,
328
- cmd,
329
- ),
330
- daemon=True,
331
- )
332
- scheduler_th.start()
333
- bckg_threads.append(scheduler_th)
345
+ command = ["flower-superexec", "--insecure"]
346
+ command += [
347
+ "--appio-api-address",
348
+ simulationio_address if is_simulation else io_address,
349
+ ]
350
+ command += [
351
+ "--plugin-type",
352
+ ExecPluginType.SIMULATION if is_simulation else ExecPluginType.SERVER_APP,
353
+ ]
354
+ command += ["--parent-pid", str(os.getpid())]
355
+ # pylint: disable-next=consider-using-with
356
+ subprocess.Popen(command)
357
+
358
+ # Launch gRPC health server
359
+ if health_server_address is not None:
360
+ health_server = run_health_server_grpc_no_tls(health_server_address)
361
+ grpc_servers.append(health_server)
334
362
 
335
363
  # Graceful shutdown
336
- register_exit_handlers(
364
+ register_signal_handlers(
337
365
  event_type=EventType.RUN_SUPERLINK_LEAVE,
338
366
  exit_message="SuperLink terminated gracefully.",
339
367
  grpc_servers=grpc_servers,
@@ -348,75 +376,6 @@ def run_superlink() -> None:
348
376
  flwr_exit(ExitCode.SUPERLINK_THREAD_CRASH)
349
377
 
350
378
 
351
- def _run_flwr_command(args: list[str], main_pid: int) -> None:
352
- # Monitor the main process in case of SIGKILL
353
- def main_process_monitor() -> None:
354
- while True:
355
- sleep(1)
356
- if os.getppid() != main_pid:
357
- os.kill(os.getpid(), 9)
358
-
359
- threading.Thread(target=main_process_monitor, daemon=True).start()
360
-
361
- # Run the command
362
- sys.argv = args
363
- if args[0] == "flwr-serverapp":
364
- flwr_serverapp()
365
- elif args[0] == "flwr-simulation":
366
- flwr_simulation()
367
- else:
368
- raise ValueError(f"Unknown command: {args[0]}")
369
-
370
-
371
- def _flwr_scheduler(
372
- state_factory: LinkStateFactory,
373
- io_api_arg: str,
374
- io_api_address: str,
375
- cmd: str,
376
- ) -> None:
377
- log(DEBUG, "Started %s scheduler thread.", cmd)
378
- state = state_factory.state()
379
- run_id_to_proc: dict[int, multiprocessing.context.SpawnProcess] = {}
380
-
381
- # Use the "spawn" start method for multiprocessing.
382
- mp_spawn_context = multiprocessing.get_context("spawn")
383
-
384
- # Periodically check for a pending run in the LinkState
385
- while True:
386
- sleep(0.1)
387
- pending_run_id = state.get_pending_run_id()
388
-
389
- if pending_run_id and pending_run_id not in run_id_to_proc:
390
-
391
- log(
392
- INFO,
393
- "Launching %s subprocess. Connects to SuperLink on %s",
394
- cmd,
395
- io_api_address,
396
- )
397
- # Start subprocess
398
- command = [
399
- cmd,
400
- "--run-once",
401
- io_api_arg,
402
- io_api_address,
403
- "--insecure",
404
- ]
405
-
406
- proc = mp_spawn_context.Process(
407
- target=_run_flwr_command, args=(command, os.getpid()), daemon=True
408
- )
409
- proc.start()
410
-
411
- # Store the process
412
- run_id_to_proc[pending_run_id] = proc
413
-
414
- # Clean up finished processes
415
- for run_id, proc in list(run_id_to_proc.items()):
416
- if not proc.is_alive():
417
- del run_id_to_proc[run_id]
418
-
419
-
420
379
  def _format_address(address: str) -> tuple[str, str, int]:
421
380
  parsed_address = parse_address(address)
422
381
  if not parsed_address:
@@ -470,10 +429,10 @@ def _try_load_public_keys_node_authentication(
470
429
  return node_public_keys
471
430
 
472
431
 
473
- def _try_obtain_exec_auth_plugins(
432
+ def _try_obtain_control_auth_plugins(
474
433
  config_path: Path, verify_tls_cert: bool
475
- ) -> tuple[ExecAuthPlugin, ExecAuthzPlugin]:
476
- """Obtain Exec API authentication and authorization plugins."""
434
+ ) -> tuple[ControlAuthPlugin, ControlAuthzPlugin]:
435
+ """Obtain Control API authentication and authorization plugins."""
477
436
  # Load YAML file
478
437
  with config_path.open("r", encoding="utf-8") as file:
479
438
  config: dict[str, Any] = yaml.safe_load(file)
@@ -503,24 +462,24 @@ def _try_obtain_exec_auth_plugins(
503
462
  auth_plugin = _load_plugin(
504
463
  section="authentication",
505
464
  yaml_key=AUTH_TYPE_YAML_KEY,
506
- loader=get_exec_auth_plugins,
465
+ loader=get_control_auth_plugins,
507
466
  )
508
467
 
509
468
  # Load authorization plugin
510
469
  authz_plugin = _load_plugin(
511
470
  section="authorization",
512
471
  yaml_key=AUTHZ_TYPE_YAML_KEY,
513
- loader=get_exec_authz_plugins,
472
+ loader=get_control_authz_plugins,
514
473
  )
515
474
 
516
475
  return auth_plugin, authz_plugin
517
476
 
518
477
 
519
- def _try_obtain_exec_event_log_writer_plugin() -> Optional[EventLogWriterPlugin]:
478
+ def _try_obtain_control_event_log_writer_plugin() -> Optional[EventLogWriterPlugin]:
520
479
  """Return an instance of the event log writer plugin."""
521
480
  try:
522
481
  all_plugins: dict[str, type[EventLogWriterPlugin]] = (
523
- get_exec_event_log_writer_plugins()
482
+ get_control_event_log_writer_plugins()
524
483
  )
525
484
  plugin_class = all_plugins[EventLogWriterType.STDOUT]
526
485
  return plugin_class()
@@ -568,7 +527,9 @@ def _run_fleet_api_grpc_rere( # pylint: disable=R0913, R0917
568
527
  interceptors=interceptors,
569
528
  )
570
529
 
571
- log(INFO, "Flower ECE: Starting Fleet API (gRPC-rere) on %s", address)
530
+ log(
531
+ INFO, "Flower Deployment Runtime: Starting Fleet API (gRPC-rere) on %s", address
532
+ )
572
533
  fleet_grpc_server.start()
573
534
 
574
535
  return fleet_grpc_server
@@ -596,7 +557,11 @@ def _run_fleet_api_grpc_adapter(
596
557
  certificates=certificates,
597
558
  )
598
559
 
599
- log(INFO, "Flower ECE: Starting Fleet API (GrpcAdapter) on %s", address)
560
+ log(
561
+ INFO,
562
+ "Flower Deployment Runtime: Starting Fleet API (GrpcAdapter) on %s",
563
+ address,
564
+ )
600
565
  fleet_grpc_server.start()
601
566
 
602
567
  return fleet_grpc_server
@@ -651,8 +616,9 @@ def _parse_args_run_superlink() -> argparse.ArgumentParser:
651
616
  add_ee_args_superlink(parser=parser)
652
617
  _add_args_serverappio_api(parser=parser)
653
618
  _add_args_fleet_api(parser=parser)
654
- _add_args_exec_api(parser=parser)
619
+ _add_args_control_api(parser=parser)
655
620
  _add_args_simulationio_api(parser=parser)
621
+ add_args_health(parser=parser)
656
622
 
657
623
  return parser
658
624
 
@@ -775,30 +741,41 @@ def _add_args_fleet_api(parser: argparse.ArgumentParser) -> None:
775
741
  )
776
742
 
777
743
 
778
- def _add_args_exec_api(parser: argparse.ArgumentParser) -> None:
779
- """Add command line arguments for Exec API."""
744
+ def _add_args_control_api(parser: argparse.ArgumentParser) -> None:
745
+ """Add command line arguments for Control API."""
746
+ parser.add_argument(
747
+ "--control-api-address",
748
+ help="Control API server address (IPv4, IPv6, or a domain name) "
749
+ f"By default, it is set to {CONTROL_API_DEFAULT_SERVER_ADDRESS}.",
750
+ default=CONTROL_API_DEFAULT_SERVER_ADDRESS,
751
+ )
780
752
  parser.add_argument(
781
753
  "--exec-api-address",
782
- help="Exec API server address (IPv4, IPv6, or a domain name) "
783
- f"By default, it is set to {EXEC_API_DEFAULT_SERVER_ADDRESS}.",
784
- default=EXEC_API_DEFAULT_SERVER_ADDRESS,
754
+ help="This argument is deprecated and will be removed in a future release. "
755
+ "Use `--control-api-address` instead.",
756
+ default=None,
785
757
  )
786
758
  parser.add_argument(
787
759
  "--executor",
788
- help="For example: `deployment:exec` or `project.package.module:wrapper.exec`. "
789
- "The default is `flwr.superexec.deployment:executor`",
790
- default="flwr.superexec.deployment:executor",
760
+ help="This argument is deprecated and will be removed in a future release.",
761
+ default=None,
791
762
  )
792
763
  parser.add_argument(
793
764
  "--executor-dir",
794
- help="The directory for the executor.",
795
- default=".",
765
+ help="This argument is deprecated and will be removed in a future release.",
766
+ default=None,
796
767
  )
797
768
  parser.add_argument(
798
769
  "--executor-config",
799
- help="Key-value pairs for the executor config, separated by spaces. "
800
- "For example:\n\n`--executor-config 'verbose=true "
801
- 'root-certificates="certificates/superlink-ca.crt"\'`',
770
+ help="This argument is deprecated and will be removed in a future release.",
771
+ default=None,
772
+ )
773
+ parser.add_argument(
774
+ "--simulation",
775
+ action="store_true",
776
+ default=False,
777
+ help="Launch the SimulationIo API server in place of "
778
+ "the ServerAppIo API server.",
802
779
  )
803
780
 
804
781
 
@@ -41,6 +41,10 @@ class FleetEventLogInterceptor(grpc.ServerInterceptor): # type: ignore
41
41
  if event logger is enabled on the SuperLink, else, terminate RPC call by setting
42
42
  context to abort.
43
43
  """
44
+ # Only apply to Fleet service
45
+ if not handler_call_details.method.startswith("/flwr.proto.Fleet/"):
46
+ return continuation(handler_call_details)
47
+
44
48
  # One of the method handlers in
45
49
  # `flwr.server.superlink.fleet.grpc_rere.fleet_servicer.FleetServicer`
46
50
  method_handler: grpc.RpcMethodHandler = continuation(handler_call_details)