Hi Kedro team, is it possible when using the omeg...
# questions
m
Hi Kedro team, is it possible when using the omegaconfigloader, to get the parent key name via a custom resolver? something like:
Copy code
breakfast:
	meal_name: ${parent_name:}
lunch:
	meal_name: ${parent_name:}
then breakfast.meal_name would return 'breakfast' my motivation is simple: when namespacing pipelines the parents are part of the namespace, and sometimes I want access to those names in a node - usually just to have a column label. e.g:
Copy code
node(
	func = lambda df, x: df.assign('meal' == x),
	inputs = ["<dataframe output from node above>", "params:meal_name"],
	...
),
I found this for omegaconf, but couldn't make it work for Kedro's omegaconfigloader. https://github.com/omry/omegaconf/discussions/937
h
Someone will reply to you shortly. In the meantime, this might help:
n
I am not so sure since it's not part of the public API, but you can try to copy that resolver and register this in Kedro and try. https://docs.kedro.org/en/stable/configuration/advanced_configuration.html#how-to-use-resolvers-in-the-omegaconfigloader
m
thanks Nok. I did try that first but could get anywhere because having to use the lambda function in the CONFIG_LOADER_ARGS was messing things up. But I managed to make it work using one of the private methods. In case anyone is interested here it is:
Copy code
CONFIG_LOADER_CLASS = OmegaConfigLoader

def parent_name_impl(_parent_) -> str:
    return _parent_._key()

def grandparent_name_impl(_parent_) -> str:
    return _parent_._get_parent()._key()


CONFIG_LOADER_CLASS._register_new_resolvers({"parent_name": parent_name_impl,
                                             "grandparent_name": grandparent_name_impl})
then in the parameters:
Copy code
park:
  playground:
    swing: ${parent_name:} # returns "playground"
    slide: ${grandparent_name:} # returns "park"
n
Good to know, what's exactly is blocking? Btw lambda function is not a requirement.
you can always declare the function first
@minmin I checked again the documentation and I could understand why you think lambda is required. https://docs.kedro.org/en/stable/configuration/advanced_configuration.html#how-to-use-resolvers-in-the-omegaconfigloader instead of
Copy code
def date_today():
    return date.today()


CONFIG_LOADER_ARGS = {
    "custom_resolvers": {
        "add": lambda *my_list: sum(my_list),
        "polars": lambda x: getattr(pl, x),
        "today": lambda: date_today(),
    }
}
The lambda is redundant, what you really need is a dictionary of callable. So it should be:
Copy code
def date_today():
    return date.today()


CONFIG_LOADER_ARGS = {
    "custom_resolvers": {
        "add": lambda *my_list: sum(my_list),
        "polars": lambda x: getattr(pl, x),
        "today": date_today,
    }
}
m
so the function has that "_parent_" input. If I did
"parent_name": lambda: parent_name_impl
kedro would complain that that I was missing a parameter:
TypeError: parent_name_impl() missing 1 required positional argument: '_parent_'
but if I stick in an input:
"parent_name": lambda x: parent_name_impl(x)
that obviously doesn't make any sense because it then expects me to give it an input in the parameters.yml, which then overrides parent completely .......but....... I took your advice and tried it without the lambda and it worked!
Copy code
CONFIG_LOADER_ARGS = {
      "custom_resolvers": {
        "grandparent_name": grandparent_name_impl,
        "parent_name": parent_name_impl,
      },
I always thought you needed the lambda (like you say, it's not super clear from the documentation that that isn't the case) but I am glad this works. Thanks so much for your help with this.
👍🏼 1
n
Nice question btw! I think this would be a common thing that people may want to do.
👍 1