yellowdog-python-examples 8.1.4__tar.gz → 8.1.6__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 (80) hide show
  1. {yellowdog_python_examples-8.1.4/yellowdog_python_examples.egg-info → yellowdog_python_examples-8.1.6}/PKG-INFO +1 -1
  2. yellowdog_python_examples-8.1.6/yellowdog_cli/__init__.py +1 -0
  3. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/create.py +4 -2
  4. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/remove.py +9 -9
  5. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/entity_utils.py +55 -12
  6. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/printing.py +9 -7
  7. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6/yellowdog_python_examples.egg-info}/PKG-INFO +1 -1
  8. yellowdog_python_examples-8.1.4/yellowdog_cli/__init__.py +0 -1
  9. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/LICENSE +0 -0
  10. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/PYPI_README.md +0 -0
  11. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/README.md +0 -0
  12. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/pyproject.toml +0 -0
  13. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/requirements.txt +0 -0
  14. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/setup.cfg +0 -0
  15. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/tests/test_create_remove.py +0 -0
  16. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/tests/test_demos.py +0 -0
  17. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/tests/test_dryruns.py +0 -0
  18. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/tests/test_entrypoints.py +0 -0
  19. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/tests/test_gui.py +0 -0
  20. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/tests/test_list.py +0 -0
  21. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/tests/test_objects.py +0 -0
  22. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/tests/test_variable_processing.py +0 -0
  23. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/abort.py +0 -0
  24. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/admin.py +0 -0
  25. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/boost.py +0 -0
  26. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/cancel.py +0 -0
  27. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/cloudwizard.py +0 -0
  28. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/compare.py +0 -0
  29. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/delete.py +0 -0
  30. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/download.py +0 -0
  31. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/finish.py +0 -0
  32. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/follow.py +0 -0
  33. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/format_json.py +0 -0
  34. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/hold.py +0 -0
  35. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/instantiate.py +0 -0
  36. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/jsonnet2json.py +0 -0
  37. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/list.py +0 -0
  38. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/provision.py +0 -0
  39. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/resize.py +0 -0
  40. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/show.py +0 -0
  41. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/shutdown.py +0 -0
  42. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/start.py +0 -0
  43. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/submit.py +0 -0
  44. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/terminate.py +0 -0
  45. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/upload.py +0 -0
  46. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/__init__.py +0 -0
  47. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/args.py +0 -0
  48. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/check_imports.py +0 -0
  49. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/cloudwizard_aws.py +0 -0
  50. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/cloudwizard_aws_types.py +0 -0
  51. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/cloudwizard_azure.py +0 -0
  52. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/cloudwizard_common.py +0 -0
  53. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/cloudwizard_gcp.py +0 -0
  54. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/compact_json.py +0 -0
  55. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/config_types.py +0 -0
  56. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/csv_data.py +0 -0
  57. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/follow_utils.py +0 -0
  58. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/interactive.py +0 -0
  59. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/items.py +0 -0
  60. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/load_config.py +0 -0
  61. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/load_resources.py +0 -0
  62. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/misc_utils.py +0 -0
  63. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/property_names.py +0 -0
  64. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/provision_utils.py +0 -0
  65. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/rich_console_input_fixed.py +0 -0
  66. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/settings.py +0 -0
  67. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/start_hold_common.py +0 -0
  68. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/submit_utils.py +0 -0
  69. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/type_check.py +0 -0
  70. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/upload_utils.py +0 -0
  71. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/validate_properties.py +0 -0
  72. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/variables.py +0 -0
  73. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/wrapper.py +0 -0
  74. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/utils/ydid_utils.py +0 -0
  75. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_cli/version.py +0 -0
  76. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_python_examples.egg-info/SOURCES.txt +0 -0
  77. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_python_examples.egg-info/dependency_links.txt +0 -0
  78. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_python_examples.egg-info/entry_points.txt +0 -0
  79. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_python_examples.egg-info/requires.txt +0 -0
  80. {yellowdog_python_examples-8.1.4 → yellowdog_python_examples-8.1.6}/yellowdog_python_examples.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yellowdog-python-examples
3
- Version: 8.1.4
3
+ Version: 8.1.6
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
@@ -0,0 +1 @@
1
+ __version__ = "8.1.6"
@@ -1319,8 +1319,10 @@ def create_namespace(resource: Dict):
1319
1319
  )
1320
1320
  except Exception as e:
1321
1321
  if "ConflictException" in str(e):
1322
- raise Exception(f"Namespace '{name}' already exists")
1323
- raise Exception(f"Failed to create namespace '{name}' ({e})")
1322
+ print_warning(f"Namespace '{name}' already exists")
1323
+ return
1324
+ else:
1325
+ raise Exception(f"Failed to create namespace '{name}' ({e})")
1324
1326
 
1325
1327
  print_log(f"Created namespace '{name}' ({namespace_id})")
1326
1328
 
@@ -151,7 +151,7 @@ def remove_compute_source_template(resource: Dict):
151
151
 
152
152
  source_id = find_compute_source_template_id_by_name(CLIENT, name)
153
153
  if source_id is None:
154
- print_error(f"Cannot find Compute Source Template '{name}'")
154
+ print_warning(f"Cannot find Compute Source Template '{name}'")
155
155
  return
156
156
 
157
157
  if not confirmed(f"Remove Compute Source Template '{name}'?"):
@@ -181,7 +181,7 @@ def remove_compute_requirement_template(resource: Dict):
181
181
 
182
182
  template_id = find_compute_requirement_template_id_by_name(CLIENT, name)
183
183
  if template_id is None:
184
- print_error(f"Cannot find Compute Requirement Template '{name}'")
184
+ print_warning(f"Cannot find Compute Requirement Template '{name}'")
185
185
  return
186
186
 
187
187
  if not confirmed(f"Remove Compute Requirement Template '{name}' ({template_id})?"):
@@ -215,7 +215,7 @@ def remove_keyring(resource: Dict):
215
215
  print_log(f"Removed Keyring '{name}'")
216
216
  except HTTPError as e:
217
217
  if e.response.status_code == 404:
218
- print_error(f"Cannot find Keyring '{name}'")
218
+ print_warning(f"Cannot find Keyring '{name}'")
219
219
  else:
220
220
  print_error(f"Unable to remove Keyring '{name}': {e}")
221
221
 
@@ -245,7 +245,7 @@ def remove_credential(resource: Dict):
245
245
  )
246
246
  except HTTPError as e:
247
247
  if e.response.status_code == 404:
248
- print_error(
248
+ print_warning(
249
249
  f"Cannot find Keyring '{keyring_name}'(possibly already deleted,"
250
250
  " including its credentials?)"
251
251
  )
@@ -275,7 +275,7 @@ def remove_image_family(resource: Dict):
275
275
  )
276
276
  except HTTPError as e:
277
277
  if e.response.status_code == 404:
278
- print_error(f"Cannot find Machine Image Family '{fq_name}'")
278
+ print_warning(f"Cannot find Machine Image Family '{fq_name}'")
279
279
  return
280
280
  else:
281
281
  raise e
@@ -304,7 +304,7 @@ def remove_namespace_configuration(resource: Dict):
304
304
  CLIENT.object_store_client.get_namespace_storage_configurations()
305
305
  )
306
306
  if namespace not in [x.namespace for x in namespaces]:
307
- print_error(f"Cannot find Namespace Storage Configuration '{namespace}'")
307
+ print_warning(f"Cannot find Namespace Storage Configuration '{namespace}'")
308
308
  return
309
309
 
310
310
  if not confirmed(f"Remove Namespace Storage Configuration '{namespace}'?"):
@@ -365,7 +365,7 @@ def remove_configured_worker_pool(resource: Dict):
365
365
  return
366
366
 
367
367
  else:
368
- print_error(f"Cannot find Configured Worker Pool '{fq_name}'")
368
+ print_warning(f"Cannot find Configured Worker Pool '{fq_name}'")
369
369
 
370
370
 
371
371
  def remove_allowance(resource: Dict):
@@ -428,7 +428,7 @@ def remove_resource_by_id(resource_id: str):
428
428
  CLIENT.keyring_client.delete_keyring_by_name(keyring.name)
429
429
  print_log(f"Removed Keyring {resource_id}")
430
430
  return
431
- raise Exception(f"Cannot find Keyring {resource_id}")
431
+ print_warning(f"Cannot find Keyring {resource_id}")
432
432
 
433
433
  elif get_ydid_type(resource_id) == YDIDType.WORKER_POOL:
434
434
  if confirmed(f"Shut down Worker Pool {resource_id}?"):
@@ -497,7 +497,7 @@ def remove_namespace_policy(resource: Dict):
497
497
  return
498
498
  except Exception:
499
499
  # Assume it's not found ... 404 from API
500
- print_error(f"Cannot find Namespace Policy '{namespace}'")
500
+ print_warning(f"Cannot find Namespace Policy '{namespace}'")
501
501
  return
502
502
 
503
503
  if not confirmed(f"Remove Namespace Policy '{namespace}'?"):
@@ -54,7 +54,7 @@ from yellowdog_client.model import (
54
54
 
55
55
  from yellowdog_cli.utils.args import ARGS_PARSER
56
56
  from yellowdog_cli.utils.interactive import confirmed, select
57
- from yellowdog_cli.utils.printing import print_log
57
+ from yellowdog_cli.utils.printing import print_log, print_warning
58
58
  from yellowdog_cli.utils.settings import NAMESPACE_PREFIX_SEPARATOR
59
59
  from yellowdog_cli.utils.ydid_utils import YDIDType, get_ydid_type
60
60
 
@@ -231,6 +231,7 @@ def _find_id_by_name(
231
231
  )
232
232
 
233
233
 
234
+ @lru_cache
234
235
  def find_compute_source_template_id_by_name(
235
236
  client: PlatformClient, name: str
236
237
  ) -> Optional[str]:
@@ -238,7 +239,12 @@ def find_compute_source_template_id_by_name(
238
239
  Find a Compute Source Template id by name.
239
240
  Compute Source Template names are unique within a namespace.
240
241
  """
241
- return _find_id_by_name(name, client, get_compute_source_templates)
242
+ template_id = _find_id_by_name(name, client, get_compute_source_templates)
243
+ if template_id is not None:
244
+ print_log(
245
+ f"Replaced Compute Source Template name '{name}' with ID {template_id}"
246
+ )
247
+ return template_id
242
248
 
243
249
 
244
250
  @lru_cache
@@ -277,8 +283,10 @@ def get_work_requirement_summaries(
277
283
  def clear_compute_source_template_cache():
278
284
  """
279
285
  Clear the cache of Compute Source Templates.
286
+ Clear name -> CST lookups.
280
287
  """
281
288
  get_compute_source_templates.cache_clear()
289
+ find_compute_source_template_id_by_name.cache_clear()
282
290
 
283
291
 
284
292
  def find_compute_requirement_template_id_by_name(
@@ -414,7 +422,7 @@ def find_image_name_or_id(
414
422
  return return_val
415
423
 
416
424
  split_name = image_name_or_id.split("/")
417
- image_family_summaries = get_image_family_summaries(client)
425
+ image_family_summaries = get_image_family_summaries(client) # All namespaces
418
426
 
419
427
  # Search for image name (only) matches
420
428
  if len(split_name) == 1:
@@ -442,6 +450,12 @@ def find_image_name_or_id(
442
450
  # Search for namespace/family_name matches, *or* family_name/group_name matches
443
451
  if len(split_name) == 2:
444
452
  # namespace/family-name match
453
+
454
+ # This will be tidied up when the Application can
455
+ # query its properties
456
+ if len(image_family_summaries) == 0: # Global search didn't work
457
+ image_family_summaries = get_image_family_summaries(client, split_name[0])
458
+
445
459
  matching_image_families = [
446
460
  ifs
447
461
  for ifs in image_family_summaries
@@ -487,6 +501,12 @@ def find_image_name_or_id(
487
501
  # Search for names of form 'namespace/image-family-name/image-group-name'
488
502
  # (the platform prevents duplicates)
489
503
  if len(split_name) == 3:
504
+
505
+ # This will be tidied up when the Application can
506
+ # query its properties
507
+ if len(image_family_summaries) == 0: # Global search didn't work
508
+ image_family_summaries = get_image_family_summaries(client, split_name[0])
509
+
490
510
  for ifs in image_family_summaries:
491
511
  if ifs.namespace == split_name[0] and ifs.name == split_name[1]:
492
512
  for ig in get_image_family_groups(client, ifs.id):
@@ -501,7 +521,7 @@ def find_image_name_or_id(
501
521
  f"group for '{original_image_name_or_id}'"
502
522
  )
503
523
 
504
- # Finally, fall through and return the original ID string
524
+ # Finally, fall through and return the unchanged, original ID string
505
525
  return original_image_name_or_id
506
526
 
507
527
 
@@ -514,7 +534,16 @@ def remove_allowances_matching_description(
514
534
  """
515
535
  allowances = client.allowances_client.get_allowances(
516
536
  AllowanceSearch(description=description)
517
- ).list_all()
537
+ ).list_all() # Can return partial matches
538
+
539
+ # Ensure exact match
540
+ allowances = [
541
+ allowance for allowance in allowances if description == allowance.description
542
+ ]
543
+
544
+ if len(allowances) == 0:
545
+ print_log(f"Cannot find Allowance matching description '{description}'")
546
+ return 0
518
547
 
519
548
  if len(allowances) > 1:
520
549
  print_log(f"Multiple Allowances match the description '{description}'")
@@ -979,17 +1008,31 @@ def get_compute_requirement_summaries(
979
1008
  @lru_cache
980
1009
  def get_image_family_summaries(
981
1010
  client: PlatformClient,
1011
+ namespace: Optional[str] = None,
982
1012
  ) -> List[MachineImageFamilySummary]:
983
1013
  """
984
1014
  Obtain and cache the list of image families.
985
1015
  """
986
- if_search = MachineImageFamilySearch(
987
- familyName=None,
988
- namespaces=None,
989
- includePublic=True,
990
- )
991
- search_client: SearchClient = client.images_client.get_image_families(if_search)
992
- return search_client.list_all()
1016
+ # Temporarily suppress most permission errors: will be improved
1017
+ # once the application can be queried for its admissible
1018
+ # IMAGE_READ namespaces
1019
+ try:
1020
+ if_search = MachineImageFamilySearch(
1021
+ familyName=None,
1022
+ namespaces=None if namespace is None else [namespace],
1023
+ includePublic=True,
1024
+ )
1025
+ search_client: SearchClient = client.images_client.get_image_families(if_search)
1026
+ return search_client.list_all()
1027
+ except Exception as e:
1028
+ if namespace is not None and "MissingPermissionException" in str(e):
1029
+ # Caching will prevent this warning appearing multiple times
1030
+ print_log(
1031
+ "Warning: Possible 'IMAGE_READ' permission missing if "
1032
+ f"'{namespace}' is meant as an Image namespace?"
1033
+ )
1034
+
1035
+ return []
993
1036
 
994
1037
 
995
1038
  @lru_cache
@@ -16,6 +16,7 @@ from typing import Any, Dict, List, Optional, Tuple, Union
16
16
 
17
17
  from rich.console import Console, Theme
18
18
  from rich.highlighter import JSONHighlighter, RegexHighlighter
19
+ from rich.markup import escape
19
20
  from tabulate import tabulate
20
21
  from yellowdog_client import PlatformClient
21
22
  from yellowdog_client.common.json import Json
@@ -192,7 +193,7 @@ def print_simple(
192
193
  if ARGS_PARSER.quiet and override_quiet is False:
193
194
  return
194
195
 
195
- CONSOLE.print(log_message)
196
+ CONSOLE.print(escape(log_message))
196
197
 
197
198
 
198
199
  def print_log(
@@ -211,7 +212,7 @@ def print_log(
211
212
  print(print_string(log_message, no_fill=no_fill), flush=True)
212
213
  return
213
214
 
214
- CONSOLE.print(print_string(log_message, no_fill=no_fill))
215
+ CONSOLE.print(escape(print_string(log_message, no_fill=no_fill)))
215
216
 
216
217
 
217
218
  def print_error(error_obj: Union[Exception, str]):
@@ -222,7 +223,7 @@ def print_error(error_obj: Union[Exception, str]):
222
223
  print(print_string(f"Error: {error_obj}"), flush=True)
223
224
  return
224
225
 
225
- CONSOLE_ERR.print(print_string(f"Error: {error_obj}"), style=ERROR_STYLE)
226
+ CONSOLE_ERR.print(escape(print_string(f"Error: {error_obj}")), style=ERROR_STYLE)
226
227
 
227
228
 
228
229
  def print_warning(
@@ -241,7 +242,8 @@ def print_warning(
241
242
  return
242
243
 
243
244
  CONSOLE.print(
244
- print_string(f"Warning: {warning}", no_fill=no_fill), style=WARNING_STYLE
245
+ escape(print_string(f"Warning: {warning}", no_fill=no_fill)),
246
+ style=WARNING_STYLE,
245
247
  )
246
248
 
247
249
 
@@ -280,7 +282,7 @@ def print_table_core(table: str):
280
282
  if ARGS_PARSER.no_format or table.count("\n") > MAX_LINES_COLOURED_FORMATTING:
281
283
  print(table, flush=True)
282
284
  else:
283
- CONSOLE_TABLE.print(table)
285
+ CONSOLE_TABLE.print(escape(table))
284
286
 
285
287
 
286
288
  def get_type_name(obj: Item) -> str:
@@ -1098,9 +1100,9 @@ def print_json(
1098
1100
 
1099
1101
  else:
1100
1102
  if with_final_comma:
1101
- CONSOLE_JSON.print(json_string, end=",\n", soft_wrap=True)
1103
+ CONSOLE_JSON.print(escape(json_string), end=",\n", soft_wrap=True)
1102
1104
  else:
1103
- CONSOLE_JSON.print(json_string, soft_wrap=True)
1105
+ CONSOLE_JSON.print(escape(json_string), soft_wrap=True)
1104
1106
 
1105
1107
  if ARGS_PARSER.output_file is not None: # Also output to a nominated file
1106
1108
  print_to_file(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yellowdog-python-examples
3
- Version: 8.1.4
3
+ Version: 8.1.6
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
@@ -1 +0,0 @@
1
- __version__ = "8.1.4"