yellowdog-python-examples 7.11.2__tar.gz → 7.11.4__tar.gz

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 (77) hide show
  1. {yellowdog_python_examples-7.11.2/yellowdog_python_examples.egg-info → yellowdog_python_examples-7.11.4}/PKG-INFO +1 -1
  2. yellowdog_python_examples-7.11.4/yd_commands/__init__.py +1 -0
  3. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/args.py +22 -0
  4. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/items.py +4 -0
  5. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/list.py +103 -17
  6. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/load_resources.py +1 -1
  7. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/printing.py +82 -20
  8. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4/yellowdog_python_examples.egg-info}/PKG-INFO +1 -1
  9. yellowdog_python_examples-7.11.2/yd_commands/__init__.py +0 -1
  10. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/LICENSE +0 -0
  11. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/PYPI_README.md +0 -0
  12. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/README.md +0 -0
  13. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/pyproject.toml +0 -0
  14. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/requirements.txt +0 -0
  15. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/setup.cfg +0 -0
  16. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/setup.py +0 -0
  17. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/tests/test_create_remove.py +0 -0
  18. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/tests/test_demos.py +0 -0
  19. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/tests/test_dryruns.py +0 -0
  20. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/tests/test_entrypoints.py +0 -0
  21. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/tests/test_gui.py +0 -0
  22. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/tests/test_list.py +0 -0
  23. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/tests/test_objects.py +0 -0
  24. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/tests/test_variable_processing.py +0 -0
  25. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/abort.py +0 -0
  26. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/admin.py +0 -0
  27. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/boost.py +0 -0
  28. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/cancel.py +0 -0
  29. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/check_imports.py +0 -0
  30. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/cloudwizard.py +0 -0
  31. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/cloudwizard_aws.py +0 -0
  32. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/cloudwizard_aws_types.py +0 -0
  33. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/cloudwizard_azure.py +0 -0
  34. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/cloudwizard_common.py +0 -0
  35. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/cloudwizard_gcp.py +0 -0
  36. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/compact_json.py +0 -0
  37. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/config_types.py +0 -0
  38. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/create.py +0 -0
  39. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/csv_data.py +0 -0
  40. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/delete.py +0 -0
  41. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/download.py +0 -0
  42. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/follow.py +0 -0
  43. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/follow_utils.py +0 -0
  44. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/format_json.py +0 -0
  45. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/hold.py +0 -0
  46. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/id_utils.py +0 -0
  47. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/instantiate.py +0 -0
  48. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/interactive.py +0 -0
  49. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/jsonnet2json.py +0 -0
  50. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/load_config.py +0 -0
  51. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/object_utilities.py +0 -0
  52. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/property_names.py +0 -0
  53. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/provision.py +0 -0
  54. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/provision_utils.py +0 -0
  55. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/remove.py +0 -0
  56. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/resize.py +0 -0
  57. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/settings.py +0 -0
  58. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/show.py +0 -0
  59. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/shutdown.py +0 -0
  60. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/start.py +0 -0
  61. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/start_hold_common.py +0 -0
  62. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/submit.py +0 -0
  63. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/submit_utils.py +0 -0
  64. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/terminate.py +0 -0
  65. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/type_check.py +0 -0
  66. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/upload.py +0 -0
  67. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/upload_utils.py +0 -0
  68. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/utils.py +0 -0
  69. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/validate_properties.py +0 -0
  70. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/variables.py +0 -0
  71. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/version.py +0 -0
  72. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yd_commands/wrapper.py +0 -0
  73. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yellowdog_python_examples.egg-info/SOURCES.txt +0 -0
  74. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yellowdog_python_examples.egg-info/dependency_links.txt +0 -0
  75. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yellowdog_python_examples.egg-info/entry_points.txt +0 -0
  76. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yellowdog_python_examples.egg-info/requires.txt +0 -0
  77. {yellowdog_python_examples-7.11.2 → yellowdog_python_examples-7.11.4}/yellowdog_python_examples.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: yellowdog-python-examples
3
- Version: 7.11.2
3
+ Version: 7.11.4
4
4
  Summary: Example Python commands using the YellowDog Python SDK
5
5
  Home-page: https://github.com/yellowdog/python-examples
6
6
  Author: YellowDog Limited
@@ -0,0 +1 @@
1
+ __version__ = "7.11.4"
@@ -516,6 +516,18 @@ class CLIParser:
516
516
  required=False,
517
517
  help="list compute instances",
518
518
  )
519
+ parser.add_argument(
520
+ "--nodes",
521
+ action="store_true",
522
+ required=False,
523
+ help="list worker pool nodes",
524
+ )
525
+ parser.add_argument(
526
+ "--workers",
527
+ action="store_true",
528
+ required=False,
529
+ help="list all workers in a worker pool",
530
+ )
519
531
  parser.add_argument(
520
532
  "--public-ips-only",
521
533
  action="store_true",
@@ -1328,6 +1340,16 @@ class CLIParser:
1328
1340
  def instances(self) -> Optional[bool]:
1329
1341
  return self.args.instances
1330
1342
 
1343
+ @property
1344
+ @allow_missing_attribute
1345
+ def nodes(self) -> Optional[bool]:
1346
+ return self.args.nodes
1347
+
1348
+ @property
1349
+ @allow_missing_attribute
1350
+ def workers(self) -> Optional[bool]:
1351
+ return self.args.workers
1352
+
1331
1353
  @property
1332
1354
  @allow_missing_attribute
1333
1355
  def allowances(self) -> Optional[bool]:
@@ -16,10 +16,12 @@ from yellowdog_client.model import (
16
16
  MachineImageFamilySummary,
17
17
  NamespacePolicy,
18
18
  NamespaceStorageConfiguration,
19
+ Node,
19
20
  ObjectPath,
20
21
  ProvisionedWorkerPool,
21
22
  Task,
22
23
  TaskGroup,
24
+ Worker,
23
25
  WorkerPoolSummary,
24
26
  WorkRequirementSummary,
25
27
  )
@@ -44,6 +46,8 @@ Item = TypeVar(
44
46
  ProvisionedWorkerPool,
45
47
  Task,
46
48
  TaskGroup,
49
+ Worker,
47
50
  WorkRequirementSummary,
48
51
  WorkerPoolSummary,
52
+ Node,
49
53
  )
@@ -30,12 +30,17 @@ from yellowdog_client.model import (
30
30
  NamespacePolicy,
31
31
  NamespacePolicySearch,
32
32
  NamespaceStorageConfiguration,
33
+ Node,
34
+ NodeSearch,
35
+ NodeStatus,
33
36
  ObjectDetail,
34
37
  Task,
35
38
  TaskGroup,
39
+ Worker,
36
40
  WorkerPool,
37
41
  WorkerPoolStatus,
38
42
  WorkerPoolSummary,
43
+ WorkerStatus,
39
44
  WorkRequirementStatus,
40
45
  WorkRequirementSummary,
41
46
  )
@@ -64,7 +69,7 @@ from yd_commands.wrapper import ARGS_PARSER, CLIENT, CONFIG_COMMON, main_wrapper
64
69
  @main_wrapper
65
70
  def main():
66
71
  if not check_for_valid_option():
67
- raise Exception("Please choose a single, valid listing type")
72
+ raise Exception("Please choose a (single) listing type")
68
73
 
69
74
  # Always use interactive mode for selections
70
75
  ARGS_PARSER.interactive = True
@@ -73,7 +78,7 @@ def main():
73
78
  list_object_paths()
74
79
  elif ARGS_PARSER.work_requirements or ARGS_PARSER.task_groups or ARGS_PARSER.tasks:
75
80
  list_work_requirements()
76
- elif ARGS_PARSER.worker_pools:
81
+ elif ARGS_PARSER.worker_pools or ARGS_PARSER.nodes or ARGS_PARSER.workers:
77
82
  list_worker_pools()
78
83
  elif ARGS_PARSER.compute_requirements or ARGS_PARSER.instances:
79
84
  list_compute_requirements()
@@ -100,21 +105,23 @@ def check_for_valid_option() -> bool:
100
105
  Only one of the listing options must be selected.
101
106
  """
102
107
  if [
103
- ARGS_PARSER.object_paths,
104
- ARGS_PARSER.work_requirements,
105
- ARGS_PARSER.task_groups,
106
- ARGS_PARSER.tasks,
107
- ARGS_PARSER.worker_pools,
108
+ ARGS_PARSER.allowances,
109
+ ARGS_PARSER.attribute_definitions,
108
110
  ARGS_PARSER.compute_requirements,
109
111
  ARGS_PARSER.compute_templates,
110
- ARGS_PARSER.source_templates,
111
- ARGS_PARSER.keyrings,
112
112
  ARGS_PARSER.image_families,
113
- ARGS_PARSER.namespace_storage_configurations,
114
113
  ARGS_PARSER.instances,
115
- ARGS_PARSER.allowances,
116
- ARGS_PARSER.attribute_definitions,
114
+ ARGS_PARSER.keyrings,
117
115
  ARGS_PARSER.namespace_policies,
116
+ ARGS_PARSER.namespace_storage_configurations,
117
+ ARGS_PARSER.nodes,
118
+ ARGS_PARSER.object_paths,
119
+ ARGS_PARSER.source_templates,
120
+ ARGS_PARSER.task_groups,
121
+ ARGS_PARSER.tasks,
122
+ ARGS_PARSER.work_requirements,
123
+ ARGS_PARSER.worker_pools,
124
+ ARGS_PARSER.workers,
118
125
  ].count(True) == 1:
119
126
  return True
120
127
  else:
@@ -257,6 +264,20 @@ def list_worker_pools():
257
264
  if len(worker_pool_summaries) == 0:
258
265
  print_log("No Worker Pools to display")
259
266
  return
267
+
268
+ if ARGS_PARSER.nodes or ARGS_PARSER.workers:
269
+ print_log(
270
+ "Please select the Worker Pool(s) for which to list "
271
+ f"{'Nodes' if ARGS_PARSER.nodes else 'Workers'}"
272
+ )
273
+ worker_pool_summaries = select(
274
+ CLIENT,
275
+ sorted_objects(worker_pool_summaries),
276
+ showing_all=showing_all,
277
+ )
278
+ list_nodes(worker_pool_summaries)
279
+ return
280
+
260
281
  if ARGS_PARSER.details:
261
282
  for worker_pool_summary in select(
262
283
  CLIENT, sorted_objects(worker_pool_summaries), showing_all=showing_all
@@ -330,9 +351,7 @@ def list_instances(compute_requirement: ComputeRequirement):
330
351
  """
331
352
  List the instances within a Compute Requirement.
332
353
  """
333
- instance_search: InstanceSearch = InstanceSearch(
334
- computeRequirementId=compute_requirement.id
335
- )
354
+ instance_search = InstanceSearch(computeRequirementId=compute_requirement.id)
336
355
  search_client: SearchClient = CLIENT.compute_client.get_instances(
337
356
  instance_search=instance_search
338
357
  )
@@ -352,10 +371,77 @@ def list_instances(compute_requirement: ComputeRequirement):
352
371
  return
353
372
 
354
373
  if ARGS_PARSER.details:
355
- for instance in select(CLIENT, search_client.list_all()):
374
+ for instance in select(CLIENT, instances):
356
375
  print_yd_object(instance)
357
376
  else:
358
- print_numbered_object_list(CLIENT, search_client.list_all())
377
+ print_numbered_object_list(CLIENT, instances)
378
+
379
+
380
+ def list_nodes(worker_pool_summaries: List[WorkerPoolSummary]):
381
+ """
382
+ List the Nodes in a list of Worker Pools.
383
+ """
384
+ nodes_all: List[Node] = []
385
+ for worker_pool_summary in worker_pool_summaries:
386
+ nodes_search = NodeSearch(
387
+ worker_pool_summary.id,
388
+ statuses=[NodeStatus.RUNNING] if ARGS_PARSER.active_only else None,
389
+ )
390
+ search_client = CLIENT.worker_pool_client.get_nodes(search=nodes_search)
391
+ nodes: List[Node] = search_client.list_all()
392
+ for node in nodes:
393
+ node.worker_pool_name = worker_pool_summary.name
394
+ nodes_all += nodes
395
+
396
+ if len(nodes_all) == 0:
397
+ print_log("No Nodes to display")
398
+ return
399
+
400
+ if ARGS_PARSER.workers:
401
+ list_workers(nodes_all)
402
+ return
403
+
404
+ if ARGS_PARSER.details:
405
+ for node in select(CLIENT, nodes_all):
406
+ delattr(node, "worker_pool_name")
407
+ print_yd_object(node)
408
+ else:
409
+ print_numbered_object_list(CLIENT, nodes_all)
410
+
411
+
412
+ def list_workers(nodes: List[Node]):
413
+ """
414
+ Display a list of workers across all nodes in a worker pool.
415
+ """
416
+ workers_all: List[Worker] = []
417
+ for node in nodes:
418
+ for worker in node.workers:
419
+ if ARGS_PARSER.active_only:
420
+ if worker.status not in [
421
+ WorkerStatus.SLEEPING,
422
+ WorkerStatus.DOING_TASK,
423
+ WorkerStatus.FOUND,
424
+ ]:
425
+ continue
426
+ # Add extra info to the Worker object
427
+ worker.worker_tag = node.details.workerTag
428
+ worker.task_types = node.details.supportedTaskTypes
429
+ worker.worker_pool_name = node.worker_pool_name
430
+ workers_all.append(worker)
431
+
432
+ if len(workers_all) == 0:
433
+ print_log("No Workers to display")
434
+ return
435
+
436
+ if not ARGS_PARSER.details:
437
+ print_numbered_object_list(CLIENT, workers_all)
438
+ return
439
+
440
+ for worker in select(CLIENT, workers_all):
441
+ delattr(worker, "worker_tag")
442
+ delattr(worker, "task_types")
443
+ delattr(worker, "worker_pool_name")
444
+ print_yd_object(worker)
359
445
 
360
446
 
361
447
  def list_compute_templates():
@@ -2,7 +2,7 @@
2
2
  Load data for resource creation/update/removal requests.
3
3
  """
4
4
 
5
- from sys import argv, exit
5
+ from sys import exit
6
6
  from typing import Dict, List
7
7
 
8
8
  from yd_commands.args import ARGS_PARSER
@@ -33,15 +33,14 @@ from yellowdog_client.model import (
33
33
  KeyringSummary,
34
34
  MachineImageFamilySummary,
35
35
  NamespacePolicy,
36
- NodeStatus,
37
- NodeSummary,
36
+ Node,
38
37
  ObjectDetail,
39
38
  ObjectPath,
40
39
  ProvisionedWorkerPool,
41
40
  ProvisionedWorkerPoolProperties,
42
41
  Task,
43
42
  TaskGroup,
44
- WorkerPool,
43
+ Worker,
45
44
  WorkerPoolSummary,
46
45
  WorkRequirement,
47
46
  WorkRequirementSummary,
@@ -212,11 +211,13 @@ TYPE_MAP = {
212
211
  KeyringSummary: "Keyring",
213
212
  MachineImageFamilySummary: "Machine Image Family",
214
213
  NamespacePolicy: "Namespace Policy",
214
+ Node: "Node",
215
215
  ObjectPath: "Object Path",
216
216
  ProvisionedWorkerPool: "Provisioned Worker Pool",
217
217
  Task: "Task",
218
218
  TaskGroup: "Task Group",
219
219
  WorkRequirementSummary: "Work Requirement",
220
+ Worker: "Worker",
220
221
  WorkerPoolSummary: "Worker Pool",
221
222
  }
222
223
 
@@ -347,32 +348,16 @@ def worker_pool_table(
347
348
  "Worker Pool Name",
348
349
  "Type",
349
350
  "Status",
350
- "Min/Run/Max",
351
351
  "ID",
352
352
  ]
353
353
  table = []
354
354
  for index, worker_pool_summary in enumerate(worker_pool_summaries):
355
- worker_pool: WorkerPool = client.worker_pool_client.get_worker_pool_by_id(
356
- worker_pool_summary.id
357
- )
358
- try:
359
- min_nodes = str(worker_pool.properties.minNodes)
360
- except:
361
- min_nodes = "_"
362
- try:
363
- max_nodes = str(worker_pool.properties.maxNodes)
364
- except:
365
- max_nodes = "_"
366
- node_summary: NodeSummary = worker_pool.nodeSummary
367
- nodes_running = node_summary.statusCounts[NodeStatus.RUNNING]
368
-
369
355
  table.append(
370
356
  [
371
357
  index + 1,
372
358
  worker_pool_summary.name,
373
359
  f"{worker_pool_summary.type.split('.')[-1:][0].replace('WorkerPool', '')}",
374
360
  f"{worker_pool_summary.status}",
375
- f"{min_nodes}/{nodes_running}/{max_nodes}",
376
361
  worker_pool_summary.id,
377
362
  ]
378
363
  )
@@ -535,6 +520,72 @@ def instances_table(
535
520
  return headers, table
536
521
 
537
522
 
523
+ def nodes_table(
524
+ nodes: List[Node],
525
+ ) -> (List[str], List[str]):
526
+ headers = [
527
+ "#",
528
+ "Worker Pool Name",
529
+ "Provider",
530
+ "RAM",
531
+ "vCPUs",
532
+ "Task Types",
533
+ "Worker Tag",
534
+ "# Workers",
535
+ "Status",
536
+ "ID",
537
+ ]
538
+ table = []
539
+ for index, node in enumerate(nodes):
540
+ if node.details is None:
541
+ continue
542
+ table.append(
543
+ [
544
+ index + 1,
545
+ node.worker_pool_name,
546
+ node.details.provider,
547
+ node.details.ram,
548
+ node.details.vcpus,
549
+ ", ".join(node.details.supportedTaskTypes),
550
+ node.details.workerTag,
551
+ len(node.workers),
552
+ node.status,
553
+ node.id,
554
+ ]
555
+ )
556
+ return headers, table
557
+
558
+
559
+ def workers_table(
560
+ workers: List[Worker],
561
+ ) -> (List[str], List[str]):
562
+ headers = [
563
+ "#",
564
+ "Worker Pool Name",
565
+ "Task Types",
566
+ "Worker Tag",
567
+ "Status",
568
+ "Claims",
569
+ "Exclusive?",
570
+ "ID",
571
+ ]
572
+ table = []
573
+ for index, worker in enumerate(workers):
574
+ table.append(
575
+ [
576
+ index + 1,
577
+ worker.worker_pool_name,
578
+ ", ".join(worker.task_types),
579
+ worker.worker_tag,
580
+ worker.status,
581
+ worker.claimCount,
582
+ worker.exclusive,
583
+ worker.id,
584
+ ]
585
+ )
586
+ return headers, table
587
+
588
+
538
589
  def allowances_table(
539
590
  allowances: List[Allowance],
540
591
  ) -> (List[str], List[str]):
@@ -691,6 +742,10 @@ def print_numbered_object_list(
691
742
  headers, table = attribute_definitions_table(objects)
692
743
  elif isinstance(objects[0], NamespacePolicy):
693
744
  headers, table = namespace_policies_table(objects)
745
+ elif isinstance(objects[0], Node):
746
+ headers, table = nodes_table(objects)
747
+ elif isinstance(objects[0], Worker):
748
+ headers, table = workers_table(objects)
694
749
  else:
695
750
  table = []
696
751
  for index, obj in enumerate(objects):
@@ -731,7 +786,7 @@ def sorted_objects(
731
786
  """
732
787
  Sort objects by their 'name' property, or 'namespace' in the case of
733
788
  Namespace Storage Configurations, or 'instanceType' in the case of
734
- Instances.
789
+ Instances, etc.
735
790
  """
736
791
  if len(objects) == 0:
737
792
  return objects
@@ -745,6 +800,13 @@ def sorted_objects(
745
800
  if isinstance(objects[0], Instance):
746
801
  return sorted(objects, key=lambda x: x.instanceType, reverse=reverse)
747
802
 
803
+ if isinstance(objects[0], Node):
804
+ # Note: worker_pool property is added dynamically in yd_list
805
+ return sorted(objects, key=lambda x: str(x.worker_pool_name), reverse=reverse)
806
+
807
+ if isinstance(objects[0], Worker):
808
+ return sorted(objects, key=lambda x: str(x.worker_pool_name), reverse=reverse)
809
+
748
810
  if isinstance(objects[0], AWSAvailabilityZone):
749
811
  return sorted(objects)
750
812
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: yellowdog-python-examples
3
- Version: 7.11.2
3
+ Version: 7.11.4
4
4
  Summary: Example Python commands using the YellowDog Python SDK
5
5
  Home-page: https://github.com/yellowdog/python-examples
6
6
  Author: YellowDog Limited
@@ -1 +0,0 @@
1
- __version__ = "7.11.2"