flwr 1.15.2__py3-none-any.whl → 1.17.0__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 (120) hide show
  1. flwr/cli/build.py +2 -0
  2. flwr/cli/log.py +20 -21
  3. flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +1 -1
  4. flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +1 -1
  5. flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +1 -1
  6. flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +1 -1
  7. flwr/cli/new/templates/app/pyproject.jax.toml.tpl +1 -1
  8. flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +1 -1
  9. flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +1 -1
  10. flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +1 -1
  11. flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +1 -1
  12. flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +1 -1
  13. flwr/cli/run/run.py +5 -9
  14. flwr/client/app.py +6 -4
  15. flwr/client/client_app.py +260 -86
  16. flwr/client/clientapp/app.py +6 -2
  17. flwr/client/grpc_client/connection.py +24 -21
  18. flwr/client/message_handler/message_handler.py +28 -28
  19. flwr/client/mod/__init__.py +2 -2
  20. flwr/client/mod/centraldp_mods.py +7 -7
  21. flwr/client/mod/comms_mods.py +16 -22
  22. flwr/client/mod/localdp_mod.py +4 -4
  23. flwr/client/mod/secure_aggregation/secaggplus_mod.py +31 -31
  24. flwr/client/rest_client/connection.py +4 -6
  25. flwr/client/run_info_store.py +2 -2
  26. flwr/client/supernode/__init__.py +0 -2
  27. flwr/client/supernode/app.py +1 -11
  28. flwr/common/__init__.py +12 -4
  29. flwr/common/address.py +35 -0
  30. flwr/common/args.py +8 -2
  31. flwr/common/auth_plugin/auth_plugin.py +2 -1
  32. flwr/common/config.py +4 -4
  33. flwr/common/constant.py +16 -0
  34. flwr/common/context.py +4 -4
  35. flwr/common/event_log_plugin/__init__.py +22 -0
  36. flwr/common/event_log_plugin/event_log_plugin.py +60 -0
  37. flwr/common/grpc.py +1 -1
  38. flwr/common/logger.py +2 -2
  39. flwr/common/message.py +338 -102
  40. flwr/common/object_ref.py +0 -10
  41. flwr/common/record/__init__.py +8 -4
  42. flwr/common/record/arrayrecord.py +626 -0
  43. flwr/common/record/{configsrecord.py → configrecord.py} +75 -29
  44. flwr/common/record/conversion_utils.py +9 -18
  45. flwr/common/record/{metricsrecord.py → metricrecord.py} +78 -32
  46. flwr/common/record/recorddict.py +288 -0
  47. flwr/common/recorddict_compat.py +410 -0
  48. flwr/common/secure_aggregation/quantization.py +5 -1
  49. flwr/common/secure_aggregation/secaggplus_constants.py +1 -1
  50. flwr/common/serde.py +67 -190
  51. flwr/common/telemetry.py +0 -10
  52. flwr/common/typing.py +44 -8
  53. flwr/proto/exec_pb2.py +3 -3
  54. flwr/proto/exec_pb2.pyi +3 -3
  55. flwr/proto/message_pb2.py +12 -12
  56. flwr/proto/message_pb2.pyi +9 -9
  57. flwr/proto/recorddict_pb2.py +70 -0
  58. flwr/proto/{recordset_pb2.pyi → recorddict_pb2.pyi} +35 -35
  59. flwr/proto/run_pb2.py +31 -31
  60. flwr/proto/run_pb2.pyi +3 -3
  61. flwr/server/__init__.py +3 -1
  62. flwr/server/app.py +74 -3
  63. flwr/server/compat/__init__.py +2 -2
  64. flwr/server/compat/app.py +15 -12
  65. flwr/server/compat/app_utils.py +26 -18
  66. flwr/server/compat/{driver_client_proxy.py → grid_client_proxy.py} +41 -41
  67. flwr/server/fleet_event_log_interceptor.py +94 -0
  68. flwr/server/{driver → grid}/__init__.py +8 -7
  69. flwr/server/{driver/driver.py → grid/grid.py} +48 -19
  70. flwr/server/{driver/grpc_driver.py → grid/grpc_grid.py} +88 -56
  71. flwr/server/{driver/inmemory_driver.py → grid/inmemory_grid.py} +41 -54
  72. flwr/server/run_serverapp.py +6 -17
  73. flwr/server/server_app.py +126 -33
  74. flwr/server/serverapp/app.py +10 -10
  75. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +2 -2
  76. flwr/server/superlink/fleet/message_handler/message_handler.py +8 -12
  77. flwr/server/superlink/fleet/vce/backend/backend.py +3 -3
  78. flwr/server/superlink/fleet/vce/backend/raybackend.py +2 -2
  79. flwr/server/superlink/fleet/vce/vce_api.py +33 -38
  80. flwr/server/superlink/linkstate/in_memory_linkstate.py +171 -132
  81. flwr/server/superlink/linkstate/linkstate.py +51 -64
  82. flwr/server/superlink/linkstate/sqlite_linkstate.py +253 -285
  83. flwr/server/superlink/linkstate/utils.py +171 -133
  84. flwr/server/superlink/{driver → serverappio}/__init__.py +1 -1
  85. flwr/server/superlink/{driver → serverappio}/serverappio_grpc.py +1 -1
  86. flwr/server/superlink/{driver → serverappio}/serverappio_servicer.py +27 -29
  87. flwr/server/superlink/simulation/simulationio_servicer.py +2 -2
  88. flwr/server/typing.py +3 -3
  89. flwr/server/utils/__init__.py +2 -2
  90. flwr/server/utils/validator.py +53 -68
  91. flwr/server/workflow/default_workflows.py +52 -58
  92. flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +48 -50
  93. flwr/simulation/app.py +2 -2
  94. flwr/simulation/ray_transport/ray_actor.py +4 -2
  95. flwr/simulation/ray_transport/ray_client_proxy.py +34 -32
  96. flwr/simulation/run_simulation.py +15 -15
  97. flwr/superexec/app.py +0 -14
  98. flwr/superexec/deployment.py +4 -4
  99. flwr/superexec/exec_event_log_interceptor.py +135 -0
  100. flwr/superexec/exec_grpc.py +10 -4
  101. flwr/superexec/exec_servicer.py +6 -6
  102. flwr/superexec/exec_user_auth_interceptor.py +22 -4
  103. flwr/superexec/executor.py +3 -3
  104. flwr/superexec/simulation.py +3 -3
  105. {flwr-1.15.2.dist-info → flwr-1.17.0.dist-info}/METADATA +5 -5
  106. {flwr-1.15.2.dist-info → flwr-1.17.0.dist-info}/RECORD +111 -112
  107. {flwr-1.15.2.dist-info → flwr-1.17.0.dist-info}/entry_points.txt +0 -3
  108. flwr/client/message_handler/task_handler.py +0 -37
  109. flwr/common/record/parametersrecord.py +0 -204
  110. flwr/common/record/recordset.py +0 -202
  111. flwr/common/recordset_compat.py +0 -418
  112. flwr/proto/recordset_pb2.py +0 -70
  113. flwr/proto/task_pb2.py +0 -33
  114. flwr/proto/task_pb2.pyi +0 -100
  115. flwr/proto/task_pb2_grpc.py +0 -4
  116. flwr/proto/task_pb2_grpc.pyi +0 -4
  117. /flwr/proto/{recordset_pb2_grpc.py → recorddict_pb2_grpc.py} +0 -0
  118. /flwr/proto/{recordset_pb2_grpc.pyi → recorddict_pb2_grpc.pyi} +0 -0
  119. {flwr-1.15.2.dist-info → flwr-1.17.0.dist-info}/LICENSE +0 -0
  120. {flwr-1.15.2.dist-info → flwr-1.17.0.dist-info}/WHEEL +0 -0
@@ -25,7 +25,11 @@ from flwr.common.typing import NDArrayFloat, NDArrayInt
25
25
  def _stochastic_round(arr: NDArrayFloat) -> NDArrayInt:
26
26
  ret: NDArrayInt = np.ceil(arr).astype(np.int32)
27
27
  rand_arr = np.random.rand(*ret.shape)
28
- ret[rand_arr < ret - arr] -= 1
28
+ if len(ret.shape) == 0:
29
+ if rand_arr < ret - arr:
30
+ ret -= 1
31
+ else:
32
+ ret[rand_arr < ret - arr] -= 1
29
33
  return ret
30
34
 
31
35
 
@@ -42,7 +42,7 @@ class Stage:
42
42
 
43
43
 
44
44
  class Key:
45
- """Keys for the configs in the ConfigsRecord."""
45
+ """Keys for the configs in the ConfigRecord."""
46
46
 
47
47
  STAGE = "stage"
48
48
  SAMPLE_NUMBER = "sample_num"
flwr/common/serde.py CHANGED
@@ -21,8 +21,6 @@ from typing import Any, TypeVar, cast
21
21
 
22
22
  from google.protobuf.message import Message as GrpcMessage
23
23
 
24
- from flwr.common.constant import SUPERLINK_NODE_ID
25
-
26
24
  # pylint: disable=E0611
27
25
  from flwr.proto.clientappio_pb2 import ClientAppOutputCode, ClientAppOutputStatus
28
26
  from flwr.proto.error_pb2 import Error as ProtoError
@@ -30,20 +28,18 @@ from flwr.proto.fab_pb2 import Fab as ProtoFab
30
28
  from flwr.proto.message_pb2 import Context as ProtoContext
31
29
  from flwr.proto.message_pb2 import Message as ProtoMessage
32
30
  from flwr.proto.message_pb2 import Metadata as ProtoMetadata
33
- from flwr.proto.node_pb2 import Node
34
- from flwr.proto.recordset_pb2 import Array as ProtoArray
35
- from flwr.proto.recordset_pb2 import BoolList, BytesList
36
- from flwr.proto.recordset_pb2 import ConfigsRecord as ProtoConfigsRecord
37
- from flwr.proto.recordset_pb2 import ConfigsRecordValue as ProtoConfigsRecordValue
38
- from flwr.proto.recordset_pb2 import DoubleList
39
- from flwr.proto.recordset_pb2 import MetricsRecord as ProtoMetricsRecord
40
- from flwr.proto.recordset_pb2 import MetricsRecordValue as ProtoMetricsRecordValue
41
- from flwr.proto.recordset_pb2 import ParametersRecord as ProtoParametersRecord
42
- from flwr.proto.recordset_pb2 import RecordSet as ProtoRecordSet
43
- from flwr.proto.recordset_pb2 import SintList, StringList, UintList
31
+ from flwr.proto.recorddict_pb2 import Array as ProtoArray
32
+ from flwr.proto.recorddict_pb2 import ArrayRecord as ProtoArrayRecord
33
+ from flwr.proto.recorddict_pb2 import BoolList, BytesList
34
+ from flwr.proto.recorddict_pb2 import ConfigRecord as ProtoConfigRecord
35
+ from flwr.proto.recorddict_pb2 import ConfigRecordValue as ProtoConfigRecordValue
36
+ from flwr.proto.recorddict_pb2 import DoubleList
37
+ from flwr.proto.recorddict_pb2 import MetricRecord as ProtoMetricRecord
38
+ from flwr.proto.recorddict_pb2 import MetricRecordValue as ProtoMetricRecordValue
39
+ from flwr.proto.recorddict_pb2 import RecordDict as ProtoRecordDict
40
+ from flwr.proto.recorddict_pb2 import SintList, StringList, UintList
44
41
  from flwr.proto.run_pb2 import Run as ProtoRun
45
42
  from flwr.proto.run_pb2 import RunStatus as ProtoRunStatus
46
- from flwr.proto.task_pb2 import Task, TaskIns, TaskRes
47
43
  from flwr.proto.transport_pb2 import (
48
44
  ClientMessage,
49
45
  Code,
@@ -57,14 +53,14 @@ from flwr.proto.transport_pb2 import (
57
53
  # pylint: enable=E0611
58
54
  from . import (
59
55
  Array,
60
- ConfigsRecord,
56
+ ArrayRecord,
57
+ ConfigRecord,
61
58
  Context,
62
- MetricsRecord,
63
- ParametersRecord,
64
- RecordSet,
59
+ MetricRecord,
60
+ RecordDict,
65
61
  typing,
66
62
  )
67
- from .message import Error, Message, Metadata
63
+ from .message import Error, Message, Metadata, make_message
68
64
  from .record.typeddict import TypedDict
69
65
 
70
66
  # === Parameters message ===
@@ -487,19 +483,19 @@ def array_from_proto(array_proto: ProtoArray) -> Array:
487
483
  )
488
484
 
489
485
 
490
- def parameters_record_to_proto(record: ParametersRecord) -> ProtoParametersRecord:
491
- """Serialize ParametersRecord to ProtoBuf."""
492
- return ProtoParametersRecord(
486
+ def array_record_to_proto(record: ArrayRecord) -> ProtoArrayRecord:
487
+ """Serialize ArrayRecord to ProtoBuf."""
488
+ return ProtoArrayRecord(
493
489
  data_keys=record.keys(),
494
490
  data_values=map(array_to_proto, record.values()),
495
491
  )
496
492
 
497
493
 
498
- def parameters_record_from_proto(
499
- record_proto: ProtoParametersRecord,
500
- ) -> ParametersRecord:
501
- """Deserialize ParametersRecord from ProtoBuf."""
502
- return ParametersRecord(
494
+ def array_record_from_proto(
495
+ record_proto: ProtoArrayRecord,
496
+ ) -> ArrayRecord:
497
+ """Deserialize ArrayRecord from ProtoBuf."""
498
+ return ArrayRecord(
503
499
  array_dict=OrderedDict(
504
500
  zip(record_proto.data_keys, map(array_from_proto, record_proto.data_values))
505
501
  ),
@@ -507,40 +503,40 @@ def parameters_record_from_proto(
507
503
  )
508
504
 
509
505
 
510
- def metrics_record_to_proto(record: MetricsRecord) -> ProtoMetricsRecord:
511
- """Serialize MetricsRecord to ProtoBuf."""
512
- return ProtoMetricsRecord(
513
- data=_record_value_dict_to_proto(record, [float, int], ProtoMetricsRecordValue)
506
+ def metric_record_to_proto(record: MetricRecord) -> ProtoMetricRecord:
507
+ """Serialize MetricRecord to ProtoBuf."""
508
+ return ProtoMetricRecord(
509
+ data=_record_value_dict_to_proto(record, [float, int], ProtoMetricRecordValue)
514
510
  )
515
511
 
516
512
 
517
- def metrics_record_from_proto(record_proto: ProtoMetricsRecord) -> MetricsRecord:
518
- """Deserialize MetricsRecord from ProtoBuf."""
519
- return MetricsRecord(
520
- metrics_dict=cast(
521
- dict[str, typing.MetricsRecordValues],
513
+ def metric_record_from_proto(record_proto: ProtoMetricRecord) -> MetricRecord:
514
+ """Deserialize MetricRecord from ProtoBuf."""
515
+ return MetricRecord(
516
+ metric_dict=cast(
517
+ dict[str, typing.MetricRecordValues],
522
518
  _record_value_dict_from_proto(record_proto.data),
523
519
  ),
524
520
  keep_input=False,
525
521
  )
526
522
 
527
523
 
528
- def configs_record_to_proto(record: ConfigsRecord) -> ProtoConfigsRecord:
529
- """Serialize ConfigsRecord to ProtoBuf."""
530
- return ProtoConfigsRecord(
524
+ def config_record_to_proto(record: ConfigRecord) -> ProtoConfigRecord:
525
+ """Serialize ConfigRecord to ProtoBuf."""
526
+ return ProtoConfigRecord(
531
527
  data=_record_value_dict_to_proto(
532
528
  record,
533
529
  [bool, int, float, str, bytes],
534
- ProtoConfigsRecordValue,
530
+ ProtoConfigRecordValue,
535
531
  )
536
532
  )
537
533
 
538
534
 
539
- def configs_record_from_proto(record_proto: ProtoConfigsRecord) -> ConfigsRecord:
540
- """Deserialize ConfigsRecord from ProtoBuf."""
541
- return ConfigsRecord(
542
- configs_dict=cast(
543
- dict[str, typing.ConfigsRecordValues],
535
+ def config_record_from_proto(record_proto: ProtoConfigRecord) -> ConfigRecord:
536
+ """Deserialize ConfigRecord from ProtoBuf."""
537
+ return ConfigRecord(
538
+ config_dict=cast(
539
+ dict[str, typing.ConfigRecordValues],
544
540
  _record_value_dict_from_proto(record_proto.data),
545
541
  ),
546
542
  keep_input=False,
@@ -562,149 +558,34 @@ def error_from_proto(error_proto: ProtoError) -> Error:
562
558
  return Error(code=error_proto.code, reason=reason)
563
559
 
564
560
 
565
- # === RecordSet message ===
561
+ # === RecordDict message ===
566
562
 
567
563
 
568
- def recordset_to_proto(recordset: RecordSet) -> ProtoRecordSet:
569
- """Serialize RecordSet to ProtoBuf."""
570
- return ProtoRecordSet(
571
- parameters={
572
- k: parameters_record_to_proto(v)
573
- for k, v in recordset.parameters_records.items()
564
+ def recorddict_to_proto(recorddict: RecordDict) -> ProtoRecordDict:
565
+ """Serialize RecordDict to ProtoBuf."""
566
+ return ProtoRecordDict(
567
+ arrays={
568
+ k: array_record_to_proto(v) for k, v in recorddict.array_records.items()
574
569
  },
575
570
  metrics={
576
- k: metrics_record_to_proto(v) for k, v in recordset.metrics_records.items()
571
+ k: metric_record_to_proto(v) for k, v in recorddict.metric_records.items()
577
572
  },
578
573
  configs={
579
- k: configs_record_to_proto(v) for k, v in recordset.configs_records.items()
580
- },
581
- )
582
-
583
-
584
- def recordset_from_proto(recordset_proto: ProtoRecordSet) -> RecordSet:
585
- """Deserialize RecordSet from ProtoBuf."""
586
- return RecordSet(
587
- parameters_records={
588
- k: parameters_record_from_proto(v)
589
- for k, v in recordset_proto.parameters.items()
574
+ k: config_record_to_proto(v) for k, v in recorddict.config_records.items()
590
575
  },
591
- metrics_records={
592
- k: metrics_record_from_proto(v) for k, v in recordset_proto.metrics.items()
593
- },
594
- configs_records={
595
- k: configs_record_from_proto(v) for k, v in recordset_proto.configs.items()
596
- },
597
- )
598
-
599
-
600
- # === Message ===
601
-
602
-
603
- def message_to_taskins(message: Message) -> TaskIns:
604
- """Create a TaskIns from the Message."""
605
- md = message.metadata
606
- return TaskIns(
607
- group_id=md.group_id,
608
- run_id=md.run_id,
609
- task=Task(
610
- producer=Node(node_id=SUPERLINK_NODE_ID), # Assume driver node
611
- consumer=Node(node_id=md.dst_node_id),
612
- created_at=md.created_at,
613
- ttl=md.ttl,
614
- ancestry=[md.reply_to_message] if md.reply_to_message != "" else [],
615
- task_type=md.message_type,
616
- recordset=(
617
- recordset_to_proto(message.content) if message.has_content() else None
618
- ),
619
- error=error_to_proto(message.error) if message.has_error() else None,
620
- ),
621
576
  )
622
577
 
623
578
 
624
- def message_from_taskins(taskins: TaskIns) -> Message:
625
- """Create a Message from the TaskIns."""
626
- # Retrieve the Metadata
627
- metadata = Metadata(
628
- run_id=taskins.run_id,
629
- message_id=taskins.task_id,
630
- src_node_id=taskins.task.producer.node_id,
631
- dst_node_id=taskins.task.consumer.node_id,
632
- reply_to_message=taskins.task.ancestry[0] if taskins.task.ancestry else "",
633
- group_id=taskins.group_id,
634
- ttl=taskins.task.ttl,
635
- message_type=taskins.task.task_type,
636
- )
637
-
638
- # Construct Message
639
- message = Message(
640
- metadata=metadata,
641
- content=(
642
- recordset_from_proto(taskins.task.recordset)
643
- if taskins.task.HasField("recordset")
644
- else None
645
- ),
646
- error=(
647
- error_from_proto(taskins.task.error)
648
- if taskins.task.HasField("error")
649
- else None
650
- ),
651
- )
652
- message.metadata.created_at = taskins.task.created_at
653
- return message
654
-
655
-
656
- def message_to_taskres(message: Message) -> TaskRes:
657
- """Create a TaskRes from the Message."""
658
- md = message.metadata
659
- return TaskRes(
660
- task_id="", # This will be generated by the server
661
- group_id=md.group_id,
662
- run_id=md.run_id,
663
- task=Task(
664
- producer=Node(node_id=md.src_node_id),
665
- consumer=Node(node_id=SUPERLINK_NODE_ID), # Assume driver node
666
- created_at=md.created_at,
667
- ttl=md.ttl,
668
- ancestry=[md.reply_to_message] if md.reply_to_message != "" else [],
669
- task_type=md.message_type,
670
- recordset=(
671
- recordset_to_proto(message.content) if message.has_content() else None
672
- ),
673
- error=error_to_proto(message.error) if message.has_error() else None,
674
- ),
675
- )
676
-
677
-
678
- def message_from_taskres(taskres: TaskRes) -> Message:
679
- """Create a Message from the TaskIns."""
680
- # Retrieve the MetaData
681
- metadata = Metadata(
682
- run_id=taskres.run_id,
683
- message_id=taskres.task_id,
684
- src_node_id=taskres.task.producer.node_id,
685
- dst_node_id=taskres.task.consumer.node_id,
686
- reply_to_message=taskres.task.ancestry[0] if taskres.task.ancestry else "",
687
- group_id=taskres.group_id,
688
- ttl=taskres.task.ttl,
689
- message_type=taskres.task.task_type,
690
- )
691
-
692
- # Construct the Message
693
- message = Message(
694
- metadata=metadata,
695
- content=(
696
- recordset_from_proto(taskres.task.recordset)
697
- if taskres.task.HasField("recordset")
698
- else None
699
- ),
700
- error=(
701
- error_from_proto(taskres.task.error)
702
- if taskres.task.HasField("error")
703
- else None
704
- ),
705
- )
706
- message.metadata.created_at = taskres.task.created_at
707
- return message
579
+ def recorddict_from_proto(recorddict_proto: ProtoRecordDict) -> RecordDict:
580
+ """Deserialize RecordDict from ProtoBuf."""
581
+ ret = RecordDict()
582
+ for k, arr_record_proto in recorddict_proto.arrays.items():
583
+ ret[k] = array_record_from_proto(arr_record_proto)
584
+ for k, m_record_proto in recorddict_proto.metrics.items():
585
+ ret[k] = metric_record_from_proto(m_record_proto)
586
+ for k, c_record_proto in recorddict_proto.configs.items():
587
+ ret[k] = config_record_from_proto(c_record_proto)
588
+ return ret
708
589
 
709
590
 
710
591
  # === FAB ===
@@ -775,7 +656,7 @@ def metadata_to_proto(metadata: Metadata) -> ProtoMetadata:
775
656
  message_id=metadata.message_id,
776
657
  src_node_id=metadata.src_node_id,
777
658
  dst_node_id=metadata.dst_node_id,
778
- reply_to_message=metadata.reply_to_message,
659
+ reply_to_message_id=metadata.reply_to_message_id,
779
660
  group_id=metadata.group_id,
780
661
  ttl=metadata.ttl,
781
662
  message_type=metadata.message_type,
@@ -791,8 +672,9 @@ def metadata_from_proto(metadata_proto: ProtoMetadata) -> Metadata:
791
672
  message_id=metadata_proto.message_id,
792
673
  src_node_id=metadata_proto.src_node_id,
793
674
  dst_node_id=metadata_proto.dst_node_id,
794
- reply_to_message=metadata_proto.reply_to_message,
675
+ reply_to_message_id=metadata_proto.reply_to_message_id,
795
676
  group_id=metadata_proto.group_id,
677
+ created_at=metadata_proto.created_at,
796
678
  ttl=metadata_proto.ttl,
797
679
  message_type=metadata_proto.message_type,
798
680
  )
@@ -807,7 +689,7 @@ def message_to_proto(message: Message) -> ProtoMessage:
807
689
  proto = ProtoMessage(
808
690
  metadata=metadata_to_proto(message.metadata),
809
691
  content=(
810
- recordset_to_proto(message.content) if message.has_content() else None
692
+ recorddict_to_proto(message.content) if message.has_content() else None
811
693
  ),
812
694
  error=error_to_proto(message.error) if message.has_error() else None,
813
695
  )
@@ -816,11 +698,10 @@ def message_to_proto(message: Message) -> ProtoMessage:
816
698
 
817
699
  def message_from_proto(message_proto: ProtoMessage) -> Message:
818
700
  """Deserialize `Message` from ProtoBuf."""
819
- created_at = message_proto.metadata.created_at
820
- message = Message(
701
+ return make_message(
821
702
  metadata=metadata_from_proto(message_proto.metadata),
822
703
  content=(
823
- recordset_from_proto(message_proto.content)
704
+ recorddict_from_proto(message_proto.content)
824
705
  if message_proto.HasField("content")
825
706
  else None
826
707
  ),
@@ -830,10 +711,6 @@ def message_from_proto(message_proto: ProtoMessage) -> Message:
830
711
  else None
831
712
  ),
832
713
  )
833
- # `.created_at` is set upon Message object construction
834
- # we need to manually set it to the original value
835
- message.metadata.created_at = created_at
836
- return message
837
714
 
838
715
 
839
716
  # === Context messages ===
@@ -845,7 +722,7 @@ def context_to_proto(context: Context) -> ProtoContext:
845
722
  run_id=context.run_id,
846
723
  node_id=context.node_id,
847
724
  node_config=user_config_to_proto(context.node_config),
848
- state=recordset_to_proto(context.state),
725
+ state=recorddict_to_proto(context.state),
849
726
  run_config=user_config_to_proto(context.run_config),
850
727
  )
851
728
  return proto
@@ -857,7 +734,7 @@ def context_from_proto(context_proto: ProtoContext) -> Context:
857
734
  run_id=context_proto.run_id,
858
735
  node_id=context_proto.node_id,
859
736
  node_config=user_config_from_proto(context_proto.node_config),
860
- state=recordset_from_proto(context_proto.state),
737
+ state=recorddict_from_proto(context_proto.state),
861
738
  run_config=user_config_from_proto(context_proto.run_config),
862
739
  )
863
740
  return context
flwr/common/telemetry.py CHANGED
@@ -181,16 +181,6 @@ class EventType(str, Enum):
181
181
  RUN_SUPERNODE_ENTER = auto()
182
182
  RUN_SUPERNODE_LEAVE = auto()
183
183
 
184
- # --- DEPRECATED -------------------------------------------------------------------
185
-
186
- # [DEPRECATED] CLI: `flower-server-app`
187
- RUN_SERVER_APP_ENTER = auto()
188
- RUN_SERVER_APP_LEAVE = auto()
189
-
190
- # [DEPRECATED] CLI: `flower-client-app`
191
- RUN_CLIENT_APP_ENTER = auto()
192
- RUN_CLIENT_APP_LEAVE = auto()
193
-
194
184
 
195
185
  # Use the ThreadPoolExecutor with max_workers=1 to have a queue
196
186
  # and also ensure that telemetry calls are not blocking.
flwr/common/typing.py CHANGED
@@ -45,14 +45,14 @@ Value = Union[
45
45
  list[str],
46
46
  ]
47
47
 
48
- # Value types for common.MetricsRecord
49
- MetricsScalar = Union[int, float]
50
- MetricsScalarList = Union[list[int], list[float]]
51
- MetricsRecordValues = Union[MetricsScalar, MetricsScalarList]
52
- # Value types for common.ConfigsRecord
53
- ConfigsScalar = Union[MetricsScalar, str, bytes, bool]
54
- ConfigsScalarList = Union[MetricsScalarList, list[str], list[bytes], list[bool]]
55
- ConfigsRecordValues = Union[ConfigsScalar, ConfigsScalarList]
48
+ # Value types for common.MetricRecord
49
+ MetricScalar = Union[int, float]
50
+ MetricScalarList = Union[list[int], list[float]]
51
+ MetricRecordValues = Union[MetricScalar, MetricScalarList]
52
+ # Value types for common.ConfigRecord
53
+ ConfigScalar = Union[MetricScalar, str, bytes, bool]
54
+ ConfigScalarList = Union[MetricScalarList, list[str], list[bytes], list[bool]]
55
+ ConfigRecordValues = Union[ConfigScalar, ConfigScalarList]
56
56
 
57
57
  Metrics = dict[str, Scalar]
58
58
  MetricsAggregationFn = Callable[[list[tuple[int, Metrics]]], Metrics]
@@ -286,3 +286,39 @@ class UserAuthCredentials:
286
286
 
287
287
  access_token: str
288
288
  refresh_token: str
289
+
290
+
291
+ @dataclass
292
+ class UserInfo:
293
+ """User information for event log."""
294
+
295
+ user_id: Optional[str]
296
+ user_name: Optional[str]
297
+
298
+
299
+ @dataclass
300
+ class Actor:
301
+ """Event log actor."""
302
+
303
+ actor_id: Optional[str]
304
+ description: Optional[str]
305
+ ip_address: str
306
+
307
+
308
+ @dataclass
309
+ class Event:
310
+ """Event log description."""
311
+
312
+ action: str
313
+ run_id: Optional[int]
314
+ fab_hash: Optional[str]
315
+
316
+
317
+ @dataclass
318
+ class LogEntry:
319
+ """Event log record."""
320
+
321
+ timestamp: str
322
+ actor: Actor
323
+ event: Event
324
+ status: str
flwr/proto/exec_pb2.py CHANGED
@@ -14,11 +14,11 @@ _sym_db = _symbol_database.Default()
14
14
 
15
15
  from flwr.proto import fab_pb2 as flwr_dot_proto_dot_fab__pb2
16
16
  from flwr.proto import transport_pb2 as flwr_dot_proto_dot_transport__pb2
17
- from flwr.proto import recordset_pb2 as flwr_dot_proto_dot_recordset__pb2
17
+ from flwr.proto import recorddict_pb2 as flwr_dot_proto_dot_recorddict__pb2
18
18
  from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2
19
19
 
20
20
 
21
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/exec.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x1a\x66lwr/proto/recordset.proto\x1a\x14\x66lwr/proto/run.proto\"\xfb\x01\n\x0fStartRunRequest\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fab\x12H\n\x0foverride_config\x18\x02 \x03(\x0b\x32/.flwr.proto.StartRunRequest.OverrideConfigEntry\x12\x35\n\x12\x66\x65\x64\x65ration_options\x18\x03 \x01(\x0b\x32\x19.flwr.proto.ConfigsRecord\x1aI\n\x13OverrideConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"2\n\x10StartRunResponse\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"<\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x17\n\x0f\x61\x66ter_timestamp\x18\x02 \x01(\x01\"B\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t\x12\x18\n\x10latest_timestamp\x18\x02 \x01(\x01\"1\n\x0fListRunsRequest\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"\x9d\x01\n\x10ListRunsResponse\x12;\n\x08run_dict\x18\x01 \x03(\x0b\x32).flwr.proto.ListRunsResponse.RunDictEntry\x12\x0b\n\x03now\x18\x02 \x01(\t\x1a?\n\x0cRunDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x1e\n\x05value\x18\x02 \x01(\x0b\x32\x0f.flwr.proto.Run:\x02\x38\x01\"\x18\n\x16GetLoginDetailsRequest\"\x8a\x01\n\x17GetLoginDetailsResponse\x12\x11\n\tauth_type\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65vice_code\x18\x02 \x01(\t\x12!\n\x19verification_uri_complete\x18\x03 \x01(\t\x12\x12\n\nexpires_in\x18\x04 \x01(\x03\x12\x10\n\x08interval\x18\x05 \x01(\x03\"+\n\x14GetAuthTokensRequest\x12\x13\n\x0b\x64\x65vice_code\x18\x01 \x01(\t\"D\n\x15GetAuthTokensResponse\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x01 \x01(\t\x12\x15\n\rrefresh_token\x18\x02 \x01(\t\" \n\x0eStopRunRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"\"\n\x0fStopRunResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x32\xe5\x03\n\x04\x45xec\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\x00\x12\x44\n\x07StopRun\x12\x1a.flwr.proto.StopRunRequest\x1a\x1b.flwr.proto.StopRunResponse\"\x00\x12O\n\nStreamLogs\x12\x1d.flwr.proto.StreamLogsRequest\x1a\x1e.flwr.proto.StreamLogsResponse\"\x00\x30\x01\x12G\n\x08ListRuns\x12\x1b.flwr.proto.ListRunsRequest\x1a\x1c.flwr.proto.ListRunsResponse\"\x00\x12\\\n\x0fGetLoginDetails\x12\".flwr.proto.GetLoginDetailsRequest\x1a#.flwr.proto.GetLoginDetailsResponse\"\x00\x12V\n\rGetAuthTokens\x12 .flwr.proto.GetAuthTokensRequest\x1a!.flwr.proto.GetAuthTokensResponse\"\x00\x62\x06proto3')
21
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/exec.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x1b\x66lwr/proto/recorddict.proto\x1a\x14\x66lwr/proto/run.proto\"\xfa\x01\n\x0fStartRunRequest\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fab\x12H\n\x0foverride_config\x18\x02 \x03(\x0b\x32/.flwr.proto.StartRunRequest.OverrideConfigEntry\x12\x34\n\x12\x66\x65\x64\x65ration_options\x18\x03 \x01(\x0b\x32\x18.flwr.proto.ConfigRecord\x1aI\n\x13OverrideConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"2\n\x10StartRunResponse\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"<\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x17\n\x0f\x61\x66ter_timestamp\x18\x02 \x01(\x01\"B\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t\x12\x18\n\x10latest_timestamp\x18\x02 \x01(\x01\"1\n\x0fListRunsRequest\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"\x9d\x01\n\x10ListRunsResponse\x12;\n\x08run_dict\x18\x01 \x03(\x0b\x32).flwr.proto.ListRunsResponse.RunDictEntry\x12\x0b\n\x03now\x18\x02 \x01(\t\x1a?\n\x0cRunDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x1e\n\x05value\x18\x02 \x01(\x0b\x32\x0f.flwr.proto.Run:\x02\x38\x01\"\x18\n\x16GetLoginDetailsRequest\"\x8a\x01\n\x17GetLoginDetailsResponse\x12\x11\n\tauth_type\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65vice_code\x18\x02 \x01(\t\x12!\n\x19verification_uri_complete\x18\x03 \x01(\t\x12\x12\n\nexpires_in\x18\x04 \x01(\x03\x12\x10\n\x08interval\x18\x05 \x01(\x03\"+\n\x14GetAuthTokensRequest\x12\x13\n\x0b\x64\x65vice_code\x18\x01 \x01(\t\"D\n\x15GetAuthTokensResponse\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x01 \x01(\t\x12\x15\n\rrefresh_token\x18\x02 \x01(\t\" \n\x0eStopRunRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"\"\n\x0fStopRunResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x32\xe5\x03\n\x04\x45xec\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\x00\x12\x44\n\x07StopRun\x12\x1a.flwr.proto.StopRunRequest\x1a\x1b.flwr.proto.StopRunResponse\"\x00\x12O\n\nStreamLogs\x12\x1d.flwr.proto.StreamLogsRequest\x1a\x1e.flwr.proto.StreamLogsResponse\"\x00\x30\x01\x12G\n\x08ListRuns\x12\x1b.flwr.proto.ListRunsRequest\x1a\x1c.flwr.proto.ListRunsResponse\"\x00\x12\\\n\x0fGetLoginDetails\x12\".flwr.proto.GetLoginDetailsRequest\x1a#.flwr.proto.GetLoginDetailsResponse\"\x00\x12V\n\rGetAuthTokens\x12 .flwr.proto.GetAuthTokensRequest\x1a!.flwr.proto.GetAuthTokensResponse\"\x00\x62\x06proto3')
22
22
 
23
23
  _globals = globals()
24
24
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -29,7 +29,7 @@ if _descriptor._USE_C_DESCRIPTORS == False:
29
29
  _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_options = b'8\001'
30
30
  _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._options = None
31
31
  _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_options = b'8\001'
32
- _globals['_STARTRUNREQUEST']._serialized_start=138
32
+ _globals['_STARTRUNREQUEST']._serialized_start=139
33
33
  _globals['_STARTRUNREQUEST']._serialized_end=389
34
34
  _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=316
35
35
  _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=389
flwr/proto/exec_pb2.pyi CHANGED
@@ -4,7 +4,7 @@ isort:skip_file
4
4
  """
5
5
  import builtins
6
6
  import flwr.proto.fab_pb2
7
- import flwr.proto.recordset_pb2
7
+ import flwr.proto.recorddict_pb2
8
8
  import flwr.proto.run_pb2
9
9
  import flwr.proto.transport_pb2
10
10
  import google.protobuf.descriptor
@@ -40,12 +40,12 @@ class StartRunRequest(google.protobuf.message.Message):
40
40
  @property
41
41
  def override_config(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, flwr.proto.transport_pb2.Scalar]: ...
42
42
  @property
43
- def federation_options(self) -> flwr.proto.recordset_pb2.ConfigsRecord: ...
43
+ def federation_options(self) -> flwr.proto.recorddict_pb2.ConfigRecord: ...
44
44
  def __init__(self,
45
45
  *,
46
46
  fab: typing.Optional[flwr.proto.fab_pb2.Fab] = ...,
47
47
  override_config: typing.Optional[typing.Mapping[typing.Text, flwr.proto.transport_pb2.Scalar]] = ...,
48
- federation_options: typing.Optional[flwr.proto.recordset_pb2.ConfigsRecord] = ...,
48
+ federation_options: typing.Optional[flwr.proto.recorddict_pb2.ConfigRecord] = ...,
49
49
  ) -> None: ...
50
50
  def HasField(self, field_name: typing_extensions.Literal["fab",b"fab","federation_options",b"federation_options"]) -> builtins.bool: ...
51
51
  def ClearField(self, field_name: typing_extensions.Literal["fab",b"fab","federation_options",b"federation_options","override_config",b"override_config"]) -> None: ...
flwr/proto/message_pb2.py CHANGED
@@ -13,11 +13,11 @@ _sym_db = _symbol_database.Default()
13
13
 
14
14
 
15
15
  from flwr.proto import error_pb2 as flwr_dot_proto_dot_error__pb2
16
- from flwr.proto import recordset_pb2 as flwr_dot_proto_dot_recordset__pb2
16
+ from flwr.proto import recorddict_pb2 as flwr_dot_proto_dot_recorddict__pb2
17
17
  from flwr.proto import transport_pb2 as flwr_dot_proto_dot_transport__pb2
18
18
 
19
19
 
20
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18\x66lwr/proto/message.proto\x12\nflwr.proto\x1a\x16\x66lwr/proto/error.proto\x1a\x1a\x66lwr/proto/recordset.proto\x1a\x1a\x66lwr/proto/transport.proto\"{\n\x07Message\x12&\n\x08metadata\x18\x01 \x01(\x0b\x32\x14.flwr.proto.Metadata\x12&\n\x07\x63ontent\x18\x02 \x01(\x0b\x32\x15.flwr.proto.RecordSet\x12 \n\x05\x65rror\x18\x03 \x01(\x0b\x32\x11.flwr.proto.Error\"\xcf\x02\n\x07\x43ontext\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x0f\n\x07node_id\x18\x02 \x01(\x04\x12\x38\n\x0bnode_config\x18\x03 \x03(\x0b\x32#.flwr.proto.Context.NodeConfigEntry\x12$\n\x05state\x18\x04 \x01(\x0b\x32\x15.flwr.proto.RecordSet\x12\x36\n\nrun_config\x18\x05 \x03(\x0b\x32\".flwr.proto.Context.RunConfigEntry\x1a\x45\n\x0fNodeConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\x1a\x44\n\x0eRunConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"\xbb\x01\n\x08Metadata\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x12\n\nmessage_id\x18\x02 \x01(\t\x12\x13\n\x0bsrc_node_id\x18\x03 \x01(\x04\x12\x13\n\x0b\x64st_node_id\x18\x04 \x01(\x04\x12\x18\n\x10reply_to_message\x18\x05 \x01(\t\x12\x10\n\x08group_id\x18\x06 \x01(\t\x12\x0b\n\x03ttl\x18\x07 \x01(\x01\x12\x14\n\x0cmessage_type\x18\x08 \x01(\t\x12\x12\n\ncreated_at\x18\t \x01(\x01\x62\x06proto3')
20
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18\x66lwr/proto/message.proto\x12\nflwr.proto\x1a\x16\x66lwr/proto/error.proto\x1a\x1b\x66lwr/proto/recorddict.proto\x1a\x1a\x66lwr/proto/transport.proto\"|\n\x07Message\x12&\n\x08metadata\x18\x01 \x01(\x0b\x32\x14.flwr.proto.Metadata\x12\'\n\x07\x63ontent\x18\x02 \x01(\x0b\x32\x16.flwr.proto.RecordDict\x12 \n\x05\x65rror\x18\x03 \x01(\x0b\x32\x11.flwr.proto.Error\"\xd0\x02\n\x07\x43ontext\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x0f\n\x07node_id\x18\x02 \x01(\x04\x12\x38\n\x0bnode_config\x18\x03 \x03(\x0b\x32#.flwr.proto.Context.NodeConfigEntry\x12%\n\x05state\x18\x04 \x01(\x0b\x32\x16.flwr.proto.RecordDict\x12\x36\n\nrun_config\x18\x05 \x03(\x0b\x32\".flwr.proto.Context.RunConfigEntry\x1a\x45\n\x0fNodeConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\x1a\x44\n\x0eRunConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"\xbe\x01\n\x08Metadata\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x12\n\nmessage_id\x18\x02 \x01(\t\x12\x13\n\x0bsrc_node_id\x18\x03 \x01(\x04\x12\x13\n\x0b\x64st_node_id\x18\x04 \x01(\x04\x12\x1b\n\x13reply_to_message_id\x18\x05 \x01(\t\x12\x10\n\x08group_id\x18\x06 \x01(\t\x12\x0b\n\x03ttl\x18\x07 \x01(\x01\x12\x14\n\x0cmessage_type\x18\x08 \x01(\t\x12\x12\n\ncreated_at\x18\t \x01(\x01\x62\x06proto3')
21
21
 
22
22
  _globals = globals()
23
23
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -28,14 +28,14 @@ if _descriptor._USE_C_DESCRIPTORS == False:
28
28
  _globals['_CONTEXT_NODECONFIGENTRY']._serialized_options = b'8\001'
29
29
  _globals['_CONTEXT_RUNCONFIGENTRY']._options = None
30
30
  _globals['_CONTEXT_RUNCONFIGENTRY']._serialized_options = b'8\001'
31
- _globals['_MESSAGE']._serialized_start=120
32
- _globals['_MESSAGE']._serialized_end=243
33
- _globals['_CONTEXT']._serialized_start=246
34
- _globals['_CONTEXT']._serialized_end=581
35
- _globals['_CONTEXT_NODECONFIGENTRY']._serialized_start=442
36
- _globals['_CONTEXT_NODECONFIGENTRY']._serialized_end=511
37
- _globals['_CONTEXT_RUNCONFIGENTRY']._serialized_start=513
38
- _globals['_CONTEXT_RUNCONFIGENTRY']._serialized_end=581
39
- _globals['_METADATA']._serialized_start=584
40
- _globals['_METADATA']._serialized_end=771
31
+ _globals['_MESSAGE']._serialized_start=121
32
+ _globals['_MESSAGE']._serialized_end=245
33
+ _globals['_CONTEXT']._serialized_start=248
34
+ _globals['_CONTEXT']._serialized_end=584
35
+ _globals['_CONTEXT_NODECONFIGENTRY']._serialized_start=445
36
+ _globals['_CONTEXT_NODECONFIGENTRY']._serialized_end=514
37
+ _globals['_CONTEXT_RUNCONFIGENTRY']._serialized_start=516
38
+ _globals['_CONTEXT_RUNCONFIGENTRY']._serialized_end=584
39
+ _globals['_METADATA']._serialized_start=587
40
+ _globals['_METADATA']._serialized_end=777
41
41
  # @@protoc_insertion_point(module_scope)