common-workflow-language / common-workflow-language/cwl-utils

[Feature Request] utility function to access nested fields

Ouverte
#106 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub
Langage dominant
Python
Étoiles
43
Forks
28
Merge moyen
4 h 7 min
PR mergées (30 j)
4

Description

# Motivation
I want to check the existence of `DockerRequirement` and get the `DockerRequirement` object from a given CWL object obtained by `load_document`.
Similar situations happen in the case of `outputs.output_file.outputBinding.glob` and `inputs.input_file.inputBinding.position`, for example.

In the current situation, we can do it with the following steps (`cwl_obj` is a CWL object obtained by `load_document`):
- check `cwl_obj.requirements` is not `None`,
- get `cwl_obj.requirements` as an array,
- search for the element with `class: DockerRequirement`, and
- return it

Here is a pseudo code for it:
```python
if cwl_obj.requirements is None:
print("DockerRequirement is not provided")
return None

reqs = cwl_obj.requirements

# Note: even if the CWL document uses a map notation for `requirements`, it is converted into an array notation due to `mapPredicate`
assert isinstance(reqs, MutableSequence)

results = list(filter(lambda r: r.class_ == "DockerRequirement", reqs))
if not results:
print("DockerRequirement is not provided")
return None

return results[0]
```

Of course it works well.
However, it looks like a complicated code even though what I want to do is a simple task.
A simple task should be represented as a simple code, IMO.

# Proposal
It would be nice if cwl-utils provides handy ways to access nested fields in a given CWL object.
For example:

```python
docker_req = dig(cwl_obj, attrs = ["requirements", "DockerRequirement"], default = None)
if docker_req is None:
print("DockerRequirement is not provided")
return None
return docker_req
```

In this example, the `dig` function (its name comes from [Ruby](https://docs.ruby-lang.org/en/3.0.0/Hash.html#method-i-dig)) takes:
- a CWL object to be accessed
- attribute names to be checked and to be accessed recursively
- a default value

It returns a `DockerRequirement` object if there exists `requirements.DockerRequirement` in a given CWL object or returns the default value (i.e., `None`) in other cases (e.g., `requirements` is not provided or no `DockerRequirement` is specified in the object).

If it is OK to add such functions to cwl-utils, I will send a pull request for it.

Notes:
- It would be nice if `dig` can take care of [identifier map](https://www.commonwl.org/v1.2/CommandLineTool.html#map) fields. A problem is that the CWL classes generated by `schema-salad-tool --codegen` lack this information.
- Clojure has a similar function named [get-in](https://clojuredocs.org/clojure.core/get-in) for associative arrays.

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.