Is there a way to put global options and subcommand options in any place? #1123
Replies: 2 comments 1 reply
-
|
i would also be interested in this ... have you @chenzhiwei made any discoveries in that regard? |
Beta Was this translation helpful? Give feedback.
-
|
I've banged my head on this for a while and came up with a partial solution that reuses the definitions for the flags and allows the flags to be used at the command level for every command they are injected into. Hopefully this will be helpful to others that are bothered by how global options must be included at the app level rather than the command level! In theory, this could be combined with Typer's app-level callbacks to allow for using the flags at any level, but for my purposes I only cared about having the same flags available for each subcommand. My partial solution revolves around creating a decorator that wraps the original command with the shared arguments/options, adds any logic to process those arguments/options, and then returns the command with a modified signature that includes the extra arguments/options. Here's an example for adding a def with_verbosity_flag(fn):
# Create a wrapper function to inject and process the --verbose flag.
@functools.wraps(fn)
def wrapper(
*args,
verbose: Annotated[Optional[bool], typer.Option("--verbose", "-v", help="Enable debug logging")] = False,
**kwargs,
):
log_level: str | int = logging.INFO
if verbose:
log_level = logging.DEBUG
init_logging(log_level)
# Return the call to the original command function.
return fn(*args, **kwargs)
# Update command function signature to include --verbose. This is what Typer looks at.
sig = inspect.signature(wrapper)
params = list(sig.parameters.values())
params.extend(
[
inspect.Parameter(
"verbose",
inspect.Parameter.KEYWORD_ONLY,
default=False,
annotation=Annotated[Optional[bool], typer.Option("--verbose", "-v", help="Enable debug logging")],
),
]
)
sig = sig.replace(parameters=params)
wrapper.__signature__ = sig
# Return the wrapper function with the injected flag and logic and modified signature
return wrapper
@app.command()
@with_verbosity_flag
def my_command(...):
my_command_logic()With the wrapper function, you can accept just about anything including the |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
First Check
Commit to Help
Example Code
Description
In above code, the
username,passwordandhostare global options and can only place it after the main program.Is there a way to put them after arguments or subcommands, like
kubectl:Operating System
Linux
Operating System Details
No response
Typer Version
0.15.1
Python Version
Python 3.13.1
Additional Context
No response
Beta Was this translation helpful? Give feedback.
All reactions