import argparse
import json
import logging
from typing import Callable, Iterable, Literal, Optional, Sequence, TypedDict
from typing_extensions import NotRequired
import yaml
from cowbird.constants import get_constant
from cowbird.typedefs import JSON
[docs]
CommandPrefixes = Optional[Iterable[str]]
[docs]
SharedParsers = Optional[Iterable[argparse.ArgumentParser]]
[docs]
ParsedArgs = Optional[argparse.Namespace]
[docs]
ParserArgs = Optional[Sequence[str]]
[docs]
HelperParser = Optional[argparse.ArgumentParser]
[docs]
ParserMaker = Callable[[SharedParsers, CommandPrefixes], argparse.ArgumentParser]
[docs]
ParserRunner = Callable[[ParserArgs, HelperParser, ParsedArgs], ParseResult]
[docs]
SubParserArgs = TypedDict(
"SubParserArgs",
{
"help": str,
"description": str,
"usage": NotRequired[str],
},
total=True,
)
[docs]
def subparser_help(description: str, parent_parser: Optional[argparse.ArgumentParser] = None) -> SubParserArgs:
"""
Generates both fields with the same description as each parameter is used in different context.
Field ``help`` is printed next to the subparser name when *parent parser* is called with ``--help``.
Field ``description`` populates the help details under the usage command when calling *child parser* ``--help``.
"""
desc: SubParserArgs = {"help": description, "description": description}
if parent_parser:
desc.update({"usage": parent_parser.usage})
return desc
[docs]
def get_config_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument("-c", "--config", help="INI configuration file to employ.",
default=get_constant("COWBIRD_INI_FILE_PATH", raise_missing=False, raise_not_set=False))
return parser
[docs]
def get_logger_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(add_help=False)
group = parser.add_mutually_exclusive_group()
group.add_argument("-q", "--quiet", action="store_true", help="Suppress informative logging.")
group.add_argument("-d", "--debug", action="store_true", help="Set debug logging level.")
group.add_argument("-l", "--level", choices=["debug", "info", "warn", "error"], default="info")
return parser
[docs]
def set_log_level(args: argparse.Namespace, logger: Optional[logging.Logger] = None) -> None:
from cowbird.cli import LOGGER
logger = logger or LOGGER
if args.quiet:
logger.setLevel(logging.ERROR)
elif args.debug:
logger.setLevel(logging.DEBUG)
elif args.level:
logger.setLevel(args.level.upper())
else:
logger.setLevel(logging.INFO)