flwr-nightly 1.23.0.dev20251001__py3-none-any.whl → 1.23.0.dev20251002__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 (44) hide show
  1. flwr/cli/app.py +13 -0
  2. flwr/cli/auth_plugin/__init__.py +6 -3
  3. flwr/cli/auth_plugin/auth_plugin.py +23 -11
  4. flwr/cli/auth_plugin/noop_auth_plugin.py +58 -0
  5. flwr/cli/auth_plugin/oidc_cli_plugin.py +12 -22
  6. flwr/cli/{cli_user_auth_interceptor.py → cli_account_auth_interceptor.py} +4 -4
  7. flwr/cli/login/login.py +29 -9
  8. flwr/{client/clientapp → cli/supernode}/__init__.py +11 -1
  9. flwr/cli/supernode/create.py +58 -0
  10. flwr/cli/supernode/delete.py +58 -0
  11. flwr/cli/supernode/ls.py +51 -0
  12. flwr/cli/utils.py +29 -15
  13. flwr/client/__init__.py +2 -1
  14. flwr/clientapp/__init__.py +1 -2
  15. flwr/{client/clientapp → clientapp}/utils.py +1 -1
  16. flwr/common/constant.py +10 -4
  17. flwr/common/typing.py +5 -5
  18. flwr/compat/client/app.py +1 -1
  19. flwr/proto/control_pb2.py +48 -35
  20. flwr/proto/control_pb2.pyi +63 -0
  21. flwr/proto/control_pb2_grpc.py +102 -0
  22. flwr/proto/control_pb2_grpc.pyi +39 -0
  23. flwr/proto/node_pb2.py +3 -1
  24. flwr/proto/node_pb2.pyi +33 -0
  25. flwr/server/app.py +17 -10
  26. flwr/server/superlink/fleet/vce/backend/backend.py +1 -1
  27. flwr/server/superlink/fleet/vce/backend/raybackend.py +1 -1
  28. flwr/server/superlink/fleet/vce/vce_api.py +2 -2
  29. flwr/simulation/ray_transport/ray_actor.py +1 -1
  30. flwr/simulation/ray_transport/ray_client_proxy.py +1 -1
  31. flwr/simulation/run_simulation.py +1 -1
  32. flwr/superlink/auth_plugin/__init__.py +5 -2
  33. flwr/superlink/auth_plugin/auth_plugin.py +16 -12
  34. flwr/superlink/auth_plugin/noop_auth_plugin.py +87 -0
  35. flwr/superlink/servicer/control/{control_user_auth_interceptor.py → control_account_auth_interceptor.py} +16 -16
  36. flwr/superlink/servicer/control/control_event_log_interceptor.py +1 -1
  37. flwr/superlink/servicer/control/control_grpc.py +6 -6
  38. flwr/superlink/servicer/control/control_servicer.py +45 -17
  39. flwr/supernode/runtime/run_clientapp.py +2 -2
  40. {flwr_nightly-1.23.0.dev20251001.dist-info → flwr_nightly-1.23.0.dev20251002.dist-info}/METADATA +1 -1
  41. {flwr_nightly-1.23.0.dev20251001.dist-info → flwr_nightly-1.23.0.dev20251002.dist-info}/RECORD +44 -39
  42. /flwr/{client → clientapp}/client_app.py +0 -0
  43. {flwr_nightly-1.23.0.dev20251001.dist-info → flwr_nightly-1.23.0.dev20251002.dist-info}/WHEEL +0 -0
  44. {flwr_nightly-1.23.0.dev20251001.dist-info → flwr_nightly-1.23.0.dev20251002.dist-info}/entry_points.txt +0 -0
flwr/cli/utils.py CHANGED
@@ -30,8 +30,8 @@ from flwr.common.constant import (
30
30
  AUTH_TYPE_JSON_KEY,
31
31
  CREDENTIALS_DIR,
32
32
  FLWR_DIR,
33
+ NO_ACCOUNT_AUTH_MESSAGE,
33
34
  NO_ARTIFACT_PROVIDER_MESSAGE,
34
- NO_USER_AUTH_MESSAGE,
35
35
  PULL_UNFINISHED_RUN_MESSAGE,
36
36
  RUN_ID_NOT_FOUND_MESSAGE,
37
37
  )
@@ -42,7 +42,7 @@ from flwr.common.grpc import (
42
42
  )
43
43
 
44
44
  from .auth_plugin import CliAuthPlugin, get_cli_auth_plugins
45
- from .cli_user_auth_interceptor import CliUserAuthInterceptor
45
+ from .cli_account_auth_interceptor import CliAccountAuthInterceptor
46
46
  from .config_utils import validate_certificate_in_federation_config
47
47
 
48
48
 
@@ -165,8 +165,8 @@ def get_sha256_hash(file_path_or_int: Union[Path, int]) -> str:
165
165
  return sha256.hexdigest()
166
166
 
167
167
 
168
- def get_user_auth_config_path(root_dir: Path, federation: str) -> Path:
169
- """Return the path to the user auth config file.
168
+ def get_account_auth_config_path(root_dir: Path, federation: str) -> Path:
169
+ """Return the path to the account auth config file.
170
170
 
171
171
  Additionally, a `.gitignore` file will be created in the Flower directory to
172
172
  include the `.credentials` folder to be excluded from git. If the `.gitignore`
@@ -216,18 +216,32 @@ def get_user_auth_config_path(root_dir: Path, federation: str) -> Path:
216
216
  return credentials_dir / f"{federation}.json"
217
217
 
218
218
 
219
+ def account_auth_enabled(federation_config: dict[str, Any]) -> bool:
220
+ """Check if account authentication is enabled in the federation config."""
221
+ enabled: bool = federation_config.get("enable-user-auth", False)
222
+ enabled |= federation_config.get("enable-account-auth", False)
223
+ if "enable-user-auth" in federation_config:
224
+ typer.secho(
225
+ "`enable-user-auth` is deprecated and will be removed in a future "
226
+ "release. Please use `enable-account-auth` instead.",
227
+ fg=typer.colors.YELLOW,
228
+ bold=True,
229
+ )
230
+ return enabled
231
+
232
+
219
233
  def try_obtain_cli_auth_plugin(
220
234
  root_dir: Path,
221
235
  federation: str,
222
236
  federation_config: dict[str, Any],
223
237
  auth_type: Optional[str] = None,
224
238
  ) -> Optional[CliAuthPlugin]:
225
- """Load the CLI-side user auth plugin for the given auth type."""
226
- # Check if user auth is enabled
227
- if not federation_config.get("enable-user-auth", False):
239
+ """Load the CLI-side account auth plugin for the given auth type."""
240
+ # Check if account auth is enabled
241
+ if not account_auth_enabled(federation_config):
228
242
  return None
229
243
 
230
- config_path = get_user_auth_config_path(root_dir, federation)
244
+ config_path = get_account_auth_config_path(root_dir, federation)
231
245
 
232
246
  # Get the auth type from the config if not provided
233
247
  # auth_type will be None for all CLI commands except login
@@ -238,7 +252,7 @@ def try_obtain_cli_auth_plugin(
238
252
  auth_type = json_file[AUTH_TYPE_JSON_KEY]
239
253
  except (FileNotFoundError, KeyError):
240
254
  typer.secho(
241
- "❌ Missing or invalid credentials for user authentication. "
255
+ "❌ Missing or invalid credentials for account authentication. "
242
256
  "Please run `flwr login` to authenticate.",
243
257
  fg=typer.colors.RED,
244
258
  bold=True,
@@ -251,7 +265,7 @@ def try_obtain_cli_auth_plugin(
251
265
  auth_plugin_class = all_plugins[auth_type]
252
266
  return auth_plugin_class(config_path)
253
267
  except KeyError:
254
- typer.echo(f"❌ Unknown user authentication type: {auth_type}")
268
+ typer.echo(f"❌ Unknown account authentication type: {auth_type}")
255
269
  raise typer.Exit(code=1) from None
256
270
  except ImportError:
257
271
  typer.echo("❌ No authentication plugins are currently supported.")
@@ -266,13 +280,13 @@ def init_channel(
266
280
  app, federation_config
267
281
  )
268
282
 
269
- # Initialize the CLI-side user auth interceptor
283
+ # Initialize the CLI-side account auth interceptor
270
284
  interceptors: list[grpc.UnaryUnaryClientInterceptor] = []
271
285
  if auth_plugin is not None:
272
286
  # Check if TLS is enabled. If not, raise an error
273
287
  if insecure:
274
288
  typer.secho(
275
- "❌ User authentication requires TLS to be enabled. "
289
+ "❌ Account authentication requires TLS to be enabled. "
276
290
  "Remove `insecure = true` from the federation configuration.",
277
291
  fg=typer.colors.RED,
278
292
  bold=True,
@@ -280,7 +294,7 @@ def init_channel(
280
294
  raise typer.Exit(code=1)
281
295
 
282
296
  auth_plugin.load_tokens()
283
- interceptors.append(CliUserAuthInterceptor(auth_plugin))
297
+ interceptors.append(CliAccountAuthInterceptor(auth_plugin))
284
298
 
285
299
  # Create the gRPC channel
286
300
  channel = create_channel(
@@ -314,9 +328,9 @@ def flwr_cli_grpc_exc_handler() -> Iterator[None]:
314
328
  )
315
329
  raise typer.Exit(code=1) from None
316
330
  if e.code() == grpc.StatusCode.UNIMPLEMENTED:
317
- if e.details() == NO_USER_AUTH_MESSAGE: # pylint: disable=E1101
331
+ if e.details() == NO_ACCOUNT_AUTH_MESSAGE: # pylint: disable=E1101
318
332
  typer.secho(
319
- "❌ User authentication is not enabled on this SuperLink.",
333
+ "❌ Account authentication is not enabled on this SuperLink.",
320
334
  fg=typer.colors.RED,
321
335
  bold=True,
322
336
  )
flwr/client/__init__.py CHANGED
@@ -15,10 +15,11 @@
15
15
  """Flower client."""
16
16
 
17
17
 
18
+ from flwr.clientapp import ClientApp
19
+
18
20
  from ..compat.client.app import start_client as start_client # Deprecated
19
21
  from ..compat.client.app import start_numpy_client as start_numpy_client # Deprecated
20
22
  from .client import Client as Client
21
- from .client_app import ClientApp as ClientApp
22
23
  from .numpy_client import NumPyClient as NumPyClient
23
24
  from .typing import ClientFn as ClientFn
24
25
  from .typing import ClientFnExt as ClientFnExt
@@ -15,9 +15,8 @@
15
15
  """Public Flower ClientApp APIs."""
16
16
 
17
17
 
18
- from flwr.client.client_app import ClientApp
19
-
20
18
  from . import mod
19
+ from .client_app import ClientApp as ClientApp
21
20
 
22
21
  __all__ = [
23
22
  "ClientApp",
@@ -19,7 +19,7 @@ from logging import DEBUG
19
19
  from pathlib import Path
20
20
  from typing import Callable, Optional
21
21
 
22
- from flwr.client.client_app import ClientApp, LoadClientAppError
22
+ from flwr.clientapp.client_app import ClientApp, LoadClientAppError
23
23
  from flwr.common.config import (
24
24
  get_flwr_dir,
25
25
  get_metadata_from_config,
flwr/common/constant.py CHANGED
@@ -109,14 +109,14 @@ LOG_UPLOAD_INTERVAL = 0.2 # Minimum interval between two log uploads
109
109
  # Retry configurations
110
110
  MAX_RETRY_DELAY = 20 # Maximum delay duration between two consecutive retries.
111
111
 
112
- # Constants for user authentication
112
+ # Constants for account authentication
113
113
  CREDENTIALS_DIR = ".credentials"
114
114
  AUTH_TYPE_JSON_KEY = "auth-type" # For key name in JSON file
115
115
  AUTH_TYPE_YAML_KEY = "auth_type" # For key name in YAML file
116
116
  ACCESS_TOKEN_KEY = "flwr-oidc-access-token"
117
117
  REFRESH_TOKEN_KEY = "flwr-oidc-refresh-token"
118
118
 
119
- # Constants for user authorization
119
+ # Constants for account authorization
120
120
  AUTHZ_TYPE_YAML_KEY = "authz_type" # For key name in YAML file
121
121
 
122
122
  # Constants for node authentication
@@ -154,7 +154,7 @@ PULL_BACKOFF_CAP = 10 # Maximum backoff time for pulling objects
154
154
 
155
155
  # ControlServicer constants
156
156
  RUN_ID_NOT_FOUND_MESSAGE = "Run ID not found"
157
- NO_USER_AUTH_MESSAGE = "ControlServicer initialized without user authentication"
157
+ NO_ACCOUNT_AUTH_MESSAGE = "ControlServicer initialized without account authentication"
158
158
  NO_ARTIFACT_PROVIDER_MESSAGE = "ControlServicer initialized without artifact provider"
159
159
  PULL_UNFINISHED_RUN_MESSAGE = "Cannot pull artifacts for an unfinished run"
160
160
 
@@ -246,8 +246,9 @@ class CliOutputFormat:
246
246
 
247
247
 
248
248
  class AuthType:
249
- """User authentication types."""
249
+ """Account authentication types."""
250
250
 
251
+ NOOP = "noop"
251
252
  OIDC = "oidc"
252
253
 
253
254
  def __new__(cls) -> AuthType:
@@ -281,3 +282,8 @@ class ExecPluginType:
281
282
  """Return all SuperExec plugin types."""
282
283
  # Filter all constants (uppercase) of the class
283
284
  return [v for k, v in vars(ExecPluginType).items() if k.isupper()]
285
+
286
+
287
+ # Constants for No-op auth plugins
288
+ NOOP_FLWR_AID = "sys_noauth"
289
+ NOOP_ACCOUNT_NAME = "sys_noauth"
flwr/common/typing.py CHANGED
@@ -270,10 +270,10 @@ class InvalidRunStatusException(BaseException):
270
270
  self.message = message
271
271
 
272
272
 
273
- # OIDC user authentication types
273
+ # OIDC account authentication types
274
274
  @dataclass
275
- class UserAuthLoginDetails:
276
- """User authentication login details."""
275
+ class AccountAuthLoginDetails:
276
+ """Account authentication login details."""
277
277
 
278
278
  auth_type: str
279
279
  device_code: str
@@ -283,8 +283,8 @@ class UserAuthLoginDetails:
283
283
 
284
284
 
285
285
  @dataclass
286
- class UserAuthCredentials:
287
- """User authentication tokens."""
286
+ class AccountAuthCredentials:
287
+ """Account authentication tokens."""
288
288
 
289
289
  access_token: str
290
290
  refresh_token: str
flwr/compat/client/app.py CHANGED
@@ -28,11 +28,11 @@ from flwr.app.error import Error
28
28
  from flwr.cli.config_utils import get_fab_metadata
29
29
  from flwr.cli.install import install_from_fab
30
30
  from flwr.client.client import Client
31
- from flwr.client.client_app import ClientApp, LoadClientAppError
32
31
  from flwr.client.message_handler.message_handler import handle_control_message
33
32
  from flwr.client.numpy_client import NumPyClient
34
33
  from flwr.client.run_info_store import DeprecatedRunInfoStore
35
34
  from flwr.client.typing import ClientFnExt
35
+ from flwr.clientapp.client_app import ClientApp, LoadClientAppError
36
36
  from flwr.common import GRPC_MAX_MESSAGE_LENGTH, Context, EventType, Message, event
37
37
  from flwr.common.address import parse_address
38
38
  from flwr.common.constant import (
flwr/proto/control_pb2.py CHANGED
@@ -16,9 +16,10 @@ from flwr.proto import fab_pb2 as flwr_dot_proto_dot_fab__pb2
16
16
  from flwr.proto import transport_pb2 as flwr_dot_proto_dot_transport__pb2
17
17
  from flwr.proto import recorddict_pb2 as flwr_dot_proto_dot_recorddict__pb2
18
18
  from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2
19
+ from flwr.proto import node_pb2 as flwr_dot_proto_dot_node__pb2
19
20
 
20
21
 
21
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18\x66lwr/proto/control.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x1b\x66lwr/proto/recorddict.proto\x1a\x14\x66lwr/proto/run.proto\"\xfa\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\x34\n\x12\x66\x65\x64\x65ration_options\x18\x03 \x01(\x0b\x32\x18.flwr.proto.ConfigRecord\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\"&\n\x14PullArtifactsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"1\n\x15PullArtifactsResponse\x12\x10\n\x03url\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x06\n\x04_url2\xc0\x04\n\x07\x43ontrol\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\x12V\n\rPullArtifacts\x12 .flwr.proto.PullArtifactsRequest\x1a!.flwr.proto.PullArtifactsResponse\"\x00\x62\x06proto3')
22
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18\x66lwr/proto/control.proto\x12\nflwr.proto\x1a\x14\x66lwr/proto/fab.proto\x1a\x1a\x66lwr/proto/transport.proto\x1a\x1b\x66lwr/proto/recorddict.proto\x1a\x14\x66lwr/proto/run.proto\x1a\x15\x66lwr/proto/node.proto\"\xfa\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\x34\n\x12\x66\x65\x64\x65ration_options\x18\x03 \x01(\x0b\x32\x18.flwr.proto.ConfigRecord\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\"&\n\x14PullArtifactsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x04\"1\n\x15PullArtifactsResponse\x12\x10\n\x03url\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x06\n\x04_url\"*\n\x14\x43reateNodeCliRequest\x12\x12\n\npublic_key\x18\x01 \x01(\t\"9\n\x15\x43reateNodeCliResponse\x12\x14\n\x07node_id\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\n\n\x08_node_id\"\'\n\x14\x44\x65leteNodeCliRequest\x12\x0f\n\x07node_id\x18\x01 \x01(\x04\"\x17\n\x15\x44\x65leteNodeCliResponse\"\x15\n\x13ListNodesCliRequest\"M\n\x14ListNodesCliResponse\x12(\n\nnodes_info\x18\x01 \x03(\x0b\x32\x14.flwr.proto.NodeInfo\x12\x0b\n\x03now\x18\x02 \x01(\t2\xc5\x06\n\x07\x43ontrol\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\x12V\n\rPullArtifacts\x12 .flwr.proto.PullArtifactsRequest\x1a!.flwr.proto.PullArtifactsResponse\"\x00\x12V\n\rCreateNodeCli\x12 .flwr.proto.CreateNodeCliRequest\x1a!.flwr.proto.CreateNodeCliResponse\"\x00\x12V\n\rDeleteNodeCli\x12 .flwr.proto.DeleteNodeCliRequest\x1a!.flwr.proto.DeleteNodeCliResponse\"\x00\x12S\n\x0cListNodesCli\x12\x1f.flwr.proto.ListNodesCliRequest\x1a .flwr.proto.ListNodesCliResponse\"\x00\x62\x06proto3')
22
23
 
23
24
  _globals = globals()
24
25
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -29,38 +30,50 @@ if _descriptor._USE_C_DESCRIPTORS == False:
29
30
  _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_options = b'8\001'
30
31
  _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._options = None
31
32
  _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_options = b'8\001'
32
- _globals['_STARTRUNREQUEST']._serialized_start=142
33
- _globals['_STARTRUNREQUEST']._serialized_end=392
34
- _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=319
35
- _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=392
36
- _globals['_STARTRUNRESPONSE']._serialized_start=394
37
- _globals['_STARTRUNRESPONSE']._serialized_end=444
38
- _globals['_STREAMLOGSREQUEST']._serialized_start=446
39
- _globals['_STREAMLOGSREQUEST']._serialized_end=506
40
- _globals['_STREAMLOGSRESPONSE']._serialized_start=508
41
- _globals['_STREAMLOGSRESPONSE']._serialized_end=574
42
- _globals['_LISTRUNSREQUEST']._serialized_start=576
43
- _globals['_LISTRUNSREQUEST']._serialized_end=625
44
- _globals['_LISTRUNSRESPONSE']._serialized_start=628
45
- _globals['_LISTRUNSRESPONSE']._serialized_end=785
46
- _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_start=722
47
- _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_end=785
48
- _globals['_GETLOGINDETAILSREQUEST']._serialized_start=787
49
- _globals['_GETLOGINDETAILSREQUEST']._serialized_end=811
50
- _globals['_GETLOGINDETAILSRESPONSE']._serialized_start=814
51
- _globals['_GETLOGINDETAILSRESPONSE']._serialized_end=952
52
- _globals['_GETAUTHTOKENSREQUEST']._serialized_start=954
53
- _globals['_GETAUTHTOKENSREQUEST']._serialized_end=997
54
- _globals['_GETAUTHTOKENSRESPONSE']._serialized_start=999
55
- _globals['_GETAUTHTOKENSRESPONSE']._serialized_end=1067
56
- _globals['_STOPRUNREQUEST']._serialized_start=1069
57
- _globals['_STOPRUNREQUEST']._serialized_end=1101
58
- _globals['_STOPRUNRESPONSE']._serialized_start=1103
59
- _globals['_STOPRUNRESPONSE']._serialized_end=1137
60
- _globals['_PULLARTIFACTSREQUEST']._serialized_start=1139
61
- _globals['_PULLARTIFACTSREQUEST']._serialized_end=1177
62
- _globals['_PULLARTIFACTSRESPONSE']._serialized_start=1179
63
- _globals['_PULLARTIFACTSRESPONSE']._serialized_end=1228
64
- _globals['_CONTROL']._serialized_start=1231
65
- _globals['_CONTROL']._serialized_end=1807
33
+ _globals['_STARTRUNREQUEST']._serialized_start=165
34
+ _globals['_STARTRUNREQUEST']._serialized_end=415
35
+ _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_start=342
36
+ _globals['_STARTRUNREQUEST_OVERRIDECONFIGENTRY']._serialized_end=415
37
+ _globals['_STARTRUNRESPONSE']._serialized_start=417
38
+ _globals['_STARTRUNRESPONSE']._serialized_end=467
39
+ _globals['_STREAMLOGSREQUEST']._serialized_start=469
40
+ _globals['_STREAMLOGSREQUEST']._serialized_end=529
41
+ _globals['_STREAMLOGSRESPONSE']._serialized_start=531
42
+ _globals['_STREAMLOGSRESPONSE']._serialized_end=597
43
+ _globals['_LISTRUNSREQUEST']._serialized_start=599
44
+ _globals['_LISTRUNSREQUEST']._serialized_end=648
45
+ _globals['_LISTRUNSRESPONSE']._serialized_start=651
46
+ _globals['_LISTRUNSRESPONSE']._serialized_end=808
47
+ _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_start=745
48
+ _globals['_LISTRUNSRESPONSE_RUNDICTENTRY']._serialized_end=808
49
+ _globals['_GETLOGINDETAILSREQUEST']._serialized_start=810
50
+ _globals['_GETLOGINDETAILSREQUEST']._serialized_end=834
51
+ _globals['_GETLOGINDETAILSRESPONSE']._serialized_start=837
52
+ _globals['_GETLOGINDETAILSRESPONSE']._serialized_end=975
53
+ _globals['_GETAUTHTOKENSREQUEST']._serialized_start=977
54
+ _globals['_GETAUTHTOKENSREQUEST']._serialized_end=1020
55
+ _globals['_GETAUTHTOKENSRESPONSE']._serialized_start=1022
56
+ _globals['_GETAUTHTOKENSRESPONSE']._serialized_end=1090
57
+ _globals['_STOPRUNREQUEST']._serialized_start=1092
58
+ _globals['_STOPRUNREQUEST']._serialized_end=1124
59
+ _globals['_STOPRUNRESPONSE']._serialized_start=1126
60
+ _globals['_STOPRUNRESPONSE']._serialized_end=1160
61
+ _globals['_PULLARTIFACTSREQUEST']._serialized_start=1162
62
+ _globals['_PULLARTIFACTSREQUEST']._serialized_end=1200
63
+ _globals['_PULLARTIFACTSRESPONSE']._serialized_start=1202
64
+ _globals['_PULLARTIFACTSRESPONSE']._serialized_end=1251
65
+ _globals['_CREATENODECLIREQUEST']._serialized_start=1253
66
+ _globals['_CREATENODECLIREQUEST']._serialized_end=1295
67
+ _globals['_CREATENODECLIRESPONSE']._serialized_start=1297
68
+ _globals['_CREATENODECLIRESPONSE']._serialized_end=1354
69
+ _globals['_DELETENODECLIREQUEST']._serialized_start=1356
70
+ _globals['_DELETENODECLIREQUEST']._serialized_end=1395
71
+ _globals['_DELETENODECLIRESPONSE']._serialized_start=1397
72
+ _globals['_DELETENODECLIRESPONSE']._serialized_end=1420
73
+ _globals['_LISTNODESCLIREQUEST']._serialized_start=1422
74
+ _globals['_LISTNODESCLIREQUEST']._serialized_end=1443
75
+ _globals['_LISTNODESCLIRESPONSE']._serialized_start=1445
76
+ _globals['_LISTNODESCLIRESPONSE']._serialized_end=1522
77
+ _globals['_CONTROL']._serialized_start=1525
78
+ _globals['_CONTROL']._serialized_end=2362
66
79
  # @@protoc_insertion_point(module_scope)
@@ -4,6 +4,7 @@ isort:skip_file
4
4
  """
5
5
  import builtins
6
6
  import flwr.proto.fab_pb2
7
+ import flwr.proto.node_pb2
7
8
  import flwr.proto.recorddict_pb2
8
9
  import flwr.proto.run_pb2
9
10
  import flwr.proto.transport_pb2
@@ -234,3 +235,65 @@ class PullArtifactsResponse(google.protobuf.message.Message):
234
235
  def ClearField(self, field_name: typing_extensions.Literal["_url",b"_url","url",b"url"]) -> None: ...
235
236
  def WhichOneof(self, oneof_group: typing_extensions.Literal["_url",b"_url"]) -> typing.Optional[typing_extensions.Literal["url"]]: ...
236
237
  global___PullArtifactsResponse = PullArtifactsResponse
238
+
239
+ class CreateNodeCliRequest(google.protobuf.message.Message):
240
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
241
+ PUBLIC_KEY_FIELD_NUMBER: builtins.int
242
+ public_key: typing.Text
243
+ def __init__(self,
244
+ *,
245
+ public_key: typing.Text = ...,
246
+ ) -> None: ...
247
+ def ClearField(self, field_name: typing_extensions.Literal["public_key",b"public_key"]) -> None: ...
248
+ global___CreateNodeCliRequest = CreateNodeCliRequest
249
+
250
+ class CreateNodeCliResponse(google.protobuf.message.Message):
251
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
252
+ NODE_ID_FIELD_NUMBER: builtins.int
253
+ node_id: builtins.int
254
+ def __init__(self,
255
+ *,
256
+ node_id: typing.Optional[builtins.int] = ...,
257
+ ) -> None: ...
258
+ def HasField(self, field_name: typing_extensions.Literal["_node_id",b"_node_id","node_id",b"node_id"]) -> builtins.bool: ...
259
+ def ClearField(self, field_name: typing_extensions.Literal["_node_id",b"_node_id","node_id",b"node_id"]) -> None: ...
260
+ def WhichOneof(self, oneof_group: typing_extensions.Literal["_node_id",b"_node_id"]) -> typing.Optional[typing_extensions.Literal["node_id"]]: ...
261
+ global___CreateNodeCliResponse = CreateNodeCliResponse
262
+
263
+ class DeleteNodeCliRequest(google.protobuf.message.Message):
264
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
265
+ NODE_ID_FIELD_NUMBER: builtins.int
266
+ node_id: builtins.int
267
+ def __init__(self,
268
+ *,
269
+ node_id: builtins.int = ...,
270
+ ) -> None: ...
271
+ def ClearField(self, field_name: typing_extensions.Literal["node_id",b"node_id"]) -> None: ...
272
+ global___DeleteNodeCliRequest = DeleteNodeCliRequest
273
+
274
+ class DeleteNodeCliResponse(google.protobuf.message.Message):
275
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
276
+ def __init__(self,
277
+ ) -> None: ...
278
+ global___DeleteNodeCliResponse = DeleteNodeCliResponse
279
+
280
+ class ListNodesCliRequest(google.protobuf.message.Message):
281
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
282
+ def __init__(self,
283
+ ) -> None: ...
284
+ global___ListNodesCliRequest = ListNodesCliRequest
285
+
286
+ class ListNodesCliResponse(google.protobuf.message.Message):
287
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
288
+ NODES_INFO_FIELD_NUMBER: builtins.int
289
+ NOW_FIELD_NUMBER: builtins.int
290
+ @property
291
+ def nodes_info(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[flwr.proto.node_pb2.NodeInfo]: ...
292
+ now: typing.Text
293
+ def __init__(self,
294
+ *,
295
+ nodes_info: typing.Optional[typing.Iterable[flwr.proto.node_pb2.NodeInfo]] = ...,
296
+ now: typing.Text = ...,
297
+ ) -> None: ...
298
+ def ClearField(self, field_name: typing_extensions.Literal["nodes_info",b"nodes_info","now",b"now"]) -> None: ...
299
+ global___ListNodesCliResponse = ListNodesCliResponse
@@ -49,6 +49,21 @@ class ControlStub(object):
49
49
  request_serializer=flwr_dot_proto_dot_control__pb2.PullArtifactsRequest.SerializeToString,
50
50
  response_deserializer=flwr_dot_proto_dot_control__pb2.PullArtifactsResponse.FromString,
51
51
  )
52
+ self.CreateNodeCli = channel.unary_unary(
53
+ '/flwr.proto.Control/CreateNodeCli',
54
+ request_serializer=flwr_dot_proto_dot_control__pb2.CreateNodeCliRequest.SerializeToString,
55
+ response_deserializer=flwr_dot_proto_dot_control__pb2.CreateNodeCliResponse.FromString,
56
+ )
57
+ self.DeleteNodeCli = channel.unary_unary(
58
+ '/flwr.proto.Control/DeleteNodeCli',
59
+ request_serializer=flwr_dot_proto_dot_control__pb2.DeleteNodeCliRequest.SerializeToString,
60
+ response_deserializer=flwr_dot_proto_dot_control__pb2.DeleteNodeCliResponse.FromString,
61
+ )
62
+ self.ListNodesCli = channel.unary_unary(
63
+ '/flwr.proto.Control/ListNodesCli',
64
+ request_serializer=flwr_dot_proto_dot_control__pb2.ListNodesCliRequest.SerializeToString,
65
+ response_deserializer=flwr_dot_proto_dot_control__pb2.ListNodesCliResponse.FromString,
66
+ )
52
67
 
53
68
 
54
69
  class ControlServicer(object):
@@ -103,6 +118,27 @@ class ControlServicer(object):
103
118
  context.set_details('Method not implemented!')
104
119
  raise NotImplementedError('Method not implemented!')
105
120
 
121
+ def CreateNodeCli(self, request, context):
122
+ """Add SuperNode
123
+ """
124
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
125
+ context.set_details('Method not implemented!')
126
+ raise NotImplementedError('Method not implemented!')
127
+
128
+ def DeleteNodeCli(self, request, context):
129
+ """Remove SuperNode
130
+ """
131
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
132
+ context.set_details('Method not implemented!')
133
+ raise NotImplementedError('Method not implemented!')
134
+
135
+ def ListNodesCli(self, request, context):
136
+ """List SuperNodes
137
+ """
138
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
139
+ context.set_details('Method not implemented!')
140
+ raise NotImplementedError('Method not implemented!')
141
+
106
142
 
107
143
  def add_ControlServicer_to_server(servicer, server):
108
144
  rpc_method_handlers = {
@@ -141,6 +177,21 @@ def add_ControlServicer_to_server(servicer, server):
141
177
  request_deserializer=flwr_dot_proto_dot_control__pb2.PullArtifactsRequest.FromString,
142
178
  response_serializer=flwr_dot_proto_dot_control__pb2.PullArtifactsResponse.SerializeToString,
143
179
  ),
180
+ 'CreateNodeCli': grpc.unary_unary_rpc_method_handler(
181
+ servicer.CreateNodeCli,
182
+ request_deserializer=flwr_dot_proto_dot_control__pb2.CreateNodeCliRequest.FromString,
183
+ response_serializer=flwr_dot_proto_dot_control__pb2.CreateNodeCliResponse.SerializeToString,
184
+ ),
185
+ 'DeleteNodeCli': grpc.unary_unary_rpc_method_handler(
186
+ servicer.DeleteNodeCli,
187
+ request_deserializer=flwr_dot_proto_dot_control__pb2.DeleteNodeCliRequest.FromString,
188
+ response_serializer=flwr_dot_proto_dot_control__pb2.DeleteNodeCliResponse.SerializeToString,
189
+ ),
190
+ 'ListNodesCli': grpc.unary_unary_rpc_method_handler(
191
+ servicer.ListNodesCli,
192
+ request_deserializer=flwr_dot_proto_dot_control__pb2.ListNodesCliRequest.FromString,
193
+ response_serializer=flwr_dot_proto_dot_control__pb2.ListNodesCliResponse.SerializeToString,
194
+ ),
144
195
  }
145
196
  generic_handler = grpc.method_handlers_generic_handler(
146
197
  'flwr.proto.Control', rpc_method_handlers)
@@ -269,3 +320,54 @@ class Control(object):
269
320
  flwr_dot_proto_dot_control__pb2.PullArtifactsResponse.FromString,
270
321
  options, channel_credentials,
271
322
  insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
323
+
324
+ @staticmethod
325
+ def CreateNodeCli(request,
326
+ target,
327
+ options=(),
328
+ channel_credentials=None,
329
+ call_credentials=None,
330
+ insecure=False,
331
+ compression=None,
332
+ wait_for_ready=None,
333
+ timeout=None,
334
+ metadata=None):
335
+ return grpc.experimental.unary_unary(request, target, '/flwr.proto.Control/CreateNodeCli',
336
+ flwr_dot_proto_dot_control__pb2.CreateNodeCliRequest.SerializeToString,
337
+ flwr_dot_proto_dot_control__pb2.CreateNodeCliResponse.FromString,
338
+ options, channel_credentials,
339
+ insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
340
+
341
+ @staticmethod
342
+ def DeleteNodeCli(request,
343
+ target,
344
+ options=(),
345
+ channel_credentials=None,
346
+ call_credentials=None,
347
+ insecure=False,
348
+ compression=None,
349
+ wait_for_ready=None,
350
+ timeout=None,
351
+ metadata=None):
352
+ return grpc.experimental.unary_unary(request, target, '/flwr.proto.Control/DeleteNodeCli',
353
+ flwr_dot_proto_dot_control__pb2.DeleteNodeCliRequest.SerializeToString,
354
+ flwr_dot_proto_dot_control__pb2.DeleteNodeCliResponse.FromString,
355
+ options, channel_credentials,
356
+ insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
357
+
358
+ @staticmethod
359
+ def ListNodesCli(request,
360
+ target,
361
+ options=(),
362
+ channel_credentials=None,
363
+ call_credentials=None,
364
+ insecure=False,
365
+ compression=None,
366
+ wait_for_ready=None,
367
+ timeout=None,
368
+ metadata=None):
369
+ return grpc.experimental.unary_unary(request, target, '/flwr.proto.Control/ListNodesCli',
370
+ flwr_dot_proto_dot_control__pb2.ListNodesCliRequest.SerializeToString,
371
+ flwr_dot_proto_dot_control__pb2.ListNodesCliResponse.FromString,
372
+ options, channel_credentials,
373
+ insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@@ -44,6 +44,21 @@ class ControlStub:
44
44
  flwr.proto.control_pb2.PullArtifactsResponse]
45
45
  """Pull artifacts generated during a run (flwr pull)"""
46
46
 
47
+ CreateNodeCli: grpc.UnaryUnaryMultiCallable[
48
+ flwr.proto.control_pb2.CreateNodeCliRequest,
49
+ flwr.proto.control_pb2.CreateNodeCliResponse]
50
+ """Add SuperNode"""
51
+
52
+ DeleteNodeCli: grpc.UnaryUnaryMultiCallable[
53
+ flwr.proto.control_pb2.DeleteNodeCliRequest,
54
+ flwr.proto.control_pb2.DeleteNodeCliResponse]
55
+ """Remove SuperNode"""
56
+
57
+ ListNodesCli: grpc.UnaryUnaryMultiCallable[
58
+ flwr.proto.control_pb2.ListNodesCliRequest,
59
+ flwr.proto.control_pb2.ListNodesCliResponse]
60
+ """List SuperNodes"""
61
+
47
62
 
48
63
  class ControlServicer(metaclass=abc.ABCMeta):
49
64
  @abc.abstractmethod
@@ -102,5 +117,29 @@ class ControlServicer(metaclass=abc.ABCMeta):
102
117
  """Pull artifacts generated during a run (flwr pull)"""
103
118
  pass
104
119
 
120
+ @abc.abstractmethod
121
+ def CreateNodeCli(self,
122
+ request: flwr.proto.control_pb2.CreateNodeCliRequest,
123
+ context: grpc.ServicerContext,
124
+ ) -> flwr.proto.control_pb2.CreateNodeCliResponse:
125
+ """Add SuperNode"""
126
+ pass
127
+
128
+ @abc.abstractmethod
129
+ def DeleteNodeCli(self,
130
+ request: flwr.proto.control_pb2.DeleteNodeCliRequest,
131
+ context: grpc.ServicerContext,
132
+ ) -> flwr.proto.control_pb2.DeleteNodeCliResponse:
133
+ """Remove SuperNode"""
134
+ pass
135
+
136
+ @abc.abstractmethod
137
+ def ListNodesCli(self,
138
+ request: flwr.proto.control_pb2.ListNodesCliRequest,
139
+ context: grpc.ServicerContext,
140
+ ) -> flwr.proto.control_pb2.ListNodesCliResponse:
141
+ """List SuperNodes"""
142
+ pass
143
+
105
144
 
106
145
  def add_ControlServicer_to_server(servicer: ControlServicer, server: grpc.Server) -> None: ...
flwr/proto/node_pb2.py CHANGED
@@ -14,7 +14,7 @@ _sym_db = _symbol_database.Default()
14
14
 
15
15
 
16
16
 
17
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/node.proto\x12\nflwr.proto\"\x17\n\x04Node\x12\x0f\n\x07node_id\x18\x01 \x01(\x04\x62\x06proto3')
17
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/node.proto\x12\nflwr.proto\"\x17\n\x04Node\x12\x0f\n\x07node_id\x18\x01 \x01(\x04\"\xb6\x01\n\x08NodeInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\x04\x12\x11\n\towner_aid\x18\x02 \x01(\t\x12\x12\n\ncreated_at\x18\x03 \x01(\t\x12\x14\n\x0c\x61\x63tivated_at\x18\x04 \x01(\t\x12\x16\n\x0e\x64\x65\x61\x63tivated_at\x18\x05 \x01(\t\x12\x12\n\ndeleted_at\x18\x06 \x01(\t\x12\x14\n\x0conline_until\x18\x07 \x01(\x02\x12\x1a\n\x12heartbeat_interval\x18\x08 \x01(\x02\x62\x06proto3')
18
18
 
19
19
  _globals = globals()
20
20
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -23,4 +23,6 @@ if _descriptor._USE_C_DESCRIPTORS == False:
23
23
  DESCRIPTOR._options = None
24
24
  _globals['_NODE']._serialized_start=37
25
25
  _globals['_NODE']._serialized_end=60
26
+ _globals['_NODEINFO']._serialized_start=63
27
+ _globals['_NODEINFO']._serialized_end=245
26
28
  # @@protoc_insertion_point(module_scope)