flwr-nightly 1.13.0.dev20241113__py3-none-any.whl → 1.13.0.dev20241115__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/cli/app.py +2 -0
- flwr/cli/ls.py +228 -0
- flwr/client/app.py +58 -13
- flwr/client/clientapp/app.py +34 -23
- flwr/client/grpc_rere_client/connection.py +2 -12
- flwr/client/rest_client/connection.py +4 -14
- flwr/client/supernode/app.py +56 -18
- flwr/common/constant.py +21 -6
- flwr/common/serde.py +10 -0
- flwr/common/typing.py +31 -10
- flwr/proto/exec_pb2.py +22 -13
- flwr/proto/exec_pb2.pyi +44 -0
- flwr/proto/exec_pb2_grpc.py +34 -0
- flwr/proto/exec_pb2_grpc.pyi +13 -0
- flwr/proto/run_pb2.py +30 -30
- flwr/proto/run_pb2.pyi +18 -1
- flwr/server/app.py +37 -12
- flwr/server/driver/grpc_driver.py +4 -14
- flwr/server/run_serverapp.py +8 -238
- flwr/server/serverapp/app.py +33 -22
- flwr/server/superlink/fleet/rest_rere/rest_api.py +10 -9
- flwr/server/superlink/linkstate/in_memory_linkstate.py +71 -46
- flwr/server/superlink/linkstate/linkstate.py +19 -5
- flwr/server/superlink/linkstate/sqlite_linkstate.py +79 -111
- flwr/server/superlink/linkstate/utils.py +182 -3
- flwr/simulation/app.py +3 -3
- flwr/simulation/legacy_app.py +21 -1
- flwr/simulation/run_simulation.py +7 -18
- flwr/simulation/simulationio_connection.py +2 -2
- flwr/superexec/deployment.py +9 -5
- flwr/superexec/exec_servicer.py +31 -2
- {flwr_nightly-1.13.0.dev20241113.dist-info → flwr_nightly-1.13.0.dev20241115.dist-info}/METADATA +2 -1
- {flwr_nightly-1.13.0.dev20241113.dist-info → flwr_nightly-1.13.0.dev20241115.dist-info}/RECORD +36 -35
- {flwr_nightly-1.13.0.dev20241113.dist-info → flwr_nightly-1.13.0.dev20241115.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.13.0.dev20241113.dist-info → flwr_nightly-1.13.0.dev20241115.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.13.0.dev20241113.dist-info → flwr_nightly-1.13.0.dev20241115.dist-info}/entry_points.txt +0 -0
flwr/client/supernode/app.py
CHANGED
|
@@ -28,9 +28,13 @@ from cryptography.hazmat.primitives.serialization import (
|
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
from flwr.common import EventType, event
|
|
31
|
-
from flwr.common.args import
|
|
31
|
+
from flwr.common.args import (
|
|
32
|
+
try_obtain_root_certificates,
|
|
33
|
+
try_obtain_server_certificates,
|
|
34
|
+
)
|
|
32
35
|
from flwr.common.config import parse_config_args
|
|
33
36
|
from flwr.common.constant import (
|
|
37
|
+
CLIENTAPPIO_API_DEFAULT_SERVER_ADDRESS,
|
|
34
38
|
FLEET_API_GRPC_RERE_DEFAULT_ADDRESS,
|
|
35
39
|
ISOLATION_MODE_PROCESS,
|
|
36
40
|
ISOLATION_MODE_SUBPROCESS,
|
|
@@ -62,10 +66,23 @@ def run_supernode() -> None:
|
|
|
62
66
|
"Ignoring `--flwr-dir`.",
|
|
63
67
|
)
|
|
64
68
|
|
|
69
|
+
# Exit if unsupported argument is passed by the user
|
|
70
|
+
if args.app is not None:
|
|
71
|
+
log(
|
|
72
|
+
ERROR,
|
|
73
|
+
"The `app` argument is deprecated. The SuperNode now automatically "
|
|
74
|
+
"uses the ClientApp delivered from the SuperLink. Providing the app "
|
|
75
|
+
"directory manually is no longer supported. Please remove the `app` "
|
|
76
|
+
"argument from your command.",
|
|
77
|
+
)
|
|
78
|
+
sys.exit(1)
|
|
79
|
+
|
|
65
80
|
root_certificates = try_obtain_root_certificates(args, args.superlink)
|
|
81
|
+
# Obtain certificates for ClientAppIo API server
|
|
82
|
+
server_certificates = try_obtain_server_certificates(args, TRANSPORT_TYPE_GRPC_RERE)
|
|
66
83
|
load_fn = get_load_client_app_fn(
|
|
67
84
|
default_app_ref="",
|
|
68
|
-
app_path=
|
|
85
|
+
app_path=None,
|
|
69
86
|
flwr_dir=args.flwr_dir,
|
|
70
87
|
multi_app=True,
|
|
71
88
|
)
|
|
@@ -87,7 +104,9 @@ def run_supernode() -> None:
|
|
|
87
104
|
),
|
|
88
105
|
flwr_path=args.flwr_dir,
|
|
89
106
|
isolation=args.isolation,
|
|
90
|
-
|
|
107
|
+
clientappio_api_address=args.clientappio_api_address,
|
|
108
|
+
certificates=server_certificates,
|
|
109
|
+
ssl_ca_certfile=args.ssl_ca_certfile,
|
|
91
110
|
)
|
|
92
111
|
|
|
93
112
|
# Graceful shutdown
|
|
@@ -137,12 +156,12 @@ def _parse_args_run_supernode() -> argparse.ArgumentParser:
|
|
|
137
156
|
"app",
|
|
138
157
|
nargs="?",
|
|
139
158
|
default=None,
|
|
140
|
-
help=
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
159
|
+
help=(
|
|
160
|
+
"(REMOVED) This argument is removed. The SuperNode now automatically "
|
|
161
|
+
"uses the ClientApp delivered from the SuperLink, so there is no need to "
|
|
162
|
+
"provide the app directory manually. This argument will be removed in a "
|
|
163
|
+
"future version."
|
|
164
|
+
),
|
|
146
165
|
)
|
|
147
166
|
_parse_args_common(parser)
|
|
148
167
|
parser.add_argument(
|
|
@@ -158,22 +177,22 @@ def _parse_args_run_supernode() -> argparse.ArgumentParser:
|
|
|
158
177
|
)
|
|
159
178
|
parser.add_argument(
|
|
160
179
|
"--isolation",
|
|
161
|
-
default=
|
|
180
|
+
default=ISOLATION_MODE_SUBPROCESS,
|
|
162
181
|
required=False,
|
|
163
182
|
choices=[
|
|
164
183
|
ISOLATION_MODE_SUBPROCESS,
|
|
165
184
|
ISOLATION_MODE_PROCESS,
|
|
166
185
|
],
|
|
167
|
-
help="Isolation mode when running a `ClientApp` (
|
|
168
|
-
"`subprocess`, `process`).
|
|
169
|
-
"
|
|
170
|
-
"
|
|
171
|
-
"independent process gets created outside of SuperNode.",
|
|
186
|
+
help="Isolation mode when running a `ClientApp` (`subprocess` by default, "
|
|
187
|
+
"possible values: `subprocess`, `process`). Use `subprocess` to configure "
|
|
188
|
+
"SuperNode to run a `ClientApp` in a subprocess. Use `process` to indicate "
|
|
189
|
+
"that a separate independent process gets created outside of SuperNode.",
|
|
172
190
|
)
|
|
173
191
|
parser.add_argument(
|
|
174
|
-
"--
|
|
175
|
-
default=
|
|
176
|
-
help="
|
|
192
|
+
"--clientappio-api-address",
|
|
193
|
+
default=CLIENTAPPIO_API_DEFAULT_SERVER_ADDRESS,
|
|
194
|
+
help="ClientAppIo API (gRPC) server address (IPv4, IPv6, or a domain name). "
|
|
195
|
+
f"By default, it is set to {CLIENTAPPIO_API_DEFAULT_SERVER_ADDRESS}.",
|
|
177
196
|
)
|
|
178
197
|
|
|
179
198
|
return parser
|
|
@@ -216,6 +235,25 @@ def _parse_args_common(parser: argparse.ArgumentParser) -> None:
|
|
|
216
235
|
help="Specifies the path to the PEM-encoded root certificate file for "
|
|
217
236
|
"establishing secure HTTPS connections.",
|
|
218
237
|
)
|
|
238
|
+
parser.add_argument(
|
|
239
|
+
"--ssl-certfile",
|
|
240
|
+
help="ClientAppIo API server SSL certificate file (as a path str) "
|
|
241
|
+
"to create a secure connection.",
|
|
242
|
+
type=str,
|
|
243
|
+
default=None,
|
|
244
|
+
)
|
|
245
|
+
parser.add_argument(
|
|
246
|
+
"--ssl-keyfile",
|
|
247
|
+
help="ClientAppIo API server SSL private key file (as a path str) "
|
|
248
|
+
"to create a secure connection.",
|
|
249
|
+
type=str,
|
|
250
|
+
)
|
|
251
|
+
parser.add_argument(
|
|
252
|
+
"--ssl-ca-certfile",
|
|
253
|
+
help="ClientAppIo API server SSL CA certificate file (as a path str) "
|
|
254
|
+
"to create a secure connection.",
|
|
255
|
+
type=str,
|
|
256
|
+
)
|
|
219
257
|
parser.add_argument(
|
|
220
258
|
"--server",
|
|
221
259
|
default=FLEET_API_GRPC_RERE_DEFAULT_ADDRESS,
|
flwr/common/constant.py
CHANGED
|
@@ -38,17 +38,30 @@ TRANSPORT_TYPES = [
|
|
|
38
38
|
]
|
|
39
39
|
|
|
40
40
|
# Addresses
|
|
41
|
+
# Ports
|
|
42
|
+
CLIENTAPPIO_PORT = "9094"
|
|
43
|
+
SERVERAPPIO_PORT = "9091"
|
|
44
|
+
FLEETAPI_GRPC_RERE_PORT = "9092"
|
|
45
|
+
FLEETAPI_PORT = "9095"
|
|
46
|
+
EXEC_API_PORT = "9093"
|
|
47
|
+
SIMULATIONIO_PORT = "9096"
|
|
48
|
+
# Octets
|
|
49
|
+
SERVER_OCTET = "0.0.0.0"
|
|
50
|
+
CLIENT_OCTET = "127.0.0.1"
|
|
41
51
|
# SuperNode
|
|
42
|
-
|
|
52
|
+
CLIENTAPPIO_API_DEFAULT_SERVER_ADDRESS = f"{SERVER_OCTET}:{CLIENTAPPIO_PORT}"
|
|
53
|
+
CLIENTAPPIO_API_DEFAULT_CLIENT_ADDRESS = f"{CLIENT_OCTET}:{CLIENTAPPIO_PORT}"
|
|
43
54
|
# SuperLink
|
|
44
|
-
|
|
45
|
-
|
|
55
|
+
SERVERAPPIO_API_DEFAULT_SERVER_ADDRESS = f"{SERVER_OCTET}:{SERVERAPPIO_PORT}"
|
|
56
|
+
SERVERAPPIO_API_DEFAULT_CLIENT_ADDRESS = f"{CLIENT_OCTET}:{SERVERAPPIO_PORT}"
|
|
57
|
+
FLEET_API_GRPC_RERE_DEFAULT_ADDRESS = f"{SERVER_OCTET}:{FLEETAPI_GRPC_RERE_PORT}"
|
|
46
58
|
FLEET_API_GRPC_BIDI_DEFAULT_ADDRESS = (
|
|
47
59
|
"[::]:8080" # IPv6 to keep start_server compatible
|
|
48
60
|
)
|
|
49
|
-
FLEET_API_REST_DEFAULT_ADDRESS = "
|
|
50
|
-
|
|
51
|
-
|
|
61
|
+
FLEET_API_REST_DEFAULT_ADDRESS = f"{SERVER_OCTET}:{FLEETAPI_PORT}"
|
|
62
|
+
EXEC_API_DEFAULT_SERVER_ADDRESS = f"{SERVER_OCTET}:{EXEC_API_PORT}"
|
|
63
|
+
SIMULATIONIO_API_DEFAULT_SERVER_ADDRESS = f"{SERVER_OCTET}:{SIMULATIONIO_PORT}"
|
|
64
|
+
SIMULATIONIO_API_DEFAULT_CLIENT_ADDRESS = f"{CLIENT_OCTET}:{SIMULATIONIO_PORT}"
|
|
52
65
|
|
|
53
66
|
# Constants for ping
|
|
54
67
|
PING_DEFAULT_INTERVAL = 30
|
|
@@ -134,6 +147,8 @@ class ErrorCode:
|
|
|
134
147
|
UNKNOWN = 0
|
|
135
148
|
LOAD_CLIENT_APP_EXCEPTION = 1
|
|
136
149
|
CLIENT_APP_RAISED_EXCEPTION = 2
|
|
150
|
+
MESSAGE_UNAVAILABLE = 3
|
|
151
|
+
REPLY_MESSAGE_UNAVAILABLE = 4
|
|
137
152
|
|
|
138
153
|
def __new__(cls) -> ErrorCode:
|
|
139
154
|
"""Prevent instantiation."""
|
flwr/common/serde.py
CHANGED
|
@@ -872,6 +872,11 @@ def run_to_proto(run: typing.Run) -> ProtoRun:
|
|
|
872
872
|
fab_version=run.fab_version,
|
|
873
873
|
fab_hash=run.fab_hash,
|
|
874
874
|
override_config=user_config_to_proto(run.override_config),
|
|
875
|
+
pending_at=run.pending_at,
|
|
876
|
+
starting_at=run.starting_at,
|
|
877
|
+
running_at=run.running_at,
|
|
878
|
+
finished_at=run.finished_at,
|
|
879
|
+
status=run_status_to_proto(run.status),
|
|
875
880
|
)
|
|
876
881
|
return proto
|
|
877
882
|
|
|
@@ -884,6 +889,11 @@ def run_from_proto(run_proto: ProtoRun) -> typing.Run:
|
|
|
884
889
|
fab_version=run_proto.fab_version,
|
|
885
890
|
fab_hash=run_proto.fab_hash,
|
|
886
891
|
override_config=user_config_from_proto(run_proto.override_config),
|
|
892
|
+
pending_at=run_proto.pending_at,
|
|
893
|
+
starting_at=run_proto.starting_at,
|
|
894
|
+
running_at=run_proto.running_at,
|
|
895
|
+
finished_at=run_proto.finished_at,
|
|
896
|
+
status=run_status_from_proto(run_proto.status),
|
|
887
897
|
)
|
|
888
898
|
return run
|
|
889
899
|
|
flwr/common/typing.py
CHANGED
|
@@ -208,7 +208,16 @@ class ClientMessage:
|
|
|
208
208
|
|
|
209
209
|
|
|
210
210
|
@dataclass
|
|
211
|
-
class
|
|
211
|
+
class RunStatus:
|
|
212
|
+
"""Run status information."""
|
|
213
|
+
|
|
214
|
+
status: str
|
|
215
|
+
sub_status: str
|
|
216
|
+
details: str
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
@dataclass
|
|
220
|
+
class Run: # pylint: disable=too-many-instance-attributes
|
|
212
221
|
"""Run details."""
|
|
213
222
|
|
|
214
223
|
run_id: int
|
|
@@ -216,15 +225,27 @@ class Run:
|
|
|
216
225
|
fab_version: str
|
|
217
226
|
fab_hash: str
|
|
218
227
|
override_config: UserConfig
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
+
pending_at: str
|
|
229
|
+
starting_at: str
|
|
230
|
+
running_at: str
|
|
231
|
+
finished_at: str
|
|
232
|
+
status: RunStatus
|
|
233
|
+
|
|
234
|
+
@classmethod
|
|
235
|
+
def create_empty(cls, run_id: int) -> "Run":
|
|
236
|
+
"""Return an empty Run instance."""
|
|
237
|
+
return cls(
|
|
238
|
+
run_id=run_id,
|
|
239
|
+
fab_id="",
|
|
240
|
+
fab_version="",
|
|
241
|
+
fab_hash="",
|
|
242
|
+
override_config={},
|
|
243
|
+
pending_at="",
|
|
244
|
+
starting_at="",
|
|
245
|
+
running_at="",
|
|
246
|
+
finished_at="",
|
|
247
|
+
status=RunStatus(status="", sub_status="", details=""),
|
|
248
|
+
)
|
|
228
249
|
|
|
229
250
|
|
|
230
251
|
@dataclass
|
flwr/proto/exec_pb2.py
CHANGED
|
@@ -15,9 +15,10 @@ _sym_db = _symbol_database.Default()
|
|
|
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
17
|
from flwr.proto import recordset_pb2 as flwr_dot_proto_dot_recordset__pb2
|
|
18
|
+
from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2
|
|
18
19
|
|
|
19
20
|
|
|
20
|
-
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\"\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\"\"\n\x10StartRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"<\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\x32\
|
|
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\"\"\n\x10StartRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"<\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\x32\xe9\x01\n\x04\x45xec\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\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\x62\x06proto3')
|
|
21
22
|
|
|
22
23
|
_globals = globals()
|
|
23
24
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
@@ -26,16 +27,24 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
|
|
26
27
|
DESCRIPTOR._options = None
|
|
27
28
|
_globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._options = None
|
|
28
29
|
_globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_options = b'8\001'
|
|
29
|
-
_globals['
|
|
30
|
-
_globals['
|
|
31
|
-
_globals['
|
|
32
|
-
_globals['
|
|
33
|
-
_globals['
|
|
34
|
-
_globals['
|
|
35
|
-
_globals['
|
|
36
|
-
_globals['
|
|
37
|
-
_globals['
|
|
38
|
-
_globals['
|
|
39
|
-
_globals['
|
|
40
|
-
_globals['
|
|
30
|
+
_globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._options = None
|
|
31
|
+
_globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_options = b'8\001'
|
|
32
|
+
_globals['_STARTRUNREQUEST']._serialized_start=138
|
|
33
|
+
_globals['_STARTRUNREQUEST']._serialized_end=389
|
|
34
|
+
_globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=316
|
|
35
|
+
_globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=389
|
|
36
|
+
_globals['_STARTRUNRESPONSE']._serialized_start=391
|
|
37
|
+
_globals['_STARTRUNRESPONSE']._serialized_end=425
|
|
38
|
+
_globals['_STREAMLOGSREQUEST']._serialized_start=427
|
|
39
|
+
_globals['_STREAMLOGSREQUEST']._serialized_end=487
|
|
40
|
+
_globals['_STREAMLOGSRESPONSE']._serialized_start=489
|
|
41
|
+
_globals['_STREAMLOGSRESPONSE']._serialized_end=555
|
|
42
|
+
_globals['_LISTRUNSREQUEST']._serialized_start=557
|
|
43
|
+
_globals['_LISTRUNSREQUEST']._serialized_end=606
|
|
44
|
+
_globals['_LISTRUNSRESPONSE']._serialized_start=609
|
|
45
|
+
_globals['_LISTRUNSRESPONSE']._serialized_end=766
|
|
46
|
+
_globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_start=703
|
|
47
|
+
_globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_end=766
|
|
48
|
+
_globals['_EXEC']._serialized_start=769
|
|
49
|
+
_globals['_EXEC']._serialized_end=1002
|
|
41
50
|
# @@protoc_insertion_point(module_scope)
|
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
|
flwr/proto/exec_pb2_grpc.py
CHANGED
|
@@ -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)
|
flwr/proto/exec_pb2_grpc.pyi
CHANGED
|
@@ -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\"\
|
|
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=
|
|
36
|
-
_globals['_RUN_OVERRIDECONFIGENTRY']._serialized_start=
|
|
37
|
-
_globals['_RUN_OVERRIDECONFIGENTRY']._serialized_end=
|
|
38
|
-
_globals['_RUNSTATUS']._serialized_start=
|
|
39
|
-
_globals['_RUNSTATUS']._serialized_end=
|
|
40
|
-
_globals['_CREATERUNREQUEST']._serialized_start=
|
|
41
|
-
_globals['_CREATERUNREQUEST']._serialized_end=
|
|
42
|
-
_globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=
|
|
43
|
-
_globals['_CREATERUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=
|
|
44
|
-
_globals['_CREATERUNRESPONSE']._serialized_start=
|
|
45
|
-
_globals['_CREATERUNRESPONSE']._serialized_end=
|
|
46
|
-
_globals['_GETRUNREQUEST']._serialized_start=
|
|
47
|
-
_globals['_GETRUNREQUEST']._serialized_end=
|
|
48
|
-
_globals['_GETRUNRESPONSE']._serialized_start=
|
|
49
|
-
_globals['_GETRUNRESPONSE']._serialized_end=
|
|
50
|
-
_globals['_UPDATERUNSTATUSREQUEST']._serialized_start=
|
|
51
|
-
_globals['_UPDATERUNSTATUSREQUEST']._serialized_end=
|
|
52
|
-
_globals['_UPDATERUNSTATUSRESPONSE']._serialized_start=
|
|
53
|
-
_globals['_UPDATERUNSTATUSRESPONSE']._serialized_end=
|
|
54
|
-
_globals['_GETRUNSTATUSREQUEST']._serialized_start=
|
|
55
|
-
_globals['_GETRUNSTATUSREQUEST']._serialized_end=
|
|
56
|
-
_globals['_GETRUNSTATUSRESPONSE']._serialized_start=
|
|
57
|
-
_globals['_GETRUNSTATUSRESPONSE']._serialized_end=
|
|
58
|
-
_globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_start=
|
|
59
|
-
_globals['_GETRUNSTATUSRESPONSE_RUNSTATUSDICTENTRY']._serialized_end=
|
|
60
|
-
_globals['_GETFEDERATIONOPTIONSREQUEST']._serialized_start=
|
|
61
|
-
_globals['_GETFEDERATIONOPTIONSREQUEST']._serialized_end=
|
|
62
|
-
_globals['_GETFEDERATIONOPTIONSRESPONSE']._serialized_start=
|
|
63
|
-
_globals['_GETFEDERATIONOPTIONSRESPONSE']._serialized_end=
|
|
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
|
|
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):
|