0

I have a very similar structure and scenario to this question and it help me a lot, but I'm looking for a more specific situation, I wanna include to my yaml file just a data from another yaml file, not the complete file. Something like:

UPDATED: I correct the structure of files below to describe properly my scenario, sorry.

foo.yaml

a: 1
b:
    - 1.43
    - 543.55
    - item : !include {I wanna just the [1, 2, 3] from} bar.yaml

bar.yaml

- 3.6
- [1, 2, 3]

Right now, I'm importing all the second file, but I don't need all and don't figure it out the proper solution since yesterday. Below is my actual structure:

foo.yaml

variables: !include bar.yaml #I'm importing the entire file for now and have to navegate in that to get what I need.
a: 1
b:
    - 1.43
    - 543.55
WyllianNeo
  • 341
  • 4
  • 14
  • YAML is not a programming language, and `!include` is not a standard tag. You can program something yourself with a custom constructor: https://pyyaml.org/wiki/PyYAMLDocumentation – tinita Sep 15 '20 at 10:05
  • Thanks for the tip, I'll look if the link can give me the correct way to solve that, and then awnser you =D – WyllianNeo Sep 15 '20 at 10:07
  • Thanks for the tip, I have looked this documentation before, and tried to use the sugested way (yaml_load.SafeLoader), but does not work properly to my code. I'll read again, maybe now it makes a little more sense to me. – WyllianNeo Sep 15 '20 at 10:42

1 Answers1

2

You can write your own custom include constructor:


bar_yaml = """
- 3.6
- [1, 2, 3]
"""

foo_yaml = """
variables: !include [bar.yaml, 1]
a: 1
b:
    - 1.43
    - 543.55
"""

def include_constructor(loader, node):
  selector = loader.construct_sequence(node)
  name = selector.pop(0)
  # in actual code, load the file named by name.
  # for this example, we'll ignore the name and load the predefined string
  content = yaml.safe_load(bar_yaml)
  # walk over the selector items and descend into the loaded structure each time.
  for item in selector:
    content = content[item]
  return content

yaml.add_constructor('!include', include_constructor, Loader=yaml.SafeLoader)

print(yaml.safe_load(foo_yaml))

This !include will treat the first item in the given sequence as file name and the following items as sequence indexes (or dictionary keys). E.g. you can do !include [bar.yaml, 1, 2] to only load the 3.

flyx
  • 35,506
  • 7
  • 89
  • 126
  • Hi flyx, thanks for the tip. Actually I use something really similar, but I see my question was not properly clear, so I updated. I wanna know if is possible to get the just part of data from a child yaml in a subitem on the main yaml. Have you seem or tried somethink like that? I don't see any examples in the searchs I'm doing. – WyllianNeo Sep 16 '20 at 11:06
  • How does writing `!include [bar.yaml, 1]` using the code I posted not solve your updated question? – flyx Sep 16 '20 at 11:13