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.
- flwr/cli/build.py +2 -0
- flwr/cli/log.py +20 -21
- flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.jax.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +1 -1
- flwr/cli/run/run.py +5 -9
- flwr/client/app.py +6 -4
- flwr/client/client_app.py +260 -86
- flwr/client/clientapp/app.py +6 -2
- flwr/client/grpc_client/connection.py +24 -21
- flwr/client/message_handler/message_handler.py +28 -28
- flwr/client/mod/__init__.py +2 -2
- flwr/client/mod/centraldp_mods.py +7 -7
- flwr/client/mod/comms_mods.py +16 -22
- flwr/client/mod/localdp_mod.py +4 -4
- flwr/client/mod/secure_aggregation/secaggplus_mod.py +31 -31
- flwr/client/rest_client/connection.py +4 -6
- flwr/client/run_info_store.py +2 -2
- flwr/client/supernode/__init__.py +0 -2
- flwr/client/supernode/app.py +1 -11
- flwr/common/__init__.py +12 -4
- flwr/common/address.py +35 -0
- flwr/common/args.py +8 -2
- flwr/common/auth_plugin/auth_plugin.py +2 -1
- flwr/common/config.py +4 -4
- flwr/common/constant.py +16 -0
- flwr/common/context.py +4 -4
- flwr/common/event_log_plugin/__init__.py +22 -0
- flwr/common/event_log_plugin/event_log_plugin.py +60 -0
- flwr/common/grpc.py +1 -1
- flwr/common/logger.py +2 -2
- flwr/common/message.py +338 -102
- flwr/common/object_ref.py +0 -10
- flwr/common/record/__init__.py +8 -4
- flwr/common/record/arrayrecord.py +626 -0
- flwr/common/record/{configsrecord.py → configrecord.py} +75 -29
- flwr/common/record/conversion_utils.py +9 -18
- flwr/common/record/{metricsrecord.py → metricrecord.py} +78 -32
- flwr/common/record/recorddict.py +288 -0
- flwr/common/recorddict_compat.py +410 -0
- flwr/common/secure_aggregation/quantization.py +5 -1
- flwr/common/secure_aggregation/secaggplus_constants.py +1 -1
- flwr/common/serde.py +67 -190
- flwr/common/telemetry.py +0 -10
- flwr/common/typing.py +44 -8
- flwr/proto/exec_pb2.py +3 -3
- flwr/proto/exec_pb2.pyi +3 -3
- flwr/proto/message_pb2.py +12 -12
- flwr/proto/message_pb2.pyi +9 -9
- flwr/proto/recorddict_pb2.py +70 -0
- flwr/proto/{recordset_pb2.pyi → recorddict_pb2.pyi} +35 -35
- flwr/proto/run_pb2.py +31 -31
- flwr/proto/run_pb2.pyi +3 -3
- flwr/server/__init__.py +3 -1
- flwr/server/app.py +74 -3
- flwr/server/compat/__init__.py +2 -2
- flwr/server/compat/app.py +15 -12
- flwr/server/compat/app_utils.py +26 -18
- flwr/server/compat/{driver_client_proxy.py → grid_client_proxy.py} +41 -41
- flwr/server/fleet_event_log_interceptor.py +94 -0
- flwr/server/{driver → grid}/__init__.py +8 -7
- flwr/server/{driver/driver.py → grid/grid.py} +48 -19
- flwr/server/{driver/grpc_driver.py → grid/grpc_grid.py} +88 -56
- flwr/server/{driver/inmemory_driver.py → grid/inmemory_grid.py} +41 -54
- flwr/server/run_serverapp.py +6 -17
- flwr/server/server_app.py +126 -33
- flwr/server/serverapp/app.py +10 -10
- flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +2 -2
- flwr/server/superlink/fleet/message_handler/message_handler.py +8 -12
- flwr/server/superlink/fleet/vce/backend/backend.py +3 -3
- flwr/server/superlink/fleet/vce/backend/raybackend.py +2 -2
- flwr/server/superlink/fleet/vce/vce_api.py +33 -38
- flwr/server/superlink/linkstate/in_memory_linkstate.py +171 -132
- flwr/server/superlink/linkstate/linkstate.py +51 -64
- flwr/server/superlink/linkstate/sqlite_linkstate.py +253 -285
- flwr/server/superlink/linkstate/utils.py +171 -133
- flwr/server/superlink/{driver → serverappio}/__init__.py +1 -1
- flwr/server/superlink/{driver → serverappio}/serverappio_grpc.py +1 -1
- flwr/server/superlink/{driver → serverappio}/serverappio_servicer.py +27 -29
- flwr/server/superlink/simulation/simulationio_servicer.py +2 -2
- flwr/server/typing.py +3 -3
- flwr/server/utils/__init__.py +2 -2
- flwr/server/utils/validator.py +53 -68
- flwr/server/workflow/default_workflows.py +52 -58
- flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +48 -50
- flwr/simulation/app.py +2 -2
- flwr/simulation/ray_transport/ray_actor.py +4 -2
- flwr/simulation/ray_transport/ray_client_proxy.py +34 -32
- flwr/simulation/run_simulation.py +15 -15
- flwr/superexec/app.py +0 -14
- flwr/superexec/deployment.py +4 -4
- flwr/superexec/exec_event_log_interceptor.py +135 -0
- flwr/superexec/exec_grpc.py +10 -4
- flwr/superexec/exec_servicer.py +6 -6
- flwr/superexec/exec_user_auth_interceptor.py +22 -4
- flwr/superexec/executor.py +3 -3
- flwr/superexec/simulation.py +3 -3
- {flwr-1.15.2.dist-info → flwr-1.17.0.dist-info}/METADATA +5 -5
- {flwr-1.15.2.dist-info → flwr-1.17.0.dist-info}/RECORD +111 -112
- {flwr-1.15.2.dist-info → flwr-1.17.0.dist-info}/entry_points.txt +0 -3
- flwr/client/message_handler/task_handler.py +0 -37
- flwr/common/record/parametersrecord.py +0 -204
- flwr/common/record/recordset.py +0 -202
- flwr/common/recordset_compat.py +0 -418
- flwr/proto/recordset_pb2.py +0 -70
- flwr/proto/task_pb2.py +0 -33
- flwr/proto/task_pb2.pyi +0 -100
- flwr/proto/task_pb2_grpc.py +0 -4
- flwr/proto/task_pb2_grpc.pyi +0 -4
- /flwr/proto/{recordset_pb2_grpc.py → recorddict_pb2_grpc.py} +0 -0
- /flwr/proto/{recordset_pb2_grpc.pyi → recorddict_pb2_grpc.pyi} +0 -0
- {flwr-1.15.2.dist-info → flwr-1.17.0.dist-info}/LICENSE +0 -0
- {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
|
-
|
|
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
|
|
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.
|
|
34
|
-
from flwr.proto.
|
|
35
|
-
from flwr.proto.
|
|
36
|
-
from flwr.proto.
|
|
37
|
-
from flwr.proto.
|
|
38
|
-
from flwr.proto.
|
|
39
|
-
from flwr.proto.
|
|
40
|
-
from flwr.proto.
|
|
41
|
-
from flwr.proto.
|
|
42
|
-
from flwr.proto.
|
|
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
|
-
|
|
56
|
+
ArrayRecord,
|
|
57
|
+
ConfigRecord,
|
|
61
58
|
Context,
|
|
62
|
-
|
|
63
|
-
|
|
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
|
|
491
|
-
"""Serialize
|
|
492
|
-
return
|
|
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
|
|
499
|
-
record_proto:
|
|
500
|
-
) ->
|
|
501
|
-
"""Deserialize
|
|
502
|
-
return
|
|
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
|
|
511
|
-
"""Serialize
|
|
512
|
-
return
|
|
513
|
-
data=_record_value_dict_to_proto(record, [float, int],
|
|
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
|
|
518
|
-
"""Deserialize
|
|
519
|
-
return
|
|
520
|
-
|
|
521
|
-
dict[str, typing.
|
|
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
|
|
529
|
-
"""Serialize
|
|
530
|
-
return
|
|
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
|
-
|
|
530
|
+
ProtoConfigRecordValue,
|
|
535
531
|
)
|
|
536
532
|
)
|
|
537
533
|
|
|
538
534
|
|
|
539
|
-
def
|
|
540
|
-
"""Deserialize
|
|
541
|
-
return
|
|
542
|
-
|
|
543
|
-
dict[str, typing.
|
|
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
|
-
# ===
|
|
561
|
+
# === RecordDict message ===
|
|
566
562
|
|
|
567
563
|
|
|
568
|
-
def
|
|
569
|
-
"""Serialize
|
|
570
|
-
return
|
|
571
|
-
|
|
572
|
-
k:
|
|
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:
|
|
571
|
+
k: metric_record_to_proto(v) for k, v in recorddict.metric_records.items()
|
|
577
572
|
},
|
|
578
573
|
configs={
|
|
579
|
-
k:
|
|
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
|
|
625
|
-
"""
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
820
|
-
message = Message(
|
|
701
|
+
return make_message(
|
|
821
702
|
metadata=metadata_from_proto(message_proto.metadata),
|
|
822
703
|
content=(
|
|
823
|
-
|
|
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=
|
|
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=
|
|
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.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
# Value types for common.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
|
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\
|
|
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=
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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\
|
|
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=
|
|
32
|
-
_globals['_MESSAGE']._serialized_end=
|
|
33
|
-
_globals['_CONTEXT']._serialized_start=
|
|
34
|
-
_globals['_CONTEXT']._serialized_end=
|
|
35
|
-
_globals['_CONTEXT_NODECONFIGENTRY']._serialized_start=
|
|
36
|
-
_globals['_CONTEXT_NODECONFIGENTRY']._serialized_end=
|
|
37
|
-
_globals['_CONTEXT_RUNCONFIGENTRY']._serialized_start=
|
|
38
|
-
_globals['_CONTEXT_RUNCONFIGENTRY']._serialized_end=
|
|
39
|
-
_globals['_METADATA']._serialized_start=
|
|
40
|
-
_globals['_METADATA']._serialized_end=
|
|
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)
|