flwr-nightly 1.13.0.dev20241019__py3-none-any.whl → 1.13.0.dev20241106__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 (81) hide show
  1. flwr/cli/build.py +2 -2
  2. flwr/cli/config_utils.py +97 -0
  3. flwr/cli/log.py +63 -97
  4. flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +1 -1
  5. flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +1 -0
  6. flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +1 -1
  7. flwr/cli/run/run.py +18 -83
  8. flwr/client/app.py +13 -14
  9. flwr/client/clientapp/app.py +1 -2
  10. flwr/client/{node_state.py → run_info_store.py} +4 -3
  11. flwr/client/supernode/app.py +6 -8
  12. flwr/common/constant.py +39 -4
  13. flwr/common/context.py +9 -4
  14. flwr/common/date.py +3 -3
  15. flwr/common/logger.py +103 -0
  16. flwr/common/serde.py +24 -0
  17. flwr/common/telemetry.py +0 -6
  18. flwr/common/typing.py +9 -0
  19. flwr/proto/exec_pb2.py +6 -6
  20. flwr/proto/exec_pb2.pyi +8 -2
  21. flwr/proto/log_pb2.py +29 -0
  22. flwr/proto/log_pb2.pyi +39 -0
  23. flwr/proto/log_pb2_grpc.py +4 -0
  24. flwr/proto/log_pb2_grpc.pyi +4 -0
  25. flwr/proto/message_pb2.py +8 -8
  26. flwr/proto/message_pb2.pyi +4 -1
  27. flwr/proto/serverappio_pb2.py +52 -0
  28. flwr/proto/{driver_pb2.pyi → serverappio_pb2.pyi} +54 -0
  29. flwr/proto/serverappio_pb2_grpc.py +376 -0
  30. flwr/proto/serverappio_pb2_grpc.pyi +147 -0
  31. flwr/proto/simulationio_pb2.py +38 -0
  32. flwr/proto/simulationio_pb2.pyi +65 -0
  33. flwr/proto/simulationio_pb2_grpc.py +171 -0
  34. flwr/proto/simulationio_pb2_grpc.pyi +68 -0
  35. flwr/server/app.py +247 -105
  36. flwr/server/driver/driver.py +15 -1
  37. flwr/server/driver/grpc_driver.py +26 -33
  38. flwr/server/driver/inmemory_driver.py +6 -14
  39. flwr/server/run_serverapp.py +29 -23
  40. flwr/server/{superlink/state → serverapp}/__init__.py +3 -9
  41. flwr/server/serverapp/app.py +270 -0
  42. flwr/server/strategy/fedadam.py +11 -1
  43. flwr/server/superlink/driver/__init__.py +1 -1
  44. flwr/server/superlink/driver/{driver_grpc.py → serverappio_grpc.py} +19 -16
  45. flwr/server/superlink/driver/{driver_servicer.py → serverappio_servicer.py} +125 -39
  46. flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +4 -2
  47. flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +2 -2
  48. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +4 -2
  49. flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +2 -2
  50. flwr/server/superlink/fleet/message_handler/message_handler.py +7 -7
  51. flwr/server/superlink/fleet/rest_rere/rest_api.py +7 -7
  52. flwr/server/superlink/fleet/vce/vce_api.py +23 -23
  53. flwr/server/superlink/linkstate/__init__.py +28 -0
  54. flwr/server/superlink/{state/in_memory_state.py → linkstate/in_memory_linkstate.py} +180 -21
  55. flwr/server/superlink/{state/state.py → linkstate/linkstate.py} +144 -15
  56. flwr/server/superlink/{state/state_factory.py → linkstate/linkstate_factory.py} +9 -9
  57. flwr/server/superlink/{state/sqlite_state.py → linkstate/sqlite_linkstate.py} +300 -50
  58. flwr/server/superlink/{state → linkstate}/utils.py +84 -2
  59. flwr/server/superlink/simulation/__init__.py +15 -0
  60. flwr/server/superlink/simulation/simulationio_grpc.py +65 -0
  61. flwr/server/superlink/simulation/simulationio_servicer.py +132 -0
  62. flwr/simulation/__init__.py +2 -0
  63. flwr/simulation/app.py +1 -1
  64. flwr/simulation/ray_transport/ray_client_proxy.py +2 -2
  65. flwr/simulation/run_simulation.py +57 -131
  66. flwr/simulation/simulationio_connection.py +86 -0
  67. flwr/superexec/app.py +6 -134
  68. flwr/superexec/deployment.py +60 -65
  69. flwr/superexec/exec_grpc.py +15 -8
  70. flwr/superexec/exec_servicer.py +34 -63
  71. flwr/superexec/executor.py +22 -4
  72. flwr/superexec/simulation.py +13 -8
  73. {flwr_nightly-1.13.0.dev20241019.dist-info → flwr_nightly-1.13.0.dev20241106.dist-info}/METADATA +1 -1
  74. {flwr_nightly-1.13.0.dev20241019.dist-info → flwr_nightly-1.13.0.dev20241106.dist-info}/RECORD +77 -64
  75. {flwr_nightly-1.13.0.dev20241019.dist-info → flwr_nightly-1.13.0.dev20241106.dist-info}/entry_points.txt +1 -0
  76. flwr/client/node_state_tests.py +0 -66
  77. flwr/proto/driver_pb2.py +0 -42
  78. flwr/proto/driver_pb2_grpc.py +0 -239
  79. flwr/proto/driver_pb2_grpc.pyi +0 -94
  80. {flwr_nightly-1.13.0.dev20241019.dist-info → flwr_nightly-1.13.0.dev20241106.dist-info}/LICENSE +0 -0
  81. {flwr_nightly-1.13.0.dev20241019.dist-info → flwr_nightly-1.13.0.dev20241106.dist-info}/WHEEL +0 -0
@@ -12,28 +12,30 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  # ==============================================================================
15
- """Abstract base class State."""
15
+ """Abstract base class LinkState."""
16
16
 
17
17
 
18
18
  import abc
19
19
  from typing import Optional
20
20
  from uuid import UUID
21
21
 
22
- from flwr.common.typing import Run, UserConfig
22
+ from flwr.common import Context
23
+ from flwr.common.record import ConfigsRecord
24
+ from flwr.common.typing import Run, RunStatus, UserConfig
23
25
  from flwr.proto.task_pb2 import TaskIns, TaskRes # pylint: disable=E0611
24
26
 
25
27
 
26
- class State(abc.ABC): # pylint: disable=R0904
27
- """Abstract State."""
28
+ class LinkState(abc.ABC): # pylint: disable=R0904
29
+ """Abstract LinkState."""
28
30
 
29
31
  @abc.abstractmethod
30
32
  def store_task_ins(self, task_ins: TaskIns) -> Optional[UUID]:
31
33
  """Store one TaskIns.
32
34
 
33
- Usually, the Driver API calls this to schedule instructions.
35
+ Usually, the ServerAppIo API calls this to schedule instructions.
34
36
 
35
- Stores the value of the `task_ins` in the state and, if successful, returns the
36
- `task_id` (UUID) of the `task_ins`. If, for any reason,
37
+ Stores the value of the `task_ins` in the link state and, if successful,
38
+ returns the `task_id` (UUID) of the `task_ins`. If, for any reason,
37
39
  storing the `task_ins` fails, `None` is returned.
38
40
 
39
41
  Constraints
@@ -101,8 +103,8 @@ class State(abc.ABC): # pylint: disable=R0904
101
103
  def get_task_res(self, task_ids: set[UUID]) -> list[TaskRes]:
102
104
  """Get TaskRes for task_ids.
103
105
 
104
- Usually, the Driver API calls this method to get results for instructions it has
105
- previously scheduled.
106
+ Usually, the ServerAppIo API calls this method to get results for instructions
107
+ it has previously scheduled.
106
108
 
107
109
  Retrieves all TaskRes for the given `task_ids` and returns and empty list of
108
110
  none could be found.
@@ -130,11 +132,11 @@ class State(abc.ABC): # pylint: disable=R0904
130
132
  def create_node(
131
133
  self, ping_interval: float, public_key: Optional[bytes] = None
132
134
  ) -> int:
133
- """Create, store in state, and return `node_id`."""
135
+ """Create, store in the link state, and return `node_id`."""
134
136
 
135
137
  @abc.abstractmethod
136
138
  def delete_node(self, node_id: int, public_key: Optional[bytes] = None) -> None:
137
- """Remove `node_id` from state."""
139
+ """Remove `node_id` from the link state."""
138
140
 
139
141
  @abc.abstractmethod
140
142
  def get_nodes(self, run_id: int) -> set[int]:
@@ -151,12 +153,13 @@ class State(abc.ABC): # pylint: disable=R0904
151
153
  """Retrieve stored `node_id` filtered by `node_public_keys`."""
152
154
 
153
155
  @abc.abstractmethod
154
- def create_run(
156
+ def create_run( # pylint: disable=too-many-arguments,too-many-positional-arguments
155
157
  self,
156
158
  fab_id: Optional[str],
157
159
  fab_version: Optional[str],
158
160
  fab_hash: Optional[str],
159
161
  override_config: UserConfig,
162
+ federation_options: ConfigsRecord,
160
163
  ) -> int:
161
164
  """Create a new run for the specified `fab_hash`."""
162
165
 
@@ -178,11 +181,74 @@ class State(abc.ABC): # pylint: disable=R0904
178
181
  - `fab_version`: The version of the FAB used in the specified run.
179
182
  """
180
183
 
184
+ @abc.abstractmethod
185
+ def get_run_status(self, run_ids: set[int]) -> dict[int, RunStatus]:
186
+ """Retrieve the statuses for the specified runs.
187
+
188
+ Parameters
189
+ ----------
190
+ run_ids : set[int]
191
+ A set of run identifiers for which to retrieve statuses.
192
+
193
+ Returns
194
+ -------
195
+ dict[int, RunStatus]
196
+ A dictionary mapping each valid run ID to its corresponding status.
197
+
198
+ Notes
199
+ -----
200
+ Only valid run IDs that exist in the State will be included in the returned
201
+ dictionary. If a run ID is not found, it will be omitted from the result.
202
+ """
203
+
204
+ @abc.abstractmethod
205
+ def update_run_status(self, run_id: int, new_status: RunStatus) -> bool:
206
+ """Update the status of the run with the specified `run_id`.
207
+
208
+ Parameters
209
+ ----------
210
+ run_id : int
211
+ The identifier of the run.
212
+ new_status : RunStatus
213
+ The new status to be assigned to the run.
214
+
215
+ Returns
216
+ -------
217
+ bool
218
+ True if the status update is successful; False otherwise.
219
+ """
220
+
221
+ @abc.abstractmethod
222
+ def get_pending_run_id(self) -> Optional[int]:
223
+ """Get the `run_id` of a run with `Status.PENDING` status.
224
+
225
+ Returns
226
+ -------
227
+ Optional[int]
228
+ The `run_id` of a `Run` that is pending to be started; None if
229
+ there is no Run pending.
230
+ """
231
+
232
+ @abc.abstractmethod
233
+ def get_federation_options(self, run_id: int) -> Optional[ConfigsRecord]:
234
+ """Retrieve the federation options for the specified `run_id`.
235
+
236
+ Parameters
237
+ ----------
238
+ run_id : int
239
+ The identifier of the run.
240
+
241
+ Returns
242
+ -------
243
+ Optional[ConfigsRecord]
244
+ The federation options for the run if it exists; None otherwise.
245
+ """
246
+
181
247
  @abc.abstractmethod
182
248
  def store_server_private_public_key(
183
249
  self, private_key: bytes, public_key: bytes
184
250
  ) -> None:
185
- """Store `server_private_key` and `server_public_key` in state."""
251
+ """Store `server_private_key` and `server_public_key` in the link state."""
186
252
 
187
253
  @abc.abstractmethod
188
254
  def get_server_private_key(self) -> Optional[bytes]:
@@ -194,11 +260,11 @@ class State(abc.ABC): # pylint: disable=R0904
194
260
 
195
261
  @abc.abstractmethod
196
262
  def store_node_public_keys(self, public_keys: set[bytes]) -> None:
197
- """Store a set of `node_public_keys` in state."""
263
+ """Store a set of `node_public_keys` in the link state."""
198
264
 
199
265
  @abc.abstractmethod
200
266
  def store_node_public_key(self, public_key: bytes) -> None:
201
- """Store a `node_public_key` in state."""
267
+ """Store a `node_public_key` in the link state."""
202
268
 
203
269
  @abc.abstractmethod
204
270
  def get_node_public_keys(self) -> set[bytes]:
@@ -222,3 +288,66 @@ class State(abc.ABC): # pylint: disable=R0904
222
288
  is_acknowledged : bool
223
289
  True if the ping is successfully acknowledged; otherwise, False.
224
290
  """
291
+
292
+ @abc.abstractmethod
293
+ def get_serverapp_context(self, run_id: int) -> Optional[Context]:
294
+ """Get the context for the specified `run_id`.
295
+
296
+ Parameters
297
+ ----------
298
+ run_id : int
299
+ The identifier of the run for which to retrieve the context.
300
+
301
+ Returns
302
+ -------
303
+ Optional[Context]
304
+ The context associated with the specified `run_id`, or `None` if no context
305
+ exists for the given `run_id`.
306
+ """
307
+
308
+ @abc.abstractmethod
309
+ def set_serverapp_context(self, run_id: int, context: Context) -> None:
310
+ """Set the context for the specified `run_id`.
311
+
312
+ Parameters
313
+ ----------
314
+ run_id : int
315
+ The identifier of the run for which to set the context.
316
+ context : Context
317
+ The context to be associated with the specified `run_id`.
318
+ """
319
+
320
+ @abc.abstractmethod
321
+ def add_serverapp_log(self, run_id: int, log_message: str) -> None:
322
+ """Add a log entry to the ServerApp logs for the specified `run_id`.
323
+
324
+ Parameters
325
+ ----------
326
+ run_id : int
327
+ The identifier of the run for which to add a log entry.
328
+ log_message : str
329
+ The log entry to be added to the ServerApp logs.
330
+ """
331
+
332
+ @abc.abstractmethod
333
+ def get_serverapp_log(
334
+ self, run_id: int, after_timestamp: Optional[float]
335
+ ) -> tuple[str, float]:
336
+ """Get the ServerApp logs for the specified `run_id`.
337
+
338
+ Parameters
339
+ ----------
340
+ run_id : int
341
+ The identifier of the run for which to retrieve the ServerApp logs.
342
+
343
+ after_timestamp : Optional[float]
344
+ Retrieve logs after this timestamp. If set to `None`, retrieve all logs.
345
+
346
+ Returns
347
+ -------
348
+ tuple[str, float]
349
+ A tuple containing:
350
+ - The ServerApp logs associated with the specified `run_id`.
351
+ - The timestamp of the latest log entry in the returned logs.
352
+ Returns `0` if no logs are returned.
353
+ """
@@ -20,13 +20,13 @@ from typing import Optional
20
20
 
21
21
  from flwr.common.logger import log
22
22
 
23
- from .in_memory_state import InMemoryState
24
- from .sqlite_state import SqliteState
25
- from .state import State
23
+ from .in_memory_linkstate import InMemoryLinkState
24
+ from .linkstate import LinkState
25
+ from .sqlite_linkstate import SqliteLinkState
26
26
 
27
27
 
28
- class StateFactory:
29
- """Factory class that creates State instances.
28
+ class LinkStateFactory:
29
+ """Factory class that creates LinkState instances.
30
30
 
31
31
  Parameters
32
32
  ----------
@@ -39,19 +39,19 @@ class StateFactory:
39
39
 
40
40
  def __init__(self, database: str) -> None:
41
41
  self.database = database
42
- self.state_instance: Optional[State] = None
42
+ self.state_instance: Optional[LinkState] = None
43
43
 
44
- def state(self) -> State:
44
+ def state(self) -> LinkState:
45
45
  """Return a State instance and create it, if necessary."""
46
46
  # InMemoryState
47
47
  if self.database == ":flwr-in-memory-state:":
48
48
  if self.state_instance is None:
49
- self.state_instance = InMemoryState()
49
+ self.state_instance = InMemoryLinkState()
50
50
  log(DEBUG, "Using InMemoryState")
51
51
  return self.state_instance
52
52
 
53
53
  # SqliteState
54
- state = SqliteState(self.database)
54
+ state = SqliteLinkState(self.database)
55
55
  state.initialize()
56
56
  log(DEBUG, "Using SqliteState")
57
57
  return state