Skip to content

[Feature Request] utility function to access nested fields #106

@tom-tan

Description

@tom-tan

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:

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:

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) 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 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 for associative arrays.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions