Инструменты Python для написания скриптов с CLI: argparse, Click и Fire

Раздел: Библиотеки -> Работа со специализированными библиотеками

Библиотеки для создания интерфейсов командной строки в Python

Как быстро и гибко реализовать многофункциональное CLI с подкомандами и валидацией?

Библиотека Click предоставляет декораторы и контекстные объекты, позволяя создавать сложные интерфейсы командной строки с минимальным кодом. Она поддерживает автоматическую обработку аргументов, опций, подкоманд (группы), а также встроенную справку.

import click

@click.group()
def cli(): pass

@cli.command()
@click.argument('filename')
@click.option('--verbose', '-v', is_flag=True, help='Вывод подробной информации')
def process(filename, verbose):
    """Обработка файла"""
    if verbose:
        click.echo(f'Обработка {filename} с подробным выводом')
    else:
        click.echo(f'Обработка {filename}')

if __name__ == '__main__':
    cli()

Python библиотеки словари (библиотеки для работы со словарями в python)

После запуска python script.py --help будет сгенерирована справка. Для установки Click используется pip install click.

Типичные ошибки: Неправильная вложенность декораторов (группа должна быть объявлена первой), пропуск декоратора @click.group() для создания группы. Решение: всегда определять группу перед её командами.

Как обойтись стандартной библиотекой Python без установки сторонних пакетов?

Модуль argparse встроен в Python и предлагает декларативное описание аргументов. Подходит для простых и средних по сложности утилит.

import argparse

parser = argparse.ArgumentParser(description='Обработка файла')
parser.add_argument('filename', help='Имя файла для обработки')
parser.add_argument('-v', '--verbose', action='store_true', help='Подробный вывод')
args = parser.parse_args()

if args.verbose:
    print(f'Обработка {args.filename} с подробным выводом')
else:
    print(f'Обработка {args.filename}')

библиотека python user (пользовательские библиотеки python)

Для работы с подкомандами используется subparsers.

Проблема: Код становится громоздким при множестве подкоманд. Решение: Разделять парсеры на отдельные функции и использовать set_defaults для вызова обработчиков.

Как превратить любой объект Python в CLI без ручного описания аргументов?

Библиотека Fire автоматически анализирует сигнатуры функций или классов и генерирует команды. Подходит для быстрого прототипирования.

import fire

class Calculator:
    def add(self, a, b):
        return a + b
    def multiply(self, a, b):
        return a * b

if __name__ == '__main__':
    fire.Fire(Calculator)

Запуск python script.py add 3 4 вернёт 7.

Сложности: Ограниченный контроль над справкой и типизацией. Для сложной валидации лучше использовать Click.

- библиотеки работы с файлами python (библиотеки для работы с файлами в python)
- Python библиотека сети (сетевая библиотека в python)

Расширенные примеры использования библиотек для CLI

Click: контекст и обратные вызовы

Пример
import click

@click.group()
@click.option('--debug/--no-debug', default=False)
@click.pass_context
def cli(ctx, debug):
    ctx.ensure_object(dict)
    ctx.obj['DEBUG'] = debug

@cli.command()
@click.argument('name')
@click.pass_context
def hello(ctx, name):
    debug = ctx.obj['DEBUG']
    if debug:
        click.echo(f'Debug mode ON, name={name}')
    click.echo(f'Hello, {name}!')

if __name__ == '__main__':
    cli()

Результат при запуске python script.py --debug hello World:

Debug mode ON, name=World
Hello, World!

argparse: подкоманды (subparsers)

Пример
import argparse

def cmd_copy(args):
    print(f'Copy from {args.source} to {args.dest}')

def cmd_move(args):
    print(f'Move from {args.source} to {args.dest}')

parser = argparse.ArgumentParser(description='File operations')
subparsers = parser.add_subparsers(dest='command')

copy_parser = subparsers.add_parser('copy', help='Copy file')
copy_parser.add_argument('source')
copy_parser.add_argument('dest')
copy_parser.set_defaults(func=cmd_copy)

move_parser = subparsers.add_parser('move', help='Move file')
move_parser.add_argument('source')
move_parser.add_argument('dest')
move_parser.set_defaults(func=cmd_move)

args = parser.parse_args()
if hasattr(args, 'func'):
    args.func(args)
else:
    parser.print_help()

Запуск python script.py copy in.txt out.txt выведет:

Copy from in.txt to out.txt

Fire: работа с несколькими функциями

Пример
import fire

def greet(greeting='Hello', name='World'):
    print(f'{greeting}, {name}!')

def add(x, y):
    return x + y

if __name__ == '__main__':
    fire.Fire({'greet': greet, 'add': add})

Вызов python script.py greet --greeting=Hi --name=Pythonista даст:

Hi, Pythonista!

Click: дополнительные проверки через Callback

Пример
import click

def validate_positive(ctx, param, value):
    if value <= 0:
        raise click.BadParameter('Число должно быть положительным')
    return value

@click.command()
@click.option('--count', type=int, callback=validate_positive, help='Количество')
def process(count):
    click.echo(f'Count = {count}')

if __name__ == '__main__':
    process()

При попытке python script.py --count -5 возникнет ошибка:

Error: Invalid value for '--count': Число должно быть положительным

Библиотека скриптов в Python - comments

En
библиотека скриптов python (python)