flwr-nightly 1.13.0.dev20241112__py3-none-any.whl → 1.13.0.dev20241114__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of flwr-nightly might be problematic. Click here for more details.

flwr/proto/exec_pb2.pyi CHANGED
@@ -5,6 +5,7 @@ isort:skip_file
5
5
  import builtins
6
6
  import flwr.proto.fab_pb2
7
7
  import flwr.proto.recordset_pb2
8
+ import flwr.proto.run_pb2
8
9
  import flwr.proto.transport_pb2
9
10
  import google.protobuf.descriptor
10
11
  import google.protobuf.internal.containers
@@ -88,3 +89,46 @@ class StreamLogsResponse(google.protobuf.message.Message):
88
89
  ) -> None: ...
89
90
  def ClearField(self, field_name: typing_extensions.Literal["latest_timestamp",b"latest_timestamp","log_output",b"log_output"]) -> None: ...
90
91
  global___StreamLogsResponse = StreamLogsResponse
92
+
93
+ class ListRunsRequest(google.protobuf.message.Message):
94
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
95
+ RUN_ID_FIELD_NUMBER: builtins.int
96
+ run_id: builtins.int
97
+ def __init__(self,
98
+ *,
99
+ run_id: typing.Optional[builtins.int] = ...,
100
+ ) -> None: ...
101
+ def HasField(self, field_name: typing_extensions.Literal["_run_id",b"_run_id","run_id",b"run_id"]) -> builtins.bool: ...
102
+ def ClearField(self, field_name: typing_extensions.Literal["_run_id",b"_run_id","run_id",b"run_id"]) -> None: ...
103
+ def WhichOneof(self, oneof_group: typing_extensions.Literal["_run_id",b"_run_id"]) -> typing.Optional[typing_extensions.Literal["run_id"]]: ...
104
+ global___ListRunsRequest = ListRunsRequest
105
+
106
+ class ListRunsResponse(google.protobuf.message.Message):
107
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
108
+ class RunDictEntry(google.protobuf.message.Message):
109
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
110
+ KEY_FIELD_NUMBER: builtins.int
111
+ VALUE_FIELD_NUMBER: builtins.int
112
+ key: builtins.int
113
+ @property
114
+ def value(self) -> flwr.proto.run_pb2.Run: ...
115
+ def __init__(self,
116
+ *,
117
+ key: builtins.int = ...,
118
+ value: typing.Optional[flwr.proto.run_pb2.Run] = ...,
119
+ ) -> None: ...
120
+ def HasField(self, field_name: typing_extensions.Literal["value",b"value"]) -> builtins.bool: ...
121
+ def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ...
122
+
123
+ RUN_DICT_FIELD_NUMBER: builtins.int
124
+ NOW_FIELD_NUMBER: builtins.int
125
+ @property
126
+ def run_dict(self) -> google.protobuf.internal.containers.MessageMap[builtins.int, flwr.proto.run_pb2.Run]: ...
127
+ now: typing.Text
128
+ def __init__(self,
129
+ *,
130
+ run_dict: typing.Optional[typing.Mapping[builtins.int, flwr.proto.run_pb2.Run]] = ...,
131
+ now: typing.Text = ...,
132
+ ) -> None: ...
133
+ def ClearField(self, field_name: typing_extensions.Literal["now",b"now","run_dict",b"run_dict"]) -> None: ...
134
+ global___ListRunsResponse = ListRunsResponse
@@ -24,6 +24,11 @@ class ExecStub(object):
24
24
  request_serializer=flwr_dot_proto_dot_exec__pb2.StreamLogsRequest.SerializeToString,
25
25
  response_deserializer=flwr_dot_proto_dot_exec__pb2.StreamLogsResponse.FromString,
26
26
  )
27
+ self.ListRuns = channel.unary_unary(
28
+ '/flwr.proto.Exec/ListRuns',
29
+ request_serializer=flwr_dot_proto_dot_exec__pb2.ListRunsRequest.SerializeToString,
30
+ response_deserializer=flwr_dot_proto_dot_exec__pb2.ListRunsResponse.FromString,
31
+ )
27
32
 
28
33
 
29
34
  class ExecServicer(object):
@@ -43,6 +48,13 @@ class ExecServicer(object):
43
48
  context.set_details('Method not implemented!')
44
49
  raise NotImplementedError('Method not implemented!')
45
50
 
51
+ def ListRuns(self, request, context):
52
+ """flwr ls command
53
+ """
54
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
55
+ context.set_details('Method not implemented!')
56
+ raise NotImplementedError('Method not implemented!')
57
+
46
58
 
47
59
  def add_ExecServicer_to_server(servicer, server):
48
60
  rpc_method_handlers = {
@@ -56,6 +68,11 @@ def add_ExecServicer_to_server(servicer, server):
56
68
  request_deserializer=flwr_dot_proto_dot_exec__pb2.StreamLogsRequest.FromString,
57
69
  response_serializer=flwr_dot_proto_dot_exec__pb2.StreamLogsResponse.SerializeToString,
58
70
  ),
71
+ 'ListRuns': grpc.unary_unary_rpc_method_handler(
72
+ servicer.ListRuns,
73
+ request_deserializer=flwr_dot_proto_dot_exec__pb2.ListRunsRequest.FromString,
74
+ response_serializer=flwr_dot_proto_dot_exec__pb2.ListRunsResponse.SerializeToString,
75
+ ),
59
76
  }
60
77
  generic_handler = grpc.method_handlers_generic_handler(
61
78
  'flwr.proto.Exec', rpc_method_handlers)
@@ -99,3 +116,20 @@ class Exec(object):
99
116
  flwr_dot_proto_dot_exec__pb2.StreamLogsResponse.FromString,
100
117
  options, channel_credentials,
101
118
  insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
119
+
120
+ @staticmethod
121
+ def ListRuns(request,
122
+ target,
123
+ options=(),
124
+ channel_credentials=None,
125
+ call_credentials=None,
126
+ insecure=False,
127
+ compression=None,
128
+ wait_for_ready=None,
129
+ timeout=None,
130
+ metadata=None):
131
+ return grpc.experimental.unary_unary(request, target, '/flwr.proto.Exec/ListRuns',
132
+ flwr_dot_proto_dot_exec__pb2.ListRunsRequest.SerializeToString,
133
+ flwr_dot_proto_dot_exec__pb2.ListRunsResponse.FromString,
134
+ options, channel_credentials,
135
+ insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@@ -19,6 +19,11 @@ class ExecStub:
19
19
  flwr.proto.exec_pb2.StreamLogsResponse]
20
20
  """Start log stream upon request"""
21
21
 
22
+ ListRuns: grpc.UnaryUnaryMultiCallable[
23
+ flwr.proto.exec_pb2.ListRunsRequest,
24
+ flwr.proto.exec_pb2.ListRunsResponse]
25
+ """flwr ls command"""
26
+
22
27
 
23
28
  class ExecServicer(metaclass=abc.ABCMeta):
24
29
  @abc.abstractmethod
@@ -37,5 +42,13 @@ class ExecServicer(metaclass=abc.ABCMeta):
37
42
  """Start log stream upon request"""
38
43
  pass
39
44
 
45
+ @abc.abstractmethod
46
+ def ListRuns(self,
47
+ request: flwr.proto.exec_pb2.ListRunsRequest,
48
+ context: grpc.ServicerContext,
49
+ ) -> flwr.proto.exec_pb2.ListRunsResponse:
50
+ """flwr ls command"""
51
+ pass
52
+
40
53
 
41
54
  def add_ExecServicer_to_server(servicer: ExecServicer, server: grpc.Server) -> None: ...
flwr/proto/run_pb2.py CHANGED
@@ -18,7 +18,7 @@ from flwr.proto import recordset_pb2 as flwr_dot_proto_dot_recordset__pb2
18
18
  from flwr.proto import transport_pb2 as flwr_dot_proto_dot_transport__pb2
19
19
 
20
20
 
21
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/run.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x1a\x66lwr/proto/recordset.proto\x1a\x1a\x66lwr/proto/transport.proto\"\xd5\x01\n\x03Run\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x0e\n\x06\x66\x61\x62_id\x18\x02 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x03 \x01(\t\x12<\n\x0foverride_config\x18\x04 \x03(\x0b\x32#.flwr.proto.Run.OverrideConfigEntry\x12\x10\n\x08\x66\x61\x62_hash\x18\x05 \x01(\t\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\"@\n\tRunStatus\x12\x0e\n\x06status\x18\x01 \x01(\t\x12\x12\n\nsub_status\x18\x02 \x01(\t\x12\x0f\n\x07\x64\x65tails\x18\x03 \x01(\t\"\xeb\x01\n\x10\x43reateRunRequest\x12\x0e\n\x06\x66\x61\x62_id\x18\x01 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x02 \x01(\t\x12I\n\x0foverride_config\x18\x03 \x03(\x0b\x32\x30.flwr.proto.CreateRunRequest.OverrideConfigEntry\x12\x1c\n\x03\x66\x61\x62\x18\x04 \x01(\x0b\x32\x0f.flwr.proto.Fab\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\"#\n\x11\x43reateRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"?\n\rGetRunRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0e\n\x06run_id\x18\x02 \x01(\x04\".\n\x0eGetRunResponse\x12\x1c\n\x03run\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Run\"S\n\x16UpdateRunStatusRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12)\n\nrun_status\x18\x02 \x01(\x0b\x32\x15.flwr.proto.RunStatus\"\x19\n\x17UpdateRunStatusResponse\"F\n\x13GetRunStatusRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0f\n\x07run_ids\x18\x02 \x03(\x04\"\xb1\x01\n\x14GetRunStatusResponse\x12L\n\x0frun_status_dict\x18\x01 \x03(\x0b\x32\x33.flwr.proto.GetRunStatusResponse.RunStatusDictEntry\x1aK\n\x12RunStatusDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.flwr.proto.RunStatus:\x02\x38\x01\"-\n\x1bGetFederationOptionsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"U\n\x1cGetFederationOptionsResponse\x12\x35\n\x12\x66\x65\x64\x65ration_options\x18\x01 \x01(\x0b\x32\x19.flwr.proto.ConfigsRecordb\x06proto3')
21
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/run.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x1a\x66lwr/proto/recordset.proto\x1a\x1a\x66lwr/proto/transport.proto\"\xce\x02\n\x03Run\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x0e\n\x06\x66\x61\x62_id\x18\x02 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x03 \x01(\t\x12<\n\x0foverride_config\x18\x04 \x03(\x0b\x32#.flwr.proto.Run.OverrideConfigEntry\x12\x10\n\x08\x66\x61\x62_hash\x18\x05 \x01(\t\x12\x12\n\npending_at\x18\x06 \x01(\t\x12\x13\n\x0bstarting_at\x18\x07 \x01(\t\x12\x12\n\nrunning_at\x18\x08 \x01(\t\x12\x13\n\x0b\x66inished_at\x18\t \x01(\t\x12%\n\x06status\x18\n \x01(\x0b\x32\x15.flwr.proto.RunStatus\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\"@\n\tRunStatus\x12\x0e\n\x06status\x18\x01 \x01(\t\x12\x12\n\nsub_status\x18\x02 \x01(\t\x12\x0f\n\x07\x64\x65tails\x18\x03 \x01(\t\"\xeb\x01\n\x10\x43reateRunRequest\x12\x0e\n\x06\x66\x61\x62_id\x18\x01 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x02 \x01(\t\x12I\n\x0foverride_config\x18\x03 \x03(\x0b\x32\x30.flwr.proto.CreateRunRequest.OverrideConfigEntry\x12\x1c\n\x03\x66\x61\x62\x18\x04 \x01(\x0b\x32\x0f.flwr.proto.Fab\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\"#\n\x11\x43reateRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"?\n\rGetRunRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0e\n\x06run_id\x18\x02 \x01(\x04\".\n\x0eGetRunResponse\x12\x1c\n\x03run\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Run\"S\n\x16UpdateRunStatusRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12)\n\nrun_status\x18\x02 \x01(\x0b\x32\x15.flwr.proto.RunStatus\"\x19\n\x17UpdateRunStatusResponse\"F\n\x13GetRunStatusRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x0f\n\x07run_ids\x18\x02 \x03(\x04\"\xb1\x01\n\x14GetRunStatusResponse\x12L\n\x0frun_status_dict\x18\x01 \x03(\x0b\x32\x33.flwr.proto.GetRunStatusResponse.RunStatusDictEntry\x1aK\n\x12RunStatusDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.flwr.proto.RunStatus:\x02\x38\x01\"-\n\x1bGetFederationOptionsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"U\n\x1cGetFederationOptionsResponse\x12\x35\n\x12\x66\x65\x64\x65ration_options\x18\x01 \x01(\x0b\x32\x19.flwr.proto.ConfigsRecordb\x06proto3')
22
22
 
23
23
  _globals = globals()
24
24
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -32,33 +32,33 @@ if _descriptor._USE_C_DESCRIPTORS == False:
32
32
  _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._options = None
33
33
  _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_options = b'8\001'
34
34
  _globals['_RUN']._serialized_start=138
35
- _globals['_RUN']._serialized_end=351
36
- _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_start=278
37
- _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_end=351
38
- _globals['_RUNSTATUS']._serialized_start=353
39
- _globals['_RUNSTATUS']._serialized_end=417
40
- _globals['_CREATERUNREQUEST']._serialized_start=420
41
- _globals['_CREATERUNREQUEST']._serialized_end=655
42
- _globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=278
43
- _globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=351
44
- _globals['_CREATERUNRESPONSE']._serialized_start=657
45
- _globals['_CREATERUNRESPONSE']._serialized_end=692
46
- _globals['_GETRUNREQUEST']._serialized_start=694
47
- _globals['_GETRUNREQUEST']._serialized_end=757
48
- _globals['_GETRUNRESPONSE']._serialized_start=759
49
- _globals['_GETRUNRESPONSE']._serialized_end=805
50
- _globals['_UPDATERUNSTATUSREQUEST']._serialized_start=807
51
- _globals['_UPDATERUNSTATUSREQUEST']._serialized_end=890
52
- _globals['_UPDATERUNSTATUSRESPONSE']._serialized_start=892
53
- _globals['_UPDATERUNSTATUSRESPONSE']._serialized_end=917
54
- _globals['_GETRUNSTATUSREQUEST']._serialized_start=919
55
- _globals['_GETRUNSTATUSREQUEST']._serialized_end=989
56
- _globals['_GETRUNSTATUSRESPONSE']._serialized_start=992
57
- _globals['_GETRUNSTATUSRESPONSE']._serialized_end=1169
58
- _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_start=1094
59
- _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_end=1169
60
- _globals['_GETFEDERATIONOPTIONSREQUEST']._serialized_start=1171
61
- _globals['_GETFEDERATIONOPTIONSREQUEST']._serialized_end=1216
62
- _globals['_GETFEDERATIONOPTIONSRESPONSE']._serialized_start=1218
63
- _globals['_GETFEDERATIONOPTIONSRESPONSE']._serialized_end=1303
35
+ _globals['_RUN']._serialized_end=472
36
+ _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_start=399
37
+ _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_end=472
38
+ _globals['_RUNSTATUS']._serialized_start=474
39
+ _globals['_RUNSTATUS']._serialized_end=538
40
+ _globals['_CREATERUNREQUEST']._serialized_start=541
41
+ _globals['_CREATERUNREQUEST']._serialized_end=776
42
+ _globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=399
43
+ _globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=472
44
+ _globals['_CREATERUNRESPONSE']._serialized_start=778
45
+ _globals['_CREATERUNRESPONSE']._serialized_end=813
46
+ _globals['_GETRUNREQUEST']._serialized_start=815
47
+ _globals['_GETRUNREQUEST']._serialized_end=878
48
+ _globals['_GETRUNRESPONSE']._serialized_start=880
49
+ _globals['_GETRUNRESPONSE']._serialized_end=926
50
+ _globals['_UPDATERUNSTATUSREQUEST']._serialized_start=928
51
+ _globals['_UPDATERUNSTATUSREQUEST']._serialized_end=1011
52
+ _globals['_UPDATERUNSTATUSRESPONSE']._serialized_start=1013
53
+ _globals['_UPDATERUNSTATUSRESPONSE']._serialized_end=1038
54
+ _globals['_GETRUNSTATUSREQUEST']._serialized_start=1040
55
+ _globals['_GETRUNSTATUSREQUEST']._serialized_end=1110
56
+ _globals['_GETRUNSTATUSRESPONSE']._serialized_start=1113
57
+ _globals['_GETRUNSTATUSRESPONSE']._serialized_end=1290
58
+ _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_start=1215
59
+ _globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_end=1290
60
+ _globals['_GETFEDERATIONOPTIONSREQUEST']._serialized_start=1292
61
+ _globals['_GETFEDERATIONOPTIONSREQUEST']._serialized_end=1337
62
+ _globals['_GETFEDERATIONOPTIONSRESPONSE']._serialized_start=1339
63
+ _globals['_GETFEDERATIONOPTIONSRESPONSE']._serialized_end=1424
64
64
  # @@protoc_insertion_point(module_scope)
flwr/proto/run_pb2.pyi CHANGED
@@ -37,12 +37,23 @@ class Run(google.protobuf.message.Message):
37
37
  FAB_VERSION_FIELD_NUMBER: builtins.int
38
38
  OVERRIDE_CONFIG_FIELD_NUMBER: builtins.int
39
39
  FAB_HASH_FIELD_NUMBER: builtins.int
40
+ PENDING_AT_FIELD_NUMBER: builtins.int
41
+ STARTING_AT_FIELD_NUMBER: builtins.int
42
+ RUNNING_AT_FIELD_NUMBER: builtins.int
43
+ FINISHED_AT_FIELD_NUMBER: builtins.int
44
+ STATUS_FIELD_NUMBER: builtins.int
40
45
  run_id: builtins.int
41
46
  fab_id: typing.Text
42
47
  fab_version: typing.Text
43
48
  @property
44
49
  def override_config(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, flwr.proto.transport_pb2.Scalar]: ...
45
50
  fab_hash: typing.Text
51
+ pending_at: typing.Text
52
+ starting_at: typing.Text
53
+ running_at: typing.Text
54
+ finished_at: typing.Text
55
+ @property
56
+ def status(self) -> global___RunStatus: ...
46
57
  def __init__(self,
47
58
  *,
48
59
  run_id: builtins.int = ...,
@@ -50,8 +61,14 @@ class Run(google.protobuf.message.Message):
50
61
  fab_version: typing.Text = ...,
51
62
  override_config: typing.Optional[typing.Mapping[typing.Text, flwr.proto.transport_pb2.Scalar]] = ...,
52
63
  fab_hash: typing.Text = ...,
64
+ pending_at: typing.Text = ...,
65
+ starting_at: typing.Text = ...,
66
+ running_at: typing.Text = ...,
67
+ finished_at: typing.Text = ...,
68
+ status: typing.Optional[global___RunStatus] = ...,
53
69
  ) -> None: ...
54
- def ClearField(self, field_name: typing_extensions.Literal["fab_hash",b"fab_hash","fab_id",b"fab_id","fab_version",b"fab_version","override_config",b"override_config","run_id",b"run_id"]) -> None: ...
70
+ def HasField(self, field_name: typing_extensions.Literal["status",b"status"]) -> builtins.bool: ...
71
+ def ClearField(self, field_name: typing_extensions.Literal["fab_hash",b"fab_hash","fab_id",b"fab_id","fab_version",b"fab_version","finished_at",b"finished_at","override_config",b"override_config","pending_at",b"pending_at","run_id",b"run_id","running_at",b"running_at","starting_at",b"starting_at","status",b"status"]) -> None: ...
55
72
  global___Run = Run
56
73
 
57
74
  class RunStatus(google.protobuf.message.Message):
@@ -26,11 +26,7 @@ from flwr.common import DEFAULT_TTL, Message, Metadata, RecordSet
26
26
  from flwr.common.constant import SERVERAPPIO_API_DEFAULT_ADDRESS
27
27
  from flwr.common.grpc import create_channel
28
28
  from flwr.common.logger import log
29
- from flwr.common.serde import (
30
- message_from_taskres,
31
- message_to_taskins,
32
- user_config_from_proto,
33
- )
29
+ from flwr.common.serde import message_from_taskres, message_to_taskins, run_from_proto
34
30
  from flwr.common.typing import Run
35
31
  from flwr.proto.node_pb2 import Node # pylint: disable=E0611
36
32
  from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611
@@ -119,13 +115,7 @@ class GrpcDriver(Driver):
119
115
  res: GetRunResponse = self._stub.GetRun(req)
120
116
  if not res.HasField("run"):
121
117
  raise RuntimeError(f"Cannot find the run with ID: {run_id}")
122
- self._run = Run(
123
- run_id=res.run.run_id,
124
- fab_id=res.run.fab_id,
125
- fab_version=res.run.fab_version,
126
- fab_hash=res.run.fab_hash,
127
- override_config=user_config_from_proto(res.run.override_config),
128
- )
118
+ self._run = run_from_proto(res.run)
129
119
 
130
120
  @property
131
121
  def run(self) -> Run:
@@ -19,7 +19,7 @@ from __future__ import annotations
19
19
 
20
20
  import sys
21
21
  from collections.abc import Awaitable
22
- from typing import Callable, TypeVar
22
+ from typing import Callable, TypeVar, cast
23
23
 
24
24
  from google.protobuf.message import Message as GrpcMessage
25
25
 
@@ -39,8 +39,9 @@ from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
39
39
  )
40
40
  from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611
41
41
  from flwr.server.superlink.ffs.ffs import Ffs
42
+ from flwr.server.superlink.ffs.ffs_factory import FfsFactory
42
43
  from flwr.server.superlink.fleet.message_handler import message_handler
43
- from flwr.server.superlink.linkstate import LinkState
44
+ from flwr.server.superlink.linkstate import LinkState, LinkStateFactory
44
45
 
45
46
  try:
46
47
  from starlette.applications import Starlette
@@ -90,7 +91,7 @@ def rest_request_response(
90
91
  async def create_node(request: CreateNodeRequest) -> CreateNodeResponse:
91
92
  """Create Node."""
92
93
  # Get state from app
93
- state: LinkState = app.state.STATE_FACTORY.state()
94
+ state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
94
95
 
95
96
  # Handle message
96
97
  return message_handler.create_node(request=request, state=state)
@@ -100,7 +101,7 @@ async def create_node(request: CreateNodeRequest) -> CreateNodeResponse:
100
101
  async def delete_node(request: DeleteNodeRequest) -> DeleteNodeResponse:
101
102
  """Delete Node Id."""
102
103
  # Get state from app
103
- state: LinkState = app.state.STATE_FACTORY.state()
104
+ state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
104
105
 
105
106
  # Handle message
106
107
  return message_handler.delete_node(request=request, state=state)
@@ -110,7 +111,7 @@ async def delete_node(request: DeleteNodeRequest) -> DeleteNodeResponse:
110
111
  async def pull_task_ins(request: PullTaskInsRequest) -> PullTaskInsResponse:
111
112
  """Pull TaskIns."""
112
113
  # Get state from app
113
- state: LinkState = app.state.STATE_FACTORY.state()
114
+ state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
114
115
 
115
116
  # Handle message
116
117
  return message_handler.pull_task_ins(request=request, state=state)
@@ -121,7 +122,7 @@ async def pull_task_ins(request: PullTaskInsRequest) -> PullTaskInsResponse:
121
122
  async def push_task_res(request: PushTaskResRequest) -> PushTaskResResponse:
122
123
  """Push TaskRes."""
123
124
  # Get state from app
124
- state: LinkState = app.state.STATE_FACTORY.state()
125
+ state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
125
126
 
126
127
  # Handle message
127
128
  return message_handler.push_task_res(request=request, state=state)
@@ -131,7 +132,7 @@ async def push_task_res(request: PushTaskResRequest) -> PushTaskResResponse:
131
132
  async def ping(request: PingRequest) -> PingResponse:
132
133
  """Ping."""
133
134
  # Get state from app
134
- state: LinkState = app.state.STATE_FACTORY.state()
135
+ state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
135
136
 
136
137
  # Handle message
137
138
  return message_handler.ping(request=request, state=state)
@@ -141,7 +142,7 @@ async def ping(request: PingRequest) -> PingResponse:
141
142
  async def get_run(request: GetRunRequest) -> GetRunResponse:
142
143
  """GetRun."""
143
144
  # Get state from app
144
- state: LinkState = app.state.STATE_FACTORY.state()
145
+ state: LinkState = cast(LinkStateFactory, app.state.STATE_FACTORY).state()
145
146
 
146
147
  # Handle message
147
148
  return message_handler.get_run(request=request, state=state)
@@ -151,7 +152,7 @@ async def get_run(request: GetRunRequest) -> GetRunResponse:
151
152
  async def get_fab(request: GetFabRequest) -> GetFabResponse:
152
153
  """GetRun."""
153
154
  # Get ffs from app
154
- ffs: Ffs = app.state.FFS_FACTORY.state()
155
+ ffs: Ffs = cast(FfsFactory, app.state.FFS_FACTORY).ffs()
155
156
 
156
157
  # Handle message
157
158
  return message_handler.get_fab(request=request, ffs=ffs)
@@ -48,11 +48,6 @@ class RunRecord: # pylint: disable=R0902
48
48
  """The record of a specific run, including its status and timestamps."""
49
49
 
50
50
  run: Run
51
- status: RunStatus
52
- pending_at: str = ""
53
- starting_at: str = ""
54
- running_at: str = ""
55
- finished_at: str = ""
56
51
  logs: list[tuple[float, str]] = field(default_factory=list)
57
52
  log_lock: threading.Lock = field(default_factory=threading.Lock)
58
53
 
@@ -386,13 +381,16 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
386
381
  fab_version=fab_version if fab_version else "",
387
382
  fab_hash=fab_hash if fab_hash else "",
388
383
  override_config=override_config,
384
+ pending_at=now().isoformat(),
385
+ starting_at="",
386
+ running_at="",
387
+ finished_at="",
388
+ status=RunStatus(
389
+ status=Status.PENDING,
390
+ sub_status="",
391
+ details="",
392
+ ),
389
393
  ),
390
- status=RunStatus(
391
- status=Status.PENDING,
392
- sub_status="",
393
- details="",
394
- ),
395
- pending_at=now().isoformat(),
396
394
  )
397
395
  self.run_ids[run_id] = run_record
398
396
 
@@ -452,7 +450,7 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
452
450
  """Retrieve the statuses for the specified runs."""
453
451
  with self.lock:
454
452
  return {
455
- run_id: self.run_ids[run_id].status
453
+ run_id: self.run_ids[run_id].run.status
456
454
  for run_id in set(run_ids)
457
455
  if run_id in self.run_ids
458
456
  }
@@ -466,7 +464,7 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
466
464
  return False
467
465
 
468
466
  # Check if the status transition is valid
469
- current_status = self.run_ids[run_id].status
467
+ current_status = self.run_ids[run_id].run.status
470
468
  if not is_valid_transition(current_status, new_status):
471
469
  log(
472
470
  ERROR,
@@ -489,12 +487,12 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
489
487
  # Update the status
490
488
  run_record = self.run_ids[run_id]
491
489
  if new_status.status == Status.STARTING:
492
- run_record.starting_at = now().isoformat()
490
+ run_record.run.starting_at = now().isoformat()
493
491
  elif new_status.status == Status.RUNNING:
494
- run_record.running_at = now().isoformat()
492
+ run_record.run.running_at = now().isoformat()
495
493
  elif new_status.status == Status.FINISHED:
496
- run_record.finished_at = now().isoformat()
497
- run_record.status = new_status
494
+ run_record.run.finished_at = now().isoformat()
495
+ run_record.run.status = new_status
498
496
  return True
499
497
 
500
498
  def get_pending_run_id(self) -> Optional[int]:
@@ -504,7 +502,7 @@ class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
504
502
  # Loop through all registered runs
505
503
  for run_id, run_rec in self.run_ids.items():
506
504
  # Break once a pending run is found
507
- if run_rec.status.status == Status.PENDING:
505
+ if run_rec.run.status.status == Status.PENDING:
508
506
  pending_run_id = run_id
509
507
  break
510
508
 
@@ -922,6 +922,15 @@ class SqliteLinkState(LinkState): # pylint: disable=R0904
922
922
  fab_version=row["fab_version"],
923
923
  fab_hash=row["fab_hash"],
924
924
  override_config=json.loads(row["override_config"]),
925
+ pending_at=row["pending_at"],
926
+ starting_at=row["starting_at"],
927
+ running_at=row["running_at"],
928
+ finished_at=row["finished_at"],
929
+ status=RunStatus(
930
+ status=determine_run_status(row),
931
+ sub_status=row["sub_status"],
932
+ details=row["details"],
933
+ ),
925
934
  )
926
935
  log(ERROR, "`run_id` does not exist.")
927
936
  return None
@@ -123,13 +123,8 @@ def run_simulation_from_cli() -> None:
123
123
  fused_config = get_fused_config_from_dir(app_path, override_config)
124
124
 
125
125
  # Create run
126
- run = Run(
127
- run_id=run_id,
128
- fab_id="",
129
- fab_version="",
130
- fab_hash="",
131
- override_config=override_config,
132
- )
126
+ run = Run.create_empty(run_id)
127
+ run.override_config = override_config
133
128
 
134
129
  _run_simulation(
135
130
  server_app_attr=server_app_attr,
@@ -333,14 +328,10 @@ def _main_loop(
333
328
  try:
334
329
  # Register run
335
330
  log(DEBUG, "Pre-registering run with id %s", run.run_id)
336
- init_status = RunStatus(Status.RUNNING, "", "")
337
- state_factory.state().run_ids[run.run_id] = RunRecord( # type: ignore
338
- run=run,
339
- status=init_status,
340
- starting_at=now().isoformat(),
341
- running_at=now().isoformat(),
342
- finished_at="",
343
- )
331
+ run.status = RunStatus(Status.RUNNING, "", "")
332
+ run.starting_at = now().isoformat()
333
+ run.running_at = run.starting_at
334
+ state_factory.state().run_ids[run.run_id] = RunRecord(run=run) # type: ignore
344
335
 
345
336
  if server_app_run_config is None:
346
337
  server_app_run_config = {}
@@ -457,9 +448,7 @@ def _run_simulation(
457
448
  # If no `Run` object is set, create one
458
449
  if run is None:
459
450
  run_id = generate_rand_int_from_bytes(RUN_ID_NUM_BYTES)
460
- run = Run(
461
- run_id=run_id, fab_id="", fab_version="", fab_hash="", override_config={}
462
- )
451
+ run = Run.create_empty(run_id=run_id)
463
452
 
464
453
  args = (
465
454
  num_supernodes,
@@ -21,6 +21,7 @@ from typing import Optional
21
21
 
22
22
  from typing_extensions import override
23
23
 
24
+ from flwr.cli.config_utils import get_fab_metadata
24
25
  from flwr.common import ConfigsRecord, Context, RecordSet
25
26
  from flwr.common.constant import SERVERAPPIO_API_DEFAULT_ADDRESS, Status, SubStatus
26
27
  from flwr.common.logger import log
@@ -132,9 +133,10 @@ class DeploymentEngine(Executor):
132
133
  raise RuntimeError(
133
134
  f"FAB ({fab.hash_str}) hash from request doesn't match contents"
134
135
  )
136
+ fab_id, fab_version = get_fab_metadata(fab.content)
135
137
 
136
138
  run_id = self.linkstate.create_run(
137
- None, None, fab_hash, override_config, ConfigsRecord()
139
+ fab_id, fab_version, fab_hash, override_config, ConfigsRecord()
138
140
  )
139
141
  return run_id
140
142
 
@@ -22,18 +22,25 @@ from typing import Any
22
22
 
23
23
  import grpc
24
24
 
25
+ from flwr.common import now
25
26
  from flwr.common.constant import LOG_STREAM_INTERVAL, Status
26
27
  from flwr.common.logger import log
27
- from flwr.common.serde import configs_record_from_proto, user_config_from_proto
28
+ from flwr.common.serde import (
29
+ configs_record_from_proto,
30
+ run_to_proto,
31
+ user_config_from_proto,
32
+ )
28
33
  from flwr.proto import exec_pb2_grpc # pylint: disable=E0611
29
34
  from flwr.proto.exec_pb2 import ( # pylint: disable=E0611
35
+ ListRunsRequest,
36
+ ListRunsResponse,
30
37
  StartRunRequest,
31
38
  StartRunResponse,
32
39
  StreamLogsRequest,
33
40
  StreamLogsResponse,
34
41
  )
35
42
  from flwr.server.superlink.ffs.ffs_factory import FfsFactory
36
- from flwr.server.superlink.linkstate import LinkStateFactory
43
+ from flwr.server.superlink.linkstate import LinkState, LinkStateFactory
37
44
 
38
45
  from .executor import Executor
39
46
 
@@ -105,3 +112,25 @@ class ExecServicer(exec_pb2_grpc.ExecServicer):
105
112
  context.cancel()
106
113
 
107
114
  time.sleep(LOG_STREAM_INTERVAL) # Sleep briefly to avoid busy waiting
115
+
116
+ def ListRuns(
117
+ self, request: ListRunsRequest, context: grpc.ServicerContext
118
+ ) -> ListRunsResponse:
119
+ """Handle `flwr ls` command."""
120
+ log(INFO, "ExecServicer.List")
121
+ state = self.linkstate_factory.state()
122
+
123
+ # Handle `flwr ls --runs`
124
+ if not request.HasField("run_id"):
125
+ return _create_list_runs_response(state.get_run_ids(), state)
126
+ # Handle `flwr ls --run-id <run_id>`
127
+ return _create_list_runs_response({request.run_id}, state)
128
+
129
+
130
+ def _create_list_runs_response(run_ids: set[int], state: LinkState) -> ListRunsResponse:
131
+ """Create response for `flwr ls --runs` and `flwr ls --run-id <run_id>`."""
132
+ run_dict = {run_id: state.get_run(run_id) for run_id in run_ids}
133
+ return ListRunsResponse(
134
+ run_dict={run_id: run_to_proto(run) for run_id, run in run_dict.items() if run},
135
+ now=now().isoformat(),
136
+ )