cloudos-cli 2.95.0__tar.gz → 2.96.0__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. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/PKG-INFO +20 -2
  2. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/README.md +19 -1
  3. cloudos_cli-2.96.0/cloudos_cli/_version.py +1 -0
  4. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/jobs/cli.py +7 -2
  5. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/jobs/job.py +170 -44
  6. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli.egg-info/PKG-INFO +20 -2
  7. cloudos_cli-2.95.0/cloudos_cli/_version.py +0 -1
  8. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/LICENSE +0 -0
  9. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/__init__.py +0 -0
  10. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/__main__.py +0 -0
  11. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/bash/__init__.py +0 -0
  12. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/bash/cli.py +0 -0
  13. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/clos.py +0 -0
  14. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/configure/__init__.py +0 -0
  15. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/configure/cli.py +0 -0
  16. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/configure/configure.py +0 -0
  17. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/constants.py +0 -0
  18. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/cost/__init__.py +0 -0
  19. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/cost/cost.py +0 -0
  20. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/cromwell/__init__.py +0 -0
  21. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/cromwell/cli.py +0 -0
  22. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/datasets/__init__.py +0 -0
  23. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/datasets/cli.py +0 -0
  24. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/datasets/datasets.py +0 -0
  25. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/import_wf/__init__.py +0 -0
  26. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/import_wf/import_wf.py +0 -0
  27. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/interactive_session/__init__.py +0 -0
  28. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/interactive_session/cli.py +0 -0
  29. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/interactive_session/interactive_session.py +0 -0
  30. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/interactive_session/link.py +0 -0
  31. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/jobs/__init__.py +0 -0
  32. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/logging/__init__.py +0 -0
  33. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/logging/logger.py +0 -0
  34. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/procurement/__init__.py +0 -0
  35. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/procurement/cli.py +0 -0
  36. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/procurement/images.py +0 -0
  37. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/projects/__init__.py +0 -0
  38. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/projects/cli.py +0 -0
  39. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/queue/__init__.py +0 -0
  40. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/queue/cli.py +0 -0
  41. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/queue/queue.py +0 -0
  42. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/related_analyses/__init__.py +0 -0
  43. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/related_analyses/related_analyses.py +0 -0
  44. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/utils/__init__.py +0 -0
  45. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/utils/array_job.py +0 -0
  46. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/utils/cli_helpers.py +0 -0
  47. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/utils/cloud.py +0 -0
  48. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/utils/details.py +0 -0
  49. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/utils/errors.py +0 -0
  50. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/utils/last_wf.py +0 -0
  51. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/utils/nextflow_version.py +0 -0
  52. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/utils/requests.py +0 -0
  53. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/utils/resources.py +0 -0
  54. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/workflows/__init__.py +0 -0
  55. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli/workflows/cli.py +0 -0
  56. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli.egg-info/SOURCES.txt +0 -0
  57. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli.egg-info/dependency_links.txt +0 -0
  58. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli.egg-info/entry_points.txt +0 -0
  59. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli.egg-info/requires.txt +0 -0
  60. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/cloudos_cli.egg-info/top_level.txt +0 -0
  61. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/setup.cfg +0 -0
  62. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/setup.py +0 -0
  63. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/__init__.py +0 -0
  64. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/functions_for_pytest.py +0 -0
  65. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_cli_project_create.py +0 -0
  66. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_cost/__init__.py +0 -0
  67. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_cost/test_job_cost.py +0 -0
  68. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_details.py +0 -0
  69. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_error_messages.py +0 -0
  70. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_interactive_session/__init__.py +0 -0
  71. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_interactive_session/test_create_session.py +0 -0
  72. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_interactive_session/test_link_error_handling.py +0 -0
  73. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_interactive_session/test_link_session.py +0 -0
  74. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_interactive_session/test_list_sessions.py +0 -0
  75. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_interactive_session/test_normalize_path.py +0 -0
  76. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_logging/__init__.py +0 -0
  77. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_logging/test_logger.py +0 -0
  78. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_nextflow_version.py +0 -0
  79. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_related_analyses/__init__.py +0 -0
  80. {cloudos_cli-2.95.0 → cloudos_cli-2.96.0}/tests/test_related_analyses/test_related_analyses.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudos_cli
3
- Version: 2.95.0
3
+ Version: 2.96.0
4
4
  Summary: Python package for interacting with the Lifebit Platform
5
5
  Home-page: https://github.com/lifebit-ai/cloudos-cli
6
6
  Author: David Piñeyro
@@ -609,7 +609,7 @@ First, configure your local environment to ease parameter input. We will try to
609
609
  cloudos job run --profile my_profile --workflow-name rnatoy --job-config cloudos_cli/examples/rnatoy.config --resumable
610
610
  ```
611
611
 
612
- As you can see, a file with the job parameters is used to configure the job. This file could be a regular `nextflow.config` file or any file with the following structure:
612
+ As you can see, a file with the job parameters is used to configure the job. This file is a list of the parameters to pass to your job, and nothing else. It has the following structure:
613
613
 
614
614
  ```
615
615
  params {
@@ -618,6 +618,24 @@ params {
618
618
  }
619
619
  ```
620
620
 
621
+ `--job-config` is shorthand for repeating `--parameter` on the command line: the CLI reads the file line by line, splits each line on the first `=`, and sends each result as one named parameter.
622
+
623
+ Every value is passed through as text, exactly as it would be when launching Nextflow from the command line.
624
+
625
+ > **IMPORTANT: `[ ]` is not expanded into a Nextflow list.** In a real `nextflow.config`, `my_param = ['a', 'b']` gives the pipeline a list of two items. Through `--job-config` it gives the pipeline the *string* `[a,b]`. The line is accepted and the job is submitted, so this fails silently at the point where your pipeline tries to iterate over the value. The CLI prints a warning when it sees a value that looks like a list, showing exactly what the pipeline will receive.
626
+
627
+ To pass a genuine list, define it in the pipeline's own `nextflow.config` in the git repository, or use `--params-file` with a JSON or YAML file (see below), which preserves types.
628
+
629
+ What a `--job-config` file cannot contain, because it is **not** a `nextflow.config` file:
630
+
631
+ - values spanning several lines
632
+ - nested blocks (e.g. `genomes { ... }`)
633
+ - `process`, `profiles`, `docker` or other config sections
634
+
635
+ Comments are supported, both on their own line and after a value, using `//` or `#`.
636
+
637
+ If a parameter needs a genuinely structured value rather than a string, either define it in the pipeline's own `nextflow.config` in the git repository and expose the parts you want to change as individual parameters, or pass it with `--params-file` (see below), which supports JSON and YAML with full type fidelity.
638
+
621
639
  In addition, parameters can also be specified using the command-line `-p` or `--parameter`. For instance:
622
640
 
623
641
  ```bash
@@ -574,7 +574,7 @@ First, configure your local environment to ease parameter input. We will try to
574
574
  cloudos job run --profile my_profile --workflow-name rnatoy --job-config cloudos_cli/examples/rnatoy.config --resumable
575
575
  ```
576
576
 
577
- As you can see, a file with the job parameters is used to configure the job. This file could be a regular `nextflow.config` file or any file with the following structure:
577
+ As you can see, a file with the job parameters is used to configure the job. This file is a list of the parameters to pass to your job, and nothing else. It has the following structure:
578
578
 
579
579
  ```
580
580
  params {
@@ -583,6 +583,24 @@ params {
583
583
  }
584
584
  ```
585
585
 
586
+ `--job-config` is shorthand for repeating `--parameter` on the command line: the CLI reads the file line by line, splits each line on the first `=`, and sends each result as one named parameter.
587
+
588
+ Every value is passed through as text, exactly as it would be when launching Nextflow from the command line.
589
+
590
+ > **IMPORTANT: `[ ]` is not expanded into a Nextflow list.** In a real `nextflow.config`, `my_param = ['a', 'b']` gives the pipeline a list of two items. Through `--job-config` it gives the pipeline the *string* `[a,b]`. The line is accepted and the job is submitted, so this fails silently at the point where your pipeline tries to iterate over the value. The CLI prints a warning when it sees a value that looks like a list, showing exactly what the pipeline will receive.
591
+
592
+ To pass a genuine list, define it in the pipeline's own `nextflow.config` in the git repository, or use `--params-file` with a JSON or YAML file (see below), which preserves types.
593
+
594
+ What a `--job-config` file cannot contain, because it is **not** a `nextflow.config` file:
595
+
596
+ - values spanning several lines
597
+ - nested blocks (e.g. `genomes { ... }`)
598
+ - `process`, `profiles`, `docker` or other config sections
599
+
600
+ Comments are supported, both on their own line and after a value, using `//` or `#`.
601
+
602
+ If a parameter needs a genuinely structured value rather than a string, either define it in the pipeline's own `nextflow.config` in the git repository and expose the parts you want to change as individual parameters, or pass it with `--params-file` (see below), which supports JSON and YAML with full type fidelity.
603
+
586
604
  In addition, parameters can also be specified using the command-line `-p` or `--parameter`. For instance:
587
605
 
588
606
  ```bash
@@ -0,0 +1 @@
1
+ __version__ = '2.96.0'
@@ -62,8 +62,13 @@ def job():
62
62
  help=('When the workflows are duplicated, use the latest imported workflow (by date).'),
63
63
  is_flag=True)
64
64
  @click.option('--job-config',
65
- help=('A config file similar to a nextflow.config file, ' +
66
- 'but only with the parameters to use with your job.'))
65
+ help=('A file listing the parameters to use with your job, as ' +
66
+ '\'name = value\' pairs inside a \'params\' block. It is ' +
67
+ 'equivalent to repeating --parameter, so only flat ' +
68
+ 'parameters are supported: it is not a nextflow.config ' +
69
+ 'and cannot contain multi-line parameters, nested blocks or sections ' +
70
+ 'such as \'process\' and \'profiles\'. Use --params-file ' +
71
+ 'for parameters that need a structured value.'))
67
72
  @click.option('--params-file',
68
73
  help=('A file containing the parameters to pass to the job call. ' +
69
74
  'It should be a .json or .yaml file with a dictionary structure ' +
@@ -176,6 +176,167 @@ class Job(Cloudos):
176
176
  else:
177
177
  raise ValueError(f'No {name} element in {resource} was found')
178
178
 
179
+ @staticmethod
180
+ def strip_inline_comment(line):
181
+ """Remove a trailing '//' or '#' comment from a job config line.
182
+
183
+ Only comments preceded by whitespace are removed, so that values
184
+ containing these characters, such as 's3://bucket/key', are preserved.
185
+
186
+ Parameters
187
+ ----------
188
+ line : string
189
+ A single raw line from a job config file.
190
+
191
+ Returns
192
+ -------
193
+ string
194
+ The line with any trailing comment removed.
195
+ """
196
+ return re.sub(r'\s+(?://|#).*$', '', line)
197
+
198
+ @staticmethod
199
+ def list_literal_warning(p_name, p_value):
200
+ """Build a warning for a value that looks like a list but is sent as text.
201
+
202
+ A '[a, b]' literal in a job config file is not expanded into a Nextflow
203
+ list: every job config value is sent as text. Users coming from real
204
+ nextflow.config files expect the expansion, so warn and show the value
205
+ the pipeline actually receives.
206
+
207
+ Parameters
208
+ ----------
209
+ p_name : string
210
+ The parameter name.
211
+ p_value : string
212
+ The parameter value, as it will be sent.
213
+
214
+ Returns
215
+ -------
216
+ string or None
217
+ The warning message, or None if the value is not a list literal.
218
+ """
219
+ if not (p_value.startswith('[') and p_value.endswith(']')):
220
+ return None
221
+ elements = [e for e in p_value[1:-1].split(',') if len(e) > 0]
222
+ element_noun = 'element' if len(elements) == 1 else 'elements'
223
+ listed = ', '.join(f"'{e}'" for e in elements) if elements else 'nothing'
224
+ return (f"Warning: parameter '{p_name}' looks like a list of "
225
+ f"{len(elements)} {element_noun} ({listed}), but every "
226
+ '--job-config value is sent as text.\n'
227
+ f"\tThe pipeline will receive the string --{p_name} '{p_value}', "
228
+ 'not a Nextflow list of '
229
+ f'{len(elements)} {element_noun}.\n'
230
+ "\tTo pass a real list, define it in the pipeline's own "
231
+ 'nextflow.config, or use --params-file with a JSON or YAML file.')
232
+
233
+ @staticmethod
234
+ def parse_job_config_params(job_config, workflow_type='nextflow'):
235
+ """Parse a job config file into a list of (name, value) parameter pairs.
236
+
237
+ The job config file is a list of parameters, equivalent to repeating
238
+ '--parameter name=value' on the command line. Every value is sent as
239
+ text, exactly as when launching Nextflow from the command line, so a
240
+ literal such as "['a', 'b']" is passed through as a string. Values
241
+ spanning several lines and nested blocks cannot be represented.
242
+
243
+ Parameters
244
+ ----------
245
+ job_config : string
246
+ Path to the job config file.
247
+ workflow_type : string
248
+ The type of workflow to run. Quotes are kept for 'wdl' workflows.
249
+
250
+ Returns
251
+ -------
252
+ list
253
+ A list of (name, value) tuples, in file order.
254
+
255
+ Raises
256
+ ------
257
+ ValueError
258
+ If the file has no 'params' block, if the block is opened and closed
259
+ on the same line, or if a line inside the block is not a
260
+ 'name = value' pair, has a value spanning several lines, or has no
261
+ value at all. Every message reports the offending line, and all but
262
+ the missing block report its line number.
263
+
264
+ Notes
265
+ -----
266
+ A value that looks like a list is parsed and returned, but prints a
267
+ warning first, since it is sent as text rather than as a Nextflow list.
268
+ The warning is skipped for 'wdl' workflows.
269
+ """
270
+ parsed = []
271
+ with open(job_config, 'r') as p:
272
+ reading = False
273
+ found_params_block = False
274
+ for line_no, p_l in enumerate(p, start=1):
275
+ if re.match(r'^\s*params\s*\{', p_l, re.IGNORECASE):
276
+ found_params_block = True
277
+ reading = True
278
+ remainder = Job.strip_inline_comment(p_l).split('{', 1)[1].strip()
279
+ if len(remainder) > 0 and remainder[0] not in ('/', '#'):
280
+ raise ValueError(
281
+ f'Could not parse line {line_no} of {job_config}: ' +
282
+ f'"{p_l.strip()}". The \'params\' block must span ' +
283
+ 'several lines, with one \'name = value\' pair per ' +
284
+ 'line.')
285
+ continue
286
+ if not reading:
287
+ continue
288
+ p_l_no_comment = Job.strip_inline_comment(p_l)
289
+ if workflow_type == 'wdl':
290
+ p_l_strip = p_l_no_comment.strip().replace(' ', '')
291
+ else:
292
+ p_l_strip = p_l_no_comment.strip().replace(
293
+ ' ', '').replace('\"', '').replace('\'', '')
294
+ if len(p_l_strip) == 0:
295
+ continue
296
+ elif p_l_strip[0] in ('/', '#', '*'):
297
+ continue
298
+ elif p_l_strip == '}':
299
+ reading = False
300
+ continue
301
+ p_list = p_l_strip.split('=')
302
+ if len(p_list) < 2:
303
+ raise ValueError(
304
+ f'Could not parse line {line_no} of {job_config}: ' +
305
+ f'"{p_l.strip()}". Expected a \'name = value\' pair. ' +
306
+ 'The job config file is a list of parameters, not a ' +
307
+ 'Nextflow config: it cannot contain values spanning ' +
308
+ 'several lines, nested blocks, or sections such as ' +
309
+ '\'process\' and \'profiles\'.')
310
+ p_name = p_list[0]
311
+ p_value = '='.join(p_list[1:])
312
+ if p_value.count('[') > p_value.count(']'):
313
+ raise ValueError(
314
+ f'Could not parse line {line_no} of {job_config}: ' +
315
+ f'"{p_l.strip()}". Values spanning several lines are ' +
316
+ 'not supported. Keep the value on a single line, ' +
317
+ 'define it in the pipeline\'s own nextflow.config, ' +
318
+ 'or pass it with --params-file using a JSON or YAML ' +
319
+ 'file.')
320
+ if len(p_value) == 0:
321
+ raise ValueError(
322
+ f'Could not parse line {line_no} of {job_config}: ' +
323
+ f'"{p_l.strip()}". Parameter \'{p_name}\' has no ' +
324
+ 'value. Give it a value, or remove the line. A value ' +
325
+ 'that starts with \'//\' or \'#\' must be quoted, ' +
326
+ 'otherwise it is read as a comment.')
327
+ if workflow_type != 'wdl':
328
+ warning = Job.list_literal_warning(p_name, p_value)
329
+ if warning is not None:
330
+ click.secho(warning, fg='yellow', bold=True)
331
+ parsed.append((p_name, p_value))
332
+ if not found_params_block:
333
+ raise ValueError(
334
+ f'No \'params\' block was found in {job_config}. ' +
335
+ 'The parameters must be listed inside a \'params { ... }\' ' +
336
+ 'block, one \'name = value\' pair per line. The ' +
337
+ '\'params.name = value\' form is not supported.')
338
+ return parsed
339
+
179
340
  def build_parameters_file_payload(self, params_file):
180
341
  """Build the parametersFile payload for a params file path."""
181
342
  if params_file is None:
@@ -323,12 +484,12 @@ class Job(Cloudos):
323
484
  command,
324
485
  cpus,
325
486
  memory):
326
- """Converts a nextflow.config file into a json formatted dict.
487
+ """Converts a job config file into a json formatted dict.
327
488
 
328
489
  Parameters
329
490
  ----------
330
491
  job_config : string
331
- Path to a nextflow.config file with parameters scope.
492
+ Path to a file with parameters scope.
332
493
  params_file : string
333
494
  S3 or File Explorer path to a JSON/YAML file with Nextflow parameters.
334
495
  parameter : tuple
@@ -422,47 +583,12 @@ class Job(Cloudos):
422
583
  raise ValueError('No --job-config or --parameter were provided. At least one of ' +
423
584
  'these are required for WDL workflows.')
424
585
  if job_config is not None:
425
- with open(job_config, 'r') as p:
426
- reading = False
427
- for p_l in p:
428
- if 'params' in p_l.lower():
429
- reading = True
430
- else:
431
- if reading:
432
- if workflow_type == 'wdl':
433
- p_l_strip = p_l.strip().replace(
434
- ' ', '')
435
- else:
436
- p_l_strip = p_l.strip().replace(
437
- ' ', '').replace('\"', '').replace('\'', '')
438
- if len(p_l_strip) == 0:
439
- continue
440
- elif p_l_strip[0] == '/' or p_l_strip[0] == '#':
441
- continue
442
- elif p_l_strip == '}':
443
- reading = False
444
- else:
445
- p_list = p_l_strip.split('=')
446
- p_name = p_list[0]
447
- p_value = '='.join(p_list[1:])
448
- if len(p_list) < 2:
449
- raise ValueError('Please, specify your ' +
450
- 'parameters in ' +
451
- f'{job_config} using ' +
452
- 'the \'=\' as spacer. ' +
453
- 'E.g: name = my_name')
454
- elif workflow_type == 'wdl':
455
- param = {"prefix": "",
456
- "name": p_name,
457
- "parameterKind": "textValue",
458
- "textValue": p_value}
459
- workflow_params.append(param)
460
- else:
461
- param = {"prefix": "--",
462
- "name": p_name,
463
- "parameterKind": "textValue",
464
- "textValue": p_value}
465
- workflow_params.append(param)
586
+ p_prefix = "" if workflow_type == 'wdl' else "--"
587
+ for p_name, p_value in Job.parse_job_config_params(job_config, workflow_type):
588
+ workflow_params.append({"prefix": p_prefix,
589
+ "name": p_name,
590
+ "parameterKind": "textValue",
591
+ "textValue": p_value})
466
592
  if len(workflow_params) == 0:
467
593
  raise ValueError(f'The {job_config} file did not contain any ' +
468
594
  'valid parameter')
@@ -611,7 +737,7 @@ class Job(Cloudos):
611
737
  Parameters
612
738
  ----------
613
739
  job_config : string
614
- Path to a nextflow.config file with parameters scope.
740
+ Path to a file with parameters scope.
615
741
  params_file : string
616
742
  S3 or File Explorer path to a JSON/YAML file with Nextflow parameters.
617
743
  parameter : tuple
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudos_cli
3
- Version: 2.95.0
3
+ Version: 2.96.0
4
4
  Summary: Python package for interacting with the Lifebit Platform
5
5
  Home-page: https://github.com/lifebit-ai/cloudos-cli
6
6
  Author: David Piñeyro
@@ -609,7 +609,7 @@ First, configure your local environment to ease parameter input. We will try to
609
609
  cloudos job run --profile my_profile --workflow-name rnatoy --job-config cloudos_cli/examples/rnatoy.config --resumable
610
610
  ```
611
611
 
612
- As you can see, a file with the job parameters is used to configure the job. This file could be a regular `nextflow.config` file or any file with the following structure:
612
+ As you can see, a file with the job parameters is used to configure the job. This file is a list of the parameters to pass to your job, and nothing else. It has the following structure:
613
613
 
614
614
  ```
615
615
  params {
@@ -618,6 +618,24 @@ params {
618
618
  }
619
619
  ```
620
620
 
621
+ `--job-config` is shorthand for repeating `--parameter` on the command line: the CLI reads the file line by line, splits each line on the first `=`, and sends each result as one named parameter.
622
+
623
+ Every value is passed through as text, exactly as it would be when launching Nextflow from the command line.
624
+
625
+ > **IMPORTANT: `[ ]` is not expanded into a Nextflow list.** In a real `nextflow.config`, `my_param = ['a', 'b']` gives the pipeline a list of two items. Through `--job-config` it gives the pipeline the *string* `[a,b]`. The line is accepted and the job is submitted, so this fails silently at the point where your pipeline tries to iterate over the value. The CLI prints a warning when it sees a value that looks like a list, showing exactly what the pipeline will receive.
626
+
627
+ To pass a genuine list, define it in the pipeline's own `nextflow.config` in the git repository, or use `--params-file` with a JSON or YAML file (see below), which preserves types.
628
+
629
+ What a `--job-config` file cannot contain, because it is **not** a `nextflow.config` file:
630
+
631
+ - values spanning several lines
632
+ - nested blocks (e.g. `genomes { ... }`)
633
+ - `process`, `profiles`, `docker` or other config sections
634
+
635
+ Comments are supported, both on their own line and after a value, using `//` or `#`.
636
+
637
+ If a parameter needs a genuinely structured value rather than a string, either define it in the pipeline's own `nextflow.config` in the git repository and expose the parts you want to change as individual parameters, or pass it with `--params-file` (see below), which supports JSON and YAML with full type fidelity.
638
+
621
639
  In addition, parameters can also be specified using the command-line `-p` or `--parameter`. For instance:
622
640
 
623
641
  ```bash
@@ -1 +0,0 @@
1
- __version__ = '2.95.0'
File without changes
File without changes
File without changes