flwr-nightly 1.11.1.dev20240912__py3-none-any.whl → 1.12.0.dev20240907__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 (27) hide show
  1. flwr/cli/new/new.py +36 -23
  2. flwr/cli/new/templates/app/code/client.huggingface.py.tpl +29 -19
  3. flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +3 -0
  4. flwr/cli/new/templates/app/code/server.huggingface.py.tpl +3 -18
  5. flwr/cli/new/templates/app/code/task.huggingface.py.tpl +13 -16
  6. flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +1 -9
  7. flwr/client/app.py +4 -3
  8. flwr/client/client_app.py +2 -2
  9. flwr/client/grpc_rere_client/client_interceptor.py +3 -2
  10. flwr/client/supernode/app.py +6 -5
  11. flwr/common/constant.py +1 -12
  12. flwr/common/record/recordset.py +1 -1
  13. flwr/common/record/typeddict.py +1 -24
  14. flwr/server/app.py +9 -8
  15. flwr/server/driver/grpc_driver.py +3 -2
  16. flwr/server/run_serverapp.py +6 -5
  17. flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +1 -2
  18. flwr/server/superlink/fleet/vce/backend/raybackend.py +12 -21
  19. flwr/simulation/ray_transport/ray_actor.py +2 -2
  20. flwr/simulation/run_simulation.py +2 -14
  21. flwr/superexec/app.py +2 -2
  22. flwr/superexec/deployment.py +2 -2
  23. {flwr_nightly-1.11.1.dev20240912.dist-info → flwr_nightly-1.12.0.dev20240907.dist-info}/METADATA +1 -1
  24. {flwr_nightly-1.11.1.dev20240912.dist-info → flwr_nightly-1.12.0.dev20240907.dist-info}/RECORD +27 -27
  25. {flwr_nightly-1.11.1.dev20240912.dist-info → flwr_nightly-1.12.0.dev20240907.dist-info}/LICENSE +0 -0
  26. {flwr_nightly-1.11.1.dev20240912.dist-info → flwr_nightly-1.12.0.dev20240907.dist-info}/WHEEL +0 -0
  27. {flwr_nightly-1.11.1.dev20240912.dist-info → flwr_nightly-1.12.0.dev20240907.dist-info}/entry_points.txt +0 -0
flwr/cli/new/new.py CHANGED
@@ -136,23 +136,36 @@ def new(
136
136
  username = prompt_text("Please provide your Flower username")
137
137
 
138
138
  if framework is not None:
139
- framework_str = str(framework.value)
139
+ framework_str_upper = str(framework.value)
140
140
  else:
141
- framework_str = prompt_options(
141
+ framework_value = prompt_options(
142
142
  "Please select ML framework by typing in the number",
143
143
  [mlf.value for mlf in MlFramework],
144
144
  )
145
+ selected_value = [
146
+ name
147
+ for name, value in vars(MlFramework).items()
148
+ if value == framework_value
149
+ ]
150
+ framework_str_upper = selected_value[0]
151
+
152
+ framework_str = framework_str_upper.lower()
145
153
 
146
154
  llm_challenge_str = None
147
- if framework_str == MlFramework.FLOWERTUNE:
155
+ if framework_str == "flowertune":
148
156
  llm_challenge_value = prompt_options(
149
157
  "Please select LLM challenge by typing in the number",
150
158
  sorted([challenge.value for challenge in LlmChallengeName]),
151
159
  )
152
- llm_challenge_str = llm_challenge_value.lower()
160
+ selected_value = [
161
+ name
162
+ for name, value in vars(LlmChallengeName).items()
163
+ if value == llm_challenge_value
164
+ ]
165
+ llm_challenge_str = selected_value[0]
166
+ llm_challenge_str = llm_challenge_str.lower()
153
167
 
154
- if framework_str == MlFramework.BASELINE:
155
- framework_str = "baseline"
168
+ is_baseline_project = framework_str == "baseline"
156
169
 
157
170
  print(
158
171
  typer.style(
@@ -163,21 +176,19 @@ def new(
163
176
  )
164
177
 
165
178
  context = {
166
- "framework_str": framework_str,
179
+ "framework_str": framework_str_upper,
167
180
  "import_name": import_name.replace("-", "_"),
168
181
  "package_name": package_name,
169
182
  "project_name": app_name,
170
183
  "username": username,
171
184
  }
172
185
 
173
- template_name = framework_str.lower()
174
-
175
186
  # List of files to render
176
187
  if llm_challenge_str:
177
188
  files = {
178
189
  ".gitignore": {"template": "app/.gitignore.tpl"},
179
- "pyproject.toml": {"template": f"app/pyproject.{template_name}.toml.tpl"},
180
- "README.md": {"template": f"app/README.{template_name}.md.tpl"},
190
+ "pyproject.toml": {"template": f"app/pyproject.{framework_str}.toml.tpl"},
191
+ "README.md": {"template": f"app/README.{framework_str}.md.tpl"},
181
192
  f"{import_name}/__init__.py": {"template": "app/code/__init__.py.tpl"},
182
193
  f"{import_name}/server_app.py": {
183
194
  "template": "app/code/flwr_tune/server_app.py.tpl"
@@ -224,42 +235,44 @@ def new(
224
235
  files = {
225
236
  ".gitignore": {"template": "app/.gitignore.tpl"},
226
237
  "README.md": {"template": "app/README.md.tpl"},
227
- "pyproject.toml": {"template": f"app/pyproject.{template_name}.toml.tpl"},
238
+ "pyproject.toml": {"template": f"app/pyproject.{framework_str}.toml.tpl"},
228
239
  f"{import_name}/__init__.py": {"template": "app/code/__init__.py.tpl"},
229
240
  f"{import_name}/server_app.py": {
230
- "template": f"app/code/server.{template_name}.py.tpl"
241
+ "template": f"app/code/server.{framework_str}.py.tpl"
231
242
  },
232
243
  f"{import_name}/client_app.py": {
233
- "template": f"app/code/client.{template_name}.py.tpl"
244
+ "template": f"app/code/client.{framework_str}.py.tpl"
234
245
  },
235
246
  }
236
247
 
237
248
  # Depending on the framework, generate task.py file
238
249
  frameworks_with_tasks = [
239
- MlFramework.PYTORCH.value,
240
- MlFramework.JAX.value,
241
- MlFramework.HUGGINGFACE.value,
242
- MlFramework.MLX.value,
243
- MlFramework.TENSORFLOW.value,
250
+ MlFramework.PYTORCH.value.lower(),
251
+ MlFramework.JAX.value.lower(),
252
+ MlFramework.HUGGINGFACE.value.lower(),
253
+ MlFramework.MLX.value.lower(),
254
+ MlFramework.TENSORFLOW.value.lower(),
244
255
  ]
245
256
  if framework_str in frameworks_with_tasks:
246
257
  files[f"{import_name}/task.py"] = {
247
- "template": f"app/code/task.{template_name}.py.tpl"
258
+ "template": f"app/code/task.{framework_str}.py.tpl"
248
259
  }
249
260
 
250
- if framework_str == "baseline":
261
+ if is_baseline_project:
251
262
  # Include additional files for baseline template
252
263
  for file_name in ["model", "dataset", "strategy", "utils", "__init__"]:
253
264
  files[f"{import_name}/{file_name}.py"] = {
254
- "template": f"app/code/{file_name}.{template_name}.py.tpl"
265
+ "template": f"app/code/{file_name}.{framework_str}.py.tpl"
255
266
  }
256
267
 
257
268
  # Replace README.md
258
- files["README.md"]["template"] = f"app/README.{template_name}.md.tpl"
269
+ files["README.md"]["template"] = f"app/README.{framework_str}.md.tpl"
259
270
 
260
271
  # Add LICENSE
261
272
  files["LICENSE"] = {"template": "app/LICENSE.tpl"}
262
273
 
274
+ context["framework_str"] = "baseline"
275
+
263
276
  for file_path, value in files.items():
264
277
  render_and_create(
265
278
  file_path=project_dir / file_path,
@@ -1,11 +1,18 @@
1
1
  """$project_name: A Flower / $framework_str app."""
2
2
 
3
- import torch
4
3
  from flwr.client import ClientApp, NumPyClient
5
4
  from flwr.common import Context
6
5
  from transformers import AutoModelForSequenceClassification
7
6
 
8
- from $import_name.task import get_weights, load_data, set_weights, test, train
7
+ from $import_name.task import (
8
+ get_weights,
9
+ load_data,
10
+ set_weights,
11
+ train,
12
+ test,
13
+ CHECKPOINT,
14
+ DEVICE,
15
+ )
9
16
 
10
17
 
11
18
  # Flower client
@@ -15,34 +22,37 @@ class FlowerClient(NumPyClient):
15
22
  self.trainloader = trainloader
16
23
  self.testloader = testloader
17
24
  self.local_epochs = local_epochs
18
- self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
19
- self.net.to(self.device)
20
25
 
21
- def fit(self, parameters, config):
26
+ def get_parameters(self, config):
27
+ return get_weights(self.net)
28
+
29
+ def set_parameters(self, parameters):
22
30
  set_weights(self.net, parameters)
23
- train(self.net, self.trainloader, epochs=self.local_epochs, device=self.device)
24
- return get_weights(self.net), len(self.trainloader), {}
31
+
32
+ def fit(self, parameters, config):
33
+ self.set_parameters(parameters)
34
+ train(
35
+ self.net,
36
+ self.trainloader,
37
+ epochs=self.local_epochs,
38
+ )
39
+ return self.get_parameters(config={}), len(self.trainloader), {}
25
40
 
26
41
  def evaluate(self, parameters, config):
27
- set_weights(self.net, parameters)
28
- loss, accuracy = test(self.net, self.testloader, self.device)
42
+ self.set_parameters(parameters)
43
+ loss, accuracy = test(self.net, self.testloader)
29
44
  return float(loss), len(self.testloader), {"accuracy": accuracy}
30
45
 
31
46
 
32
47
  def client_fn(context: Context):
48
+ # Load model and data
49
+ net = AutoModelForSequenceClassification.from_pretrained(
50
+ CHECKPOINT, num_labels=2
51
+ ).to(DEVICE)
33
52
 
34
- # Get this client's dataset partition
35
53
  partition_id = context.node_config["partition-id"]
36
54
  num_partitions = context.node_config["num-partitions"]
37
- model_name = context.run_config["model-name"]
38
- trainloader, valloader = load_data(partition_id, num_partitions, model_name)
39
-
40
- # Load model
41
- num_labels = context.run_config["num-labels"]
42
- net = AutoModelForSequenceClassification.from_pretrained(
43
- model_name, num_labels=num_labels
44
- )
45
-
55
+ trainloader, valloader = load_data(partition_id, num_partitions)
46
56
  local_epochs = context.run_config["local-epochs"]
47
57
 
48
58
  # Return Client instance
@@ -17,6 +17,9 @@ class FlowerClient(NumPyClient):
17
17
  self.batch_size = batch_size
18
18
  self.verbose = verbose
19
19
 
20
+ def get_parameters(self, config):
21
+ return self.model.get_weights()
22
+
20
23
  def fit(self, parameters, config):
21
24
  self.model.set_weights(parameters)
22
25
  self.model.fit(
@@ -1,33 +1,18 @@
1
1
  """$project_name: A Flower / $framework_str app."""
2
2
 
3
- from flwr.common import Context, ndarrays_to_parameters
4
- from flwr.server import ServerApp, ServerAppComponents, ServerConfig
3
+ from flwr.common import Context
5
4
  from flwr.server.strategy import FedAvg
6
- from transformers import AutoModelForSequenceClassification
7
-
8
- from $import_name.task import get_weights
5
+ from flwr.server import ServerApp, ServerAppComponents, ServerConfig
9
6
 
10
7
 
11
8
  def server_fn(context: Context):
12
9
  # Read from config
13
10
  num_rounds = context.run_config["num-server-rounds"]
14
- fraction_fit = context.run_config["fraction-fit"]
15
-
16
- # Initialize global model
17
- model_name = context.run_config["model-name"]
18
- num_labels = context.run_config["num-labels"]
19
- net = AutoModelForSequenceClassification.from_pretrained(
20
- model_name, num_labels=num_labels
21
- )
22
-
23
- weights = get_weights(net)
24
- initial_parameters = ndarrays_to_parameters(weights)
25
11
 
26
12
  # Define strategy
27
13
  strategy = FedAvg(
28
- fraction_fit=fraction_fit,
14
+ fraction_fit=1.0,
29
15
  fraction_evaluate=1.0,
30
- initial_parameters=initial_parameters,
31
16
  )
32
17
  config = ServerConfig(num_rounds=num_rounds)
33
18
 
@@ -4,25 +4,24 @@ import warnings
4
4
  from collections import OrderedDict
5
5
 
6
6
  import torch
7
- import transformers
8
- from datasets.utils.logging import disable_progress_bar
9
7
  from evaluate import load as load_metric
10
- from flwr_datasets import FederatedDataset
11
- from flwr_datasets.partitioner import IidPartitioner
12
8
  from torch.optim import AdamW
13
9
  from torch.utils.data import DataLoader
14
10
  from transformers import AutoTokenizer, DataCollatorWithPadding
15
11
 
12
+ from flwr_datasets import FederatedDataset
13
+ from flwr_datasets.partitioner import IidPartitioner
14
+
15
+
16
16
  warnings.filterwarnings("ignore", category=UserWarning)
17
- warnings.filterwarnings("ignore", category=FutureWarning)
18
- disable_progress_bar()
19
- transformers.logging.set_verbosity_error()
17
+ DEVICE = torch.device("cpu")
18
+ CHECKPOINT = "distilbert-base-uncased" # transformer model checkpoint
20
19
 
21
20
 
22
21
  fds = None # Cache FederatedDataset
23
22
 
24
23
 
25
- def load_data(partition_id: int, num_partitions: int, model_name: str):
24
+ def load_data(partition_id: int, num_partitions: int):
26
25
  """Load IMDB data (training and eval)"""
27
26
  # Only initialize `FederatedDataset` once
28
27
  global fds
@@ -36,12 +35,10 @@ def load_data(partition_id: int, num_partitions: int, model_name: str):
36
35
  # Divide data: 80% train, 20% test
37
36
  partition_train_test = partition.train_test_split(test_size=0.2, seed=42)
38
37
 
39
- tokenizer = AutoTokenizer.from_pretrained(model_name)
38
+ tokenizer = AutoTokenizer.from_pretrained(CHECKPOINT)
40
39
 
41
40
  def tokenize_function(examples):
42
- return tokenizer(
43
- examples["text"], truncation=True, add_special_tokens=True, max_length=512
44
- )
41
+ return tokenizer(examples["text"], truncation=True)
45
42
 
46
43
  partition_train_test = partition_train_test.map(tokenize_function, batched=True)
47
44
  partition_train_test = partition_train_test.remove_columns("text")
@@ -62,12 +59,12 @@ def load_data(partition_id: int, num_partitions: int, model_name: str):
62
59
  return trainloader, testloader
63
60
 
64
61
 
65
- def train(net, trainloader, epochs, device):
62
+ def train(net, trainloader, epochs):
66
63
  optimizer = AdamW(net.parameters(), lr=5e-5)
67
64
  net.train()
68
65
  for _ in range(epochs):
69
66
  for batch in trainloader:
70
- batch = {k: v.to(device) for k, v in batch.items()}
67
+ batch = {k: v.to(DEVICE) for k, v in batch.items()}
71
68
  outputs = net(**batch)
72
69
  loss = outputs.loss
73
70
  loss.backward()
@@ -75,12 +72,12 @@ def train(net, trainloader, epochs, device):
75
72
  optimizer.zero_grad()
76
73
 
77
74
 
78
- def test(net, testloader, device):
75
+ def test(net, testloader):
79
76
  metric = load_metric("accuracy")
80
77
  loss = 0
81
78
  net.eval()
82
79
  for batch in testloader:
83
- batch = {k: v.to(device) for k, v in batch.items()}
80
+ batch = {k: v.to(DEVICE) for k, v in batch.items()}
84
81
  with torch.no_grad():
85
82
  outputs = net(**batch)
86
83
  logits = outputs.logits
@@ -8,7 +8,7 @@ version = "1.0.0"
8
8
  description = ""
9
9
  license = "Apache-2.0"
10
10
  dependencies = [
11
- "flwr[simulation]>=1.11.0",
11
+ "flwr[simulation]>=1.10.0",
12
12
  "flwr-datasets>=0.3.0",
13
13
  "torch==2.2.1",
14
14
  "transformers>=4.30.0,<5.0",
@@ -29,18 +29,10 @@ clientapp = "$import_name.client_app:app"
29
29
 
30
30
  [tool.flwr.app.config]
31
31
  num-server-rounds = 3
32
- fraction-fit = 0.5
33
32
  local-epochs = 1
34
- model-name = "prajjwal1/bert-tiny" # Set a larger model if you have access to more GPU resources
35
- num-labels = 2
36
33
 
37
34
  [tool.flwr.federations]
38
35
  default = "localhost"
39
36
 
40
37
  [tool.flwr.federations.localhost]
41
38
  options.num-supernodes = 10
42
-
43
- [tool.flwr.federations.localhost-gpu]
44
- options.num-supernodes = 10
45
- options.backend.client-resources.num-cpus = 4 # each ClientApp assumes to use 4CPUs
46
- options.backend.client-resources.num-gpus = 0.25 # at most 4 ClientApps will run in a given GPU
flwr/client/app.py CHANGED
@@ -35,7 +35,6 @@ from flwr.client.typing import ClientFnExt
35
35
  from flwr.common import GRPC_MAX_MESSAGE_LENGTH, Context, EventType, Message, event
36
36
  from flwr.common.address import parse_address
37
37
  from flwr.common.constant import (
38
- CLIENTAPPIO_API_DEFAULT_ADDRESS,
39
38
  MISSING_EXTRA_REST,
40
39
  RUN_ID_NUM_BYTES,
41
40
  TRANSPORT_TYPE_GRPC_ADAPTER,
@@ -61,6 +60,8 @@ from .message_handler.message_handler import handle_control_message
61
60
  from .node_state import NodeState
62
61
  from .numpy_client import NumPyClient
63
62
 
63
+ ADDRESS_CLIENTAPPIO_API_GRPC_RERE = "0.0.0.0:9094"
64
+
64
65
  ISOLATION_MODE_SUBPROCESS = "subprocess"
65
66
  ISOLATION_MODE_PROCESS = "process"
66
67
 
@@ -210,7 +211,7 @@ def start_client_internal(
210
211
  max_wait_time: Optional[float] = None,
211
212
  flwr_path: Optional[Path] = None,
212
213
  isolation: Optional[str] = None,
213
- supernode_address: Optional[str] = CLIENTAPPIO_API_DEFAULT_ADDRESS,
214
+ supernode_address: Optional[str] = ADDRESS_CLIENTAPPIO_API_GRPC_RERE,
214
215
  ) -> None:
215
216
  """Start a Flower client node which connects to a Flower server.
216
217
 
@@ -265,7 +266,7 @@ def start_client_internal(
265
266
  by the SueprNode and communicates using gRPC at the address
266
267
  `supernode_address`. If `process`, the `ClientApp` runs in a separate isolated
267
268
  process and communicates using gRPC at the address `supernode_address`.
268
- supernode_address : Optional[str] (default: `CLIENTAPPIO_API_DEFAULT_ADDRESS`)
269
+ supernode_address : Optional[str] (default: `ADDRESS_CLIENTAPPIO_API_GRPC_RERE`)
269
270
  The SuperNode gRPC server address.
270
271
  """
271
272
  if insecure is None:
flwr/client/client_app.py CHANGED
@@ -41,11 +41,11 @@ def _alert_erroneous_client_fn() -> None:
41
41
 
42
42
  def _inspect_maybe_adapt_client_fn_signature(client_fn: ClientFnExt) -> ClientFnExt:
43
43
  client_fn_args = inspect.signature(client_fn).parameters
44
+ first_arg = list(client_fn_args.keys())[0]
44
45
 
45
46
  if len(client_fn_args) != 1:
46
47
  _alert_erroneous_client_fn()
47
48
 
48
- first_arg = list(client_fn_args.keys())[0]
49
49
  first_arg_type = client_fn_args[first_arg].annotation
50
50
 
51
51
  if first_arg_type is str or first_arg == "cid":
@@ -263,7 +263,7 @@ def _registration_error(fn_name: str) -> ValueError:
263
263
  >>> class FlowerClient(NumPyClient):
264
264
  >>> # ...
265
265
  >>>
266
- >>> def client_fn(context: Context):
266
+ >>> def client_fn(cid) -> Client:
267
267
  >>> return FlowerClient().to_client()
268
268
  >>>
269
269
  >>> app = ClientApp(
@@ -130,12 +130,13 @@ class AuthenticateClientInterceptor(grpc.UnaryUnaryClientInterceptor): # type:
130
130
  if self.shared_secret is None:
131
131
  raise RuntimeError("Failure to compute hmac")
132
132
 
133
- message_bytes = request.SerializeToString(deterministic=True)
134
133
  metadata.append(
135
134
  (
136
135
  _AUTH_TOKEN_HEADER,
137
136
  base64.urlsafe_b64encode(
138
- compute_hmac(self.shared_secret, message_bytes)
137
+ compute_hmac(
138
+ self.shared_secret, request.SerializeToString(True)
139
+ )
139
140
  ),
140
141
  )
141
142
  )
@@ -30,7 +30,6 @@ from cryptography.hazmat.primitives.serialization import (
30
30
  from flwr.common import EventType, event
31
31
  from flwr.common.config import parse_config_args
32
32
  from flwr.common.constant import (
33
- FLEET_API_GRPC_RERE_DEFAULT_ADDRESS,
34
33
  TRANSPORT_TYPE_GRPC_ADAPTER,
35
34
  TRANSPORT_TYPE_GRPC_RERE,
36
35
  TRANSPORT_TYPE_REST,
@@ -45,6 +44,8 @@ from ..app import (
45
44
  )
46
45
  from ..clientapp.utils import get_load_client_app_fn
47
46
 
47
+ ADDRESS_FLEET_API_GRPC_RERE = "0.0.0.0:9092"
48
+
48
49
 
49
50
  def run_supernode() -> None:
50
51
  """Run Flower SuperNode."""
@@ -102,11 +103,11 @@ def run_client_app() -> None:
102
103
 
103
104
  def _warn_deprecated_server_arg(args: argparse.Namespace) -> None:
104
105
  """Warn about the deprecated argument `--server`."""
105
- if args.server != FLEET_API_GRPC_RERE_DEFAULT_ADDRESS:
106
+ if args.server != ADDRESS_FLEET_API_GRPC_RERE:
106
107
  warn = "Passing flag --server is deprecated. Use --superlink instead."
107
108
  warn_deprecated_feature(warn)
108
109
 
109
- if args.superlink != FLEET_API_GRPC_RERE_DEFAULT_ADDRESS:
110
+ if args.superlink != ADDRESS_FLEET_API_GRPC_RERE:
110
111
  # if `--superlink` also passed, then
111
112
  # warn user that this argument overrides what was passed with `--server`
112
113
  log(
@@ -246,12 +247,12 @@ def _parse_args_common(parser: argparse.ArgumentParser) -> None:
246
247
  )
247
248
  parser.add_argument(
248
249
  "--server",
249
- default=FLEET_API_GRPC_RERE_DEFAULT_ADDRESS,
250
+ default=ADDRESS_FLEET_API_GRPC_RERE,
250
251
  help="Server address",
251
252
  )
252
253
  parser.add_argument(
253
254
  "--superlink",
254
- default=FLEET_API_GRPC_RERE_DEFAULT_ADDRESS,
255
+ default=ADDRESS_FLEET_API_GRPC_RERE,
255
256
  help="SuperLink Fleet API (gRPC-rere) address (IPv4, IPv6, or a domain name)",
256
257
  )
257
258
  parser.add_argument(
flwr/common/constant.py CHANGED
@@ -37,18 +37,7 @@ TRANSPORT_TYPES = [
37
37
  TRANSPORT_TYPE_VCE,
38
38
  ]
39
39
 
40
- # Addresses
41
- # SuperNode
42
- CLIENTAPPIO_API_DEFAULT_ADDRESS = "0.0.0.0:9094"
43
- # SuperExec
44
- EXEC_API_DEFAULT_ADDRESS = "0.0.0.0:9093"
45
- # SuperLink
46
- DRIVER_API_DEFAULT_ADDRESS = "0.0.0.0:9091"
47
- FLEET_API_GRPC_RERE_DEFAULT_ADDRESS = "0.0.0.0:9092"
48
- FLEET_API_GRPC_BIDI_DEFAULT_ADDRESS = (
49
- "[::]:8080" # IPv6 to keep start_server compatible
50
- )
51
- FLEET_API_REST_DEFAULT_ADDRESS = "0.0.0.0:9093"
40
+ SUPEREXEC_DEFAULT_ADDRESS = "0.0.0.0:9093"
52
41
 
53
42
  # Constants for ping
54
43
  PING_DEFAULT_INTERVAL = 30
@@ -119,7 +119,7 @@ class RecordSet:
119
119
  Let's see an example.
120
120
 
121
121
  >>> from flwr.common import RecordSet
122
- >>> from flwr.common import ConfigsRecord, MetricsRecord, ParametersRecord
122
+ >>> from flwr.common import ConfigsRecords, MetricsRecords, ParametersRecord
123
123
  >>>
124
124
  >>> # Let's begin with an empty record
125
125
  >>> my_recordset = RecordSet()
@@ -15,18 +15,7 @@
15
15
  """Typed dict base class for *Records."""
16
16
 
17
17
 
18
- from typing import (
19
- Callable,
20
- Dict,
21
- Generic,
22
- ItemsView,
23
- Iterator,
24
- KeysView,
25
- MutableMapping,
26
- TypeVar,
27
- ValuesView,
28
- cast,
29
- )
18
+ from typing import Callable, Dict, Generic, Iterator, MutableMapping, TypeVar, cast
30
19
 
31
20
  K = TypeVar("K") # Key type
32
21
  V = TypeVar("V") # Value type
@@ -84,15 +73,3 @@ class TypedDict(MutableMapping[K, V], Generic[K, V]):
84
73
  if isinstance(other, dict):
85
74
  return data == other
86
75
  return NotImplemented
87
-
88
- def keys(self) -> KeysView[K]:
89
- """D.keys() -> a set-like object providing a view on D's keys."""
90
- return cast(Dict[K, V], self.__dict__["_data"]).keys()
91
-
92
- def values(self) -> ValuesView[V]:
93
- """D.values() -> an object providing a view on D's values."""
94
- return cast(Dict[K, V], self.__dict__["_data"]).values()
95
-
96
- def items(self) -> ItemsView[K, V]:
97
- """D.items() -> a set-like object providing a view on D's items."""
98
- return cast(Dict[K, V], self.__dict__["_data"]).items()
flwr/server/app.py CHANGED
@@ -36,10 +36,6 @@ from flwr.common import GRPC_MAX_MESSAGE_LENGTH, EventType, event
36
36
  from flwr.common.address import parse_address
37
37
  from flwr.common.config import get_flwr_dir
38
38
  from flwr.common.constant import (
39
- DRIVER_API_DEFAULT_ADDRESS,
40
- FLEET_API_GRPC_BIDI_DEFAULT_ADDRESS,
41
- FLEET_API_GRPC_RERE_DEFAULT_ADDRESS,
42
- FLEET_API_REST_DEFAULT_ADDRESS,
43
39
  MISSING_EXTRA_REST,
44
40
  TRANSPORT_TYPE_GRPC_ADAPTER,
45
41
  TRANSPORT_TYPE_GRPC_RERE,
@@ -72,13 +68,18 @@ from .superlink.fleet.grpc_rere.fleet_servicer import FleetServicer
72
68
  from .superlink.fleet.grpc_rere.server_interceptor import AuthenticateServerInterceptor
73
69
  from .superlink.state import StateFactory
74
70
 
71
+ ADDRESS_DRIVER_API = "0.0.0.0:9091"
72
+ ADDRESS_FLEET_API_GRPC_RERE = "0.0.0.0:9092"
73
+ ADDRESS_FLEET_API_GRPC_BIDI = "[::]:8080" # IPv6 to keep start_server compatible
74
+ ADDRESS_FLEET_API_REST = "0.0.0.0:9093"
75
+
75
76
  DATABASE = ":flwr-in-memory-state:"
76
77
  BASE_DIR = get_flwr_dir() / "superlink" / "ffs"
77
78
 
78
79
 
79
80
  def start_server( # pylint: disable=too-many-arguments,too-many-locals
80
81
  *,
81
- server_address: str = FLEET_API_GRPC_BIDI_DEFAULT_ADDRESS,
82
+ server_address: str = ADDRESS_FLEET_API_GRPC_BIDI,
82
83
  server: Optional[Server] = None,
83
84
  config: Optional[ServerConfig] = None,
84
85
  strategy: Optional[Strategy] = None,
@@ -231,9 +232,9 @@ def run_superlink() -> None:
231
232
  TRANSPORT_TYPE_GRPC_RERE,
232
233
  TRANSPORT_TYPE_GRPC_ADAPTER,
233
234
  ]:
234
- args.fleet_api_address = FLEET_API_GRPC_RERE_DEFAULT_ADDRESS
235
+ args.fleet_api_address = ADDRESS_FLEET_API_GRPC_RERE
235
236
  elif args.fleet_api_type == TRANSPORT_TYPE_REST:
236
- args.fleet_api_address = FLEET_API_REST_DEFAULT_ADDRESS
237
+ args.fleet_api_address = ADDRESS_FLEET_API_REST
237
238
 
238
239
  fleet_address, host, port = _format_address(args.fleet_api_address)
239
240
 
@@ -652,7 +653,7 @@ def _add_args_driver_api(parser: argparse.ArgumentParser) -> None:
652
653
  parser.add_argument(
653
654
  "--driver-api-address",
654
655
  help="Driver API (gRPC) server address (IPv4, IPv6, or a domain name).",
655
- default=DRIVER_API_DEFAULT_ADDRESS,
656
+ default=ADDRESS_DRIVER_API,
656
657
  )
657
658
 
658
659
 
@@ -22,7 +22,6 @@ from typing import Iterable, List, Optional, cast
22
22
  import grpc
23
23
 
24
24
  from flwr.common import DEFAULT_TTL, Message, Metadata, RecordSet
25
- from flwr.common.constant import DRIVER_API_DEFAULT_ADDRESS
26
25
  from flwr.common.grpc import create_channel
27
26
  from flwr.common.logger import log
28
27
  from flwr.common.serde import (
@@ -46,6 +45,8 @@ from flwr.proto.task_pb2 import TaskIns # pylint: disable=E0611
46
45
 
47
46
  from .driver import Driver
48
47
 
48
+ DEFAULT_SERVER_ADDRESS_DRIVER = "[::]:9091"
49
+
49
50
  ERROR_MESSAGE_DRIVER_NOT_CONNECTED = """
50
51
  [Driver] Error: Not connected.
51
52
 
@@ -72,7 +73,7 @@ class GrpcDriver(Driver):
72
73
  def __init__( # pylint: disable=too-many-arguments
73
74
  self,
74
75
  run_id: int,
75
- driver_service_address: str = DRIVER_API_DEFAULT_ADDRESS,
76
+ driver_service_address: str = DEFAULT_SERVER_ADDRESS_DRIVER,
76
77
  root_certificates: Optional[bytes] = None,
77
78
  ) -> None:
78
79
  self._run_id = run_id
@@ -31,7 +31,6 @@ from flwr.common.config import (
31
31
  get_project_config,
32
32
  get_project_dir,
33
33
  )
34
- from flwr.common.constant import DRIVER_API_DEFAULT_ADDRESS
35
34
  from flwr.common.logger import log, update_console_handler, warn_deprecated_feature
36
35
  from flwr.common.object_ref import load_app
37
36
  from flwr.common.typing import UserConfig
@@ -45,6 +44,8 @@ from .driver import Driver
45
44
  from .driver.grpc_driver import GrpcDriver
46
45
  from .server_app import LoadServerAppError, ServerApp
47
46
 
47
+ ADDRESS_DRIVER_API = "0.0.0.0:9091"
48
+
48
49
 
49
50
  def run(
50
51
  driver: Driver,
@@ -111,11 +112,11 @@ def run_server_app() -> None:
111
112
  "app by executing `flwr new` and following the prompt."
112
113
  )
113
114
 
114
- if args.server != DRIVER_API_DEFAULT_ADDRESS:
115
+ if args.server != ADDRESS_DRIVER_API:
115
116
  warn = "Passing flag --server is deprecated. Use --superlink instead."
116
117
  warn_deprecated_feature(warn)
117
118
 
118
- if args.superlink != DRIVER_API_DEFAULT_ADDRESS:
119
+ if args.superlink != ADDRESS_DRIVER_API:
119
120
  # if `--superlink` also passed, then
120
121
  # warn user that this argument overrides what was passed with `--server`
121
122
  log(
@@ -274,12 +275,12 @@ def _parse_args_run_server_app() -> argparse.ArgumentParser:
274
275
  )
275
276
  parser.add_argument(
276
277
  "--server",
277
- default=DRIVER_API_DEFAULT_ADDRESS,
278
+ default=ADDRESS_DRIVER_API,
278
279
  help="Server address",
279
280
  )
280
281
  parser.add_argument(
281
282
  "--superlink",
282
- default=DRIVER_API_DEFAULT_ADDRESS,
283
+ default=ADDRESS_DRIVER_API,
283
284
  help="SuperLink Driver API (gRPC-rere) address (IPv4, IPv6, or a domain name)",
284
285
  )
285
286
  parser.add_argument(
@@ -188,8 +188,7 @@ class AuthenticateServerInterceptor(grpc.ServerInterceptor): # type: ignore
188
188
  self, public_key: ec.EllipticCurvePublicKey, request: Request, hmac_value: bytes
189
189
  ) -> bool:
190
190
  shared_secret = generate_shared_key(self.server_private_key, public_key)
191
- message_bytes = request.SerializeToString(deterministic=True)
192
- return verify_hmac(shared_secret, message_bytes, hmac_value)
191
+ return verify_hmac(shared_secret, request.SerializeToString(True), hmac_value)
193
192
 
194
193
  def _create_authenticated_node(
195
194
  self,
@@ -52,11 +52,16 @@ class RayBackend(Backend):
52
52
 
53
53
  # Validate client resources
54
54
  self.client_resources_key = "client_resources"
55
- self.client_resources = self._validate_client_resources(config=backend_config)
55
+ client_resources = self._validate_client_resources(config=backend_config)
56
56
 
57
- # Valide actor resources
58
- self.actor_kwargs = self._validate_actor_arguments(config=backend_config)
59
- self.pool: Optional[BasicActorPool] = None
57
+ # Create actor pool
58
+ actor_kwargs = self._validate_actor_arguments(config=backend_config)
59
+
60
+ self.pool = BasicActorPool(
61
+ actor_type=ClientAppActor,
62
+ client_resources=client_resources,
63
+ actor_kwargs=actor_kwargs,
64
+ )
60
65
 
61
66
  self.app_fn: Optional[Callable[[], ClientApp]] = None
62
67
 
@@ -117,24 +122,14 @@ class RayBackend(Backend):
117
122
  @property
118
123
  def num_workers(self) -> int:
119
124
  """Return number of actors in pool."""
120
- return self.pool.num_actors if self.pool else 0
125
+ return self.pool.num_actors
121
126
 
122
127
  def is_worker_idle(self) -> bool:
123
128
  """Report whether the pool has idle actors."""
124
- return self.pool.is_actor_available() if self.pool else False
129
+ return self.pool.is_actor_available()
125
130
 
126
131
  def build(self, app_fn: Callable[[], ClientApp]) -> None:
127
132
  """Build pool of Ray actors that this backend will submit jobs to."""
128
- # Create Actor Pool
129
- try:
130
- self.pool = BasicActorPool(
131
- actor_type=ClientAppActor,
132
- client_resources=self.client_resources,
133
- actor_kwargs=self.actor_kwargs,
134
- )
135
- except Exception as ex:
136
- raise ex
137
-
138
133
  self.pool.add_actors_to_pool(self.pool.actors_capacity)
139
134
  # Set ClientApp callable that ray actors will use
140
135
  self.app_fn = app_fn
@@ -151,9 +146,6 @@ class RayBackend(Backend):
151
146
  """
152
147
  partition_id = context.node_config[PARTITION_ID_KEY]
153
148
 
154
- if self.pool is None:
155
- raise ValueError("The actor pool is empty, unfit to process messages.")
156
-
157
149
  if self.app_fn is None:
158
150
  raise ValueError(
159
151
  "Unspecified function to load a `ClientApp`. "
@@ -187,7 +179,6 @@ class RayBackend(Backend):
187
179
 
188
180
  def terminate(self) -> None:
189
181
  """Terminate all actors in actor pool."""
190
- if self.pool:
191
- self.pool.terminate_all_actors()
182
+ self.pool.terminate_all_actors()
192
183
  ray.shutdown()
193
184
  log(DEBUG, "Terminated %s", self.__class__.__name__)
@@ -124,14 +124,14 @@ def pool_size_from_resources(client_resources: Dict[str, Union[int, float]]) ->
124
124
  WARNING,
125
125
  "The ActorPool is empty. The system (CPUs=%s, GPUs=%s) "
126
126
  "does not meet the criteria to host at least one client with resources:"
127
- " %s. Lowering these resources could help.",
127
+ " %s. Lowering the `client_resources` could help.",
128
128
  num_cpus,
129
129
  num_gpus,
130
130
  client_resources,
131
131
  )
132
132
  raise ValueError(
133
133
  "ActorPool is empty. Stopping Simulation. "
134
- "Check `num_cpus` and/or `num_gpus` passed to the simulation engine"
134
+ "Check 'client_resources' passed to `start_simulation`"
135
135
  )
136
136
 
137
137
  return total_num_actors
@@ -216,7 +216,6 @@ def run_simulation_from_cli() -> None:
216
216
  app_dir=app_dir,
217
217
  run=run,
218
218
  enable_tf_gpu_growth=args.enable_tf_gpu_growth,
219
- delay_start=args.delay_start,
220
219
  verbose_logging=args.verbose,
221
220
  server_app_run_config=fused_config,
222
221
  is_app=is_app,
@@ -310,6 +309,7 @@ def run_serverapp_th(
310
309
  f_stop: threading.Event,
311
310
  has_exception: threading.Event,
312
311
  enable_tf_gpu_growth: bool,
312
+ delay_launch: int = 3,
313
313
  ) -> threading.Thread:
314
314
  """Run SeverApp in a thread."""
315
315
 
@@ -365,6 +365,7 @@ def run_serverapp_th(
365
365
  server_app,
366
366
  ),
367
367
  )
368
+ sleep(delay_launch)
368
369
  serverapp_th.start()
369
370
  return serverapp_th
370
371
 
@@ -379,7 +380,6 @@ def _main_loop(
379
380
  enable_tf_gpu_growth: bool,
380
381
  run: Run,
381
382
  exit_event: EventType,
382
- delay_start: int,
383
383
  flwr_dir: Optional[str] = None,
384
384
  client_app: Optional[ClientApp] = None,
385
385
  client_app_attr: Optional[str] = None,
@@ -419,9 +419,6 @@ def _main_loop(
419
419
  enable_tf_gpu_growth=enable_tf_gpu_growth,
420
420
  )
421
421
 
422
- # Buffer time so the `ServerApp` in separate thread is ready
423
- log(DEBUG, "Buffer time delay: %ds", delay_start)
424
- sleep(delay_start)
425
422
  # Start Simulation Engine
426
423
  vce.start_vce(
427
424
  num_supernodes=num_supernodes,
@@ -470,7 +467,6 @@ def _run_simulation(
470
467
  flwr_dir: Optional[str] = None,
471
468
  run: Optional[Run] = None,
472
469
  enable_tf_gpu_growth: bool = False,
473
- delay_start: int = 5,
474
470
  verbose_logging: bool = False,
475
471
  is_app: bool = False,
476
472
  ) -> None:
@@ -527,7 +523,6 @@ def _run_simulation(
527
523
  enable_tf_gpu_growth,
528
524
  run,
529
525
  exit_event,
530
- delay_start,
531
526
  flwr_dir,
532
527
  client_app,
533
528
  client_app_attr,
@@ -615,13 +610,6 @@ def _parse_args_run_simulation() -> argparse.ArgumentParser:
615
610
  "Read more about how `tf.config.experimental.set_memory_growth()` works in "
616
611
  "the TensorFlow documentation: https://www.tensorflow.org/api/stable.",
617
612
  )
618
- parser.add_argument(
619
- "--delay-start",
620
- type=int,
621
- default=3,
622
- help="Buffer time (in seconds) to delay the start the simulation engine after "
623
- "the `ServerApp`, which runs in a separate thread, has been launched.",
624
- )
625
613
  parser.add_argument(
626
614
  "--verbose",
627
615
  action="store_true",
flwr/superexec/app.py CHANGED
@@ -25,7 +25,7 @@ import grpc
25
25
  from flwr.common import EventType, event, log
26
26
  from flwr.common.address import parse_address
27
27
  from flwr.common.config import parse_config_args
28
- from flwr.common.constant import EXEC_API_DEFAULT_ADDRESS
28
+ from flwr.common.constant import SUPEREXEC_DEFAULT_ADDRESS
29
29
  from flwr.common.exit_handlers import register_exit_handlers
30
30
  from flwr.common.object_ref import load_app, validate
31
31
 
@@ -81,7 +81,7 @@ def _parse_args_run_superexec() -> argparse.ArgumentParser:
81
81
  parser.add_argument(
82
82
  "--address",
83
83
  help="SuperExec (gRPC) server address (IPv4, IPv6, or a domain name)",
84
- default=EXEC_API_DEFAULT_ADDRESS,
84
+ default=SUPEREXEC_DEFAULT_ADDRESS,
85
85
  )
86
86
  parser.add_argument(
87
87
  "--executor",
@@ -23,13 +23,13 @@ from typing import Optional
23
23
  from typing_extensions import override
24
24
 
25
25
  from flwr.cli.install import install_from_fab
26
- from flwr.common.constant import DRIVER_API_DEFAULT_ADDRESS
27
26
  from flwr.common.grpc import create_channel
28
27
  from flwr.common.logger import log
29
28
  from flwr.common.serde import fab_to_proto, user_config_to_proto
30
29
  from flwr.common.typing import Fab, UserConfig
31
30
  from flwr.proto.driver_pb2 import CreateRunRequest # pylint: disable=E0611
32
31
  from flwr.proto.driver_pb2_grpc import DriverStub
32
+ from flwr.server.driver.grpc_driver import DEFAULT_SERVER_ADDRESS_DRIVER
33
33
 
34
34
  from .executor import Executor, RunTracker
35
35
 
@@ -50,7 +50,7 @@ class DeploymentEngine(Executor):
50
50
 
51
51
  def __init__(
52
52
  self,
53
- superlink: str = DRIVER_API_DEFAULT_ADDRESS,
53
+ superlink: str = DEFAULT_SERVER_ADDRESS_DRIVER,
54
54
  root_certificates: Optional[str] = None,
55
55
  flwr_dir: Optional[str] = None,
56
56
  ) -> None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flwr-nightly
3
- Version: 1.11.1.dev20240912
3
+ Version: 1.12.0.dev20240907
4
4
  Summary: Flower: A Friendly Federated Learning Framework
5
5
  Home-page: https://flower.ai
6
6
  License: Apache-2.0
@@ -6,7 +6,7 @@ flwr/cli/config_utils.py,sha256=mDGXbcIxG14UpkUplILBYUkSk5M1LeTzZYDGNx-pFpU,7540
6
6
  flwr/cli/example.py,sha256=1bGDYll3BXQY2kRqSN-oICqS5n1b9m0g0RvXTopXHl4,2215
7
7
  flwr/cli/install.py,sha256=tUncrbZYRbC9QEcWSeTER16plPEoU-ERP0-nMgWiSPo,7094
8
8
  flwr/cli/new/__init__.py,sha256=cQzK1WH4JP2awef1t2UQ2xjl1agVEz9rwutV18SWV1k,789
9
- flwr/cli/new/new.py,sha256=9nBm6yjy3q4AHxT-wzV3n5cgO82F19xajfrdu3DIfyk,9605
9
+ flwr/cli/new/new.py,sha256=uRC1nr22JomszfBAzQ3w4fiKrq31nxlMFquYGpPVei0,10074
10
10
  flwr/cli/new/templates/__init__.py,sha256=4luU8RL-CK8JJCstQ_ON809W9bNTkY1l9zSaPKBkgwY,725
11
11
  flwr/cli/new/templates/app/.gitignore.tpl,sha256=XixnHdyeMB2vwkGtGnwHqoWpH-9WChdyG0GXe57duhc,3078
12
12
  flwr/cli/new/templates/app/LICENSE.tpl,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
@@ -18,13 +18,13 @@ flwr/cli/new/templates/app/code/__init__.baseline.py.tpl,sha256=YkHAgppUeD2BnBoG
18
18
  flwr/cli/new/templates/app/code/__init__.py,sha256=EM6vfvgAILKPaPn7H1wMV1Wi01WyZCP_Eg6NxD6oWg8,736
19
19
  flwr/cli/new/templates/app/code/__init__.py.tpl,sha256=J0Gn74E7khpLyKJVNqOPu7ev93vkcu1PZugsbxtABMw,52
20
20
  flwr/cli/new/templates/app/code/client.baseline.py.tpl,sha256=1htktXX3jXX05r0vuG_afjS1sXGtuONW9EpiQ7vSBes,1901
21
- flwr/cli/new/templates/app/code/client.huggingface.py.tpl,sha256=ifD08KwjdoGieV26hFCgf3PQB6rMhj_NZLo5iUUndm8,1846
21
+ flwr/cli/new/templates/app/code/client.huggingface.py.tpl,sha256=62wtB4k1yrDApiG-rvGlOYFuiwAVk8kqJFmyY_v8HLo,1803
22
22
  flwr/cli/new/templates/app/code/client.jax.py.tpl,sha256=c2LDew2V8BUybZJiz1FeB3Kq4ey0Q2s0S5qNPUTNmI4,1490
23
23
  flwr/cli/new/templates/app/code/client.mlx.py.tpl,sha256=gxipt57ldc741qwRqSWtsLQH05JODKdGMTtvoXiBzDA,2906
24
24
  flwr/cli/new/templates/app/code/client.numpy.py.tpl,sha256=DMUXvQd2dr-wEn0ZrYJQhZ0OFUT4PKoHXtiD2haWnCI,570
25
25
  flwr/cli/new/templates/app/code/client.pytorch.py.tpl,sha256=WczaR5avJUhfw2Grn2KEC4tDJ4voIYG-2pAy-7i2cT8,1685
26
26
  flwr/cli/new/templates/app/code/client.sklearn.py.tpl,sha256=xW9cuKhybk5S8IeDZhbeb0DNegDIJGEYrzMKsxgc2GE,2978
27
- flwr/cli/new/templates/app/code/client.tensorflow.py.tpl,sha256=yBiiU7B9Kf70U52cPkNs_dUpYrrTwbUi2os-PAyheaM,1680
27
+ flwr/cli/new/templates/app/code/client.tensorflow.py.tpl,sha256=u3KKf7hC9xGqOIUJXYCHJ_jiIu3aVbsC8pxVxm4yN6I,1759
28
28
  flwr/cli/new/templates/app/code/dataset.baseline.py.tpl,sha256=jbd_exHAk2-Blu_kVutjPO6a_dkJQWb232zxSeXIZ1k,1453
29
29
  flwr/cli/new/templates/app/code/flwr_tune/__init__.py,sha256=JgNgBtKdm1jKM9625WxappCAVUGtYAmcjKSsXJ1u3ZQ,748
30
30
  flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl,sha256=DbotzaXzLDwplVBkJLOe5Lt5b6Yutwv9rJ69oVwyrvU,4397
@@ -34,7 +34,7 @@ flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl,sha256=yMVcbfGkTPV9A
34
34
  flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl,sha256=BhiqRg9w1MGuU5h2_vrLhRc0oHItYzE69qX_JI411k8,2754
35
35
  flwr/cli/new/templates/app/code/model.baseline.py.tpl,sha256=cSz6-IWsnMl7s04DW4URINiIppCIberrtE8NqK6Qz48,2571
36
36
  flwr/cli/new/templates/app/code/server.baseline.py.tpl,sha256=outx7lDXsWS8QXKWOGOiDno6eE8WL7LBD51ZkAuC3WU,1570
37
- flwr/cli/new/templates/app/code/server.huggingface.py.tpl,sha256=0PJmnZvR9_VPLSak1yVfkOx3dmqo6cynhY1l2s4AZrE,1158
37
+ flwr/cli/new/templates/app/code/server.huggingface.py.tpl,sha256=etpjLvGu6pVXzYQBKZp4tTbD3zm461qFo24NliKo74U,591
38
38
  flwr/cli/new/templates/app/code/server.jax.py.tpl,sha256=pIdUH-LgWRAGWQYLlivMNf8XnDSNDe2cCuRjlxbRzys,529
39
39
  flwr/cli/new/templates/app/code/server.mlx.py.tpl,sha256=RqiZ0k468SOlm9dcPr-fvA8xcWv4zwDCbJfBwL7P9Us,529
40
40
  flwr/cli/new/templates/app/code/server.numpy.py.tpl,sha256=RqiZ0k468SOlm9dcPr-fvA8xcWv4zwDCbJfBwL7P9Us,529
@@ -42,7 +42,7 @@ flwr/cli/new/templates/app/code/server.pytorch.py.tpl,sha256=DW5c8vzXCvFeIE8YIWB
42
42
  flwr/cli/new/templates/app/code/server.sklearn.py.tpl,sha256=25Ae3kDqjDdBl8LwkDwye69nevd02Pk_e7F3SQKLdyk,624
43
43
  flwr/cli/new/templates/app/code/server.tensorflow.py.tpl,sha256=xMhQ7AumowgLkgUilgjVK7IbpRhPjslhVJU-vID6NY8,856
44
44
  flwr/cli/new/templates/app/code/strategy.baseline.py.tpl,sha256=YkHAgppUeD2BnBoGfVB6dEvBfjuIPGsU1gw4CiUi3qA,40
45
- flwr/cli/new/templates/app/code/task.huggingface.py.tpl,sha256=ua6cAhJYPUCwML20DEucM0F4ZzzsEVQLYrRvhQ7CGRE,3347
45
+ flwr/cli/new/templates/app/code/task.huggingface.py.tpl,sha256=G_LOeGErw-6WZAyuT01mXqR6s_BUrQYErXf_nHLujo4,3153
46
46
  flwr/cli/new/templates/app/code/task.jax.py.tpl,sha256=F05eg149c9icRyVNdfcLyZvAXROQ7QhfifoGw_U1dsg,1530
47
47
  flwr/cli/new/templates/app/code/task.mlx.py.tpl,sha256=jWtCULLRr_9bCIJvoTLMx037-SDl_LF8udtA1UGoXDk,2946
48
48
  flwr/cli/new/templates/app/code/task.pytorch.py.tpl,sha256=NgbPix74X1t3ybaGjqdls30vF1i5oY3L7EQExhWhN74,3812
@@ -50,7 +50,7 @@ flwr/cli/new/templates/app/code/task.tensorflow.py.tpl,sha256=SKXAZdgBnPpbAbJ90R
50
50
  flwr/cli/new/templates/app/code/utils.baseline.py.tpl,sha256=YkHAgppUeD2BnBoGfVB6dEvBfjuIPGsU1gw4CiUi3qA,40
51
51
  flwr/cli/new/templates/app/pyproject.baseline.toml.tpl,sha256=4gi90W9_B1kj6rYkpvVJxhNX9Yctsv9OH6CzXP-dcE4,2666
52
52
  flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=pogRZLrwSfN_XH4NxDdMkhMh1O_7DP90VOoP-cP0HvI,1827
53
- flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl,sha256=CHJgkPNkJfzJhEbTe15uiV3AhOtIddQi-yofPZsCk3E,1143
53
+ flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl,sha256=nD0rRUyr_Cj0TaSH8PsiaMhCwu_BuOVX4oqWfFSvOcE,765
54
54
  flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=Tq6jeGcoOKzMwWWYxMVnzMcipLURHLiW69iYlD1ywMg,659
55
55
  flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=SHwYAA2qgIlOAU3Sb9BKSZcZ7O9biACg27MHexXUtDw,741
56
56
  flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=-FCi64ygMgQke3zApUt0XtkIBo3WtQoPAPhtp_FqkPE,612
@@ -61,9 +61,9 @@ flwr/cli/run/__init__.py,sha256=oCd6HmQDx-sqver1gecgx-uMA38BLTSiiKpl7RGNceg,789
61
61
  flwr/cli/run/run.py,sha256=RI6MgLBNYxmacjQg8XMAQ7VKxbV0DkRyJTfe4GsDFuw,7979
62
62
  flwr/cli/utils.py,sha256=l65Ul0YsSBPuypk0uorAtEDmLEYiUrzpCXi6zCg9mJ4,4506
63
63
  flwr/client/__init__.py,sha256=DGDoO0AEAfz-0CUFmLdyUUweAS64-07AOnmDfWUefK4,1192
64
- flwr/client/app.py,sha256=S7o09GZaD7XH3zdVow3XKbktkHvi6H-xnlrhNBHYQ80,31937
64
+ flwr/client/app.py,sha256=o_2bhmlBeZATtWnAPZhL-Q1Ly0QZxc9ou4i7t0HKumE,31956
65
65
  flwr/client/client.py,sha256=gy6WVlMUFAp8oevN4xpQPX30vPOIYGVqdbuFlTWkyG4,9080
66
- flwr/client/client_app.py,sha256=6TIH-B5lgKn199uzcjxfFKiGvKN5tmKYFpsovUrSXoo,10396
66
+ flwr/client/client_app.py,sha256=WcO4r6wrdfaus__3s22D2sYjfcptdgmVujUAYdNE6HU,10393
67
67
  flwr/client/clientapp/__init__.py,sha256=kZqChGnTChQ1WGSUkIlW2S5bc0d0mzDubCAmZUGRpEY,800
68
68
  flwr/client/clientapp/app.py,sha256=4QtblvJsZ0-V-QBbzyNqWV13ugrgJmkZnsHpBCuqgi8,7797
69
69
  flwr/client/clientapp/clientappio_servicer.py,sha256=5L6bjw_j3Mnx9kRFwYwxDNABKurBO5q1jZOWE_X11wQ,8522
@@ -74,7 +74,7 @@ flwr/client/grpc_adapter_client/connection.py,sha256=aOlCYasl8f2CrfcN-WrVEmvjAZF
74
74
  flwr/client/grpc_client/__init__.py,sha256=LsnbqXiJhgQcB0XzAlUQgPx011Uf7Y7yabIC1HxivJ8,735
75
75
  flwr/client/grpc_client/connection.py,sha256=czhRm23fwTgjN24Vf5nyNQ3hcb5Fo_5k-o9yZnelQCs,9362
76
76
  flwr/client/grpc_rere_client/__init__.py,sha256=MK-oSoV3kwUEQnIwl0GN4OpiHR7eLOrMA8ikunET130,752
77
- flwr/client/grpc_rere_client/client_interceptor.py,sha256=eONCq-uRYvRCxjdP4wIi_FDynDipHs3DYjExgzAcJ5M,5240
77
+ flwr/client/grpc_rere_client/client_interceptor.py,sha256=wRMgrxt_IN1MNsaJdNscfMZD7jExJOL2g8yV5mC_RBc,5238
78
78
  flwr/client/grpc_rere_client/connection.py,sha256=aiIWW9fVgJZNeZ9SjUAx5ax-3825JrjYc5E5l7XvzyM,10913
79
79
  flwr/client/grpc_rere_client/grpc_adapter.py,sha256=Pw7Toi4wCUIEdBMyv4yKirjgW6814gFhhAmsTYmV4IM,5005
80
80
  flwr/client/heartbeat.py,sha256=cx37mJBH8LyoIN4Lks85wtqT1mnU5GulQnr4pGCvAq0,2404
@@ -95,12 +95,12 @@ flwr/client/numpy_client.py,sha256=9rpj5OLmeeDQVzopR1My6A2VS3nkBFw6cmNcMMPYGlQ,1
95
95
  flwr/client/rest_client/__init__.py,sha256=5KGlp7pjc1dhNRkKlaNtUfQmg8wrRFh9lS3P3uRS-7Q,735
96
96
  flwr/client/rest_client/connection.py,sha256=21YNE6K6JfyZtwIftx1MGOkM78J9wb4EGGOyLS8ej0E,12767
97
97
  flwr/client/supernode/__init__.py,sha256=SUhWOzcgXRNXk1V9UgB5-FaWukqqrOEajVUHEcPkwyQ,865
98
- flwr/client/supernode/app.py,sha256=LlDO4hOzJZVIF6wmcSYYYnrVuSH_umvhr4m3EtVnLyI,11947
98
+ flwr/client/supernode/app.py,sha256=6dWrpgMDmbWt-GFzWcANGsDdpGuCS5fb4j7dEDeVvX4,11920
99
99
  flwr/client/typing.py,sha256=dxoTBnTMfqXr5J7G3y-uNjqxYCddvxhu89spfj4Lm2U,1048
100
100
  flwr/common/__init__.py,sha256=TVaoFEJE158aui1TPZQiJCDZX4RNHRyI8I55VC80HhI,3901
101
101
  flwr/common/address.py,sha256=1zvmVIAyYP6JbGkMnXuROzkYJ7aSKbJM754lC_kbh1M,3024
102
102
  flwr/common/config.py,sha256=TBw2sI0ZgZ3l3JrjfrcnD1mnMJbaHi_i8w68YXEgPUk,7586
103
- flwr/common/constant.py,sha256=BxVpp2o3h70h-klxiwsyLT7U5woj2GD-TXh92-STlLc,3351
103
+ flwr/common/constant.py,sha256=1XxuRezsr9fl3xvQNPR2kyFkwNeG_f5vZayv0PFh0kY,3012
104
104
  flwr/common/context.py,sha256=5Bd9RCrhLkYZOVR7vr97OVhzVBHQkS1fUsYiIKTwpxU,2239
105
105
  flwr/common/date.py,sha256=OcQuwpb2HxcblTqYm6H223ufop5UZw5N_fzalbpOVzY,891
106
106
  flwr/common/differential_privacy.py,sha256=WZWrL7C9XaB9l9NDkLDI5PvM7jwcoTTFu08ZVG8-M5Q,6113
@@ -118,8 +118,8 @@ flwr/common/record/configsrecord.py,sha256=6nIpGaeB_o8SvjMfD_iehJC1efAHgWyaeGfLD
118
118
  flwr/common/record/conversion_utils.py,sha256=n3I3SI2P6hUjyxbWNc0QAch-SEhfMK6Hm-UUaplAlUc,1393
119
119
  flwr/common/record/metricsrecord.py,sha256=aTuw0gWjRaZhekf76zg0h0rES3iEnTIGPZ7-jN2PYO4,5764
120
120
  flwr/common/record/parametersrecord.py,sha256=mOcERCUylgWLQ-hISYmOHXlt-Qohv8YtPnJdLO0Kr8U,7730
121
- flwr/common/record/recordset.py,sha256=sSofrBycZSqiHR4TzfI4_QoIIN-5B1LnMG0C9CiByAo,8312
122
- flwr/common/record/typeddict.py,sha256=TDPLdeuHiAUy9JyfJN0VF1zSyqdnf_uNWUFjAd2z_Os,3623
121
+ flwr/common/record/recordset.py,sha256=6-a6EYN2YlH0H62jymJcHGVFBB8gJo69U2lvWyAv60A,8314
122
+ flwr/common/record/typeddict.py,sha256=M9zU1vjuPmKRxA0uiP2v752TB3D2VfrJzKNWx-EFviw,3016
123
123
  flwr/common/recordset_compat.py,sha256=5prvfx8mT4ZWIEU4Gmz2wzCbO4yPjQ3ONr20uKt3UM0,13973
124
124
  flwr/common/retry_invoker.py,sha256=dQY5fPIKhy9OiFswZhLxA9fB455u-DYCvDVcFJmrPDk,11707
125
125
  flwr/common/secure_aggregation/__init__.py,sha256=erPnTWdOfMH0K0HQTmj5foDJ6t3iYcExy2aACy8iZNQ,731
@@ -193,7 +193,7 @@ flwr/proto/transport_pb2_grpc.py,sha256=vLN3EHtx2aEEMCO4f1Upu-l27BPzd3-5pV-u8wPc
193
193
  flwr/proto/transport_pb2_grpc.pyi,sha256=AGXf8RiIiW2J5IKMlm_3qT3AzcDa4F3P5IqUjve_esA,766
194
194
  flwr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
195
195
  flwr/server/__init__.py,sha256=cEg1oecBu4cKB69iJCqWEylC8b5XW47bl7rQiJsdTvM,1528
196
- flwr/server/app.py,sha256=ecE7Q4gDKIiRyv6818IEPr2HlcWRzx3UMDODCwz66MY,24408
196
+ flwr/server/app.py,sha256=QFnqrN1aeNTN-hmHt2YcqZNncAq89Qr2mlZtwITRIc4,24430
197
197
  flwr/server/client_manager.py,sha256=T8UDSRJBVD3fyIDI7NTAA-NA7GPrMNNgH2OAF54RRxE,6127
198
198
  flwr/server/client_proxy.py,sha256=4G-oTwhb45sfWLx2uZdcXD98IZwdTS6F88xe3akCdUg,2399
199
199
  flwr/server/compat/__init__.py,sha256=VxnJtJyOjNFQXMNi9hIuzNlZM5n0Hj1p3aq_Pm2udw4,892
@@ -204,10 +204,10 @@ flwr/server/compat/legacy_context.py,sha256=wBzBcfV6YO6IQGriM_FdJ5XZfiBBEEJdS_Od
204
204
  flwr/server/criterion.py,sha256=ypbAexbztzGUxNen9RCHF91QeqiEQix4t4Ih3E-42MM,1061
205
205
  flwr/server/driver/__init__.py,sha256=bikRv6CjTwSvYh7tf10gziU5o2YotOWhhftz2tr3KDc,886
206
206
  flwr/server/driver/driver.py,sha256=NT_yaeit7_kZEIsCEqOWPID1GrVD3ywH4xZ2wtIh5lM,5217
207
- flwr/server/driver/grpc_driver.py,sha256=QMVf5KrnIWVuqeYoSO31o698utJlbLAm6s9VAAxFZLA,9660
207
+ flwr/server/driver/grpc_driver.py,sha256=qrCF0hi2AlKF_8R5N_W5aKoAxd80lN1xbdLTUVtpSO0,9648
208
208
  flwr/server/driver/inmemory_driver.py,sha256=RcK94_NtjGZ4aZDIscnU7A3Uv1u8jGx29-xcbjQvZTM,6444
209
209
  flwr/server/history.py,sha256=bBOHKyX1eQONIsUx4EUU-UnAk1i0EbEl8ioyMq_UWQ8,5063
210
- flwr/server/run_serverapp.py,sha256=ASpwKHNlxpDfBe6UPotxkaifXZyKS9ZIrdwtTGLCt3k,10534
210
+ flwr/server/run_serverapp.py,sha256=Xw42zqNXmKGy3Fz5QjYOUS1MH7ULy2u9nad4QA8hh74,10479
211
211
  flwr/server/server.py,sha256=PsJeh7ROKMoeLpIVrmbKoQUvdz-iqb54E4HZJanRUmM,17912
212
212
  flwr/server/server_app.py,sha256=1hul76ospG8L_KooK_ewn1sWPNTNYLTtZMeGNOBNruA,6267
213
213
  flwr/server/server_config.py,sha256=CZaHVAsMvGLjpWVcLPkiYxgJN4xfIyAiUrCI3fETKY4,1349
@@ -254,7 +254,7 @@ flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py,sha256=h3EhqgelegVC4E
254
254
  flwr/server/superlink/fleet/grpc_bidi/grpc_server.py,sha256=DIXCYfPwm5paWq6hccReW0tB7-dTfq4vvMZ7CsiuYf4,12292
255
255
  flwr/server/superlink/fleet/grpc_rere/__init__.py,sha256=j2hyC342am-_Hgp1g80Y3fGDzfTI6n8QOOn2PyWf4eg,758
256
256
  flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py,sha256=bgoLQEhahVHjdlRDk_58zyKFeMOziiPUXSbYMhOxybY,4757
257
- flwr/server/superlink/fleet/grpc_rere/server_interceptor.py,sha256=zN8TIdg9ZxKtmrwtarWUPdm08jUBBGoz59ndO3C-7jg,7985
257
+ flwr/server/superlink/fleet/grpc_rere/server_interceptor.py,sha256=paUSrLADNsMdN0anHdbEeGDvI_SMWjAkFSiP3SA-hx8,7933
258
258
  flwr/server/superlink/fleet/message_handler/__init__.py,sha256=h8oLD7uo5lKICPy0rRdKRjTYe62u8PKkT_fA4xF5JPA,731
259
259
  flwr/server/superlink/fleet/message_handler/message_handler.py,sha256=9qDDPwj3txHPo2dNaWQiO3UpGno5Zm9IMhJXnAPZbqg,4439
260
260
  flwr/server/superlink/fleet/rest_rere/__init__.py,sha256=5jbYbAn75sGv-gBwOPDySE0kz96F6dTYLeMrGqNi4lM,735
@@ -262,7 +262,7 @@ flwr/server/superlink/fleet/rest_rere/rest_api.py,sha256=3wegOVJadA3pH_2CwZHQ3Uw
262
262
  flwr/server/superlink/fleet/vce/__init__.py,sha256=36MHKiefnJeyjwMQzVUK4m06Ojon3WDcwZGQsAcyVhQ,783
263
263
  flwr/server/superlink/fleet/vce/backend/__init__.py,sha256=psQjI1DQHOM5uWVXM27l_wPHjfEkMUTP-_8-lEFH1JA,1466
264
264
  flwr/server/superlink/fleet/vce/backend/backend.py,sha256=YugFH_XYclqmq07er5ne1DZc7PgR9lWGs5LY_YIHwc8,2207
265
- flwr/server/superlink/fleet/vce/backend/raybackend.py,sha256=VQ63rZytcavfDedfjArAejPi3VGYXrfcsb8yi57prRc,7168
265
+ flwr/server/superlink/fleet/vce/backend/raybackend.py,sha256=GkeaSe7uXg2iIgKiZNTCwM3TAwYEzuJnr9mA8-vg4hM,6793
266
266
  flwr/server/superlink/fleet/vce/vce_api.py,sha256=lTQ2WycKK4-w22EPoJJz1qn73j9ZTwBlNz2cla2Zv0Q,12653
267
267
  flwr/server/superlink/state/__init__.py,sha256=Gj2OTFLXvA-mAjBvwuKDM3rDrVaQPcIoybSa2uskMTE,1003
268
268
  flwr/server/superlink/state/in_memory_state.py,sha256=eNXOVt3HhJOYxkbYRNWEudCaNrYj2B7tOU9xgKbM2Ag,13166
@@ -283,19 +283,19 @@ flwr/server/workflow/secure_aggregation/secaggplus_workflow.py,sha256=vdS_AeRYBv
283
283
  flwr/simulation/__init__.py,sha256=ybVBW3xT6cg_IasJV4_ymI3bVrCbFhw1mmcfrdfl3q0,1359
284
284
  flwr/simulation/app.py,sha256=te3dQB3eodPwzsv1y4daPyaskIAaOtgoHaQLobrqoqY,15163
285
285
  flwr/simulation/ray_transport/__init__.py,sha256=wzcEEwUUlulnXsg6raCA1nGpP3LlAQDtJ8zNkCXcVbA,734
286
- flwr/simulation/ray_transport/ray_actor.py,sha256=IbFwbRFxKHoLjgx_LTuehS0L3uHPw_SPaMfA4wHA0Xk,19026
286
+ flwr/simulation/ray_transport/ray_actor.py,sha256=3j0HgzjrlYjnzdTRy8aA4Nf6VoUvxi1hGRQkGSU5z6c,19020
287
287
  flwr/simulation/ray_transport/ray_client_proxy.py,sha256=0abIsU0VBk9rNJZOKHIyzYGy3ZnWBgqYocX_oct1EP0,7307
288
288
  flwr/simulation/ray_transport/utils.py,sha256=TYdtfg1P9VfTdLMOJlifInGpxWHYs9UfUqIv2wfkRLA,2392
289
- flwr/simulation/run_simulation.py,sha256=hnH3qThfg_ii2tMu1y3X4ZWbw99CNk7vfduQ1fdZxbY,22750
289
+ flwr/simulation/run_simulation.py,sha256=TjkgoSh_FGiFmyJ9g45S-uh4nh16scm4GDo-5J8k2gI,22279
290
290
  flwr/superexec/__init__.py,sha256=fcj366jh4RFby_vDwLroU4kepzqbnJgseZD_jUr_Mko,715
291
- flwr/superexec/app.py,sha256=58EbFCFhFLzMrkxDZwZ8_nEitd6ckQc1v_5H9s4nxlM,6559
292
- flwr/superexec/deployment.py,sha256=sNb-sYdCDkVEALSbC_eBNIulieHwpg7HzgmDIp4wT9o,6267
291
+ flwr/superexec/app.py,sha256=gH25dr7FL9IWODSOtP0-r59iuOKDeSXLLPxpEAL50BM,6561
292
+ flwr/superexec/deployment.py,sha256=1qhztkcZDjaSbicligbXGqn49gbpN271rTlEVAnNuWw,6283
293
293
  flwr/superexec/exec_grpc.py,sha256=PhqGoZEpTMxSQmUSV8Wgtzb1Za_pHJ-adZqo5RYnDyE,1942
294
294
  flwr/superexec/exec_servicer.py,sha256=jl0aKVjm0PLQABcTL5c3jdSIzb0Z6hpVOtrAn4Ob7ts,2323
295
295
  flwr/superexec/executor.py,sha256=k_adivto6R2U82DADOHNvdtobehBYreRek1gOEBIQnQ,2318
296
296
  flwr/superexec/simulation.py,sha256=J6pw-RqCSiUed8I_3MasZH4tl57ZmDebPAHNnbb0-vE,7420
297
- flwr_nightly-1.11.1.dev20240912.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
298
- flwr_nightly-1.11.1.dev20240912.dist-info/METADATA,sha256=d7S_JhUvUHkUP-WXBYMhrwM0P0KEvftKDl68QuQk-iU,15703
299
- flwr_nightly-1.11.1.dev20240912.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
300
- flwr_nightly-1.11.1.dev20240912.dist-info/entry_points.txt,sha256=WUCbqhLEOzjx_lyATIM0-f0e8kOVaQjzwOvyOxHrMhs,434
301
- flwr_nightly-1.11.1.dev20240912.dist-info/RECORD,,
297
+ flwr_nightly-1.12.0.dev20240907.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
298
+ flwr_nightly-1.12.0.dev20240907.dist-info/METADATA,sha256=Wl469AtkL3tGYcWA_ghsNh6KCRT-JSMpmAqIMouVOcA,15703
299
+ flwr_nightly-1.12.0.dev20240907.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
300
+ flwr_nightly-1.12.0.dev20240907.dist-info/entry_points.txt,sha256=WUCbqhLEOzjx_lyATIM0-f0e8kOVaQjzwOvyOxHrMhs,434
301
+ flwr_nightly-1.12.0.dev20240907.dist-info/RECORD,,