flwr 1.14.0__py3-none-any.whl → 1.15.0__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.
Files changed (102) hide show
  1. flwr/cli/auth_plugin/__init__.py +31 -0
  2. flwr/cli/auth_plugin/oidc_cli_plugin.py +150 -0
  3. flwr/cli/cli_user_auth_interceptor.py +6 -2
  4. flwr/cli/config_utils.py +24 -147
  5. flwr/cli/constant.py +27 -0
  6. flwr/cli/install.py +1 -1
  7. flwr/cli/log.py +18 -3
  8. flwr/cli/login/login.py +43 -8
  9. flwr/cli/ls.py +14 -5
  10. flwr/cli/new/templates/app/README.md.tpl +3 -2
  11. flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +4 -4
  12. flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +2 -2
  13. flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +4 -4
  14. flwr/cli/new/templates/app/pyproject.jax.toml.tpl +2 -2
  15. flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +2 -2
  16. flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +2 -2
  17. flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +4 -4
  18. flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +3 -3
  19. flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +2 -2
  20. flwr/cli/run/run.py +21 -11
  21. flwr/cli/stop.py +13 -4
  22. flwr/cli/utils.py +54 -40
  23. flwr/client/app.py +36 -48
  24. flwr/client/clientapp/app.py +19 -25
  25. flwr/client/clientapp/utils.py +1 -1
  26. flwr/client/grpc_client/connection.py +1 -12
  27. flwr/client/grpc_rere_client/client_interceptor.py +19 -119
  28. flwr/client/grpc_rere_client/connection.py +46 -36
  29. flwr/client/grpc_rere_client/grpc_adapter.py +12 -12
  30. flwr/client/message_handler/task_handler.py +0 -17
  31. flwr/client/rest_client/connection.py +34 -26
  32. flwr/client/supernode/app.py +18 -72
  33. flwr/common/args.py +25 -47
  34. flwr/common/auth_plugin/auth_plugin.py +34 -23
  35. flwr/common/config.py +166 -16
  36. flwr/common/constant.py +22 -9
  37. flwr/common/differential_privacy.py +2 -1
  38. flwr/common/exit/__init__.py +24 -0
  39. flwr/common/exit/exit.py +99 -0
  40. flwr/common/exit/exit_code.py +93 -0
  41. flwr/common/exit_handlers.py +24 -10
  42. flwr/common/grpc.py +167 -4
  43. flwr/common/logger.py +26 -7
  44. flwr/common/record/recordset.py +1 -1
  45. flwr/common/secure_aggregation/crypto/symmetric_encryption.py +45 -0
  46. flwr/common/serde.py +6 -4
  47. flwr/common/typing.py +20 -0
  48. flwr/proto/clientappio_pb2.py +1 -1
  49. flwr/proto/error_pb2.py +1 -1
  50. flwr/proto/exec_pb2.py +13 -25
  51. flwr/proto/exec_pb2.pyi +27 -54
  52. flwr/proto/fab_pb2.py +1 -1
  53. flwr/proto/fleet_pb2.py +31 -31
  54. flwr/proto/fleet_pb2.pyi +23 -23
  55. flwr/proto/fleet_pb2_grpc.py +30 -30
  56. flwr/proto/fleet_pb2_grpc.pyi +20 -20
  57. flwr/proto/grpcadapter_pb2.py +1 -1
  58. flwr/proto/log_pb2.py +1 -1
  59. flwr/proto/message_pb2.py +1 -1
  60. flwr/proto/node_pb2.py +3 -3
  61. flwr/proto/node_pb2.pyi +1 -4
  62. flwr/proto/recordset_pb2.py +1 -1
  63. flwr/proto/run_pb2.py +1 -1
  64. flwr/proto/serverappio_pb2.py +24 -25
  65. flwr/proto/serverappio_pb2.pyi +26 -32
  66. flwr/proto/serverappio_pb2_grpc.py +28 -28
  67. flwr/proto/serverappio_pb2_grpc.pyi +16 -16
  68. flwr/proto/simulationio_pb2.py +1 -1
  69. flwr/proto/task_pb2.py +1 -1
  70. flwr/proto/transport_pb2.py +1 -1
  71. flwr/server/app.py +116 -128
  72. flwr/server/compat/app_utils.py +0 -1
  73. flwr/server/compat/driver_client_proxy.py +1 -2
  74. flwr/server/driver/grpc_driver.py +32 -27
  75. flwr/server/driver/inmemory_driver.py +2 -1
  76. flwr/server/serverapp/app.py +12 -10
  77. flwr/server/superlink/driver/serverappio_grpc.py +1 -1
  78. flwr/server/superlink/driver/serverappio_servicer.py +74 -48
  79. flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +20 -88
  80. flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +2 -165
  81. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +25 -24
  82. flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +97 -168
  83. flwr/server/superlink/fleet/message_handler/message_handler.py +37 -24
  84. flwr/server/superlink/fleet/rest_rere/rest_api.py +16 -18
  85. flwr/server/superlink/fleet/vce/vce_api.py +2 -2
  86. flwr/server/superlink/linkstate/in_memory_linkstate.py +45 -75
  87. flwr/server/superlink/linkstate/linkstate.py +17 -38
  88. flwr/server/superlink/linkstate/sqlite_linkstate.py +81 -145
  89. flwr/server/superlink/linkstate/utils.py +18 -8
  90. flwr/server/superlink/simulation/simulationio_grpc.py +1 -1
  91. flwr/server/utils/validator.py +9 -34
  92. flwr/simulation/app.py +4 -6
  93. flwr/simulation/legacy_app.py +4 -2
  94. flwr/simulation/run_simulation.py +1 -1
  95. flwr/simulation/simulationio_connection.py +2 -1
  96. flwr/superexec/exec_grpc.py +1 -1
  97. flwr/superexec/exec_servicer.py +23 -2
  98. {flwr-1.14.0.dist-info → flwr-1.15.0.dist-info}/METADATA +8 -8
  99. {flwr-1.14.0.dist-info → flwr-1.15.0.dist-info}/RECORD +102 -96
  100. {flwr-1.14.0.dist-info → flwr-1.15.0.dist-info}/LICENSE +0 -0
  101. {flwr-1.14.0.dist-info → flwr-1.15.0.dist-info}/WHEEL +0 -0
  102. {flwr-1.14.0.dist-info → flwr-1.15.0.dist-info}/entry_points.txt +0 -0
flwr/common/grpc.py CHANGED
@@ -15,16 +15,33 @@
15
15
  """Utility functions for gRPC."""
16
16
 
17
17
 
18
+ import concurrent.futures
19
+ import os
20
+ import sys
18
21
  from collections.abc import Sequence
19
- from logging import DEBUG
20
- from typing import Optional
22
+ from logging import DEBUG, ERROR
23
+ from typing import Any, Callable, Optional
21
24
 
22
25
  import grpc
23
26
 
24
- from flwr.common.logger import log
27
+ from .address import is_port_in_use
28
+ from .logger import log
25
29
 
26
30
  GRPC_MAX_MESSAGE_LENGTH: int = 536_870_912 # == 512 * 1024 * 1024
27
31
 
32
+ INVALID_CERTIFICATES_ERR_MSG = """
33
+ When setting any of root_certificate, certificate, or private_key,
34
+ all of them need to be set.
35
+ """
36
+
37
+ AddServicerToServerFn = Callable[..., Any]
38
+
39
+ if "GRPC_VERBOSITY" not in os.environ:
40
+ os.environ["GRPC_VERBOSITY"] = "error"
41
+ # The following flags can be uncommented for debugging. Other possible values:
42
+ # https://github.com/grpc/grpc/blob/master/doc/environment_variables.md
43
+ # os.environ["GRPC_TRACE"] = "tcp,http"
44
+
28
45
 
29
46
  def create_channel(
30
47
  server_address: str,
@@ -63,6 +80,152 @@ def create_channel(
63
80
  log(DEBUG, "Opened secure gRPC connection using certificates")
64
81
 
65
82
  if interceptors is not None:
66
- channel = grpc.intercept_channel(channel, interceptors)
83
+ channel = grpc.intercept_channel(channel, *interceptors)
67
84
 
68
85
  return channel
86
+
87
+
88
+ def valid_certificates(certificates: tuple[bytes, bytes, bytes]) -> bool:
89
+ """Validate certificates tuple."""
90
+ is_valid = (
91
+ all(isinstance(certificate, bytes) for certificate in certificates)
92
+ and len(certificates) == 3
93
+ )
94
+
95
+ if not is_valid:
96
+ log(ERROR, INVALID_CERTIFICATES_ERR_MSG)
97
+
98
+ return is_valid
99
+
100
+
101
+ def generic_create_grpc_server( # pylint: disable=too-many-arguments,R0917
102
+ servicer_and_add_fn: tuple[Any, AddServicerToServerFn],
103
+ server_address: str,
104
+ max_concurrent_workers: int = 1000,
105
+ max_message_length: int = GRPC_MAX_MESSAGE_LENGTH,
106
+ keepalive_time_ms: int = 210000,
107
+ certificates: Optional[tuple[bytes, bytes, bytes]] = None,
108
+ interceptors: Optional[Sequence[grpc.ServerInterceptor]] = None,
109
+ ) -> grpc.Server:
110
+ """Create a gRPC server with a single servicer.
111
+
112
+ Parameters
113
+ ----------
114
+ servicer_and_add_fn : tuple
115
+ A tuple holding a servicer implementation and a matching
116
+ add_Servicer_to_server function.
117
+ server_address : str
118
+ Server address in the form of HOST:PORT e.g. "[::]:8080"
119
+ max_concurrent_workers : int
120
+ Maximum number of clients the server can process before returning
121
+ RESOURCE_EXHAUSTED status (default: 1000)
122
+ max_message_length : int
123
+ Maximum message length that the server can send or receive.
124
+ Int valued in bytes. -1 means unlimited. (default: GRPC_MAX_MESSAGE_LENGTH)
125
+ keepalive_time_ms : int
126
+ Flower uses a default gRPC keepalive time of 210000ms (3 minutes 30 seconds)
127
+ because some cloud providers (for example, Azure) agressively clean up idle
128
+ TCP connections by terminating them after some time (4 minutes in the case
129
+ of Azure). Flower does not use application-level keepalive signals and relies
130
+ on the assumption that the transport layer will fail in cases where the
131
+ connection is no longer active. `keepalive_time_ms` can be used to customize
132
+ the keepalive interval for specific environments. The default Flower gRPC
133
+ keepalive of 210000 ms (3 minutes 30 seconds) ensures that Flower can keep
134
+ the long running streaming connection alive in most environments. The actual
135
+ gRPC default of this setting is 7200000 (2 hours), which results in dropped
136
+ connections in some cloud environments.
137
+
138
+ These settings are related to the issue described here:
139
+ - https://github.com/grpc/proposal/blob/master/A8-client-side-keepalive.md
140
+ - https://github.com/grpc/grpc/blob/master/doc/keepalive.md
141
+ - https://grpc.io/docs/guides/performance/
142
+
143
+ Mobile Flower clients may choose to increase this value if their server
144
+ environment allows long-running idle TCP connections.
145
+ (default: 210000)
146
+ certificates : Tuple[bytes, bytes, bytes] (default: None)
147
+ Tuple containing root certificate, server certificate, and private key to
148
+ start a secure SSL-enabled server. The tuple is expected to have three bytes
149
+ elements in the following order:
150
+
151
+ * CA certificate.
152
+ * server certificate.
153
+ * server private key.
154
+ interceptors : Optional[Sequence[grpc.ServerInterceptor]] (default: None)
155
+ A list of gRPC interceptors.
156
+
157
+ Returns
158
+ -------
159
+ server : grpc.Server
160
+ A non-running instance of a gRPC server.
161
+ """
162
+ # Check if port is in use
163
+ if is_port_in_use(server_address):
164
+ sys.exit(f"Port in server address {server_address} is already in use.")
165
+
166
+ # Deconstruct tuple into servicer and function
167
+ servicer, add_servicer_to_server_fn = servicer_and_add_fn
168
+
169
+ # Possible options:
170
+ # https://github.com/grpc/grpc/blob/v1.43.x/include/grpc/impl/codegen/grpc_types.h
171
+ options = [
172
+ # Maximum number of concurrent incoming streams to allow on a http2
173
+ # connection. Int valued.
174
+ ("grpc.max_concurrent_streams", max(100, max_concurrent_workers)),
175
+ # Maximum message length that the channel can send.
176
+ # Int valued, bytes. -1 means unlimited.
177
+ ("grpc.max_send_message_length", max_message_length),
178
+ # Maximum message length that the channel can receive.
179
+ # Int valued, bytes. -1 means unlimited.
180
+ ("grpc.max_receive_message_length", max_message_length),
181
+ # The gRPC default for this setting is 7200000 (2 hours). Flower uses a
182
+ # customized default of 210000 (3 minutes and 30 seconds) to improve
183
+ # compatibility with popular cloud providers. Mobile Flower clients may
184
+ # choose to increase this value if their server environment allows
185
+ # long-running idle TCP connections.
186
+ ("grpc.keepalive_time_ms", keepalive_time_ms),
187
+ # Setting this to zero will allow sending unlimited keepalive pings in between
188
+ # sending actual data frames.
189
+ ("grpc.http2.max_pings_without_data", 0),
190
+ # Is it permissible to send keepalive pings from the client without
191
+ # any outstanding streams. More explanation here:
192
+ # https://github.com/adap/flower/pull/2197
193
+ ("grpc.keepalive_permit_without_calls", 0),
194
+ ]
195
+
196
+ server = grpc.server(
197
+ concurrent.futures.ThreadPoolExecutor(max_workers=max_concurrent_workers),
198
+ # Set the maximum number of concurrent RPCs this server will service before
199
+ # returning RESOURCE_EXHAUSTED status, or None to indicate no limit.
200
+ maximum_concurrent_rpcs=max_concurrent_workers,
201
+ options=options,
202
+ interceptors=interceptors,
203
+ )
204
+ add_servicer_to_server_fn(servicer, server)
205
+
206
+ if certificates is not None:
207
+ if not valid_certificates(certificates):
208
+ sys.exit(1)
209
+
210
+ root_certificate_b, certificate_b, private_key_b = certificates
211
+
212
+ server_credentials = grpc.ssl_server_credentials(
213
+ ((private_key_b, certificate_b),),
214
+ root_certificates=root_certificate_b,
215
+ # A boolean indicating whether or not to require clients to be
216
+ # authenticated. May only be True if root_certificates is not None.
217
+ # We are explicitly setting the current gRPC default to document
218
+ # the option. For further reference see:
219
+ # https://grpc.github.io/grpc/python/grpc.html#create-server-credentials
220
+ require_client_auth=False,
221
+ )
222
+ server.add_secure_port(server_address, server_credentials)
223
+ else:
224
+ server.add_insecure_port(server_address)
225
+
226
+ return server
227
+
228
+
229
+ def on_channel_state_change(channel_connectivity: str) -> None:
230
+ """Log channel connectivity."""
231
+ log(DEBUG, channel_connectivity)
flwr/common/logger.py CHANGED
@@ -17,12 +17,13 @@
17
17
 
18
18
  import json as _json
19
19
  import logging
20
+ import os
20
21
  import re
21
22
  import sys
22
23
  import threading
23
24
  import time
24
25
  from io import StringIO
25
- from logging import WARN, LogRecord
26
+ from logging import ERROR, WARN, LogRecord
26
27
  from logging.handlers import HTTPHandler
27
28
  from queue import Empty, Queue
28
29
  from typing import TYPE_CHECKING, Any, Optional, TextIO, Union
@@ -42,6 +43,7 @@ from .constant import LOG_UPLOAD_INTERVAL
42
43
  LOGGER_NAME = "flwr"
43
44
  FLOWER_LOGGER = logging.getLogger(LOGGER_NAME)
44
45
  FLOWER_LOGGER.setLevel(logging.DEBUG)
46
+ log = FLOWER_LOGGER.log # pylint: disable=invalid-name
45
47
 
46
48
  LOG_COLORS = {
47
49
  "DEBUG": "\033[94m", # Blue
@@ -101,7 +103,7 @@ class ConsoleHandler(StreamHandler):
101
103
 
102
104
 
103
105
  def update_console_handler(
104
- level: Optional[int] = None,
106
+ level: Optional[Union[int, str]] = None,
105
107
  timestamps: Optional[bool] = None,
106
108
  colored: Optional[bool] = None,
107
109
  ) -> None:
@@ -125,6 +127,27 @@ console_handler = ConsoleHandler(
125
127
  console_handler.setLevel(logging.INFO)
126
128
  FLOWER_LOGGER.addHandler(console_handler)
127
129
 
130
+ # Set log level via env var (show timestamps for `DEBUG`)
131
+ if log_level := os.getenv("FLWR_LOG_LEVEL"):
132
+ log_level = log_level.upper()
133
+ try:
134
+ is_debug = log_level == "DEBUG"
135
+ if is_debug:
136
+ log(
137
+ WARN,
138
+ "DEBUG logs enabled. Do not use this in production, as it may expose "
139
+ "sensitive details.",
140
+ )
141
+ update_console_handler(level=log_level, timestamps=is_debug, colored=True)
142
+ except Exception: # pylint: disable=broad-exception-caught
143
+ # Alert user but don't raise exception
144
+ log(
145
+ ERROR,
146
+ "Failed to set logging level %s. Using default level: %s",
147
+ log_level,
148
+ logging.getLevelName(console_handler.level),
149
+ )
150
+
128
151
 
129
152
  class CustomHTTPHandler(HTTPHandler):
130
153
  """Custom HTTPHandler which overrides the mapLogRecords method."""
@@ -185,10 +208,6 @@ def configure(
185
208
  FLOWER_LOGGER.addHandler(http_handler)
186
209
 
187
210
 
188
- logger = logging.getLogger(LOGGER_NAME) # pylint: disable=invalid-name
189
- log = logger.log # pylint: disable=invalid-name
190
-
191
-
192
211
  def warn_preview_feature(name: str) -> None:
193
212
  """Warn the user when they use a preview feature."""
194
213
  log(
@@ -320,7 +339,7 @@ def _log_uploader(
320
339
  ) -> None:
321
340
  """Upload logs to the SuperLink."""
322
341
  exit_flag = False
323
- node = Node(node_id=node_id, anonymous=False)
342
+ node = Node(node_id=node_id)
324
343
  msgs: list[str] = []
325
344
  while True:
326
345
  # Fetch all messages from the queue
@@ -151,7 +151,7 @@ class RecordSet:
151
151
  >>> p_record = ParametersRecord({"my_array": arr})
152
152
  >>>
153
153
  >>> # Adding it to the record_set would look like this
154
- >>> my_recordset.configs_records["my_config"] = c_record
154
+ >>> my_recordset.parameters_records["my_parameters"] = p_record
155
155
 
156
156
  For additional examples on how to construct each of the records types shown
157
157
  above, please refer to the documentation for :code:`ConfigsRecord`,
@@ -117,3 +117,48 @@ def verify_hmac(key: bytes, message: bytes, hmac_value: bytes) -> bool:
117
117
  return True
118
118
  except InvalidSignature:
119
119
  return False
120
+
121
+
122
+ def sign_message(private_key: ec.EllipticCurvePrivateKey, message: bytes) -> bytes:
123
+ """Sign a message using the provided EC private key.
124
+
125
+ Parameters
126
+ ----------
127
+ private_key : ec.EllipticCurvePrivateKey
128
+ The EC private key to sign the message with.
129
+ message : bytes
130
+ The message to be signed.
131
+
132
+ Returns
133
+ -------
134
+ bytes
135
+ The signature of the message.
136
+ """
137
+ signature = private_key.sign(message, ec.ECDSA(hashes.SHA256()))
138
+ return signature
139
+
140
+
141
+ def verify_signature(
142
+ public_key: ec.EllipticCurvePublicKey, message: bytes, signature: bytes
143
+ ) -> bool:
144
+ """Verify a signature against a message using the provided EC public key.
145
+
146
+ Parameters
147
+ ----------
148
+ public_key : ec.EllipticCurvePublicKey
149
+ The EC public key to verify the signature.
150
+ message : bytes
151
+ The original message.
152
+ signature : bytes
153
+ The signature to verify.
154
+
155
+ Returns
156
+ -------
157
+ bool
158
+ True if the signature is valid, False otherwise.
159
+ """
160
+ try:
161
+ public_key.verify(signature, message, ec.ECDSA(hashes.SHA256()))
162
+ return True
163
+ except InvalidSignature:
164
+ return False
flwr/common/serde.py CHANGED
@@ -21,6 +21,8 @@ from typing import Any, TypeVar, cast
21
21
 
22
22
  from google.protobuf.message import Message as GrpcMessage
23
23
 
24
+ from flwr.common.constant import SUPERLINK_NODE_ID
25
+
24
26
  # pylint: disable=E0611
25
27
  from flwr.proto.clientappio_pb2 import ClientAppOutputCode, ClientAppOutputStatus
26
28
  from flwr.proto.error_pb2 import Error as ProtoError
@@ -605,8 +607,8 @@ def message_to_taskins(message: Message) -> TaskIns:
605
607
  group_id=md.group_id,
606
608
  run_id=md.run_id,
607
609
  task=Task(
608
- producer=Node(node_id=0, anonymous=True), # Assume driver node
609
- consumer=Node(node_id=md.dst_node_id, anonymous=False),
610
+ producer=Node(node_id=SUPERLINK_NODE_ID), # Assume driver node
611
+ consumer=Node(node_id=md.dst_node_id),
610
612
  created_at=md.created_at,
611
613
  ttl=md.ttl,
612
614
  ancestry=[md.reply_to_message] if md.reply_to_message != "" else [],
@@ -659,8 +661,8 @@ def message_to_taskres(message: Message) -> TaskRes:
659
661
  group_id=md.group_id,
660
662
  run_id=md.run_id,
661
663
  task=Task(
662
- producer=Node(node_id=md.src_node_id, anonymous=False),
663
- consumer=Node(node_id=0, anonymous=True), # Assume driver node
664
+ producer=Node(node_id=md.src_node_id),
665
+ consumer=Node(node_id=SUPERLINK_NODE_ID), # Assume driver node
664
666
  created_at=md.created_at,
665
667
  ttl=md.ttl,
666
668
  ancestry=[md.reply_to_message] if md.reply_to_message != "" else [],
flwr/common/typing.py CHANGED
@@ -266,3 +266,23 @@ class InvalidRunStatusException(BaseException):
266
266
  def __init__(self, message: str) -> None:
267
267
  super().__init__(message)
268
268
  self.message = message
269
+
270
+
271
+ # OIDC user authentication types
272
+ @dataclass
273
+ class UserAuthLoginDetails:
274
+ """User authentication login details."""
275
+
276
+ auth_type: str
277
+ device_code: str
278
+ verification_uri_complete: str
279
+ expires_in: int
280
+ interval: int
281
+
282
+
283
+ @dataclass
284
+ class UserAuthCredentials:
285
+ """User authentication tokens."""
286
+
287
+ access_token: str
288
+ refresh_token: str
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: flwr/proto/clientappio.proto
4
- # Protobuf Python Version: 4.25.0
4
+ # Protobuf Python Version: 4.25.1
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
flwr/proto/error_pb2.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: flwr/proto/error.proto
4
- # Protobuf Python Version: 4.25.0
4
+ # Protobuf Python Version: 4.25.1
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
flwr/proto/exec_pb2.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: flwr/proto/exec.proto
4
- # Protobuf Python Version: 4.25.0
4
+ # Protobuf Python Version: 4.25.1
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -18,7 +18,7 @@ from flwr.proto import recordset_pb2 as flwr_dot_proto_dot_recordset__pb2
18
18
  from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2
19
19
 
20
20
 
21
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/exec.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x1a\x66lwr/proto/recordset.proto\x1a\x14\x66lwr/proto/run.proto\"\xfb\x01\n\x0fStartRunRequest\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fab\x12H\n\x0foverride_config\x18\x02 \x03(\x0b\x32/.flwr.proto.StartRunRequest.OverrideConfigEntry\x12\x35\n\x12\x66\x65\x64\x65ration_options\x18\x03 \x01(\x0b\x32\x19.flwr.proto.ConfigsRecord\x1aI\n\x13OverrideConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"2\n\x10StartRunResponse\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"<\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x17\n\x0f\x61\x66ter_timestamp\x18\x02 \x01(\x01\"B\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t\x12\x18\n\x10latest_timestamp\x18\x02 \x01(\x01\"1\n\x0fListRunsRequest\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"\x9d\x01\n\x10ListRunsResponse\x12;\n\x08run_dict\x18\x01 \x03(\x0b\x32).flwr.proto.ListRunsResponse.RunDictEntry\x12\x0b\n\x03now\x18\x02 \x01(\t\x1a?\n\x0cRunDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x1e\n\x05value\x18\x02 \x01(\x0b\x32\x0f.flwr.proto.Run:\x02\x38\x01\"\x18\n\x16GetLoginDetailsRequest\"\x9c\x01\n\x17GetLoginDetailsResponse\x12L\n\rlogin_details\x18\x01 \x03(\x0b\x32\x35.flwr.proto.GetLoginDetailsResponse.LoginDetailsEntry\x1a\x33\n\x11LoginDetailsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x93\x01\n\x14GetAuthTokensRequest\x12G\n\x0c\x61uth_details\x18\x01 \x03(\x0b\x32\x31.flwr.proto.GetAuthTokensRequest.AuthDetailsEntry\x1a\x32\n\x10\x41uthDetailsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x92\x01\n\x15GetAuthTokensResponse\x12\x46\n\x0b\x61uth_tokens\x18\x01 \x03(\x0b\x32\x31.flwr.proto.GetAuthTokensResponse.AuthTokensEntry\x1a\x31\n\x0f\x41uthTokensEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\" \n\x0eStopRunRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"\"\n\x0fStopRunResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x32\xe5\x03\n\x04\x45xec\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\x00\x12\x44\n\x07StopRun\x12\x1a.flwr.proto.StopRunRequest\x1a\x1b.flwr.proto.StopRunResponse\"\x00\x12O\n\nStreamLogs\x12\x1d.flwr.proto.StreamLogsRequest\x1a\x1e.flwr.proto.StreamLogsResponse\"\x00\x30\x01\x12G\n\x08ListRuns\x12\x1b.flwr.proto.ListRunsRequest\x1a\x1c.flwr.proto.ListRunsResponse\"\x00\x12\\\n\x0fGetLoginDetails\x12\".flwr.proto.GetLoginDetailsRequest\x1a#.flwr.proto.GetLoginDetailsResponse\"\x00\x12V\n\rGetAuthTokens\x12 .flwr.proto.GetAuthTokensRequest\x1a!.flwr.proto.GetAuthTokensResponse\"\x00\x62\x06proto3')
21
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/exec.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x1a\x66lwr/proto/recordset.proto\x1a\x14\x66lwr/proto/run.proto\"\xfb\x01\n\x0fStartRunRequest\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fab\x12H\n\x0foverride_config\x18\x02 \x03(\x0b\x32/.flwr.proto.StartRunRequest.OverrideConfigEntry\x12\x35\n\x12\x66\x65\x64\x65ration_options\x18\x03 \x01(\x0b\x32\x19.flwr.proto.ConfigsRecord\x1aI\n\x13OverrideConfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.flwr.proto.Scalar:\x02\x38\x01\"2\n\x10StartRunResponse\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"<\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\x12\x17\n\x0f\x61\x66ter_timestamp\x18\x02 \x01(\x01\"B\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t\x12\x18\n\x10latest_timestamp\x18\x02 \x01(\x01\"1\n\x0fListRunsRequest\x12\x13\n\x06run_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\t\n\x07_run_id\"\x9d\x01\n\x10ListRunsResponse\x12;\n\x08run_dict\x18\x01 \x03(\x0b\x32).flwr.proto.ListRunsResponse.RunDictEntry\x12\x0b\n\x03now\x18\x02 \x01(\t\x1a?\n\x0cRunDictEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x1e\n\x05value\x18\x02 \x01(\x0b\x32\x0f.flwr.proto.Run:\x02\x38\x01\"\x18\n\x16GetLoginDetailsRequest\"\x8a\x01\n\x17GetLoginDetailsResponse\x12\x11\n\tauth_type\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65vice_code\x18\x02 \x01(\t\x12!\n\x19verification_uri_complete\x18\x03 \x01(\t\x12\x12\n\nexpires_in\x18\x04 \x01(\x03\x12\x10\n\x08interval\x18\x05 \x01(\x03\"+\n\x14GetAuthTokensRequest\x12\x13\n\x0b\x64\x65vice_code\x18\x01 \x01(\t\"D\n\x15GetAuthTokensResponse\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x01 \x01(\t\x12\x15\n\rrefresh_token\x18\x02 \x01(\t\" \n\x0eStopRunRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"\"\n\x0fStopRunResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x32\xe5\x03\n\x04\x45xec\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\x00\x12\x44\n\x07StopRun\x12\x1a.flwr.proto.StopRunRequest\x1a\x1b.flwr.proto.StopRunResponse\"\x00\x12O\n\nStreamLogs\x12\x1d.flwr.proto.StreamLogsRequest\x1a\x1e.flwr.proto.StreamLogsResponse\"\x00\x30\x01\x12G\n\x08ListRuns\x12\x1b.flwr.proto.ListRunsRequest\x1a\x1c.flwr.proto.ListRunsResponse\"\x00\x12\\\n\x0fGetLoginDetails\x12\".flwr.proto.GetLoginDetailsRequest\x1a#.flwr.proto.GetLoginDetailsResponse\"\x00\x12V\n\rGetAuthTokens\x12 .flwr.proto.GetAuthTokensRequest\x1a!.flwr.proto.GetAuthTokensResponse\"\x00\x62\x06proto3')
22
22
 
23
23
  _globals = globals()
24
24
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -29,12 +29,6 @@ if _descriptor._USE_C_DESCRIPTORS == False:
29
29
  _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_options = b'8\001'
30
30
  _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._options = None
31
31
  _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_options = b'8\001'
32
- _globals['_GETLOGINDETAILSRESPONSE_LOGINDETAILSENTRY']._options = None
33
- _globals['_GETLOGINDETAILSRESPONSE_LOGINDETAILSENTRY']._serialized_options = b'8\001'
34
- _globals['_GETAUTHTOKENSREQUEST_AUTHDETAILSENTRY']._options = None
35
- _globals['_GETAUTHTOKENSREQUEST_AUTHDETAILSENTRY']._serialized_options = b'8\001'
36
- _globals['_GETAUTHTOKENSRESPONSE_AUTHTOKENSENTRY']._options = None
37
- _globals['_GETAUTHTOKENSRESPONSE_AUTHTOKENSENTRY']._serialized_options = b'8\001'
38
32
  _globals['_STARTRUNREQUEST']._serialized_start=138
39
33
  _globals['_STARTRUNREQUEST']._serialized_end=389
40
34
  _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=316
@@ -54,21 +48,15 @@ if _descriptor._USE_C_DESCRIPTORS == False:
54
48
  _globals['_GETLOGINDETAILSREQUEST']._serialized_start=784
55
49
  _globals['_GETLOGINDETAILSREQUEST']._serialized_end=808
56
50
  _globals['_GETLOGINDETAILSRESPONSE']._serialized_start=811
57
- _globals['_GETLOGINDETAILSRESPONSE']._serialized_end=967
58
- _globals['_GETLOGINDETAILSRESPONSE_LOGINDETAILSENTRY']._serialized_start=916
59
- _globals['_GETLOGINDETAILSRESPONSE_LOGINDETAILSENTRY']._serialized_end=967
60
- _globals['_GETAUTHTOKENSREQUEST']._serialized_start=970
61
- _globals['_GETAUTHTOKENSREQUEST']._serialized_end=1117
62
- _globals['_GETAUTHTOKENSREQUEST_AUTHDETAILSENTRY']._serialized_start=1067
63
- _globals['_GETAUTHTOKENSREQUEST_AUTHDETAILSENTRY']._serialized_end=1117
64
- _globals['_GETAUTHTOKENSRESPONSE']._serialized_start=1120
65
- _globals['_GETAUTHTOKENSRESPONSE']._serialized_end=1266
66
- _globals['_GETAUTHTOKENSRESPONSE_AUTHTOKENSENTRY']._serialized_start=1217
67
- _globals['_GETAUTHTOKENSRESPONSE_AUTHTOKENSENTRY']._serialized_end=1266
68
- _globals['_STOPRUNREQUEST']._serialized_start=1268
69
- _globals['_STOPRUNREQUEST']._serialized_end=1300
70
- _globals['_STOPRUNRESPONSE']._serialized_start=1302
71
- _globals['_STOPRUNRESPONSE']._serialized_end=1336
72
- _globals['_EXEC']._serialized_start=1339
73
- _globals['_EXEC']._serialized_end=1824
51
+ _globals['_GETLOGINDETAILSRESPONSE']._serialized_end=949
52
+ _globals['_GETAUTHTOKENSREQUEST']._serialized_start=951
53
+ _globals['_GETAUTHTOKENSREQUEST']._serialized_end=994
54
+ _globals['_GETAUTHTOKENSRESPONSE']._serialized_start=996
55
+ _globals['_GETAUTHTOKENSRESPONSE']._serialized_end=1064
56
+ _globals['_STOPRUNREQUEST']._serialized_start=1066
57
+ _globals['_STOPRUNREQUEST']._serialized_end=1098
58
+ _globals['_STOPRUNRESPONSE']._serialized_start=1100
59
+ _globals['_STOPRUNRESPONSE']._serialized_end=1134
60
+ _globals['_EXEC']._serialized_start=1137
61
+ _globals['_EXEC']._serialized_end=1622
74
62
  # @@protoc_insertion_point(module_scope)
flwr/proto/exec_pb2.pyi CHANGED
@@ -143,77 +143,50 @@ global___GetLoginDetailsRequest = GetLoginDetailsRequest
143
143
 
144
144
  class GetLoginDetailsResponse(google.protobuf.message.Message):
145
145
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
146
- class LoginDetailsEntry(google.protobuf.message.Message):
147
- DESCRIPTOR: google.protobuf.descriptor.Descriptor
148
- KEY_FIELD_NUMBER: builtins.int
149
- VALUE_FIELD_NUMBER: builtins.int
150
- key: typing.Text
151
- value: typing.Text
152
- def __init__(self,
153
- *,
154
- key: typing.Text = ...,
155
- value: typing.Text = ...,
156
- ) -> None: ...
157
- def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ...
158
-
159
- LOGIN_DETAILS_FIELD_NUMBER: builtins.int
160
- @property
161
- def login_details(self) -> google.protobuf.internal.containers.ScalarMap[typing.Text, typing.Text]: ...
146
+ AUTH_TYPE_FIELD_NUMBER: builtins.int
147
+ DEVICE_CODE_FIELD_NUMBER: builtins.int
148
+ VERIFICATION_URI_COMPLETE_FIELD_NUMBER: builtins.int
149
+ EXPIRES_IN_FIELD_NUMBER: builtins.int
150
+ INTERVAL_FIELD_NUMBER: builtins.int
151
+ auth_type: typing.Text
152
+ device_code: typing.Text
153
+ verification_uri_complete: typing.Text
154
+ expires_in: builtins.int
155
+ interval: builtins.int
162
156
  def __init__(self,
163
157
  *,
164
- login_details: typing.Optional[typing.Mapping[typing.Text, typing.Text]] = ...,
158
+ auth_type: typing.Text = ...,
159
+ device_code: typing.Text = ...,
160
+ verification_uri_complete: typing.Text = ...,
161
+ expires_in: builtins.int = ...,
162
+ interval: builtins.int = ...,
165
163
  ) -> None: ...
166
- def ClearField(self, field_name: typing_extensions.Literal["login_details",b"login_details"]) -> None: ...
164
+ def ClearField(self, field_name: typing_extensions.Literal["auth_type",b"auth_type","device_code",b"device_code","expires_in",b"expires_in","interval",b"interval","verification_uri_complete",b"verification_uri_complete"]) -> None: ...
167
165
  global___GetLoginDetailsResponse = GetLoginDetailsResponse
168
166
 
169
167
  class GetAuthTokensRequest(google.protobuf.message.Message):
170
168
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
171
- class AuthDetailsEntry(google.protobuf.message.Message):
172
- DESCRIPTOR: google.protobuf.descriptor.Descriptor
173
- KEY_FIELD_NUMBER: builtins.int
174
- VALUE_FIELD_NUMBER: builtins.int
175
- key: typing.Text
176
- value: typing.Text
177
- def __init__(self,
178
- *,
179
- key: typing.Text = ...,
180
- value: typing.Text = ...,
181
- ) -> None: ...
182
- def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ...
183
-
184
- AUTH_DETAILS_FIELD_NUMBER: builtins.int
185
- @property
186
- def auth_details(self) -> google.protobuf.internal.containers.ScalarMap[typing.Text, typing.Text]: ...
169
+ DEVICE_CODE_FIELD_NUMBER: builtins.int
170
+ device_code: typing.Text
187
171
  def __init__(self,
188
172
  *,
189
- auth_details: typing.Optional[typing.Mapping[typing.Text, typing.Text]] = ...,
173
+ device_code: typing.Text = ...,
190
174
  ) -> None: ...
191
- def ClearField(self, field_name: typing_extensions.Literal["auth_details",b"auth_details"]) -> None: ...
175
+ def ClearField(self, field_name: typing_extensions.Literal["device_code",b"device_code"]) -> None: ...
192
176
  global___GetAuthTokensRequest = GetAuthTokensRequest
193
177
 
194
178
  class GetAuthTokensResponse(google.protobuf.message.Message):
195
179
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
196
- class AuthTokensEntry(google.protobuf.message.Message):
197
- DESCRIPTOR: google.protobuf.descriptor.Descriptor
198
- KEY_FIELD_NUMBER: builtins.int
199
- VALUE_FIELD_NUMBER: builtins.int
200
- key: typing.Text
201
- value: typing.Text
202
- def __init__(self,
203
- *,
204
- key: typing.Text = ...,
205
- value: typing.Text = ...,
206
- ) -> None: ...
207
- def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ...
208
-
209
- AUTH_TOKENS_FIELD_NUMBER: builtins.int
210
- @property
211
- def auth_tokens(self) -> google.protobuf.internal.containers.ScalarMap[typing.Text, typing.Text]: ...
180
+ ACCESS_TOKEN_FIELD_NUMBER: builtins.int
181
+ REFRESH_TOKEN_FIELD_NUMBER: builtins.int
182
+ access_token: typing.Text
183
+ refresh_token: typing.Text
212
184
  def __init__(self,
213
185
  *,
214
- auth_tokens: typing.Optional[typing.Mapping[typing.Text, typing.Text]] = ...,
186
+ access_token: typing.Text = ...,
187
+ refresh_token: typing.Text = ...,
215
188
  ) -> None: ...
216
- def ClearField(self, field_name: typing_extensions.Literal["auth_tokens",b"auth_tokens"]) -> None: ...
189
+ def ClearField(self, field_name: typing_extensions.Literal["access_token",b"access_token","refresh_token",b"refresh_token"]) -> None: ...
217
190
  global___GetAuthTokensResponse = GetAuthTokensResponse
218
191
 
219
192
  class StopRunRequest(google.protobuf.message.Message):
flwr/proto/fab_pb2.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: flwr/proto/fab.proto
4
- # Protobuf Python Version: 4.25.0
4
+ # Protobuf Python Version: 4.25.1
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool