def rc_load_json(fpath, emheading=None): """Load JSON-formatted data from a (resource) file. :param fpath: pathlib.Path, path to a source file. :param emheading: str, heading to be added to the exception's description :return: json obj, JSON-formatted data """ assert isinstance(fpath, Path) and fpath.is_absolute(), ( f'Argument: fpath: Absolute pathlib.Path is required: {fpath}') try: with fpath.open() as fp: j_body = json.load(fp, strict=False) except FileNotFoundError: err_msg = f'Load: {fpath}' err_msg = f'{emheading}: {err_msg}' if emheading else err_msg raise cr_exc.RCNotFoundError(err_msg) except (OSError, RuntimeError) as e: err_msg = f'Load: {fpath}: {type(e).__name__}: {e}' err_msg = f'{emheading}: {err_msg}' if emheading else err_msg raise cr_exc.RCError(err_msg) except cr_exc.JSON_ERRORS as e: err_msg = f'Load: {fpath}: {type(e).__name__}: {e}' err_msg = f'{emheading}: {err_msg}' if emheading else err_msg raise cr_exc.RCInvalidError(err_msg) else: return j_body
def rc_load_ini(fpath, emheading=None): """Load INI-formatted data from a (resource) file. :param fpath: pathlib.Path, path to a source file :param emheading: str, heading to be added to the exception's description :return: dict, configparser.ConfigParser.read_dict() compatible data. """ assert isinstance(fpath, Path) and fpath.is_absolute(), ( f'Argument: fpath: Absolute pathlib.Path is required: {fpath}') cfg_parser = cfp.ConfigParser() try: with fpath.open() as fp: cfg_parser.read_file(fp) except FileNotFoundError: err_msg = f'Load: {fpath}' err_msg = f'{emheading}: {err_msg}' if emheading else err_msg raise cr_exc.RCNotFoundError(err_msg) except (OSError, RuntimeError) as e: err_msg = f'Load: {fpath}: {type(e).__name__}: {e}' err_msg = f'{emheading}: {err_msg}' if emheading else err_msg raise cr_exc.RCError(err_msg) except cfp.Error as e: err_msg = f'Load: {fpath}: {type(e).__name__}: {e}' err_msg = f'{emheading}: {err_msg}' if emheading else err_msg raise cr_exc.RCInvalidError(err_msg) else: return {k: dict(v) for k, v in cfg_parser.items()}
def rc_load_ini(fpath, emheading=None, render=False, context=None): """Load INI-formatted data from a resource file. Content of a resource file can be pre-processed by Jinja2 rendering engine before being passed to INI-parser. :param fpath: pathlib.Path, path to a source file :param emheading: str, heading to be added to the exception's description :param render: bool, perform template rendering :param context: ResourceContext, rendering context data object :return: dict, configparser.ConfigParser.read_dict() compatible data. """ assert isinstance(fpath, Path) and fpath.is_absolute(), ( f'Argument: fpath: Absolute pathlib.Path is required: {fpath}' ) if context is None: context_items = {} else: assert isinstance(context, ResourceContext), ( f'Argument: context:' f' Got {type(context).__name__} instead of ResourceContext' ) context_items = context.get_items() cfg_parser = cfp.ConfigParser() try: if render is True: jj2_env = jj2.Environment( loader=jj2.FileSystemLoader(str(fpath.parent)) ) jj2_tmpl = jj2_env.get_template(str(fpath.name)) ini_str = jj2_tmpl.render(**context_items) LOG.debug(f'rc_load_ini(): ini_str: {ini_str}') cfg_parser.read_string(ini_str, source=str(fpath)) else: with fpath.open() as fp: cfg_parser.read_file(fp) except (FileNotFoundError, jj2.TemplateNotFound) as e: err_msg = f'Load: {fpath}' err_msg = f'{emheading}: {err_msg}' if emheading else err_msg raise cr_exc.RCNotFoundError(err_msg) from e except (OSError, RuntimeError) as e: err_msg = f'Load: {fpath}: {type(e).__name__}: {e}' err_msg = f'{emheading}: {err_msg}' if emheading else err_msg raise cr_exc.RCError(err_msg) from e except (jj2.TemplateError, cfp.Error) as e: err_msg = f'Load: {fpath}: {type(e).__name__}: {e}' err_msg = f'{emheading}: {err_msg}' if emheading else err_msg raise cr_exc.RCInvalidError(err_msg) from e else: return {k: dict(v) for k, v in cfg_parser.items()}
def rc_load_json(fpath, emheading=None, render=False, context=None): """Load JSON-formatted data from a resource file. Content of a resource file can be pre-processed by Jinja2 rendering engine before being passed to JSON-parser. :param fpath: pathlib.Path, path to a source file. :param emheading: str, heading to be added to the exception's description :param render: bool, perform template rendering :param context: ResourceContext, rendering context data object :return: json obj, JSON-formatted data """ assert isinstance(fpath, Path) and fpath.is_absolute(), ( f'Argument: fpath: Absolute pathlib.Path is required: {fpath}' ) if context is None: context_items = {} else: assert isinstance(context, ResourceContext), ( f'Argument: context:' f' Got {type(context).__name__} instead of ResourceContext' ) context_items = context.get_items(json_ready=True) try: if render is True: jj2_env = jj2.Environment( loader=jj2.FileSystemLoader(str(fpath.parent)) ) jj2_tmpl = jj2_env.get_template(str(fpath.name)) json_str = jj2_tmpl.render(**context_items) LOG.debug(f'rc_load_json(): json_str: {json_str}') j_body = json.loads(json_str, strict=False) else: with fpath.open() as fp: j_body = json.load(fp, strict=False) except (FileNotFoundError, jj2.TemplateNotFound) as e: err_msg = f'Load: {fpath}' err_msg = f'{emheading}: {err_msg}' if emheading else err_msg raise cr_exc.RCNotFoundError(err_msg) from e except (OSError, RuntimeError) as e: err_msg = f'Load: {fpath}: {type(e).__name__}: {e}' err_msg = f'{emheading}: {err_msg}' if emheading else err_msg raise cr_exc.RCError(err_msg) from e except (jj2.TemplateError,) + cr_exc.JSON_ERRORS as e: err_msg = f'Load: {fpath}: {type(e).__name__}: {e}' err_msg = f'{emheading}: {err_msg}' if emheading else err_msg raise cr_exc.RCInvalidError(err_msg) from e else: return j_body
def wrapper(fpath: Path, emheading: str = None, render: bool = False, context: ResourceContext = None) -> Any: try: content = func(fpath, emheading, render, context) except (FileNotFoundError, jj2.TemplateNotFound) as e: err_msg = f'Load: {fpath}' err_msg = f'{emheading}: {err_msg}' if emheading else err_msg raise cr_exc.RCNotFoundError(err_msg) from e except (OSError, RuntimeError) as e: err_msg = f'Load: {fpath}: {type(e).__name__}: {e}' err_msg = f'{emheading}: {err_msg}' if emheading else err_msg raise cr_exc.RCError(err_msg) from e except (jj2.TemplateError, yaml.YAMLError) + cr_exc.JSON_ERRORS as e: err_msg = f'Load: {fpath}: {type(e).__name__}: {e}' err_msg = f'{emheading}: {err_msg}' if emheading else err_msg raise cr_exc.RCInvalidError(err_msg) from e else: return content