0

In pyhocon can is it possible to include a file in runtime?

I know how to merge trees in runtime e.g.

conf = ConfigFactory.parse_file(conf_file)
conf1 = ConfigFactory.parse_file(include_conf)
conf = ConfigTree.merge_configs(conf, conf1)

I would like to emulate the include statement so that hocon variables get evaluated in runtime like in the wishful code below:

conf = ConfigFactory.parse_files([conf_file, include_conf])
Rubber Duck
  • 3,673
  • 3
  • 40
  • 59

1 Answers1

1

Newer pyhocon has a possibility to parse a config file without resolving variables.

import pprint

from pyhocon import ConfigFactory


if __name__ == "__main__":

    conf = ConfigFactory\
        .parse_file('./app.conf', resolve=False)\
        .with_fallback(
            config='./app_vars.conf',
            resolve=True,
        )

    pprint.pprint(conf)

app.conf:

smart: {
   super_hero: ${super_hero}
}

app_vars.conf:

super_hero: Buggs_Bunny

It's possible to use strings:

from pyhocon import ConfigFactory

# readingconf entrypoint
file = open('application.conf', mode='r')
conf_string = file.read()
file.close()

conf_string_ready = conf_string.replace("PATH_TO_CONFIG","spec.conf")
conf = ConfigFactory.parse_string(conf_string_ready)

print(conf)

application.conf has

include "file://INCLUDE_FILE"

or in runtime without preparation I wrote it myself using python 3.65:

#!/usr/bin/env python

import os
from pyhocon import ConfigFactory as Cf


def is_line_in_file(full_path, line):

    with open(full_path) as f:
        content = f.readlines()

        for l in content:
            if line in l:
               f.close()
               return True

        return False


 def line_prepender(filename, line, once=True):

    with open(filename, 'r+') as f:
        content = f.read()
        f.seek(0, 0)

        if is_line_in_file(filename, line) and once:
             return

        f.write(line.rstrip('\r\n') + '\n' + content)


 def include_configs(base_path, included_paths):

     for included_path in included_paths:

         line_prepender(filename=base_path, line=f'include file("{included_path}")')

     return Cf.parse_file(base_path)


if __name__ == "__main__":

    dir_path = os.path.dirname(os.path.realpath(__file__))
    print(f"current working dir: {dir_path}")

    dir_path = ''

    _base_path = f'{dir_path}example.conf'
    _included_files = [f'{dir_path}example1.conf', f'{dir_path}example2.conf']

    _conf = include_configs(base_path=_base_path, included_paths=_included_files)

    print('break point')
Rubber Duck
  • 3,673
  • 3
  • 40
  • 59