Source code for deode.argparse_wrapper

#!/usr/bin/env python3
"""Wrappers for argparse functionality."""
import argparse
import sys
from pathlib import Path

from . import GeneralConstants
from .commands_functions import (
    create_exp,
    doc_config,
    namelist_convert,
    namelist_format,
    namelist_integrate,
    run_task,
    show_config,
    show_config_schema,
    show_host,
    show_namelist,
    show_paths,
    start_suite,
)
from .config_parser import ConfigParserDefaults
from .namelist import NamelistConverter


[docs] def get_parsed_args(program_name=GeneralConstants.PACKAGE_NAME, argv=None): """Get parsed command line arguments. Args: program_name (str): The name of the program. argv (list): A list of passed command line args. Returns: argparse.Namespace: Parsed command line arguments. """ if argv is None: argv = sys.argv[1:] ###################################################################################### # Command line args that will be common to main_parser and possibly other subparsers.# # # # You should add `parents=[common_parser]` to your subparser definition if you want # # these options to apply there too. # ###################################################################################### common_parser = argparse.ArgumentParser(add_help=False) common_parser.add_argument( "--deode-home", default=None, help="Specify deode_home to override automatic detection", ) common_parser.add_argument( "--config-file", "-c", metavar="CONFIG_FILE_PATH", default=ConfigParserDefaults.CONFIG_PATH, type=Path, help=( "Path to the config file. The default is whichever of the " + "following is first encountered: " + "(i) The value of the 'DEODE_CONFIG_PATH' envvar or " + "(ii) './config.toml'. If both (i) and (ii) are missing, " + "then the default will become " + "'" + f"{ConfigParserDefaults.PACKAGE_CONFIG_PATH}" + "'" ), ) common_parser.add_argument( "--host-file", dest="host_file", help="Config file for host recognition rules", required=False, default=None, ) common_parser.add_argument( "--config-data-dir", nargs="+", type=str, help="Search path(s) for config directory.", required=False, default=None, ) ########################################## # Define main parser and general options # ########################################## main_parser = argparse.ArgumentParser( prog=program_name, formatter_class=argparse.ArgumentDefaultsHelpFormatter, fromfile_prefix_chars="?", ) main_parser.add_argument( "--version", "-v", action="version", version="%(prog)s v" + GeneralConstants.VERSION, ) # Configure the main parser to handle the commands subparsers = main_parser.add_subparsers( title="commands", required=True, dest="command", description=( f"Valid commands for {program_name} (note that commands also accept their " + "own arguments, in particular [-h]):" ), help="command description", ) ########################################## # Configure parser for the "run" command # ########################################## parser_run = subparsers.add_parser( "run", help="Runs a task.", parents=[common_parser] ) parser_run.add_argument("--task", "-t", help="Task name", required=True) parser_run.add_argument( "--template-job", help="Template", required=False, default=f"{GeneralConstants.PACKAGE_DIRECTORY}/templates/stand_alone.py", ) parser_run.add_argument( "--job", dest="task_job", help="Task job file", required=False ) parser_run.add_argument("--output", "-o", help="Task output file", required=False) parser_run.add_argument("--troika", default="troika") parser_run.add_argument("--troika-config", default="/opt/troika/etc/troika.yml") parser_run.set_defaults(run_command=run_task) ########################################## # Configure parser for the "case" command # ########################################## parser_case = subparsers.add_parser( "case", help="Create a config file to run an experiment case", parents=[common_parser], ) parser_case.add_argument( "--output", "-o", dest="output_file", help="Output config file, if not given the name will be the same as the case", default=None, required=False, ) parser_case.add_argument( "--case-name", dest="case", help="Case name", required=False, default=None ) parser_case.add_argument( "config_mods", help="Path to configuration modifications", nargs="*", type=Path, default=None, ) parser_case.add_argument( "--expand-config", "-e", action="store_true", default=False, help="Expand macros in config", required=False, ) parser_case.add_argument( "--start-suite", "-s", action="store_true", default=False, help="Start suite as well", required=False, ) add_keep_def_file( parser_case, help_message="Keep suite definition file in case of submission" ) parser_case.set_defaults(run_command=create_exp) ############################################ # Configure parser for the "start" command # ############################################ parser_start = subparsers.add_parser("start", help="Start various tasks and exit.") start_command_subparsers = parser_start.add_subparsers( title="start", dest="start_what", required=True, description=( "Valid commands below (note that commands also accept their " + "own arguments, in particular [-h]):" ), help="command description", ) # suite parser_start_suite = start_command_subparsers.add_parser( "suite", help="Start the suite", parents=[common_parser] ) parser_start_suite.add_argument( "--start-command", type=str, help="Start command for server", default=None ) parser_start_suite.add_argument( "--def-file", "-f", help="Suite definition file", default="", ) add_keep_def_file(parser_start_suite) parser_start_suite.set_defaults(run_command=start_suite) ########################################### # Configure parser for the "show" command # ########################################### parser_show = subparsers.add_parser( "show", help="Display results from output files, as well as configs" ) show_command_subparsers = parser_show.add_subparsers( title="show", dest="show_what", required=True, description=( "Valid commands below (note that commands also accept their " + "own arguments, in particular [-h]):" ), help="command description", ) # show config parser_show_config = show_command_subparsers.add_parser( "config", help="Print configs in use and exit", parents=[common_parser] ) parser_show_config.add_argument( "section", help="The config section (optional)", default="", nargs="?" ) parser_show_config.add_argument( "--format", "-fmt", help="Output format", choices=["toml", "json", "yaml"], default="toml", ) parser_show_config.set_defaults(run_command=show_config) # show config-schema parser_show_config_schema = show_command_subparsers.add_parser( "config-schema", help="Print JSON schema used for validation of configs and exit", parents=[common_parser], ) parser_show_config_schema.add_argument( "section", help="The config section (optional)", default="", nargs="?" ) parser_show_config_schema.set_defaults(run_command=show_config_schema) # show host parser_show_host = show_command_subparsers.add_parser( "host", help="Print current and available hosts", parents=[common_parser] ) parser_show_host.set_defaults(run_command=show_host) # show namelist parser_show_namelist = show_command_subparsers.add_parser( "namelist", help="Print namelist in use and exit", parents=[common_parser] ) add_namelist_args(parser_show_namelist) # show paths parser_show_paths = show_command_subparsers.add_parser( "paths", help="Print paths in use and exit", parents=[common_parser] ) parser_show_paths.set_defaults(run_command=show_paths) ########################################### # Configure parser for the "doc" command # ########################################### parser_doc = subparsers.add_parser("doc", help="Print documentation style output") doc_command_subparsers = parser_doc.add_subparsers( title="doc", dest="doc_what", required=True, description=( "Valid commands below (note that commands also accept their " + "own arguments, in particular [-h]):" ), help="command description", ) # doc config parser_doc_config = doc_command_subparsers.add_parser( "config", help="Print documentation for the config's json schema in markdown style", parents=[common_parser], ) parser_doc_config.set_defaults(run_command=doc_config) # namelist subparser parser_namelist = subparsers.add_parser( "namelist", help="Namelist show (output), integrate (input), " + "convert (input, output), format (input, output)", ) namelist_command_subparsers = parser_namelist.add_subparsers( title="namelist", dest="namelist_what", required=True, description=( "Valid commands below (note that commands also accept their " + "own arguments, in particular [-h]):" ), help="command description", ) # show namelist parser_namelist_show = namelist_command_subparsers.add_parser( "show", help="Print namelist in use and exit", parents=[common_parser] ) add_namelist_args(parser_namelist_show) # namelist integrate parser_namelist_integrate = namelist_command_subparsers.add_parser( "integrate", help="Read fortran [+yaml] namelist(s) and output as yaml dict(s)", parents=[common_parser], ) parser_namelist_integrate.add_argument( "-n", "--namelist", nargs="+", type=str, help="Fortran namelist input file(s)", required=True, default=None, ) parser_namelist_integrate.add_argument( "-o", "--output", type=str, help="Output file (yaml format)", required=True, default=None, ) parser_namelist_integrate.add_argument( "-t", "--tag", type=str, help="Tag used as base for comparisons", required=False, default=None, ) parser_namelist_integrate.add_argument( "-y", "--yaml", type=str, help="Input yaml file (from earlier run)", required=False, default=None, ) parser_namelist_integrate.set_defaults(run_command=namelist_integrate) # namelist convert parser_namelist_convert = namelist_command_subparsers.add_parser( "convert", help="Convert a namelist (ftn or yml) to a new Cycle", parents=[common_parser], ) parser_namelist_convert.add_argument( "-n", "--namelist", type=str, help="Input namelist definition filename", required=True, default=None, ) parser_namelist_convert.add_argument( "-o", "--output", type=str, help="Output namelist definition filename", required=True, default=None, ) parser_namelist_convert.add_argument( "--from-cycle", type=str, help="Cycle of input namelist", choices=NamelistConverter.get_known_cycles(), required=True, default=None, ) parser_namelist_convert.add_argument( "--to-cycle", type=str, help="Cycle of output namelist", choices=NamelistConverter.get_known_cycles(), required=True, default=None, ) parser_namelist_convert.add_argument( "--format", "-fmt", help="Input format", choices=["yaml", "ftn"], default="yaml" ) parser_namelist_convert.set_defaults(run_command=namelist_convert) # namelist format parser_namelist_format = namelist_command_subparsers.add_parser( "format", help="Format a namelist (ftn or yml) ", parents=[common_parser], ) parser_namelist_format.add_argument( "-n", "--namelist", type=str, help="Input namelist definition filename", required=True, default=None, ) parser_namelist_format.add_argument( "-o", "--output", type=str, help="Output namelist definition filename", required=True, default=None, ) parser_namelist_format.add_argument( "--format", "-fmt", help="Input format", choices=["yaml", "ftn"], default="yaml" ) parser_namelist_format.set_defaults(run_command=namelist_format) return main_parser.parse_args(argv)
[docs] def add_namelist_args(parser_object): """Add namelist args. Args: parser_object (args oject): args object to update Returns: parser_object (args oject): updated args object """ parser_object.add_argument( "--namelist-type", "-t", type=str, help="Namelist target, master or surfex", choices=["master", "surfex"], required=True, default=None, ) parser_object.add_argument( "--namelist", "-n", type=str, help="Namelist to show, type anything to print available options", required=True, default=None, ) parser_object.add_argument( "--optional-namelist-name", "-o", type=str, dest="namelist_name", help="Optional namelist name", default=None, ) parser_object.add_argument( "--no-substitute", "-b", action="store_false", default=True, help="Do not substitute config values in the written namelist", ) parser_object.set_defaults(run_command=show_namelist) return parser_object
[docs] def add_keep_def_file( parser_object, help_message="Keep suite definition file after submission" ): """Add object args. Args: parser_object (args oject): args object to update help_message (str): Help text """ parser_object.add_argument( "--keep-def-file", "-k", help=help_message, action="store_true", default=False, required=False, )