yellowdog-python-examples 7.8.3__tar.gz → 7.8.5__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.8.3/yellowdog_python_examples.egg-info → yellowdog_python_examples-7.8.5}/PKG-INFO +1 -1
  2. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/README.md +13 -7
  3. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/tests/test_demos.py +8 -0
  4. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/tests/test_dryruns.py +13 -0
  5. yellowdog_python_examples-7.8.5/yd_commands/__init__.py +1 -0
  6. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/args.py +3 -2
  7. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/csv_data.py +16 -2
  8. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/interactive.py +12 -2
  9. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/list.py +4 -4
  10. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/printing.py +9 -17
  11. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/settings.py +1 -0
  12. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/submit.py +10 -4
  13. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/submit_utils.py +1 -21
  14. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/utils.py +18 -0
  15. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/variables.py +12 -2
  16. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5/yellowdog_python_examples.egg-info}/PKG-INFO +1 -1
  17. yellowdog-python-examples-7.8.3/yd_commands/__init__.py +0 -1
  18. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/LICENSE +0 -0
  19. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/PYPI_README.md +0 -0
  20. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/pyproject.toml +0 -0
  21. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/requirements.txt +0 -0
  22. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/setup.cfg +0 -0
  23. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/setup.py +0 -0
  24. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/tests/test_create_remove.py +0 -0
  25. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/tests/test_entrypoints.py +0 -0
  26. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/tests/test_gui.py +0 -0
  27. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/tests/test_list.py +0 -0
  28. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/tests/test_objects.py +0 -0
  29. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/tests/test_variable_processing.py +0 -0
  30. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/abort.py +0 -0
  31. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/admin.py +0 -0
  32. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/boost.py +0 -0
  33. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/cancel.py +0 -0
  34. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/check_imports.py +0 -0
  35. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/cloudwizard.py +0 -0
  36. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/cloudwizard_aws.py +0 -0
  37. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/cloudwizard_aws_types.py +0 -0
  38. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/cloudwizard_azure.py +0 -0
  39. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/cloudwizard_common.py +0 -0
  40. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/cloudwizard_gcp.py +0 -0
  41. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/compact_json.py +0 -0
  42. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/config_types.py +0 -0
  43. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/create.py +0 -0
  44. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/delete.py +0 -0
  45. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/download.py +0 -0
  46. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/follow.py +0 -0
  47. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/follow_utils.py +0 -0
  48. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/format_json.py +0 -0
  49. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/hold.py +0 -0
  50. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/id_utils.py +0 -0
  51. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/instantiate.py +0 -0
  52. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/items.py +0 -0
  53. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/jsonnet2json.py +0 -0
  54. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/load_config.py +0 -0
  55. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/load_resources.py +0 -0
  56. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/object_utilities.py +0 -0
  57. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/property_names.py +0 -0
  58. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/provision.py +0 -0
  59. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/provision_utils.py +0 -0
  60. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/remove.py +0 -0
  61. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/resize.py +0 -0
  62. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/shutdown.py +0 -0
  63. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/start.py +0 -0
  64. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/start_hold_common.py +0 -0
  65. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/terminate.py +0 -0
  66. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/type_check.py +0 -0
  67. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/upload.py +0 -0
  68. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/upload_utils.py +0 -0
  69. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/validate_properties.py +0 -0
  70. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/version.py +0 -0
  71. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yd_commands/wrapper.py +0 -0
  72. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yellowdog_python_examples.egg-info/SOURCES.txt +0 -0
  73. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yellowdog_python_examples.egg-info/dependency_links.txt +0 -0
  74. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yellowdog_python_examples.egg-info/entry_points.txt +0 -0
  75. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/yellowdog_python_examples.egg-info/requires.txt +0 -0
  76. {yellowdog-python-examples-7.8.3 → yellowdog_python_examples-7.8.5}/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.8.3
3
+ Version: 7.8.5
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
@@ -132,7 +132,7 @@ The commands provide the following capabilities:
132
132
 
133
133
  - **Provisioning** Worker Pools with the **`yd-provision`** command
134
134
  - **Submitting** Work Requirements with the **`yd-submit`** command
135
- - **Starting** HELD Work Requirements and **Holding** (or pausing) RUNNING Work Requirements
135
+ - **Starting** HELD Work Requirements and **Holding** (or pausing) RUNNING Work Requirements with the **`yd-start`** and **`yd-hold`** commands
136
136
  - **Uploading** files to the YellowDog Object Store with the **`yd-upload`** command
137
137
  - **Instantiating** Compute Requirements with the **`yd-instantiate`** command
138
138
  - **Downloading** Results from the YellowDog Object Store with the **`yd-download`** command
@@ -142,15 +142,17 @@ The commands provide the following capabilities:
142
142
  - **Terminating** Compute Requirements with the **`yd-terminate`** command
143
143
  - **Deleting** objects in the YellowDog Object Store with the **`yd-delete`** command
144
144
  - **Listing** YellowDog items using the **`yd-list`** command
145
- - **Resizing** Worker Pools and Compute Requirements
146
- - **Boosting** Allowances
147
- - **Creating, Updating and Removing** Source Templates, Compute Templates, Keyrings, Credentials, Namespace Storage Configurations, Image Families, Allowances, and Configured Worker Pools
148
- - **Following Event Streams** for Work Requirements, Worker Pools and Compute Requirements
145
+ - **Resizing** Worker Pools and Compute Requirements with the **`yd-resize`** command
146
+ - **Boosting** Allowances with the **`yd-boost`** command
147
+ - **Creating, Updating and Removing** Source Templates, Compute Templates, Keyrings, Credentials, Namespace Storage Configurations, Image Families, Allowances, and Configured Worker Pools with the **`yd-create`** and **`yd-remove`** commands
148
+ - **Following Event Streams** for Work Requirements, Worker Pools and Compute Requirements with the **`yd-follow`** command
149
149
 
150
150
  The operation of the commands is controlled using TOML configuration files and/or environment variables and command line arguments. In addition, Work Requirements and Worker Pools can be defined using JSON files providing extensive configurability.
151
151
 
152
152
  Commands are also provided for the semi-automatic setup of cloud provider accounts for use with YellowDog, and the creation of YellowDog assets to work with these cloud provider accounts. Please see **[Cloud Wizard](README_CLOUDWIZARD.md)** for more details.
153
153
 
154
+ Run any command with the `--help`/`-h` option to discover the command's options.
155
+
154
156
  # YellowDog Prerequisites
155
157
 
156
158
  To submit **Work Requirements** to YellowDog for processing by Configured Worker Pools (on-premise) and/or Provisioned Worker Pools (cloud-provisioned resources), you'll need:
@@ -275,6 +277,10 @@ All entity names used within the YellowDog Platform must comply with the followi
275
277
 
276
278
  These restrictions apply to entities including Namespaces, Tags, Work Requirements, Task Groups, Tasks, Worker Pools, and Compute Requirements, and also apply to entities that are currently used indirectly by these scripts, including Usernames, Credentials, Keyrings, Compute Sources and Compute Templates.
277
279
 
280
+ Later sections of this document describe variable substitutions implemented with user-defined and CSV-file-defined variables. As a type modifier within these substitution expressions, the `format_name:` option is available, and works in the same manner as `num:`, `bool:`, etc. The `format_name:` modifier will convert the substituted string into one that satisfies YellowDog naming, by switching characters to lower case, etc.
281
+
282
+ For example, a variable substitution `{{format_name:ligand_name}}`, with variable `ligand_name` set to `DCCCDE_00000s`, would substitute to become `dcccde_00000s`, and would be acceptable for use as a component of a YellowDog name.
283
+
278
284
  # Common Properties
279
285
 
280
286
  The `[common]` section of the configuration file can contain the following properties:
@@ -1803,7 +1809,7 @@ However, this means that **caution is required** when updating or removing resou
1803
1809
 
1804
1810
  The JSON specification used to define each type of resource can be found by inspecting the YellowDog Platform REST API documentation at https://docs.yellowdog.co/api.
1805
1811
 
1806
- For example, to obtain the JSON schema for creating a Compute Source Template, take a look at the REST API call for adding a new Compute Source template: https://docs.yellowdog.co/api/?spec=Compute%20API#tag/compute/post/compute/templates/sources. This will display an **Example Value**, and an adjacent tab will show the **Schema**.
1812
+ For example, to obtain the JSON schema for creating a Compute Source Template, take a look at the REST API call for adding a new Compute Source template: https://docs.yellowdog.co/api/?spec=Compute%20API#tag/compute/post/compute/templates/sources.
1807
1813
 
1808
1814
  When using the `yd-create` and `yd-remove` commands, note that an additional property `resource` must be supplied, to identify the type of resource being specified. The `"resource"` property can take the following values:
1809
1815
 
@@ -2563,4 +2569,4 @@ It can optionally be supplied with a list of the names and/or YDIDs of the speci
2563
2569
 
2564
2570
  ## yd-boost
2565
2571
 
2566
- The `yd-boost` command is used to boost an Allowance by the specified number of hours.
2572
+ The `yd-boost` command is used to boost Allowances by the specified number of hours.
@@ -53,6 +53,14 @@ class TestDemos:
53
53
  result = shell(f"cd {DEMO_DIR}/cmd.exe && {CMD_SEQ}")
54
54
  assert result.exit_code == 0
55
55
 
56
+ def test_blender(self):
57
+ result = shell(f"cd {DEMO_DIR}/blender && {CMD_SEQ}")
58
+ assert result.exit_code == 0
59
+
60
+ def test_montecarlo(self):
61
+ result = shell(f"cd {DEMO_DIR}/montecarlo && {CMD_SEQ}")
62
+ assert result.exit_code == 0
63
+
56
64
  def test_nextflow_image_montage(self):
57
65
  result = shell(
58
66
  f"cd {DEMO_DIR}/nextflow/image-montage && {NEXTFLOW} main.nf "
@@ -60,6 +60,10 @@ class TestDemoDryRuns:
60
60
  result = shell(f"cd {DEMO_DIR}/blender && {CMD_SEQ}")
61
61
  assert result.exit_code == 0
62
62
 
63
+ def test_montecarlo(self):
64
+ result = shell(f"cd {DEMO_DIR}/montecarlo && {CMD_SEQ}")
65
+ assert result.exit_code == 0
66
+
63
67
  # Tests run from outside the demo directories
64
68
  def test_bash_out(self):
65
69
  demo_name = "bash"
@@ -169,3 +173,12 @@ class TestDemoDryRuns:
169
173
  f" {demo_name}/config.toml"
170
174
  )
171
175
  assert result.exit_code == 0
176
+
177
+ def test_montecarlo_out(self):
178
+ demo_name = "montecarlo"
179
+ result = shell(
180
+ f"cd {DEMO_DIR} && yd-provision -D -c {demo_name}/config.toml && yd-submit"
181
+ f" -D -c {demo_name}/config.toml && yd-instantiate -D -c"
182
+ f" {demo_name}/config.toml"
183
+ )
184
+ assert result.exit_code == 0
@@ -0,0 +1 @@
1
+ __version__ = "7.8.5"
@@ -513,6 +513,7 @@ class CLIParser:
513
513
  )
514
514
  parser.add_argument(
515
515
  "--instances",
516
+ "-i",
516
517
  action="store_true",
517
518
  required=False,
518
519
  help="list compute instances",
@@ -810,8 +811,8 @@ class CLIParser:
810
811
  type=str,
811
812
  required=False,
812
813
  help=(
813
- "the directory in which files for upload (or for user data) are"
814
- " found"
814
+ "the directory in which files for upload (or for user data "
815
+ "or CSV data) are found"
815
816
  ),
816
817
  metavar="<directory>",
817
818
  )
@@ -20,8 +20,10 @@ from yd_commands.settings import (
20
20
  BOOL_TYPE_TAG,
21
21
  CSV_VAR_CLOSING_DELIMITER,
22
22
  CSV_VAR_OPENING_DELIMITER,
23
+ FORMAT_NAME_TYPE_TAG,
23
24
  NUMBER_TYPE_TAG,
24
25
  )
26
+ from yd_commands.utils import format_yd_name
25
27
  from yd_commands.variables import (
26
28
  load_jsonnet_file_with_variable_substitutions,
27
29
  process_variable_substitutions_insitu,
@@ -166,7 +168,7 @@ def load_toml_file_with_csv_task_expansion(
166
168
  with open(resolve_filename(files_directory, toml_file), "r") as f:
167
169
  wr_data = toml_load(f)
168
170
 
169
- return perform_csv_task_expansion(wr_data, csv_files, f)
171
+ return perform_csv_task_expansion(wr_data, csv_files, files_directory)
170
172
 
171
173
 
172
174
  def perform_csv_task_expansion(
@@ -273,6 +275,13 @@ def make_string_substitutions(input: str, var_name: str, value: str) -> str:
273
275
  raise Exception(f"Invalid Boolean substitution in CSV: '{value}'")
274
276
  input = input.replace(f"'{bool_sub_str}'", value)
275
277
 
278
+ lower_sub_str = f"{CSV_VAR_OPENING_DELIMITER}{FORMAT_NAME_TYPE_TAG}{var_name}{CSV_VAR_CLOSING_DELIMITER}"
279
+ if lower_sub_str in input:
280
+ input = input.replace(
281
+ f"{lower_sub_str}",
282
+ format_yd_name(value, add_prefix=False),
283
+ )
284
+
276
285
  return input
277
286
 
278
287
 
@@ -344,6 +353,11 @@ def substitions_present(var_names: List[str], task_prototype: str) -> bool:
344
353
  in task_prototype
345
354
  for var_name in var_names
346
355
  )
356
+ or any(
357
+ f"{CSV_VAR_OPENING_DELIMITER}{FORMAT_NAME_TYPE_TAG}{var_name}{CSV_VAR_CLOSING_DELIMITER}"
358
+ in task_prototype
359
+ for var_name in var_names
360
+ )
347
361
  )
348
362
 
349
363
 
@@ -395,4 +409,4 @@ def csv_expand_toml_tasks(
395
409
  ):
396
410
  task_proto[config_name] = config_value
397
411
 
398
- return perform_csv_task_expansion(wr_data, [csv_file])
412
+ return perform_csv_task_expansion(wr_data, [csv_file], files_directory)
@@ -75,7 +75,7 @@ def select(
75
75
  if single_result
76
76
  else (f"Please select items (e.g.: 1,2,4-7 / *){cancel_string}:")
77
77
  )
78
- selector_string = CONSOLE.input(print_string(input_string) + " ")
78
+ selector_string = _get_user_input(print_string(input_string) + " ")
79
79
  if selector_string.strip() == "*":
80
80
  selector_string = f"1-{len(objects)}"
81
81
  selector_list = selector_string.split(",")
@@ -153,10 +153,20 @@ def confirmed(msg: str) -> bool:
153
153
 
154
154
  # Seek user confirmation
155
155
  while True:
156
- response = CONSOLE.input(print_string(f"{msg} (y/N):") + " ")
156
+ response = _get_user_input(print_string(f"{msg} (y/N):") + " ")
157
157
  if response.lower() in ["y", "yes"]:
158
158
  print_log("Action confirmed by user")
159
159
  return True
160
160
  elif response.lower() in ["n", "no", ""]:
161
161
  print_log("Action cancelled by user")
162
162
  return False
163
+
164
+
165
+ def _get_user_input(input_prompt: str) -> str:
166
+ """
167
+ Get user input, respecting the --no-format option.
168
+ """
169
+ if ARGS_PARSER.no_format:
170
+ return input(input_prompt)
171
+ else:
172
+ return CONSOLE.input(input_prompt)
@@ -46,10 +46,10 @@ from yd_commands.object_utilities import (
46
46
  get_task_groups_from_wr_summary,
47
47
  )
48
48
  from yd_commands.printing import (
49
- CONSOLE_TABLE,
50
49
  indent,
51
50
  print_log,
52
51
  print_numbered_object_list,
52
+ print_table_core,
53
53
  print_yd_object,
54
54
  sorted_objects,
55
55
  )
@@ -525,11 +525,11 @@ def list_namespaces():
525
525
  for index, namespace in enumerate(namespace_list)
526
526
  ]
527
527
  )
528
- print()
529
- CONSOLE_TABLE.print(
528
+ print(flush=True)
529
+ print_table_core(
530
530
  indent(tabulate(rows, headings, tablefmt="simple_outline")),
531
531
  )
532
- print()
532
+ print(flush=True)
533
533
 
534
534
  if ARGS_PARSER.details: # Print the details for non-default only
535
535
  for namespace in select(CLIENT, namespaces_config, showing_all=True):
@@ -495,9 +495,10 @@ def instances_table(
495
495
  ) -> (List[str], List[str]):
496
496
  headers = [
497
497
  "#",
498
- "Type",
499
498
  "Provider",
500
499
  "Instance Type",
500
+ "Hostname",
501
+ "Status",
501
502
  "Private IP",
502
503
  "Public IP",
503
504
  ]
@@ -506,9 +507,10 @@ def instances_table(
506
507
  table.append(
507
508
  [
508
509
  index + 1,
509
- instance.type.split(".")[-1],
510
510
  instance.provider,
511
511
  instance.instanceType,
512
+ instance.hostname,
513
+ instance.status,
512
514
  instance.privateIpAddress,
513
515
  instance.publicIpAddress,
514
516
  ]
@@ -920,22 +922,12 @@ def print_batch_download_files(
920
922
  counter += 1
921
923
 
922
924
  print(flush=True)
923
-
924
- if ARGS_PARSER.no_format:
925
- print(
926
- indent(
927
- tabulate(table, headers=headers, tablefmt="simple_outline"),
928
- indent_width=4,
929
- ),
930
- flush=True,
931
- )
932
- else:
933
- CONSOLE_TABLE.print(
934
- indent(
935
- tabulate(table, headers=headers, tablefmt="simple_outline"),
936
- indent_width=4,
937
- ),
925
+ print_table_core(
926
+ indent(
927
+ tabulate(table, headers=headers, tablefmt="simple_outline"),
928
+ indent_width=4,
938
929
  )
930
+ )
939
931
  print(flush=True)
940
932
  return counter
941
933
 
@@ -31,6 +31,7 @@ NUMBER_TYPE_TAG = "num" + TYPE_TAG_TERMINATOR
31
31
  BOOL_TYPE_TAG = "bool" + TYPE_TAG_TERMINATOR
32
32
  ARRAY_TYPE_TAG = "array" + TYPE_TAG_TERMINATOR
33
33
  TABLE_TYPE_TAG = "table" + TYPE_TAG_TERMINATOR
34
+ FORMAT_NAME_TYPE_TAG = "format_name" + TYPE_TAG_TERMINATOR
34
35
  TOML_VAR_NESTED_DEPTH = 3
35
36
 
36
37
  DEFAULT_LOG_WIDTH = 120
@@ -57,7 +57,6 @@ from yd_commands.settings import (
57
57
  )
58
58
  from yd_commands.submit_utils import (
59
59
  UploadedFiles,
60
- format_yd_name,
61
60
  generate_task_input_list,
62
61
  pause_between_batches,
63
62
  update_config_work_requirement_object,
@@ -71,7 +70,7 @@ from yd_commands.type_check import (
71
70
  check_str,
72
71
  )
73
72
  from yd_commands.upload_utils import unique_upload_pathname
74
- from yd_commands.utils import generate_id, link_entity
73
+ from yd_commands.utils import format_yd_name, generate_id, link_entity
75
74
  from yd_commands.validate_properties import validate_properties
76
75
  from yd_commands.variables import (
77
76
  L_TASK_COUNT,
@@ -156,7 +155,7 @@ def main():
156
155
  if wr_data_file is None and csv_files is not None:
157
156
  wr_data = csv_expand_toml_tasks(CONFIG_WR, csv_files[0], files_directory)
158
157
  submit_work_requirement(
159
- files_directory=CONFIG_FILE_DIR,
158
+ files_directory=files_directory,
160
159
  wr_data=wr_data,
161
160
  )
162
161
 
@@ -1233,7 +1232,7 @@ def create_task(
1233
1232
  args.insert(0, "/c")
1234
1233
  return _make_task(flatten_input_paths)
1235
1234
 
1236
- # Special processing for Docker tasks if the 'executable property is set.
1235
+ # Special processing for Docker tasks if the 'executable' property is set.
1237
1236
  # Sets up the '--env' environment strings and the DockerHub username and
1238
1237
  # password if specified.
1239
1238
  elif task_type == "docker":
@@ -1318,6 +1317,13 @@ def create_task(
1318
1317
  if docker_registry is not None
1319
1318
  else {}
1320
1319
  )
1320
+ env_copy.update(
1321
+ {
1322
+ "DOCKER_IMAGE": executable,
1323
+ }
1324
+ if executable is not None
1325
+ else {}
1326
+ )
1321
1327
  return _make_task(flatten_input_paths)
1322
1328
 
1323
1329
  else:
@@ -2,7 +2,6 @@
2
2
  Utility functions for use with the submit command.
3
3
  """
4
4
 
5
- import re
6
5
  from dataclasses import dataclass
7
6
  from glob import glob
8
7
  from os import chdir, getcwd
@@ -14,7 +13,7 @@ from yellowdog_client import PlatformClient
14
13
  from yellowdog_client.model import ObjectPath, TaskInput, TaskInputVerification
15
14
 
16
15
  from yd_commands.config_types import ConfigCommon, ConfigWorkRequirement
17
- from yd_commands.printing import print_error, print_log, print_warning
16
+ from yd_commands.printing import print_error, print_log
18
17
  from yd_commands.settings import NAMESPACE_PREFIX_SEPARATOR
19
18
  from yd_commands.upload_utils import unique_upload_pathname, upload_file_core
20
19
  from yd_commands.variables import process_variable_substitutions_insitu
@@ -239,25 +238,6 @@ class UploadedFiles:
239
238
  self._uploaded_files = []
240
239
 
241
240
 
242
- def format_yd_name(yd_name: str) -> str:
243
- """
244
- Format a string to be consistent with YellowDog naming requirements.
245
- """
246
- # Make obvious substitutions
247
- new_yd_name = yd_name.replace("/", "-").replace(" ", "_").lower()
248
- # Enforce acceptable regex, starting character and name length
249
- new_yd_name = re.sub("[^a-z0-9_-]", "", new_yd_name)
250
- if not new_yd_name[0].isalpha():
251
- new_yd_name = f"yd_{new_yd_name}"
252
- new_yd_name = new_yd_name[:60]
253
- if new_yd_name != yd_name:
254
- print_warning(
255
- f"Changing name '{yd_name}' to '{new_yd_name}' to comply with YellowDog"
256
- " naming requirements"
257
- )
258
- return new_yd_name
259
-
260
-
261
241
  def update_config_work_requirement_object(
262
242
  config_wr: ConfigWorkRequirement,
263
243
  ) -> ConfigWorkRequirement:
@@ -218,3 +218,21 @@ def remove_outer_delimiters(
218
218
  return input_string.replace(f"{opening_delimiter}", "", 1)[::-1].replace(
219
219
  f"{closing_delimiter[::-1]}", "", 1
220
220
  )[::-1]
221
+
222
+
223
+ def format_yd_name(yd_name: str, add_prefix: bool = True) -> str:
224
+ """
225
+ Format a string to be consistent with YellowDog naming requirements.
226
+ """
227
+ # Make obvious substitutions
228
+ new_yd_name = yd_name.replace("/", "-").replace(" ", "_").lower()
229
+
230
+ # Enforce acceptable regex
231
+ new_yd_name = re.sub("[^a-z0-9_-]", "", new_yd_name)
232
+
233
+ # Must start with an alphabetic character
234
+ if add_prefix and not new_yd_name[0].isalpha():
235
+ new_yd_name = f"y{new_yd_name}"
236
+
237
+ # Mustn't exceed 60 chars
238
+ return new_yd_name[:60]
@@ -22,6 +22,7 @@ from yd_commands.settings import (
22
22
  ARRAY_TYPE_TAG,
23
23
  BOOL_TYPE_TAG,
24
24
  ENV_VAR_PREFIX,
25
+ FORMAT_NAME_TYPE_TAG,
25
26
  NUMBER_TYPE_TAG,
26
27
  RAND_VAR_SIZE,
27
28
  TABLE_TYPE_TAG,
@@ -33,7 +34,12 @@ from yd_commands.settings import (
33
34
  WP_VARIABLES_POSTFIX,
34
35
  WP_VARIABLES_PREFIX,
35
36
  )
36
- from yd_commands.utils import UTCNOW, remove_outer_delimiters, split_delimited_string
37
+ from yd_commands.utils import (
38
+ UTCNOW,
39
+ format_yd_name,
40
+ remove_outer_delimiters,
41
+ split_delimited_string,
42
+ )
37
43
 
38
44
  # Set up default variable substitutions
39
45
  VARIABLE_SUBSTITUTIONS = {
@@ -185,7 +191,8 @@ def process_variable_substitutions(
185
191
  type_tag = (
186
192
  re.match(
187
193
  f"^{opening_delimiter}({NUMBER_TYPE_TAG}|{BOOL_TYPE_TAG}"
188
- f"|{TABLE_TYPE_TAG}|{ARRAY_TYPE_TAG})(?!{TAG_DEFAULT_DIFF})",
194
+ f"|{TABLE_TYPE_TAG}|{ARRAY_TYPE_TAG}|{FORMAT_NAME_TYPE_TAG})"
195
+ f"(?!{TAG_DEFAULT_DIFF})",
189
196
  element,
190
197
  )
191
198
  .group(0)
@@ -313,6 +320,9 @@ def process_typed_variable_substitution(
313
320
  Process a single typed substitution, returning the appropriate type.
314
321
  Assumes there is a substitution present.
315
322
  """
323
+ if type_string == FORMAT_NAME_TYPE_TAG:
324
+ return format_yd_name(input_string, add_prefix=False)
325
+
316
326
  if type_string == NUMBER_TYPE_TAG:
317
327
  try:
318
328
  return int(input_string)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: yellowdog-python-examples
3
- Version: 7.8.3
3
+ Version: 7.8.5
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.8.3"