Source code for orion.core.cli.base

Base class and function utilities for cli
import argparse
import logging
import os
import sys
import textwrap

import orion
import orion.core
from import DatabaseError
from orion.core.utils.exceptions import (

logger = logging.getLogger(__name__)

CLI_DOC_HEADER = "Oríon CLI for asynchronous distributed optimization"

[docs]class OrionArgsParser: """Parser object handling the upper-level parsing of Oríon's arguments.""" def __init__(self, description=CLI_DOC_HEADER): """Create the pre-command arguments""" self.description = description self.parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=textwrap.dedent(description), ) self.parser.add_argument( "-V", "--version", action="version", version="orion " + orion.core.__version__, ) self.parser.add_argument( "-v", "--verbose", action="count", default=0, help="logging levels of information about the process (-v: INFO. -vv: DEBUG)", ) self.parser.add_argument( "--logdir", type=str, default=None, help="Path to a directory to store logs", ) self.parser.add_argument( "-d", "--debug", action="store_true", help="Use debugging mode with EphemeralDB.", ) self.subparsers = self.parser.add_subparsers(dest="command")
[docs] def get_subparsers(self): """Return the subparser object for this parser.""" return self.subparsers
[docs] def parse(self, argv): """Call argparse and generate a dictionary of arguments' value""" args = vars(self.parser.parse_args(argv)) verbose = args.pop("verbose", 0) levels = {0: logging.WARNING, 1: logging.INFO, 2: logging.DEBUG} logdir = args.pop("logdir") logfile = None if logdir is not None: os.makedirs(logdir, exist_ok=True) pid = os.getpid() logfile = os.path.join(logdir, f"orion_{pid}.log") logging.basicConfig( format="%(asctime)-15s::%(levelname)s::%(name)s::%(message)s", level=levels.get(verbose, logging.DEBUG), filename=logfile, ) logger.debug("Orion version : %s", orion.core.__version__) if args["command"] is None: self.parser.parse_args(["--help"]) function = args.pop("func", None) empty_command = (argv[-1] if argv else sys.argv[-1]) == args["command"] if function is None or (empty_command and args.pop("help_empty", False)): self.parser.parse_args([args["command"], "--help"]) return args, function
[docs] def execute(self, argv): """Execute main function of the subparser""" try: args, function = self.parse(argv) returncode = function(args) except ( NoConfigurationError, NoNameError, DatabaseError, MissingResultFile, BranchingEvent, InexecutableUserScript, ) as e: print("Error:", e, file=sys.stderr) if args.get("verbose", 0) >= 2: raise e return 1 except KeyboardInterrupt: print("Orion is interrupted.") return 130 return 0 if returncode is None else returncode
[docs]def get_basic_args_group( parser, group_name="Oríon arguments", group_help="These arguments determine orion's behaviour", ): """Return the basic arguments for any command.""" basic_args_group = parser.add_argument_group(group_name, description=group_help) basic_args_group.add_argument( "-n", "--name", type=str, metavar="stringID", help="experiment's unique name; " "(default: None - specified either here or in a config)", ) basic_args_group.add_argument( "-u", "--user", type=str, help="user associated to experiment's unique name; " "(default: $USER - can be overridden either here or in a config)", ) basic_args_group.add_argument( "-v", "--version", type=int, help="specific version of experiment to fetch; " "(default: None - latest experiment.)", ) basic_args_group.add_argument( "-c", "--config", type=argparse.FileType("r"), metavar="path-to-config", help="user provided " "orion configuration file", ) return basic_args_group
[docs]def get_user_args_group(parser): """ Return the user group arguments for any command. User group arguments are composed of the user script and the user args """ usergroup = parser.add_argument_group( "User script related arguments", description="These arguments determine user's script behaviour " "and they can serve as orion's parameter declaration.", ) usergroup.add_argument( "user_args", nargs=argparse.REMAINDER, metavar="...", help="Command line of user script. A configuration " "file intended to be used with 'userscript' must be given as a path " "in the **first positional** argument OR using `--config=<path>` " "keyword argument.", ) return usergroup