flwr-nightly 1.11.0.dev20240724__py3-none-any.whl → 1.11.0.dev20240811__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 (59) hide show
  1. flwr/cli/build.py +22 -20
  2. flwr/cli/config_utils.py +27 -8
  3. flwr/cli/new/new.py +23 -22
  4. flwr/cli/new/templates/app/README.md.tpl +1 -1
  5. flwr/cli/new/templates/app/code/__init__.py.tpl +1 -1
  6. flwr/cli/new/templates/app/code/client.huggingface.py.tpl +1 -1
  7. flwr/cli/new/templates/app/code/client.jax.py.tpl +1 -1
  8. flwr/cli/new/templates/app/code/client.mlx.py.tpl +1 -1
  9. flwr/cli/new/templates/app/code/client.numpy.py.tpl +1 -1
  10. flwr/cli/new/templates/app/code/client.pytorch.py.tpl +9 -8
  11. flwr/cli/new/templates/app/code/client.sklearn.py.tpl +1 -1
  12. flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +5 -8
  13. flwr/cli/new/templates/app/code/server.huggingface.py.tpl +1 -1
  14. flwr/cli/new/templates/app/code/server.jax.py.tpl +1 -1
  15. flwr/cli/new/templates/app/code/server.mlx.py.tpl +1 -1
  16. flwr/cli/new/templates/app/code/server.numpy.py.tpl +1 -1
  17. flwr/cli/new/templates/app/code/server.pytorch.py.tpl +7 -6
  18. flwr/cli/new/templates/app/code/server.sklearn.py.tpl +1 -1
  19. flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +4 -5
  20. flwr/cli/new/templates/app/code/task.huggingface.py.tpl +1 -1
  21. flwr/cli/new/templates/app/code/task.jax.py.tpl +2 -2
  22. flwr/cli/new/templates/app/code/task.mlx.py.tpl +2 -1
  23. flwr/cli/new/templates/app/code/task.pytorch.py.tpl +14 -20
  24. flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +16 -4
  25. flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +2 -2
  26. flwr/cli/new/templates/app/pyproject.jax.toml.tpl +1 -1
  27. flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +3 -3
  28. flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +1 -1
  29. flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +3 -2
  30. flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +2 -2
  31. flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +2 -2
  32. flwr/cli/run/run.py +15 -12
  33. flwr/client/grpc_rere_client/grpc_adapter.py +7 -0
  34. flwr/client/supernode/app.py +36 -28
  35. flwr/common/config.py +30 -0
  36. flwr/common/typing.py +8 -0
  37. flwr/proto/driver_pb2.py +22 -21
  38. flwr/proto/driver_pb2.pyi +7 -1
  39. flwr/proto/driver_pb2_grpc.py +35 -0
  40. flwr/proto/driver_pb2_grpc.pyi +14 -0
  41. flwr/proto/fab_pb2.py +6 -6
  42. flwr/proto/fab_pb2.pyi +8 -8
  43. flwr/proto/fleet_pb2.py +28 -27
  44. flwr/proto/fleet_pb2_grpc.py +35 -0
  45. flwr/proto/fleet_pb2_grpc.pyi +14 -0
  46. flwr/proto/run_pb2.py +8 -8
  47. flwr/proto/run_pb2.pyi +4 -1
  48. flwr/server/run_serverapp.py +28 -46
  49. flwr/server/superlink/driver/driver_servicer.py +7 -0
  50. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +7 -0
  51. flwr/server/superlink/fleet/vce/backend/backend.py +1 -1
  52. flwr/server/superlink/fleet/vce/backend/raybackend.py +4 -35
  53. flwr/server/superlink/fleet/vce/vce_api.py +3 -3
  54. flwr/superexec/simulation.py +15 -3
  55. {flwr_nightly-1.11.0.dev20240724.dist-info → flwr_nightly-1.11.0.dev20240811.dist-info}/METADATA +2 -2
  56. {flwr_nightly-1.11.0.dev20240724.dist-info → flwr_nightly-1.11.0.dev20240811.dist-info}/RECORD +59 -59
  57. {flwr_nightly-1.11.0.dev20240724.dist-info → flwr_nightly-1.11.0.dev20240811.dist-info}/LICENSE +0 -0
  58. {flwr_nightly-1.11.0.dev20240724.dist-info → flwr_nightly-1.11.0.dev20240811.dist-info}/WHEEL +0 -0
  59. {flwr_nightly-1.11.0.dev20240724.dist-info → flwr_nightly-1.11.0.dev20240811.dist-info}/entry_points.txt +0 -0
flwr/proto/fleet_pb2.py CHANGED
@@ -15,9 +15,10 @@ _sym_db = _symbol_database.Default()
15
15
  from flwr.proto import node_pb2 as flwr_dot_proto_dot_node__pb2
16
16
  from flwr.proto import task_pb2 as flwr_dot_proto_dot_task__pb2
17
17
  from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2
18
+ from flwr.proto import fab_pb2 as flwr_dot_proto_dot_fab__pb2
18
19
 
19
20
 
20
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x66lwr/proto/fleet.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x15\x66lwr/proto/task.proto\x1a\x14\x66lwr/proto/run.proto\"*\n\x11\x43reateNodeRequest\x12\x15\n\rping_interval\x18\x01 \x01(\x01\"4\n\x12\x43reateNodeResponse\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"3\n\x11\x44\x65leteNodeRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"\x14\n\x12\x44\x65leteNodeResponse\"D\n\x0bPingRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x15\n\rping_interval\x18\x02 \x01(\x01\"\x1f\n\x0cPingResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\"F\n\x12PullTaskInsRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"k\n\x13PullTaskInsResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12*\n\rtask_ins_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.TaskIns\"@\n\x12PushTaskResRequest\x12*\n\rtask_res_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskRes\"\xae\x01\n\x13PushTaskResResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12=\n\x07results\x18\x02 \x03(\x0b\x32,.flwr.proto.PushTaskResResponse.ResultsEntry\x1a.\n\x0cResultsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\r:\x02\x38\x01\"\x1e\n\tReconnect\x12\x11\n\treconnect\x18\x01 \x01(\x04\x32\xc9\x03\n\x05\x46leet\x12M\n\nCreateNode\x12\x1d.flwr.proto.CreateNodeRequest\x1a\x1e.flwr.proto.CreateNodeResponse\"\x00\x12M\n\nDeleteNode\x12\x1d.flwr.proto.DeleteNodeRequest\x1a\x1e.flwr.proto.DeleteNodeResponse\"\x00\x12;\n\x04Ping\x12\x17.flwr.proto.PingRequest\x1a\x18.flwr.proto.PingResponse\"\x00\x12P\n\x0bPullTaskIns\x12\x1e.flwr.proto.PullTaskInsRequest\x1a\x1f.flwr.proto.PullTaskInsResponse\"\x00\x12P\n\x0bPushTaskRes\x12\x1e.flwr.proto.PushTaskResRequest\x1a\x1f.flwr.proto.PushTaskResResponse\"\x00\x12\x41\n\x06GetRun\x12\x19.flwr.proto.GetRunRequest\x1a\x1a.flwr.proto.GetRunResponse\"\x00\x62\x06proto3')
21
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x66lwr/proto/fleet.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x15\x66lwr/proto/task.proto\x1a\x14\x66lwr/proto/run.proto\x1a\x14\x66lwr/proto/fab.proto\"*\n\x11\x43reateNodeRequest\x12\x15\n\rping_interval\x18\x01 \x01(\x01\"4\n\x12\x43reateNodeResponse\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"3\n\x11\x44\x65leteNodeRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"\x14\n\x12\x44\x65leteNodeResponse\"D\n\x0bPingRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x15\n\rping_interval\x18\x02 \x01(\x01\"\x1f\n\x0cPingResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\"F\n\x12PullTaskInsRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"k\n\x13PullTaskInsResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12*\n\rtask_ins_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.TaskIns\"@\n\x12PushTaskResRequest\x12*\n\rtask_res_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskRes\"\xae\x01\n\x13PushTaskResResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12=\n\x07results\x18\x02 \x03(\x0b\x32,.flwr.proto.PushTaskResResponse.ResultsEntry\x1a.\n\x0cResultsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\r:\x02\x38\x01\"\x1e\n\tReconnect\x12\x11\n\treconnect\x18\x01 \x01(\x04\x32\x8c\x04\n\x05\x46leet\x12M\n\nCreateNode\x12\x1d.flwr.proto.CreateNodeRequest\x1a\x1e.flwr.proto.CreateNodeResponse\"\x00\x12M\n\nDeleteNode\x12\x1d.flwr.proto.DeleteNodeRequest\x1a\x1e.flwr.proto.DeleteNodeResponse\"\x00\x12;\n\x04Ping\x12\x17.flwr.proto.PingRequest\x1a\x18.flwr.proto.PingResponse\"\x00\x12P\n\x0bPullTaskIns\x12\x1e.flwr.proto.PullTaskInsRequest\x1a\x1f.flwr.proto.PullTaskInsResponse\"\x00\x12P\n\x0bPushTaskRes\x12\x1e.flwr.proto.PushTaskResRequest\x1a\x1f.flwr.proto.PushTaskResResponse\"\x00\x12\x41\n\x06GetRun\x12\x19.flwr.proto.GetRunRequest\x1a\x1a.flwr.proto.GetRunResponse\"\x00\x12\x41\n\x06GetFab\x12\x19.flwr.proto.GetFabRequest\x1a\x1a.flwr.proto.GetFabResponse\"\x00\x62\x06proto3')
21
22
 
22
23
  _globals = globals()
23
24
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -26,30 +27,30 @@ if _descriptor._USE_C_DESCRIPTORS == False:
26
27
  DESCRIPTOR._options = None
27
28
  _globals['_PUSHTASKRESRESPONSE_RESULTSENTRY']._options = None
28
29
  _globals['_PUSHTASKRESRESPONSE_RESULTSENTRY']._serialized_options = b'8\001'
29
- _globals['_CREATENODEREQUEST']._serialized_start=106
30
- _globals['_CREATENODEREQUEST']._serialized_end=148
31
- _globals['_CREATENODERESPONSE']._serialized_start=150
32
- _globals['_CREATENODERESPONSE']._serialized_end=202
33
- _globals['_DELETENODEREQUEST']._serialized_start=204
34
- _globals['_DELETENODEREQUEST']._serialized_end=255
35
- _globals['_DELETENODERESPONSE']._serialized_start=257
36
- _globals['_DELETENODERESPONSE']._serialized_end=277
37
- _globals['_PINGREQUEST']._serialized_start=279
38
- _globals['_PINGREQUEST']._serialized_end=347
39
- _globals['_PINGRESPONSE']._serialized_start=349
40
- _globals['_PINGRESPONSE']._serialized_end=380
41
- _globals['_PULLTASKINSREQUEST']._serialized_start=382
42
- _globals['_PULLTASKINSREQUEST']._serialized_end=452
43
- _globals['_PULLTASKINSRESPONSE']._serialized_start=454
44
- _globals['_PULLTASKINSRESPONSE']._serialized_end=561
45
- _globals['_PUSHTASKRESREQUEST']._serialized_start=563
46
- _globals['_PUSHTASKRESREQUEST']._serialized_end=627
47
- _globals['_PUSHTASKRESRESPONSE']._serialized_start=630
48
- _globals['_PUSHTASKRESRESPONSE']._serialized_end=804
49
- _globals['_PUSHTASKRESRESPONSE_RESULTSENTRY']._serialized_start=758
50
- _globals['_PUSHTASKRESRESPONSE_RESULTSENTRY']._serialized_end=804
51
- _globals['_RECONNECT']._serialized_start=806
52
- _globals['_RECONNECT']._serialized_end=836
53
- _globals['_FLEET']._serialized_start=839
54
- _globals['_FLEET']._serialized_end=1296
30
+ _globals['_CREATENODEREQUEST']._serialized_start=128
31
+ _globals['_CREATENODEREQUEST']._serialized_end=170
32
+ _globals['_CREATENODERESPONSE']._serialized_start=172
33
+ _globals['_CREATENODERESPONSE']._serialized_end=224
34
+ _globals['_DELETENODEREQUEST']._serialized_start=226
35
+ _globals['_DELETENODEREQUEST']._serialized_end=277
36
+ _globals['_DELETENODERESPONSE']._serialized_start=279
37
+ _globals['_DELETENODERESPONSE']._serialized_end=299
38
+ _globals['_PINGREQUEST']._serialized_start=301
39
+ _globals['_PINGREQUEST']._serialized_end=369
40
+ _globals['_PINGRESPONSE']._serialized_start=371
41
+ _globals['_PINGRESPONSE']._serialized_end=402
42
+ _globals['_PULLTASKINSREQUEST']._serialized_start=404
43
+ _globals['_PULLTASKINSREQUEST']._serialized_end=474
44
+ _globals['_PULLTASKINSRESPONSE']._serialized_start=476
45
+ _globals['_PULLTASKINSRESPONSE']._serialized_end=583
46
+ _globals['_PUSHTASKRESREQUEST']._serialized_start=585
47
+ _globals['_PUSHTASKRESREQUEST']._serialized_end=649
48
+ _globals['_PUSHTASKRESRESPONSE']._serialized_start=652
49
+ _globals['_PUSHTASKRESRESPONSE']._serialized_end=826
50
+ _globals['_PUSHTASKRESRESPONSE_RESULTSENTRY']._serialized_start=780
51
+ _globals['_PUSHTASKRESRESPONSE_RESULTSENTRY']._serialized_end=826
52
+ _globals['_RECONNECT']._serialized_start=828
53
+ _globals['_RECONNECT']._serialized_end=858
54
+ _globals['_FLEET']._serialized_start=861
55
+ _globals['_FLEET']._serialized_end=1385
55
56
  # @@protoc_insertion_point(module_scope)
@@ -2,6 +2,7 @@
2
2
  """Client and server classes corresponding to protobuf-defined services."""
3
3
  import grpc
4
4
 
5
+ from flwr.proto import fab_pb2 as flwr_dot_proto_dot_fab__pb2
5
6
  from flwr.proto import fleet_pb2 as flwr_dot_proto_dot_fleet__pb2
6
7
  from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2
7
8
 
@@ -45,6 +46,11 @@ class FleetStub(object):
45
46
  request_serializer=flwr_dot_proto_dot_run__pb2.GetRunRequest.SerializeToString,
46
47
  response_deserializer=flwr_dot_proto_dot_run__pb2.GetRunResponse.FromString,
47
48
  )
49
+ self.GetFab = channel.unary_unary(
50
+ '/flwr.proto.Fleet/GetFab',
51
+ request_serializer=flwr_dot_proto_dot_fab__pb2.GetFabRequest.SerializeToString,
52
+ response_deserializer=flwr_dot_proto_dot_fab__pb2.GetFabResponse.FromString,
53
+ )
48
54
 
49
55
 
50
56
  class FleetServicer(object):
@@ -92,6 +98,13 @@ class FleetServicer(object):
92
98
  context.set_details('Method not implemented!')
93
99
  raise NotImplementedError('Method not implemented!')
94
100
 
101
+ def GetFab(self, request, context):
102
+ """Get FAB
103
+ """
104
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
105
+ context.set_details('Method not implemented!')
106
+ raise NotImplementedError('Method not implemented!')
107
+
95
108
 
96
109
  def add_FleetServicer_to_server(servicer, server):
97
110
  rpc_method_handlers = {
@@ -125,6 +138,11 @@ def add_FleetServicer_to_server(servicer, server):
125
138
  request_deserializer=flwr_dot_proto_dot_run__pb2.GetRunRequest.FromString,
126
139
  response_serializer=flwr_dot_proto_dot_run__pb2.GetRunResponse.SerializeToString,
127
140
  ),
141
+ 'GetFab': grpc.unary_unary_rpc_method_handler(
142
+ servicer.GetFab,
143
+ request_deserializer=flwr_dot_proto_dot_fab__pb2.GetFabRequest.FromString,
144
+ response_serializer=flwr_dot_proto_dot_fab__pb2.GetFabResponse.SerializeToString,
145
+ ),
128
146
  }
129
147
  generic_handler = grpc.method_handlers_generic_handler(
130
148
  'flwr.proto.Fleet', rpc_method_handlers)
@@ -236,3 +254,20 @@ class Fleet(object):
236
254
  flwr_dot_proto_dot_run__pb2.GetRunResponse.FromString,
237
255
  options, channel_credentials,
238
256
  insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
257
+
258
+ @staticmethod
259
+ def GetFab(request,
260
+ target,
261
+ options=(),
262
+ channel_credentials=None,
263
+ call_credentials=None,
264
+ insecure=False,
265
+ compression=None,
266
+ wait_for_ready=None,
267
+ timeout=None,
268
+ metadata=None):
269
+ return grpc.experimental.unary_unary(request, target, '/flwr.proto.Fleet/GetFab',
270
+ flwr_dot_proto_dot_fab__pb2.GetFabRequest.SerializeToString,
271
+ flwr_dot_proto_dot_fab__pb2.GetFabResponse.FromString,
272
+ options, channel_credentials,
273
+ insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@@ -3,6 +3,7 @@
3
3
  isort:skip_file
4
4
  """
5
5
  import abc
6
+ import flwr.proto.fab_pb2
6
7
  import flwr.proto.fleet_pb2
7
8
  import flwr.proto.run_pb2
8
9
  import grpc
@@ -41,6 +42,11 @@ class FleetStub:
41
42
  flwr.proto.run_pb2.GetRunRequest,
42
43
  flwr.proto.run_pb2.GetRunResponse]
43
44
 
45
+ GetFab: grpc.UnaryUnaryMultiCallable[
46
+ flwr.proto.fab_pb2.GetFabRequest,
47
+ flwr.proto.fab_pb2.GetFabResponse]
48
+ """Get FAB"""
49
+
44
50
 
45
51
  class FleetServicer(metaclass=abc.ABCMeta):
46
52
  @abc.abstractmethod
@@ -89,5 +95,13 @@ class FleetServicer(metaclass=abc.ABCMeta):
89
95
  context: grpc.ServicerContext,
90
96
  ) -> flwr.proto.run_pb2.GetRunResponse: ...
91
97
 
98
+ @abc.abstractmethod
99
+ def GetFab(self,
100
+ request: flwr.proto.fab_pb2.GetFabRequest,
101
+ context: grpc.ServicerContext,
102
+ ) -> flwr.proto.fab_pb2.GetFabResponse:
103
+ """Get FAB"""
104
+ pass
105
+
92
106
 
93
107
  def add_FleetServicer_to_server(servicer: FleetServicer, server: grpc.Server) -> None: ...
flwr/proto/run_pb2.py CHANGED
@@ -15,7 +15,7 @@ _sym_db = _symbol_database.Default()
15
15
  from flwr.proto import transport_pb2 as flwr_dot_proto_dot_transport__pb2
16
16
 
17
17
 
18
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/run.proto\x12\nflwr.proto\x1a\x1a\x66lwr/proto/transport.proto\"\xc3\x01\n\x03Run\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\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\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\"\x1f\n\rGetRunRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\".\n\x0eGetRunResponse\x12\x1c\n\x03run\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Runb\x06proto3')
18
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/run.proto\x12\nflwr.proto\x1a\x1a\x66lwr/proto/transport.proto\"\xd5\x01\n\x03Run\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\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\"\x1f\n\rGetRunRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\".\n\x0eGetRunResponse\x12\x1c\n\x03run\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Runb\x06proto3')
19
19
 
20
20
  _globals = globals()
21
21
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -25,11 +25,11 @@ if _descriptor._USE_C_DESCRIPTORS == False:
25
25
  _globals['_RUN_OVERRIDECONFIGENTRY']._options = None
26
26
  _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_options = b'8\001'
27
27
  _globals['_RUN']._serialized_start=65
28
- _globals['_RUN']._serialized_end=260
29
- _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_start=187
30
- _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_end=260
31
- _globals['_GETRUNREQUEST']._serialized_start=262
32
- _globals['_GETRUNREQUEST']._serialized_end=293
33
- _globals['_GETRUNRESPONSE']._serialized_start=295
34
- _globals['_GETRUNRESPONSE']._serialized_end=341
28
+ _globals['_RUN']._serialized_end=278
29
+ _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_start=205
30
+ _globals['_RUN_OVERRIDECONFIGENTRY']._serialized_end=278
31
+ _globals['_GETRUNREQUEST']._serialized_start=280
32
+ _globals['_GETRUNREQUEST']._serialized_end=311
33
+ _globals['_GETRUNRESPONSE']._serialized_start=313
34
+ _globals['_GETRUNRESPONSE']._serialized_end=359
35
35
  # @@protoc_insertion_point(module_scope)
flwr/proto/run_pb2.pyi CHANGED
@@ -33,19 +33,22 @@ class Run(google.protobuf.message.Message):
33
33
  FAB_ID_FIELD_NUMBER: builtins.int
34
34
  FAB_VERSION_FIELD_NUMBER: builtins.int
35
35
  OVERRIDE_CONFIG_FIELD_NUMBER: builtins.int
36
+ FAB_HASH_FIELD_NUMBER: builtins.int
36
37
  run_id: builtins.int
37
38
  fab_id: typing.Text
38
39
  fab_version: typing.Text
39
40
  @property
40
41
  def override_config(self) -> google.protobuf.internal.containers.MessageMap[typing.Text, flwr.proto.transport_pb2.Scalar]: ...
42
+ fab_hash: typing.Text
41
43
  def __init__(self,
42
44
  *,
43
45
  run_id: builtins.int = ...,
44
46
  fab_id: typing.Text = ...,
45
47
  fab_version: typing.Text = ...,
46
48
  override_config: typing.Optional[typing.Mapping[typing.Text, flwr.proto.transport_pb2.Scalar]] = ...,
49
+ fab_hash: typing.Text = ...,
47
50
  ) -> None: ...
48
- def ClearField(self, field_name: typing_extensions.Literal["fab_id",b"fab_id","fab_version",b"fab_version","override_config",b"override_config","run_id",b"run_id"]) -> None: ...
51
+ 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: ...
49
52
  global___Run = Run
50
53
 
51
54
  class GetRunRequest(google.protobuf.message.Message):
@@ -24,7 +24,8 @@ from typing import Optional
24
24
  from flwr.common import Context, EventType, RecordSet, event
25
25
  from flwr.common.config import (
26
26
  get_flwr_dir,
27
- get_fused_config,
27
+ get_fused_config_from_dir,
28
+ get_metadata_from_config,
28
29
  get_project_config,
29
30
  get_project_dir,
30
31
  )
@@ -146,51 +147,50 @@ def run_server_app() -> None: # pylint: disable=too-many-branches
146
147
  cert_path,
147
148
  )
148
149
 
149
- server_app_attr: Optional[str] = getattr(args, "server-app")
150
- if not (server_app_attr is None) ^ (args.run_id is None):
150
+ app_path: Optional[str] = args.app
151
+ if not (app_path is None) ^ (args.run_id is None):
151
152
  raise sys.exit(
152
- "Please provide either a ServerApp reference or a Run ID, but not both. "
153
+ "Please provide either a Flower App path or a Run ID, but not both. "
153
154
  "For more details, use: ``flower-server-app -h``"
154
155
  )
155
156
 
156
157
  # Initialize GrpcDriver
157
- if args.run_id is not None:
158
- # User provided `--run-id`, but not `server-app`
158
+ if app_path is None:
159
+ # User provided `--run-id`, but not `app_dir`
159
160
  driver = GrpcDriver(
160
161
  run_id=args.run_id,
161
162
  driver_service_address=args.superlink,
162
163
  root_certificates=root_certificates,
163
164
  )
165
+ flwr_dir = get_flwr_dir(args.flwr_dir)
166
+ run_ = driver.run
167
+ app_path = str(get_project_dir(run_.fab_id, run_.fab_version, flwr_dir))
168
+ config = get_project_config(app_path)
164
169
  else:
165
- # User provided `server-app`, but not `--run-id`
170
+ # User provided `app_dir`, but not `--run-id`
166
171
  # Create run if run_id is not provided
167
172
  driver = GrpcDriver(
168
173
  run_id=0, # Will be overwritten
169
174
  driver_service_address=args.superlink,
170
175
  root_certificates=root_certificates,
171
176
  )
177
+ # Load config from the project directory
178
+ config = get_project_config(app_path)
179
+ fab_version, fab_id = get_metadata_from_config(config)
180
+
172
181
  # Create run
173
- req = CreateRunRequest(fab_id=args.fab_id, fab_version=args.fab_version)
182
+ req = CreateRunRequest(fab_id=fab_id, fab_version=fab_version)
174
183
  res: CreateRunResponse = driver._stub.CreateRun(req) # pylint: disable=W0212
175
184
  # Overwrite driver._run_id
176
185
  driver._run_id = res.run_id # pylint: disable=W0212
177
186
 
178
- server_app_run_config = {}
179
-
180
- # Dynamically obtain ServerApp path based on run_id
181
- if args.run_id is not None:
182
- # User provided `--run-id`, but not `server-app`
183
- flwr_dir = get_flwr_dir(args.flwr_dir)
184
- run_ = driver.run
185
- server_app_dir = str(get_project_dir(run_.fab_id, run_.fab_version, flwr_dir))
186
- config = get_project_config(server_app_dir)
187
- server_app_attr = config["tool"]["flwr"]["app"]["components"]["serverapp"]
188
- server_app_run_config = get_fused_config(run_, flwr_dir)
189
- else:
190
- # User provided `server-app`, but not `--run-id`
191
- server_app_dir = str(Path(args.dir).absolute())
187
+ # Obtain server app reference and the run config
188
+ server_app_attr = config["tool"]["flwr"]["app"]["components"]["serverapp"]
189
+ server_app_run_config = get_fused_config_from_dir(
190
+ Path(app_path), driver.run.override_config
191
+ )
192
192
 
193
- log(DEBUG, "Flower will load ServerApp `%s` in %s", server_app_attr, server_app_dir)
193
+ log(DEBUG, "Flower will load ServerApp `%s` in %s", server_app_attr, app_path)
194
194
 
195
195
  log(
196
196
  DEBUG,
@@ -201,7 +201,7 @@ def run_server_app() -> None: # pylint: disable=too-many-branches
201
201
  # Run the ServerApp with the Driver
202
202
  run(
203
203
  driver=driver,
204
- server_app_dir=server_app_dir,
204
+ server_app_dir=app_path,
205
205
  server_app_run_config=server_app_run_config,
206
206
  server_app_attr=server_app_attr,
207
207
  )
@@ -219,15 +219,16 @@ def _parse_args_run_server_app() -> argparse.ArgumentParser:
219
219
  )
220
220
 
221
221
  parser.add_argument(
222
- "server-app",
222
+ "app",
223
223
  nargs="?",
224
224
  default=None,
225
- help="For example: `server:app` or `project.package.module:wrapper.app`",
225
+ help="Load and run the `ServerApp` from the specified Flower App path. "
226
+ "The `pyproject.toml` file must be located in the root of this path.",
226
227
  )
227
228
  parser.add_argument(
228
229
  "--insecure",
229
230
  action="store_true",
230
- help="Run the server app without HTTPS. By default, the app runs with "
231
+ help="Run the `ServerApp` without HTTPS. By default, the app runs with "
231
232
  "HTTPS enabled. Use this flag only if you understand the risks.",
232
233
  )
233
234
  parser.add_argument(
@@ -252,25 +253,6 @@ def _parse_args_run_server_app() -> argparse.ArgumentParser:
252
253
  default=ADDRESS_DRIVER_API,
253
254
  help="SuperLink Driver API (gRPC-rere) address (IPv4, IPv6, or a domain name)",
254
255
  )
255
- parser.add_argument(
256
- "--dir",
257
- default="",
258
- help="Add specified directory to the PYTHONPATH and load Flower "
259
- "app from there."
260
- " Default: current working directory.",
261
- )
262
- parser.add_argument(
263
- "--fab-id",
264
- default=None,
265
- type=str,
266
- help="The identifier of the FAB used in the run.",
267
- )
268
- parser.add_argument(
269
- "--fab-version",
270
- default=None,
271
- type=str,
272
- help="The version of the FAB used in the run.",
273
- )
274
256
  parser.add_argument(
275
257
  "--run-id",
276
258
  default=None,
@@ -35,6 +35,7 @@ from flwr.proto.driver_pb2 import ( # pylint: disable=E0611
35
35
  PushTaskInsRequest,
36
36
  PushTaskInsResponse,
37
37
  )
38
+ from flwr.proto.fab_pb2 import GetFabRequest, GetFabResponse # pylint: disable=E0611
38
39
  from flwr.proto.node_pb2 import Node # pylint: disable=E0611
39
40
  from flwr.proto.run_pb2 import ( # pylint: disable=E0611
40
41
  GetRunRequest,
@@ -163,6 +164,12 @@ class DriverServicer(driver_pb2_grpc.DriverServicer):
163
164
  )
164
165
  )
165
166
 
167
+ def GetFab(
168
+ self, request: GetFabRequest, context: grpc.ServicerContext
169
+ ) -> GetFabResponse:
170
+ """Will be implemented later."""
171
+ raise NotImplementedError
172
+
166
173
 
167
174
  def _raise_if(validation_error: bool, detail: str) -> None:
168
175
  if validation_error:
@@ -21,6 +21,7 @@ import grpc
21
21
 
22
22
  from flwr.common.logger import log
23
23
  from flwr.proto import fleet_pb2_grpc # pylint: disable=E0611
24
+ from flwr.proto.fab_pb2 import GetFabRequest, GetFabResponse # pylint: disable=E0611
24
25
  from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
25
26
  CreateNodeRequest,
26
27
  CreateNodeResponse,
@@ -101,3 +102,9 @@ class FleetServicer(fleet_pb2_grpc.FleetServicer):
101
102
  request=request,
102
103
  state=self.state_factory.state(),
103
104
  )
105
+
106
+ def GetFab(
107
+ self, request: GetFabRequest, context: grpc.ServicerContext
108
+ ) -> GetFabResponse:
109
+ """Will be implemented later."""
110
+ raise NotImplementedError
@@ -29,7 +29,7 @@ BackendConfig = Dict[str, Dict[str, ConfigsRecordValues]]
29
29
  class Backend(ABC):
30
30
  """Abstract base class for a Simulation Engine Backend."""
31
31
 
32
- def __init__(self, backend_config: BackendConfig, work_dir: str) -> None:
32
+ def __init__(self, backend_config: BackendConfig) -> None:
33
33
  """Construct a backend."""
34
34
 
35
35
  @abstractmethod
@@ -14,9 +14,8 @@
14
14
  # ==============================================================================
15
15
  """Ray backend for the Fleet API using the Simulation Engine."""
16
16
 
17
- import pathlib
18
17
  from logging import DEBUG, ERROR
19
- from typing import Callable, Dict, List, Tuple, Union
18
+ from typing import Callable, Dict, Tuple, Union
20
19
 
21
20
  import ray
22
21
 
@@ -33,7 +32,6 @@ from .backend import Backend, BackendConfig
33
32
 
34
33
  ClientResourcesDict = Dict[str, Union[int, float]]
35
34
  ActorArgsDict = Dict[str, Union[int, float, Callable[[], None]]]
36
- RunTimeEnvDict = Dict[str, Union[str, List[str]]]
37
35
 
38
36
 
39
37
  class RayBackend(Backend):
@@ -42,18 +40,14 @@ class RayBackend(Backend):
42
40
  def __init__(
43
41
  self,
44
42
  backend_config: BackendConfig,
45
- work_dir: str,
46
43
  ) -> None:
47
44
  """Prepare RayBackend by initialising Ray and creating the ActorPool."""
48
45
  log(DEBUG, "Initialising: %s", self.__class__.__name__)
49
46
  log(DEBUG, "Backend config: %s", backend_config)
50
47
 
51
- if not pathlib.Path(work_dir).exists():
52
- raise ValueError(f"Specified work_dir {work_dir} does not exist.")
53
-
54
48
  # Initialise ray
55
49
  self.init_args_key = "init_args"
56
- self.init_ray(backend_config, work_dir)
50
+ self.init_ray(backend_config)
57
51
 
58
52
  # Validate client resources
59
53
  self.client_resources_key = "client_resources"
@@ -68,23 +62,6 @@ class RayBackend(Backend):
68
62
  actor_kwargs=actor_kwargs,
69
63
  )
70
64
 
71
- def _configure_runtime_env(self, work_dir: str) -> RunTimeEnvDict:
72
- """Return list of files/subdirectories to exclude relative to work_dir.
73
-
74
- Without this, Ray will push everything to the Ray Cluster.
75
- """
76
- runtime_env: RunTimeEnvDict = {"working_dir": work_dir}
77
-
78
- excludes = []
79
- path = pathlib.Path(work_dir)
80
- for p in path.rglob("*"):
81
- # Exclude files need to be relative to the working_dir
82
- if p.is_file() and not str(p).endswith(".py"):
83
- excludes.append(str(p.relative_to(path)))
84
- runtime_env["excludes"] = excludes
85
-
86
- return runtime_env
87
-
88
65
  def _validate_client_resources(self, config: BackendConfig) -> ClientResourcesDict:
89
66
  client_resources_config = config.get(self.client_resources_key)
90
67
  client_resources: ClientResourcesDict = {}
@@ -123,26 +100,18 @@ class RayBackend(Backend):
123
100
  actor_args["on_actor_init_fn"] = enable_tf_gpu_growth
124
101
  return actor_args
125
102
 
126
- def init_ray(self, backend_config: BackendConfig, work_dir: str) -> None:
103
+ def init_ray(self, backend_config: BackendConfig) -> None:
127
104
  """Intialises Ray if not already initialised."""
128
105
  if not ray.is_initialized():
129
- # Init ray and append working dir if needed
130
- runtime_env = (
131
- self._configure_runtime_env(work_dir=work_dir) if work_dir else None
132
- )
133
-
134
106
  ray_init_args: Dict[
135
107
  str,
136
- Union[ConfigsRecordValues, RunTimeEnvDict],
108
+ ConfigsRecordValues,
137
109
  ] = {}
138
110
 
139
111
  if backend_config.get(self.init_args_key):
140
112
  for k, v in backend_config[self.init_args_key].items():
141
113
  ray_init_args[k] = v
142
114
 
143
- if runtime_env is not None:
144
- ray_init_args["runtime_env"] = runtime_env
145
-
146
115
  ray.init(**ray_init_args)
147
116
 
148
117
  @property
@@ -339,7 +339,7 @@ def start_vce(
339
339
 
340
340
  def backend_fn() -> Backend:
341
341
  """Instantiate a Backend."""
342
- return backend_type(backend_config, work_dir=app_dir)
342
+ return backend_type(backend_config)
343
343
 
344
344
  # Load ClientApp if needed
345
345
  def _load() -> ClientApp:
@@ -347,9 +347,9 @@ def start_vce(
347
347
  if client_app_attr:
348
348
  app = _get_load_client_app_fn(
349
349
  default_app_ref=client_app_attr,
350
- project_dir=app_dir,
350
+ app_path=app_dir,
351
351
  flwr_dir=flwr_dir,
352
- multi_app=True,
352
+ multi_app=False,
353
353
  )(run.fab_id, run.fab_version)
354
354
 
355
355
  if client_app:
@@ -63,8 +63,10 @@ class SimulationEngine(Executor):
63
63
  def __init__(
64
64
  self,
65
65
  num_supernodes: Optional[int] = None,
66
+ verbose: Optional[bool] = False,
66
67
  ) -> None:
67
68
  self.num_supernodes = num_supernodes
69
+ self.verbose = verbose
68
70
 
69
71
  @override
70
72
  def set_config(
@@ -80,6 +82,8 @@ class SimulationEngine(Executor):
80
82
  Supported configuration key/value pairs:
81
83
  - "num-supernodes": int
82
84
  Number of nodes to register for the simulation.
85
+ - "verbose": bool
86
+ Set verbosity of logs.
83
87
  """
84
88
  if num_supernodes := config.get("num-supernodes"):
85
89
  if not isinstance(num_supernodes, int):
@@ -97,6 +101,13 @@ class SimulationEngine(Executor):
97
101
  "positive integer."
98
102
  )
99
103
 
104
+ if verbose := config.get("verbose"):
105
+ if not isinstance(verbose, bool):
106
+ raise ValueError(
107
+ "The `verbose` value must be a string `true` or `false`."
108
+ )
109
+ self.verbose = verbose
110
+
100
111
  @override
101
112
  def start_run(
102
113
  self,
@@ -121,10 +132,11 @@ class SimulationEngine(Executor):
121
132
  fab_path = install_from_fab(fab_file, None, True)
122
133
 
123
134
  # Install FAB Python package
124
- subprocess.check_call(
135
+ subprocess.run(
125
136
  [sys.executable, "-m", "pip", "install", "--no-deps", str(fab_path)],
126
- stdout=subprocess.DEVNULL,
127
- stderr=subprocess.DEVNULL,
137
+ stdout=None if self.verbose else subprocess.DEVNULL,
138
+ stderr=None if self.verbose else subprocess.DEVNULL,
139
+ check=True,
128
140
  )
129
141
 
130
142
  # Load and validate config
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flwr-nightly
3
- Version: 1.11.0.dev20240724
3
+ Version: 1.11.0.dev20240811
4
4
  Summary: Flower: A Friendly Federated Learning Framework
5
5
  Home-page: https://flower.ai
6
6
  License: Apache-2.0
@@ -33,7 +33,7 @@ Classifier: Typing :: Typed
33
33
  Provides-Extra: rest
34
34
  Provides-Extra: simulation
35
35
  Requires-Dist: cryptography (>=42.0.4,<43.0.0)
36
- Requires-Dist: grpcio (>=1.60.0,<2.0.0,!=1.64.2,!=1.65.1)
36
+ Requires-Dist: grpcio (>=1.60.0,<2.0.0,!=1.64.2,!=1.65.1,!=1.65.2,!=1.65.4)
37
37
  Requires-Dist: iterators (>=0.0.2,<0.0.3)
38
38
  Requires-Dist: numpy (>=1.21.0,<2.0.0)
39
39
  Requires-Dist: pathspec (>=0.12.1,<0.13.0)