flwr-nightly 1.13.0.dev20241111__py3-none-any.whl → 1.14.0.dev20241126__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.

Files changed (53) hide show
  1. flwr/cli/app.py +2 -0
  2. flwr/cli/install.py +0 -16
  3. flwr/cli/ls.py +228 -0
  4. flwr/cli/new/new.py +23 -13
  5. flwr/cli/new/templates/app/README.md.tpl +11 -0
  6. flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +1 -1
  7. flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +1 -1
  8. flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +1 -1
  9. flwr/cli/new/templates/app/pyproject.jax.toml.tpl +1 -1
  10. flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +1 -1
  11. flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +1 -1
  12. flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +1 -1
  13. flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +1 -1
  14. flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +1 -1
  15. flwr/cli/run/run.py +4 -2
  16. flwr/client/app.py +50 -14
  17. flwr/client/clientapp/app.py +40 -23
  18. flwr/client/grpc_rere_client/connection.py +7 -12
  19. flwr/client/rest_client/connection.py +4 -14
  20. flwr/client/supernode/app.py +31 -53
  21. flwr/common/args.py +85 -16
  22. flwr/common/constant.py +24 -6
  23. flwr/common/date.py +18 -0
  24. flwr/common/grpc.py +4 -1
  25. flwr/common/serde.py +10 -0
  26. flwr/common/typing.py +31 -10
  27. flwr/proto/exec_pb2.py +22 -13
  28. flwr/proto/exec_pb2.pyi +44 -0
  29. flwr/proto/exec_pb2_grpc.py +34 -0
  30. flwr/proto/exec_pb2_grpc.pyi +13 -0
  31. flwr/proto/run_pb2.py +30 -30
  32. flwr/proto/run_pb2.pyi +18 -1
  33. flwr/server/app.py +47 -77
  34. flwr/server/driver/grpc_driver.py +66 -16
  35. flwr/server/run_serverapp.py +8 -238
  36. flwr/server/serverapp/app.py +49 -29
  37. flwr/server/superlink/fleet/rest_rere/rest_api.py +10 -9
  38. flwr/server/superlink/linkstate/in_memory_linkstate.py +71 -46
  39. flwr/server/superlink/linkstate/linkstate.py +19 -5
  40. flwr/server/superlink/linkstate/sqlite_linkstate.py +81 -113
  41. flwr/server/superlink/linkstate/utils.py +193 -3
  42. flwr/simulation/app.py +52 -91
  43. flwr/simulation/legacy_app.py +21 -1
  44. flwr/simulation/run_simulation.py +7 -18
  45. flwr/simulation/simulationio_connection.py +2 -2
  46. flwr/superexec/deployment.py +12 -6
  47. flwr/superexec/exec_servicer.py +31 -2
  48. flwr/superexec/simulation.py +11 -46
  49. {flwr_nightly-1.13.0.dev20241111.dist-info → flwr_nightly-1.14.0.dev20241126.dist-info}/METADATA +5 -4
  50. {flwr_nightly-1.13.0.dev20241111.dist-info → flwr_nightly-1.14.0.dev20241126.dist-info}/RECORD +53 -52
  51. {flwr_nightly-1.13.0.dev20241111.dist-info → flwr_nightly-1.14.0.dev20241126.dist-info}/LICENSE +0 -0
  52. {flwr_nightly-1.13.0.dev20241111.dist-info → flwr_nightly-1.14.0.dev20241126.dist-info}/WHEEL +0 -0
  53. {flwr_nightly-1.13.0.dev20241111.dist-info → flwr_nightly-1.14.0.dev20241126.dist-info}/entry_points.txt +0 -0
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\xa0\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\x62\x06proto3')
21
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/exec.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\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['_STARTRUNREQUEST']._serialized_start=116
30
- _globals['_STARTRUNREQUEST']._serialized_end=367
31
- _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=294
32
- _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=367
33
- _globals['_STARTRUNRESPONSE']._serialized_start=369
34
- _globals['_STARTRUNRESPONSE']._serialized_end=403
35
- _globals['_STREAMLOGSREQUEST']._serialized_start=405
36
- _globals['_STREAMLOGSREQUEST']._serialized_end=465
37
- _globals['_STREAMLOGSRESPONSE']._serialized_start=467
38
- _globals['_STREAMLOGSRESPONSE']._serialized_end=533
39
- _globals['_EXEC']._serialized_start=536
40
- _globals['_EXEC']._serialized_end=696
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
@@ -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):
flwr/server/app.py CHANGED
@@ -22,7 +22,6 @@ import sys
22
22
  import threading
23
23
  from collections.abc import Sequence
24
24
  from logging import DEBUG, INFO, WARN
25
- from os.path import isfile
26
25
  from pathlib import Path
27
26
  from time import sleep
28
27
  from typing import Optional
@@ -37,23 +36,26 @@ from cryptography.hazmat.primitives.serialization import (
37
36
 
38
37
  from flwr.common import GRPC_MAX_MESSAGE_LENGTH, EventType, event
39
38
  from flwr.common.address import parse_address
39
+ from flwr.common.args import try_obtain_server_certificates
40
40
  from flwr.common.config import get_flwr_dir, parse_config_args
41
41
  from flwr.common.constant import (
42
- EXEC_API_DEFAULT_ADDRESS,
42
+ CLIENT_OCTET,
43
+ EXEC_API_DEFAULT_SERVER_ADDRESS,
43
44
  FLEET_API_GRPC_BIDI_DEFAULT_ADDRESS,
44
45
  FLEET_API_GRPC_RERE_DEFAULT_ADDRESS,
45
46
  FLEET_API_REST_DEFAULT_ADDRESS,
46
47
  ISOLATION_MODE_PROCESS,
47
48
  ISOLATION_MODE_SUBPROCESS,
48
49
  MISSING_EXTRA_REST,
49
- SERVERAPPIO_API_DEFAULT_ADDRESS,
50
- SIMULATIONIO_API_DEFAULT_ADDRESS,
50
+ SERVER_OCTET,
51
+ SERVERAPPIO_API_DEFAULT_SERVER_ADDRESS,
52
+ SIMULATIONIO_API_DEFAULT_SERVER_ADDRESS,
51
53
  TRANSPORT_TYPE_GRPC_ADAPTER,
52
54
  TRANSPORT_TYPE_GRPC_RERE,
53
55
  TRANSPORT_TYPE_REST,
54
56
  )
55
57
  from flwr.common.exit_handlers import register_exit_handlers
56
- from flwr.common.logger import log
58
+ from flwr.common.logger import log, warn_deprecated_feature
57
59
  from flwr.common.secure_aggregation.crypto.symmetric_encryption import (
58
60
  private_key_to_bytes,
59
61
  public_key_to_bytes,
@@ -99,6 +101,11 @@ def start_server( # pylint: disable=too-many-arguments,too-many-locals
99
101
  ) -> History:
100
102
  """Start a Flower server using the gRPC transport layer.
101
103
 
104
+ Warning
105
+ -------
106
+ This function is deprecated since 1.13.0. Use the :code:`flower-superlink` command
107
+ instead to start a SuperLink.
108
+
102
109
  Parameters
103
110
  ----------
104
111
  server_address : Optional[str]
@@ -156,6 +163,17 @@ def start_server( # pylint: disable=too-many-arguments,too-many-locals
156
163
  >>> )
157
164
  >>> )
158
165
  """
166
+ msg = (
167
+ "flwr.server.start_server() is deprecated."
168
+ "\n\tInstead, use the `flower-superlink` CLI command to start a SuperLink "
169
+ "as shown below:"
170
+ "\n\n\t\t$ flower-superlink --insecure"
171
+ "\n\n\tTo view usage and all available options, run:"
172
+ "\n\n\t\t$ flower-superlink --help"
173
+ "\n\n\tUsing `start_server()` is deprecated."
174
+ )
175
+ warn_deprecated_feature(name=msg)
176
+
159
177
  event(EventType.START_SERVER_ENTER)
160
178
 
161
179
  # Parse IP address
@@ -227,7 +245,7 @@ def run_superlink() -> None:
227
245
  simulationio_address, _, _ = _format_address(args.simulationio_api_address)
228
246
 
229
247
  # Obtain certificates
230
- certificates = _try_obtain_certificates(args)
248
+ certificates = try_obtain_server_certificates(args, args.fleet_api_type)
231
249
 
232
250
  # Initialize StateFactory
233
251
  state_factory = LinkStateFactory(args.database)
@@ -260,7 +278,7 @@ def run_superlink() -> None:
260
278
  address=simulationio_address,
261
279
  state_factory=state_factory,
262
280
  ffs_factory=ffs_factory,
263
- certificates=certificates,
281
+ certificates=None, # SimulationAppIo API doesn't support SSL yet
264
282
  )
265
283
  grpc_servers.append(simulationio_server)
266
284
 
@@ -270,7 +288,7 @@ def run_superlink() -> None:
270
288
  address=serverappio_address,
271
289
  state_factory=state_factory,
272
290
  ffs_factory=ffs_factory,
273
- certificates=certificates,
291
+ certificates=None, # ServerAppIo API doesn't support SSL yet
274
292
  )
275
293
  grpc_servers.append(serverappio_server)
276
294
 
@@ -367,7 +385,14 @@ def run_superlink() -> None:
367
385
 
368
386
  if args.isolation == ISOLATION_MODE_SUBPROCESS:
369
387
 
370
- address = simulationio_address if sim_exec else serverappio_address
388
+ _octet, _colon, _port = serverappio_address.rpartition(":")
389
+ io_address = (
390
+ f"{CLIENT_OCTET}:{_port}" if _octet == SERVER_OCTET else serverappio_address
391
+ )
392
+ address_arg = (
393
+ "--simulationio-api-address" if sim_exec else "--serverappio-api-address"
394
+ )
395
+ address = simulationio_address if sim_exec else io_address
371
396
  cmd = "flwr-simulation" if sim_exec else "flwr-serverapp"
372
397
 
373
398
  # Scheduler thread
@@ -375,8 +400,8 @@ def run_superlink() -> None:
375
400
  target=_flwr_scheduler,
376
401
  args=(
377
402
  state_factory,
403
+ address_arg,
378
404
  address,
379
- args.ssl_ca_certfile,
380
405
  cmd,
381
406
  ),
382
407
  )
@@ -401,8 +426,8 @@ def run_superlink() -> None:
401
426
 
402
427
  def _flwr_scheduler(
403
428
  state_factory: LinkStateFactory,
429
+ io_api_arg: str,
404
430
  io_api_address: str,
405
- ssl_ca_certfile: Optional[str],
406
431
  cmd: str,
407
432
  ) -> None:
408
433
  log(DEBUG, "Started %s scheduler thread.", cmd)
@@ -426,14 +451,10 @@ def _flwr_scheduler(
426
451
  command = [
427
452
  cmd,
428
453
  "--run-once",
429
- "--superlink",
454
+ io_api_arg,
430
455
  io_api_address,
456
+ "--insecure",
431
457
  ]
432
- if ssl_ca_certfile:
433
- command.append("--root-certificates")
434
- command.append(ssl_ca_certfile)
435
- else:
436
- command.append("--insecure")
437
458
 
438
459
  subprocess.Popen( # pylint: disable=consider-using-with
439
460
  command,
@@ -540,60 +561,6 @@ def _try_setup_node_authentication(
540
561
  )
541
562
 
542
563
 
543
- def _try_obtain_certificates(
544
- args: argparse.Namespace,
545
- ) -> Optional[tuple[bytes, bytes, bytes]]:
546
- # Obtain certificates
547
- if args.insecure:
548
- log(WARN, "Option `--insecure` was set. Starting insecure HTTP server.")
549
- return None
550
- # Check if certificates are provided
551
- if args.fleet_api_type in [TRANSPORT_TYPE_GRPC_RERE, TRANSPORT_TYPE_GRPC_ADAPTER]:
552
- if args.ssl_certfile and args.ssl_keyfile and args.ssl_ca_certfile:
553
- if not isfile(args.ssl_ca_certfile):
554
- sys.exit("Path argument `--ssl-ca-certfile` does not point to a file.")
555
- if not isfile(args.ssl_certfile):
556
- sys.exit("Path argument `--ssl-certfile` does not point to a file.")
557
- if not isfile(args.ssl_keyfile):
558
- sys.exit("Path argument `--ssl-keyfile` does not point to a file.")
559
- certificates = (
560
- Path(args.ssl_ca_certfile).read_bytes(), # CA certificate
561
- Path(args.ssl_certfile).read_bytes(), # server certificate
562
- Path(args.ssl_keyfile).read_bytes(), # server private key
563
- )
564
- return certificates
565
- if args.ssl_certfile or args.ssl_keyfile or args.ssl_ca_certfile:
566
- sys.exit(
567
- "You need to provide valid file paths to `--ssl-certfile`, "
568
- "`--ssl-keyfile`, and `—-ssl-ca-certfile` to create a secure "
569
- "connection in Fleet API server (gRPC-rere)."
570
- )
571
- if args.fleet_api_type == TRANSPORT_TYPE_REST:
572
- if args.ssl_certfile and args.ssl_keyfile:
573
- if not isfile(args.ssl_certfile):
574
- sys.exit("Path argument `--ssl-certfile` does not point to a file.")
575
- if not isfile(args.ssl_keyfile):
576
- sys.exit("Path argument `--ssl-keyfile` does not point to a file.")
577
- certificates = (
578
- b"",
579
- Path(args.ssl_certfile).read_bytes(), # server certificate
580
- Path(args.ssl_keyfile).read_bytes(), # server private key
581
- )
582
- return certificates
583
- if args.ssl_certfile or args.ssl_keyfile:
584
- sys.exit(
585
- "You need to provide valid file paths to `--ssl-certfile` "
586
- "and `--ssl-keyfile` to create a secure connection "
587
- "in Fleet API server (REST, experimental)."
588
- )
589
- sys.exit(
590
- "Certificates are required unless running in insecure mode. "
591
- "Please provide certificate paths to `--ssl-certfile`, "
592
- "`--ssl-keyfile`, and `—-ssl-ca-certfile` or run the server "
593
- "in insecure mode using '--insecure' if you understand the risks."
594
- )
595
-
596
-
597
564
  def _run_fleet_api_grpc_rere(
598
565
  address: str,
599
566
  state_factory: LinkStateFactory,
@@ -786,8 +753,9 @@ def _add_args_common(parser: argparse.ArgumentParser) -> None:
786
753
  def _add_args_serverappio_api(parser: argparse.ArgumentParser) -> None:
787
754
  parser.add_argument(
788
755
  "--serverappio-api-address",
789
- help="ServerAppIo API (gRPC) server address (IPv4, IPv6, or a domain name).",
790
- default=SERVERAPPIO_API_DEFAULT_ADDRESS,
756
+ default=SERVERAPPIO_API_DEFAULT_SERVER_ADDRESS,
757
+ help="ServerAppIo API (gRPC) server address (IPv4, IPv6, or a domain name). "
758
+ f"By default, it is set to {SERVERAPPIO_API_DEFAULT_SERVER_ADDRESS}.",
791
759
  )
792
760
 
793
761
 
@@ -820,8 +788,9 @@ def _add_args_exec_api(parser: argparse.ArgumentParser) -> None:
820
788
  """Add command line arguments for Exec API."""
821
789
  parser.add_argument(
822
790
  "--exec-api-address",
823
- help="Exec API server address (IPv4, IPv6, or a domain name)",
824
- default=EXEC_API_DEFAULT_ADDRESS,
791
+ help="Exec API server address (IPv4, IPv6, or a domain name) "
792
+ f"By default, it is set to {EXEC_API_DEFAULT_SERVER_ADDRESS}.",
793
+ default=EXEC_API_DEFAULT_SERVER_ADDRESS,
825
794
  )
826
795
  parser.add_argument(
827
796
  "--executor",
@@ -845,6 +814,7 @@ def _add_args_exec_api(parser: argparse.ArgumentParser) -> None:
845
814
  def _add_args_simulationio_api(parser: argparse.ArgumentParser) -> None:
846
815
  parser.add_argument(
847
816
  "--simulationio-api-address",
848
- help="SimulationIo API (gRPC) server address (IPv4, IPv6, or a domain name).",
849
- default=SIMULATIONIO_API_DEFAULT_ADDRESS,
817
+ default=SIMULATIONIO_API_DEFAULT_SERVER_ADDRESS,
818
+ help="SimulationIo API (gRPC) server address (IPv4, IPv6, or a domain name)."
819
+ f"By default, it is set to {SIMULATIONIO_API_DEFAULT_SERVER_ADDRESS}.",
850
820
  )