flwr-nightly 1.14.0.dev20241210__py3-none-any.whl → 1.14.0.dev20241212__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 (36) hide show
  1. flwr/cli/app.py +2 -0
  2. flwr/cli/cli_user_auth_interceptor.py +86 -0
  3. flwr/cli/config_utils.py +18 -2
  4. flwr/cli/log.py +10 -31
  5. flwr/cli/login/__init__.py +21 -0
  6. flwr/cli/login/login.py +82 -0
  7. flwr/cli/ls.py +10 -40
  8. flwr/cli/new/new.py +1 -1
  9. flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +1 -2
  10. flwr/cli/run/run.py +14 -25
  11. flwr/cli/stop.py +9 -39
  12. flwr/cli/utils.py +108 -1
  13. flwr/client/mod/localdp_mod.py +1 -1
  14. flwr/common/config.py +2 -1
  15. flwr/common/constant.py +4 -1
  16. flwr/common/object_ref.py +57 -54
  17. flwr/common/retry_invoker.py +75 -0
  18. flwr/common/secure_aggregation/secaggplus_utils.py +2 -2
  19. flwr/common/telemetry.py +2 -1
  20. flwr/common/typing.py +4 -0
  21. flwr/proto/fab_pb2.py +4 -4
  22. flwr/proto/fab_pb2.pyi +4 -1
  23. flwr/proto/serverappio_pb2.py +18 -18
  24. flwr/proto/serverappio_pb2.pyi +8 -2
  25. flwr/proto/serverappio_pb2_grpc.py +34 -0
  26. flwr/proto/serverappio_pb2_grpc.pyi +13 -0
  27. flwr/server/compat/app_utils.py +7 -1
  28. flwr/server/driver/grpc_driver.py +10 -63
  29. flwr/server/serverapp/app.py +8 -2
  30. flwr/server/superlink/driver/serverappio_servicer.py +68 -6
  31. flwr/server/superlink/utils.py +65 -0
  32. {flwr_nightly-1.14.0.dev20241210.dist-info → flwr_nightly-1.14.0.dev20241212.dist-info}/METADATA +6 -6
  33. {flwr_nightly-1.14.0.dev20241210.dist-info → flwr_nightly-1.14.0.dev20241212.dist-info}/RECORD +36 -32
  34. {flwr_nightly-1.14.0.dev20241210.dist-info → flwr_nightly-1.14.0.dev20241212.dist-info}/LICENSE +0 -0
  35. {flwr_nightly-1.14.0.dev20241210.dist-info → flwr_nightly-1.14.0.dev20241212.dist-info}/WHEEL +0 -0
  36. {flwr_nightly-1.14.0.dev20241210.dist-info → flwr_nightly-1.14.0.dev20241212.dist-info}/entry_points.txt +0 -0
@@ -56,6 +56,11 @@ class ServerAppIoStub:
56
56
  flwr.proto.run_pb2.UpdateRunStatusResponse]
57
57
  """Update the status of a given run"""
58
58
 
59
+ GetRunStatus: grpc.UnaryUnaryMultiCallable[
60
+ flwr.proto.run_pb2.GetRunStatusRequest,
61
+ flwr.proto.run_pb2.GetRunStatusResponse]
62
+ """Get the status of a given run"""
63
+
59
64
  PushLogs: grpc.UnaryUnaryMultiCallable[
60
65
  flwr.proto.log_pb2.PushLogsRequest,
61
66
  flwr.proto.log_pb2.PushLogsResponse]
@@ -135,6 +140,14 @@ class ServerAppIoServicer(metaclass=abc.ABCMeta):
135
140
  """Update the status of a given run"""
136
141
  pass
137
142
 
143
+ @abc.abstractmethod
144
+ def GetRunStatus(self,
145
+ request: flwr.proto.run_pb2.GetRunStatusRequest,
146
+ context: grpc.ServicerContext,
147
+ ) -> flwr.proto.run_pb2.GetRunStatusResponse:
148
+ """Get the status of a given run"""
149
+ pass
150
+
138
151
  @abc.abstractmethod
139
152
  def PushLogs(self,
140
153
  request: flwr.proto.log_pb2.PushLogsRequest,
@@ -17,6 +17,8 @@
17
17
 
18
18
  import threading
19
19
 
20
+ from flwr.common.typing import RunNotRunningException
21
+
20
22
  from ..client_manager import ClientManager
21
23
  from ..compat.driver_client_proxy import DriverClientProxy
22
24
  from ..driver import Driver
@@ -74,7 +76,11 @@ def _update_client_manager(
74
76
  # Loop until the driver is disconnected
75
77
  registered_nodes: dict[int, DriverClientProxy] = {}
76
78
  while not f_stop.is_set():
77
- all_node_ids = set(driver.get_node_ids())
79
+ try:
80
+ all_node_ids = set(driver.get_node_ids())
81
+ except RunNotRunningException:
82
+ f_stop.set()
83
+ break
78
84
  dead_nodes = set(registered_nodes).difference(all_node_ids)
79
85
  new_nodes = all_node_ids.difference(registered_nodes)
80
86
 
@@ -17,16 +17,16 @@
17
17
  import time
18
18
  import warnings
19
19
  from collections.abc import Iterable
20
- from logging import DEBUG, INFO, WARN, WARNING
21
- from typing import Any, Optional, cast
20
+ from logging import DEBUG, WARNING
21
+ from typing import Optional, cast
22
22
 
23
23
  import grpc
24
24
 
25
25
  from flwr.common import DEFAULT_TTL, Message, Metadata, RecordSet
26
- from flwr.common.constant import MAX_RETRY_DELAY, SERVERAPPIO_API_DEFAULT_CLIENT_ADDRESS
26
+ from flwr.common.constant import SERVERAPPIO_API_DEFAULT_CLIENT_ADDRESS
27
27
  from flwr.common.grpc import create_channel
28
28
  from flwr.common.logger import log
29
- from flwr.common.retry_invoker import RetryInvoker, RetryState, exponential
29
+ from flwr.common.retry_invoker import _make_simple_grpc_retry_invoker, _wrap_stub
30
30
  from flwr.common.serde import message_from_taskres, message_to_taskins, run_from_proto
31
31
  from flwr.common.typing import Run
32
32
  from flwr.proto.node_pb2 import Node # pylint: disable=E0611
@@ -203,7 +203,9 @@ class GrpcDriver(Driver):
203
203
  task_ins_list.append(taskins)
204
204
  # Call GrpcDriverStub method
205
205
  res: PushTaskInsResponse = self._stub.PushTaskIns(
206
- PushTaskInsRequest(task_ins_list=task_ins_list)
206
+ PushTaskInsRequest(
207
+ task_ins_list=task_ins_list, run_id=cast(Run, self._run).run_id
208
+ )
207
209
  )
208
210
  return list(res.task_ids)
209
211
 
@@ -215,7 +217,9 @@ class GrpcDriver(Driver):
215
217
  """
216
218
  # Pull TaskRes
217
219
  res: PullTaskResResponse = self._stub.PullTaskRes(
218
- PullTaskResRequest(node=self.node, task_ids=message_ids)
220
+ PullTaskResRequest(
221
+ node=self.node, task_ids=message_ids, run_id=cast(Run, self._run).run_id
222
+ )
219
223
  )
220
224
  # Convert TaskRes to Message
221
225
  msgs = [message_from_taskres(taskres) for taskres in res.task_res_list]
@@ -258,60 +262,3 @@ class GrpcDriver(Driver):
258
262
  return
259
263
  # Disconnect
260
264
  self._disconnect()
261
-
262
-
263
- def _make_simple_grpc_retry_invoker() -> RetryInvoker:
264
- """Create a simple gRPC retry invoker."""
265
-
266
- def _on_sucess(retry_state: RetryState) -> None:
267
- if retry_state.tries > 1:
268
- log(
269
- INFO,
270
- "Connection successful after %.2f seconds and %s tries.",
271
- retry_state.elapsed_time,
272
- retry_state.tries,
273
- )
274
-
275
- def _on_backoff(retry_state: RetryState) -> None:
276
- if retry_state.tries == 1:
277
- log(WARN, "Connection attempt failed, retrying...")
278
- else:
279
- log(
280
- WARN,
281
- "Connection attempt failed, retrying in %.2f seconds",
282
- retry_state.actual_wait,
283
- )
284
-
285
- def _on_giveup(retry_state: RetryState) -> None:
286
- if retry_state.tries > 1:
287
- log(
288
- WARN,
289
- "Giving up reconnection after %.2f seconds and %s tries.",
290
- retry_state.elapsed_time,
291
- retry_state.tries,
292
- )
293
-
294
- return RetryInvoker(
295
- wait_gen_factory=lambda: exponential(max_delay=MAX_RETRY_DELAY),
296
- recoverable_exceptions=grpc.RpcError,
297
- max_tries=None,
298
- max_time=None,
299
- on_success=_on_sucess,
300
- on_backoff=_on_backoff,
301
- on_giveup=_on_giveup,
302
- should_giveup=lambda e: e.code() != grpc.StatusCode.UNAVAILABLE, # type: ignore
303
- )
304
-
305
-
306
- def _wrap_stub(stub: ServerAppIoStub, retry_invoker: RetryInvoker) -> None:
307
- """Wrap the gRPC stub with a retry invoker."""
308
-
309
- def make_lambda(original_method: Any) -> Any:
310
- return lambda *args, **kwargs: retry_invoker.invoke(
311
- original_method, *args, **kwargs
312
- )
313
-
314
- for method_name in vars(stub):
315
- method = getattr(stub, method_name)
316
- if callable(method):
317
- setattr(stub, method_name, make_lambda(method))
@@ -50,7 +50,7 @@ from flwr.common.serde import (
50
50
  run_from_proto,
51
51
  run_status_to_proto,
52
52
  )
53
- from flwr.common.typing import RunStatus
53
+ from flwr.common.typing import RunNotRunningException, RunStatus
54
54
  from flwr.proto.run_pb2 import UpdateRunStatusRequest # pylint: disable=E0611
55
55
  from flwr.proto.serverappio_pb2 import ( # pylint: disable=E0611
56
56
  PullServerAppInputsRequest,
@@ -96,7 +96,7 @@ def flwr_serverapp() -> None:
96
96
  restore_output()
97
97
 
98
98
 
99
- def run_serverapp( # pylint: disable=R0914, disable=W0212
99
+ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915
100
100
  serverappio_api_address: str,
101
101
  log_queue: Queue[Optional[str]],
102
102
  run_once: bool,
@@ -187,6 +187,12 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212
187
187
 
188
188
  run_status = RunStatus(Status.FINISHED, SubStatus.COMPLETED, "")
189
189
 
190
+ except RunNotRunningException:
191
+ log(INFO, "")
192
+ log(INFO, "Run ID %s stopped.", run.run_id)
193
+ log(INFO, "")
194
+ run_status = None
195
+
190
196
  except Exception as ex: # pylint: disable=broad-exception-caught
191
197
  exc_entity = "ServerApp"
192
198
  log(ERROR, "%s raised an exception", exc_entity, exc_info=ex)
@@ -32,6 +32,7 @@ from flwr.common.serde import (
32
32
  fab_from_proto,
33
33
  fab_to_proto,
34
34
  run_status_from_proto,
35
+ run_status_to_proto,
35
36
  run_to_proto,
36
37
  user_config_from_proto,
37
38
  )
@@ -48,6 +49,8 @@ from flwr.proto.run_pb2 import ( # pylint: disable=E0611
48
49
  CreateRunResponse,
49
50
  GetRunRequest,
50
51
  GetRunResponse,
52
+ GetRunStatusRequest,
53
+ GetRunStatusResponse,
51
54
  UpdateRunStatusRequest,
52
55
  UpdateRunStatusResponse,
53
56
  )
@@ -67,6 +70,7 @@ from flwr.proto.task_pb2 import TaskRes # pylint: disable=E0611
67
70
  from flwr.server.superlink.ffs.ffs import Ffs
68
71
  from flwr.server.superlink.ffs.ffs_factory import FfsFactory
69
72
  from flwr.server.superlink.linkstate import LinkState, LinkStateFactory
73
+ from flwr.server.superlink.utils import abort_if
70
74
  from flwr.server.utils.validator import validate_task_ins_or_res
71
75
 
72
76
 
@@ -85,7 +89,18 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
85
89
  ) -> GetNodesResponse:
86
90
  """Get available nodes."""
87
91
  log(DEBUG, "ServerAppIoServicer.GetNodes")
92
+
93
+ # Init state
88
94
  state: LinkState = self.state_factory.state()
95
+
96
+ # Abort if the run is not running
97
+ abort_if(
98
+ request.run_id,
99
+ [Status.PENDING, Status.STARTING, Status.FINISHED],
100
+ state,
101
+ context,
102
+ )
103
+
89
104
  all_ids: set[int] = state.get_nodes(request.run_id)
90
105
  nodes: list[Node] = [
91
106
  Node(node_id=node_id, anonymous=False) for node_id in all_ids
@@ -123,6 +138,17 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
123
138
  """Push a set of TaskIns."""
124
139
  log(DEBUG, "ServerAppIoServicer.PushTaskIns")
125
140
 
141
+ # Init state
142
+ state: LinkState = self.state_factory.state()
143
+
144
+ # Abort if the run is not running
145
+ abort_if(
146
+ request.run_id,
147
+ [Status.PENDING, Status.STARTING, Status.FINISHED],
148
+ state,
149
+ context,
150
+ )
151
+
126
152
  # Set pushed_at (timestamp in seconds)
127
153
  pushed_at = time.time()
128
154
  for task_ins in request.task_ins_list:
@@ -134,9 +160,6 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
134
160
  validation_errors = validate_task_ins_or_res(task_ins)
135
161
  _raise_if(bool(validation_errors), ", ".join(validation_errors))
136
162
 
137
- # Init state
138
- state: LinkState = self.state_factory.state()
139
-
140
163
  # Store each TaskIns
141
164
  task_ids: list[Optional[UUID]] = []
142
165
  for task_ins in request.task_ins_list:
@@ -153,12 +176,20 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
153
176
  """Pull a set of TaskRes."""
154
177
  log(DEBUG, "ServerAppIoServicer.PullTaskRes")
155
178
 
156
- # Convert each task_id str to UUID
157
- task_ids: set[UUID] = {UUID(task_id) for task_id in request.task_ids}
158
-
159
179
  # Init state
160
180
  state: LinkState = self.state_factory.state()
161
181
 
182
+ # Abort if the run is not running
183
+ abort_if(
184
+ request.run_id,
185
+ [Status.PENDING, Status.STARTING, Status.FINISHED],
186
+ state,
187
+ context,
188
+ )
189
+
190
+ # Convert each task_id str to UUID
191
+ task_ids: set[UUID] = {UUID(task_id) for task_id in request.task_ids}
192
+
162
193
  # Register callback
163
194
  def on_rpc_done() -> None:
164
195
  log(
@@ -255,7 +286,18 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
255
286
  ) -> PushServerAppOutputsResponse:
256
287
  """Push ServerApp process outputs."""
257
288
  log(DEBUG, "ServerAppIoServicer.PushServerAppOutputs")
289
+
290
+ # Init state
258
291
  state = self.state_factory.state()
292
+
293
+ # Abort if the run is not running
294
+ abort_if(
295
+ request.run_id,
296
+ [Status.PENDING, Status.STARTING, Status.FINISHED],
297
+ state,
298
+ context,
299
+ )
300
+
259
301
  state.set_serverapp_context(request.run_id, context_from_proto(request.context))
260
302
  return PushServerAppOutputsResponse()
261
303
 
@@ -264,8 +306,13 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
264
306
  ) -> UpdateRunStatusResponse:
265
307
  """Update the status of a run."""
266
308
  log(DEBUG, "ServerAppIoServicer.UpdateRunStatus")
309
+
310
+ # Init state
267
311
  state = self.state_factory.state()
268
312
 
313
+ # Abort if the run is finished
314
+ abort_if(request.run_id, [Status.FINISHED], state, context)
315
+
269
316
  # Update the run status
270
317
  state.update_run_status(
271
318
  run_id=request.run_id, new_status=run_status_from_proto(request.run_status)
@@ -284,6 +331,21 @@ class ServerAppIoServicer(serverappio_pb2_grpc.ServerAppIoServicer):
284
331
  state.add_serverapp_log(request.run_id, merged_logs)
285
332
  return PushLogsResponse()
286
333
 
334
+ def GetRunStatus(
335
+ self, request: GetRunStatusRequest, context: grpc.ServicerContext
336
+ ) -> GetRunStatusResponse:
337
+ """Get the status of a run."""
338
+ log(DEBUG, "ServerAppIoServicer.GetRunStatus")
339
+ state = self.state_factory.state()
340
+
341
+ # Get run status from LinkState
342
+ run_statuses = state.get_run_status(set(request.run_ids))
343
+ run_status_dict = {
344
+ run_id: run_status_to_proto(run_status)
345
+ for run_id, run_status in run_statuses.items()
346
+ }
347
+ return GetRunStatusResponse(run_status_dict=run_status_dict)
348
+
287
349
 
288
350
  def _raise_if(validation_error: bool, detail: str) -> None:
289
351
  if validation_error:
@@ -0,0 +1,65 @@
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
+ """SuperLink utilities."""
16
+
17
+
18
+ from typing import Union
19
+
20
+ import grpc
21
+
22
+ from flwr.common.constant import Status, SubStatus
23
+ from flwr.common.typing import RunStatus
24
+ from flwr.server.superlink.linkstate import LinkState
25
+
26
+ _STATUS_TO_MSG = {
27
+ Status.PENDING: "Run is pending.",
28
+ Status.STARTING: "Run is starting.",
29
+ Status.RUNNING: "Run is running.",
30
+ Status.FINISHED: "Run is finished.",
31
+ }
32
+
33
+
34
+ def check_abort(
35
+ run_id: int,
36
+ abort_status_list: list[str],
37
+ state: LinkState,
38
+ ) -> Union[str, None]:
39
+ """Check if the status of the provided `run_id` is in `abort_status_list`."""
40
+ run_status: RunStatus = state.get_run_status({run_id})[run_id]
41
+
42
+ if run_status.status in abort_status_list:
43
+ msg = _STATUS_TO_MSG[run_status.status]
44
+ if run_status.sub_status == SubStatus.STOPPED:
45
+ msg += " Stopped by user."
46
+ return msg
47
+
48
+ return None
49
+
50
+
51
+ def abort_grpc_context(msg: Union[str, None], context: grpc.ServicerContext) -> None:
52
+ """Abort context with statuscode PERMISSION_DENIED if `msg` is not None."""
53
+ if msg is not None:
54
+ context.abort(grpc.StatusCode.PERMISSION_DENIED, msg)
55
+
56
+
57
+ def abort_if(
58
+ run_id: int,
59
+ abort_status_list: list[str],
60
+ state: LinkState,
61
+ context: grpc.ServicerContext,
62
+ ) -> None:
63
+ """Abort context if status of the provided `run_id` is in `abort_status_list`."""
64
+ msg = check_abort(run_id, abort_status_list, state)
65
+ abort_grpc_context(msg, context)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flwr-nightly
3
- Version: 1.14.0.dev20241210
3
+ Version: 1.14.0.dev20241212
4
4
  Summary: Flower: A Friendly Federated AI Framework
5
5
  Home-page: https://flower.ai
6
6
  License: Apache-2.0
@@ -102,23 +102,23 @@ Flower's goal is to make federated learning accessible to everyone. This series
102
102
 
103
103
  0. **What is Federated Learning?**
104
104
 
105
- [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/adap/flower/blob/main/doc/source/tutorial-series-what-is-federated-learning.ipynb) (or open the [Jupyter Notebook](https://github.com/adap/flower/blob/main/doc/source/tutorial-series-what-is-federated-learning.ipynb))
105
+ [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/adap/flower/blob/main/framework/docs/source/tutorial-series-what-is-federated-learning.ipynb) (or open the [Jupyter Notebook](https://github.com/adap/flower/blob/main/framework/docs/source/tutorial-series-what-is-federated-learning.ipynb))
106
106
 
107
107
  1. **An Introduction to Federated Learning**
108
108
 
109
- [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/adap/flower/blob/main/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb) (or open the [Jupyter Notebook](https://github.com/adap/flower/blob/main/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb))
109
+ [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/adap/flower/blob/main/framework/docs/source/tutorial-series-get-started-with-flower-pytorch.ipynb) (or open the [Jupyter Notebook](https://github.com/adap/flower/blob/main/framework/docs/source/tutorial-series-get-started-with-flower-pytorch.ipynb))
110
110
 
111
111
  2. **Using Strategies in Federated Learning**
112
112
 
113
- [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/adap/flower/blob/main/doc/source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb) (or open the [Jupyter Notebook](https://github.com/adap/flower/blob/main/doc/source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb))
113
+ [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/adap/flower/blob/main/framework/docs/source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb) (or open the [Jupyter Notebook](https://github.com/adap/flower/blob/main/framework/docs/source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb))
114
114
 
115
115
  3. **Building Strategies for Federated Learning**
116
116
 
117
- [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/adap/flower/blob/main/doc/source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb) (or open the [Jupyter Notebook](https://github.com/adap/flower/blob/main/doc/source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb))
117
+ [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/adap/flower/blob/main/framework/docs/source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb) (or open the [Jupyter Notebook](https://github.com/adap/flower/blob/main/framework/docs/source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb))
118
118
 
119
119
  4. **Custom Clients for Federated Learning**
120
120
 
121
- [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/adap/flower/blob/main/doc/source/tutorial-series-customize-the-client-pytorch.ipynb) (or open the [Jupyter Notebook](https://github.com/adap/flower/blob/main/doc/source/tutorial-series-customize-the-client-pytorch.ipynb))
121
+ [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/adap/flower/blob/main/doc/source/tutorial-series-customize-the-client-pytorch.ipynb) (or open the [Jupyter Notebook](https://github.com/adap/flower/blob/main/framework/docs/source/tutorial-series-customize-the-client-pytorch.ipynb))
122
122
 
123
123
  Stay tuned, more tutorials are coming soon. Topics include **Privacy and Security in Federated Learning**, and **Scaling Federated Learning**.
124
124
 
@@ -1,14 +1,17 @@
1
1
  flwr/__init__.py,sha256=VmBWedrCxqmt4QvUHBLqyVEH6p7zaFMD_oCHerXHSVw,937
2
2
  flwr/cli/__init__.py,sha256=cZJVgozlkC6Ni2Hd_FAIrqefrkCGOV18fikToq-6iLw,720
3
- flwr/cli/app.py,sha256=4naV5q1Fepne8XAgdGISxotWSIT__sm0TIHdodSvou4,1335
3
+ flwr/cli/app.py,sha256=KF__zHSy7KQCMx_Rb0YPzcoZbQY-Zo4f70BhBgP4ENM,1381
4
4
  flwr/cli/build.py,sha256=k2M0aIY2q5WB_yXQ22Woxt1zb6m-Z1wNwmhWMxEm5Dw,6344
5
- flwr/cli/config_utils.py,sha256=n-xNkQG_0POz5UUHyE00lthNaOjuS6IYU9Thzb_BThs,11431
5
+ flwr/cli/cli_user_auth_interceptor.py,sha256=rEjgAZmzHO0GjwdyZib6bkTI2X59ErJAZlutqpqZGF0,2952
6
+ flwr/cli/config_utils.py,sha256=f4ViGujhEat9l3YDq24AE-hao4pAK_hVLRXZXDd_F_A,12078
6
7
  flwr/cli/example.py,sha256=1bGDYll3BXQY2kRqSN-oICqS5n1b9m0g0RvXTopXHl4,2215
7
8
  flwr/cli/install.py,sha256=kmD2dW-9B7645GAQx5es1o2W11gRHQ2Fg2E31SLomrg,8179
8
- flwr/cli/log.py,sha256=WlAuxZdTUYZ5bRKkm0jLWrOxHTS0TlSA5BeDtO9xF3k,6659
9
- flwr/cli/ls.py,sha256=aUaP49kkg4nV2nRYfO8qgbtV_FF5xN5gCy3ziD2HbUk,11513
9
+ flwr/cli/log.py,sha256=7V5NPGiR8FMDkkNTc5SE1pxMskQgp0H5HniG977LISo,5994
10
+ flwr/cli/login/__init__.py,sha256=PEh6QjLSx7ltN8d8Jfi25dHFPKtCNKjYJZCkYQBfmm0,799
11
+ flwr/cli/login/login.py,sha256=GVm6rkLDVQ6WuT2mw52gBKNW_Y5IjGg_OOGoEmpx9KM,2796
12
+ flwr/cli/ls.py,sha256=5uO0YG0XXn7paS4oUs1T7rwicApxMV3ac9ejBZfLN3k,10545
10
13
  flwr/cli/new/__init__.py,sha256=cQzK1WH4JP2awef1t2UQ2xjl1agVEz9rwutV18SWV1k,789
11
- flwr/cli/new/new.py,sha256=xgzObnhNpnGvjVs6wTj6BlJ9X-avPhRX3DuwWnk9ED0,9903
14
+ flwr/cli/new/new.py,sha256=AoGfQl_IPN6LwZBYPgRAMgME5BODsL3n1OtErSEVVkc,9921
12
15
  flwr/cli/new/templates/__init__.py,sha256=4luU8RL-CK8JJCstQ_ON809W9bNTkY1l9zSaPKBkgwY,725
13
16
  flwr/cli/new/templates/app/.gitignore.tpl,sha256=XixnHdyeMB2vwkGtGnwHqoWpH-9WChdyG0GXe57duhc,3078
14
17
  flwr/cli/new/templates/app/LICENSE.tpl,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
@@ -56,15 +59,15 @@ flwr/cli/new/templates/app/pyproject.baseline.toml.tpl,sha256=_bT_ze1QPajyFZW0Ax
56
59
  flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=WHLdFbHhfs3ZmLCG5pa5TUKFoRV67TT1J1SXMM0zStY,1873
57
60
  flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl,sha256=_LSCSc9cAiRuvTLdsy9wphwzhV7FCOUxO1ce12YOk58,1143
58
61
  flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=8xC1457V13AxTsO7SaLsqhQQPN7Aau3wbNZqKJ9Inx8,673
59
- flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=834E6VDgomPGTNRUHjfi3wWaJpwE0xaL_qPgEZbqEJc,765
62
+ flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=sJMPYaroZLM7EkIX5ulnCelKxHlpViYiSqhswEnGrB0,744
60
63
  flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=SbCIUjwCIsgTRoBb-GMwivcWdoigMvD3QbKL6TJNgWM,612
61
64
  flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=UtH3Vslg2S8fIKIHC-dJGcxz5YUK2WI3F2TUAgTsQn0,710
62
65
  flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=01HArBqRrbZT3O7pXOM9MqduXMNm525wv7Sj6dvYMJE,686
63
66
  flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=KVCIOEYNWnq6j7XOboXqZshc9aQ2PyRDUu7bZtmfJ24,710
64
67
  flwr/cli/run/__init__.py,sha256=oCd6HmQDx-sqver1gecgx-uMA38BLTSiiKpl7RGNceg,789
65
- flwr/cli/run/run.py,sha256=5To92BOrfM5VEwNp2zzRUoz4tHE2NtazxIQICProA8k,8503
66
- flwr/cli/stop.py,sha256=OrV_znXyu3t_gABHisAA6uHwFdFPP2Z9bKvhcE1O5Yk,4116
67
- flwr/cli/utils.py,sha256=emMUdthvoHBTB0iGQp-oFBmA5wV46lw3y3FmfXQPCsc,4500
68
+ flwr/cli/run/run.py,sha256=sklMcREZnnuot4TSeCIpVYqZJ2Ar2SOye3q0lw5s218,8139
69
+ flwr/cli/stop.py,sha256=pa3etMLCLxfGl9w2c2o6e5u46j6LimEmNp2zuQGxAIk,3143
70
+ flwr/cli/utils.py,sha256=hiT4-tDPmS5U_mH0ED9DVTElfmfYUMV6JuPWZjTaIgQ,8330
68
71
  flwr/client/__init__.py,sha256=DGDoO0AEAfz-0CUFmLdyUUweAS64-07AOnmDfWUefK4,1192
69
72
  flwr/client/app.py,sha256=3AKrJduvki_1ATvKCQV4T9_1qZuarVVTtpnsq6_cWw0,34384
70
73
  flwr/client/client.py,sha256=gy6WVlMUFAp8oevN4xpQPX30vPOIYGVqdbuFlTWkyG4,9080
@@ -89,7 +92,7 @@ flwr/client/message_handler/task_handler.py,sha256=ZDJBKmrn2grRMNl1rU1iGs7FiMHL5
89
92
  flwr/client/mod/__init__.py,sha256=37XeXZLFq_tzFVKVtC9JaigM2bSAU7BrGQvMPCE3Q28,1159
90
93
  flwr/client/mod/centraldp_mods.py,sha256=UGwNuqpmOWfLdfJITFgdi1TG-nLjuSb-cbEyoyfDgxQ,5415
91
94
  flwr/client/mod/comms_mods.py,sha256=QzJF7lgbYGnZvY805rkBfDsYCRC0HBHeDkJQ_JXhUZY,2624
92
- flwr/client/mod/localdp_mod.py,sha256=SBDhW71vY6lEU_lQNOySLUWypkNwUwuHAtbBErOarpM,4982
95
+ flwr/client/mod/localdp_mod.py,sha256=Zhcu2M1QYCaS0dfmTjkhmFABIJcFXfT6zDgV0o9sn-4,5003
93
96
  flwr/client/mod/secure_aggregation/__init__.py,sha256=A7DzZ3uvXTUkuHBzrxJMWQQD4RtO_PsVA53yHc4oWco,849
94
97
  flwr/client/mod/secure_aggregation/secagg_mod.py,sha256=wI9tuIEvMUETz-wVIEbPYvh-1nK9CEylBLGoVpNhL94,1095
95
98
  flwr/client/mod/secure_aggregation/secaggplus_mod.py,sha256=7cNXsY07ZA0M5_9VSc52F8JUoAoGaraNDA2rgaLvvFo,19680
@@ -110,8 +113,8 @@ flwr/common/address.py,sha256=7kM2Rqjw86-c8aKwAvrXerWqznnVv4TFJ62aSAeTn10,3017
110
113
  flwr/common/args.py,sha256=-KeQ6AZw1-G4Ifhsg4qlRnWhGH1m_OzUgxH7Z4j_0ns,6222
111
114
  flwr/common/auth_plugin/__init__.py,sha256=1Y8Oj3iB49IHDu9tvDih1J74Ygu7k85V9s2A4WORPyA,887
112
115
  flwr/common/auth_plugin/auth_plugin.py,sha256=6WEAVVPrS7LgSBpd4WyHYU4EsajT2nBGI_IN3mhYzoU,3567
113
- flwr/common/config.py,sha256=qC1QvGAGr4faBtg3Y5dWhfyK5FggyWUMjPqg-Rx_FW4,8083
114
- flwr/common/constant.py,sha256=-HoTq6u_9VGbva21qTm_vfvQV9cxV7LwsvvlHEBjNwk,5817
116
+ flwr/common/config.py,sha256=kH8u7VBRfyv5cpOC0lQ1jBbxJ6Jo2b3XhUwbIbHoHHw,8098
117
+ flwr/common/constant.py,sha256=9HwFVxFWbLTzMetIffUT3gAC9nPtqzBNxrKWr5A0oSI,5996
115
118
  flwr/common/context.py,sha256=uJ-mnoC_8y_udEb3kAX-r8CPphNTWM72z1AlsvQEu54,2403
116
119
  flwr/common/date.py,sha256=NHHpESce5wYqEwoDXf09gp9U9l_5Bmlh2BsOcwS-kDM,1554
117
120
  flwr/common/differential_privacy.py,sha256=XwcJ3rWr8S8BZUocc76vLSJAXIf6OHnWkBV6-xlIRuw,6106
@@ -121,7 +124,7 @@ flwr/common/exit_handlers.py,sha256=MracJaBeoCOC7TaXK9zCJQxhrMSx9ZtczK237qvhBpU,
121
124
  flwr/common/grpc.py,sha256=AIPMAHsvcTlduaYKCgnoBnst1A7RZEgGqh0Ulm7qfJ0,2621
122
125
  flwr/common/logger.py,sha256=NQkdrtAP3NFTH_ebTTrjD2z6y-1bdoiIx9_npC-1TWw,11940
123
126
  flwr/common/message.py,sha256=4O1m0OWXBAYZz05gKgEtnoJ94J1gjo7hCNHyUXThxRo,13831
124
- flwr/common/object_ref.py,sha256=DavEkh-IJv_s0VeLsJvSZS5k-Ix_k1UcNXbldfNFXxM,9859
127
+ flwr/common/object_ref.py,sha256=fIXf8aP5mG6Nuni7dvcKK5Di3zRfRWGs4ljvqIXplds,10115
125
128
  flwr/common/parameter.py,sha256=-bFAUayToYDF50FZGrBC1hQYJCQDtB2bbr3ZuVLMtdE,2095
126
129
  flwr/common/pyproject.py,sha256=EI_ovbCHGmhYrdPx0RSDi5EkFZFof-8m1PA54c0ZTjc,1385
127
130
  flwr/common/record/__init__.py,sha256=ejDBQOIA0OkwZAC5cK_tTPHA4oAM0Ju7Oi13-NneMlE,1054
@@ -132,7 +135,7 @@ flwr/common/record/parametersrecord.py,sha256=IjnewX8Ea6JXLRWcPMVole2sNjwzRVjBVv
132
135
  flwr/common/record/recordset.py,sha256=sSofrBycZSqiHR4TzfI4_QoIIN-5B1LnMG0C9CiByAo,8312
133
136
  flwr/common/record/typeddict.py,sha256=q5hL2xkXymuiCprHWb69mUmLpWQk_XXQq0hGQ69YPaw,3599
134
137
  flwr/common/recordset_compat.py,sha256=ViSwA26h6Q55ZmV1LLjSJpcKiipV-p_JpCj4wxdE-Ow,14230
135
- flwr/common/retry_invoker.py,sha256=u5dHcRMoyS8ABL3Fjk4P5P1lgRYYa1edfLGzWXxwyAc,11969
138
+ flwr/common/retry_invoker.py,sha256=nCA-dfBw6YoWkOgop71QfhTDmYj1JIgXsdpzlyqgZK4,14396
136
139
  flwr/common/secure_aggregation/__init__.py,sha256=erPnTWdOfMH0K0HQTmj5foDJ6t3iYcExy2aACy8iZNQ,731
137
140
  flwr/common/secure_aggregation/crypto/__init__.py,sha256=nlHesCWy8xxE5s6qHWnauCtyClcMQ2K0CEXAHakY5n0,738
138
141
  flwr/common/secure_aggregation/crypto/shamir.py,sha256=wCSfEfeaPgJ9Om580-YPUF2ljiyRhq33TRC4HtwxYl8,2779
@@ -140,10 +143,10 @@ flwr/common/secure_aggregation/crypto/symmetric_encryption.py,sha256=wTDbOaMGZwT
140
143
  flwr/common/secure_aggregation/ndarrays_arithmetic.py,sha256=zvVAIrIyI6OSzGhpCi8NNaTvPXmoMYQIPJT-NkBg8RU,3013
141
144
  flwr/common/secure_aggregation/quantization.py,sha256=mC4uLf05zeONo8Ke-BY0Tj8UCMOS7VD93zHCzuv3MHU,2304
142
145
  flwr/common/secure_aggregation/secaggplus_constants.py,sha256=9MF-oQh62uD7rt9VeNB-rHf2gBLd5GL3S9OejCxmILY,2183
143
- flwr/common/secure_aggregation/secaggplus_utils.py,sha256=o7IhHH6J9xqinhQy3TdPgQpoj1XyEpyv3OQFyx81RVQ,3193
146
+ flwr/common/secure_aggregation/secaggplus_utils.py,sha256=OgYd68YBRaHQYLc-YdExj9CSpwL58bVTaPrdHoAj2AE,3214
144
147
  flwr/common/serde.py,sha256=K9ExsqcTPETESkt2HMaNtIQAIAfwmuwtJFlG-59I7Sw,31046
145
- flwr/common/telemetry.py,sha256=20AYNaePOBaSEh99PIuBrxRxtY53-kZ5-2Ej0JWUJmc,8731
146
- flwr/common/typing.py,sha256=RLq2f9jhE_Nndtk023cPMG0LpoQHaacEsww-3j0xs4Q,5710
148
+ flwr/common/telemetry.py,sha256=CHIwFFQ13sWFavmEvkvA43XR1sbh1S3nWvD5TuCO2eI,8774
149
+ flwr/common/typing.py,sha256=Ux8rJllzqORzCiv9HYkqVVyEzmd3nOKbcmttj5d2P_I,5801
147
150
  flwr/common/version.py,sha256=tCcl_FvxVK206C1dxIJCs4TjL06WmyaODBP19FRHE1c,1324
148
151
  flwr/proto/__init__.py,sha256=hbY7JYakwZwCkYgCNlmHdc8rtvfoJbAZLalMdc--CGc,683
149
152
  flwr/proto/clientappio_pb2.py,sha256=Y3PMv-JMaBGehpslgbvGY6l2u5vNpfCTFWu-fmAmBJ4,3703
@@ -158,8 +161,8 @@ flwr/proto/exec_pb2.py,sha256=IVqmpzzThSjuLBCF8T9VofTpnUXtp3SYWOEp8dzyv5o,6883
158
161
  flwr/proto/exec_pb2.pyi,sha256=amt-3e3zJVjkRlQ8Gz6m1A7hXyeZmbQhHpAEIQyIDn0,10660
159
162
  flwr/proto/exec_pb2_grpc.py,sha256=-bdLqjsqQxK9R8LIiZaKlLKH2NmjR50EaGKTPPTwFhI,10445
160
163
  flwr/proto/exec_pb2_grpc.pyi,sha256=M5k-FzeLWxal7zt28LJfzMWWRxmNknTC2BzHRRMa1sQ,2914
161
- flwr/proto/fab_pb2.py,sha256=3QSDq9pjbZoqVxsmCRDwHO5PrSjzn2vixjYxE-qPmb0,1589
162
- flwr/proto/fab_pb2.pyi,sha256=fXI108QaFtbl1WWTyslPbIx9c_19D0aYCoFn0xYtL4U,2277
164
+ flwr/proto/fab_pb2.py,sha256=-gfW_ePYHx1vDGHfimwn91qEhmmY_gslaOHwqqZnVdU,1627
165
+ flwr/proto/fab_pb2.pyi,sha256=AMXpiDK0fo3nZWjxsC2E4otSaVjyQbU7iiWKrsSZavs,2395
163
166
  flwr/proto/fab_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
164
167
  flwr/proto/fab_pb2_grpc.pyi,sha256=ff2TSiLVnG6IVQcTGzb2DIH3XRSoAvAo_RMcvbMFyc0,76
165
168
  flwr/proto/fleet_pb2.py,sha256=06NAaIAOxTA2UhkBA-VWZKflaVQIzXgPZ3Fb6vtliY0,4789
@@ -190,10 +193,10 @@ flwr/proto/run_pb2.py,sha256=J2TQwf-S0o9ImGuQLrczw99S0GSXm6hk-npJ8rXAC0Y,5743
190
193
  flwr/proto/run_pb2.pyi,sha256=i6TEwphuFH94_kT2hZWb_RjndLuphkPrT3C2VP-NnVs,11739
191
194
  flwr/proto/run_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
192
195
  flwr/proto/run_pb2_grpc.pyi,sha256=ff2TSiLVnG6IVQcTGzb2DIH3XRSoAvAo_RMcvbMFyc0,76
193
- flwr/proto/serverappio_pb2.py,sha256=zWnODeaj26oSx98-BFvwtWM_fYvsw9OeSIuV7JnKVvw,4822
194
- flwr/proto/serverappio_pb2.pyi,sha256=Ib9c32FCtjA9zZY54Ohi6B-DtLgSjokAqOExm_2uOvY,6429
195
- flwr/proto/serverappio_pb2_grpc.py,sha256=M__pFMmb9yTAGMHVd3_K1V6DeLRuFc9UErJHWjBAsZs,17439
196
- flwr/proto/serverappio_pb2_grpc.pyi,sha256=ERM-0cQVmUqrVXlvEbS2wfUZpZmv5SlIeNsGZPYMrVo,4779
196
+ flwr/proto/serverappio_pb2.py,sha256=VXJxFLDrH4XzCEM9VnNg3z7gVIsrvl1VE4ZtK_lI_eE,5003
197
+ flwr/proto/serverappio_pb2.pyi,sha256=5SoXVb7fyN0xkl411pmJChlWeQ-sr1Qf9J3B0cAQYc4,6665
198
+ flwr/proto/serverappio_pb2_grpc.py,sha256=fGmk0XC7il5wYFSo6zEa21Ki1OYvEuDDXL0hDDoU4QQ,19062
199
+ flwr/proto/serverappio_pb2_grpc.pyi,sha256=pKdqFpAgkHaNSjRNahnGtSndUif8uB5eFui_q37eDho,5220
197
200
  flwr/proto/simulationio_pb2.py,sha256=Fv7m8d4vR_0CIGU93nN5tDXSCk2QPbASH_8mT2wBPTE,3117
198
201
  flwr/proto/simulationio_pb2.pyi,sha256=oXx8_FLBe5B54wduZj-f89kub73XxNtQbThuW8YfPAs,2660
199
202
  flwr/proto/simulationio_pb2_grpc.py,sha256=9I3yAfJaeMuG-qH_5Ge45eFOftsIOmL9b8E_xHmcvKw,11232
@@ -213,13 +216,13 @@ flwr/server/client_manager.py,sha256=7Ese0tgrH-i-ms363feYZJKwB8gWnXSmg_hYF2Bju4U
213
216
  flwr/server/client_proxy.py,sha256=4G-oTwhb45sfWLx2uZdcXD98IZwdTS6F88xe3akCdUg,2399
214
217
  flwr/server/compat/__init__.py,sha256=VxnJtJyOjNFQXMNi9hIuzNlZM5n0Hj1p3aq_Pm2udw4,892
215
218
  flwr/server/compat/app.py,sha256=5vkHHm_h-4cMthvWD1GJo1ZW3eihytjGgvsgfXUK9gA,3298
216
- flwr/server/compat/app_utils.py,sha256=i8MseZQculltLTsRIEe4XUnmAuu3LF3WzGjYi0c-cps,3425
219
+ flwr/server/compat/app_utils.py,sha256=ha1K9h4KfM80-Bcluwa_LtBfQ5g643Eb_QfaAm-GmTU,3579
217
220
  flwr/server/compat/driver_client_proxy.py,sha256=Af0bRUEVZNcCYRxt3DjpLPdvVYpTgz6LSlILtI_8DQY,5010
218
221
  flwr/server/compat/legacy_context.py,sha256=wBzBcfV6YO6IQGriM_FdJ5XZfiBBEEJdS_OdAiF47dY,1804
219
222
  flwr/server/criterion.py,sha256=ypbAexbztzGUxNen9RCHF91QeqiEQix4t4Ih3E-42MM,1061
220
223
  flwr/server/driver/__init__.py,sha256=bikRv6CjTwSvYh7tf10gziU5o2YotOWhhftz2tr3KDc,886
221
224
  flwr/server/driver/driver.py,sha256=u_fMfqLYTroTafGCNwKPHI4lttRL-Z5CqeT3_FHSq-Q,5701
222
- flwr/server/driver/grpc_driver.py,sha256=aTeQVYjyp19LGUa-a5iKdQRFijLzut2bXj1h8YovdIM,11397
225
+ flwr/server/driver/grpc_driver.py,sha256=KXe_zlwwzgnawkeYFNVo8Tq45CGGmMFBAerqxso-s-E,9635
223
226
  flwr/server/driver/inmemory_driver.py,sha256=gfB4jmkk1indhRa9XCdKCXghVcWBF1qBD-tAxMUyQm0,6404
224
227
  flwr/server/history.py,sha256=qSb5_pPTrwofpSYGsZWzMPkl_4uJ4mJFWesxXDrEvDU,5026
225
228
  flwr/server/run_serverapp.py,sha256=oDfHaHyVT5BRcckFFQKg8AVPCWR1ek7OhNceTC8qq9g,2493
@@ -227,7 +230,7 @@ flwr/server/server.py,sha256=1ZsFEptmAV-L2vP2etNC9Ed5CLSxpuKzUFkAPQ4l5Xc,17893
227
230
  flwr/server/server_app.py,sha256=RsgS6PRS5Z74cMUAHzsm8r3LWddwn00MjRs6rlacHt8,6297
228
231
  flwr/server/server_config.py,sha256=CZaHVAsMvGLjpWVcLPkiYxgJN4xfIyAiUrCI3fETKY4,1349
229
232
  flwr/server/serverapp/__init__.py,sha256=L0K-94UDdTyEZ8LDtYybGIIIv3HW6AhSVjXMUfYJQnQ,800
230
- flwr/server/serverapp/app.py,sha256=wYs5H8TU7egSB32DzDnJCUHmcli201e7MlWmhkOgn30,7693
233
+ flwr/server/serverapp/app.py,sha256=E35c-Ic8l9gH463nRBQlMxamJ72Ng-ka4jGWDkwlK_U,7910
231
234
  flwr/server/serverapp_components.py,sha256=-IV_CitOfrJclJj2jNdbN1Q65PyFmtKtrTIg1hc6WQw,2118
232
235
  flwr/server/strategy/__init__.py,sha256=tQer2SwjDnvgFFuJMZM-S01Z615N5XK6MaCvpm4BMU0,2836
233
236
  flwr/server/strategy/aggregate.py,sha256=PDvekufza13s9AsVmz9WASunaBs3yCtl8JVliFx9j6Q,13978
@@ -256,7 +259,7 @@ flwr/server/strategy/strategy.py,sha256=cXapkD5uDrt5C-RbmWDn9FLoap3Q41i7GKvbmfbC
256
259
  flwr/server/superlink/__init__.py,sha256=8tHYCfodUlRD8PCP9fHgvu8cz5N31A2QoRVL0jDJ15E,707
257
260
  flwr/server/superlink/driver/__init__.py,sha256=5soEK5QSvxNjmJQ-CGTWROc4alSAeU0e9Ad9RDhsd3E,717
258
261
  flwr/server/superlink/driver/serverappio_grpc.py,sha256=oTogZLkfeThKdx9Q_bw6OMGHnLIryxQOHxbWi0qgaRM,2185
259
- flwr/server/superlink/driver/serverappio_servicer.py,sha256=nUQgQlxUfCYIvUW5NBq0ZysEL2cFoF2iQJIFabGodNE,10458
262
+ flwr/server/superlink/driver/serverappio_servicer.py,sha256=As8Ow1Dmv4tTiuCMTtokE66kGZr8BTN0fd6EgT_XkLs,12161
260
263
  flwr/server/superlink/ffs/__init__.py,sha256=FAY-zShcfPmOxosok2QyT6hTNMNctG8cH9s_nIl8jkI,840
261
264
  flwr/server/superlink/ffs/disk_ffs.py,sha256=yCN6CCzegnJIOaHr5nIu49wZQa4g5BByiSKshz50RKU,3296
262
265
  flwr/server/superlink/ffs/ffs.py,sha256=qLI1UfosJugu2BKOJWqHIhafTm-YiuKqGf3OGWPH0NM,2395
@@ -290,6 +293,7 @@ flwr/server/superlink/linkstate/utils.py,sha256=d5uqqIOCKfd54X8CFNfUr3AWqPLpgmzs
290
293
  flwr/server/superlink/simulation/__init__.py,sha256=mg-oapC9dkzEfjXPQFior5lpWj4g9kwbLovptyYM_g0,718
291
294
  flwr/server/superlink/simulation/simulationio_grpc.py,sha256=5wflYW_TS0mjmPG6OYuHMJwXD2_cYmUNhFkdOU0jMWQ,2237
292
295
  flwr/server/superlink/simulation/simulationio_servicer.py,sha256=riaZm090aTs7o8cFD8gvCWkX7A2SPLXKM4K8MG60av8,6545
296
+ flwr/server/superlink/utils.py,sha256=KVb3K_g2vYfu9TnftcN0ewmev133WZcjuEePMm8d7GE,2137
293
297
  flwr/server/typing.py,sha256=5kaRLZuxTEse9A0g7aVna2VhYxU3wTq1f3d3mtw7kXs,1019
294
298
  flwr/server/utils/__init__.py,sha256=pltsPHJoXmUIr3utjwwYxu7_ZAGy5u4MVHzv9iA5Un8,908
295
299
  flwr/server/utils/tensorboard.py,sha256=gEBD8w_5uaIfp5aw5RYH66lYZpd_SfkObHQ7eDd9MUk,5466
@@ -317,8 +321,8 @@ flwr/superexec/exec_servicer.py,sha256=jEYcASzkQR1ftjzilmlcTPKXo8NSno9mSj_UbBvMj
317
321
  flwr/superexec/exec_user_auth_interceptor.py,sha256=K06OU-l4LnYhTDg071hGJuOaQWEJbZsYi5qxUmmtiG0,3704
318
322
  flwr/superexec/executor.py,sha256=zH3_53il6Jh0ZscIVEB9f4GNnXMeBbCGyCoBCxLgiG0,3114
319
323
  flwr/superexec/simulation.py,sha256=WQDon15oqpMopAZnwRZoTICYCfHqtkvFSqiTQ2hLD_g,4088
320
- flwr_nightly-1.14.0.dev20241210.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
321
- flwr_nightly-1.14.0.dev20241210.dist-info/METADATA,sha256=3DjOUcyJbLgmX8glq_Tt7SV70giiQh5JP39zfpFyLjE,15700
322
- flwr_nightly-1.14.0.dev20241210.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
323
- flwr_nightly-1.14.0.dev20241210.dist-info/entry_points.txt,sha256=JlNxX3qhaV18_2yj5a3kJW1ESxm31cal9iS_N_pf1Rk,538
324
- flwr_nightly-1.14.0.dev20241210.dist-info/RECORD,,
324
+ flwr_nightly-1.14.0.dev20241212.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
325
+ flwr_nightly-1.14.0.dev20241212.dist-info/METADATA,sha256=IHpu3jP8Tt8KxOP3b4XtkPPf3wRSXYzwknPGE7mDlAY,15799
326
+ flwr_nightly-1.14.0.dev20241212.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
327
+ flwr_nightly-1.14.0.dev20241212.dist-info/entry_points.txt,sha256=JlNxX3qhaV18_2yj5a3kJW1ESxm31cal9iS_N_pf1Rk,538
328
+ flwr_nightly-1.14.0.dev20241212.dist-info/RECORD,,