flwr-nightly 1.11.0.dev20240813__py3-none-any.whl → 1.11.0.dev20240822__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 (58) hide show
  1. flwr/cli/config_utils.py +2 -2
  2. flwr/cli/install.py +3 -1
  3. flwr/cli/run/run.py +15 -11
  4. flwr/client/app.py +132 -14
  5. flwr/client/clientapp/__init__.py +22 -0
  6. flwr/client/clientapp/app.py +233 -0
  7. flwr/client/clientapp/clientappio_servicer.py +244 -0
  8. flwr/client/clientapp/utils.py +108 -0
  9. flwr/client/grpc_rere_client/connection.py +9 -1
  10. flwr/client/node_state.py +17 -4
  11. flwr/client/rest_client/connection.py +16 -3
  12. flwr/client/supernode/__init__.py +0 -2
  13. flwr/client/supernode/app.py +36 -164
  14. flwr/common/__init__.py +4 -0
  15. flwr/common/config.py +31 -10
  16. flwr/common/record/configsrecord.py +49 -15
  17. flwr/common/record/metricsrecord.py +54 -14
  18. flwr/common/record/parametersrecord.py +84 -17
  19. flwr/common/record/recordset.py +80 -8
  20. flwr/common/record/typeddict.py +20 -58
  21. flwr/common/recordset_compat.py +6 -6
  22. flwr/common/serde.py +24 -2
  23. flwr/common/typing.py +1 -0
  24. flwr/proto/clientappio_pb2.py +17 -13
  25. flwr/proto/clientappio_pb2.pyi +24 -2
  26. flwr/proto/clientappio_pb2_grpc.py +34 -0
  27. flwr/proto/clientappio_pb2_grpc.pyi +13 -0
  28. flwr/proto/exec_pb2.py +16 -15
  29. flwr/proto/exec_pb2.pyi +7 -4
  30. flwr/proto/message_pb2.py +2 -2
  31. flwr/proto/message_pb2.pyi +4 -1
  32. flwr/server/app.py +15 -0
  33. flwr/server/driver/grpc_driver.py +1 -0
  34. flwr/server/run_serverapp.py +18 -2
  35. flwr/server/server.py +3 -1
  36. flwr/server/superlink/driver/driver_grpc.py +3 -0
  37. flwr/server/superlink/driver/driver_servicer.py +32 -4
  38. flwr/server/superlink/ffs/disk_ffs.py +6 -3
  39. flwr/server/superlink/ffs/ffs.py +3 -3
  40. flwr/server/superlink/ffs/ffs_factory.py +47 -0
  41. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +12 -4
  42. flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +8 -2
  43. flwr/server/superlink/fleet/message_handler/message_handler.py +16 -1
  44. flwr/server/superlink/fleet/vce/backend/raybackend.py +5 -2
  45. flwr/server/superlink/fleet/vce/vce_api.py +2 -2
  46. flwr/server/superlink/state/in_memory_state.py +7 -5
  47. flwr/server/superlink/state/sqlite_state.py +17 -7
  48. flwr/server/superlink/state/state.py +4 -3
  49. flwr/server/workflow/default_workflows.py +3 -1
  50. flwr/simulation/run_simulation.py +5 -67
  51. flwr/superexec/app.py +3 -3
  52. flwr/superexec/deployment.py +8 -9
  53. flwr/superexec/exec_servicer.py +1 -1
  54. {flwr_nightly-1.11.0.dev20240813.dist-info → flwr_nightly-1.11.0.dev20240822.dist-info}/METADATA +2 -2
  55. {flwr_nightly-1.11.0.dev20240813.dist-info → flwr_nightly-1.11.0.dev20240822.dist-info}/RECORD +58 -53
  56. {flwr_nightly-1.11.0.dev20240813.dist-info → flwr_nightly-1.11.0.dev20240822.dist-info}/entry_points.txt +1 -1
  57. {flwr_nightly-1.11.0.dev20240813.dist-info → flwr_nightly-1.11.0.dev20240822.dist-info}/LICENSE +0 -0
  58. {flwr_nightly-1.11.0.dev20240813.dist-info → flwr_nightly-1.11.0.dev20240822.dist-info}/WHEEL +0 -0
@@ -15,8 +15,10 @@
15
15
  """RecordSet."""
16
16
 
17
17
 
18
+ from __future__ import annotations
19
+
18
20
  from dataclasses import dataclass
19
- from typing import Dict, Optional, cast
21
+ from typing import cast
20
22
 
21
23
  from .configsrecord import ConfigsRecord
22
24
  from .metricsrecord import MetricsRecord
@@ -34,9 +36,9 @@ class RecordSetData:
34
36
 
35
37
  def __init__(
36
38
  self,
37
- parameters_records: Optional[Dict[str, ParametersRecord]] = None,
38
- metrics_records: Optional[Dict[str, MetricsRecord]] = None,
39
- configs_records: Optional[Dict[str, ConfigsRecord]] = None,
39
+ parameters_records: dict[str, ParametersRecord] | None = None,
40
+ metrics_records: dict[str, MetricsRecord] | None = None,
41
+ configs_records: dict[str, ConfigsRecord] | None = None,
40
42
  ) -> None:
41
43
  self.parameters_records = TypedDict[str, ParametersRecord](
42
44
  self._check_fn_str, self._check_fn_params
@@ -84,13 +86,83 @@ class RecordSetData:
84
86
 
85
87
 
86
88
  class RecordSet:
87
- """RecordSet stores groups of parameters, metrics and configs."""
89
+ """RecordSet stores groups of parameters, metrics and configs.
90
+
91
+ A :code:`RecordSet` is the unified mechanism by which parameters,
92
+ metrics and configs can be either stored as part of a
93
+ `flwr.common.Context <flwr.common.Context.html>`_ in your apps
94
+ or communicated as part of a
95
+ `flwr.common.Message <flwr.common.Message.html>`_ between your apps.
96
+
97
+ Parameters
98
+ ----------
99
+ parameters_records : Optional[Dict[str, ParametersRecord]]
100
+ A dictionary of :code:`ParametersRecords` that can be used to record
101
+ and communicate model parameters and high-dimensional arrays.
102
+ metrics_records : Optional[Dict[str, MetricsRecord]]
103
+ A dictionary of :code:`MetricsRecord` that can be used to record
104
+ and communicate scalar-valued metrics that are the result of performing
105
+ and action, for example, by a :code:`ClientApp`.
106
+ configs_records : Optional[Dict[str, ConfigsRecord]]
107
+ A dictionary of :code:`ConfigsRecord` that can be used to record
108
+ and communicate configuration values to an entity (e.g. to a
109
+ :code:`ClientApp`)
110
+ for it to adjust how an action is performed.
111
+
112
+ Examples
113
+ --------
114
+ A :code:`RecordSet` can hold three types of records, each designed
115
+ with an specific purpose. What is common to all of them is that they
116
+ are Python dictionaries designed to ensure that each key-value pair
117
+ adheres to specified data types.
118
+
119
+ Let's see an example.
120
+
121
+ >>> from flwr.common import RecordSet
122
+ >>> from flwr.common import ConfigsRecords, MetricsRecords, ParametersRecord
123
+ >>>
124
+ >>> # Let's begin with an empty record
125
+ >>> my_recordset = RecordSet()
126
+ >>>
127
+ >>> # We can create a ConfigsRecord
128
+ >>> c_record = ConfigsRecord({"lr": 0.1, "batch-size": 128})
129
+ >>> # Adding it to the record_set would look like this
130
+ >>> my_recordset.configs_records["my_config"] = c_record
131
+ >>>
132
+ >>> # We can create a MetricsRecord following a similar process
133
+ >>> m_record = MetricsRecord({"accuracy": 0.93, "losses": [0.23, 0.1]})
134
+ >>> # Adding it to the record_set would look like this
135
+ >>> my_recordset.metrics_records["my_metrics"] = m_record
136
+
137
+ Adding a :code:`ParametersRecord` follows the same steps as above but first,
138
+ the array needs to be serialized and represented as a :code:`flwr.common.Array`.
139
+ If the array is a :code:`NumPy` array, you can use the built-in utility function
140
+ `array_from_numpy <flwr.common.array_from_numpy.html>`_. It is often possible to
141
+ convert an array first to :code:`NumPy` and then use the aforementioned function.
142
+
143
+ >>> from flwr.common import array_from_numpy
144
+ >>> # Creating a ParametersRecord would look like this
145
+ >>> arr_np = np.random.randn(3, 3)
146
+ >>>
147
+ >>> # You can use the built-in tool to serialize the array
148
+ >>> arr = array_from_numpy(arr_np)
149
+ >>>
150
+ >>> # Finally, create the record
151
+ >>> p_record = ParametersRecord({"my_array": arr})
152
+ >>>
153
+ >>> # Adding it to the record_set would look like this
154
+ >>> my_recordset.configs_records["my_config"] = c_record
155
+
156
+ For additional examples on how to construct each of the records types shown
157
+ above, please refer to the documentation for :code:`ConfigsRecord`,
158
+ :code:`MetricsRecord` and :code:`ParametersRecord`.
159
+ """
88
160
 
89
161
  def __init__(
90
162
  self,
91
- parameters_records: Optional[Dict[str, ParametersRecord]] = None,
92
- metrics_records: Optional[Dict[str, MetricsRecord]] = None,
93
- configs_records: Optional[Dict[str, ConfigsRecord]] = None,
163
+ parameters_records: dict[str, ParametersRecord] | None = None,
164
+ metrics_records: dict[str, MetricsRecord] | None = None,
165
+ configs_records: dict[str, ConfigsRecord] | None = None,
94
166
  ) -> None:
95
167
  data = RecordSetData(
96
168
  parameters_records=parameters_records,
@@ -15,99 +15,61 @@
15
15
  """Typed dict base class for *Records."""
16
16
 
17
17
 
18
- from typing import Any, Callable, Dict, Generic, Iterator, Tuple, TypeVar, cast
18
+ from typing import Callable, Dict, Generic, Iterator, MutableMapping, TypeVar, cast
19
19
 
20
20
  K = TypeVar("K") # Key type
21
21
  V = TypeVar("V") # Value type
22
22
 
23
23
 
24
- class TypedDict(Generic[K, V]):
24
+ class TypedDict(MutableMapping[K, V], Generic[K, V]):
25
25
  """Typed dictionary."""
26
26
 
27
27
  def __init__(
28
28
  self, check_key_fn: Callable[[K], None], check_value_fn: Callable[[V], None]
29
29
  ):
30
- self._data: Dict[K, V] = {}
31
- self._check_key_fn = check_key_fn
32
- self._check_value_fn = check_value_fn
30
+ self.__dict__["_check_key_fn"] = check_key_fn
31
+ self.__dict__["_check_value_fn"] = check_value_fn
32
+ self.__dict__["_data"] = {}
33
33
 
34
34
  def __setitem__(self, key: K, value: V) -> None:
35
35
  """Set the given key to the given value after type checking."""
36
36
  # Check the types of key and value
37
- self._check_key_fn(key)
38
- self._check_value_fn(value)
37
+ cast(Callable[[K], None], self.__dict__["_check_key_fn"])(key)
38
+ cast(Callable[[V], None], self.__dict__["_check_value_fn"])(value)
39
+
39
40
  # Set key-value pair
40
- self._data[key] = value
41
+ cast(Dict[K, V], self.__dict__["_data"])[key] = value
41
42
 
42
43
  def __delitem__(self, key: K) -> None:
43
44
  """Remove the item with the specified key."""
44
- del self._data[key]
45
+ del cast(Dict[K, V], self.__dict__["_data"])[key]
45
46
 
46
47
  def __getitem__(self, item: K) -> V:
47
48
  """Return the value for the specified key."""
48
- return self._data[item]
49
+ return cast(Dict[K, V], self.__dict__["_data"])[item]
49
50
 
50
51
  def __iter__(self) -> Iterator[K]:
51
52
  """Yield an iterator over the keys of the dictionary."""
52
- return iter(self._data)
53
+ return iter(cast(Dict[K, V], self.__dict__["_data"]))
53
54
 
54
55
  def __repr__(self) -> str:
55
56
  """Return a string representation of the dictionary."""
56
- return self._data.__repr__()
57
+ return cast(Dict[K, V], self.__dict__["_data"]).__repr__()
57
58
 
58
59
  def __len__(self) -> int:
59
60
  """Return the number of items in the dictionary."""
60
- return len(self._data)
61
+ return len(cast(Dict[K, V], self.__dict__["_data"]))
61
62
 
62
- def __contains__(self, key: K) -> bool:
63
+ def __contains__(self, key: object) -> bool:
63
64
  """Check if the dictionary contains the specified key."""
64
- return key in self._data
65
+ return key in cast(Dict[K, V], self.__dict__["_data"])
65
66
 
66
67
  def __eq__(self, other: object) -> bool:
67
68
  """Compare this instance to another dictionary or TypedDict."""
69
+ data = cast(Dict[K, V], self.__dict__["_data"])
68
70
  if isinstance(other, TypedDict):
69
- return self._data == other._data
71
+ other_data = cast(Dict[K, V], other.__dict__["_data"])
72
+ return data == other_data
70
73
  if isinstance(other, dict):
71
- return self._data == other
74
+ return data == other
72
75
  return NotImplemented
73
-
74
- def items(self) -> Iterator[Tuple[K, V]]:
75
- """R.items() -> a set-like object providing a view on R's items."""
76
- return cast(Iterator[Tuple[K, V]], self._data.items())
77
-
78
- def keys(self) -> Iterator[K]:
79
- """R.keys() -> a set-like object providing a view on R's keys."""
80
- return cast(Iterator[K], self._data.keys())
81
-
82
- def values(self) -> Iterator[V]:
83
- """R.values() -> an object providing a view on R's values."""
84
- return cast(Iterator[V], self._data.values())
85
-
86
- def update(self, *args: Any, **kwargs: Any) -> None:
87
- """R.update([E, ]**F) -> None.
88
-
89
- Update R from dict/iterable E and F.
90
- """
91
- for key, value in dict(*args, **kwargs).items():
92
- self[key] = value
93
-
94
- def pop(self, key: K) -> V:
95
- """R.pop(k[,d]) -> v, remove specified key and return the corresponding value.
96
-
97
- If key is not found, d is returned if given, otherwise KeyError is raised.
98
- """
99
- return self._data.pop(key)
100
-
101
- def get(self, key: K, default: V) -> V:
102
- """R.get(k[,d]) -> R[k] if k in R, else d.
103
-
104
- d defaults to None.
105
- """
106
- return self._data.get(key, default)
107
-
108
- def clear(self) -> None:
109
- """R.clear() -> None.
110
-
111
- Remove all items from R.
112
- """
113
- self._data.clear()
@@ -145,7 +145,7 @@ def _recordset_to_fit_or_evaluate_ins_components(
145
145
  # get config dict
146
146
  config_record = recordset.configs_records[f"{ins_str}.config"]
147
147
  # pylint: disable-next=protected-access
148
- config_dict = _check_mapping_from_recordscalartype_to_scalar(config_record._data)
148
+ config_dict = _check_mapping_from_recordscalartype_to_scalar(config_record)
149
149
 
150
150
  return parameters, config_dict
151
151
 
@@ -213,7 +213,7 @@ def recordset_to_fitres(recordset: RecordSet, keep_input: bool) -> FitRes:
213
213
  )
214
214
  configs_record = recordset.configs_records[f"{ins_str}.metrics"]
215
215
  # pylint: disable-next=protected-access
216
- metrics = _check_mapping_from_recordscalartype_to_scalar(configs_record._data)
216
+ metrics = _check_mapping_from_recordscalartype_to_scalar(configs_record)
217
217
  status = _extract_status_from_recordset(ins_str, recordset)
218
218
 
219
219
  return FitRes(
@@ -274,7 +274,7 @@ def recordset_to_evaluateres(recordset: RecordSet) -> EvaluateRes:
274
274
  configs_record = recordset.configs_records[f"{ins_str}.metrics"]
275
275
 
276
276
  # pylint: disable-next=protected-access
277
- metrics = _check_mapping_from_recordscalartype_to_scalar(configs_record._data)
277
+ metrics = _check_mapping_from_recordscalartype_to_scalar(configs_record)
278
278
  status = _extract_status_from_recordset(ins_str, recordset)
279
279
 
280
280
  return EvaluateRes(
@@ -314,7 +314,7 @@ def recordset_to_getparametersins(recordset: RecordSet) -> GetParametersIns:
314
314
  """Derive GetParametersIns from a RecordSet object."""
315
315
  config_record = recordset.configs_records["getparametersins.config"]
316
316
  # pylint: disable-next=protected-access
317
- config_dict = _check_mapping_from_recordscalartype_to_scalar(config_record._data)
317
+ config_dict = _check_mapping_from_recordscalartype_to_scalar(config_record)
318
318
 
319
319
  return GetParametersIns(config=config_dict)
320
320
 
@@ -365,7 +365,7 @@ def recordset_to_getpropertiesins(recordset: RecordSet) -> GetPropertiesIns:
365
365
  """Derive GetPropertiesIns from a RecordSet object."""
366
366
  config_record = recordset.configs_records["getpropertiesins.config"]
367
367
  # pylint: disable-next=protected-access
368
- config_dict = _check_mapping_from_recordscalartype_to_scalar(config_record._data)
368
+ config_dict = _check_mapping_from_recordscalartype_to_scalar(config_record)
369
369
 
370
370
  return GetPropertiesIns(config=config_dict)
371
371
 
@@ -384,7 +384,7 @@ def recordset_to_getpropertiesres(recordset: RecordSet) -> GetPropertiesRes:
384
384
  res_str = "getpropertiesres"
385
385
  config_record = recordset.configs_records[f"{res_str}.properties"]
386
386
  # pylint: disable-next=protected-access
387
- properties = _check_mapping_from_recordscalartype_to_scalar(config_record._data)
387
+ properties = _check_mapping_from_recordscalartype_to_scalar(config_record)
388
388
 
389
389
  status = _extract_status_from_recordset(res_str, recordset=recordset)
390
390
 
flwr/common/serde.py CHANGED
@@ -22,6 +22,7 @@ from google.protobuf.message import Message as GrpcMessage
22
22
  # pylint: disable=E0611
23
23
  from flwr.proto.clientappio_pb2 import ClientAppOutputCode, ClientAppOutputStatus
24
24
  from flwr.proto.error_pb2 import Error as ProtoError
25
+ from flwr.proto.fab_pb2 import Fab as ProtoFab
25
26
  from flwr.proto.message_pb2 import Context as ProtoContext
26
27
  from flwr.proto.message_pb2 import Message as ProtoMessage
27
28
  from flwr.proto.message_pb2 import Metadata as ProtoMetadata
@@ -686,6 +687,19 @@ def message_from_taskres(taskres: TaskRes) -> Message:
686
687
  return message
687
688
 
688
689
 
690
+ # === FAB ===
691
+
692
+
693
+ def fab_to_proto(fab: typing.Fab) -> ProtoFab:
694
+ """Create a proto Fab object from a Python Fab."""
695
+ return ProtoFab(hash_str=fab.hash_str, content=fab.content)
696
+
697
+
698
+ def fab_from_proto(fab: ProtoFab) -> typing.Fab:
699
+ """Create a Python Fab object from a proto Fab."""
700
+ return typing.Fab(fab.hash_str, fab.content)
701
+
702
+
689
703
  # === User configs ===
690
704
 
691
705
 
@@ -745,6 +759,7 @@ def metadata_to_proto(metadata: Metadata) -> ProtoMetadata:
745
759
  group_id=metadata.group_id,
746
760
  ttl=metadata.ttl,
747
761
  message_type=metadata.message_type,
762
+ created_at=metadata.created_at,
748
763
  )
749
764
  return proto
750
765
 
@@ -771,7 +786,9 @@ def message_to_proto(message: Message) -> ProtoMessage:
771
786
  """Serialize `Message` to ProtoBuf."""
772
787
  proto = ProtoMessage(
773
788
  metadata=metadata_to_proto(message.metadata),
774
- content=recordset_to_proto(message.content),
789
+ content=(
790
+ recordset_to_proto(message.content) if message.has_content() else None
791
+ ),
775
792
  error=error_to_proto(message.error) if message.has_error() else None,
776
793
  )
777
794
  return proto
@@ -779,6 +796,7 @@ def message_to_proto(message: Message) -> ProtoMessage:
779
796
 
780
797
  def message_from_proto(message_proto: ProtoMessage) -> Message:
781
798
  """Deserialize `Message` from ProtoBuf."""
799
+ created_at = message_proto.metadata.created_at
782
800
  message = Message(
783
801
  metadata=metadata_from_proto(message_proto.metadata),
784
802
  content=(
@@ -792,6 +810,9 @@ def message_from_proto(message_proto: ProtoMessage) -> Message:
792
810
  else None
793
811
  ),
794
812
  )
813
+ # `.created_at` is set upon Message object construction
814
+ # we need to manually set it to the original value
815
+ message.metadata.created_at = created_at
795
816
  return message
796
817
 
797
818
 
@@ -829,8 +850,8 @@ def run_to_proto(run: typing.Run) -> ProtoRun:
829
850
  run_id=run.run_id,
830
851
  fab_id=run.fab_id,
831
852
  fab_version=run.fab_version,
853
+ fab_hash=run.fab_hash,
832
854
  override_config=user_config_to_proto(run.override_config),
833
- fab_hash="",
834
855
  )
835
856
  return proto
836
857
 
@@ -841,6 +862,7 @@ def run_from_proto(run_proto: ProtoRun) -> typing.Run:
841
862
  run_id=run_proto.run_id,
842
863
  fab_id=run_proto.fab_id,
843
864
  fab_version=run_proto.fab_version,
865
+ fab_hash=run_proto.fab_hash,
844
866
  override_config=user_config_from_proto(run_proto.override_config),
845
867
  )
846
868
  return run
flwr/common/typing.py CHANGED
@@ -214,6 +214,7 @@ class Run:
214
214
  run_id: int
215
215
  fab_id: str
216
216
  fab_version: str
217
+ fab_hash: str
217
218
  override_config: UserConfig
218
219
 
219
220
 
@@ -17,25 +17,29 @@ from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2
17
17
  from flwr.proto import message_pb2 as flwr_dot_proto_dot_message__pb2
18
18
 
19
19
 
20
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x66lwr/proto/clientappio.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x14\x66lwr/proto/run.proto\x1a\x18\x66lwr/proto/message.proto\"W\n\x15\x43lientAppOutputStatus\x12-\n\x04\x63ode\x18\x01 \x01(\x0e\x32\x1f.flwr.proto.ClientAppOutputCode\x12\x0f\n\x07message\x18\x02 \x01(\t\"+\n\x1aPullClientAppInputsRequest\x12\r\n\x05token\x18\x01 \x01(\x12\"\x87\x01\n\x1bPullClientAppInputsResponse\x12$\n\x07message\x18\x01 \x01(\x0b\x32\x13.flwr.proto.Message\x12$\n\x07\x63ontext\x18\x02 \x01(\x0b\x32\x13.flwr.proto.Context\x12\x1c\n\x03run\x18\x03 \x01(\x0b\x32\x0f.flwr.proto.Run\"x\n\x1bPushClientAppOutputsRequest\x12\r\n\x05token\x18\x01 \x01(\x12\x12$\n\x07message\x18\x02 \x01(\x0b\x32\x13.flwr.proto.Message\x12$\n\x07\x63ontext\x18\x03 \x01(\x0b\x32\x13.flwr.proto.Context\"Q\n\x1cPushClientAppOutputsResponse\x12\x31\n\x06status\x18\x01 \x01(\x0b\x32!.flwr.proto.ClientAppOutputStatus*L\n\x13\x43lientAppOutputCode\x12\x0b\n\x07SUCCESS\x10\x00\x12\x15\n\x11\x44\x45\x41\x44LINE_EXCEEDED\x10\x01\x12\x11\n\rUNKNOWN_ERROR\x10\x02\x32\xe4\x01\n\x0b\x43lientAppIo\x12h\n\x13PullClientAppInputs\x12&.flwr.proto.PullClientAppInputsRequest\x1a\'.flwr.proto.PullClientAppInputsResponse\"\x00\x12k\n\x14PushClientAppOutputs\x12\'.flwr.proto.PushClientAppOutputsRequest\x1a(.flwr.proto.PushClientAppOutputsResponse\"\x00\x62\x06proto3')
20
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x66lwr/proto/clientappio.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x14\x66lwr/proto/run.proto\x1a\x18\x66lwr/proto/message.proto\"W\n\x15\x43lientAppOutputStatus\x12-\n\x04\x63ode\x18\x01 \x01(\x0e\x32\x1f.flwr.proto.ClientAppOutputCode\x12\x0f\n\x07message\x18\x02 \x01(\t\"\x11\n\x0fGetTokenRequest\"!\n\x10GetTokenResponse\x12\r\n\x05token\x18\x01 \x01(\x12\"+\n\x1aPullClientAppInputsRequest\x12\r\n\x05token\x18\x01 \x01(\x12\"\xa5\x01\n\x1bPullClientAppInputsResponse\x12$\n\x07message\x18\x01 \x01(\x0b\x32\x13.flwr.proto.Message\x12$\n\x07\x63ontext\x18\x02 \x01(\x0b\x32\x13.flwr.proto.Context\x12\x1c\n\x03run\x18\x03 \x01(\x0b\x32\x0f.flwr.proto.Run\x12\x1c\n\x03\x66\x61\x62\x18\x04 \x01(\x0b\x32\x0f.flwr.proto.Fab\"x\n\x1bPushClientAppOutputsRequest\x12\r\n\x05token\x18\x01 \x01(\x12\x12$\n\x07message\x18\x02 \x01(\x0b\x32\x13.flwr.proto.Message\x12$\n\x07\x63ontext\x18\x03 \x01(\x0b\x32\x13.flwr.proto.Context\"Q\n\x1cPushClientAppOutputsResponse\x12\x31\n\x06status\x18\x01 \x01(\x0b\x32!.flwr.proto.ClientAppOutputStatus*L\n\x13\x43lientAppOutputCode\x12\x0b\n\x07SUCCESS\x10\x00\x12\x15\n\x11\x44\x45\x41\x44LINE_EXCEEDED\x10\x01\x12\x11\n\rUNKNOWN_ERROR\x10\x02\x32\xad\x02\n\x0b\x43lientAppIo\x12G\n\x08GetToken\x12\x1b.flwr.proto.GetTokenRequest\x1a\x1c.flwr.proto.GetTokenResponse\"\x00\x12h\n\x13PullClientAppInputs\x12&.flwr.proto.PullClientAppInputsRequest\x1a\'.flwr.proto.PullClientAppInputsResponse\"\x00\x12k\n\x14PushClientAppOutputs\x12\'.flwr.proto.PushClientAppOutputsRequest\x1a(.flwr.proto.PushClientAppOutputsResponse\"\x00\x62\x06proto3')
21
21
 
22
22
  _globals = globals()
23
23
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
24
24
  _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.clientappio_pb2', _globals)
25
25
  if _descriptor._USE_C_DESCRIPTORS == False:
26
26
  DESCRIPTOR._options = None
27
- _globals['_CLIENTAPPOUTPUTCODE']._serialized_start=591
28
- _globals['_CLIENTAPPOUTPUTCODE']._serialized_end=667
27
+ _globals['_CLIENTAPPOUTPUTCODE']._serialized_start=675
28
+ _globals['_CLIENTAPPOUTPUTCODE']._serialized_end=751
29
29
  _globals['_CLIENTAPPOUTPUTSTATUS']._serialized_start=114
30
30
  _globals['_CLIENTAPPOUTPUTSTATUS']._serialized_end=201
31
- _globals['_PULLCLIENTAPPINPUTSREQUEST']._serialized_start=203
32
- _globals['_PULLCLIENTAPPINPUTSREQUEST']._serialized_end=246
33
- _globals['_PULLCLIENTAPPINPUTSRESPONSE']._serialized_start=249
34
- _globals['_PULLCLIENTAPPINPUTSRESPONSE']._serialized_end=384
35
- _globals['_PUSHCLIENTAPPOUTPUTSREQUEST']._serialized_start=386
36
- _globals['_PUSHCLIENTAPPOUTPUTSREQUEST']._serialized_end=506
37
- _globals['_PUSHCLIENTAPPOUTPUTSRESPONSE']._serialized_start=508
38
- _globals['_PUSHCLIENTAPPOUTPUTSRESPONSE']._serialized_end=589
39
- _globals['_CLIENTAPPIO']._serialized_start=670
40
- _globals['_CLIENTAPPIO']._serialized_end=898
31
+ _globals['_GETTOKENREQUEST']._serialized_start=203
32
+ _globals['_GETTOKENREQUEST']._serialized_end=220
33
+ _globals['_GETTOKENRESPONSE']._serialized_start=222
34
+ _globals['_GETTOKENRESPONSE']._serialized_end=255
35
+ _globals['_PULLCLIENTAPPINPUTSREQUEST']._serialized_start=257
36
+ _globals['_PULLCLIENTAPPINPUTSREQUEST']._serialized_end=300
37
+ _globals['_PULLCLIENTAPPINPUTSRESPONSE']._serialized_start=303
38
+ _globals['_PULLCLIENTAPPINPUTSRESPONSE']._serialized_end=468
39
+ _globals['_PUSHCLIENTAPPOUTPUTSREQUEST']._serialized_start=470
40
+ _globals['_PUSHCLIENTAPPOUTPUTSREQUEST']._serialized_end=590
41
+ _globals['_PUSHCLIENTAPPOUTPUTSRESPONSE']._serialized_start=592
42
+ _globals['_PUSHCLIENTAPPOUTPUTSRESPONSE']._serialized_end=673
43
+ _globals['_CLIENTAPPIO']._serialized_start=754
44
+ _globals['_CLIENTAPPIO']._serialized_end=1055
41
45
  # @@protoc_insertion_point(module_scope)
@@ -3,6 +3,7 @@
3
3
  isort:skip_file
4
4
  """
5
5
  import builtins
6
+ import flwr.proto.fab_pb2
6
7
  import flwr.proto.message_pb2
7
8
  import flwr.proto.run_pb2
8
9
  import google.protobuf.descriptor
@@ -44,6 +45,23 @@ class ClientAppOutputStatus(google.protobuf.message.Message):
44
45
  def ClearField(self, field_name: typing_extensions.Literal["code",b"code","message",b"message"]) -> None: ...
45
46
  global___ClientAppOutputStatus = ClientAppOutputStatus
46
47
 
48
+ class GetTokenRequest(google.protobuf.message.Message):
49
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
50
+ def __init__(self,
51
+ ) -> None: ...
52
+ global___GetTokenRequest = GetTokenRequest
53
+
54
+ class GetTokenResponse(google.protobuf.message.Message):
55
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
56
+ TOKEN_FIELD_NUMBER: builtins.int
57
+ token: builtins.int
58
+ def __init__(self,
59
+ *,
60
+ token: builtins.int = ...,
61
+ ) -> None: ...
62
+ def ClearField(self, field_name: typing_extensions.Literal["token",b"token"]) -> None: ...
63
+ global___GetTokenResponse = GetTokenResponse
64
+
47
65
  class PullClientAppInputsRequest(google.protobuf.message.Message):
48
66
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
49
67
  TOKEN_FIELD_NUMBER: builtins.int
@@ -60,20 +78,24 @@ class PullClientAppInputsResponse(google.protobuf.message.Message):
60
78
  MESSAGE_FIELD_NUMBER: builtins.int
61
79
  CONTEXT_FIELD_NUMBER: builtins.int
62
80
  RUN_FIELD_NUMBER: builtins.int
81
+ FAB_FIELD_NUMBER: builtins.int
63
82
  @property
64
83
  def message(self) -> flwr.proto.message_pb2.Message: ...
65
84
  @property
66
85
  def context(self) -> flwr.proto.message_pb2.Context: ...
67
86
  @property
68
87
  def run(self) -> flwr.proto.run_pb2.Run: ...
88
+ @property
89
+ def fab(self) -> flwr.proto.fab_pb2.Fab: ...
69
90
  def __init__(self,
70
91
  *,
71
92
  message: typing.Optional[flwr.proto.message_pb2.Message] = ...,
72
93
  context: typing.Optional[flwr.proto.message_pb2.Context] = ...,
73
94
  run: typing.Optional[flwr.proto.run_pb2.Run] = ...,
95
+ fab: typing.Optional[flwr.proto.fab_pb2.Fab] = ...,
74
96
  ) -> None: ...
75
- def HasField(self, field_name: typing_extensions.Literal["context",b"context","message",b"message","run",b"run"]) -> builtins.bool: ...
76
- def ClearField(self, field_name: typing_extensions.Literal["context",b"context","message",b"message","run",b"run"]) -> None: ...
97
+ def HasField(self, field_name: typing_extensions.Literal["context",b"context","fab",b"fab","message",b"message","run",b"run"]) -> builtins.bool: ...
98
+ def ClearField(self, field_name: typing_extensions.Literal["context",b"context","fab",b"fab","message",b"message","run",b"run"]) -> None: ...
77
99
  global___PullClientAppInputsResponse = PullClientAppInputsResponse
78
100
 
79
101
  class PushClientAppOutputsRequest(google.protobuf.message.Message):
@@ -14,6 +14,11 @@ class ClientAppIoStub(object):
14
14
  Args:
15
15
  channel: A grpc.Channel.
16
16
  """
17
+ self.GetToken = channel.unary_unary(
18
+ '/flwr.proto.ClientAppIo/GetToken',
19
+ request_serializer=flwr_dot_proto_dot_clientappio__pb2.GetTokenRequest.SerializeToString,
20
+ response_deserializer=flwr_dot_proto_dot_clientappio__pb2.GetTokenResponse.FromString,
21
+ )
17
22
  self.PullClientAppInputs = channel.unary_unary(
18
23
  '/flwr.proto.ClientAppIo/PullClientAppInputs',
19
24
  request_serializer=flwr_dot_proto_dot_clientappio__pb2.PullClientAppInputsRequest.SerializeToString,
@@ -29,6 +34,13 @@ class ClientAppIoStub(object):
29
34
  class ClientAppIoServicer(object):
30
35
  """Missing associated documentation comment in .proto file."""
31
36
 
37
+ def GetToken(self, request, context):
38
+ """Get token
39
+ """
40
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
41
+ context.set_details('Method not implemented!')
42
+ raise NotImplementedError('Method not implemented!')
43
+
32
44
  def PullClientAppInputs(self, request, context):
33
45
  """Get Message, Context, and Run
34
46
  """
@@ -46,6 +58,11 @@ class ClientAppIoServicer(object):
46
58
 
47
59
  def add_ClientAppIoServicer_to_server(servicer, server):
48
60
  rpc_method_handlers = {
61
+ 'GetToken': grpc.unary_unary_rpc_method_handler(
62
+ servicer.GetToken,
63
+ request_deserializer=flwr_dot_proto_dot_clientappio__pb2.GetTokenRequest.FromString,
64
+ response_serializer=flwr_dot_proto_dot_clientappio__pb2.GetTokenResponse.SerializeToString,
65
+ ),
49
66
  'PullClientAppInputs': grpc.unary_unary_rpc_method_handler(
50
67
  servicer.PullClientAppInputs,
51
68
  request_deserializer=flwr_dot_proto_dot_clientappio__pb2.PullClientAppInputsRequest.FromString,
@@ -66,6 +83,23 @@ def add_ClientAppIoServicer_to_server(servicer, server):
66
83
  class ClientAppIo(object):
67
84
  """Missing associated documentation comment in .proto file."""
68
85
 
86
+ @staticmethod
87
+ def GetToken(request,
88
+ target,
89
+ options=(),
90
+ channel_credentials=None,
91
+ call_credentials=None,
92
+ insecure=False,
93
+ compression=None,
94
+ wait_for_ready=None,
95
+ timeout=None,
96
+ metadata=None):
97
+ return grpc.experimental.unary_unary(request, target, '/flwr.proto.ClientAppIo/GetToken',
98
+ flwr_dot_proto_dot_clientappio__pb2.GetTokenRequest.SerializeToString,
99
+ flwr_dot_proto_dot_clientappio__pb2.GetTokenResponse.FromString,
100
+ options, channel_credentials,
101
+ insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
102
+
69
103
  @staticmethod
70
104
  def PullClientAppInputs(request,
71
105
  target,
@@ -8,6 +8,11 @@ import grpc
8
8
 
9
9
  class ClientAppIoStub:
10
10
  def __init__(self, channel: grpc.Channel) -> None: ...
11
+ GetToken: grpc.UnaryUnaryMultiCallable[
12
+ flwr.proto.clientappio_pb2.GetTokenRequest,
13
+ flwr.proto.clientappio_pb2.GetTokenResponse]
14
+ """Get token"""
15
+
11
16
  PullClientAppInputs: grpc.UnaryUnaryMultiCallable[
12
17
  flwr.proto.clientappio_pb2.PullClientAppInputsRequest,
13
18
  flwr.proto.clientappio_pb2.PullClientAppInputsResponse]
@@ -20,6 +25,14 @@ class ClientAppIoStub:
20
25
 
21
26
 
22
27
  class ClientAppIoServicer(metaclass=abc.ABCMeta):
28
+ @abc.abstractmethod
29
+ def GetToken(self,
30
+ request: flwr.proto.clientappio_pb2.GetTokenRequest,
31
+ context: grpc.ServicerContext,
32
+ ) -> flwr.proto.clientappio_pb2.GetTokenResponse:
33
+ """Get token"""
34
+ pass
35
+
23
36
  @abc.abstractmethod
24
37
  def PullClientAppInputs(self,
25
38
  request: flwr.proto.clientappio_pb2.PullClientAppInputsRequest,
flwr/proto/exec_pb2.py CHANGED
@@ -12,10 +12,11 @@ from google.protobuf.internal import builder as _builder
12
12
  _sym_db = _symbol_database.Default()
13
13
 
14
14
 
15
+ from flwr.proto import fab_pb2 as flwr_dot_proto_dot_fab__pb2
15
16
  from flwr.proto import transport_pb2 as flwr_dot_proto_dot_transport__pb2
16
17
 
17
18
 
18
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/exec.proto\x12\nflwr.proto\x1a\x1a\x66lwr/proto/transport.proto\"\xd3\x02\n\x0fStartRunRequest\x12\x10\n\x08\x66\x61\x62_file\x18\x01 \x01(\x0c\x12H\n\x0foverride_config\x18\x02 \x03(\x0b\x32/.flwr.proto.StartRunRequest.OverrideConfigEntry\x12L\n\x11\x66\x65\x64\x65ration_config\x18\x03 \x03(\x0b\x32\x31.flwr.proto.StartRunRequest.FederationConfigEntry\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\x1aK\n\x15\x46\x65\x64\x65rationConfigEntry\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(\x12\"#\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"(\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t2\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')
19
+ 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\"\xdf\x02\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\x12L\n\x11\x66\x65\x64\x65ration_config\x18\x03 \x03(\x0b\x32\x31.flwr.proto.StartRunRequest.FederationConfigEntry\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\x1aK\n\x15\x46\x65\x64\x65rationConfigEntry\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(\x12\"#\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"(\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t2\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')
19
20
 
20
21
  _globals = globals()
21
22
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -26,18 +27,18 @@ if _descriptor._USE_C_DESCRIPTORS == False:
26
27
  _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_options = b'8\001'
27
28
  _globals['_STARTRUNREQUEST_FEDERATIONCONFIGENTRY']._options = None
28
29
  _globals['_STARTRUNREQUEST_FEDERATIONCONFIGENTRY']._serialized_options = b'8\001'
29
- _globals['_STARTRUNREQUEST']._serialized_start=66
30
- _globals['_STARTRUNREQUEST']._serialized_end=405
31
- _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=255
32
- _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=328
33
- _globals['_STARTRUNREQUEST_FEDERATIONCONFIGENTRY']._serialized_start=330
34
- _globals['_STARTRUNREQUEST_FEDERATIONCONFIGENTRY']._serialized_end=405
35
- _globals['_STARTRUNRESPONSE']._serialized_start=407
36
- _globals['_STARTRUNRESPONSE']._serialized_end=441
37
- _globals['_STREAMLOGSREQUEST']._serialized_start=443
38
- _globals['_STREAMLOGSREQUEST']._serialized_end=478
39
- _globals['_STREAMLOGSRESPONSE']._serialized_start=480
40
- _globals['_STREAMLOGSRESPONSE']._serialized_end=520
41
- _globals['_EXEC']._serialized_start=523
42
- _globals['_EXEC']._serialized_end=683
30
+ _globals['_STARTRUNREQUEST']._serialized_start=88
31
+ _globals['_STARTRUNREQUEST']._serialized_end=439
32
+ _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=289
33
+ _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=362
34
+ _globals['_STARTRUNREQUEST_FEDERATIONCONFIGENTRY']._serialized_start=364
35
+ _globals['_STARTRUNREQUEST_FEDERATIONCONFIGENTRY']._serialized_end=439
36
+ _globals['_STARTRUNRESPONSE']._serialized_start=441
37
+ _globals['_STARTRUNRESPONSE']._serialized_end=475
38
+ _globals['_STREAMLOGSREQUEST']._serialized_start=477
39
+ _globals['_STREAMLOGSREQUEST']._serialized_end=512
40
+ _globals['_STREAMLOGSRESPONSE']._serialized_start=514
41
+ _globals['_STREAMLOGSRESPONSE']._serialized_end=554
42
+ _globals['_EXEC']._serialized_start=557
43
+ _globals['_EXEC']._serialized_end=717
43
44
  # @@protoc_insertion_point(module_scope)