How to implement –version using python click?
Question:
I want to implement mycommand --version
using python click. I have something like this working but it feels kinda clunky.
@click.group(invoke_without_command=True, no_args_is_help=True)
@click.pass_context
@click.option('--version', 'version')
def cli(ctx, version):
if version:
ctx.echo(f'{sys.argv[0]} {__version__}')
ctx.exit()
Answers:
As it turns out, click
has a builtin decorator click.version_option
to accomplish this. The code now becomes:
@click.group()
@click.version_option(__version__)
@click.pass_context
def cli(ctx):
pass
You can use click.version_option
decorator to implement --version
option.
If your setup.py
like this and have version
click will read it automatically.
from setuptools import setup
setup(
name='application',
version='0.1',
py_modules=['application'],
install_requires=[
'Click',
],
)
The click.version_option
option without any argument will read version from setup.py
.
@click.group(invoke_without_command=True, no_args_is_help=True)
@click.pass_context
@click.version_option()
def cli(ctx):
...
Run and Result
$ application --version
application, version 0.1
I want to add another scenario that I ran into but isn’t explicitly stated here:
Your CLI name can be different from your entry point, which can mean you’ll need to provide the name explicitly if importlib_metadata can’t automatically find the name
Error
Without package_name='my_command_line_interface'
:
mycli --version
RuntimeError: ‘mycli’ is not installed. Try passing ‘package_name’ instead.
Setup
setup.py
setup(
name='my_command_line_interface',
version='0.1',
py_modules=['application'],
install_requires=[
'Click',
],
entry_points="""
[console_scripts]
mycli=my_command_line_interface.cli:cli
""",
)
cli.py
@click.group()
@click.version_option(package_name='my_command_line_interface') # <-- ADDED
@click.pass_context
def cli(ctx):
pass
__main__.py
from .cli import cli
if __name__ == "__main__":
cli()
I want to implement mycommand --version
using python click. I have something like this working but it feels kinda clunky.
@click.group(invoke_without_command=True, no_args_is_help=True)
@click.pass_context
@click.option('--version', 'version')
def cli(ctx, version):
if version:
ctx.echo(f'{sys.argv[0]} {__version__}')
ctx.exit()
As it turns out, click
has a builtin decorator click.version_option
to accomplish this. The code now becomes:
@click.group()
@click.version_option(__version__)
@click.pass_context
def cli(ctx):
pass
You can use click.version_option
decorator to implement --version
option.
If your setup.py
like this and have version
click will read it automatically.
from setuptools import setup
setup(
name='application',
version='0.1',
py_modules=['application'],
install_requires=[
'Click',
],
)
The click.version_option
option without any argument will read version from setup.py
.
@click.group(invoke_without_command=True, no_args_is_help=True)
@click.pass_context
@click.version_option()
def cli(ctx):
...
Run and Result
$ application --version
application, version 0.1
I want to add another scenario that I ran into but isn’t explicitly stated here:
Your CLI name can be different from your entry point, which can mean you’ll need to provide the name explicitly if importlib_metadata can’t automatically find the name
Error
Without package_name='my_command_line_interface'
:
mycli --version
RuntimeError: ‘mycli’ is not installed. Try passing ‘package_name’ instead.
Setup
setup.py
setup(
name='my_command_line_interface',
version='0.1',
py_modules=['application'],
install_requires=[
'Click',
],
entry_points="""
[console_scripts]
mycli=my_command_line_interface.cli:cli
""",
)
cli.py
@click.group()
@click.version_option(package_name='my_command_line_interface') # <-- ADDED
@click.pass_context
def cli(ctx):
pass
__main__.py
from .cli import cli
if __name__ == "__main__":
cli()