-
First Check
Commit to Help
Example Codeimport typer
app = typer.Typer()
@app.command()
def put():
print("Storing data")
@app.command()
def get():
print("Fetching data")
if __name__ == "__main__":
app() DescriptionThe examples on https://typer.tiangolo.com/tutorial/options/version/ show how to add This was added in connection to issue #52, but that discusses the value of a global mechanism for adding Example use-case: Given an example $ myapp --version
myapp v1.3.5
$ myapp put --version
myapp v1.3.5
$ myapp get -x 17 -y 42 --version
myapp v1.3.5 This assumes the same default option name A suggested minimal but non-extensible syntax was: # auto detect package name and version
app = typer.Typer(version_option=True)
# specify version string manually
app = typer.Typer(version_option="myapp v1.3.5") Personally I would like a little more flexibility, specifcially to be able to use both Operating SystemmacOS Operating System DetailsOS independent. Typer Version0.15.1 Python Version3.12.9 Additional ContextI have tried using a callback, but have not hit on a combination which covers both the base tool ( |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Based on #52 (comment) the following isn't too much extra code, but not a full solution: import click
import typer
__version__ = "1.3.5"
app = typer.Typer()
class CommandWithVersion(typer.core.TyperCommand):
"""Subclassed TyperCommand with --version included."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
click.version_option(version=__version__, prog_name="myapp")(self)
app = typer.Typer(no_args_is_help=True)
@app.command(cls=CommandWithVersion)
def put(data: str):
"""Mock command for storing data."""
print(f"Storing {data=}")
@app.command(cls=CommandWithVersion)
def get():
"""Mock command for retrieving data."""
print("Fetching data")
if __name__ == "__main__":
app() There's the extra subclass, and then every subcommand you want to add This then works: ❯ python myapp.py get --version
myapp, version 1.3.5
❯ python myapp.py put --version
myapp, version 1.3.5
❯ python myapp.py put --help
Usage: myapp.py put [OPTIONS] DATA
Mock command for storing data.
╭─ Arguments ─────────────────────────────────────────────╮
│ * data TEXT [default: None] [required] │
╰─────────────────────────────────────────────────────────╯
╭─ Options ───────────────────────────────────────────────╮
│ --version Show the version and exit. │
│ --help Show this message and exit. │
╰─────────────────────────────────────────────────────────╯ However, this does not add ❯ python myapp.py --version
Usage: myapp.py [OPTIONS] COMMAND [ARGS]...
Try 'myapp.py --help' for help.
╭─ Error ─────────────────────────────────────────────────╮
│ No such option: --version │
╰─────────────────────────────────────────────────────────╯ |
Beta Was this translation helpful? Give feedback.
-
A solution based on this stack overflow answer, but using type annotation style, and also explicitly adding the version option to all the subcommands. import sys
import typer
from typing_extensions import Annotated
__version__ = "1.3.5"
def version_callback(version: bool = False) -> None:
if version:
print(f"myapp {__version__}")
sys.exit(0) # typer.Exit() does not quit immediately
VERSION_TYPE_DEF = Annotated[
bool,
typer.Option(
"--version",
"-v",
help="Show tool version (on stdout) and quit.",
show_default=False,
is_eager=True,
callback=version_callback,
),
]
app = typer.Typer(no_args_is_help=True)
@app.callback()
def common(
ctx: typer.Context,
version: VERSION_TYPE_DEF = False,
):
pass
# Must explicitly add --version, -v to each subcommand
@app.command()
def put(
data: str,
version: VERSION_TYPE_DEF = False,
):
"""Mock command for storing data."""
print(f"Storing {data=}")
# Must explicitly add --version, -v to each subcommand
@app.command()
def get(
version: VERSION_TYPE_DEF = False,
):
"""Mock command for retrieving data."""
print("Fetching data")
if __name__ == "__main__":
app() This seem to work as I wished: ❯ python myapp.py
Usage: myapp.py [OPTIONS] COMMAND [ARGS]...
╭─ Options ───────────────────────────────────────────────────────╮
│ --version -v Show tool version (on stdout) │
│ and quit. │
│ --install-completion Install completion for the │
│ current shell. │
│ --show-completion Show completion for the current │
│ shell, to copy it or customize │
│ the installation. │
│ --help Show this message and exit. │
╰─────────────────────────────────────────────────────────────────╯
╭─ Commands ──────────────────────────────────────────────────────╮
│ put Mock command for storing data. │
│ get Mock command for retrieving data. │
╰─────────────────────────────────────────────────────────────────╯
❯ python myapp.py -v
myapp 1.3.5 This includes all subcommand where ❯ python myapp.py get --help
Usage: myapp.py get [OPTIONS]
Mock command for retrieving data.
╭─ Options ─────────────────────────────────────────────────╮
│ --version -v Show tool version (on stdout) and │
│ quit. │
│ --help Show this message and exit. │
╰───────────────────────────────────────────────────────────╯
❯ python myapp.py get --version
myapp 1.3.5
❯ python myapp.py put --version
myapp 1.3.5 On the bright side, having to explicitly add |
Beta Was this translation helpful? Give feedback.
A solution based on this stack overflow answer, but using type annotation style, and also explicitly adding the version option to all the subcommands.