Source code for bnlcrl.utils

import json
import os
from pykern import pkjinja


[docs]def defaults_file(suffix=None, defaults_file_path=None): script_path = os.path.dirname(os.path.realpath(__file__)) # Fix for Jython: try: script_path = script_path.replace( os.path.join(format(os.environ['HOME']), '.jython-cache/cachedir/classes'), '' ) except: pass dat_dir = os.path.join(script_path, 'package_data', 'dat') config_dir = os.path.join(script_path, 'package_data', 'json') if not defaults_file_path: file_name = 'defaults_{}.json'.format(suffix) if suffix else 'defaults.json' defaults_file = os.path.join(config_dir, file_name) else: defaults_file = defaults_file_path return { 'dat_dir': dat_dir, 'config_dir': config_dir, 'defaults_file': defaults_file, }
[docs]def console(class_name, parameters_file): import argparse data = read_json(parameters_file) description = data['description'] parameters = convert_types(data['parameters']) # Processing arguments: required_args = [] optional_args = [] for key in sorted(parameters.keys()): if parameters[key]['default'] is None: required_args.append(key) else: optional_args.append(key) parser = argparse.ArgumentParser(description=description) for key in required_args + optional_args: args = [] if 'short_argument' in parameters[key]: args.append('-{}'.format(parameters[key]['short_argument'])) args.append('--{}'.format(key)) kwargs = { 'dest': key, 'default': parameters[key]['default'], 'required': False, 'type': parameters[key]['type'], 'help': '{}.'.format(parameters[key]['help']), } if parameters[key]['default'] is None: kwargs['required'] = True if parameters[key]['type'] == bool: kwargs['action'] = 'store_true' del (kwargs['type']) if parameters[key]['type'] == str: pass if parameters[key]['type'] in [list, tuple]: kwargs['type'] = parameters[key]['element_type'] kwargs['nargs'] = '*' # '*' - zero or more elements, '+' - one or more elements parser.add_argument(*args, **kwargs) args = parser.parse_args() for key in args.__dict__.keys(): if type(args.__dict__[key]) == str and args.__dict__[key] == 'None': args.__dict__[key] = None class_name(**args.__dict__)
[docs]def convert_types(input_dict): """Convert types of values from specified JSON file.""" # Eval `type` and `element_type` first: for key in input_dict.keys(): if input_dict[key]['type'] == 'tuple': input_dict[key]['type'] = 'list' for el_key in ['type', 'element_type']: if el_key in input_dict[key].keys(): input_dict[key][el_key] = eval(input_dict[key][el_key]) # Convert values: for key in input_dict.keys(): if 'default' in input_dict[key].keys() and input_dict[key]['default'] is not None: if 'element_type' in input_dict[key].keys(): if input_dict[key]['type'] == list: for i in range(len(input_dict[key]['default'])): input_dict[key]['default'][i] = input_dict[key]['element_type'](input_dict[key]['default'][i]) else: input_dict[key]['default'] = input_dict[key]['type'](input_dict[key]['default']) return input_dict
[docs]def create_cli_function(function_name, parameters, config): """The function creates the content of the CLI functions with the input from JSON config. Args: function_name (str): name of the function. parameters (dict): dictionary with the parameters of the arguments (default value, help info, type). config (dict): dictionary with the parameters (descriptions, used class name, returns, parameters (optional)). Returns: str: resulted function represented as a string. """ # argh_decorators: argh_args = '' argh_kwargs = '' for key in sorted(parameters.keys()): if parameters[key]['default'] is None: if parameters[key]['type'] in [list, tuple]: argh_args += "@argh.arg('{}', nargs='*', type={})\n".format(key, parameters[key]['element_type'].__name__) else: argh_args += "@argh.arg('{}', type={})\n".format(key, parameters[key]['type'].__name__) else: if parameters[key]['type'] in [list, tuple]: argh_kwargs += "@argh.arg('--{}', nargs='+', type={})\n".format(key, parameters[key][ 'element_type'].__name__) if 'choices' in parameters[key]: argh_kwargs += "@argh.arg('--{}', choices=[{}])\n".format( key, ', '.join(["\'{}\'".format(x) for x in parameters[key]['choices'].keys()]) ) argh_decorators = '{}{}'.format(argh_args, argh_kwargs) # function_arguments: str_args = '' str_kwargs = '' for key in sorted(parameters.keys()): a = parameters[key]['default'] if parameters[key]['default'] is None: str_args += ' {},\n'.format(key) continue if parameters[key]['type'] == str: a = "\'{}\'".format(parameters[key]['default']) str_kwargs += ' {}={},\n'.format(key, a) function_arguments = '\n{}{}'.format(str_args, str_kwargs) # descriptions: description_short = config['description_short'] description_long = config['description_long'] # arguments_description: arguments_description = '' for key in sorted(parameters.keys()): format_str = ' {} ({}): {}.\n' format_values = [ key, parameters[key]['type'].__name__, parameters[key]['help'], ] if 'choices' in parameters[key]: format_str = ' {} ({}): {} ({}).\n' choices_str = '' comma = ', ' for i, choices_key in enumerate(sorted(parameters[key]['choices'].keys())): if i == len(parameters[key]['choices'].keys()) - 1: comma = '' choices_str += "``{}`` - {}{}".format(choices_key, parameters[key]['choices'][choices_key], comma) format_values.append(choices_str) arguments_description += format_str.format(*format_values) # class_name: class_name = config['class_name'] # class_arguments: class_arguments = '' for key in sorted(parameters.keys()): class_arguments += ' {}={},\n'.format(key, key) # return_dict return_dict = '' if type(config['returns']) == list: for r in config['returns']: return_dict += " '{}': c.{},\n".format(r, r) return_dict = '{{\n{} }}'.format(return_dict) else: return_dict = config['returns'] v = { 'argh_decorators': argh_decorators, 'function_name': function_name, 'function_arguments': function_arguments, 'description_short': description_short, 'description_long': description_long, 'arguments_description': arguments_description, 'class_name': class_name, 'class_arguments': class_arguments, 'return_dict': return_dict, } return pkjinja.render_resource('cli_function', v)
[docs]def get_cli_functions(config): """Get list of CLI functions' content with the input from JSON config. Args: config (dict): dictionary with the configuration in JSON format. Returns: list: list of functions' contents. """ functions_list = [] for key in config['cli_functions'].keys(): if 'parameters' in config['cli_functions'][key]: parameters = convert_types(config['cli_functions'][key]['parameters']) else: parameters = convert_types(config['parameters']) content = create_cli_function(key, parameters, config['cli_functions'][key]) functions_list.append(content) return functions_list
[docs]def read_json(file_name): try: with open(file_name, 'r') as f: data = json.load(f) except IOError: raise Exception('The specified file <{}> not found!'.format(file_name)) except ValueError: raise Exception('Malformed JSON file <{}>!'.format(file_name)) return data