flwr-nightly 1.17.0.dev20250319__py3-none-any.whl → 1.17.0.dev20250320__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.
Files changed (50) hide show
  1. flwr/client/app.py +6 -4
  2. flwr/client/clientapp/app.py +2 -2
  3. flwr/client/grpc_client/connection.py +23 -20
  4. flwr/client/message_handler/message_handler.py +27 -27
  5. flwr/client/mod/centraldp_mods.py +7 -7
  6. flwr/client/mod/localdp_mod.py +4 -4
  7. flwr/client/mod/secure_aggregation/secaggplus_mod.py +5 -5
  8. flwr/client/run_info_store.py +2 -2
  9. flwr/common/__init__.py +2 -0
  10. flwr/common/context.py +4 -4
  11. flwr/common/message.py +269 -101
  12. flwr/common/record/__init__.py +2 -1
  13. flwr/common/record/configsrecord.py +2 -2
  14. flwr/common/record/metricsrecord.py +1 -1
  15. flwr/common/record/parametersrecord.py +1 -1
  16. flwr/common/record/{recordset.py → recorddict.py} +57 -17
  17. flwr/common/{recordset_compat.py → recorddict_compat.py} +105 -105
  18. flwr/common/serde.py +33 -37
  19. flwr/proto/exec_pb2.py +32 -32
  20. flwr/proto/exec_pb2.pyi +3 -3
  21. flwr/proto/message_pb2.py +12 -12
  22. flwr/proto/message_pb2.pyi +9 -9
  23. flwr/proto/recorddict_pb2.py +70 -0
  24. flwr/proto/{recordset_pb2.pyi → recorddict_pb2.pyi} +2 -2
  25. flwr/proto/run_pb2.py +32 -32
  26. flwr/proto/run_pb2.pyi +3 -3
  27. flwr/server/compat/grid_client_proxy.py +30 -30
  28. flwr/server/grid/grid.py +3 -3
  29. flwr/server/grid/grpc_grid.py +15 -23
  30. flwr/server/grid/inmemory_grid.py +14 -20
  31. flwr/server/superlink/fleet/vce/vce_api.py +1 -3
  32. flwr/server/superlink/linkstate/in_memory_linkstate.py +1 -1
  33. flwr/server/superlink/linkstate/sqlite_linkstate.py +14 -18
  34. flwr/server/superlink/linkstate/utils.py +10 -7
  35. flwr/server/superlink/serverappio/serverappio_servicer.py +1 -1
  36. flwr/server/utils/validator.py +4 -4
  37. flwr/server/workflow/default_workflows.py +7 -7
  38. flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +8 -8
  39. flwr/simulation/ray_transport/ray_client_proxy.py +34 -32
  40. flwr/simulation/run_simulation.py +3 -3
  41. flwr/superexec/deployment.py +2 -2
  42. flwr/superexec/simulation.py +2 -2
  43. {flwr_nightly-1.17.0.dev20250319.dist-info → flwr_nightly-1.17.0.dev20250320.dist-info}/METADATA +1 -1
  44. {flwr_nightly-1.17.0.dev20250319.dist-info → flwr_nightly-1.17.0.dev20250320.dist-info}/RECORD +49 -49
  45. flwr/proto/recordset_pb2.py +0 -70
  46. /flwr/proto/{recordset_pb2_grpc.py → recorddict_pb2_grpc.py} +0 -0
  47. /flwr/proto/{recordset_pb2_grpc.pyi → recorddict_pb2_grpc.pyi} +0 -0
  48. {flwr_nightly-1.17.0.dev20250319.dist-info → flwr_nightly-1.17.0.dev20250320.dist-info}/LICENSE +0 -0
  49. {flwr_nightly-1.17.0.dev20250319.dist-info → flwr_nightly-1.17.0.dev20250320.dist-info}/WHEEL +0 -0
  50. {flwr_nightly-1.17.0.dev20250319.dist-info → flwr_nightly-1.17.0.dev20250320.dist-info}/entry_points.txt +0 -0
flwr/common/message.py CHANGED
@@ -17,19 +17,34 @@
17
17
 
18
18
  from __future__ import annotations
19
19
 
20
- import time
21
20
  from logging import WARNING
22
- from typing import Optional, cast
21
+ from typing import Any, Optional, cast, overload
22
+
23
+ from flwr.common.date import now
24
+ from flwr.common.logger import warn_deprecated_feature
23
25
 
24
26
  from .constant import MESSAGE_TTL_TOLERANCE, MessageType, MessageTypeLegacy
25
27
  from .logger import log
26
- from .record import RecordSet
28
+ from .record import RecordDict
27
29
 
28
30
  DEFAULT_TTL = 43200 # This is 12 hours
31
+ MESSAGE_INIT_ERROR_MESSAGE = (
32
+ "Invalid arguments for Message. Expected one of the documented "
33
+ "signatures: Message(content: RecordDict, dst_node_id: int, message_type: str,"
34
+ " *, [ttl: float, group_id: str]) or Message(content: RecordDict | error: Error,"
35
+ " *, reply_to: Message, [ttl: float])."
36
+ )
37
+
38
+
39
+ class MessageInitializationError(TypeError):
40
+ """Error raised when initializing a message with invalid arguments."""
41
+
42
+ def __init__(self, message: str | None = None) -> None:
43
+ super().__init__(message or MESSAGE_INIT_ERROR_MESSAGE)
29
44
 
30
45
 
31
46
  class Metadata: # pylint: disable=too-many-instance-attributes
32
- """A dataclass holding metadata associated with the current message.
47
+ """The class representing metadata associated with the current message.
33
48
 
34
49
  Parameters
35
50
  ----------
@@ -41,11 +56,13 @@ class Metadata: # pylint: disable=too-many-instance-attributes
41
56
  An identifier for the node sending this message.
42
57
  dst_node_id : int
43
58
  An identifier for the node receiving this message.
44
- reply_to_message : str
45
- An identifier for the message this message replies to.
59
+ reply_to_message_id : str
60
+ An identifier for the message to which this message is a reply.
46
61
  group_id : str
47
62
  An identifier for grouping messages. In some settings,
48
63
  this is used as the FL round.
64
+ created_at : float
65
+ Unix timestamp when the message was created.
49
66
  ttl : float
50
67
  Time-to-live for this message in seconds.
51
68
  message_type : str
@@ -59,8 +76,9 @@ class Metadata: # pylint: disable=too-many-instance-attributes
59
76
  message_id: str,
60
77
  src_node_id: int,
61
78
  dst_node_id: int,
62
- reply_to_message: str,
79
+ reply_to_message_id: str,
63
80
  group_id: str,
81
+ created_at: float,
64
82
  ttl: float,
65
83
  message_type: str,
66
84
  ) -> None:
@@ -69,8 +87,9 @@ class Metadata: # pylint: disable=too-many-instance-attributes
69
87
  "_message_id": message_id,
70
88
  "_src_node_id": src_node_id,
71
89
  "_dst_node_id": dst_node_id,
72
- "_reply_to_message": reply_to_message,
90
+ "_reply_to_message_id": reply_to_message_id,
73
91
  "_group_id": group_id,
92
+ "_created_at": created_at,
74
93
  "_ttl": ttl,
75
94
  "_message_type": message_type,
76
95
  }
@@ -93,9 +112,9 @@ class Metadata: # pylint: disable=too-many-instance-attributes
93
112
  return cast(int, self.__dict__["_src_node_id"])
94
113
 
95
114
  @property
96
- def reply_to_message(self) -> str:
97
- """An identifier for the message this message replies to."""
98
- return cast(str, self.__dict__["_reply_to_message"])
115
+ def reply_to_message_id(self) -> str:
116
+ """An identifier for the message to which this message is a reply."""
117
+ return cast(str, self.__dict__["_reply_to_message_id"])
99
118
 
100
119
  @property
101
120
  def dst_node_id(self) -> int:
@@ -124,7 +143,7 @@ class Metadata: # pylint: disable=too-many-instance-attributes
124
143
 
125
144
  @created_at.setter
126
145
  def created_at(self, value: float) -> None:
127
- """Set creation timestamp for this message."""
146
+ """Set creation timestamp of this message."""
128
147
  self.__dict__["_created_at"] = value
129
148
 
130
149
  @property
@@ -181,7 +200,7 @@ class Metadata: # pylint: disable=too-many-instance-attributes
181
200
 
182
201
 
183
202
  class Error:
184
- """A dataclass that stores information about an error that occurred.
203
+ """The class storing information about an error that occurred.
185
204
 
186
205
  Parameters
187
206
  ----------
@@ -221,31 +240,148 @@ class Error:
221
240
 
222
241
 
223
242
  class Message:
224
- """State of your application from the viewpoint of the entity using it.
243
+ """Represents a message exchanged between ClientApp and ServerApp.
244
+
245
+ This class encapsulates the payload and metadata necessary for communication
246
+ between a ClientApp and a ServerApp.
225
247
 
226
248
  Parameters
227
249
  ----------
228
- metadata : Metadata
229
- A dataclass including information about the message to be executed.
230
- content : Optional[RecordSet]
250
+ content : Optional[RecordDict] (default: None)
231
251
  Holds records either sent by another entity (e.g. sent by the server-side
232
252
  logic to a client, or vice-versa) or that will be sent to it.
233
- error : Optional[Error]
253
+ error : Optional[Error] (default: None)
234
254
  A dataclass that captures information about an error that took place
235
255
  when processing another message.
256
+ dst_node_id : Optional[int] (default: None)
257
+ An identifier for the node receiving this message.
258
+ message_type : Optional[str] (default: None)
259
+ A string that encodes the action to be executed on
260
+ the receiving end.
261
+ ttl : Optional[float] (default: None)
262
+ Time-to-live (TTL) for this message in seconds. If `None` (default),
263
+ the TTL is set to 43,200 seconds (12 hours).
264
+ group_id : Optional[str] (default: None)
265
+ An identifier for grouping messages. In some settings, this is used as
266
+ the FL round.
267
+ reply_to : Optional[Message] (default: None)
268
+ The instruction message to which this message is a reply. This message does
269
+ not retain the original message's content but derives its metadata from it.
236
270
  """
237
271
 
238
- def __init__(
272
+ @overload
273
+ def __init__( # pylint: disable=too-many-arguments # noqa: E704
239
274
  self,
240
- metadata: Metadata,
241
- content: RecordSet | None = None,
275
+ content: RecordDict,
276
+ dst_node_id: int,
277
+ message_type: str,
278
+ *,
279
+ ttl: float | None = None,
280
+ group_id: str | None = None,
281
+ ) -> None: ...
282
+
283
+ @overload
284
+ def __init__( # noqa: E704
285
+ self, content: RecordDict, *, reply_to: Message, ttl: float | None = None
286
+ ) -> None: ...
287
+
288
+ @overload
289
+ def __init__( # noqa: E704
290
+ self, error: Error, *, reply_to: Message, ttl: float | None = None
291
+ ) -> None: ...
292
+
293
+ def __init__( # pylint: disable=too-many-arguments
294
+ self,
295
+ *args: Any,
296
+ dst_node_id: int | None = None,
297
+ message_type: str | None = None,
298
+ content: RecordDict | None = None,
242
299
  error: Error | None = None,
300
+ ttl: float | None = None,
301
+ group_id: str | None = None,
302
+ reply_to: Message | None = None,
303
+ metadata: Metadata | None = None,
243
304
  ) -> None:
244
- if not (content is None) ^ (error is None):
245
- raise ValueError("Either `content` or `error` must be set, but not both.")
305
+ # Set positional arguments
306
+ content, error, dst_node_id, message_type = _extract_positional_args(
307
+ *args,
308
+ content=content,
309
+ error=error,
310
+ dst_node_id=dst_node_id,
311
+ message_type=message_type,
312
+ )
313
+ _check_arg_types(
314
+ dst_node_id=dst_node_id,
315
+ message_type=message_type,
316
+ content=content,
317
+ error=error,
318
+ ttl=ttl,
319
+ group_id=group_id,
320
+ reply_to=reply_to,
321
+ metadata=metadata,
322
+ )
323
+
324
+ # Set metadata directly (This is for internal use only)
325
+ if metadata is not None:
326
+ # When metadata is set, all other arguments must be None,
327
+ # except `content`, `error`, or `content_or_error`
328
+ if any(
329
+ x is not None
330
+ for x in [dst_node_id, message_type, ttl, group_id, reply_to]
331
+ ):
332
+ raise MessageInitializationError(
333
+ f"Invalid arguments for {Message.__qualname__}. "
334
+ "Expected only `metadata` to be set when creating a message "
335
+ "with provided metadata."
336
+ )
337
+
338
+ # Create metadata for an instruction message
339
+ elif reply_to is None:
340
+ # Check arguments
341
+ # `content`, `dst_node_id` and `message_type` must be set
342
+ if not (
343
+ isinstance(content, RecordDict)
344
+ and isinstance(dst_node_id, int)
345
+ and isinstance(message_type, str)
346
+ ):
347
+ raise MessageInitializationError()
348
+
349
+ # Set metadata
350
+ metadata = Metadata(
351
+ run_id=0, # Will be set before pushed
352
+ message_id="", # Will be set by the SuperLink
353
+ src_node_id=0, # Will be set before pushed
354
+ dst_node_id=dst_node_id,
355
+ # Instruction messages do not reply to any message
356
+ reply_to_message_id="",
357
+ group_id=group_id or "",
358
+ created_at=now().timestamp(),
359
+ ttl=ttl or DEFAULT_TTL,
360
+ message_type=message_type,
361
+ )
362
+
363
+ # Create metadata for a reply message
364
+ else:
365
+ # Check arguments
366
+ # `dst_node_id`, `message_type` and `group_id` must not be set
367
+ if any(x is not None for x in [dst_node_id, message_type, group_id]):
368
+ raise MessageInitializationError()
369
+
370
+ # Set metadata
371
+ current = now().timestamp()
372
+ metadata = Metadata(
373
+ run_id=reply_to.metadata.run_id,
374
+ message_id="", # Will be set by the SuperLink
375
+ src_node_id=reply_to.metadata.dst_node_id,
376
+ dst_node_id=reply_to.metadata.src_node_id,
377
+ reply_to_message_id=reply_to.metadata.message_id,
378
+ group_id=reply_to.metadata.group_id,
379
+ created_at=current,
380
+ ttl=_limit_reply_ttl(current, ttl, reply_to),
381
+ message_type=reply_to.metadata.message_type,
382
+ )
246
383
 
247
- metadata.created_at = time.time() # Set the message creation timestamp
248
- metadata.delivered_at = ""
384
+ metadata.delivered_at = "" # Backward compatibility
249
385
  var_dict = {
250
386
  "_metadata": metadata,
251
387
  "_content": content,
@@ -259,17 +395,17 @@ class Message:
259
395
  return cast(Metadata, self.__dict__["_metadata"])
260
396
 
261
397
  @property
262
- def content(self) -> RecordSet:
398
+ def content(self) -> RecordDict:
263
399
  """The content of this message."""
264
400
  if self.__dict__["_content"] is None:
265
401
  raise ValueError(
266
402
  "Message content is None. Use <message>.has_content() "
267
403
  "to check if a message has content."
268
404
  )
269
- return cast(RecordSet, self.__dict__["_content"])
405
+ return cast(RecordDict, self.__dict__["_content"])
270
406
 
271
407
  @content.setter
272
- def content(self, value: RecordSet) -> None:
408
+ def content(self, value: RecordDict) -> None:
273
409
  """Set content."""
274
410
  if self.__dict__["_error"] is None:
275
411
  self.__dict__["_content"] = value
@@ -320,33 +456,25 @@ class Message:
320
456
  message : Message
321
457
  A Message containing only the relevant error and metadata.
322
458
  """
323
- # If no TTL passed, use default for message creation (will update after
324
- # message creation)
325
- ttl_ = DEFAULT_TTL if ttl is None else ttl
326
- # Create reply with error
327
- message = Message(metadata=_create_reply_metadata(self, ttl_), error=error)
328
-
329
- if ttl is None:
330
- # Set TTL equal to the remaining time for the received message to expire
331
- ttl = self.metadata.ttl - (
332
- message.metadata.created_at - self.metadata.created_at
333
- )
334
- message.metadata.ttl = ttl
335
-
336
- self._limit_message_res_ttl(message)
337
-
338
- return message
459
+ warn_deprecated_feature(
460
+ "`Message.create_error_reply` is deprecated. "
461
+ "Instead of calling `some_message.create_error_reply(some_error, ttl=...)`"
462
+ ", use `Message(some_error, reply_to=some_message, ttl=...)`."
463
+ )
464
+ if ttl is not None:
465
+ return Message(error, reply_to=self, ttl=ttl)
466
+ return Message(error, reply_to=self)
339
467
 
340
- def create_reply(self, content: RecordSet, ttl: float | None = None) -> Message:
468
+ def create_reply(self, content: RecordDict, ttl: float | None = None) -> Message:
341
469
  """Create a reply to this message with specified content and TTL.
342
470
 
343
471
  The method generates a new `Message` as a reply to this message.
344
472
  It inherits 'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from
345
- this message and sets 'reply_to_message' to the ID of this message.
473
+ this message and sets 'reply_to_message_id' to the ID of this message.
346
474
 
347
475
  Parameters
348
476
  ----------
349
- content : RecordSet
477
+ content : RecordDict
350
478
  The content for the reply message.
351
479
  ttl : Optional[float] (default: None)
352
480
  Time-to-live for this message in seconds. If unset, it will be set based
@@ -360,25 +488,14 @@ class Message:
360
488
  Message
361
489
  A new `Message` instance representing the reply.
362
490
  """
363
- # If no TTL passed, use default for message creation (will update after
364
- # message creation)
365
- ttl_ = DEFAULT_TTL if ttl is None else ttl
366
-
367
- message = Message(
368
- metadata=_create_reply_metadata(self, ttl_),
369
- content=content,
491
+ warn_deprecated_feature(
492
+ "`Message.create_reply` is deprecated. "
493
+ "Instead of calling `some_message.create_reply(some_content, ttl=...)`"
494
+ ", use `Message(some_content, reply_to=some_message, ttl=...)`."
370
495
  )
371
-
372
- if ttl is None:
373
- # Set TTL equal to the remaining time for the received message to expire
374
- ttl = self.metadata.ttl - (
375
- message.metadata.created_at - self.metadata.created_at
376
- )
377
- message.metadata.ttl = ttl
378
-
379
- self._limit_message_res_ttl(message)
380
-
381
- return message
496
+ if ttl is not None:
497
+ return Message(content, reply_to=self, ttl=ttl)
498
+ return Message(content, reply_to=self)
382
499
 
383
500
  def __repr__(self) -> str:
384
501
  """Return a string representation of this instance."""
@@ -391,44 +508,95 @@ class Message:
391
508
  )
392
509
  return f"{self.__class__.__qualname__}({view})"
393
510
 
394
- def _limit_message_res_ttl(self, message: Message) -> None:
395
- """Limit the TTL of the provided Message to not exceed the expiration time of
396
- this Message it replies to.
397
511
 
398
- Parameters
399
- ----------
400
- message : Message
401
- The reply Message to limit the TTL for.
402
- """
403
- # Calculate the maximum allowed TTL
404
- max_allowed_ttl = (
405
- self.metadata.created_at + self.metadata.ttl - message.metadata.created_at
512
+ def make_message(
513
+ metadata: Metadata, content: RecordDict | None = None, error: Error | None = None
514
+ ) -> Message:
515
+ """Create a message with the provided metadata, content, and error."""
516
+ return Message(metadata=metadata, content=content, error=error) # type: ignore
517
+
518
+
519
+ def _limit_reply_ttl(
520
+ current: float, reply_ttl: float | None, reply_to: Message
521
+ ) -> float:
522
+ """Limit the TTL of a reply message such that it does exceed the expiration time of
523
+ the message it replies to."""
524
+ # Calculate the maximum allowed TTL
525
+ max_allowed_ttl = reply_to.metadata.created_at + reply_to.metadata.ttl - current
526
+
527
+ if reply_ttl is not None and reply_ttl - max_allowed_ttl > MESSAGE_TTL_TOLERANCE:
528
+ log(
529
+ WARNING,
530
+ "The reply TTL of %.2f seconds exceeded the "
531
+ "allowed maximum of %.2f seconds. "
532
+ "The TTL has been updated to the allowed maximum.",
533
+ reply_ttl,
534
+ max_allowed_ttl,
406
535
  )
407
-
408
- if message.metadata.ttl - max_allowed_ttl > MESSAGE_TTL_TOLERANCE:
409
- log(
410
- WARNING,
411
- "The reply TTL of %.2f seconds exceeded the "
412
- "allowed maximum of %.2f seconds. "
413
- "The TTL has been updated to the allowed maximum.",
414
- message.metadata.ttl,
415
- max_allowed_ttl,
416
- )
417
- message.metadata.ttl = max_allowed_ttl
418
-
419
-
420
- def _create_reply_metadata(msg: Message, ttl: float) -> Metadata:
421
- """Construct metadata for a reply message."""
422
- return Metadata(
423
- run_id=msg.metadata.run_id,
424
- message_id="",
425
- src_node_id=msg.metadata.dst_node_id,
426
- dst_node_id=msg.metadata.src_node_id,
427
- reply_to_message=msg.metadata.message_id,
428
- group_id=msg.metadata.group_id,
429
- ttl=ttl,
430
- message_type=msg.metadata.message_type,
431
- )
536
+ return max_allowed_ttl
537
+
538
+ return reply_ttl or max_allowed_ttl
539
+
540
+
541
+ def _extract_positional_args(
542
+ *args: Any,
543
+ content: RecordDict | None,
544
+ error: Error | None,
545
+ dst_node_id: int | None,
546
+ message_type: str | None,
547
+ ) -> tuple[RecordDict | None, Error | None, int | None, str | None]:
548
+ """Extract positional arguments for the `Message` constructor."""
549
+ content_or_error = args[0] if args else None
550
+ if len(args) > 1:
551
+ if dst_node_id is not None:
552
+ raise MessageInitializationError()
553
+ dst_node_id = args[1]
554
+ if len(args) > 2:
555
+ if message_type is not None:
556
+ raise MessageInitializationError()
557
+ message_type = args[2]
558
+ if len(args) > 3:
559
+ raise MessageInitializationError()
560
+
561
+ # One and only one of `content_or_error`, `content` and `error` must be set
562
+ if sum(x is not None for x in [content_or_error, content, error]) != 1:
563
+ raise MessageInitializationError()
564
+
565
+ # Set `content` or `error` based on `content_or_error`
566
+ if content_or_error is not None: # This means `content` and `error` are None
567
+ if isinstance(content_or_error, RecordDict):
568
+ content = content_or_error
569
+ elif isinstance(content_or_error, Error):
570
+ error = content_or_error
571
+ else:
572
+ raise MessageInitializationError()
573
+ return content, error, dst_node_id, message_type
574
+
575
+
576
+ def _check_arg_types( # pylint: disable=too-many-arguments, R0917
577
+ dst_node_id: int | None = None,
578
+ message_type: str | None = None,
579
+ content: RecordDict | None = None,
580
+ error: Error | None = None,
581
+ ttl: float | None = None,
582
+ group_id: str | None = None,
583
+ reply_to: Message | None = None,
584
+ metadata: Metadata | None = None,
585
+ ) -> None:
586
+ """Check argument types for the `Message` constructor."""
587
+ # pylint: disable=too-many-boolean-expressions
588
+ if (
589
+ (dst_node_id is None or isinstance(dst_node_id, int))
590
+ and (message_type is None or isinstance(message_type, str))
591
+ and (content is None or isinstance(content, RecordDict))
592
+ and (error is None or isinstance(error, Error))
593
+ and (ttl is None or isinstance(ttl, (int, float)))
594
+ and (group_id is None or isinstance(group_id, str))
595
+ and (reply_to is None or isinstance(reply_to, Message))
596
+ and (metadata is None or isinstance(metadata, Metadata))
597
+ ):
598
+ return
599
+ raise MessageInitializationError()
432
600
 
433
601
 
434
602
  def validate_message_type(message_type: str) -> bool:
@@ -19,13 +19,14 @@ from .configsrecord import ConfigsRecord
19
19
  from .conversion_utils import array_from_numpy
20
20
  from .metricsrecord import MetricsRecord
21
21
  from .parametersrecord import Array, ParametersRecord
22
- from .recordset import RecordSet
22
+ from .recorddict import RecordDict, RecordSet
23
23
 
24
24
  __all__ = [
25
25
  "Array",
26
26
  "ConfigsRecord",
27
27
  "MetricsRecord",
28
28
  "ParametersRecord",
29
+ "RecordDict",
29
30
  "RecordSet",
30
31
  "array_from_numpy",
31
32
  ]
@@ -63,7 +63,7 @@ class ConfigsRecord(TypedDict[str, ConfigsRecordValues]):
63
63
  A :code:`ConfigsRecord` is a Python dictionary designed to ensure that
64
64
  each key-value pair adheres to specified data types. A :code:`ConfigsRecord`
65
65
  is one of the types of records that a
66
- `flwr.common.RecordSet <flwr.common.RecordSet.html#recordset>`_ supports and
66
+ `flwr.common.RecordDict <flwr.common.RecordDict.html#recorddict>`_ supports and
67
67
  can therefore be used to construct :code:`common.Message` objects.
68
68
 
69
69
  Parameters
@@ -101,7 +101,7 @@ class ConfigsRecord(TypedDict[str, ConfigsRecordValues]):
101
101
  >>> # And string values (among other types)
102
102
  >>> record["path-to-S3"] = "s3://bucket_name/folder1/fileA.json"
103
103
 
104
- Just like the other types of records in a :code:`flwr.common.RecordSet`, types are
104
+ Just like the other types of records in a :code:`flwr.common.RecordDict`, types are
105
105
  enforced. If you need to add a custom data structure or object, we recommend to
106
106
  serialise it into bytes and save it as such (bytes are allowed in a
107
107
  :code:`ConfigsRecord`)
@@ -63,7 +63,7 @@ class MetricsRecord(TypedDict[str, MetricsRecordValues]):
63
63
  A :code:`MetricsRecord` is a Python dictionary designed to ensure that
64
64
  each key-value pair adheres to specified data types. A :code:`MetricsRecord`
65
65
  is one of the types of records that a
66
- `flwr.common.RecordSet <flwr.common.RecordSet.html#recordset>`_ supports and
66
+ `flwr.common.RecordDict <flwr.common.RecordDict.html#recorddict>`_ supports and
67
67
  can therefore be used to construct :code:`common.Message` objects.
68
68
 
69
69
  Parameters
@@ -282,7 +282,7 @@ class ParametersRecord(TypedDict[str, Array]):
282
282
  ``OrderedDict[str, Array]``. A ``ParametersRecord`` can be viewed as an
283
283
  equivalent to PyTorch's ``state_dict``, but it holds arrays in serialized form.
284
284
 
285
- This object is one of the record types supported by :class:`RecordSet` and can
285
+ This object is one of the record types supported by :class:`RecordDict` and can
286
286
  therefore be stored in the ``content`` of a :class:`Message` or the ``state``
287
287
  of a :class:`Context`.
288
288