Source code for iblutil.io.params

import collections
from pathlib import Path, PurePath
import sys
import os
import json
import subprocess


[docs] def as_dict(par): if not par or isinstance(par, dict): return par else: return dict(par._asdict())
[docs] def from_dict(par_dict): if not par_dict: return None par = collections.namedtuple('Params', par_dict.keys()) class IBLParams(par): __slots__ = () def set(self, field, value): d = as_dict(self) d[field] = value return from_dict(d) def as_dict(self): return as_dict(self) return IBLParams(**par_dict)
[docs] def getfile(str_params): """ Returns full path of the param file per system convention: linux/mac: ~/.str_params, Windows: APPDATA folder :param str_params: string that identifies parm file :return: string of full path """ # strips already existing dot if any parts = ['.' + p if not p.startswith('.') else p for p in Path(str_params).parts] if sys.platform == 'win32' or sys.platform == 'cygwin': pfile = str(PurePath(os.environ['APPDATA'], *parts)) else: pfile = str(Path.home().joinpath(*parts)) return pfile
[docs] def set_hidden(path, hide: bool) -> Path: """ Set a given file or folder path to be hidden. On macOS and Windows a specific flag is set, while on other systems the file or folder is simply renamed to start with a dot. On macOS the folder may only be hidden in Explorer. Parameters ---------- path : str, pathlib.Path The path of the file or folder to (un)hide. hide : bool If True the path is set to hidden, otherwise it is unhidden. Returns ------- pathlib.Path The path of the file or folder, which may have been renamed. """ path = Path(path) assert path.exists() if sys.platform == 'win32' or sys.platform == 'cygwin': flag = ('+' if hide else '-') + 'H' subprocess.run(['attrib', flag, str(path)]).check_returncode() elif sys.platform == 'darwin': flag = ('' if hide else 'no') + 'hidden' subprocess.run(['chflags', flag, str(path)]).check_returncode() elif hide and not path.name.startswith('.'): path = path.rename(path.parent.joinpath('.' + path.name)) elif not hide and path.name.startswith('.'): path = path.rename(path.parent.joinpath(path.name[1:])) return path
[docs] def read(str_params, default=None): """ Reads in and parse Json parameter file into dictionary. If the parameter file doesn't exist and no defaults are provided, a FileNotFound error is raised, otherwise any extra default parameters will be written into the file. Examples: # Load parameters, raise error if file not found par = read('globus/admin') # Load with defaults par = read('globus/admin', {'local_endpoint': None, 'remote_endpoint': None}) # Return empty dict if file not found (i.e. touch new param file) par = read('new_pars', {}) :param str_params: path to text json file :param default: default values for missing parameters :return: named tuple containing parameters """ pfile = getfile(str_params) par_dict = as_dict(default) or {} if Path(pfile).exists(): with open(pfile) as fil: file_pars = json.loads(fil.read()) par_dict.update(file_pars) elif default is None: # No defaults provided raise FileNotFoundError(f'Parameter file {pfile} not found') if not Path(pfile).exists() or par_dict.keys() > file_pars.keys(): # write the new parameter file with the extra param write(str_params, par_dict) return from_dict(par_dict)
[docs] def write(str_params, par): """ Write a parameter file in Json format :param str_params: path to text json file :param par: dictionary containing parameters values :return: None """ pfile = Path(getfile(str_params)) if not pfile.parent.exists(): pfile.parent.mkdir() dpar = as_dict(par) for k in dpar: if isinstance(dpar[k], Path): dpar[k] = str(dpar[k]) with open(pfile, 'w') as fil: json.dump(as_dict(par), fil, sort_keys=False, indent=4)