yellowdog-python-examples 8.2.0__py3-none-any.whl → 8.3.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.
yellowdog_cli/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "8.2.0"
1
+ __version__ = "8.3.0"
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """
4
+ A script for reporting on the details of the Application being used.
5
+ """
6
+
7
+ from yellowdog_client.model import ApplicationDetails
8
+
9
+ from yellowdog_cli.utils.entity_utils import (
10
+ get_all_roles_and_namespaces_for_application,
11
+ get_application_details,
12
+ get_application_group_summaries,
13
+ )
14
+ from yellowdog_cli.utils.printing import print_simple
15
+ from yellowdog_cli.utils.wrapper import CLIENT, CONFIG_COMMON, main_wrapper
16
+
17
+
18
+ @main_wrapper
19
+ def main():
20
+
21
+ application_details: ApplicationDetails = get_application_details(CLIENT)
22
+
23
+ print()
24
+ print_simple(
25
+ f" Application name: {application_details.name}",
26
+ override_quiet=True,
27
+ )
28
+ print_simple(
29
+ f" Application ID: {application_details.id}",
30
+ override_quiet=True,
31
+ )
32
+ print_simple(
33
+ f" Account name: {application_details.accountName}",
34
+ override_quiet=True,
35
+ )
36
+ if "api" in CONFIG_COMMON.url:
37
+ print_simple(
38
+ " Portal URL: "
39
+ f"{CONFIG_COMMON.url.replace('api', 'portal')}"
40
+ f"/#/signin?account={application_details.accountName}",
41
+ override_quiet=True,
42
+ )
43
+ print_simple(
44
+ f" Account ID: {application_details.accountId}",
45
+ override_quiet=True,
46
+ )
47
+ features = (
48
+ ""
49
+ if application_details.features is None
50
+ else ", ".join([str(feature) for feature in application_details.features])
51
+ )
52
+ print_simple(
53
+ f" Account features: {features}",
54
+ override_quiet=True,
55
+ )
56
+ all_ns_readable = "Yes" if application_details.allNamespacesReadable else "No"
57
+ print_simple(
58
+ f" All namespaces readable: {all_ns_readable}",
59
+ override_quiet=True,
60
+ )
61
+ if not application_details.allNamespacesReadable:
62
+ readable_namespaces = (
63
+ ""
64
+ if application_details.readableNamespaces is None
65
+ else ", ".join([rns for rns in application_details.readableNamespaces])
66
+ )
67
+ print_simple(
68
+ f" Readable namespaces: {readable_namespaces}",
69
+ override_quiet=True,
70
+ )
71
+ try:
72
+ groups = get_application_group_summaries(CLIENT, application_details.id)
73
+ group_names = ", ".join([group.name for group in groups])
74
+ print_simple(
75
+ f" In group(s): {group_names}",
76
+ override_quiet=True,
77
+ )
78
+ for i, (role, namespaces) in enumerate(
79
+ get_all_roles_and_namespaces_for_application(
80
+ CLIENT, application_details.id
81
+ ).items()
82
+ ):
83
+ msg = f"{role} [{', '.join(namespaces)}]"
84
+ if i == 0:
85
+ print_simple(
86
+ f" With role(s) [in namespace(s)]: {msg}",
87
+ override_quiet=True,
88
+ )
89
+ else:
90
+ print_simple(
91
+ f" {msg}",
92
+ override_quiet=True,
93
+ )
94
+
95
+ except Exception as e:
96
+ if "Forbidden" in str(e):
97
+ print_simple(
98
+ " Groups and roles: "
99
+ "Cannot be determined due to application permissions",
100
+ override_quiet=True,
101
+ )
102
+ else:
103
+ pass
104
+ print()
yellowdog_cli/create.py CHANGED
@@ -48,13 +48,14 @@ from yellowdog_client.model.exceptions import InvalidRequestException
48
48
 
49
49
  from yellowdog_cli.utils.entity_utils import (
50
50
  clear_application_caches,
51
+ clear_compute_requirement_template_cache,
51
52
  clear_compute_source_template_cache,
52
53
  clear_group_caches,
53
54
  clear_image_caches,
54
55
  find_compute_requirement_template_id_by_name,
55
56
  find_compute_source_template_id_by_name,
56
57
  find_image_name_or_id,
57
- get_application_groups,
58
+ get_application_group_summaries,
58
59
  get_application_id_by_name,
59
60
  get_group_id_by_name,
60
61
  get_group_name_by_id,
@@ -130,6 +131,7 @@ from yellowdog_cli.utils.wrapper import ARGS_PARSER, CLIENT, CONFIG_COMMON, main
130
131
  from yellowdog_cli.utils.ydid_utils import YDIDType, get_ydid_type
131
132
 
132
133
  CLEAR_CST_CACHE: bool = False # Track whether the CST cache needs to be cleared
134
+ CLEAR_CRT_CACHE: bool = False # Track whether the CRT cache needs to be cleared
133
135
  CLEAR_IMAGE_FAMILY_CACHE: bool = (
134
136
  False # Track whether the image caches need to be cleared
135
137
  )
@@ -391,6 +393,8 @@ def create_compute_requirement_template(resource: Dict):
391
393
  template = CLIENT.compute_client.add_compute_requirement_template(
392
394
  compute_template
393
395
  )
396
+ global CLEAR_CRT_CACHE
397
+ CLEAR_CRT_CACHE = True
394
398
  print_log(f"Created Compute Requirement Template '{name}' ({template.id})")
395
399
  if ARGS_PARSER.quiet:
396
400
  print(template.id)
@@ -729,6 +733,10 @@ def create_allowance(resource: Dict):
729
733
  template_name_or_id = resource.get(PROP_SOURCE_CREATED_FROM, None)
730
734
  if template_name_or_id is not None:
731
735
  if get_ydid_type(template_name_or_id) != YDIDType.COMPUTE_SOURCE_TEMPLATE:
736
+ global CLEAR_CST_CACHE
737
+ if CLEAR_CST_CACHE: # Update the CST cache if required
738
+ clear_compute_source_template_cache()
739
+ CLEAR_CST_CACHE = False
732
740
  template_id = find_compute_source_template_id_by_name(
733
741
  client=CLIENT, name=template_name_or_id
734
742
  )
@@ -750,6 +758,10 @@ def create_allowance(resource: Dict):
750
758
  get_ydid_type(template_name_or_id)
751
759
  != YDIDType.COMPUTE_REQUIREMENT_TEMPLATE
752
760
  ):
761
+ global CLEAR_CRT_CACHE
762
+ if CLEAR_CRT_CACHE: # Update the CRT cache if required
763
+ clear_compute_requirement_template_cache()
764
+ CLEAR_CRT_CACHE = False
753
765
  template_id = find_compute_requirement_template_id_by_name(
754
766
  client=CLIENT, name=template_name_or_id
755
767
  )
@@ -1144,7 +1156,7 @@ def create_application(resource: Dict):
1144
1156
  Helper function to add/remove groups from an application.
1145
1157
  """
1146
1158
  current_group_ids = {
1147
- group.id for group in get_application_groups(CLIENT, app.id)
1159
+ group.id for group in get_application_group_summaries(CLIENT, app.id)
1148
1160
  }
1149
1161
 
1150
1162
  if current_group_ids == new_group_ids:
yellowdog_cli/list.py CHANGED
@@ -52,7 +52,7 @@ from yellowdog_cli.utils.entity_utils import (
52
52
  get_all_groups,
53
53
  get_all_roles,
54
54
  get_all_users,
55
- get_application_groups,
55
+ get_application_group_summaries,
56
56
  get_compute_requirement_summaries,
57
57
  get_compute_requirement_templates,
58
58
  get_compute_source_templates,
@@ -992,7 +992,9 @@ def list_applications():
992
992
  {
993
993
  PROP_GROUPS: [
994
994
  group.name
995
- for group in get_application_groups(CLIENT, application.id)
995
+ for group in get_application_group_summaries(
996
+ CLIENT, application.id
997
+ )
996
998
  ],
997
999
  PROP_RESOURCE: RN_APPLICATION,
998
1000
  },
yellowdog_cli/show.py CHANGED
@@ -8,7 +8,7 @@ from yellowdog_client.model import ConfiguredWorkerPool
8
8
 
9
9
  from yellowdog_cli.list import get_keyring
10
10
  from yellowdog_cli.utils.entity_utils import (
11
- get_application_groups,
11
+ get_application_group_summaries,
12
12
  substitute_id_for_name_in_allowance,
13
13
  substitute_ids_for_names_in_crt,
14
14
  substitute_image_family_id_for_name_in_cst,
@@ -225,7 +225,9 @@ def show_details(ydid: str, initial_indent: int = 0, with_final_comma: bool = Fa
225
225
 
226
226
  elif ydid_type == YDIDType.APPLICATION:
227
227
  print_log(f"Showing details of Application ID '{ydid}'")
228
- group_names = [group.name for group in get_application_groups(CLIENT, ydid)]
228
+ group_names = [
229
+ group.name for group in get_application_group_summaries(CLIENT, ydid)
230
+ ]
229
231
  print_yd_object(
230
232
  CLIENT.account_client.get_application(ydid),
231
233
  initial_indent=initial_indent,
@@ -1884,6 +1884,8 @@ def lookup_module_description(module_name: str) -> Optional[str]:
1884
1884
  "comparing whether a work requirement or task group is matched by "
1885
1885
  "workers in the specified provisioned worker pools"
1886
1886
  )
1887
+ elif "application" in module_name:
1888
+ suffix = "reporting the details of the current Application"
1887
1889
 
1888
1890
  return None if suffix is None else prefix + suffix
1889
1891
 
@@ -3,7 +3,7 @@ Various utility functions for finding objects, etc.
3
3
  """
4
4
 
5
5
  from functools import lru_cache
6
- from typing import Callable, List, Optional, Tuple, Union
6
+ from typing import Callable, Dict, List, Optional, Tuple, Union
7
7
 
8
8
  from yellowdog_client import PlatformClient
9
9
  from yellowdog_client.common import SearchClient
@@ -11,6 +11,7 @@ from yellowdog_client.model import (
11
11
  AccountAllowance,
12
12
  AllowanceSearch,
13
13
  Application,
14
+ ApplicationDetails,
14
15
  ApplicationSearch,
15
16
  ComputeRequirementStatus,
16
17
  ComputeRequirementSummary,
@@ -22,6 +23,7 @@ from yellowdog_client.model import (
22
23
  ComputeSourceTemplateSearch,
23
24
  ComputeSourceTemplateSummary,
24
25
  ExternalUser,
26
+ Group,
25
27
  GroupSearch,
26
28
  GroupSummary,
27
29
  ImageAccess,
@@ -385,7 +387,7 @@ def find_image_name_or_id(
385
387
  PUBLIC images.
386
388
 
387
389
  Finally, if nothing matches, the original ID is returned. This is
388
- likely to be a provider specific string.
390
+ likely to be a provider-specific string.
389
391
  """
390
392
  if image_name_or_id is None:
391
393
  return None
@@ -522,6 +524,7 @@ def find_image_name_or_id(
522
524
  )
523
525
 
524
526
  # Finally, fall through and return the unchanged, original ID string
527
+ print_log(f"No Images ID substitution possible for '{original_image_name_or_id}'")
525
528
  return original_image_name_or_id
526
529
 
527
530
 
@@ -915,21 +918,71 @@ def get_application_id_by_name(client: PlatformClient, app_name: str) -> Optiona
915
918
  return None
916
919
 
917
920
 
918
- def clear_application_caches():
921
+ @lru_cache
922
+ def get_application_details(client: PlatformClient) -> ApplicationDetails:
919
923
  """
920
- Clear the application caches.
924
+ Load and cache the Application's details
921
925
  """
922
- get_all_applications.cache_clear()
923
- get_application_id_by_name.cache_clear()
926
+ return client.application_client.get_application_details()
924
927
 
925
928
 
926
- def get_application_groups(client: PlatformClient, app_id: str) -> List[GroupSummary]:
929
+ @lru_cache
930
+ def get_application_group_summaries(
931
+ client: PlatformClient, app_id: str
932
+ ) -> List[GroupSummary]:
927
933
  """
928
- Get the groups to which an application belongs.
934
+ Get the summaries of the groups to which an application belongs.
929
935
  """
930
936
  return client.account_client.get_application_groups(app_id).list_all()
931
937
 
932
938
 
939
+ @lru_cache
940
+ def get_application_groups(client: PlatformClient, app_id: str) -> List[Group]:
941
+ """
942
+ Get the groups to which an application belongs.
943
+ """
944
+ return [
945
+ client.account_client.get_group(group_summary.id)
946
+ for group_summary in get_application_group_summaries(client, app_id)
947
+ ]
948
+
949
+
950
+ @lru_cache
951
+ def get_all_roles_and_namespaces_for_application(
952
+ client: PlatformClient, application_id: str
953
+ ) -> Dict:
954
+ """
955
+ Get a list of roles and the namespaces to which they apply, for a given application.
956
+ Returns {role_name: [namespace, ...]}, sorted by role name.
957
+ """
958
+ # Iterate through groups, roles
959
+ roles_ = dict()
960
+ for group in get_application_groups(client, application_id):
961
+ for role in group.roles:
962
+ if roles_.get(role.role.name) is None:
963
+ roles_[role.role.name] = []
964
+ if role.scope.global_:
965
+ roles_[role.role.name] += ["GLOBAL"]
966
+ else:
967
+ roles_[role.role.name] += [
968
+ namespace.namespace for namespace in role.scope.namespaces
969
+ ]
970
+
971
+ return {role: namespaces for role, namespaces in sorted(roles_.items())}
972
+
973
+
974
+ def clear_application_caches():
975
+ """
976
+ Clear the application caches.
977
+ """
978
+ get_all_applications.cache_clear()
979
+ get_application_id_by_name.cache_clear()
980
+ get_application_details.cache_clear()
981
+ get_application_group_summaries.cache_clear()
982
+ get_application_groups.cache_clear()
983
+ get_all_roles_and_namespaces_for_application.cache_clear()
984
+
985
+
933
986
  def get_user_groups(client: PlatformClient, user_id: str) -> List[GroupSummary]:
934
987
  """
935
988
  Get the groups to which a user belongs.
@@ -1013,13 +1066,25 @@ def get_image_family_summaries(
1013
1066
  """
1014
1067
  Obtain and cache the list of image families.
1015
1068
  """
1016
- # Temporarily suppress most permission errors: will be improved
1017
- # once the application can be queried for its admissible
1018
- # IMAGE_READ namespaces
1069
+ # Determine namespace(s) to search
1070
+ if namespace is None:
1071
+ # Attempt to use the namespace(s) that are 'readable' by
1072
+ # this application; does not guarantee IMAGE_READ
1073
+ application_details = get_application_details(client)
1074
+ if application_details.allNamespacesReadable:
1075
+ namespaces = None # Search all namespaces
1076
+ elif application_details.readableNamespaces is not None:
1077
+ namespaces = application_details.readableNamespaces
1078
+ else:
1079
+ namespaces = []
1080
+ else:
1081
+ # Use the supplied namespace
1082
+ namespaces = [namespace]
1083
+
1019
1084
  try:
1020
1085
  if_search = MachineImageFamilySearch(
1021
1086
  familyName=None,
1022
- namespaces=None if namespace is None else [namespace],
1087
+ namespaces=namespaces,
1023
1088
  includePublic=True,
1024
1089
  )
1025
1090
  search_client: SearchClient = client.images_client.get_image_families(if_search)
@@ -256,7 +256,10 @@ def load_dotenv_file():
256
256
  if dotenv_file == "":
257
257
  return
258
258
 
259
- print_log(f"Loading environment variables from '{dotenv_file}'")
259
+ print_log(
260
+ f"Loading environment variables from '{dotenv_file}' ("
261
+ f"{'' if ARGS_PARSER.env_override else 'NOT '}OVERRIDING existing variables)"
262
+ )
260
263
 
261
264
  dotenv_yd_substitutions = [ # Find 'YD' variables
262
265
  f"'{key}'"
@@ -5,11 +5,10 @@ for all commands.
5
5
 
6
6
  import os
7
7
  from sys import exit
8
- from typing import List
9
8
 
10
9
  from pypac import pac_context_for_url
11
10
  from yellowdog_client import PlatformClient
12
- from yellowdog_client.model import ApiKey, KeyringSummary, ServicesSchema
11
+ from yellowdog_client.model import ApiKey, ServicesSchema
13
12
 
14
13
  from yellowdog_cli.utils.args import ARGS_PARSER
15
14
  from yellowdog_cli.utils.config_types import ConfigCommon
@@ -22,62 +21,38 @@ CLIENT = PlatformClient.create(
22
21
  ApiKey(CONFIG_COMMON.key, CONFIG_COMMON.secret),
23
22
  )
24
23
 
25
- from requests.exceptions import HTTPError
26
-
27
24
 
28
25
  def dry_run() -> bool:
29
26
  """
30
27
  Is this a dry-run?
31
28
  """
32
- dry_run = ARGS_PARSER.dry_run or ARGS_PARSER.process_csv_only
33
- if dry_run is None:
29
+ dry_run_ = ARGS_PARSER.dry_run or ARGS_PARSER.process_csv_only
30
+ if dry_run_ is None:
34
31
  return False
35
32
  else:
36
- return dry_run
37
-
38
-
39
- def print_account():
40
- """
41
- Print the six character hexadecimal account ID. Depends on there
42
- being at least one Keyring in the account. Omit if this is a dry run.
43
- """
44
- if not dry_run():
45
- try:
46
- keyrings: List[KeyringSummary] = CLIENT.keyring_client.find_all_keyrings()
47
- if len(keyrings) > 0:
48
- # This is a little brittle, obviously
49
- print_log(
50
- f"YellowDog Account short identifier is: '{keyrings[0].id[13:19]}'"
51
- )
52
- except HTTPError as e:
53
- if "Unauthorized" in str(e):
54
- print_error(
55
- "Unable to authorise YellowDog Application; please check"
56
- " your Application Key/Secret and its permissions"
57
- )
58
- exit(1)
59
- except:
60
- pass
33
+ return dry_run_
61
34
 
62
35
 
63
36
  def set_proxy():
64
37
  """
65
38
  Set the HTTPS proxy using autoconfiguration (PAC) if enabled.
66
39
  """
67
- if not dry_run():
68
- proxy_var = "HTTPS_PROXY"
69
- if CONFIG_COMMON.use_pac:
70
- print_log("Using Proxy Auto-Configuration (PAC)")
71
- with pac_context_for_url(CONFIG_COMMON.url):
72
- https_proxy = os.getenv(proxy_var, None)
73
- if https_proxy is not None:
74
- os.environ[proxy_var] = https_proxy
75
- else:
76
- print_log("No PAC proxy settings found")
77
- else:
40
+ if dry_run():
41
+ return
42
+
43
+ proxy_var = "HTTPS_PROXY"
44
+ if CONFIG_COMMON.use_pac:
45
+ print_log("Using Proxy Auto-Configuration (PAC)")
46
+ with pac_context_for_url(CONFIG_COMMON.url):
78
47
  https_proxy = os.getenv(proxy_var, None)
79
48
  if https_proxy is not None:
80
- print_log(f"Using {proxy_var}={https_proxy}")
49
+ os.environ[proxy_var] = https_proxy
50
+ else:
51
+ print_log("No PAC proxy settings found")
52
+ else:
53
+ https_proxy = os.getenv(proxy_var, None)
54
+ if https_proxy is not None:
55
+ print_log(f"Using {proxy_var}={https_proxy}")
81
56
 
82
57
 
83
58
  def main_wrapper(func):
@@ -86,7 +61,6 @@ def main_wrapper(func):
86
61
  exit_code = 0
87
62
  try:
88
63
  set_proxy()
89
- # print_account()
90
64
  func()
91
65
  except Exception as e:
92
66
  if "MissingPermissionException" in str(e):
@@ -96,6 +70,10 @@ def main_wrapper(func):
96
70
  " Application belongs to the required group(s), e.g.,"
97
71
  f" 'administrators', with roles in the required namespace(s): {e}"
98
72
  )
73
+ elif "Unauthorized" in str(e):
74
+ print_error(
75
+ f"Your Application Key ID and SECRET are not recognised: {e}"
76
+ )
99
77
  else:
100
78
  print_error(e)
101
79
  exit_code = 1
@@ -109,11 +87,12 @@ def main_wrapper(func):
109
87
  print_log("Done")
110
88
  exit(exit_code)
111
89
  else:
112
- set_proxy()
113
- # print_account()
114
- func()
115
- CLIENT.close()
116
- print_log("Done")
117
- exit(0)
90
+ try:
91
+ set_proxy()
92
+ func()
93
+ print_log("Done")
94
+ exit(0)
95
+ finally:
96
+ CLIENT.close()
118
97
 
119
98
  return wrapper
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yellowdog-python-examples
3
- Version: 8.2.0
3
+ Version: 8.3.0
4
4
  Summary: Python CLI commands using the YellowDog Python SDK
5
5
  Author-email: YellowDog Limited <support@yellowdog.co>
6
6
  License-Expression: Apache-2.0
@@ -26,7 +26,7 @@ Requires-Dist: requests
26
26
  Requires-Dist: rich==13.9.4
27
27
  Requires-Dist: tabulate>=0.9.0
28
28
  Requires-Dist: toml
29
- Requires-Dist: yellowdog-sdk>=11.7.0
29
+ Requires-Dist: yellowdog-sdk>=11.8.1
30
30
  Provides-Extra: jsonnet
31
31
  Requires-Dist: jsonnet; extra == "jsonnet"
32
32
  Provides-Extra: cloudwizard
@@ -44,7 +44,7 @@ Dynamic: license-file
44
44
 
45
45
  ## Overview
46
46
 
47
- This is a set of Python CLI commands for interacting with the YellowDog Platform, providing examples of usage of the [YellowDog Python SDK](https://docs.yellowdog.co/api/python/index.html).
47
+ This is a set of Python CLI commands for interacting with the YellowDog Platform, providing examples of usage of the [YellowDog Python SDK](https://docs.yellowdog.ai/sdk/python/index.html).
48
48
 
49
49
  The commands support:
50
50
 
@@ -62,10 +62,11 @@ The commands support:
62
62
  - **Provisioning** Worker Pools with the **`yd-provision`** command
63
63
  - **Resizing** Worker Pools and Compute Requirements with the **`yd-resize`** command
64
64
  - **Showing** the details of any YellowDog entity using its YellowDog ID with the **`yd-show`** command
65
+ - **Showing** the details of the current Application with the **`yd-application`** command
65
66
  - **Shutting Down** Worker Pools and Nodes with the **`yd-shutdown`** command
66
67
  - **Starting** HELD Work Requirements and **Holding** (or pausing) RUNNING Work Requirements with the **`yd-start`** and **`yd-hold`** commands
67
68
  - **Submitting** Work Requirements with the **`yd-submit`** command
68
69
  - **Terminating** Compute Requirements with the **`yd-terminate`** command
69
70
  - **Uploading** files to the YellowDog Object Store with the **`yd-upload`** command
70
71
 
71
- Please see the documenation in the [GitHub repository](https://github.com/yellowdog/python-examples) for more details.
72
+ Please see the documentation in the [GitHub repository](https://github.com/yellowdog/python-examples) for more details.
@@ -1,11 +1,12 @@
1
- yellowdog_cli/__init__.py,sha256=Xb24P8T6pG5QQaEw-UTO0iybyDoxvRGJaUR_qFoVAJQ,22
1
+ yellowdog_cli/__init__.py,sha256=hiR7PouSkHWKTT2q2JFrz5vsu1x5YsLxuo4hVevNMUU,22
2
2
  yellowdog_cli/abort.py,sha256=S8tCr-Fcc8zM7luQ5_xunEeo-eqmkO4pmahDZEpxWF4,4311
3
3
  yellowdog_cli/admin.py,sha256=Iipc0_A-Rf997hSDjOOYTaPpB3dsuqekV8Slmm154GI,1010
4
+ yellowdog_cli/application.py,sha256=00pup0YJ_4XOanisPwCb-JCWXvs-jOYohAaRUYwBzs4,3446
4
5
  yellowdog_cli/boost.py,sha256=JOUkXpl7yvmVZCAS_iv8GJ6g2wF1siVjGGJ-EUDI0FI,1268
5
6
  yellowdog_cli/cancel.py,sha256=Eu0FIH-VNNhW7WzvC0tcHgp7KxMVc35n5Rinu_YPeZc,6357
6
7
  yellowdog_cli/cloudwizard.py,sha256=UC1CDNPAsUMh_0C9ScLF4wGmvJ2Rbryravj67LHdFnI,2647
7
8
  yellowdog_cli/compare.py,sha256=yihgygtxedvRXz0mQV9hmvvMeKaNYIMfgBlTHetaa_s,24311
8
- yellowdog_cli/create.py,sha256=QD9Su3GXEQTOsfNt0BswEWpKcD65kpJZnwcUZMf_6-c,51944
9
+ yellowdog_cli/create.py,sha256=-CTw28ino-xpmTYI9t-FML_3ATC2jLc1ac1SllMhvJA,52582
9
10
  yellowdog_cli/delete.py,sha256=7YWGY8vI9ec3QP2y7VSEFFyAsY3IWcsZndDDXhlUNTY,3023
10
11
  yellowdog_cli/download.py,sha256=zYlfr7jCoJGzoayjhpoy3Ku9unmXnLu5XORRuUIuDlo,5479
11
12
  yellowdog_cli/finish.py,sha256=Edcz9__13ppE2KUffuLoLTjo4Cj9FKLhj-ttxYiEKvs,5231
@@ -14,11 +15,11 @@ yellowdog_cli/format_json.py,sha256=NrgE0jAUK46Kd4yWxuVbjKXQMzWewP3I8us8QkZZx1s,
14
15
  yellowdog_cli/hold.py,sha256=wqSsI8UhFZX4pE-pTefxvnVCb0uCY1P_kJjm_YMedsM,306
15
16
  yellowdog_cli/instantiate.py,sha256=TDwvUVwqWLY4m0updxbWPTgLX2J0SOmT-EqZRDHgOgI,11996
16
17
  yellowdog_cli/jsonnet2json.py,sha256=kv-AZSR-xwIbXnUdL3gYGjYdSiHq7cAvlEGPz4StdTE,765
17
- yellowdog_cli/list.py,sha256=MNiIJkTygRMtNvfcscys-wWg8_18_PO672z4HnwQprM,33345
18
+ yellowdog_cli/list.py,sha256=XESqjdovQbJKiZp5rSSLsOQehCXW4MdRzg8PMMw-dpk,33417
18
19
  yellowdog_cli/provision.py,sha256=-rbFJYzd3Kfq6zpFhbM_KM0VUSkJAa3mvY2YODTNc5Q,19667
19
20
  yellowdog_cli/remove.py,sha256=yPZSVXY0shzcb_FN8MvW1friuixVzuVGmwqZAnFLDno,20904
20
21
  yellowdog_cli/resize.py,sha256=5oMqZmT1KXjnqEClCVzQbCDyZaEu-oc06mypy0TlTBo,4353
21
- yellowdog_cli/show.py,sha256=tXKl5QgO2o1AgcGXXpxTA1MvmLzm1df1UnwcFBAYrNo,11015
22
+ yellowdog_cli/show.py,sha256=pti-rgPjprgF8h8rNfdgbT3LnmRT6-RGnurHr16on3k,11063
22
23
  yellowdog_cli/shutdown.py,sha256=JlgdJWv4hfVf_eTQU5z_tlSLFXNw4Pb31rA2NjxBijM,5606
23
24
  yellowdog_cli/start.py,sha256=9PHUAbS6vSq9RbttKkymOBzltIlWssQvk4zHJ8R-bWw,314
24
25
  yellowdog_cli/submit.py,sha256=nsP3ooUvri70yieB91I3_YwDxJ8MdAdpDmepZVtiAXA,62126
@@ -26,7 +27,7 @@ yellowdog_cli/terminate.py,sha256=GCHAvK3iQBoKoea6UVT63f7stejSEhJGRGUcLRW8VGw,46
26
27
  yellowdog_cli/upload.py,sha256=tCqspQ5xNqUFsAIqBxzvyVQ5Uhk5uZFTf1xM3JFSgBs,5389
27
28
  yellowdog_cli/version.py,sha256=IADl53F8zo2pe1FrgZqo3hKNQXmfz7GnynIbXZ7ryQo,1208
28
29
  yellowdog_cli/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
- yellowdog_cli/utils/args.py,sha256=jO-hPWhSF-8HWWRNlKhlM8R8ziwc2Y4zt5Z5en6wzw8,59357
30
+ yellowdog_cli/utils/args.py,sha256=-_BvdR_fMGohqiH1c5WzXLWi5FaZi04PBYvB7a24Cd8,59464
30
31
  yellowdog_cli/utils/check_imports.py,sha256=uZB7lo3W_XhDezzgJF6JKkaSBPt-YM9uvRZ077smPe4,1155
31
32
  yellowdog_cli/utils/cloudwizard_aws.py,sha256=3hRUP8E5zxiy7fkuaceeutIGtF7JVs9fZrDHBi04Gp8,38129
32
33
  yellowdog_cli/utils/cloudwizard_aws_types.py,sha256=dh2VbzcN3-skECEjDEUxIHLHnfFo88SHMNH-qyY5wso,481
@@ -36,13 +37,13 @@ yellowdog_cli/utils/cloudwizard_gcp.py,sha256=zb4WdNrkMgbWWgko3zOb8uTyeQ6BuWsdeV
36
37
  yellowdog_cli/utils/compact_json.py,sha256=l-tOoOaiS7Th8ravH66F_xam0dPX2CXLRq-gEBIcNl8,3757
37
38
  yellowdog_cli/utils/config_types.py,sha256=RYgL_Ms8BYlEwh6Vb7Awr9wBfXSgbl2yC2iDYFovchQ,3963
38
39
  yellowdog_cli/utils/csv_data.py,sha256=vyLhb6ZRzQXzSjK9VWzoP6AP43SuHoWxbD5kEAzUwvM,14409
39
- yellowdog_cli/utils/entity_utils.py,sha256=CAzKhYDB3QNzvMNQqWsCMgIJum4xySIuMu4fTe3jZPk,33007
40
+ yellowdog_cli/utils/entity_utils.py,sha256=3xeMZ5qtk1fuw2GJygSObXAhYsqYLPb9iGJ1cmQQpaw,35212
40
41
  yellowdog_cli/utils/follow_utils.py,sha256=Tiq6n86v1cEMBACVoz6IFj_GLW0Fp0qKB2EZINX8wKE,4320
41
42
  yellowdog_cli/utils/interactive.py,sha256=VQZKZ9GtA-bSsWGJgEoOQ0WrOeXbeALpkRhHENCJ8q0,5778
42
43
  yellowdog_cli/utils/items.py,sha256=AhSyhgi-p6EZpwozFIxwIxbjxRwKgR2_wt6QdZtORj8,1333
43
44
  yellowdog_cli/utils/load_config.py,sha256=vFe9tegO2IVUm90_Yg2mHx02S5sGn22j1J76FgP6Xa0,19300
44
45
  yellowdog_cli/utils/load_resources.py,sha256=tJlXuDjNKLu5yB7defWxRf4Rl_5zE4tHALlZT8VM_q0,4560
45
- yellowdog_cli/utils/misc_utils.py,sha256=pZIIS1s9LfeI24ef_cXJsth3nDdIJvbVX7VToTM0LzQ,8565
46
+ yellowdog_cli/utils/misc_utils.py,sha256=D2s3e3xZIfNHHz6Fu-hrEJ7QorKY9b94Ov40MFSNVvo,8667
46
47
  yellowdog_cli/utils/printing.py,sha256=gGgvshfcBcQHI50yMSDrCCJpzkLAecumzst4Cx8gMMg,46403
47
48
  yellowdog_cli/utils/property_names.py,sha256=eM550eiMD6-o5RjjHovU5y1Ki8RCkacaKN-Az6msXSk,7025
48
49
  yellowdog_cli/utils/provision_utils.py,sha256=oLiOWvb-V38asFFEFNpF_T-vyz2c-ez47yrZ8skzemk,3673
@@ -54,11 +55,11 @@ yellowdog_cli/utils/type_check.py,sha256=QILKGpeFo53VrtpWyyMoPlqTJNhAkLsZJ_r0jHi
54
55
  yellowdog_cli/utils/upload_utils.py,sha256=K7bZrkajZWjYaDqcgxwlLl4xvXNndRnw0bkiiHnW9io,3657
55
56
  yellowdog_cli/utils/validate_properties.py,sha256=TsroKrf4jcAg_uQLRb9DpoSjRZ49XBrl7AQEOe_rhCk,2502
56
57
  yellowdog_cli/utils/variables.py,sha256=AHaolW682lkqm1P9MqWZnwvvK-Gd8hgV0HgzX76A1Ck,20542
57
- yellowdog_cli/utils/wrapper.py,sha256=TtvHmPKqKRk9meQw3LcsZcpkYNyuPSGcS0tC3fbQ4U4,3846
58
+ yellowdog_cli/utils/wrapper.py,sha256=3Kp5rIKdxLD2C3Aa0rhBzsnZ-l4joO5RTsOkWQG5cvw,3058
58
59
  yellowdog_cli/utils/ydid_utils.py,sha256=Gs98Pidkpd6v-cpL28t3z8mOW9JMB7ZY2MkGBX8EhMo,2360
59
- yellowdog_python_examples-8.2.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
60
- yellowdog_python_examples-8.2.0.dist-info/METADATA,sha256=wHbZAMaPm1-uvj6HCtfMBBpZlGWPx19JCRqtTQS5Hy0,3927
61
- yellowdog_python_examples-8.2.0.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
62
- yellowdog_python_examples-8.2.0.dist-info/entry_points.txt,sha256=KABYVOB3kO7kVqnUplNNoz4l36KUUVY05ynsZ9jSVL8,1016
63
- yellowdog_python_examples-8.2.0.dist-info/top_level.txt,sha256=RfffFF4rsBrBbPB1qRkJsRpUn_5icIZSdCqMDLO3hgA,14
64
- yellowdog_python_examples-8.2.0.dist-info/RECORD,,
60
+ yellowdog_python_examples-8.3.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
61
+ yellowdog_python_examples-8.3.0.dist-info/METADATA,sha256=vqKUV2u950CdfF806GBGovHDypF12dCXkwHjCBnkw0E,4019
62
+ yellowdog_python_examples-8.3.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
63
+ yellowdog_python_examples-8.3.0.dist-info/entry_points.txt,sha256=hRncrxB1ZmKjXwqyFQ3VVF_v5bLg4kaCaxT098J2d0k,1064
64
+ yellowdog_python_examples-8.3.0.dist-info/top_level.txt,sha256=RfffFF4rsBrBbPB1qRkJsRpUn_5icIZSdCqMDLO3hgA,14
65
+ yellowdog_python_examples-8.3.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.10.1)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,5 +1,6 @@
1
1
  [console_scripts]
2
2
  yd-abort = yellowdog_cli.abort:main
3
+ yd-application = yellowdog_cli.application:main
3
4
  yd-boost = yellowdog_cli.boost:main
4
5
  yd-cancel = yellowdog_cli.cancel:main
5
6
  yd-cloudwizard = yellowdog_cli.cloudwizard:main