flwr-nightly 1.13.0.dev20241028__py3-none-any.whl → 1.13.0.dev20241030__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/build.py +2 -2
  2. flwr/cli/log.py +46 -17
  3. flwr/common/constant.py +6 -0
  4. flwr/common/date.py +3 -3
  5. flwr/common/logger.py +103 -0
  6. flwr/common/serde.py +22 -0
  7. flwr/proto/driver_pb2.py +24 -23
  8. flwr/proto/driver_pb2.pyi +0 -5
  9. flwr/proto/driver_pb2_grpc.py +69 -0
  10. flwr/proto/driver_pb2_grpc.pyi +27 -0
  11. flwr/proto/exec_pb2.py +6 -6
  12. flwr/proto/exec_pb2.pyi +8 -2
  13. flwr/proto/log_pb2.py +29 -0
  14. flwr/proto/log_pb2.pyi +39 -0
  15. flwr/proto/log_pb2_grpc.py +4 -0
  16. flwr/proto/log_pb2_grpc.pyi +4 -0
  17. flwr/server/app.py +1 -5
  18. flwr/server/driver/driver.py +14 -0
  19. flwr/server/driver/grpc_driver.py +8 -15
  20. flwr/server/driver/inmemory_driver.py +3 -11
  21. flwr/server/run_serverapp.py +3 -4
  22. flwr/server/serverapp/app.py +148 -18
  23. flwr/server/superlink/driver/driver_servicer.py +36 -9
  24. flwr/server/superlink/linkstate/in_memory_linkstate.py +28 -2
  25. flwr/server/superlink/linkstate/linkstate.py +35 -0
  26. flwr/server/superlink/linkstate/sqlite_linkstate.py +50 -0
  27. flwr/simulation/run_simulation.py +2 -1
  28. flwr/superexec/deployment.py +22 -40
  29. flwr/superexec/exec_servicer.py +23 -62
  30. flwr/superexec/executor.py +3 -4
  31. flwr/superexec/simulation.py +4 -7
  32. {flwr_nightly-1.13.0.dev20241028.dist-info → flwr_nightly-1.13.0.dev20241030.dist-info}/METADATA +1 -1
  33. {flwr_nightly-1.13.0.dev20241028.dist-info → flwr_nightly-1.13.0.dev20241030.dist-info}/RECORD +36 -32
  34. {flwr_nightly-1.13.0.dev20241028.dist-info → flwr_nightly-1.13.0.dev20241030.dist-info}/LICENSE +0 -0
  35. {flwr_nightly-1.13.0.dev20241028.dist-info → flwr_nightly-1.13.0.dev20241030.dist-info}/WHEEL +0 -0
  36. {flwr_nightly-1.13.0.dev20241028.dist-info → flwr_nightly-1.13.0.dev20241030.dist-info}/entry_points.txt +0 -0
@@ -99,6 +99,17 @@ CREATE TABLE IF NOT EXISTS run(
99
99
  );
100
100
  """
101
101
 
102
+ SQL_CREATE_TABLE_LOGS = """
103
+ CREATE TABLE IF NOT EXISTS logs (
104
+ timestamp REAL,
105
+ run_id INTEGER,
106
+ node_id INTEGER,
107
+ log TEXT,
108
+ PRIMARY KEY (timestamp, run_id, node_id),
109
+ FOREIGN KEY (run_id) REFERENCES run(run_id)
110
+ );
111
+ """
112
+
102
113
  SQL_CREATE_TABLE_CONTEXT = """
103
114
  CREATE TABLE IF NOT EXISTS context(
104
115
  run_id INTEGER UNIQUE,
@@ -191,6 +202,7 @@ class SqliteLinkState(LinkState): # pylint: disable=R0904
191
202
 
192
203
  # Create each table if not exists queries
193
204
  cur.execute(SQL_CREATE_TABLE_RUN)
205
+ cur.execute(SQL_CREATE_TABLE_LOGS)
194
206
  cur.execute(SQL_CREATE_TABLE_CONTEXT)
195
207
  cur.execute(SQL_CREATE_TABLE_TASK_INS)
196
208
  cur.execute(SQL_CREATE_TABLE_TASK_RES)
@@ -1015,6 +1027,44 @@ class SqliteLinkState(LinkState): # pylint: disable=R0904
1015
1027
  except sqlite3.IntegrityError:
1016
1028
  raise ValueError(f"Run {run_id} not found") from None
1017
1029
 
1030
+ def add_serverapp_log(self, run_id: int, log_message: str) -> None:
1031
+ """Add a log entry to the ServerApp logs for the specified `run_id`."""
1032
+ # Convert the uint64 value to sint64 for SQLite
1033
+ sint64_run_id = convert_uint64_to_sint64(run_id)
1034
+
1035
+ # Store log
1036
+ try:
1037
+ query = """
1038
+ INSERT INTO logs (timestamp, run_id, node_id, log) VALUES (?, ?, ?, ?);
1039
+ """
1040
+ self.query(query, (now().timestamp(), sint64_run_id, 0, log_message))
1041
+ except sqlite3.IntegrityError:
1042
+ raise ValueError(f"Run {run_id} not found") from None
1043
+
1044
+ def get_serverapp_log(
1045
+ self, run_id: int, after_timestamp: Optional[float]
1046
+ ) -> tuple[str, float]:
1047
+ """Get the ServerApp logs for the specified `run_id`."""
1048
+ # Convert the uint64 value to sint64 for SQLite
1049
+ sint64_run_id = convert_uint64_to_sint64(run_id)
1050
+
1051
+ # Check if the run_id exists
1052
+ query = "SELECT run_id FROM run WHERE run_id = ?;"
1053
+ if not self.query(query, (sint64_run_id,)):
1054
+ raise ValueError(f"Run {run_id} not found")
1055
+
1056
+ # Retrieve logs
1057
+ if after_timestamp is None:
1058
+ after_timestamp = 0.0
1059
+ query = """
1060
+ SELECT log, timestamp FROM logs
1061
+ WHERE run_id = ? AND node_id = ? AND timestamp > ?;
1062
+ """
1063
+ rows = self.query(query, (sint64_run_id, 0, after_timestamp))
1064
+ rows.sort(key=lambda x: x["timestamp"])
1065
+ latest_timestamp = rows[-1]["timestamp"] if rows else 0.0
1066
+ return "".join(row["log"] for row in rows), latest_timestamp
1067
+
1018
1068
  def get_valid_task_ins(self, task_id: str) -> Optional[dict[str, Any]]:
1019
1069
  """Check if the TaskIns exists and is valid (not expired).
1020
1070
 
@@ -421,7 +421,8 @@ def _main_loop(
421
421
  server_app_run_config = {}
422
422
 
423
423
  # Initialize Driver
424
- driver = InMemoryDriver(run_id=run.run_id, state_factory=state_factory)
424
+ driver = InMemoryDriver(state_factory=state_factory)
425
+ driver.init_run(run_id=run.run_id)
425
426
 
426
427
  # Get and run ServerApp thread
427
428
  serverapp_th = run_serverapp_th(
@@ -15,22 +15,21 @@
15
15
  """Deployment engine executor."""
16
16
 
17
17
  import hashlib
18
- import subprocess
19
18
  from logging import ERROR, INFO
20
19
  from pathlib import Path
21
20
  from typing import Optional
22
21
 
23
22
  from typing_extensions import override
24
23
 
25
- from flwr.cli.install import install_from_fab
26
- from flwr.common.constant import DRIVER_API_DEFAULT_ADDRESS
24
+ from flwr.common import Context, RecordSet
25
+ from flwr.common.constant import DRIVER_API_DEFAULT_ADDRESS, Status, SubStatus
27
26
  from flwr.common.logger import log
28
- from flwr.common.typing import Fab, UserConfig
27
+ from flwr.common.typing import Fab, RunStatus, UserConfig
29
28
  from flwr.server.superlink.ffs import Ffs
30
29
  from flwr.server.superlink.ffs.ffs_factory import FfsFactory
31
30
  from flwr.server.superlink.linkstate import LinkState, LinkStateFactory
32
31
 
33
- from .executor import Executor, RunTracker
32
+ from .executor import Executor
34
33
 
35
34
 
36
35
  class DeploymentEngine(Executor):
@@ -137,58 +136,41 @@ class DeploymentEngine(Executor):
137
136
  run_id = self.linkstate.create_run(None, None, fab_hash, override_config)
138
137
  return run_id
139
138
 
139
+ def _create_context(self, run_id: int) -> None:
140
+ """Register a Context for a Run."""
141
+ # Create an empty context for the Run
142
+ context = Context(node_id=0, node_config={}, state=RecordSet(), run_config={})
143
+
144
+ # Register the context at the LinkState
145
+ self.linkstate.set_serverapp_context(run_id=run_id, context=context)
146
+
140
147
  @override
141
148
  def start_run(
142
149
  self,
143
150
  fab_file: bytes,
144
151
  override_config: UserConfig,
145
152
  federation_config: UserConfig,
146
- ) -> Optional[RunTracker]:
153
+ ) -> Optional[int]:
147
154
  """Start run using the Flower Deployment Engine."""
155
+ run_id = None
148
156
  try:
149
- # Install FAB to flwr dir
150
- install_from_fab(fab_file, None, True)
151
157
 
152
158
  # Call SuperLink to create run
153
- run_id: int = self._create_run(
159
+ run_id = self._create_run(
154
160
  Fab(hashlib.sha256(fab_file).hexdigest(), fab_file), override_config
155
161
  )
156
- log(INFO, "Created run %s", str(run_id))
157
162
 
158
- command = [
159
- "flower-server-app",
160
- "--run-id",
161
- str(run_id),
162
- "--superlink",
163
- str(self.superlink),
164
- ]
165
-
166
- if self.flwr_dir:
167
- command.append("--flwr-dir")
168
- command.append(self.flwr_dir)
169
-
170
- if self.root_certificates is None:
171
- command.append("--insecure")
172
- else:
173
- command.append("--root-certificates")
174
- command.append(self.root_certificates)
175
-
176
- # Execute the command
177
- proc = subprocess.Popen( # pylint: disable=consider-using-with
178
- command,
179
- stdout=subprocess.PIPE,
180
- stderr=subprocess.PIPE,
181
- text=True,
182
- )
183
- log(INFO, "Started run %s", str(run_id))
163
+ # Register context for the Run
164
+ self._create_context(run_id=run_id)
165
+ log(INFO, "Created run %s", str(run_id))
184
166
 
185
- return RunTracker(
186
- run_id=run_id,
187
- proc=proc,
188
- )
167
+ return run_id
189
168
  # pylint: disable-next=broad-except
190
169
  except Exception as e:
191
170
  log(ERROR, "Could not start run: %s", str(e))
171
+ if run_id:
172
+ run_status = RunStatus(Status.FINISHED, SubStatus.FAILED, str(e))
173
+ self.linkstate.update_run_status(run_id, new_status=run_status)
192
174
  return None
193
175
 
194
176
 
@@ -15,9 +15,6 @@
15
15
  """SuperExec API servicer."""
16
16
 
17
17
 
18
- import select
19
- import sys
20
- import threading
21
18
  import time
22
19
  from collections.abc import Generator
23
20
  from logging import ERROR, INFO
@@ -25,6 +22,7 @@ from typing import Any
25
22
 
26
23
  import grpc
27
24
 
25
+ from flwr.common.constant import LOG_STREAM_INTERVAL, Status
28
26
  from flwr.common.logger import log
29
27
  from flwr.common.serde import user_config_from_proto
30
28
  from flwr.proto import exec_pb2_grpc # pylint: disable=E0611
@@ -37,9 +35,7 @@ from flwr.proto.exec_pb2 import ( # pylint: disable=E0611
37
35
  from flwr.server.superlink.ffs.ffs_factory import FfsFactory
38
36
  from flwr.server.superlink.linkstate import LinkStateFactory
39
37
 
40
- from .executor import Executor, RunTracker
41
-
42
- SELECT_TIMEOUT = 1 # Timeout for selecting ready-to-read file descriptors (in seconds)
38
+ from .executor import Executor
43
39
 
44
40
 
45
41
  class ExecServicer(exec_pb2_grpc.ExecServicer):
@@ -55,7 +51,6 @@ class ExecServicer(exec_pb2_grpc.ExecServicer):
55
51
  self.ffs_factory = ffs_factory
56
52
  self.executor = executor
57
53
  self.executor.initialize(linkstate_factory, ffs_factory)
58
- self.runs: dict[int, RunTracker] = {}
59
54
 
60
55
  def StartRun(
61
56
  self, request: StartRunRequest, context: grpc.ServicerContext
@@ -63,84 +58,50 @@ class ExecServicer(exec_pb2_grpc.ExecServicer):
63
58
  """Create run ID."""
64
59
  log(INFO, "ExecServicer.StartRun")
65
60
 
66
- run = self.executor.start_run(
61
+ run_id = self.executor.start_run(
67
62
  request.fab.content,
68
63
  user_config_from_proto(request.override_config),
69
64
  user_config_from_proto(request.federation_config),
70
65
  )
71
66
 
72
- if run is None:
67
+ if run_id is None:
73
68
  log(ERROR, "Executor failed to start run")
74
69
  return StartRunResponse()
75
70
 
76
- self.runs[run.run_id] = run
77
-
78
- # Start a background thread to capture the log output
79
- capture_thread = threading.Thread(
80
- target=_capture_logs, args=(run,), daemon=True
81
- )
82
- capture_thread.start()
83
-
84
- return StartRunResponse(run_id=run.run_id)
71
+ return StartRunResponse(run_id=run_id)
85
72
 
86
73
  def StreamLogs( # pylint: disable=C0103
87
74
  self, request: StreamLogsRequest, context: grpc.ServicerContext
88
75
  ) -> Generator[StreamLogsResponse, Any, None]:
89
76
  """Get logs."""
90
77
  log(INFO, "ExecServicer.StreamLogs")
78
+ state = self.linkstate_factory.state()
79
+
80
+ # Retrieve run ID
81
+ run_id = request.run_id
91
82
 
92
83
  # Exit if `run_id` not found
93
- if request.run_id not in self.runs:
84
+ if not state.get_run(run_id):
94
85
  context.abort(grpc.StatusCode.NOT_FOUND, "Run ID not found")
95
86
 
96
- last_sent_index = 0
87
+ after_timestamp = request.after_timestamp + 1e-6
97
88
  while context.is_active():
98
- # Yield n'th row of logs, if n'th row < len(logs)
99
- logs = self.runs[request.run_id].logs
100
- for i in range(last_sent_index, len(logs)):
101
- yield StreamLogsResponse(log_output=logs[i])
102
- last_sent_index = len(logs)
89
+ log_msg, latest_timestamp = state.get_serverapp_log(run_id, after_timestamp)
90
+ if log_msg:
91
+ yield StreamLogsResponse(
92
+ log_output=log_msg,
93
+ latest_timestamp=latest_timestamp,
94
+ )
95
+ # Add a small epsilon to the latest timestamp to avoid getting
96
+ # the same log
97
+ after_timestamp = max(latest_timestamp + 1e-6, after_timestamp)
103
98
 
104
99
  # Wait for and continue to yield more log responses only if the
105
100
  # run isn't completed yet. If the run is finished, the entire log
106
101
  # is returned at this point and the server ends the stream.
107
- if self.runs[request.run_id].proc.poll() is not None:
102
+ run_status = state.get_run_status({run_id})[run_id]
103
+ if run_status.status == Status.FINISHED:
108
104
  log(INFO, "All logs for run ID `%s` returned", request.run_id)
109
- context.set_code(grpc.StatusCode.OK)
110
105
  context.cancel()
111
106
 
112
- time.sleep(1.0) # Sleep briefly to avoid busy waiting
113
-
114
-
115
- def _capture_logs(
116
- run: RunTracker,
117
- ) -> None:
118
- while True:
119
- # Explicitly check if Popen.poll() is None. Required for `pytest`.
120
- if run.proc.poll() is None:
121
- # Select streams only when ready to read
122
- ready_to_read, _, _ = select.select(
123
- [run.proc.stdout, run.proc.stderr],
124
- [],
125
- [],
126
- SELECT_TIMEOUT,
127
- )
128
- # Read from std* and append to RunTracker.logs
129
- for stream in ready_to_read:
130
- # Flush stdout to view output in real time
131
- readline = stream.readline()
132
- sys.stdout.write(readline)
133
- sys.stdout.flush()
134
- # Append to logs
135
- line = readline.rstrip()
136
- if line:
137
- run.logs.append(f"{line}")
138
-
139
- # Close std* to prevent blocking
140
- elif run.proc.poll() is not None:
141
- log(INFO, "Subprocess finished, exiting log capture")
142
- if run.proc.stdout:
143
- run.proc.stdout.close()
144
- if run.proc.stderr:
145
- run.proc.stderr.close()
146
- break
107
+ time.sleep(LOG_STREAM_INTERVAL) # Sleep briefly to avoid busy waiting
@@ -72,7 +72,7 @@ class Executor(ABC):
72
72
  fab_file: bytes,
73
73
  override_config: UserConfig,
74
74
  federation_config: UserConfig,
75
- ) -> Optional[RunTracker]:
75
+ ) -> Optional[int]:
76
76
  """Start a run using the given Flower FAB ID and version.
77
77
 
78
78
  This method creates a new run on the SuperLink, returns its run_id
@@ -89,7 +89,6 @@ class Executor(ABC):
89
89
 
90
90
  Returns
91
91
  -------
92
- run_id : Optional[RunTracker]
93
- The run_id and the associated process of the run created by the SuperLink,
94
- or `None` if it fails.
92
+ run_id : Optional[int]
93
+ The run_id of the run created by the SuperLink, or `None` if it fails.
95
94
  """
@@ -33,7 +33,7 @@ from flwr.server.superlink.ffs.ffs_factory import FfsFactory
33
33
  from flwr.server.superlink.linkstate import LinkStateFactory
34
34
  from flwr.server.superlink.linkstate.utils import generate_rand_int_from_bytes
35
35
 
36
- from .executor import Executor, RunTracker
36
+ from .executor import Executor
37
37
 
38
38
 
39
39
  def _user_config_to_str(user_config: UserConfig) -> str:
@@ -125,7 +125,7 @@ class SimulationEngine(Executor):
125
125
  fab_file: bytes,
126
126
  override_config: UserConfig,
127
127
  federation_config: UserConfig,
128
- ) -> Optional[RunTracker]:
128
+ ) -> Optional[int]:
129
129
  """Start run using the Flower Simulation Engine."""
130
130
  if self.num_supernodes is None:
131
131
  raise ValueError(
@@ -199,17 +199,14 @@ class SimulationEngine(Executor):
199
199
  command.extend(["--run-config", f"{override_config_str}"])
200
200
 
201
201
  # Start Simulation
202
- proc = subprocess.Popen( # pylint: disable=consider-using-with
202
+ _ = subprocess.Popen( # pylint: disable=consider-using-with
203
203
  command,
204
204
  text=True,
205
205
  )
206
206
 
207
207
  log(INFO, "Started run %s", str(run_id))
208
208
 
209
- return RunTracker(
210
- run_id=run_id,
211
- proc=proc,
212
- )
209
+ return run_id
213
210
 
214
211
  # pylint: disable-next=broad-except
215
212
  except Exception as e:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flwr-nightly
3
- Version: 1.13.0.dev20241028
3
+ Version: 1.13.0.dev20241030
4
4
  Summary: Flower: A Friendly Federated Learning Framework
5
5
  Home-page: https://flower.ai
6
6
  License: Apache-2.0
@@ -1,11 +1,11 @@
1
1
  flwr/__init__.py,sha256=VmBWedrCxqmt4QvUHBLqyVEH6p7zaFMD_oCHerXHSVw,937
2
2
  flwr/cli/__init__.py,sha256=cZJVgozlkC6Ni2Hd_FAIrqefrkCGOV18fikToq-6iLw,720
3
3
  flwr/cli/app.py,sha256=_HDs7HS12Dp7NXIyVrkPs1SKJq3x-XvVZd6y1lvyud4,1255
4
- flwr/cli/build.py,sha256=WC7e6xPJJqRJvXmi8u0ECRvPThPYQcGOxLEgh9uG0gI,6365
4
+ flwr/cli/build.py,sha256=k2M0aIY2q5WB_yXQ22Woxt1zb6m-Z1wNwmhWMxEm5Dw,6344
5
5
  flwr/cli/config_utils.py,sha256=U0tYiC4uwT68LzXFpiiu6XzzplEo-43BR_ON9t3aHOw,7956
6
6
  flwr/cli/example.py,sha256=1bGDYll3BXQY2kRqSN-oICqS5n1b9m0g0RvXTopXHl4,2215
7
7
  flwr/cli/install.py,sha256=7Dx8zrn49mTktxGOToBhGx8hzsHOViDasMJ43ooKPXc,8646
8
- flwr/cli/log.py,sha256=uhtcLcFGkazirWnEmet3Wt3rt_q-a13kauQqPLaMaRY,8097
8
+ flwr/cli/log.py,sha256=SaHqtqI0xKRxt25s-ocQkKxhvXoLGkrsnXff3BBFPMI,9003
9
9
  flwr/cli/new/__init__.py,sha256=cQzK1WH4JP2awef1t2UQ2xjl1agVEz9rwutV18SWV1k,789
10
10
  flwr/cli/new/new.py,sha256=uSiG7aXQzPDnikv2YcjQ86OOLqint0hNWCI0fSQD0jI,9634
11
11
  flwr/cli/new/templates/__init__.py,sha256=4luU8RL-CK8JJCstQ_ON809W9bNTkY1l9zSaPKBkgwY,725
@@ -102,15 +102,15 @@ flwr/client/typing.py,sha256=dxoTBnTMfqXr5J7G3y-uNjqxYCddvxhu89spfj4Lm2U,1048
102
102
  flwr/common/__init__.py,sha256=TVaoFEJE158aui1TPZQiJCDZX4RNHRyI8I55VC80HhI,3901
103
103
  flwr/common/address.py,sha256=7kM2Rqjw86-c8aKwAvrXerWqznnVv4TFJ62aSAeTn10,3017
104
104
  flwr/common/config.py,sha256=nYA1vjiiqSWx5JjSdlQd1i_0N_Dh9kEGUse1Qze3JMs,7803
105
- flwr/common/constant.py,sha256=iv2O8vQdrIqsGy-RFluRDd0R0oaqWO046KPm14yPzw0,4376
105
+ flwr/common/constant.py,sha256=jWAHR2SRW_XJQ7ZMumFL54gSlo6Jp_sr1ndI5ebQNnI,4701
106
106
  flwr/common/context.py,sha256=5Bd9RCrhLkYZOVR7vr97OVhzVBHQkS1fUsYiIKTwpxU,2239
107
- flwr/common/date.py,sha256=OcQuwpb2HxcblTqYm6H223ufop5UZw5N_fzalbpOVzY,891
107
+ flwr/common/date.py,sha256=uTvLmCkd3uVQuD4MviPHnIXMGyheL16mEI_UlOsv_R8,894
108
108
  flwr/common/differential_privacy.py,sha256=XwcJ3rWr8S8BZUocc76vLSJAXIf6OHnWkBV6-xlIRuw,6106
109
109
  flwr/common/differential_privacy_constants.py,sha256=c7b7tqgvT7yMK0XN9ndiTBs4mQf6d3qk6K7KBZGlV4Q,1074
110
110
  flwr/common/dp.py,sha256=vddkvyjV2FhRoN4VuU2LeAM1UBn7dQB8_W-Qdiveal8,1978
111
111
  flwr/common/exit_handlers.py,sha256=MracJaBeoCOC7TaXK9zCJQxhrMSx9ZtczK237qvhBpU,2806
112
112
  flwr/common/grpc.py,sha256=6Yi28JjAll19nxYJlOT9B03RN8dvJZP9zUoR3RSmxoY,2487
113
- flwr/common/logger.py,sha256=PnO5x79HDZBwpzo2z70DBF3BrPuQasWfcmvbwCFunsI,8123
113
+ flwr/common/logger.py,sha256=F5mfXVuxo0qfYIcWpxTkwkOeyhpUZ7oeDS9CUHxCibg,11045
114
114
  flwr/common/message.py,sha256=4O1m0OWXBAYZz05gKgEtnoJ94J1gjo7hCNHyUXThxRo,13831
115
115
  flwr/common/object_ref.py,sha256=5lgWqYaJR28UdFc-iirWw9YqFXMfgkOOAdfJc1AVibE,8711
116
116
  flwr/common/parameter.py,sha256=-bFAUayToYDF50FZGrBC1hQYJCQDtB2bbr3ZuVLMtdE,2095
@@ -132,7 +132,7 @@ flwr/common/secure_aggregation/ndarrays_arithmetic.py,sha256=zvVAIrIyI6OSzGhpCi8
132
132
  flwr/common/secure_aggregation/quantization.py,sha256=mC4uLf05zeONo8Ke-BY0Tj8UCMOS7VD93zHCzuv3MHU,2304
133
133
  flwr/common/secure_aggregation/secaggplus_constants.py,sha256=9MF-oQh62uD7rt9VeNB-rHf2gBLd5GL3S9OejCxmILY,2183
134
134
  flwr/common/secure_aggregation/secaggplus_utils.py,sha256=o7IhHH6J9xqinhQy3TdPgQpoj1XyEpyv3OQFyx81RVQ,3193
135
- flwr/common/serde.py,sha256=74nN5uqASdqfykSWPOhaTJARA07Iznyg3Nyr-dh-uy4,29918
135
+ flwr/common/serde.py,sha256=ZNPGTjxmIyRMPskpIy3VVYgjckeix0jzDEc1PtVSgLo,30562
136
136
  flwr/common/telemetry.py,sha256=PvdlipCPYciqEgmXRwQ1HklP1uyECcNqt9HTBzthmAg,8904
137
137
  flwr/common/typing.py,sha256=fS_KmVdg0c1B87yMnccIPfjBzQ3CTRwYJcaWfmvZzEA,5103
138
138
  flwr/common/version.py,sha256=tCcl_FvxVK206C1dxIJCs4TjL06WmyaODBP19FRHE1c,1324
@@ -149,16 +149,16 @@ flwr/proto/control_pb2.py,sha256=yaUkwY2J9uo-fdUIB5aHwVSDOuGunxaUr4ZlggifA_M,143
149
149
  flwr/proto/control_pb2.pyi,sha256=XbFvpZvvrS7QcH5AFXfpRGl4hQvhd3QdKO6x0oTlCCU,165
150
150
  flwr/proto/control_pb2_grpc.py,sha256=FFE21nZvEILWpe1WCR5vAwgYEtpzrdG78-_SsU0gZ7w,5783
151
151
  flwr/proto/control_pb2_grpc.pyi,sha256=9DU4sgkzJ497a4Nq6kitZWEG4g_5MO8MevichnO0oAg,1672
152
- flwr/proto/driver_pb2.py,sha256=8WmaJ3F5iPuHeiFkfkf_9Pa86qgoUYLPaIL-9igdcIk,4528
153
- flwr/proto/driver_pb2.pyi,sha256=Mq4xZ5Hn55CrUVLu4kvNZylKtF9AQ9NomOv1qJ3Py4Q,6636
154
- flwr/proto/driver_pb2_grpc.py,sha256=KgJNfvIkTX4z3u9jU05z3GvyCx39cQ1r_OgiD3zoinw,13886
155
- flwr/proto/driver_pb2_grpc.pyi,sha256=_aiUW3TsX1jPL7WqdUhiAPK_6bK8Cv5Flo_SntmlL44,3766
152
+ flwr/proto/driver_pb2.py,sha256=2BEQT2YloRBX1-5Gp_rjKBiUD3SY7sr_ic6y0MGlsRk,4795
153
+ flwr/proto/driver_pb2.pyi,sha256=Ib9c32FCtjA9zZY54Ohi6B-DtLgSjokAqOExm_2uOvY,6429
154
+ flwr/proto/driver_pb2_grpc.py,sha256=UgZ2PrrBmff-mwH1FG3Zf1YPYLoZVMldEBMUesjC-IQ,17154
155
+ flwr/proto/driver_pb2_grpc.pyi,sha256=1yVGhlZFwR-o1hrGFJptMBrEpdjc_MYpD14oEWDqib8,4654
156
156
  flwr/proto/error_pb2.py,sha256=LarjKL90LbwkXKlhzNrDssgl4DXcvIPve8NVCXHpsKA,1084
157
157
  flwr/proto/error_pb2.pyi,sha256=ZNH4HhJTU_KfMXlyCeg8FwU-fcUYxTqEmoJPtWtHikc,734
158
158
  flwr/proto/error_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
159
159
  flwr/proto/error_pb2_grpc.pyi,sha256=ff2TSiLVnG6IVQcTGzb2DIH3XRSoAvAo_RMcvbMFyc0,76
160
- flwr/proto/exec_pb2.py,sha256=GH_VWC-BZwWmeWdmjP4IkXvwR8yY1uBZNNwKru-ZZL4,3231
161
- flwr/proto/exec_pb2.pyi,sha256=5y6L3xFkAuCfLTn2pVIHQAlXp17YcTTq8WVDS7_MPl4,4273
160
+ flwr/proto/exec_pb2.py,sha256=jrPfFdZrT7L6kI-MGu6Ej2rYpd8sgen27bm6njrTrrk,3335
161
+ flwr/proto/exec_pb2.pyi,sha256=rvf6cp7YXGQiltzjhd7ZeZmyAeHexDKTp_5kyavZYsA,4612
162
162
  flwr/proto/exec_pb2_grpc.py,sha256=faAN19XEMP8GTKrcIU6jvlWkN44n2KiUsZh_OG0sYcg,4072
163
163
  flwr/proto/exec_pb2_grpc.pyi,sha256=VrFhT1Um3Nb8UC2YqnR9GIiM-Yyx0FqaxVOWljh-G_w,1208
164
164
  flwr/proto/fab_pb2.py,sha256=3QSDq9pjbZoqVxsmCRDwHO5PrSjzn2vixjYxE-qPmb0,1589
@@ -173,6 +173,10 @@ flwr/proto/grpcadapter_pb2.py,sha256=bb8mW09XzNCpMdr1KuYQkefPFWR8lc8y1uL6Uk0TtsM
173
173
  flwr/proto/grpcadapter_pb2.pyi,sha256=AR77gDsF6f8zqSIQp3877DUd7S8lP95lFak5Ir_WPkw,1716
174
174
  flwr/proto/grpcadapter_pb2_grpc.py,sha256=rRNuNES5nBugUZWfeA8oAy8dMHgzqU_PF1srTseo3b8,2634
175
175
  flwr/proto/grpcadapter_pb2_grpc.pyi,sha256=AgA9Qo_lnANb9SNuPzbZGAxupau-xcqYawZz6vqf-24,735
176
+ flwr/proto/log_pb2.py,sha256=0McrbU6ZlGLMEUAOhxmJvcVdEnptE2t4HsuzI_j77Sg,1393
177
+ flwr/proto/log_pb2.pyi,sha256=ipuhgo40sAHTcRzCsGI1HwIstr5q0THPNk_cf62YyME,1448
178
+ flwr/proto/log_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
179
+ flwr/proto/log_pb2_grpc.pyi,sha256=ff2TSiLVnG6IVQcTGzb2DIH3XRSoAvAo_RMcvbMFyc0,76
176
180
  flwr/proto/message_pb2.py,sha256=GW0ID-d2pvtgylsKxtINQx_oORgNGel3WJ3ybZcXxtI,3151
177
181
  flwr/proto/message_pb2.pyi,sha256=_J9NjZa7Pr-kSO7-GGOL5EvIXQx5mQD04iVIvnVHBMU,5617
178
182
  flwr/proto/message_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
@@ -199,7 +203,7 @@ flwr/proto/transport_pb2_grpc.py,sha256=vLN3EHtx2aEEMCO4f1Upu-l27BPzd3-5pV-u8wPc
199
203
  flwr/proto/transport_pb2_grpc.pyi,sha256=AGXf8RiIiW2J5IKMlm_3qT3AzcDa4F3P5IqUjve_esA,766
200
204
  flwr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
201
205
  flwr/server/__init__.py,sha256=cEg1oecBu4cKB69iJCqWEylC8b5XW47bl7rQiJsdTvM,1528
202
- flwr/server/app.py,sha256=7mV0p6Ej7GHyAnSyTOaaPJC2UuXpXfgNLuoDvLemsRM,28353
206
+ flwr/server/app.py,sha256=xt4o1Ls7BYEZ-R2Ro6_-zaBmv5yn2PtMH6p66mfZSmU,28222
203
207
  flwr/server/client_manager.py,sha256=7Ese0tgrH-i-ms363feYZJKwB8gWnXSmg_hYF2Bju4U,6227
204
208
  flwr/server/client_proxy.py,sha256=4G-oTwhb45sfWLx2uZdcXD98IZwdTS6F88xe3akCdUg,2399
205
209
  flwr/server/compat/__init__.py,sha256=VxnJtJyOjNFQXMNi9hIuzNlZM5n0Hj1p3aq_Pm2udw4,892
@@ -209,16 +213,16 @@ flwr/server/compat/driver_client_proxy.py,sha256=Af0bRUEVZNcCYRxt3DjpLPdvVYpTgz6
209
213
  flwr/server/compat/legacy_context.py,sha256=wBzBcfV6YO6IQGriM_FdJ5XZfiBBEEJdS_OdAiF47dY,1804
210
214
  flwr/server/criterion.py,sha256=ypbAexbztzGUxNen9RCHF91QeqiEQix4t4Ih3E-42MM,1061
211
215
  flwr/server/driver/__init__.py,sha256=bikRv6CjTwSvYh7tf10gziU5o2YotOWhhftz2tr3KDc,886
212
- flwr/server/driver/driver.py,sha256=KpLrWeF0zP9HBdo_mucPlNVj5eS0K8DDHRRY_58E1BM,5244
213
- flwr/server/driver/grpc_driver.py,sha256=AhkqfXBSv8TnqBGxqj1nhkOxp6HVU0WaJq4YlqIz8Hw,9687
214
- flwr/server/driver/inmemory_driver.py,sha256=7gw1zRgNvmy2FWCEOMs8udpc2HQsxURrIwbpKv5VyoE,6656
216
+ flwr/server/driver/driver.py,sha256=m8u4ZjtRmy1Cqg7SAld1trg9cd7E7O2IAnfsrJ97sXE,5697
217
+ flwr/server/driver/grpc_driver.py,sha256=cB9uL3JnMOBaObtwo0c60JH2slnoG2-Hsv9tZXpaeCI,9539
218
+ flwr/server/driver/inmemory_driver.py,sha256=kMNYmWWy2VOTDC_PnU-jKfVGrCqdeqp3-kwWiYkJGjo,6453
215
219
  flwr/server/history.py,sha256=qSb5_pPTrwofpSYGsZWzMPkl_4uJ4mJFWesxXDrEvDU,5026
216
- flwr/server/run_serverapp.py,sha256=_i0kBRrSzeR4-DDswysoWYertdAq7-LfrSAJ2n-GB8Q,10530
220
+ flwr/server/run_serverapp.py,sha256=QAeNzOpZPgHQqhCu2glwMSAE-TSu5Z0IQvldNETKA3w,10497
217
221
  flwr/server/server.py,sha256=1ZsFEptmAV-L2vP2etNC9Ed5CLSxpuKzUFkAPQ4l5Xc,17893
218
222
  flwr/server/server_app.py,sha256=RsgS6PRS5Z74cMUAHzsm8r3LWddwn00MjRs6rlacHt8,6297
219
223
  flwr/server/server_config.py,sha256=CZaHVAsMvGLjpWVcLPkiYxgJN4xfIyAiUrCI3fETKY4,1349
220
224
  flwr/server/serverapp/__init__.py,sha256=L0K-94UDdTyEZ8LDtYybGIIIv3HW6AhSVjXMUfYJQnQ,800
221
- flwr/server/serverapp/app.py,sha256=4c_aoB8v8qIr5_IQCg4PocCSiTt7Nsf0wYPNwUymUuo,4485
225
+ flwr/server/serverapp/app.py,sha256=bCCfNmUYME1NQGcX8mNsTiI6WTFNHeXDJ7vHx4nmXtE,8979
222
226
  flwr/server/serverapp_components.py,sha256=-IV_CitOfrJclJj2jNdbN1Q65PyFmtKtrTIg1hc6WQw,2118
223
227
  flwr/server/strategy/__init__.py,sha256=tQer2SwjDnvgFFuJMZM-S01Z615N5XK6MaCvpm4BMU0,2836
224
228
  flwr/server/strategy/aggregate.py,sha256=iFZ8lp7PV_a2m9kywV-FK0iM33ofxavOs5TIaEQY8nU,13961
@@ -247,7 +251,7 @@ flwr/server/strategy/strategy.py,sha256=cXapkD5uDrt5C-RbmWDn9FLoap3Q41i7GKvbmfbC
247
251
  flwr/server/superlink/__init__.py,sha256=8tHYCfodUlRD8PCP9fHgvu8cz5N31A2QoRVL0jDJ15E,707
248
252
  flwr/server/superlink/driver/__init__.py,sha256=_JaRW-FdyikHc7souUrnk3mwTGViraEJCeUBY_M_ocs,712
249
253
  flwr/server/superlink/driver/driver_grpc.py,sha256=melAgaV37Y0B9bZe5bRWQOobItZZ9DIzlcbVE8B01wo,2060
250
- flwr/server/superlink/driver/driver_servicer.py,sha256=JDkUcj1HDtjyxupsXDKw9BErJcngb-V87VLKQw3gMjI,9672
254
+ flwr/server/superlink/driver/driver_servicer.py,sha256=n2De3kPaUwR9rFycWbpCp4mQILLshCNu9pUZW80_Ezc,10534
251
255
  flwr/server/superlink/ffs/__init__.py,sha256=FAY-zShcfPmOxosok2QyT6hTNMNctG8cH9s_nIl8jkI,840
252
256
  flwr/server/superlink/ffs/disk_ffs.py,sha256=yCN6CCzegnJIOaHr5nIu49wZQa4g5BByiSKshz50RKU,3296
253
257
  flwr/server/superlink/ffs/ffs.py,sha256=qLI1UfosJugu2BKOJWqHIhafTm-YiuKqGf3OGWPH0NM,2395
@@ -273,10 +277,10 @@ flwr/server/superlink/fleet/vce/backend/backend.py,sha256=LBAQxnbfPAphVOVIvYMj0Q
273
277
  flwr/server/superlink/fleet/vce/backend/raybackend.py,sha256=7kB3re3mR53b7E6L6DPSioTSKD3YGtS3uJsPD7Hn2Fw,7155
274
278
  flwr/server/superlink/fleet/vce/vce_api.py,sha256=VL6e_Jwf4uxA-X1EelxJZMv6Eji-_p2J9D0MdHG10a4,13029
275
279
  flwr/server/superlink/linkstate/__init__.py,sha256=v-2JyJlCB3qyhMNwMjmcNVOq4rkooqFU0LHH8Zo1jls,1064
276
- flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=guqspi2WYyAXZKIxXCApuJZsuraNEVvb7aredtlXzRw,19327
277
- flwr/server/superlink/linkstate/linkstate.py,sha256=A0LCOH0xpq9_mTPrO1LB0MDWKhfUcOSnkKeC3-AeFHU,10256
280
+ flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=zsolNnK3LPkk_b00hnA9kSmnQ71hS_BPpc7s7uG_tps,20599
281
+ flwr/server/superlink/linkstate/linkstate.py,sha256=fBaIBlQAc0oBu_AWSXlMmHAUHJ2YF1I79MS9wq7HvCs,11428
278
282
  flwr/server/superlink/linkstate/linkstate_factory.py,sha256=ISSMjDlwuN7swxjOeYlTNpI_kuZ8PGkMcJnf1dbhUSE,2069
279
- flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=JhP6DtM0xBYtT0B0b1lwy96fY6i_C_Zm6Iq_t3VVQ5o,41245
283
+ flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=Yda1uPiRkEmH7HDNwVtQnpzVjDAkGCJePutkjeyYyT4,43188
280
284
  flwr/server/superlink/linkstate/utils.py,sha256=ukrMlSv0mNFd0YSpyPDpq_ND90SBkwuKgw3FFux3lqs,6914
281
285
  flwr/server/typing.py,sha256=5kaRLZuxTEse9A0g7aVna2VhYxU3wTq1f3d3mtw7kXs,1019
282
286
  flwr/server/utils/__init__.py,sha256=pltsPHJoXmUIr3utjwwYxu7_ZAGy5u4MVHzv9iA5Un8,908
@@ -294,16 +298,16 @@ flwr/simulation/ray_transport/__init__.py,sha256=wzcEEwUUlulnXsg6raCA1nGpP3LlAQD
294
298
  flwr/simulation/ray_transport/ray_actor.py,sha256=9-XBguAm5IFqm2ddPFsQtnuuFN6lzqdb00SnCxGUGBo,18996
295
299
  flwr/simulation/ray_transport/ray_client_proxy.py,sha256=2vjOKoom3B74C6XU-jC3N6DwYmsLdB-lmkHZ_Xrv96o,7367
296
300
  flwr/simulation/ray_transport/utils.py,sha256=TYdtfg1P9VfTdLMOJlifInGpxWHYs9UfUqIv2wfkRLA,2392
297
- flwr/simulation/run_simulation.py,sha256=nVLoP5rzH3bmZQ-pW9Nka2m0M1pFIEFODtIY7nHY0jQ,23412
301
+ flwr/simulation/run_simulation.py,sha256=3n1nSik8tTC6LCYVZesNkHuXDQ1Ea4unTnNEOC5rdAc,23436
298
302
  flwr/superexec/__init__.py,sha256=fcj366jh4RFby_vDwLroU4kepzqbnJgseZD_jUr_Mko,715
299
303
  flwr/superexec/app.py,sha256=Tt3GonnTwHrMmicwx9XaP-crP78-bf4DUWl-N5cG6zY,1841
300
- flwr/superexec/deployment.py,sha256=3uAauE8mI4bHwVF4_Rp26mXy18QnnIRlQD_yDo_Xs00,6780
304
+ flwr/superexec/deployment.py,sha256=jWEA8lnTYpOf8EHMzmoF9x6I_qh_gyJGQCVxk-DJshY,6401
301
305
  flwr/superexec/exec_grpc.py,sha256=OuhBAk7hiky9rjGceinLGIXqchtzGPQThZnwyYv6Ei0,2241
302
- flwr/superexec/exec_servicer.py,sha256=9MdFODQkLK_942XwaqwwIi1OP0Tiv3Mh7smj4mbreBE,5124
303
- flwr/superexec/executor.py,sha256=125FvdpjT_awBCREm_YkLMg0YgToarVg7Y3wPt5tXQA,3126
304
- flwr/superexec/simulation.py,sha256=PGADPXcfFVOss4uwPvFq_6vrIlkxezHppnBPAYWUBuU,7739
305
- flwr_nightly-1.13.0.dev20241028.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
306
- flwr_nightly-1.13.0.dev20241028.dist-info/METADATA,sha256=WXI84xjpiOMmUBA16dNB8_CIZybwX9HBfTFdisf91Dw,15618
307
- flwr_nightly-1.13.0.dev20241028.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
308
- flwr_nightly-1.13.0.dev20241028.dist-info/entry_points.txt,sha256=FxJQ96pmcNF2OvkTH6XF-Ip2PNrHvykjArkvkjQC7Mk,486
309
- flwr_nightly-1.13.0.dev20241028.dist-info/RECORD,,
306
+ flwr/superexec/exec_servicer.py,sha256=6dUCijBYhrntZeQj82q2kVOUNFu_tsFOwT5HkkLYn9Q,3927
307
+ flwr/superexec/executor.py,sha256=QA2_hQJxmN3zc75oEkDs-zkWAHesz59jE0P5lem-5VU,3073
308
+ flwr/superexec/simulation.py,sha256=Ny3MJnNlgzW4K3NbgsgDM0LKKcoCd_q3LqNqb0GhWLI,7640
309
+ flwr_nightly-1.13.0.dev20241030.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
310
+ flwr_nightly-1.13.0.dev20241030.dist-info/METADATA,sha256=Uz_4aLDl_yW5l5At_04N_oqhAid1FC9yx7sxME_0uLY,15618
311
+ flwr_nightly-1.13.0.dev20241030.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
312
+ flwr_nightly-1.13.0.dev20241030.dist-info/entry_points.txt,sha256=FxJQ96pmcNF2OvkTH6XF-Ip2PNrHvykjArkvkjQC7Mk,486
313
+ flwr_nightly-1.13.0.dev20241030.dist-info/RECORD,,