flwr-nightly 1.10.0.dev20240612__py3-none-any.whl → 1.10.0.dev20240624__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 (130) hide show
  1. flwr/cli/app.py +3 -0
  2. flwr/cli/build.py +6 -8
  3. flwr/cli/config_utils.py +53 -3
  4. flwr/cli/install.py +35 -20
  5. flwr/cli/new/new.py +104 -28
  6. flwr/cli/new/templates/app/README.flowertune.md.tpl +56 -0
  7. flwr/cli/new/templates/app/code/flwr_tune/__init__.py +15 -0
  8. flwr/cli/new/templates/app/code/flwr_tune/app.py.tpl +86 -0
  9. flwr/cli/new/templates/app/code/flwr_tune/client.py.tpl +124 -0
  10. flwr/cli/new/templates/app/code/flwr_tune/config.yaml.tpl +34 -0
  11. flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +57 -0
  12. flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +59 -0
  13. flwr/cli/new/templates/app/code/flwr_tune/server.py.tpl +48 -0
  14. flwr/cli/new/templates/app/code/flwr_tune/static_config.yaml.tpl +11 -0
  15. flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +42 -0
  16. flwr/cli/run/run.py +46 -2
  17. flwr/client/__init__.py +1 -1
  18. flwr/client/app.py +22 -10
  19. flwr/client/client_app.py +1 -1
  20. flwr/client/dpfedavg_numpy_client.py +1 -1
  21. flwr/client/grpc_adapter_client/__init__.py +15 -0
  22. flwr/client/grpc_adapter_client/connection.py +94 -0
  23. flwr/client/grpc_client/connection.py +5 -1
  24. flwr/client/grpc_rere_client/__init__.py +1 -1
  25. flwr/client/grpc_rere_client/connection.py +9 -2
  26. flwr/client/grpc_rere_client/grpc_adapter.py +133 -0
  27. flwr/client/message_handler/__init__.py +1 -1
  28. flwr/client/message_handler/message_handler.py +1 -1
  29. flwr/client/mod/__init__.py +4 -4
  30. flwr/client/mod/secure_aggregation/__init__.py +1 -1
  31. flwr/client/mod/utils.py +1 -1
  32. flwr/client/rest_client/__init__.py +1 -1
  33. flwr/client/rest_client/connection.py +10 -2
  34. flwr/client/supernode/app.py +141 -41
  35. flwr/common/__init__.py +12 -12
  36. flwr/common/address.py +1 -1
  37. flwr/common/config.py +73 -0
  38. flwr/common/constant.py +16 -1
  39. flwr/common/date.py +1 -1
  40. flwr/common/dp.py +1 -1
  41. flwr/common/grpc.py +1 -1
  42. flwr/common/object_ref.py +39 -5
  43. flwr/common/record/__init__.py +1 -1
  44. flwr/common/secure_aggregation/__init__.py +1 -1
  45. flwr/common/secure_aggregation/crypto/__init__.py +1 -1
  46. flwr/common/secure_aggregation/crypto/shamir.py +1 -1
  47. flwr/common/secure_aggregation/crypto/symmetric_encryption.py +1 -1
  48. flwr/common/secure_aggregation/ndarrays_arithmetic.py +1 -1
  49. flwr/common/secure_aggregation/quantization.py +1 -1
  50. flwr/common/secure_aggregation/secaggplus_constants.py +1 -1
  51. flwr/common/secure_aggregation/secaggplus_utils.py +1 -1
  52. flwr/common/telemetry.py +4 -0
  53. flwr/common/typing.py +9 -0
  54. flwr/common/version.py +14 -0
  55. flwr/proto/exec_pb2.py +34 -0
  56. flwr/proto/exec_pb2.pyi +55 -0
  57. flwr/proto/exec_pb2_grpc.py +101 -0
  58. flwr/proto/exec_pb2_grpc.pyi +41 -0
  59. flwr/proto/fab_pb2.py +30 -0
  60. flwr/proto/fab_pb2.pyi +56 -0
  61. flwr/proto/fab_pb2_grpc.py +4 -0
  62. flwr/proto/fab_pb2_grpc.pyi +4 -0
  63. flwr/server/__init__.py +2 -2
  64. flwr/server/app.py +62 -25
  65. flwr/server/compat/app.py +1 -1
  66. flwr/server/compat/app_utils.py +1 -1
  67. flwr/server/compat/driver_client_proxy.py +1 -1
  68. flwr/server/driver/driver.py +6 -0
  69. flwr/server/driver/grpc_driver.py +85 -63
  70. flwr/server/driver/inmemory_driver.py +28 -26
  71. flwr/server/run_serverapp.py +65 -20
  72. flwr/server/strategy/__init__.py +2 -2
  73. flwr/server/strategy/bulyan.py +1 -1
  74. flwr/server/strategy/dpfedavg_adaptive.py +1 -1
  75. flwr/server/strategy/dpfedavg_fixed.py +1 -1
  76. flwr/server/strategy/fedadagrad.py +1 -1
  77. flwr/server/strategy/fedadam.py +1 -1
  78. flwr/server/strategy/fedavg_android.py +1 -1
  79. flwr/server/strategy/fedavgm.py +1 -1
  80. flwr/server/strategy/fedmedian.py +1 -1
  81. flwr/server/strategy/fedopt.py +1 -1
  82. flwr/server/strategy/fedprox.py +1 -1
  83. flwr/server/strategy/fedxgb_bagging.py +1 -1
  84. flwr/server/strategy/fedxgb_cyclic.py +1 -1
  85. flwr/server/strategy/fedxgb_nn_avg.py +1 -1
  86. flwr/server/strategy/fedyogi.py +1 -1
  87. flwr/server/strategy/krum.py +1 -1
  88. flwr/server/strategy/qfedavg.py +1 -1
  89. flwr/server/superlink/driver/__init__.py +1 -1
  90. flwr/server/superlink/driver/driver_grpc.py +1 -1
  91. flwr/server/superlink/driver/driver_servicer.py +15 -3
  92. flwr/server/superlink/fleet/__init__.py +1 -1
  93. flwr/server/superlink/fleet/grpc_adapter/__init__.py +15 -0
  94. flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +131 -0
  95. flwr/server/superlink/fleet/grpc_bidi/__init__.py +1 -1
  96. flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +1 -1
  97. flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +1 -1
  98. flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +1 -1
  99. flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +5 -1
  100. flwr/server/superlink/fleet/grpc_rere/__init__.py +1 -1
  101. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +1 -1
  102. flwr/server/superlink/fleet/message_handler/__init__.py +1 -1
  103. flwr/server/superlink/fleet/message_handler/message_handler.py +4 -4
  104. flwr/server/superlink/fleet/rest_rere/__init__.py +1 -1
  105. flwr/server/superlink/fleet/rest_rere/rest_api.py +1 -1
  106. flwr/server/superlink/fleet/vce/backend/raybackend.py +44 -25
  107. flwr/server/superlink/fleet/vce/vce_api.py +3 -1
  108. flwr/server/superlink/state/__init__.py +1 -1
  109. flwr/server/superlink/state/in_memory_state.py +9 -6
  110. flwr/server/superlink/state/sqlite_state.py +7 -4
  111. flwr/server/superlink/state/state.py +6 -5
  112. flwr/server/superlink/state/state_factory.py +11 -2
  113. flwr/server/utils/__init__.py +1 -1
  114. flwr/server/utils/tensorboard.py +1 -1
  115. flwr/simulation/__init__.py +5 -2
  116. flwr/simulation/app.py +1 -1
  117. flwr/simulation/ray_transport/__init__.py +1 -1
  118. flwr/simulation/ray_transport/ray_actor.py +0 -6
  119. flwr/simulation/ray_transport/ray_client_proxy.py +1 -1
  120. flwr/simulation/run_simulation.py +63 -22
  121. flwr/superexec/__init__.py +21 -0
  122. flwr/superexec/app.py +178 -0
  123. flwr/superexec/exec_grpc.py +51 -0
  124. flwr/superexec/exec_servicer.py +65 -0
  125. flwr/superexec/executor.py +54 -0
  126. {flwr_nightly-1.10.0.dev20240612.dist-info → flwr_nightly-1.10.0.dev20240624.dist-info}/METADATA +2 -1
  127. {flwr_nightly-1.10.0.dev20240612.dist-info → flwr_nightly-1.10.0.dev20240624.dist-info}/RECORD +130 -101
  128. {flwr_nightly-1.10.0.dev20240612.dist-info → flwr_nightly-1.10.0.dev20240624.dist-info}/entry_points.txt +1 -0
  129. {flwr_nightly-1.10.0.dev20240612.dist-info → flwr_nightly-1.10.0.dev20240624.dist-info}/LICENSE +0 -0
  130. {flwr_nightly-1.10.0.dev20240612.dist-info → flwr_nightly-1.10.0.dev20240624.dist-info}/WHEEL +0 -0
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 ADDED
@@ -0,0 +1,73 @@
1
+ # Copyright 2024 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
+ # ==============================================================================
15
+ """Provide functions for managing global Flower config."""
16
+
17
+ import os
18
+ from pathlib import Path
19
+ from typing import Any, Dict, Optional, Union
20
+
21
+ import tomli
22
+
23
+ from flwr.cli.config_utils import validate_fields
24
+ from flwr.common.constant import APP_DIR, FAB_CONFIG_FILE, FLWR_HOME
25
+
26
+
27
+ def get_flwr_dir(provided_path: Optional[str] = None) -> Path:
28
+ """Return the Flower home directory based on env variables."""
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
+ )
35
+ )
36
+ return Path(provided_path).absolute()
37
+
38
+
39
+ def get_project_dir(
40
+ fab_id: str, fab_version: str, flwr_dir: Optional[Union[str, Path]] = None
41
+ ) -> Path:
42
+ """Return the project directory based on the given fab_id and fab_version."""
43
+ # Check the fab_id
44
+ if fab_id.count("/") != 1:
45
+ raise ValueError(
46
+ f"Invalid FAB ID: {fab_id}",
47
+ )
48
+ publisher, project_name = fab_id.split("/")
49
+ if flwr_dir is None:
50
+ flwr_dir = get_flwr_dir()
51
+ return Path(flwr_dir) / APP_DIR / publisher / project_name / fab_version
52
+
53
+
54
+ def get_project_config(project_dir: Union[str, Path]) -> Dict[str, Any]:
55
+ """Return pyproject.toml in the given project directory."""
56
+ # Load pyproject.toml file
57
+ toml_path = Path(project_dir) / FAB_CONFIG_FILE
58
+ if not toml_path.is_file():
59
+ raise FileNotFoundError(
60
+ f"Cannot find {FAB_CONFIG_FILE} in {project_dir}",
61
+ )
62
+ with toml_path.open(encoding="utf-8") as toml_file:
63
+ config = tomli.loads(toml_file.read())
64
+
65
+ # Validate pyproject.toml fields
66
+ is_valid, errors, _ = validate_fields(config)
67
+ if not is_valid:
68
+ error_msg = "\n".join([f" - {error}" for error in errors])
69
+ raise ValueError(
70
+ f"Invalid {FAB_CONFIG_FILE}:\n{error_msg}",
71
+ )
72
+
73
+ return config
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 = [
@@ -36,6 +37,8 @@ TRANSPORT_TYPES = [
36
37
  TRANSPORT_TYPE_VCE,
37
38
  ]
38
39
 
40
+ SUPEREXEC_DEFAULT_ADDRESS = "0.0.0.0:9093"
41
+
39
42
  # Constants for ping
40
43
  PING_DEFAULT_INTERVAL = 30
41
44
  PING_CALL_TIMEOUT = 5
@@ -43,6 +46,18 @@ PING_BASE_MULTIPLIER = 0.8
43
46
  PING_RANDOM_RANGE = (-0.1, 0.1)
44
47
  PING_MAX_INTERVAL = 1e300
45
48
 
49
+ GRPC_ADAPTER_METADATA_FLOWER_VERSION_KEY = "flower-version"
50
+ GRPC_ADAPTER_METADATA_SHOULD_EXIT_KEY = "should-exit"
51
+
52
+ # Constants for FAB
53
+ APP_DIR = "apps"
54
+ FAB_CONFIG_FILE = "pyproject.toml"
55
+ FLWR_HOME = "FLWR_HOME"
56
+
57
+
58
+ GRPC_ADAPTER_METADATA_FLOWER_VERSION_KEY = "flower-version"
59
+ GRPC_ADAPTER_METADATA_SHOULD_EXIT_KEY = "should-exit"
60
+
46
61
 
47
62
  class MessageType:
48
63
  """Message type."""
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/telemetry.py CHANGED
@@ -164,6 +164,10 @@ class EventType(str, Enum):
164
164
  RUN_SUPERNODE_ENTER = auto()
165
165
  RUN_SUPERNODE_LEAVE = auto()
166
166
 
167
+ # SuperExec
168
+ RUN_SUPEREXEC_ENTER = auto()
169
+ RUN_SUPEREXEC_LEAVE = auto()
170
+
167
171
 
168
172
  # Use the ThreadPoolExecutor with max_workers=1 to have a queue
169
173
  # and also ensure that telemetry calls are not blocking.
flwr/common/typing.py CHANGED
@@ -185,3 +185,12 @@ class ClientMessage:
185
185
  get_parameters_res: Optional[GetParametersRes] = None
186
186
  fit_res: Optional[FitRes] = None
187
187
  evaluate_res: Optional[EvaluateRes] = None
188
+
189
+
190
+ @dataclass
191
+ class Run:
192
+ """Run details."""
193
+
194
+ run_id: int
195
+ fab_id: str
196
+ fab_version: str
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/proto/exec_pb2.py ADDED
@@ -0,0 +1,34 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: flwr/proto/exec.proto
4
+ # Protobuf Python Version: 4.25.0
5
+ """Generated protocol buffer code."""
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ from google.protobuf.internal import builder as _builder
10
+ # @@protoc_insertion_point(imports)
11
+
12
+ _sym_db = _symbol_database.Default()
13
+
14
+
15
+
16
+
17
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/exec.proto\x12\nflwr.proto\"#\n\x0fStartRunRequest\x12\x10\n\x08\x66\x61\x62_file\x18\x01 \x01(\x0c\"\"\n\x10StartRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"#\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"(\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t2\xa0\x01\n\x04\x45xec\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\x00\x12O\n\nStreamLogs\x12\x1d.flwr.proto.StreamLogsRequest\x1a\x1e.flwr.proto.StreamLogsResponse\"\x00\x30\x01\x62\x06proto3')
18
+
19
+ _globals = globals()
20
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
21
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.exec_pb2', _globals)
22
+ if _descriptor._USE_C_DESCRIPTORS == False:
23
+ DESCRIPTOR._options = None
24
+ _globals['_STARTRUNREQUEST']._serialized_start=37
25
+ _globals['_STARTRUNREQUEST']._serialized_end=72
26
+ _globals['_STARTRUNRESPONSE']._serialized_start=74
27
+ _globals['_STARTRUNRESPONSE']._serialized_end=108
28
+ _globals['_STREAMLOGSREQUEST']._serialized_start=110
29
+ _globals['_STREAMLOGSREQUEST']._serialized_end=145
30
+ _globals['_STREAMLOGSRESPONSE']._serialized_start=147
31
+ _globals['_STREAMLOGSRESPONSE']._serialized_end=187
32
+ _globals['_EXEC']._serialized_start=190
33
+ _globals['_EXEC']._serialized_end=350
34
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,55 @@
1
+ """
2
+ @generated by mypy-protobuf. Do not edit manually!
3
+ isort:skip_file
4
+ """
5
+ import builtins
6
+ import google.protobuf.descriptor
7
+ import google.protobuf.message
8
+ import typing
9
+ import typing_extensions
10
+
11
+ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
12
+
13
+ class StartRunRequest(google.protobuf.message.Message):
14
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
15
+ FAB_FILE_FIELD_NUMBER: builtins.int
16
+ fab_file: builtins.bytes
17
+ def __init__(self,
18
+ *,
19
+ fab_file: builtins.bytes = ...,
20
+ ) -> None: ...
21
+ def ClearField(self, field_name: typing_extensions.Literal["fab_file",b"fab_file"]) -> None: ...
22
+ global___StartRunRequest = StartRunRequest
23
+
24
+ class StartRunResponse(google.protobuf.message.Message):
25
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
26
+ RUN_ID_FIELD_NUMBER: builtins.int
27
+ run_id: builtins.int
28
+ def __init__(self,
29
+ *,
30
+ run_id: builtins.int = ...,
31
+ ) -> None: ...
32
+ def ClearField(self, field_name: typing_extensions.Literal["run_id",b"run_id"]) -> None: ...
33
+ global___StartRunResponse = StartRunResponse
34
+
35
+ class StreamLogsRequest(google.protobuf.message.Message):
36
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
37
+ RUN_ID_FIELD_NUMBER: builtins.int
38
+ run_id: builtins.int
39
+ def __init__(self,
40
+ *,
41
+ run_id: builtins.int = ...,
42
+ ) -> None: ...
43
+ def ClearField(self, field_name: typing_extensions.Literal["run_id",b"run_id"]) -> None: ...
44
+ global___StreamLogsRequest = StreamLogsRequest
45
+
46
+ class StreamLogsResponse(google.protobuf.message.Message):
47
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
48
+ LOG_OUTPUT_FIELD_NUMBER: builtins.int
49
+ log_output: typing.Text
50
+ def __init__(self,
51
+ *,
52
+ log_output: typing.Text = ...,
53
+ ) -> None: ...
54
+ def ClearField(self, field_name: typing_extensions.Literal["log_output",b"log_output"]) -> None: ...
55
+ global___StreamLogsResponse = StreamLogsResponse
@@ -0,0 +1,101 @@
1
+ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2
+ """Client and server classes corresponding to protobuf-defined services."""
3
+ import grpc
4
+
5
+ from flwr.proto import exec_pb2 as flwr_dot_proto_dot_exec__pb2
6
+
7
+
8
+ class ExecStub(object):
9
+ """Missing associated documentation comment in .proto file."""
10
+
11
+ def __init__(self, channel):
12
+ """Constructor.
13
+
14
+ Args:
15
+ channel: A grpc.Channel.
16
+ """
17
+ self.StartRun = channel.unary_unary(
18
+ '/flwr.proto.Exec/StartRun',
19
+ request_serializer=flwr_dot_proto_dot_exec__pb2.StartRunRequest.SerializeToString,
20
+ response_deserializer=flwr_dot_proto_dot_exec__pb2.StartRunResponse.FromString,
21
+ )
22
+ self.StreamLogs = channel.unary_stream(
23
+ '/flwr.proto.Exec/StreamLogs',
24
+ request_serializer=flwr_dot_proto_dot_exec__pb2.StreamLogsRequest.SerializeToString,
25
+ response_deserializer=flwr_dot_proto_dot_exec__pb2.StreamLogsResponse.FromString,
26
+ )
27
+
28
+
29
+ class ExecServicer(object):
30
+ """Missing associated documentation comment in .proto file."""
31
+
32
+ def StartRun(self, request, context):
33
+ """Start run upon request
34
+ """
35
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
36
+ context.set_details('Method not implemented!')
37
+ raise NotImplementedError('Method not implemented!')
38
+
39
+ def StreamLogs(self, request, context):
40
+ """Start log stream upon request
41
+ """
42
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
43
+ context.set_details('Method not implemented!')
44
+ raise NotImplementedError('Method not implemented!')
45
+
46
+
47
+ def add_ExecServicer_to_server(servicer, server):
48
+ rpc_method_handlers = {
49
+ 'StartRun': grpc.unary_unary_rpc_method_handler(
50
+ servicer.StartRun,
51
+ request_deserializer=flwr_dot_proto_dot_exec__pb2.StartRunRequest.FromString,
52
+ response_serializer=flwr_dot_proto_dot_exec__pb2.StartRunResponse.SerializeToString,
53
+ ),
54
+ 'StreamLogs': grpc.unary_stream_rpc_method_handler(
55
+ servicer.StreamLogs,
56
+ request_deserializer=flwr_dot_proto_dot_exec__pb2.StreamLogsRequest.FromString,
57
+ response_serializer=flwr_dot_proto_dot_exec__pb2.StreamLogsResponse.SerializeToString,
58
+ ),
59
+ }
60
+ generic_handler = grpc.method_handlers_generic_handler(
61
+ 'flwr.proto.Exec', rpc_method_handlers)
62
+ server.add_generic_rpc_handlers((generic_handler,))
63
+
64
+
65
+ # This class is part of an EXPERIMENTAL API.
66
+ class Exec(object):
67
+ """Missing associated documentation comment in .proto file."""
68
+
69
+ @staticmethod
70
+ def StartRun(request,
71
+ target,
72
+ options=(),
73
+ channel_credentials=None,
74
+ call_credentials=None,
75
+ insecure=False,
76
+ compression=None,
77
+ wait_for_ready=None,
78
+ timeout=None,
79
+ metadata=None):
80
+ return grpc.experimental.unary_unary(request, target, '/flwr.proto.Exec/StartRun',
81
+ flwr_dot_proto_dot_exec__pb2.StartRunRequest.SerializeToString,
82
+ flwr_dot_proto_dot_exec__pb2.StartRunResponse.FromString,
83
+ options, channel_credentials,
84
+ insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
85
+
86
+ @staticmethod
87
+ def StreamLogs(request,
88
+ target,
89
+ options=(),
90
+ channel_credentials=None,
91
+ call_credentials=None,
92
+ insecure=False,
93
+ compression=None,
94
+ wait_for_ready=None,
95
+ timeout=None,
96
+ metadata=None):
97
+ return grpc.experimental.unary_stream(request, target, '/flwr.proto.Exec/StreamLogs',
98
+ flwr_dot_proto_dot_exec__pb2.StreamLogsRequest.SerializeToString,
99
+ flwr_dot_proto_dot_exec__pb2.StreamLogsResponse.FromString,
100
+ options, channel_credentials,
101
+ insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@@ -0,0 +1,41 @@
1
+ """
2
+ @generated by mypy-protobuf. Do not edit manually!
3
+ isort:skip_file
4
+ """
5
+ import abc
6
+ import flwr.proto.exec_pb2
7
+ import grpc
8
+ import typing
9
+
10
+ class ExecStub:
11
+ def __init__(self, channel: grpc.Channel) -> None: ...
12
+ StartRun: grpc.UnaryUnaryMultiCallable[
13
+ flwr.proto.exec_pb2.StartRunRequest,
14
+ flwr.proto.exec_pb2.StartRunResponse]
15
+ """Start run upon request"""
16
+
17
+ StreamLogs: grpc.UnaryStreamMultiCallable[
18
+ flwr.proto.exec_pb2.StreamLogsRequest,
19
+ flwr.proto.exec_pb2.StreamLogsResponse]
20
+ """Start log stream upon request"""
21
+
22
+
23
+ class ExecServicer(metaclass=abc.ABCMeta):
24
+ @abc.abstractmethod
25
+ def StartRun(self,
26
+ request: flwr.proto.exec_pb2.StartRunRequest,
27
+ context: grpc.ServicerContext,
28
+ ) -> flwr.proto.exec_pb2.StartRunResponse:
29
+ """Start run upon request"""
30
+ pass
31
+
32
+ @abc.abstractmethod
33
+ def StreamLogs(self,
34
+ request: flwr.proto.exec_pb2.StreamLogsRequest,
35
+ context: grpc.ServicerContext,
36
+ ) -> typing.Iterator[flwr.proto.exec_pb2.StreamLogsResponse]:
37
+ """Start log stream upon request"""
38
+ pass
39
+
40
+
41
+ def add_ExecServicer_to_server(servicer: ExecServicer, server: grpc.Server) -> None: ...
flwr/proto/fab_pb2.py ADDED
@@ -0,0 +1,30 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: flwr/proto/fab.proto
4
+ # Protobuf Python Version: 4.25.0
5
+ """Generated protocol buffer code."""
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ from google.protobuf.internal import builder as _builder
10
+ # @@protoc_insertion_point(imports)
11
+
12
+ _sym_db = _symbol_database.Default()
13
+
14
+
15
+
16
+
17
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/fab.proto\x12\nflwr.proto\"$\n\x03\x46\x61\x62\x12\x0c\n\x04hash\x18\x01 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x02 \x01(\x0c\"\x1d\n\rGetFabRequest\x12\x0c\n\x04hash\x18\x01 \x01(\t\".\n\x0eGetFabResponse\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fabb\x06proto3')
18
+
19
+ _globals = globals()
20
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
21
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.fab_pb2', _globals)
22
+ if _descriptor._USE_C_DESCRIPTORS == False:
23
+ DESCRIPTOR._options = None
24
+ _globals['_FAB']._serialized_start=36
25
+ _globals['_FAB']._serialized_end=72
26
+ _globals['_GETFABREQUEST']._serialized_start=74
27
+ _globals['_GETFABREQUEST']._serialized_end=103
28
+ _globals['_GETFABRESPONSE']._serialized_start=105
29
+ _globals['_GETFABRESPONSE']._serialized_end=151
30
+ # @@protoc_insertion_point(module_scope)