Top-level options with subcommands (e.g. verbosity/logging configuration) #2189
Unanswered
calebstewart
asked this question in
Q&A
Replies: 1 comment
-
I've been able to get this somewhat working with the following custom class CommandWithVerbosity(click.Command):
"""A command that automatically adds the verbosity and traceback
arguments, sets up logging prior to invocation, and catches any
unhandled exceptions/logs them according to the logging configuration."""
def __init__(self, *args, **kwargs):
# This shouldn't happen, but :shrug:
if not kwargs.get("params"):
kwargs["params"] = []
# Add extra arguments to this command for logging setup
kwargs["params"].append(
click.Option(
["--verbose", "-v"], count=True, help="Increase logging verbosity."
)
)
kwargs["params"].append(
click.Option(
["--traceback", "-t"], is_flag=True, help="Dump a traceback on errors."
)
)
super().__init__(*args, **kwargs)
def invoke(self, ctx: click.Context):
# Setup logging according to the --verbose argument
logging.basicConfig(
level=logging.ERROR
- ctx.params["verbose"] * (logging.CRITICAL - logging.ERROR),
format="%(message)s",
handlers=[RichHandler(rich_tracebacks=True, console=error_console)],
)
# Store the traceback state in the context object in case
# a command needs to use it directly
if ctx.obj is None:
ctx.obj = {}
ctx.obj["traceback"] = ctx.params["traceback"]
# Remove the traceback and logging parameters
# to ensure they aren't passed to the command
# functions.
del ctx.params["traceback"]
del ctx.params["verbose"]
try:
# Invoke the command
super().invoke(ctx)
except ClickException:
# Click exceptions handled normally to maintain
# the look/feel of help and usage output.
raise
except Exception as exc:
# All other exceptions handled through logging.
if ctx.obj["traceback"]:
logger.exception(str(exc))
else:
logger.error(str(exc)) |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Say I have a command with subcommands like:
I would like to define options related to logging which affect all subcommands. I know that I could do that on the base click command, but doing this requires that the arguments related to logging are placed prior to the subcommands, and this is not very intuitive from a user stand point. Through examples:
I can make this work by duplicating the logging configuration across all sub-commands, but that's a lot of code duplication. Is there any native way to support this with click that I've missed in the documentation? Thanks in advance!
Beta Was this translation helpful? Give feedback.
All reactions