flwr-nightly 1.10.0.dev20240722__py3-none-any.whl → 1.11.0.dev20240805__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 (66) hide show
  1. flwr/cli/config_utils.py +40 -23
  2. flwr/cli/new/new.py +7 -6
  3. flwr/cli/new/templates/app/README.md.tpl +1 -1
  4. flwr/cli/new/templates/app/code/__init__.py.tpl +1 -1
  5. flwr/cli/new/templates/app/code/{client.hf.py.tpl → client.huggingface.py.tpl} +8 -6
  6. flwr/cli/new/templates/app/code/client.jax.py.tpl +1 -1
  7. flwr/cli/new/templates/app/code/client.mlx.py.tpl +29 -11
  8. flwr/cli/new/templates/app/code/client.numpy.py.tpl +1 -1
  9. flwr/cli/new/templates/app/code/client.pytorch.py.tpl +16 -13
  10. flwr/cli/new/templates/app/code/client.sklearn.py.tpl +3 -3
  11. flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +20 -13
  12. flwr/cli/new/templates/app/code/flwr_tune/app.py.tpl +20 -17
  13. flwr/cli/new/templates/app/code/flwr_tune/client.py.tpl +5 -3
  14. flwr/cli/new/templates/app/code/{server.hf.py.tpl → server.huggingface.py.tpl} +3 -2
  15. flwr/cli/new/templates/app/code/server.jax.py.tpl +3 -2
  16. flwr/cli/new/templates/app/code/server.mlx.py.tpl +3 -2
  17. flwr/cli/new/templates/app/code/server.numpy.py.tpl +3 -2
  18. flwr/cli/new/templates/app/code/server.pytorch.py.tpl +8 -7
  19. flwr/cli/new/templates/app/code/server.sklearn.py.tpl +3 -2
  20. flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +5 -6
  21. flwr/cli/new/templates/app/code/{task.hf.py.tpl → task.huggingface.py.tpl} +14 -2
  22. flwr/cli/new/templates/app/code/task.jax.py.tpl +2 -2
  23. flwr/cli/new/templates/app/code/task.mlx.py.tpl +15 -2
  24. flwr/cli/new/templates/app/code/task.pytorch.py.tpl +26 -21
  25. flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +29 -5
  26. flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +3 -3
  27. flwr/cli/new/templates/app/{pyproject.hf.toml.tpl → pyproject.huggingface.toml.tpl} +4 -4
  28. flwr/cli/new/templates/app/pyproject.jax.toml.tpl +4 -4
  29. flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +11 -11
  30. flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +4 -4
  31. flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +7 -6
  32. flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +5 -5
  33. flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +8 -8
  34. flwr/cli/run/run.py +31 -27
  35. flwr/client/grpc_rere_client/grpc_adapter.py +7 -0
  36. flwr/client/supernode/app.py +12 -43
  37. flwr/common/config.py +6 -1
  38. flwr/common/object_ref.py +84 -21
  39. flwr/proto/driver_pb2.py +22 -21
  40. flwr/proto/driver_pb2.pyi +7 -1
  41. flwr/proto/driver_pb2_grpc.py +35 -0
  42. flwr/proto/driver_pb2_grpc.pyi +14 -0
  43. flwr/proto/exec_pb2.py +16 -12
  44. flwr/proto/exec_pb2.pyi +20 -1
  45. flwr/proto/fleet_pb2.py +28 -27
  46. flwr/proto/fleet_pb2_grpc.py +35 -0
  47. flwr/proto/fleet_pb2_grpc.pyi +14 -0
  48. flwr/proto/run_pb2.py +8 -8
  49. flwr/proto/run_pb2.pyi +4 -1
  50. flwr/server/run_serverapp.py +0 -3
  51. flwr/server/superlink/driver/driver_servicer.py +7 -0
  52. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +7 -0
  53. flwr/server/superlink/fleet/vce/backend/__init__.py +1 -1
  54. flwr/server/superlink/fleet/vce/vce_api.py +4 -4
  55. flwr/simulation/__init__.py +1 -1
  56. flwr/simulation/run_simulation.py +32 -4
  57. flwr/superexec/app.py +4 -5
  58. flwr/superexec/deployment.py +1 -2
  59. flwr/superexec/exec_servicer.py +3 -1
  60. flwr/superexec/executor.py +3 -0
  61. flwr/superexec/simulation.py +54 -12
  62. {flwr_nightly-1.10.0.dev20240722.dist-info → flwr_nightly-1.11.0.dev20240805.dist-info}/METADATA +1 -1
  63. {flwr_nightly-1.10.0.dev20240722.dist-info → flwr_nightly-1.11.0.dev20240805.dist-info}/RECORD +66 -66
  64. {flwr_nightly-1.10.0.dev20240722.dist-info → flwr_nightly-1.11.0.dev20240805.dist-info}/LICENSE +0 -0
  65. {flwr_nightly-1.10.0.dev20240722.dist-info → flwr_nightly-1.11.0.dev20240805.dist-info}/WHEEL +0 -0
  66. {flwr_nightly-1.10.0.dev20240722.dist-info → flwr_nightly-1.11.0.dev20240805.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):
@@ -57,9 +57,6 @@ def run(
57
57
  "but not both."
58
58
  )
59
59
 
60
- if server_app_dir is not None:
61
- sys.path.insert(0, str(Path(server_app_dir).absolute()))
62
-
63
60
  # Load ServerApp if needed
64
61
  def _load() -> ServerApp:
65
62
  if server_app_attr:
@@ -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
@@ -38,7 +38,7 @@ else:
38
38
 
39
39
  To install the necessary dependencies, install `flwr` with the `simulation` extra:
40
40
 
41
- pip install -U flwr["simulation"]
41
+ pip install -U "flwr[simulation]"
42
42
  """
43
43
 
44
44
 
@@ -72,8 +72,8 @@ def _register_node_states(
72
72
  node_states[node_id] = NodeState(
73
73
  node_id=node_id,
74
74
  node_config={
75
- PARTITION_ID_KEY: str(partition_id),
76
- NUM_PARTITIONS_KEY: str(num_partitions),
75
+ PARTITION_ID_KEY: partition_id,
76
+ NUM_PARTITIONS_KEY: num_partitions,
77
77
  },
78
78
  )
79
79
 
@@ -347,8 +347,8 @@ 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
- dir_arg=app_dir,
351
- flwr_dir_arg=flwr_dir,
350
+ project_dir=app_dir,
351
+ flwr_dir=flwr_dir,
352
352
  multi_app=True,
353
353
  )(run.fab_id, run.fab_version)
354
354
 
@@ -28,7 +28,7 @@ else:
28
28
 
29
29
  To install the necessary dependencies, install `flwr` with the `simulation` extra:
30
30
 
31
- pip install -U flwr["simulation"]
31
+ pip install -U "flwr[simulation]"
32
32
  """
33
33
 
34
34
  def start_simulation(*args, **kwargs): # type: ignore
@@ -32,7 +32,11 @@ from flwr.client import ClientApp
32
32
  from flwr.common import EventType, event, log
33
33
  from flwr.common.config import get_fused_config_from_dir, parse_config_args
34
34
  from flwr.common.constant import RUN_ID_NUM_BYTES
35
- from flwr.common.logger import set_logger_propagation, update_console_handler
35
+ from flwr.common.logger import (
36
+ set_logger_propagation,
37
+ update_console_handler,
38
+ warn_deprecated_feature_with_example,
39
+ )
36
40
  from flwr.common.typing import Run, UserConfig
37
41
  from flwr.server.driver import Driver, InMemoryDriver
38
42
  from flwr.server.run_serverapp import run as run_server_app
@@ -93,6 +97,14 @@ def run_simulation_from_cli() -> None:
93
97
  """Run Simulation Engine from the CLI."""
94
98
  args = _parse_args_run_simulation().parse_args()
95
99
 
100
+ if args.enable_tf_gpu_growth:
101
+ warn_deprecated_feature_with_example(
102
+ "Passing `--enable-tf-gpu-growth` is deprecated.",
103
+ example_message="Instead, set the `TF_FORCE_GPU_ALLOW_GROWTH` environmnet "
104
+ "variable to true.",
105
+ code_example='TF_FORCE_GPU_ALLOW_GROWTH="true" flower-simulation <...>',
106
+ )
107
+
96
108
  # We are supporting two modes for the CLI entrypoint:
97
109
  # 1) Running an app dir containing a `pyproject.toml`
98
110
  # 2) Running any ClientApp and SeverApp w/o pyproject.toml being present
@@ -223,6 +235,15 @@ def run_simulation(
223
235
  When disabled, only INFO, WARNING and ERROR log messages will be shown. If
224
236
  enabled, DEBUG-level logs will be displayed.
225
237
  """
238
+ if enable_tf_gpu_growth:
239
+ warn_deprecated_feature_with_example(
240
+ "Passing `enable_tf_gpu_growth=True` is deprecated.",
241
+ example_message="Instead, set the `TF_FORCE_GPU_ALLOW_GROWTH` environmnet "
242
+ "variable to true.",
243
+ code_example='import os;os.environ["TF_FORCE_GPU_ALLOW_GROWTH"]="true"'
244
+ "\n\tflwr.simulation.run_simulationt(...)",
245
+ )
246
+
226
247
  _run_simulation(
227
248
  num_supernodes=num_supernodes,
228
249
  client_app=client_app,
@@ -264,7 +285,7 @@ def run_serverapp_th(
264
285
  """
265
286
  try:
266
287
  if tf_gpu_growth:
267
- log(INFO, "Enabling GPU growth for Tensorflow on the main thread.")
288
+ log(INFO, "Enabling GPU growth for Tensorflow on the server thread.")
268
289
  enable_gpu_growth()
269
290
 
270
291
  # Run ServerApp
@@ -475,6 +496,14 @@ def _run_simulation(
475
496
  if "init_args" not in backend_config:
476
497
  backend_config["init_args"] = {}
477
498
 
499
+ # Set default client_resources if not passed
500
+ if "client_resources" not in backend_config:
501
+ backend_config["client_resources"] = {"num_cpus": 2, "num_gpus": 0}
502
+
503
+ # Initialization of backend config to enable GPU growth globally when set
504
+ if "actor" not in backend_config:
505
+ backend_config["actor"] = {"tensorflow": 0}
506
+
478
507
  # Set logging level
479
508
  logger = logging.getLogger("flwr")
480
509
  if verbose_logging:
@@ -580,8 +609,7 @@ def _parse_args_run_simulation() -> argparse.ArgumentParser:
580
609
  parser.add_argument(
581
610
  "--backend-config",
582
611
  type=str,
583
- default='{"client_resources": {"num_cpus":2, "num_gpus":0.0},'
584
- '"actor": {"tensorflow": 0}}',
612
+ default="{}",
585
613
  help='A JSON formatted stream, e.g \'{"<keyA>":<value>, "<keyB>":<value>}\' to '
586
614
  "configure a backend. Values supported in <value> are those included by "
587
615
  "`flwr.common.typing.ConfigsRecordValues`. ",
flwr/superexec/app.py CHANGED
@@ -93,7 +93,9 @@ def _parse_args_run_superexec() -> argparse.ArgumentParser:
93
93
  )
94
94
  parser.add_argument(
95
95
  "--executor-config",
96
- help="Key-value pairs for the executor config, separated by commas.",
96
+ help="Key-value pairs for the executor config, separated by commas. "
97
+ 'For example:\n\n`--executor-config superlink="superlink:9091",'
98
+ 'root-certificates="certificates/superlink-ca.crt"`',
97
99
  )
98
100
  parser.add_argument(
99
101
  "--insecure",
@@ -163,11 +165,8 @@ def _load_executor(
163
165
  args: argparse.Namespace,
164
166
  ) -> Executor:
165
167
  """Get the executor plugin."""
166
- if args.executor_dir is not None:
167
- sys.path.insert(0, args.executor_dir)
168
-
169
168
  executor_ref: str = args.executor
170
- valid, error_msg = validate(executor_ref)
169
+ valid, error_msg = validate(executor_ref, project_dir=args.executor_dir)
171
170
  if not valid and error_msg:
172
171
  raise LoadExecutorError(error_msg) from None
173
172
 
@@ -135,6 +135,7 @@ class DeploymentEngine(Executor):
135
135
  self,
136
136
  fab_file: bytes,
137
137
  override_config: UserConfig,
138
+ federation_config: UserConfig,
138
139
  ) -> Optional[RunTracker]:
139
140
  """Start run using the Flower Deployment Engine."""
140
141
  try:
@@ -167,8 +168,6 @@ class DeploymentEngine(Executor):
167
168
  # Execute the command
168
169
  proc = subprocess.Popen( # pylint: disable=consider-using-with
169
170
  command,
170
- stdout=subprocess.PIPE,
171
- stderr=subprocess.PIPE,
172
171
  text=True,
173
172
  )
174
173
  log(INFO, "Started run %s", str(run_id))
@@ -47,7 +47,9 @@ class ExecServicer(exec_pb2_grpc.ExecServicer):
47
47
  log(INFO, "ExecServicer.StartRun")
48
48
 
49
49
  run = self.executor.start_run(
50
- request.fab_file, user_config_from_proto(request.override_config)
50
+ request.fab_file,
51
+ user_config_from_proto(request.override_config),
52
+ user_config_from_proto(request.federation_config),
51
53
  )
52
54
 
53
55
  if run is None:
@@ -51,6 +51,7 @@ class Executor(ABC):
51
51
  self,
52
52
  fab_file: bytes,
53
53
  override_config: UserConfig,
54
+ federation_config: UserConfig,
54
55
  ) -> Optional[RunTracker]:
55
56
  """Start a run using the given Flower FAB ID and version.
56
57
 
@@ -63,6 +64,8 @@ class Executor(ABC):
63
64
  The Flower App Bundle file bytes.
64
65
  override_config: UserConfig
65
66
  The config overrides dict sent by the user (using `flwr run`).
67
+ federation_config: UserConfig
68
+ The federation options dict sent by the user (using `flwr run`).
66
69
 
67
70
  Returns
68
71
  -------
@@ -32,6 +32,25 @@ from flwr.server.superlink.state.utils import generate_rand_int_from_bytes
32
32
  from .executor import Executor, RunTracker
33
33
 
34
34
 
35
+ def _user_config_to_str(user_config: UserConfig) -> str:
36
+ """Convert override user config to string."""
37
+ user_config_list_str = []
38
+ for key, value in user_config.items():
39
+ if isinstance(value, bool):
40
+ user_config_list_str.append(f"{key}={str(value).lower()}")
41
+ elif isinstance(value, (int, float)):
42
+ user_config_list_str.append(f"{key}={value}")
43
+ elif isinstance(value, str):
44
+ user_config_list_str.append(f'{key}="{value}"')
45
+ else:
46
+ raise ValueError(
47
+ "Only types `bool`, `float`, `int` and `str` are supported"
48
+ )
49
+
50
+ user_config_str = ",".join(user_config_list_str)
51
+ return user_config_str
52
+
53
+
35
54
  class SimulationEngine(Executor):
36
55
  """Simulation engine executor.
37
56
 
@@ -44,8 +63,10 @@ class SimulationEngine(Executor):
44
63
  def __init__(
45
64
  self,
46
65
  num_supernodes: Optional[int] = None,
66
+ verbose: Optional[bool] = False,
47
67
  ) -> None:
48
68
  self.num_supernodes = num_supernodes
69
+ self.verbose = verbose
49
70
 
50
71
  @override
51
72
  def set_config(
@@ -61,14 +82,14 @@ class SimulationEngine(Executor):
61
82
  Supported configuration key/value pairs:
62
83
  - "num-supernodes": int
63
84
  Number of nodes to register for the simulation.
85
+ - "verbose": bool
86
+ Set verbosity of logs.
64
87
  """
65
- if not config:
66
- return
67
88
  if num_supernodes := config.get("num-supernodes"):
68
89
  if not isinstance(num_supernodes, int):
69
90
  raise ValueError("The `num-supernodes` value should be of type `int`.")
70
91
  self.num_supernodes = num_supernodes
71
- else:
92
+ elif self.num_supernodes is None:
72
93
  log(
73
94
  ERROR,
74
95
  "To start a run with the simulation plugin, please specify "
@@ -80,21 +101,42 @@ class SimulationEngine(Executor):
80
101
  "positive integer."
81
102
  )
82
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
+
83
111
  @override
84
112
  def start_run(
85
- self, fab_file: bytes, override_config: UserConfig
113
+ self,
114
+ fab_file: bytes,
115
+ override_config: UserConfig,
116
+ federation_config: UserConfig,
86
117
  ) -> Optional[RunTracker]:
87
118
  """Start run using the Flower Simulation Engine."""
119
+ if self.num_supernodes is None:
120
+ raise ValueError(
121
+ "Error in `SuperExec` (`SimulationEngine` executor):\n\n"
122
+ "`num-supernodes` must not be `None`, it must be a valid "
123
+ "positive integer. In order to start this simulation executor "
124
+ "with a specified number of `SuperNodes`, you can either provide "
125
+ "a `--executor` that has been initialized with a number of nodes "
126
+ "to the `flower-superexec` CLI, or `--executor-config num-supernodes=N`"
127
+ "to the `flower-superexec` CLI."
128
+ )
88
129
  try:
89
130
 
90
131
  # Install FAB to flwr dir
91
132
  fab_path = install_from_fab(fab_file, None, True)
92
133
 
93
134
  # Install FAB Python package
94
- subprocess.check_call(
135
+ subprocess.run(
95
136
  [sys.executable, "-m", "pip", "install", "--no-deps", str(fab_path)],
96
- stdout=subprocess.DEVNULL,
97
- stderr=subprocess.DEVNULL,
137
+ stdout=None if self.verbose else subprocess.DEVNULL,
138
+ stderr=None if self.verbose else subprocess.DEVNULL,
139
+ check=True,
98
140
  )
99
141
 
100
142
  # Load and validate config
@@ -120,18 +162,18 @@ class SimulationEngine(Executor):
120
162
  "--app",
121
163
  f"{str(fab_path)}",
122
164
  "--num-supernodes",
123
- f"{self.num_supernodes}",
165
+ f"{federation_config.get('num-supernodes', self.num_supernodes)}",
124
166
  "--run-id",
125
167
  str(run_id),
126
168
  ]
127
169
 
128
170
  if override_config:
129
- command.extend(["--run-config", f"{override_config}"])
171
+ override_config_str = _user_config_to_str(override_config)
172
+ command.extend(["--run-config", f"{override_config_str}"])
130
173
 
131
174
  # Start Simulation
132
- proc = subprocess.run( # pylint: disable=consider-using-with
175
+ proc = subprocess.Popen( # pylint: disable=consider-using-with
133
176
  command,
134
- check=True,
135
177
  text=True,
136
178
  )
137
179
 
@@ -139,7 +181,7 @@ class SimulationEngine(Executor):
139
181
 
140
182
  return RunTracker(
141
183
  run_id=run_id,
142
- proc=proc, # type:ignore
184
+ proc=proc,
143
185
  )
144
186
 
145
187
  # pylint: disable-next=broad-except
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flwr-nightly
3
- Version: 1.10.0.dev20240722
3
+ Version: 1.11.0.dev20240805
4
4
  Summary: Flower: A Friendly Federated Learning Framework
5
5
  Home-page: https://flower.ai
6
6
  License: Apache-2.0