yellowdog-python-examples 7.9.0__tar.gz → 7.9.1__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 (76) hide show
  1. {yellowdog_python_examples-7.9.0/yellowdog_python_examples.egg-info → yellowdog_python_examples-7.9.1}/PKG-INFO +1 -1
  2. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/README.md +26 -4
  3. yellowdog_python_examples-7.9.1/yd_commands/__init__.py +1 -0
  4. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/args.py +12 -0
  5. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/create.py +32 -14
  6. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/interactive.py +5 -3
  7. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/list.py +38 -0
  8. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/load_resources.py +2 -0
  9. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/printing.py +27 -1
  10. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/remove.py +9 -5
  11. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/settings.py +1 -0
  12. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1/yellowdog_python_examples.egg-info}/PKG-INFO +1 -1
  13. yellowdog_python_examples-7.9.0/yd_commands/__init__.py +0 -1
  14. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/LICENSE +0 -0
  15. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/PYPI_README.md +0 -0
  16. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/pyproject.toml +0 -0
  17. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/requirements.txt +0 -0
  18. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/setup.cfg +0 -0
  19. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/setup.py +0 -0
  20. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/tests/test_create_remove.py +0 -0
  21. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/tests/test_demos.py +0 -0
  22. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/tests/test_dryruns.py +0 -0
  23. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/tests/test_entrypoints.py +0 -0
  24. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/tests/test_gui.py +0 -0
  25. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/tests/test_list.py +0 -0
  26. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/tests/test_objects.py +0 -0
  27. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/tests/test_variable_processing.py +0 -0
  28. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/abort.py +0 -0
  29. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/admin.py +0 -0
  30. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/boost.py +0 -0
  31. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/cancel.py +0 -0
  32. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/check_imports.py +0 -0
  33. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/cloudwizard.py +0 -0
  34. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/cloudwizard_aws.py +0 -0
  35. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/cloudwizard_aws_types.py +0 -0
  36. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/cloudwizard_azure.py +0 -0
  37. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/cloudwizard_common.py +0 -0
  38. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/cloudwizard_gcp.py +0 -0
  39. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/compact_json.py +0 -0
  40. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/config_types.py +0 -0
  41. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/csv_data.py +0 -0
  42. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/delete.py +0 -0
  43. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/download.py +0 -0
  44. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/follow.py +0 -0
  45. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/follow_utils.py +0 -0
  46. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/format_json.py +0 -0
  47. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/hold.py +0 -0
  48. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/id_utils.py +0 -0
  49. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/instantiate.py +0 -0
  50. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/items.py +0 -0
  51. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/jsonnet2json.py +0 -0
  52. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/load_config.py +0 -0
  53. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/object_utilities.py +0 -0
  54. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/property_names.py +0 -0
  55. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/provision.py +0 -0
  56. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/provision_utils.py +0 -0
  57. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/resize.py +0 -0
  58. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/shutdown.py +0 -0
  59. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/start.py +0 -0
  60. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/start_hold_common.py +0 -0
  61. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/submit.py +0 -0
  62. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/submit_utils.py +0 -0
  63. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/terminate.py +0 -0
  64. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/type_check.py +0 -0
  65. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/upload.py +0 -0
  66. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/upload_utils.py +0 -0
  67. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/utils.py +0 -0
  68. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/validate_properties.py +0 -0
  69. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/variables.py +0 -0
  70. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/version.py +0 -0
  71. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yd_commands/wrapper.py +0 -0
  72. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yellowdog_python_examples.egg-info/SOURCES.txt +0 -0
  73. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yellowdog_python_examples.egg-info/dependency_links.txt +0 -0
  74. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yellowdog_python_examples.egg-info/entry_points.txt +0 -0
  75. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/yellowdog_python_examples.egg-info/requires.txt +0 -0
  76. {yellowdog_python_examples-7.9.0 → yellowdog_python_examples-7.9.1}/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.9.0
3
+ Version: 7.9.1
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
@@ -87,7 +87,9 @@
87
87
  * [Namespace Storage Configurations](#namespace-storage-configurations)
88
88
  * [Configured Worker Pools](#configured-worker-pools)
89
89
  * [Allowances](#allowances)
90
- * [String Attribute Definitions](#string-attribute-definitions)
90
+ * [Attribute Definitions](#attribute-definitions)
91
+ * [String Attribute Definitions](#string-attribute-definitions)
92
+ * [Numeric Attribute Definitions](#numeric-attribute-definitions)
91
93
  * [Jsonnet Support](#jsonnet-support)
92
94
  * [Jsonnet Installation](#jsonnet-installation)
93
95
  * [Variable Substitutions in Jsonnet Files](#variable-substitutions-in-jsonnet-files)
@@ -115,7 +117,7 @@
115
117
  * [yd-boost](#yd-boost)
116
118
 
117
119
  <!-- Created by https://github.com/ekalinin/github-markdown-toc -->
118
- <!-- Added by: pwt, at: Wed May 8 16:37:54 BST 2024 -->
120
+ <!-- Added by: pwt, at: Thu May 9 16:47:20 BST 2024 -->
119
121
 
120
122
  <!--te-->
121
123
 
@@ -2163,9 +2165,11 @@ When using `yd-remove`, Allowances are again matched using their `description` p
2163
2165
 
2164
2166
  Allowances can be **boosted** (have extra hours added to the Allowance) using the `yd-boost` command.
2165
2167
 
2166
- ## String Attribute Definitions
2168
+ ## Attribute Definitions
2167
2169
 
2168
- The Attribute Definition example and schema can be found at: https://docs.yellowdog.co/api/?spec=Compute%20API#tag/compute/post/compute/attributes/user. Currently, only **String Attribute Definitions** are supported.
2170
+ The Attribute Definition example and schema can be found at: https://docs.yellowdog.co/api/?spec=Compute%20API#tag/compute/post/compute/attributes/user.
2171
+
2172
+ ### String Attribute Definitions
2169
2173
 
2170
2174
  Example:
2171
2175
 
@@ -2181,6 +2185,24 @@ Example:
2181
2185
 
2182
2186
  The `name` and `title` properties are required, while the rest are optional. The `user.` prefix is required when specifying the `name` property.
2183
2187
 
2188
+ ### Numeric Attribute Definitions
2189
+
2190
+ Example:
2191
+
2192
+ ```json
2193
+ {
2194
+ "resource": "NumericAttributeDefinition",
2195
+ "name": "my-numeric-attribute",
2196
+ "title": "Attribute Title",
2197
+ "defaultRankOrder": "PREFER_LOWER",
2198
+ "description": "A description of the attribute",
2199
+ "units": "$",
2200
+ "range": {"min": 1, "max": 10}
2201
+ }
2202
+ ```
2203
+
2204
+ The `name`, `title` and `defaultRankOrder` properties are required, while the rest are optional. The `user.` prefix is required when specifying the `name` property.
2205
+
2184
2206
  # Jsonnet Support
2185
2207
 
2186
2208
  In all circumstances where JSON files are used by the Python Examples commands, **[Jsonnet](https://jsonnet.org)** files can be used instead. This allows the use of Jsonnet's powerful JSON extensions, including comments, variables, functions, etc.
@@ -0,0 +1 @@
1
+ __version__ = "7.9.1"
@@ -529,6 +529,13 @@ class CLIParser:
529
529
  required=False,
530
530
  help="list allowances",
531
531
  )
532
+ parser.add_argument(
533
+ "--attribute-definitions",
534
+ "-R",
535
+ action="store_true",
536
+ required=False,
537
+ help="list attribute definitions",
538
+ )
532
539
 
533
540
  if any(module in sys.argv[0] for module in ["upload"]):
534
541
  parser.add_argument(
@@ -1310,6 +1317,11 @@ class CLIParser:
1310
1317
  def allowances(self) -> Optional[bool]:
1311
1318
  return self.args.allowances
1312
1319
 
1320
+ @property
1321
+ @allow_missing_attribute
1322
+ def attribute_definitions(self) -> Optional[bool]:
1323
+ return self.args.attribute_definitions
1324
+
1313
1325
  @property
1314
1326
  @allow_missing_attribute
1315
1327
  def show_keyring_passwords(self) -> Optional[bool]:
@@ -51,6 +51,7 @@ from yd_commands.settings import (
51
51
  RN_CREDENTIAL,
52
52
  RN_IMAGE_FAMILY,
53
53
  RN_KEYRING,
54
+ RN_NUMERIC_ATTRIBUTE_DEFINITION,
54
55
  RN_REQUIREMENT_TEMPLATE,
55
56
  RN_SOURCE_TEMPLATE,
56
57
  RN_STORAGE_CONFIGURATION,
@@ -119,8 +120,11 @@ def create_resources(
119
120
  create_configured_worker_pool(resource)
120
121
  elif resource_type == RN_ALLOWANCE:
121
122
  create_allowance(resource)
122
- elif resource_type == RN_STRING_ATTRIBUTE_DEFINITION:
123
- create_string_attribute_definition_via_api(resource)
123
+ elif resource_type in [
124
+ RN_STRING_ATTRIBUTE_DEFINITION,
125
+ RN_NUMERIC_ATTRIBUTE_DEFINITION,
126
+ ]:
127
+ create_attribute_definition_via_api(resource, resource_type)
124
128
  else:
125
129
  print_error(f"Unknown resource type '{resource_type}'")
126
130
  except Exception as e:
@@ -792,40 +796,54 @@ def _get_model_class(class_name: str):
792
796
  return getattr(model, class_name)
793
797
 
794
798
 
795
- def create_string_attribute_definition_via_api(resource: Dict):
799
+ def create_attribute_definition_via_api(resource: Dict, resource_type: str):
796
800
  """
797
- Use the API to create/update user string attribute definitions.
801
+ Use the API to create/update user attribute definitions.
798
802
  """
799
803
  try:
800
804
  name = resource["name"]
801
805
  title = resource["title"]
806
+ if resource_type == RN_NUMERIC_ATTRIBUTE_DEFINITION:
807
+ default_rank_order = resource["defaultRankOrder"]
802
808
  except KeyError as e:
803
809
  raise Exception(f"Expected property to be defined ({e})")
804
810
 
805
811
  url = f"{CONFIG_COMMON.url}/compute/attributes/user"
806
812
  headers = {"Authorization": f"yd-key {CONFIG_COMMON.key}:{CONFIG_COMMON.secret}"}
807
- payload = {
808
- "name": name,
809
- "title": title,
810
- "type": "co.yellowdog.platform.model.StringAttributeDefinition",
811
- "description": resource.get("description", ""),
812
- "options": resource.get("options", []),
813
- }
813
+ if resource_type == RN_STRING_ATTRIBUTE_DEFINITION:
814
+ payload = {
815
+ "type": "co.yellowdog.platform.model.StringAttributeDefinition",
816
+ "name": name,
817
+ "title": title,
818
+ "description": resource.get("description"),
819
+ "options": resource.get("options"),
820
+ }
821
+ else: # RN_NUMERIC_ATTRIBUTE_DEFINITION
822
+ payload = {
823
+ "type": "co.yellowdog.platform.model.NumericAttributeDefinition",
824
+ "name": name,
825
+ "title": title,
826
+ "defaultRankOrder": default_rank_order,
827
+ "description": resource.get("description"),
828
+ "units": resource.get("units"),
829
+ "range": resource.get("range"),
830
+ }
814
831
 
815
832
  # Attempt attribute creation
833
+ print_log(f"Attempting to create or update Attribute Definition '{name}'")
816
834
  response = post(url=url, headers=headers, json=payload)
817
835
 
818
836
  if response.status_code == 200:
819
- print_log(f"Created new String Attribute Definition '{name}'")
837
+ print_log(f"Created new Attribute Definition '{name}'")
820
838
  return
821
839
 
822
840
  if "Attribute already exists" in response.text:
823
- if not confirmed(f"Update existing String Attribute Definition '{name}'?"):
841
+ if not confirmed(f"Update existing Attribute Definition '{name}'?"):
824
842
  return
825
843
 
826
844
  response = put(url=url, headers=headers, json=payload)
827
845
  if response.status_code == 200:
828
- print_log(f"Updated existing String Attribute Definition '{name}'")
846
+ print_log(f"Updated existing Attribute Definition '{name}'")
829
847
  return
830
848
 
831
849
  raise Exception(f"HTTP {response.status_code} ({response.text})")
@@ -3,7 +3,7 @@ User interaction processing utilities.
3
3
  """
4
4
 
5
5
  from os import getenv
6
- from typing import List, Optional, Set, Union
6
+ from typing import Dict, List, Optional, Set, Union
7
7
 
8
8
  from yellowdog_client import PlatformClient
9
9
 
@@ -30,13 +30,14 @@ YD_YES = "YD_YES"
30
30
 
31
31
  def select(
32
32
  client: PlatformClient,
33
- objects: List[Union[Item, str]],
33
+ objects: List[Union[Item, str, Dict]],
34
34
  object_type_name: Optional[str] = None,
35
35
  override_quiet: bool = False,
36
36
  single_result: bool = False,
37
37
  showing_all: bool = False,
38
38
  force_interactive: bool = False,
39
39
  result_required: bool = False,
40
+ sort_objects: bool = True,
40
41
  ) -> List[Item]:
41
42
  """
42
43
  Print a numbered list of objects.
@@ -47,7 +48,8 @@ def select(
47
48
  if len(objects) == 0:
48
49
  return objects
49
50
 
50
- objects = sorted_objects(objects)
51
+ if sort_objects:
52
+ objects = sorted_objects(objects)
51
53
 
52
54
  if not ARGS_PARSER.quiet or override_quiet or ARGS_PARSER.interactive:
53
55
  print_numbered_object_list(
@@ -5,6 +5,7 @@ Command to list YellowDog entities.
5
5
  """
6
6
 
7
7
  from dataclasses import asdict, fields
8
+ from json import loads as json_loads
8
9
  from typing import Dict, List
9
10
 
10
11
  from requests import get
@@ -47,6 +48,7 @@ from yd_commands.object_utilities import (
47
48
  )
48
49
  from yd_commands.printing import (
49
50
  indent,
51
+ print_json,
50
52
  print_log,
51
53
  print_numbered_object_list,
52
54
  print_table_core,
@@ -85,6 +87,8 @@ def main():
85
87
  list_namespaces()
86
88
  elif ARGS_PARSER.allowances:
87
89
  list_allowances()
90
+ elif ARGS_PARSER.attribute_definitions:
91
+ list_attribute_definitions()
88
92
 
89
93
 
90
94
  def check_for_valid_option() -> bool:
@@ -105,6 +109,7 @@ def check_for_valid_option() -> bool:
105
109
  ARGS_PARSER.namespace_storage_configurations,
106
110
  ARGS_PARSER.instances,
107
111
  ARGS_PARSER.allowances,
112
+ ARGS_PARSER.attribute_definitions,
108
113
  ].count(True) == 1:
109
114
  return True
110
115
  else:
@@ -568,6 +573,39 @@ def list_allowances():
568
573
  print_yd_object(allowance)
569
574
 
570
575
 
576
+ def list_attribute_definitions():
577
+ """
578
+ List user compute attribute definitions using the API.
579
+ """
580
+ response = get(
581
+ url=f"{CONFIG_COMMON.url}/compute/attributes/user",
582
+ headers={"Authorization": f"yd-key {CONFIG_COMMON.key}:{CONFIG_COMMON.secret}"},
583
+ )
584
+
585
+ if response.status_code != 200:
586
+ raise Exception(
587
+ "Unable to list user attribute definitions: HTTP "
588
+ f"{response.status_code} ({response.text})"
589
+ )
590
+
591
+ attribute_definition_list = json_loads(response.text)
592
+ attribute_definition_list.sort(key=lambda x: x["name"])
593
+
594
+ if not ARGS_PARSER.details:
595
+ print_numbered_object_list(
596
+ CLIENT, attribute_definition_list, object_type_name="Attribute Definition"
597
+ )
598
+ return
599
+
600
+ for selected_attribute_definition in select(
601
+ CLIENT,
602
+ attribute_definition_list,
603
+ object_type_name="Attribute Definition",
604
+ sort_objects=False,
605
+ ):
606
+ print_json(selected_attribute_definition)
607
+
608
+
571
609
  # Entry point
572
610
  if __name__ == "__main__":
573
611
  main()
@@ -13,6 +13,7 @@ from yd_commands.settings import (
13
13
  RN_CREDENTIAL,
14
14
  RN_IMAGE_FAMILY,
15
15
  RN_KEYRING,
16
+ RN_NUMERIC_ATTRIBUTE_DEFINITION,
16
17
  RN_REQUIREMENT_TEMPLATE,
17
18
  RN_SOURCE_TEMPLATE,
18
19
  RN_STORAGE_CONFIGURATION,
@@ -96,6 +97,7 @@ def _resequence_resources(
96
97
  RN_CREDENTIAL,
97
98
  RN_IMAGE_FAMILY,
98
99
  RN_STRING_ATTRIBUTE_DEFINITION,
100
+ RN_NUMERIC_ATTRIBUTE_DEFINITION,
99
101
  RN_SOURCE_TEMPLATE,
100
102
  RN_REQUIREMENT_TEMPLATE,
101
103
  RN_ALLOWANCE,
@@ -552,6 +552,30 @@ def allowances_table(
552
552
  return headers, table
553
553
 
554
554
 
555
+ def attribute_definitions_table(
556
+ attribute_definitions: List[Dict],
557
+ ) -> (List[str], List[str]):
558
+ headers = [
559
+ "#",
560
+ "Name",
561
+ "Type",
562
+ "Title",
563
+ "Description",
564
+ ]
565
+ table = []
566
+ for index, attribute_definition in enumerate(attribute_definitions):
567
+ table.append(
568
+ [
569
+ index + 1,
570
+ attribute_definition["name"],
571
+ attribute_definition["type"].split(".")[-1],
572
+ attribute_definition["title"],
573
+ attribute_definition.get("description", ""),
574
+ ]
575
+ )
576
+ return headers, table
577
+
578
+
555
579
  def aws_availability_zone_table(
556
580
  aws_azs: List[AWSAvailabilityZone],
557
581
  ) -> (List[str], List[str]):
@@ -576,7 +600,7 @@ def aws_availability_zone_table(
576
600
 
577
601
  def print_numbered_object_list(
578
602
  client: PlatformClient,
579
- objects: List[Union[Item, str]],
603
+ objects: List[Union[Item, str, Dict]],
580
604
  object_type_name: Optional[str] = None,
581
605
  override_quiet: bool = False,
582
606
  showing_all: bool = False,
@@ -626,6 +650,8 @@ def print_numbered_object_list(
626
650
  headers, table = allowances_table(objects)
627
651
  elif isinstance(objects[0], AWSAvailabilityZone):
628
652
  headers, table = aws_availability_zone_table(objects)
653
+ elif object_type_name == "Attribute Definition":
654
+ headers, table = attribute_definitions_table(objects)
629
655
  else:
630
656
  table = []
631
657
  for index, obj in enumerate(objects):
@@ -32,6 +32,7 @@ from yd_commands.settings import (
32
32
  RN_CREDENTIAL,
33
33
  RN_IMAGE_FAMILY,
34
34
  RN_KEYRING,
35
+ RN_NUMERIC_ATTRIBUTE_DEFINITION,
35
36
  RN_REQUIREMENT_TEMPLATE,
36
37
  RN_SOURCE_TEMPLATE,
37
38
  RN_STORAGE_CONFIGURATION,
@@ -94,8 +95,11 @@ def remove_resources(resources: Optional[List[Dict]] = None):
94
95
  "alternatively, Allowances can be removed by their "
95
96
  "YellowDog IDs (yd-remove --ids)"
96
97
  )
97
- elif resource_type == RN_STRING_ATTRIBUTE_DEFINITION:
98
- remove_string_attribute_definition_via_api(resource)
98
+ elif resource_type in [
99
+ RN_STRING_ATTRIBUTE_DEFINITION,
100
+ RN_NUMERIC_ATTRIBUTE_DEFINITION,
101
+ ]:
102
+ remove_attribute_definition_via_api(resource)
99
103
  else:
100
104
  print_error(f"Unknown resource type '{resource_type}'")
101
105
  except Exception as e:
@@ -411,7 +415,7 @@ def remove_resource_by_id(resource_id: str):
411
415
  print_error(f"Unable to remove resource with ID {resource_id}: {e}")
412
416
 
413
417
 
414
- def remove_string_attribute_definition_via_api(resource: Dict):
418
+ def remove_attribute_definition_via_api(resource: Dict):
415
419
  """
416
420
  Use the API to remove user string attribute definitions.
417
421
  """
@@ -420,7 +424,7 @@ def remove_string_attribute_definition_via_api(resource: Dict):
420
424
  except KeyError as e:
421
425
  raise Exception(f"Expected property to be defined ({e})")
422
426
 
423
- if not confirmed(f"Remove String Attribute Definition '{name}'?"):
427
+ if not confirmed(f"Remove Attribute Definition '{name}'?"):
424
428
  return
425
429
 
426
430
  url = f"{CONFIG_COMMON.url}/compute/attributes/user/{name}"
@@ -428,7 +432,7 @@ def remove_string_attribute_definition_via_api(resource: Dict):
428
432
  response = delete(url=url, headers=headers)
429
433
 
430
434
  if response.status_code == 200:
431
- print_log(f"Removed String Attribute Definition '{name}' (if present)")
435
+ print_log(f"Removed Attribute Definition '{name}' (if present)")
432
436
  return
433
437
 
434
438
  raise Exception(f"HTTP {response.status_code} ({response.text})")
@@ -106,3 +106,4 @@ RN_REQUIREMENT_TEMPLATE = "ComputeRequirementTemplate"
106
106
  RN_SOURCE_TEMPLATE = "ComputeSourceTemplate"
107
107
  RN_STORAGE_CONFIGURATION = "NamespaceStorageConfiguration"
108
108
  RN_STRING_ATTRIBUTE_DEFINITION = "StringAttributeDefinition"
109
+ RN_NUMERIC_ATTRIBUTE_DEFINITION = "NumericAttributeDefinition"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: yellowdog-python-examples
3
- Version: 7.9.0
3
+ Version: 7.9.1
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.9.0"