common-workflow-language / common-workflow-language/cwl-utils
[Feature Request] utility function to access nested fields
- 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.