Click интерфейс командной строки
pip install click
Базовая концепция
Клик базируется на декларации команд через декораторы. Функция становится инструментом командной строки, когда снабжена декоратором @click.command()
import click
@click.command()
def hello():
click.echo('Hello World!')
if __name__ == '__main__':
hello()
@click.eshoe()
используется вместо стандартного print()
для поддержки разных окружений, чтобы не сломать реализацию, если конфигурация нарушена.
Поддерживаются вложенные команды через декоратор @click.group()
@click.group()
def cli():
pass
@click.command()
def initdb():
click.echo('Initialized the database')
@click.command()
def dropdb():
click.echo('Dropped the database')
cli.add_command(initdb)
cli.add_command(dropdb)
или для простых скриптов
@click.group()
def cli():
pass
@cli.command()
def initdb():
click.echo('Initialized the database')
@cli.command()
def dropdb():
click.echo('Dropped the database')
if __name__ == '__main__':
cli()
Так-же команды могут регистрироваться в группы позже
@click.command()
def greet():
click.echo("Hello, World!")
@click.group()
def group():
pass
group.add_command(greet)
Добавление аргументов и опций производится через @click.option()
и @click.argument()
@click.command()
@click.option('--count', default=1, help='number of greetings')
@click.argument('name')
def hello(count, name):
for x in range(count):
click.echo(f"Hello {name}!")
$ python hello.py --help
Usage: hello.py [OPTIONS] NAME
Options:
--count INTEGER number of greetings
--help Show this message and exit.
Поддержка интеграции с [setuptools]
Параметры
Доступны два типа параметров - опции и аргументы. Рекомендуется использовать аргументы исключительно для таких вещей, как переход к подкомандам или ввод имен файлов/URL-адресов, а опции использовать для всего остального.
Для опций доступно:
- автоматическое дополнение для пропущенных опций
- булевы значения
- опции могут быть добавлены из переменных окружения (аругменты нет)
- опции полностью задокументированы и будут отображены с вызовом
--help
флага
Типы параметров определены в самом click. Смотри доки. Кроме того, можно задать кастомные типы параметров
Опции
Имена опций могут быть использованы как аргументы при вызове декорированной функции. Порядок выбора имен:
- если имя не имеет префикса, оно используется как имя аргумента и не используется как имя опции в командной строке
- если хотя бы одно имя снабжено двойными черточками - первое из таких используется как имя опции
- в остальных случаях используется первое имя с одинарной черточкой
При ээтом большие буквы конвертятся в маленькие, а избыточные черточки игнорируются:
- “-f”, “–foo-bar”, the name is
foo_bar
- “-x”, the name is
x
- “-f”, “–filename”, “dest”, the name is
dest
- ”–CamelCase”, the name is
camelcase
- “-f”, “-fb”, the name is
f
- ”–f”, “–foo-bar”, the name is
f
- ”—f”, the name is
f
@click.command()
@click.option('-s', '--string-to-echo')
def echo(string_to_echo):
click.echo(string_to_echo)
@click.command()
@click.option('-s', '--string-to-echo', 'string')
def echo(string):
click.echo(string)
Наиболее базовые опции - это опции значений
Можно определить тип, обязательность параметра, показ дефолтных значений при запросе через --help
. Кроме того, можно определить в качестве имен параметров заррезервированные имена
@click.command()
@click.option('--from', '-f', 'from_')
@click.option('--to', '-t')
def reserved_param_name(from_, to):
click.echo(f"from {from_} to {to}")
Можно передавать несколько значений опции
@click.command()
@click.option('--pos', nargs=2, type=float)
def findme(pos):
a, b = pos
click.echo(f"{a} / {b}")
Кроме того, можно использовать кортежи и множественные опции по одному имени
@click.command()
@click.option('-v', '--verbose', count=True)
def log(verbose):
click.echo(f"Verbosity: {verbose}")
$ commit -m foo -m bar
foo
bar
Булевы флаги используют определение двух имен через слеш
import sys
@click.command()
@click.option('--shout/--no-shout', default=False)
def info(shout):
rv = sys.platform
if shout:
rv = rv.upper() + '!!!!111'
click.echo(rv)
$ info --shout
LINUX!!!!111
$ info --no-shout
linux
$ info
linux
Если требуется только одно состояние флага, то можно так:
import sys
@click.command()
@click.option('--shout', is_flag=True)
def info(shout):
rv = sys.platform
if shout:
rv = rv.upper() + '!!!!111'
click.echo(rv)
Переключатель опций
import sys
@click.command()
@click.option('--upper', 'transformation', flag_value='upper',
default=True)
@click.option('--lower', 'transformation', flag_value='lower')
def info(transformation):
click.echo(getattr(sys.platform, transformation)())
$ info --upper
LINUX
$ info --lower
linux
$ info
LINUX
Опция выбора опций
Можно передать список (или кортеж), из которого можно выбрать значение опции
@click.command()
@click.option('--hash-type',
type=click.Choice(['MD5', 'SHA1'], case_sensitive=False))
def digest(hash_type):
click.echo(hash_type)
Ввод
@click.command()
@click.option('--name', prompt=True)
def hello(name):
click.echo(f"Hello {name}!")
Или так:
@click.command()
@click.option('--name', prompt='Your name please')
def hello(name):
click.echo(f"Hello {name}!")
Ввод пародей тоже реализован
Колбеки
Запрос согласия для опасных операций
Значения из переменных окружения
Есть несколько способов. Во первых можно реализовать через auto_envvar_prefix=
самой функции
@click.command()
@click.option('--username')
def greet(username):
click.echo(f'Hello {username}!')
if __name__ == '__main__':
greet(auto_envvar_prefix='GREETER')
Второй вариант - вручную добавить в декоратор черех envvar=
@click.command()
@click.option('--username', envvar='USERNAME')
def greet(username):
click.echo(f"Hello {username}!")
if __name__ == '__main__':
greet()
Можно использовать множественные переменные
Другие префиксы
Опция ренжа
Валидация
Опциональные значения
Аргументы
Работауют идентично опциям, но являются позиционными. поддерживают лишь часть функционала и не документируются.
@click.command()
@click.argument('filename')
def touch(filename):
"""Print FILENAME."""
click.echo(filename)
$ touch foo.txt
foo.txt
Варианты использования:
- переменные
- аргументы файлов
- аргументы путей файлов
- использование переменных окружения
- аргументы-опции
Команды и группы
Это одна из главных фичей пакета - возможность собирать несколько аргументво в бандлы. Реализуется через command
, group
и multicommand
Что доступно:
- передача контекста между командами
- создание собственных групп команд
- мерж групп команд между собой
- цепочки мультикоманд
- пайплайны мультикоманд
- переопределение дефолтных значений
- дефолтные значения для разных контекстов
Документирование для –help
Дополнительные паттерны
- алиасы команд
- модификация параметров
- приведение токенов к правильному формату
- вызов других команд из команд
- определения порядка колбеков
- передача неизвестных опций в следующий контекст
- доступ к глобальному контексту
- определение источника параметра (логирование)
- управление ресурсами группы команд
Как все это тестировать
Дополнительные утилиты
- вывод в stdout
- ANSI colors
- пагинация
- очистка страницы
- получение отдельных знаков из терминала (к примеру y/n)
- press any key
- запуск редактора
- запуск приложения
- вывод названия файла
- использование стандартного потока
- открытие файла через контекстный менеджер
- поиск папки приложения
- прогресс-бар
Больше информации обо всем в документации проекта или на github
Смотри так-же:
- [argparsing]
- Click-log: Simple and beautiful logging for click applications
- asyncclick
- [python-standart-library]
- [poetry]
- poethepoet энтрипоинт для [poetry]
- [makefile]
- [cl]