Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
tom-tan opened this issue Oct 2, 2021 · 1 comment
Open

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

tom-tan opened this issue Oct 2, 2021 · 1 comment

Comments

@tom-tan
Copy link
Member

tom-tan commented Oct 2, 2021

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.
@mr-c
Copy link
Member

mr-c commented Aug 3, 2022

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

Yes, that would be welcome, please do so!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants