flwr-nightly 1.14.0.dev20241204__py3-none-any.whl → 1.14.0.dev20241216__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 (101) hide show
  1. flwr/cli/app.py +5 -0
  2. flwr/cli/build.py +1 -0
  3. flwr/cli/cli_user_auth_interceptor.py +86 -0
  4. flwr/cli/config_utils.py +19 -2
  5. flwr/cli/example.py +1 -0
  6. flwr/cli/install.py +1 -0
  7. flwr/cli/log.py +11 -31
  8. flwr/cli/login/__init__.py +22 -0
  9. flwr/cli/login/login.py +81 -0
  10. flwr/cli/ls.py +25 -55
  11. flwr/cli/new/__init__.py +1 -0
  12. flwr/cli/new/new.py +2 -1
  13. flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +2 -2
  14. flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +1 -2
  15. flwr/cli/run/__init__.py +1 -0
  16. flwr/cli/run/run.py +17 -39
  17. flwr/cli/stop.py +129 -0
  18. flwr/cli/utils.py +96 -1
  19. flwr/client/app.py +14 -3
  20. flwr/client/client.py +1 -0
  21. flwr/client/clientapp/app.py +4 -1
  22. flwr/client/clientapp/utils.py +1 -0
  23. flwr/client/grpc_adapter_client/connection.py +1 -1
  24. flwr/client/grpc_client/connection.py +1 -1
  25. flwr/client/grpc_rere_client/connection.py +13 -7
  26. flwr/client/message_handler/message_handler.py +1 -0
  27. flwr/client/mod/comms_mods.py +1 -0
  28. flwr/client/mod/localdp_mod.py +1 -1
  29. flwr/client/nodestate/__init__.py +1 -0
  30. flwr/client/nodestate/nodestate.py +1 -0
  31. flwr/client/nodestate/nodestate_factory.py +1 -0
  32. flwr/client/rest_client/connection.py +3 -3
  33. flwr/client/supernode/app.py +1 -0
  34. flwr/common/address.py +1 -0
  35. flwr/common/args.py +1 -0
  36. flwr/common/auth_plugin/__init__.py +24 -0
  37. flwr/common/auth_plugin/auth_plugin.py +111 -0
  38. flwr/common/config.py +3 -1
  39. flwr/common/constant.py +6 -1
  40. flwr/common/logger.py +17 -1
  41. flwr/common/message.py +1 -0
  42. flwr/common/object_ref.py +57 -54
  43. flwr/common/pyproject.py +1 -0
  44. flwr/common/record/__init__.py +1 -0
  45. flwr/common/record/parametersrecord.py +1 -0
  46. flwr/common/retry_invoker.py +77 -0
  47. flwr/common/secure_aggregation/secaggplus_utils.py +2 -2
  48. flwr/common/telemetry.py +2 -1
  49. flwr/common/typing.py +12 -0
  50. flwr/common/version.py +1 -0
  51. flwr/proto/exec_pb2.py +27 -3
  52. flwr/proto/exec_pb2.pyi +103 -0
  53. flwr/proto/exec_pb2_grpc.py +102 -0
  54. flwr/proto/exec_pb2_grpc.pyi +39 -0
  55. flwr/proto/fab_pb2.py +4 -4
  56. flwr/proto/fab_pb2.pyi +4 -1
  57. flwr/proto/serverappio_pb2.py +18 -18
  58. flwr/proto/serverappio_pb2.pyi +8 -2
  59. flwr/proto/serverappio_pb2_grpc.py +34 -0
  60. flwr/proto/serverappio_pb2_grpc.pyi +13 -0
  61. flwr/proto/simulationio_pb2.py +2 -2
  62. flwr/proto/simulationio_pb2_grpc.py +34 -0
  63. flwr/proto/simulationio_pb2_grpc.pyi +13 -0
  64. flwr/server/app.py +52 -1
  65. flwr/server/compat/app_utils.py +7 -1
  66. flwr/server/driver/grpc_driver.py +11 -63
  67. flwr/server/driver/inmemory_driver.py +5 -1
  68. flwr/server/serverapp/app.py +9 -2
  69. flwr/server/strategy/dpfedavg_fixed.py +1 -0
  70. flwr/server/superlink/driver/serverappio_grpc.py +1 -0
  71. flwr/server/superlink/driver/serverappio_servicer.py +72 -22
  72. flwr/server/superlink/ffs/disk_ffs.py +1 -0
  73. flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +1 -0
  74. flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +1 -0
  75. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +32 -12
  76. flwr/server/superlink/fleet/message_handler/message_handler.py +32 -5
  77. flwr/server/superlink/fleet/rest_rere/rest_api.py +4 -1
  78. flwr/server/superlink/fleet/vce/__init__.py +1 -0
  79. flwr/server/superlink/fleet/vce/backend/__init__.py +1 -0
  80. flwr/server/superlink/fleet/vce/backend/raybackend.py +1 -0
  81. flwr/server/superlink/linkstate/in_memory_linkstate.py +14 -30
  82. flwr/server/superlink/linkstate/linkstate.py +13 -2
  83. flwr/server/superlink/linkstate/sqlite_linkstate.py +24 -44
  84. flwr/server/superlink/simulation/simulationio_servicer.py +20 -0
  85. flwr/server/superlink/utils.py +65 -0
  86. flwr/simulation/app.py +1 -0
  87. flwr/simulation/ray_transport/ray_actor.py +1 -0
  88. flwr/simulation/ray_transport/utils.py +1 -0
  89. flwr/simulation/run_simulation.py +1 -15
  90. flwr/simulation/simulationio_connection.py +3 -0
  91. flwr/superexec/app.py +1 -0
  92. flwr/superexec/deployment.py +1 -0
  93. flwr/superexec/exec_grpc.py +19 -1
  94. flwr/superexec/exec_servicer.py +76 -2
  95. flwr/superexec/exec_user_auth_interceptor.py +101 -0
  96. flwr/superexec/executor.py +1 -0
  97. {flwr_nightly-1.14.0.dev20241204.dist-info → flwr_nightly-1.14.0.dev20241216.dist-info}/METADATA +8 -7
  98. {flwr_nightly-1.14.0.dev20241204.dist-info → flwr_nightly-1.14.0.dev20241216.dist-info}/RECORD +101 -93
  99. {flwr_nightly-1.14.0.dev20241204.dist-info → flwr_nightly-1.14.0.dev20241216.dist-info}/LICENSE +0 -0
  100. {flwr_nightly-1.14.0.dev20241204.dist-info → flwr_nightly-1.14.0.dev20241216.dist-info}/WHEEL +0 -0
  101. {flwr_nightly-1.14.0.dev20241204.dist-info → flwr_nightly-1.14.0.dev20241216.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,111 @@
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
+ """Abstract classes for Flower User Auth Plugin."""
16
+
17
+
18
+ from abc import ABC, abstractmethod
19
+ from collections.abc import Sequence
20
+ from pathlib import Path
21
+ from typing import Any, Optional, Union
22
+
23
+ from flwr.proto.exec_pb2_grpc import ExecStub
24
+
25
+
26
+ class ExecAuthPlugin(ABC):
27
+ """Abstract Flower Auth Plugin class for ExecServicer.
28
+
29
+ Parameters
30
+ ----------
31
+ config : dict[str, Any]
32
+ The authentication configuration loaded from a YAML file.
33
+ """
34
+
35
+ @abstractmethod
36
+ def __init__(self, config: dict[str, Any]):
37
+ """Abstract constructor."""
38
+
39
+ @abstractmethod
40
+ def get_login_details(self) -> dict[str, str]:
41
+ """Get the login details."""
42
+
43
+ @abstractmethod
44
+ def validate_tokens_in_metadata(
45
+ self, metadata: Sequence[tuple[str, Union[str, bytes]]]
46
+ ) -> bool:
47
+ """Validate authentication tokens in the provided metadata."""
48
+
49
+ @abstractmethod
50
+ def get_auth_tokens(self, auth_details: dict[str, str]) -> dict[str, str]:
51
+ """Get authentication tokens."""
52
+
53
+ @abstractmethod
54
+ def refresh_tokens(
55
+ self, metadata: Sequence[tuple[str, Union[str, bytes]]]
56
+ ) -> Optional[Sequence[tuple[str, Union[str, bytes]]]]:
57
+ """Refresh authentication tokens in the provided metadata."""
58
+
59
+
60
+ class CliAuthPlugin(ABC):
61
+ """Abstract Flower Auth Plugin class for CLI.
62
+
63
+ Parameters
64
+ ----------
65
+ user_auth_config_path : Path
66
+ The path to the user's authentication configuration file.
67
+ """
68
+
69
+ @staticmethod
70
+ @abstractmethod
71
+ def login(
72
+ login_details: dict[str, str],
73
+ exec_stub: ExecStub,
74
+ ) -> dict[str, Any]:
75
+ """Authenticate the user with the SuperLink.
76
+
77
+ Parameters
78
+ ----------
79
+ login_details : dict[str, str]
80
+ A dictionary containing the user's login details.
81
+ exec_stub : ExecStub
82
+ An instance of `ExecStub` used for communication with the SuperLink.
83
+
84
+ Returns
85
+ -------
86
+ user_auth_config : dict[str, Any]
87
+ A dictionary containing the user's authentication configuration
88
+ in JSON format.
89
+ """
90
+
91
+ @abstractmethod
92
+ def __init__(self, user_auth_config_path: Path):
93
+ """Abstract constructor."""
94
+
95
+ @abstractmethod
96
+ def store_tokens(self, user_auth_config: dict[str, Any]) -> None:
97
+ """Store authentication tokens from the provided user_auth_config.
98
+
99
+ The configuration, including tokens, will be saved as a JSON file
100
+ at `user_auth_config_path`.
101
+ """
102
+
103
+ @abstractmethod
104
+ def load_tokens(self) -> None:
105
+ """Load authentication tokens from the user_auth_config_path."""
106
+
107
+ @abstractmethod
108
+ def write_tokens_to_metadata(
109
+ self, metadata: Sequence[tuple[str, Union[str, bytes]]]
110
+ ) -> Sequence[tuple[str, Union[str, bytes]]]:
111
+ """Write authentication tokens to the provided metadata."""
flwr/common/config.py CHANGED
@@ -14,6 +14,7 @@
14
14
  # ==============================================================================
15
15
  """Provide functions for managing global Flower config."""
16
16
 
17
+
17
18
  import os
18
19
  import re
19
20
  from pathlib import Path
@@ -27,6 +28,7 @@ from flwr.common.constant import (
27
28
  APP_DIR,
28
29
  FAB_CONFIG_FILE,
29
30
  FAB_HASH_TRUNCATION,
31
+ FLWR_DIR,
30
32
  FLWR_HOME,
31
33
  )
32
34
  from flwr.common.typing import Run, UserConfig, UserConfigValue
@@ -38,7 +40,7 @@ def get_flwr_dir(provided_path: Optional[str] = None) -> Path:
38
40
  return Path(
39
41
  os.getenv(
40
42
  FLWR_HOME,
41
- Path(f"{os.getenv('XDG_DATA_HOME', os.getenv('HOME'))}") / ".flwr",
43
+ Path(f"{os.getenv('XDG_DATA_HOME', os.getenv('HOME'))}") / FLWR_DIR,
42
44
  )
43
45
  )
44
46
  return Path(provided_path).absolute()
flwr/common/constant.py CHANGED
@@ -80,7 +80,8 @@ FAB_ALLOWED_EXTENSIONS = {".py", ".toml", ".md"}
80
80
  FAB_CONFIG_FILE = "pyproject.toml"
81
81
  FAB_DATE = (2024, 10, 1, 0, 0, 0)
82
82
  FAB_HASH_TRUNCATION = 8
83
- FLWR_HOME = "FLWR_HOME"
83
+ FLWR_DIR = ".flwr" # The default Flower directory: ~/.flwr/
84
+ FLWR_HOME = "FLWR_HOME" # If set, override the default Flower directory
84
85
 
85
86
  # Constants entries in Node config for Simulation
86
87
  PARTITION_ID_KEY = "partition-id"
@@ -110,6 +111,10 @@ LOG_UPLOAD_INTERVAL = 0.2 # Minimum interval between two log uploads
110
111
  # Retry configurations
111
112
  MAX_RETRY_DELAY = 20 # Maximum delay duration between two consecutive retries.
112
113
 
114
+ # Constants for user authentication
115
+ CREDENTIALS_DIR = ".credentials"
116
+ AUTH_TYPE = "auth_type"
117
+
113
118
 
114
119
  class MessageType:
115
120
  """Message type."""
flwr/common/logger.py CHANGED
@@ -14,6 +14,8 @@
14
14
  # ==============================================================================
15
15
  """Flower Logger."""
16
16
 
17
+
18
+ import json as _json
17
19
  import logging
18
20
  import re
19
21
  import sys
@@ -26,6 +28,8 @@ from queue import Empty, Queue
26
28
  from typing import TYPE_CHECKING, Any, Optional, TextIO, Union
27
29
 
28
30
  import grpc
31
+ import typer
32
+ from rich.console import Console
29
33
 
30
34
  from flwr.proto.log_pb2 import PushLogsRequest # pylint: disable=E0611
31
35
  from flwr.proto.node_pb2 import Node # pylint: disable=E0611
@@ -376,7 +380,7 @@ def stop_log_uploader(
376
380
  log_uploader.join()
377
381
 
378
382
 
379
- def remove_emojis(text: str) -> str:
383
+ def _remove_emojis(text: str) -> str:
380
384
  """Remove emojis from the provided text."""
381
385
  emoji_pattern = re.compile(
382
386
  "["
@@ -390,3 +394,15 @@ def remove_emojis(text: str) -> str:
390
394
  flags=re.UNICODE,
391
395
  )
392
396
  return emoji_pattern.sub(r"", text)
397
+
398
+
399
+ def print_json_error(msg: str, e: Union[typer.Exit, Exception]) -> None:
400
+ """Print error message as JSON."""
401
+ Console().print_json(
402
+ _json.dumps(
403
+ {
404
+ "success": False,
405
+ "error-message": _remove_emojis(str(msg) + "\n" + str(e)),
406
+ }
407
+ )
408
+ )
flwr/common/message.py CHANGED
@@ -14,6 +14,7 @@
14
14
  # ==============================================================================
15
15
  """Message."""
16
16
 
17
+
17
18
  from __future__ import annotations
18
19
 
19
20
  import time
flwr/common/object_ref.py CHANGED
@@ -21,6 +21,7 @@ import sys
21
21
  from importlib.util import find_spec
22
22
  from logging import WARN
23
23
  from pathlib import Path
24
+ from threading import Lock
24
25
  from typing import Any, Optional, Union
25
26
 
26
27
  from .logger import log
@@ -34,6 +35,7 @@ attribute.
34
35
 
35
36
 
36
37
  _current_sys_path: Optional[str] = None
38
+ _import_lock = Lock()
37
39
 
38
40
 
39
41
  def validate(
@@ -146,60 +148,61 @@ def load_app( # pylint: disable= too-many-branches
146
148
  - This function will modify `sys.path` by inserting the provided `project_dir`
147
149
  and removing the previously inserted `project_dir`.
148
150
  """
149
- valid, error_msg = validate(module_attribute_str, check_module=False)
150
- if not valid and error_msg:
151
- raise error_type(error_msg) from None
152
-
153
- module_str, _, attributes_str = module_attribute_str.partition(":")
154
-
155
- try:
156
- # Initialize project path
157
- if project_dir is None:
158
- project_dir = Path.cwd()
159
- project_dir = Path(project_dir).absolute()
160
-
161
- # Unload modules if the project directory has changed
162
- if _current_sys_path and _current_sys_path != str(project_dir):
163
- _unload_modules(Path(_current_sys_path))
164
-
165
- # Set the system path
166
- _set_sys_path(project_dir)
167
-
168
- # Import the module
169
- if module_str not in sys.modules:
170
- module = importlib.import_module(module_str)
171
- # Hack: `tabnet` does not work with `importlib.reload`
172
- elif "tabnet" in sys.modules:
173
- log(
174
- WARN,
175
- "Cannot reload module `%s` from disk due to compatibility issues "
176
- "with the `tabnet` library. The module will be loaded from the "
177
- "cache instead. If you experience issues, consider restarting "
178
- "the application.",
179
- module_str,
180
- )
181
- module = sys.modules[module_str]
182
- else:
183
- module = sys.modules[module_str]
184
- _reload_modules(project_dir)
185
-
186
- except ModuleNotFoundError as err:
187
- raise error_type(
188
- f"Unable to load module {module_str}{OBJECT_REF_HELP_STR}",
189
- ) from err
190
-
191
- # Recursively load attribute
192
- attribute = module
193
- try:
194
- for attribute_str in attributes_str.split("."):
195
- attribute = getattr(attribute, attribute_str)
196
- except AttributeError as err:
197
- raise error_type(
198
- f"Unable to load attribute {attributes_str} from module {module_str}"
199
- f"{OBJECT_REF_HELP_STR}",
200
- ) from err
201
-
202
- return attribute
151
+ with _import_lock:
152
+ valid, error_msg = validate(module_attribute_str, check_module=False)
153
+ if not valid and error_msg:
154
+ raise error_type(error_msg) from None
155
+
156
+ module_str, _, attributes_str = module_attribute_str.partition(":")
157
+
158
+ try:
159
+ # Initialize project path
160
+ if project_dir is None:
161
+ project_dir = Path.cwd()
162
+ project_dir = Path(project_dir).absolute()
163
+
164
+ # Unload modules if the project directory has changed
165
+ if _current_sys_path and _current_sys_path != str(project_dir):
166
+ _unload_modules(Path(_current_sys_path))
167
+
168
+ # Set the system path
169
+ _set_sys_path(project_dir)
170
+
171
+ # Import the module
172
+ if module_str not in sys.modules:
173
+ module = importlib.import_module(module_str)
174
+ # Hack: `tabnet` does not work with `importlib.reload`
175
+ elif "tabnet" in sys.modules:
176
+ log(
177
+ WARN,
178
+ "Cannot reload module `%s` from disk due to compatibility issues "
179
+ "with the `tabnet` library. The module will be loaded from the "
180
+ "cache instead. If you experience issues, consider restarting "
181
+ "the application.",
182
+ module_str,
183
+ )
184
+ module = sys.modules[module_str]
185
+ else:
186
+ module = sys.modules[module_str]
187
+ _reload_modules(project_dir)
188
+
189
+ except ModuleNotFoundError as err:
190
+ raise error_type(
191
+ f"Unable to load module {module_str}{OBJECT_REF_HELP_STR}",
192
+ ) from err
193
+
194
+ # Recursively load attribute
195
+ attribute = module
196
+ try:
197
+ for attribute_str in attributes_str.split("."):
198
+ attribute = getattr(attribute, attribute_str)
199
+ except AttributeError as err:
200
+ raise error_type(
201
+ f"Unable to load attribute {attributes_str} from module {module_str}"
202
+ f"{OBJECT_REF_HELP_STR}",
203
+ ) from err
204
+
205
+ return attribute
203
206
 
204
207
 
205
208
  def _unload_modules(project_dir: Path) -> None:
flwr/common/pyproject.py CHANGED
@@ -14,6 +14,7 @@
14
14
  # ==============================================================================
15
15
  """Validates the project's name property."""
16
16
 
17
+
17
18
  import re
18
19
 
19
20
 
@@ -14,6 +14,7 @@
14
14
  # ==============================================================================
15
15
  """Record APIs."""
16
16
 
17
+
17
18
  from .configsrecord import ConfigsRecord
18
19
  from .conversion_utils import array_from_numpy
19
20
  from .metricsrecord import MetricsRecord
@@ -14,6 +14,7 @@
14
14
  # ==============================================================================
15
15
  """ParametersRecord and Array."""
16
16
 
17
+
17
18
  from collections import OrderedDict
18
19
  from dataclasses import dataclass
19
20
  from io import BytesIO
@@ -20,8 +20,18 @@ import random
20
20
  import time
21
21
  from collections.abc import Generator, Iterable
22
22
  from dataclasses import dataclass
23
+ from logging import INFO, WARN
23
24
  from typing import Any, Callable, Optional, Union, cast
24
25
 
26
+ import grpc
27
+
28
+ from flwr.common.constant import MAX_RETRY_DELAY
29
+ from flwr.common.logger import log
30
+ from flwr.common.typing import RunNotRunningException
31
+ from flwr.proto.clientappio_pb2_grpc import ClientAppIoStub
32
+ from flwr.proto.serverappio_pb2_grpc import ServerAppIoStub
33
+ from flwr.proto.simulationio_pb2_grpc import SimulationIoStub
34
+
25
35
 
26
36
  def exponential(
27
37
  base_delay: float = 1,
@@ -303,3 +313,70 @@ class RetryInvoker:
303
313
  # Trigger success event
304
314
  try_call_event_handler(self.on_success)
305
315
  return ret
316
+
317
+
318
+ def _make_simple_grpc_retry_invoker() -> RetryInvoker:
319
+ """Create a simple gRPC retry invoker."""
320
+
321
+ def _on_sucess(retry_state: RetryState) -> None:
322
+ if retry_state.tries > 1:
323
+ log(
324
+ INFO,
325
+ "Connection successful after %.2f seconds and %s tries.",
326
+ retry_state.elapsed_time,
327
+ retry_state.tries,
328
+ )
329
+
330
+ def _on_backoff(retry_state: RetryState) -> None:
331
+ if retry_state.tries == 1:
332
+ log(WARN, "Connection attempt failed, retrying...")
333
+ else:
334
+ log(
335
+ WARN,
336
+ "Connection attempt failed, retrying in %.2f seconds",
337
+ retry_state.actual_wait,
338
+ )
339
+
340
+ def _on_giveup(retry_state: RetryState) -> None:
341
+ if retry_state.tries > 1:
342
+ log(
343
+ WARN,
344
+ "Giving up reconnection after %.2f seconds and %s tries.",
345
+ retry_state.elapsed_time,
346
+ retry_state.tries,
347
+ )
348
+
349
+ def _should_giveup_fn(e: Exception) -> bool:
350
+ if e.code() == grpc.StatusCode.PERMISSION_DENIED: # type: ignore
351
+ raise RunNotRunningException
352
+ if e.code() == grpc.StatusCode.UNAVAILABLE: # type: ignore
353
+ return False
354
+ return True
355
+
356
+ return RetryInvoker(
357
+ wait_gen_factory=lambda: exponential(max_delay=MAX_RETRY_DELAY),
358
+ recoverable_exceptions=grpc.RpcError,
359
+ max_tries=None,
360
+ max_time=None,
361
+ on_success=_on_sucess,
362
+ on_backoff=_on_backoff,
363
+ on_giveup=_on_giveup,
364
+ should_giveup=_should_giveup_fn,
365
+ )
366
+
367
+
368
+ def _wrap_stub(
369
+ stub: Union[ServerAppIoStub, ClientAppIoStub, SimulationIoStub],
370
+ retry_invoker: RetryInvoker,
371
+ ) -> None:
372
+ """Wrap a gRPC stub with a retry invoker."""
373
+
374
+ def make_lambda(original_method: Any) -> Any:
375
+ return lambda *args, **kwargs: retry_invoker.invoke(
376
+ original_method, *args, **kwargs
377
+ )
378
+
379
+ for method_name in vars(stub):
380
+ method = getattr(stub, method_name)
381
+ if callable(method):
382
+ setattr(stub, method_name, make_lambda(method))
@@ -93,8 +93,8 @@ def pseudo_rand_gen(
93
93
  output = []
94
94
  for dimension in dimensions_list:
95
95
  if len(dimension) == 0:
96
- arr = np.array(gen.randint(0, num_range - 1), dtype=int)
96
+ arr = np.array(gen.randint(0, num_range - 1), dtype=np.int64)
97
97
  else:
98
- arr = gen.randint(0, num_range - 1, dimension)
98
+ arr = gen.randint(0, num_range - 1, dimension, dtype=np.int64)
99
99
  output.append(arr)
100
100
  return output
flwr/common/telemetry.py CHANGED
@@ -27,6 +27,7 @@ from enum import Enum, auto
27
27
  from pathlib import Path
28
28
  from typing import Any, Optional, Union, cast
29
29
 
30
+ from flwr.common.constant import FLWR_DIR
30
31
  from flwr.common.version import package_name, package_version
31
32
 
32
33
  FLWR_TELEMETRY_ENABLED = os.getenv("FLWR_TELEMETRY_ENABLED", "1")
@@ -86,7 +87,7 @@ def _get_source_id() -> str:
86
87
  # If the home directory can’t be resolved, RuntimeError is raised.
87
88
  return source_id
88
89
 
89
- flwr_dir = home.joinpath(".flwr")
90
+ flwr_dir = home.joinpath(FLWR_DIR)
90
91
  # Create .flwr directory if it does not exist yet.
91
92
  try:
92
93
  flwr_dir.mkdir(parents=True, exist_ok=True)
flwr/common/typing.py CHANGED
@@ -254,3 +254,15 @@ class Fab:
254
254
 
255
255
  hash_str: str
256
256
  content: bytes
257
+
258
+
259
+ class RunNotRunningException(BaseException):
260
+ """Raised when a run is not running."""
261
+
262
+
263
+ class InvalidRunStatusException(BaseException):
264
+ """Raised when an RPC is invalidated by the RunStatus."""
265
+
266
+ def __init__(self, message: str) -> None:
267
+ super().__init__(message)
268
+ self.message = message
flwr/common/version.py CHANGED
@@ -14,6 +14,7 @@
14
14
  # ==============================================================================
15
15
  """Flower package version helper."""
16
16
 
17
+
17
18
  import importlib.metadata as importlib_metadata
18
19
 
19
20
 
flwr/proto/exec_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 run_pb2 as flwr_dot_proto_dot_run__pb2
19
19
 
20
20
 
21
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/exec.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x1a\x66lwr/proto/recordset.proto\x1a\x14\x66lwr/proto/run.proto\"\xfb\x01\n\x0fStartRunRequest\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fab\x12H\n\x0foverride_config\x18\x02 \x03(\x0b\x32/.flwr.proto.StartRunRequest.OverrideConfigEntry\x12\x35\n\x12\x66\x65\x64\x65ration_options\x18\x03 \x01(\x0b\x32\x19.flwr.proto.ConfigsRecord\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\"2\n\x10StartRunResponse\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"<\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x17\n\x0f\x61\x66ter_timestamp\x18\x02 \x01(\x01\"B\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t\x12\x18\n\x10latest_timestamp\x18\x02 \x01(\x01\"1\n\x0fListRunsRequest\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"\x9d\x01\n\x10ListRunsResponse\x12;\n\x08run_dict\x18\x01 \x03(\x0b\x32).flwr.proto.ListRunsResponse.RunDictEntry\x12\x0b\n\x03now\x18\x02 \x01(\t\x1a?\n\x0cRunDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x1e\n\x05value\x18\x02 \x01(\x0b\x32\x0f.flwr.proto.Run:\x02\x38\x01\x32\xe9\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\x12G\n\x08ListRuns\x12\x1b.flwr.proto.ListRunsRequest\x1a\x1c.flwr.proto.ListRunsResponse\"\x00\x62\x06proto3')
21
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/exec.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x1a\x66lwr/proto/recordset.proto\x1a\x14\x66lwr/proto/run.proto\"\xfb\x01\n\x0fStartRunRequest\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fab\x12H\n\x0foverride_config\x18\x02 \x03(\x0b\x32/.flwr.proto.StartRunRequest.OverrideConfigEntry\x12\x35\n\x12\x66\x65\x64\x65ration_options\x18\x03 \x01(\x0b\x32\x19.flwr.proto.ConfigsRecord\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\"2\n\x10StartRunResponse\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"<\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x17\n\x0f\x61\x66ter_timestamp\x18\x02 \x01(\x01\"B\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t\x12\x18\n\x10latest_timestamp\x18\x02 \x01(\x01\"1\n\x0fListRunsRequest\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"\x9d\x01\n\x10ListRunsResponse\x12;\n\x08run_dict\x18\x01 \x03(\x0b\x32).flwr.proto.ListRunsResponse.RunDictEntry\x12\x0b\n\x03now\x18\x02 \x01(\t\x1a?\n\x0cRunDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x1e\n\x05value\x18\x02 \x01(\x0b\x32\x0f.flwr.proto.Run:\x02\x38\x01\"\x18\n\x16GetLoginDetailsRequest\"\x9c\x01\n\x17GetLoginDetailsResponse\x12L\n\rlogin_details\x18\x01 \x03(\x0b\x32\x35.flwr.proto.GetLoginDetailsResponse.LoginDetailsEntry\x1a\x33\n\x11LoginDetailsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x93\x01\n\x14GetAuthTokensRequest\x12G\n\x0c\x61uth_details\x18\x01 \x03(\x0b\x32\x31.flwr.proto.GetAuthTokensRequest.AuthDetailsEntry\x1a\x32\n\x10\x41uthDetailsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x92\x01\n\x15GetAuthTokensResponse\x12\x46\n\x0b\x61uth_tokens\x18\x01 \x03(\x0b\x32\x31.flwr.proto.GetAuthTokensResponse.AuthTokensEntry\x1a\x31\n\x0f\x41uthTokensEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\" \n\x0eStopRunRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"\"\n\x0fStopRunResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x32\xe5\x03\n\x04\x45xec\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\x00\x12\x44\n\x07StopRun\x12\x1a.flwr.proto.StopRunRequest\x1a\x1b.flwr.proto.StopRunResponse\"\x00\x12O\n\nStreamLogs\x12\x1d.flwr.proto.StreamLogsRequest\x1a\x1e.flwr.proto.StreamLogsResponse\"\x00\x30\x01\x12G\n\x08ListRuns\x12\x1b.flwr.proto.ListRunsRequest\x1a\x1c.flwr.proto.ListRunsResponse\"\x00\x12\\\n\x0fGetLoginDetails\x12\".flwr.proto.GetLoginDetailsRequest\x1a#.flwr.proto.GetLoginDetailsResponse\"\x00\x12V\n\rGetAuthTokens\x12 .flwr.proto.GetAuthTokensRequest\x1a!.flwr.proto.GetAuthTokensResponse\"\x00\x62\x06proto3')
22
22
 
23
23
  _globals = globals()
24
24
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -29,6 +29,12 @@ if _descriptor._USE_C_DESCRIPTORS == False:
29
29
  _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_options = b'8\001'
30
30
  _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._options = None
31
31
  _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_options = b'8\001'
32
+ _globals['_GETLOGINDETAILSRESPONSE_LOGINDETAILSENTRY']._options = None
33
+ _globals['_GETLOGINDETAILSRESPONSE_LOGINDETAILSENTRY']._serialized_options = b'8\001'
34
+ _globals['_GETAUTHTOKENSREQUEST_AUTHDETAILSENTRY']._options = None
35
+ _globals['_GETAUTHTOKENSREQUEST_AUTHDETAILSENTRY']._serialized_options = b'8\001'
36
+ _globals['_GETAUTHTOKENSRESPONSE_AUTHTOKENSENTRY']._options = None
37
+ _globals['_GETAUTHTOKENSRESPONSE_AUTHTOKENSENTRY']._serialized_options = b'8\001'
32
38
  _globals['_STARTRUNREQUEST']._serialized_start=138
33
39
  _globals['_STARTRUNREQUEST']._serialized_end=389
34
40
  _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=316
@@ -45,6 +51,24 @@ if _descriptor._USE_C_DESCRIPTORS == False:
45
51
  _globals['_LISTRUNSRESPONSE']._serialized_end=782
46
52
  _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_start=719
47
53
  _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_end=782
48
- _globals['_EXEC']._serialized_start=785
49
- _globals['_EXEC']._serialized_end=1018
54
+ _globals['_GETLOGINDETAILSREQUEST']._serialized_start=784
55
+ _globals['_GETLOGINDETAILSREQUEST']._serialized_end=808
56
+ _globals['_GETLOGINDETAILSRESPONSE']._serialized_start=811
57
+ _globals['_GETLOGINDETAILSRESPONSE']._serialized_end=967
58
+ _globals['_GETLOGINDETAILSRESPONSE_LOGINDETAILSENTRY']._serialized_start=916
59
+ _globals['_GETLOGINDETAILSRESPONSE_LOGINDETAILSENTRY']._serialized_end=967
60
+ _globals['_GETAUTHTOKENSREQUEST']._serialized_start=970
61
+ _globals['_GETAUTHTOKENSREQUEST']._serialized_end=1117
62
+ _globals['_GETAUTHTOKENSREQUEST_AUTHDETAILSENTRY']._serialized_start=1067
63
+ _globals['_GETAUTHTOKENSREQUEST_AUTHDETAILSENTRY']._serialized_end=1117
64
+ _globals['_GETAUTHTOKENSRESPONSE']._serialized_start=1120
65
+ _globals['_GETAUTHTOKENSRESPONSE']._serialized_end=1266
66
+ _globals['_GETAUTHTOKENSRESPONSE_AUTHTOKENSENTRY']._serialized_start=1217
67
+ _globals['_GETAUTHTOKENSRESPONSE_AUTHTOKENSENTRY']._serialized_end=1266
68
+ _globals['_STOPRUNREQUEST']._serialized_start=1268
69
+ _globals['_STOPRUNREQUEST']._serialized_end=1300
70
+ _globals['_STOPRUNRESPONSE']._serialized_start=1302
71
+ _globals['_STOPRUNRESPONSE']._serialized_end=1336
72
+ _globals['_EXEC']._serialized_start=1339
73
+ _globals['_EXEC']._serialized_end=1824
50
74
  # @@protoc_insertion_point(module_scope)