flwr-nightly 1.10.0.dev20240618__py3-none-any.whl → 1.10.0.dev20240620__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 (98) hide show
  1. flwr/cli/app.py +3 -0
  2. flwr/cli/build.py +3 -7
  3. flwr/cli/new/new.py +1 -1
  4. flwr/cli/run/run.py +8 -1
  5. flwr/client/__init__.py +1 -1
  6. flwr/client/app.py +4 -0
  7. flwr/client/client_app.py +1 -1
  8. flwr/client/dpfedavg_numpy_client.py +1 -1
  9. flwr/client/grpc_rere_client/__init__.py +1 -1
  10. flwr/client/grpc_rere_client/connection.py +1 -1
  11. flwr/client/message_handler/__init__.py +1 -1
  12. flwr/client/message_handler/message_handler.py +1 -1
  13. flwr/client/mod/__init__.py +4 -4
  14. flwr/client/mod/secure_aggregation/__init__.py +1 -1
  15. flwr/client/mod/utils.py +1 -1
  16. flwr/client/rest_client/__init__.py +1 -1
  17. flwr/client/rest_client/connection.py +1 -1
  18. flwr/client/supernode/app.py +29 -6
  19. flwr/common/__init__.py +12 -12
  20. flwr/common/address.py +1 -1
  21. flwr/common/config.py +8 -6
  22. flwr/common/constant.py +5 -1
  23. flwr/common/date.py +1 -1
  24. flwr/common/dp.py +1 -1
  25. flwr/common/grpc.py +1 -1
  26. flwr/common/object_ref.py +39 -5
  27. flwr/common/record/__init__.py +1 -1
  28. flwr/common/secure_aggregation/__init__.py +1 -1
  29. flwr/common/secure_aggregation/crypto/__init__.py +1 -1
  30. flwr/common/secure_aggregation/crypto/shamir.py +1 -1
  31. flwr/common/secure_aggregation/crypto/symmetric_encryption.py +1 -1
  32. flwr/common/secure_aggregation/ndarrays_arithmetic.py +1 -1
  33. flwr/common/secure_aggregation/quantization.py +1 -1
  34. flwr/common/secure_aggregation/secaggplus_constants.py +1 -1
  35. flwr/common/secure_aggregation/secaggplus_utils.py +1 -1
  36. flwr/common/version.py +14 -0
  37. flwr/server/__init__.py +2 -2
  38. flwr/server/app.py +47 -7
  39. flwr/server/compat/app.py +1 -1
  40. flwr/server/compat/app_utils.py +1 -1
  41. flwr/server/compat/driver_client_proxy.py +1 -1
  42. flwr/server/driver/driver.py +6 -0
  43. flwr/server/driver/grpc_driver.py +85 -63
  44. flwr/server/driver/inmemory_driver.py +28 -26
  45. flwr/server/run_serverapp.py +15 -8
  46. flwr/server/strategy/__init__.py +2 -2
  47. flwr/server/strategy/bulyan.py +1 -1
  48. flwr/server/strategy/dpfedavg_adaptive.py +1 -1
  49. flwr/server/strategy/dpfedavg_fixed.py +1 -1
  50. flwr/server/strategy/fedadagrad.py +1 -1
  51. flwr/server/strategy/fedadam.py +1 -1
  52. flwr/server/strategy/fedavg_android.py +1 -1
  53. flwr/server/strategy/fedavgm.py +1 -1
  54. flwr/server/strategy/fedmedian.py +1 -1
  55. flwr/server/strategy/fedopt.py +1 -1
  56. flwr/server/strategy/fedprox.py +1 -1
  57. flwr/server/strategy/fedxgb_bagging.py +1 -1
  58. flwr/server/strategy/fedxgb_cyclic.py +1 -1
  59. flwr/server/strategy/fedxgb_nn_avg.py +1 -1
  60. flwr/server/strategy/fedyogi.py +1 -1
  61. flwr/server/strategy/krum.py +1 -1
  62. flwr/server/strategy/qfedavg.py +1 -1
  63. flwr/server/superlink/driver/__init__.py +1 -1
  64. flwr/server/superlink/driver/driver_grpc.py +1 -1
  65. flwr/server/superlink/driver/driver_servicer.py +15 -3
  66. flwr/server/superlink/fleet/__init__.py +1 -1
  67. flwr/server/superlink/fleet/grpc_adapter/__init__.py +15 -0
  68. flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +131 -0
  69. flwr/server/superlink/fleet/grpc_bidi/__init__.py +1 -1
  70. flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +1 -1
  71. flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +1 -1
  72. flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +1 -1
  73. flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +5 -1
  74. flwr/server/superlink/fleet/grpc_rere/__init__.py +1 -1
  75. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +1 -1
  76. flwr/server/superlink/fleet/message_handler/__init__.py +1 -1
  77. flwr/server/superlink/fleet/message_handler/message_handler.py +1 -1
  78. flwr/server/superlink/fleet/rest_rere/__init__.py +1 -1
  79. flwr/server/superlink/fleet/rest_rere/rest_api.py +1 -1
  80. flwr/server/superlink/fleet/vce/vce_api.py +1 -1
  81. flwr/server/superlink/state/__init__.py +1 -1
  82. flwr/server/superlink/state/in_memory_state.py +1 -1
  83. flwr/server/superlink/state/sqlite_state.py +1 -1
  84. flwr/server/superlink/state/state.py +1 -1
  85. flwr/server/superlink/state/state_factory.py +11 -2
  86. flwr/server/utils/__init__.py +1 -1
  87. flwr/server/utils/tensorboard.py +1 -1
  88. flwr/simulation/__init__.py +5 -2
  89. flwr/simulation/app.py +1 -1
  90. flwr/simulation/ray_transport/__init__.py +1 -1
  91. flwr/simulation/ray_transport/ray_client_proxy.py +1 -1
  92. flwr/simulation/run_simulation.py +15 -8
  93. flwr/superexec/app.py +1 -1
  94. {flwr_nightly-1.10.0.dev20240618.dist-info → flwr_nightly-1.10.0.dev20240620.dist-info}/METADATA +2 -1
  95. {flwr_nightly-1.10.0.dev20240618.dist-info → flwr_nightly-1.10.0.dev20240620.dist-info}/RECORD +98 -96
  96. {flwr_nightly-1.10.0.dev20240618.dist-info → flwr_nightly-1.10.0.dev20240620.dist-info}/LICENSE +0 -0
  97. {flwr_nightly-1.10.0.dev20240618.dist-info → flwr_nightly-1.10.0.dev20240620.dist-info}/WHEEL +0 -0
  98. {flwr_nightly-1.10.0.dev20240618.dist-info → flwr_nightly-1.10.0.dev20240620.dist-info}/entry_points.txt +0 -0
flwr/cli/app.py CHANGED
@@ -15,6 +15,7 @@
15
15
  """Flower command line interface."""
16
16
 
17
17
  import typer
18
+ from typer.main import get_command
18
19
 
19
20
  from .build import build
20
21
  from .example import example
@@ -37,5 +38,7 @@ app.command()(run)
37
38
  app.command()(build)
38
39
  app.command()(install)
39
40
 
41
+ typer_click_object = get_command(app)
42
+
40
43
  if __name__ == "__main__":
41
44
  app()
flwr/cli/build.py CHANGED
@@ -36,13 +36,9 @@ def build(
36
36
  ) -> str:
37
37
  """Build a Flower project into a Flower App Bundle (FAB).
38
38
 
39
- You can run `flwr build` without any argument to bundle the current directory:
40
-
41
- `flwr build`
42
-
43
- You can also build a specific directory:
44
-
45
- `flwr build --directory ./projects/flower-hello-world`
39
+ You can run ``flwr build`` without any arguments to bundle the current directory,
40
+ or you can use ``--directory`` to build a specific directory:
41
+ ``flwr build --directory ./projects/flower-hello-world``.
46
42
  """
47
43
  if directory is None:
48
44
  directory = Path.cwd()
flwr/cli/new/new.py CHANGED
@@ -190,7 +190,7 @@ def new(
190
190
  )
191
191
  print(
192
192
  typer.style(
193
- f" cd {project_name}\n" + " pip install -e .\n flwr run\n",
193
+ f" cd {package_name}\n" + " pip install -e .\n flwr run\n",
194
194
  fg=typer.colors.BRIGHT_CYAN,
195
195
  bold=True,
196
196
  )
flwr/cli/run/run.py CHANGED
@@ -41,7 +41,10 @@ class Engine(str, Enum):
41
41
  def run(
42
42
  engine: Annotated[
43
43
  Optional[Engine],
44
- typer.Option(case_sensitive=False, help="The execution engine to run the app"),
44
+ typer.Option(
45
+ case_sensitive=False,
46
+ help="The engine to run FL with (currently only simulation is supported).",
47
+ ),
45
48
  ] = None,
46
49
  use_superexec: Annotated[
47
50
  bool,
@@ -87,12 +90,16 @@ def run(
87
90
 
88
91
  if engine == Engine.SIMULATION:
89
92
  num_supernodes = config["flower"]["engine"]["simulation"]["supernode"]["num"]
93
+ backend_config = config["flower"]["engine"]["simulation"].get(
94
+ "backend_config", None
95
+ )
90
96
 
91
97
  typer.secho("Starting run... ", fg=typer.colors.BLUE)
92
98
  _run_simulation(
93
99
  server_app_attr=server_app_ref,
94
100
  client_app_attr=client_app_ref,
95
101
  num_supernodes=num_supernodes,
102
+ backend_config=backend_config,
96
103
  )
97
104
  else:
98
105
  typer.secho(
flwr/client/__init__.py CHANGED
@@ -28,8 +28,8 @@ __all__ = [
28
28
  "Client",
29
29
  "ClientApp",
30
30
  "ClientFn",
31
- "mod",
32
31
  "NumPyClient",
32
+ "mod",
33
33
  "run_client_app",
34
34
  "run_supernode",
35
35
  "start_client",
flwr/client/app.py CHANGED
@@ -31,6 +31,7 @@ from flwr.common import GRPC_MAX_MESSAGE_LENGTH, EventType, Message, event
31
31
  from flwr.common.address import parse_address
32
32
  from flwr.common.constant import (
33
33
  MISSING_EXTRA_REST,
34
+ TRANSPORT_TYPE_GRPC_ADAPTER,
34
35
  TRANSPORT_TYPE_GRPC_BIDI,
35
36
  TRANSPORT_TYPE_GRPC_RERE,
36
37
  TRANSPORT_TYPE_REST,
@@ -41,6 +42,7 @@ from flwr.common.logger import log, warn_deprecated_feature
41
42
  from flwr.common.message import Error
42
43
  from flwr.common.retry_invoker import RetryInvoker, RetryState, exponential
43
44
 
45
+ from .grpc_adapter_client.connection import grpc_adapter
44
46
  from .grpc_client.connection import grpc_connection
45
47
  from .grpc_rere_client.connection import grpc_request_response
46
48
  from .message_handler.message_handler import handle_control_message
@@ -600,6 +602,8 @@ def _init_connection(transport: Optional[str], server_address: str) -> Tuple[
600
602
  connection, error_type = http_request_response, RequestsConnectionError
601
603
  elif transport == TRANSPORT_TYPE_GRPC_RERE:
602
604
  connection, error_type = grpc_request_response, RpcError
605
+ elif transport == TRANSPORT_TYPE_GRPC_ADAPTER:
606
+ connection, error_type = grpc_adapter, RpcError
603
607
  elif transport == TRANSPORT_TYPE_GRPC_BIDI:
604
608
  connection, error_type = grpc_connection, RpcError
605
609
  else:
flwr/client/client_app.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2022 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2022 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2022 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -22,12 +22,12 @@ from .secure_aggregation import secagg_mod, secaggplus_mod
22
22
  from .utils import make_ffn
23
23
 
24
24
  __all__ = [
25
+ "LocalDpMod",
25
26
  "adaptiveclipping_mod",
26
27
  "fixedclipping_mod",
27
- "LocalDpMod",
28
28
  "make_ffn",
29
- "secagg_mod",
30
- "secaggplus_mod",
31
29
  "message_size_mod",
32
30
  "parameters_size_mod",
31
+ "secagg_mod",
32
+ "secaggplus_mod",
33
33
  ]
@@ -1,4 +1,4 @@
1
- # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
flwr/client/mod/utils.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -30,6 +30,11 @@ from cryptography.hazmat.primitives.serialization import (
30
30
  from flwr.client.client_app import ClientApp, LoadClientAppError
31
31
  from flwr.common import EventType, event
32
32
  from flwr.common.config import get_flwr_dir, get_project_config, get_project_dir
33
+ from flwr.common.constant import (
34
+ TRANSPORT_TYPE_GRPC_ADAPTER,
35
+ TRANSPORT_TYPE_GRPC_RERE,
36
+ TRANSPORT_TYPE_REST,
37
+ )
33
38
  from flwr.common.exit_handlers import register_exit_handlers
34
39
  from flwr.common.logger import log, warn_deprecated_feature
35
40
  from flwr.common.object_ref import load_app, validate
@@ -56,7 +61,7 @@ def run_supernode() -> None:
56
61
  _start_client_internal(
57
62
  server_address=args.superlink,
58
63
  load_client_app_fn=load_fn,
59
- transport="rest" if args.rest else "grpc-rere",
64
+ transport=args.transport,
60
65
  root_certificates=root_certificates,
61
66
  insecure=args.insecure,
62
67
  authentication_keys=authentication_keys,
@@ -87,7 +92,7 @@ def run_client_app() -> None:
87
92
  _start_client_internal(
88
93
  server_address=args.superlink,
89
94
  load_client_app_fn=load_fn,
90
- transport="rest" if args.rest else "grpc-rere",
95
+ transport=args.transport,
91
96
  root_certificates=root_certificates,
92
97
  insecure=args.insecure,
93
98
  authentication_keys=authentication_keys,
@@ -230,7 +235,7 @@ def _get_load_client_app_fn(
230
235
  "Loading ClientApp `%s`",
231
236
  client_app_ref,
232
237
  )
233
- client_app = load_app(client_app_ref, LoadClientAppError)
238
+ client_app = load_app(client_app_ref, LoadClientAppError, sys_path)
234
239
 
235
240
  if not isinstance(client_app, ClientApp):
236
241
  raise LoadClientAppError(
@@ -262,7 +267,7 @@ def _parse_args_run_supernode() -> argparse.ArgumentParser:
262
267
  "--flwr-dir",
263
268
  default=None,
264
269
  help="""The path containing installed Flower Apps.
265
- By default, this value isequal to:
270
+ By default, this value is equal to:
266
271
 
267
272
  - `$FLWR_HOME/` if `$FLWR_HOME` is defined
268
273
  - `$XDG_DATA_HOME/.flwr/` if `$XDG_DATA_HOME` is defined
@@ -295,9 +300,27 @@ def _parse_args_common(parser: argparse.ArgumentParser) -> None:
295
300
  help="Run the client without HTTPS. By default, the client runs with "
296
301
  "HTTPS enabled. Use this flag only if you understand the risks.",
297
302
  )
298
- parser.add_argument(
303
+ ex_group = parser.add_mutually_exclusive_group()
304
+ ex_group.add_argument(
305
+ "--grpc-rere",
306
+ action="store_const",
307
+ dest="transport",
308
+ const=TRANSPORT_TYPE_GRPC_RERE,
309
+ default=TRANSPORT_TYPE_GRPC_RERE,
310
+ help="Use grpc-rere as a transport layer for the client.",
311
+ )
312
+ ex_group.add_argument(
313
+ "--grpc-adapter",
314
+ action="store_const",
315
+ dest="transport",
316
+ const=TRANSPORT_TYPE_GRPC_ADAPTER,
317
+ help="Use grpc-adapter as a transport layer for the client.",
318
+ )
319
+ ex_group.add_argument(
299
320
  "--rest",
300
- action="store_true",
321
+ action="store_const",
322
+ dest="transport",
323
+ const=TRANSPORT_TYPE_REST,
301
324
  help="Use REST as a transport layer for the client.",
302
325
  )
303
326
  parser.add_argument(
flwr/common/__init__.py CHANGED
@@ -63,43 +63,34 @@ from .typing import Status as Status
63
63
 
64
64
  __all__ = [
65
65
  "Array",
66
- "array_from_numpy",
67
- "bytes_to_ndarray",
68
66
  "ClientMessage",
69
67
  "Code",
70
68
  "Config",
71
69
  "ConfigsRecord",
72
- "configure",
73
70
  "Context",
71
+ "DEFAULT_TTL",
74
72
  "DisconnectRes",
73
+ "Error",
75
74
  "EvaluateIns",
76
75
  "EvaluateRes",
77
- "event",
78
76
  "EventType",
79
77
  "FitIns",
80
78
  "FitRes",
81
- "Error",
79
+ "GRPC_MAX_MESSAGE_LENGTH",
82
80
  "GetParametersIns",
83
81
  "GetParametersRes",
84
82
  "GetPropertiesIns",
85
83
  "GetPropertiesRes",
86
- "GRPC_MAX_MESSAGE_LENGTH",
87
- "log",
88
84
  "Message",
89
85
  "MessageType",
90
86
  "MessageTypeLegacy",
91
- "DEFAULT_TTL",
92
87
  "Metadata",
93
88
  "Metrics",
94
89
  "MetricsAggregationFn",
95
90
  "MetricsRecord",
96
- "ndarray_to_bytes",
97
- "now",
98
91
  "NDArray",
99
92
  "NDArrays",
100
- "ndarrays_to_parameters",
101
93
  "Parameters",
102
- "parameters_to_ndarrays",
103
94
  "ParametersRecord",
104
95
  "Properties",
105
96
  "ReconnectIns",
@@ -107,4 +98,13 @@ __all__ = [
107
98
  "Scalar",
108
99
  "ServerMessage",
109
100
  "Status",
101
+ "array_from_numpy",
102
+ "bytes_to_ndarray",
103
+ "configure",
104
+ "event",
105
+ "log",
106
+ "ndarray_to_bytes",
107
+ "ndarrays_to_parameters",
108
+ "now",
109
+ "parameters_to_ndarrays",
110
110
  ]
flwr/common/address.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
flwr/common/config.py CHANGED
@@ -24,14 +24,16 @@ from flwr.cli.config_utils import validate_fields
24
24
  from flwr.common.constant import APP_DIR, FAB_CONFIG_FILE, FLWR_HOME
25
25
 
26
26
 
27
- def get_flwr_dir() -> Path:
27
+ def get_flwr_dir(provided_path: Optional[str] = None) -> Path:
28
28
  """Return the Flower home directory based on env variables."""
29
- return Path(
30
- os.getenv(
31
- FLWR_HOME,
32
- f"{os.getenv('XDG_DATA_HOME', os.getenv('HOME'))}/.flwr",
29
+ if provided_path is None or not Path(provided_path).is_dir():
30
+ return Path(
31
+ os.getenv(
32
+ FLWR_HOME,
33
+ f"{os.getenv('XDG_DATA_HOME', os.getenv('HOME'))}/.flwr",
34
+ )
33
35
  )
34
- )
36
+ return Path(provided_path).absolute()
35
37
 
36
38
 
37
39
  def get_project_dir(
flwr/common/constant.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@ To use the REST API, install `flwr` with the `rest` extra:
27
27
 
28
28
  TRANSPORT_TYPE_GRPC_BIDI = "grpc-bidi"
29
29
  TRANSPORT_TYPE_GRPC_RERE = "grpc-rere"
30
+ TRANSPORT_TYPE_GRPC_ADAPTER = "grpc-adapter"
30
31
  TRANSPORT_TYPE_REST = "rest"
31
32
  TRANSPORT_TYPE_VCE = "vce"
32
33
  TRANSPORT_TYPES = [
@@ -45,6 +46,9 @@ PING_BASE_MULTIPLIER = 0.8
45
46
  PING_RANDOM_RANGE = (-0.1, 0.1)
46
47
  PING_MAX_INTERVAL = 1e300
47
48
 
49
+ GRPC_ADAPTER_METADATA_FLOWER_VERSION_KEY = "flower-version"
50
+ GRPC_ADAPTER_METADATA_SHOULD_EXIT_KEY = "should-exit"
51
+
48
52
  # Constants for FAB
49
53
  APP_DIR = "apps"
50
54
  FAB_CONFIG_FILE = "pyproject.toml"
flwr/common/date.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
flwr/common/dp.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2022 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
flwr/common/grpc.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2022 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
flwr/common/object_ref.py CHANGED
@@ -17,8 +17,13 @@
17
17
 
18
18
  import ast
19
19
  import importlib
20
+ import sys
20
21
  from importlib.util import find_spec
21
- from typing import Any, Optional, Tuple, Type
22
+ from logging import WARN
23
+ from pathlib import Path
24
+ from typing import Any, Optional, Tuple, Type, Union
25
+
26
+ from .logger import log
22
27
 
23
28
  OBJECT_REF_HELP_STR = """
24
29
  \n\nThe object reference string should have the form <module>:<attribute>. Valid
@@ -77,9 +82,10 @@ def validate(
77
82
  )
78
83
 
79
84
 
80
- def load_app(
85
+ def load_app( # pylint: disable= too-many-branches
81
86
  module_attribute_str: str,
82
87
  error_type: Type[Exception],
88
+ project_dir: Optional[Union[str, Path]] = None,
83
89
  ) -> Any:
84
90
  """Return the object specified in a module attribute string.
85
91
 
@@ -95,11 +101,39 @@ def load_app(
95
101
  module_str, _, attributes_str = module_attribute_str.partition(":")
96
102
 
97
103
  try:
98
- module = importlib.import_module(module_str)
99
- except ModuleNotFoundError:
104
+ if module_str not in sys.modules:
105
+ module = importlib.import_module(module_str)
106
+ # Hack: `tabnet` does not work with `importlib.reload`
107
+ elif "tabnet" in sys.modules:
108
+ log(
109
+ WARN,
110
+ "Cannot reload module `%s` from disk due to compatibility issues "
111
+ "with the `tabnet` library. The module will be loaded from the "
112
+ "cache instead. If you experience issues, consider restarting "
113
+ "the application.",
114
+ module_str,
115
+ )
116
+ module = sys.modules[module_str]
117
+ else:
118
+ module = sys.modules[module_str]
119
+ if project_dir is None:
120
+ path: Optional[str] = getattr(module, "__file__", None)
121
+ if path is not None:
122
+ project_dir = str(Path(path).parent)
123
+ else:
124
+ project_dir = str(Path(project_dir).absolute())
125
+
126
+ # Reload cached modules in the project directory
127
+ if project_dir is not None:
128
+ for m in list(sys.modules.values()):
129
+ path = getattr(m, "__file__", None)
130
+ if path is not None and path.startswith(project_dir):
131
+ importlib.reload(m)
132
+
133
+ except ModuleNotFoundError as err:
100
134
  raise error_type(
101
135
  f"Unable to load module {module_str}{OBJECT_REF_HELP_STR}",
102
- ) from None
136
+ ) from err
103
137
 
104
138
  # Recursively load attribute
105
139
  attribute = module
@@ -22,9 +22,9 @@ from .recordset import RecordSet
22
22
 
23
23
  __all__ = [
24
24
  "Array",
25
- "array_from_numpy",
26
25
  "ConfigsRecord",
27
26
  "MetricsRecord",
28
27
  "ParametersRecord",
29
28
  "RecordSet",
29
+ "array_from_numpy",
30
30
  ]
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
flwr/common/version.py CHANGED
@@ -1,3 +1,17 @@
1
+ # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ # ==============================================================================
1
15
  """Flower package version helper."""
2
16
 
3
17
  import importlib.metadata as importlib_metadata
flwr/server/__init__.py CHANGED
@@ -34,12 +34,12 @@ __all__ = [
34
34
  "Driver",
35
35
  "History",
36
36
  "LegacyContext",
37
- "run_server_app",
38
- "run_superlink",
39
37
  "Server",
40
38
  "ServerApp",
41
39
  "ServerConfig",
42
40
  "SimpleClientManager",
41
+ "run_server_app",
42
+ "run_superlink",
43
43
  "start_server",
44
44
  "strategy",
45
45
  "workflow",