Создание интерфейсов командной строки (CLI) с помощью Fire в Python

Введение Интерфейс командной строки (CLI) [https://en.wikipedia.org/wiki/Command-line_interface] - это способ взаимодействия с компьютерами с помощью текстовых команд. Многие инструменты, для которых не требуется графический интерфейс, написаны как инструменты / утилиты CLI. Хотя в Python есть встроенный модуль argparse [/ create-command-line-utilities-with-pythons-argparse /], существуют другие библиотеки с аналогичной функциональностью. Эти библиотеки могут помочь нам в написании сценариев CLI, предоставляя такие услуги, как параметры синтаксического анализа и флаги.

Вступление

Интерфейс командной строки (CLI) - это способ взаимодействия с компьютерами с помощью текстовых команд.

Многие инструменты, для которых не требуется графический интерфейс, написаны как инструменты / утилиты CLI. Хотя в Python есть встроенный модуль argparse , существуют и другие библиотеки с аналогичной функциональностью.

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

В этой статье обсуждается библиотека Python Fire , написанная Google Inc., полезный инструмент для создания интерфейса командной строки с минимальным кодом.

Общая форма приложений CLI

Прежде чем мы начнем с Fire давайте попробуем разобраться в основах программ интерфейса командной строки в целом. В зависимости от программы и команды, общий шаблон интерфейса командной строки можно резюмировать следующим образом:

 prompt command parameter1 parameter2 ... parameterN 
  • приглашение - это последовательность символов, которая предлагает пользователю ввести команду
  • команда - это имя программы, которую выполняет пользователь (например, ls )
  • параметры - это необязательные токены, которые дополняют или изменяют вывод команды

Программа CLI выполняется путем ввода имени программы после появления prompt , в данном случае символа $.

Здесь мы используем команду ls которая возвращает список имен файлов в каталоге, текущий каталог используется по умолчанию:

 $ ls 
 README.md 
 python 

Вы можете изменить поведение или вывод программы командной строки, предоставив ей список токенов или параметров, более известных как флаги . Попробуем проверить флаг команды ls :

 $ ls -l 
 -rwxrwxrwx 1 pandeytapan pandeytapan 10 Sep 23 18:29 README.md 
 drwxrwxrwx 1 pandeytapan pandeytapan 512 Sep 23 18:29 python 

Как видите, после передачи -l мы получаем дополнительную информацию для каждой записи, такую как владелец, группа и размер файла.

Флаги с одним дефисом ( - ) называются короткими опциями, а -- ) называются длинными опциями. Оба вида можно использовать вместе в одной команде, как в следующем примере:

 $ ls -l --time-style=full-iso 
 -rwxrwxrwx 1 pandeytapan pandeytapan 10 2020-09-23 18:29:25.501149000 +0530 README.md 
 drwxrwxrwx 1 pandeytapan pandeytapan 512 2020-09-23 18:29:25.506148600 +0530 python 

Разница между коротким и длинным вариантами:

  1. Короткие варианты можно объединить в цепочку
    • Если мы хотим использовать как -l и -a короткие варианты , мы просто введите -al
  2. Короткие варианты обозначаются одним символом, а длинные варианты имеют полное имя, разделенное дефисом, и не могут быть объединены в цепочку.

--time-style работает с -l и управляет форматом времени отображения для списка каталогов.

Интерфейс командной строки предоставляет пользователю простой способ настройки и запуска приложения из командной строки. Библиотека Google Python Fire упрощает добавление компонента обработки интерфейса командной строки к любому существующему сценарию Python.

Давайте посмотрим, как создать приложение из командной строки с помощью Python Fire .

Монтаж

Давайте продолжим и установим библиотеку с помощью pip :

 $ pip install fire 

Python Fire работает с любым объектом Python, т.е. функциями, классами, словарями, списками и т. Д. Давайте попробуем понять использование Python Fire на некоторых примерах.

Создание приложения CLI с помощью Python Fire

Создадим скрипт, скажем fire_cli.py и поместим в него функцию:

 def greet_mankind(): 
 """Greets you with Hello World""" 
 return 'Hello World' 

При запуске этой программы в оболочке Python вывод будет:

 >>> from fire_cli import greet_mankind 
 >>> greet_mankind() 
 'Hello World' 
 >>> 

Мы можем легко превратить этот скрипт в приложение CLI, используя Python Fire:

 import fire 
 
 def greet_mankind(): 
 """ 
 Returns a textual message 
 """ 
 return 'Hello World' 
 
 if __name__ == '__main__': 
 fire.Fire() 

fire.Fire() превращает модуль, т.е. fire_cli.py в приложение Fire CLI. Более того, он автоматически предоставил функцию greet_mankind()

Теперь мы можем сохранить и запустить приведенный выше сценарий как CLI следующим образом:

 $ python fire_greet_mk_cli.py greet_mankind 
 Hello World 

В качестве напоминания давайте разберемся с вызовом:

  • $ - это подсказка
  • python - интерпретатор команд
  • fire_cli.py - это модуль, содержащий команду CLI
  • greet_mankind - это команда

Передача аргументов команде

Давайте создадим другое приложение CLI, которое принимает имя в качестве параметра и отображает настраиваемое приветственное сообщение:

 import fire 
 
 def greetings(name): 
 ''' 
 Returns a greeting message 
 Parameters 
 ---------- 
 name : string 
 String that represents the addresses name 
 
 Returns 
 ------- 
 string 
 greeting message concatenated with name 
 ''' 
 return 'Hello %s' % name 
 
 if __name__ == '__main__': 
 fire.Fire() 

Здесь у нас есть функция, которая принимает строку name . Python Fire автоматически подбирает это, и если мы предоставим аргумент после greetings , он привяжет этот ввод к параметру name Мы также добавили комментарий как своего рода документацию для команды --help .

Вот как мы можем запустить эту команду из командной строки:

 $ python fire_greet_cli.py greetings Robin 
 Hello Robin 

Приложение Fire CLI может использовать --help для проверки описания команды, сгенерированной из документов Python:

 python fire_greet_cli.py greetings --help 
 NAME 
 fire_greet_cli.py greetings - Returns a greeting message 
 
 SYNOPSIS 
 fire_greet_cli.py greetings NAME 
 
 DESCRIPTION 
 Returns a greetings message 
 
 POSITIONAL ARGUMENTS 
 NAME 
 String that represents the addresses name 
 
 NOTES 
 You can also use flags syntax for POSITIONAL ARGUMENTS 

Установка функции в качестве точки входа

С небольшими изменениями мы можем контролировать отображение функции greetings() в командной строке и установить ее как точку входа по умолчанию:

 import fire 
 
 def greetings(name): 
 ''' 
 Returns a greeting message 
 :param name: string argument 
 :return: greeting message appended with name 
 ''' 
 return 'Hello %s' % name 
 
 if __name__ == '__main__': 
 fire.Fire(greetings) 

Вот как мы сейчас запустим команду:

 $ python fire_greet_cli.py Robin 
 Hello Robin 

Итак, на этот раз нам больше не нужно вызывать команду, поскольку мы greetings как точку входа с помощью Fire() . Здесь следует отметить одну вещь: в этой версии мы можем передать только один аргумент :

 $ python fire_greet_cli.py Robin Hood 
 ERROR: Could not consume arg: Hood 
 ... 
 $ python fire_greet_cli.py Robin 
 Hello Robin 

Разбор аргументов

Библиотека Fire также работает с классами. Давайте определим класс CustomSequence который генерирует и возвращает список чисел между start и end :

 import fire 
 
 class CustomSequence: 
 '''Class that generates a sequence of numbers''' 
 def __init__(self, offset=1): 
 ''' 
 Parameters 
 ---------- 
 offset : int, optional 
 Number controlling the difference between two generated values 
 ''' 
 self.offset = offset 
 
 def generate(self, start, stop): 
 ''' 
 Generates the sequence of numbers 
 
 Parameters 
 ---------- 
 start : int 
 Number that represents the elements lower bound 
 stop : int 
 Number that represents the elements upper bound 
 
 Returns 
 ------- 
 string 
 a string that represents the generated sequence 
 ''' 
 return ' '.join(str(item) for item in range(start, stop, self.offset)) 
 
 if __name__ == '__main__': 
 fire.Fire(CustomSequence) 

Вот как мы генерируем последовательность с помощью этой утилиты командной строки:

 $ python fire_gen_cli.py generate 1 10 
 1 2 3 4 5 6 7 8 9 

Мы использовали класс вместо функции, потому что в отличие от функций, если мы хотим передать аргумент конструктору, он всегда должен быть представлен как флаг командной строки с двойными дефисами (например, --offset=2 ).

Поэтому наше приложение CLI поддерживает необязательный аргумент --offset который будет передан конструктору класса. Это изменяет вывод, контролируя разницу между двумя последовательными сгенерированными значениями:

Вот результат со значением смещения 2:

 $ python fire_gen_cli.py generate 1 10 --offset=2 
 1 3 5 7 9 

Аргументы конструктора всегда передаются с использованием синтаксиса флага, тогда как аргументы другим методам или функциям передаются позиционно или по имени:

 $ python fire_gen_cli.py generate --start=10 --stop=20 
 10 11 12 13 14 15 16 17 18 19 
 $ python fire_gen_cli.py generate 10 20 
 10 11 12 13 14 15 16 17 18 19 
 $ python fire_gen_cli.py generate --start=10 --stop=20 --offset=2 
 10 12 14 16 18 

Мы можем проверить использование команды generate с помощью флага --help Это даст информацию об использовании интерфейса командной строки:

 $ python fire_gen_cli.py generate --help 
 INFO: Showing help with the command 'fire_gen_cli.py generate -- --help'. 
 
 NAME 
 fire_gen_cli.py generate - Generates the sequence of numbers 
 
 SYNOPSIS 
 fire_gen_cli.py generate START STOP 
 
 DESCRIPTION 
 Generates the sequence of numbers 
 
 POSITIONAL ARGUMENTS 
 START 
 Number that represents the first value for the sequence 
 STOP 
 Number that represents the ending value for the sequence 
 
 NOTES 
 You can also use flags syntax for POSITIONAL ARGUMENTS 

Использование --help с модулем дает нам информацию о его использовании:

 $ python fire_gen_cli.py --help 
 INFO: Showing help with the command 'fire_gen_cli.py -- --help'. 
 
 NAME 
 fire_gen_cli.py - Class that generates a sequence of numbers 
 
 SYNOPSIS 
 fire_gen_cli.py <flags> 
 
 DESCRIPTION 
 Class that generates a sequence of numbers 
 
 FLAGS 
 --offset=OFFSET 

Пожарные флаги

Интерфейс командной строки Fire имеет множество встроенных флагов. Мы уже видели --help , но еще один полезный флаг - --interactive . Использование этого флага переводит нас в режим Python REPL с уже определенным модулем.

Это очень полезно для тестирования команд:

 $ python fire_greet_cli.py -- --interactive 
 Fire is starting a Python REPL with the following objects: 
 Modules: fire 
 Objects: component, fire_greet_cli.py, greetings, result, trace 
 
 Python 3.7.8 (tags/v3.7.8:4b47a5b6ba, Jun 28 2020, 08:53:46) [MSC v.1916 64 bit (AMD64)] 
 Type 'copyright', 'credits' or 'license' for more information 
 IPython 7.16.1 -- An enhanced Interactive Python. Type '?' for help. 
 
 
 In [1]: greetings("Robin") 
 Out[1]: 'Hello Robin' 

Обратите внимание, что флаги Fire должны быть отделены от других параметров двумя дефисами ( -- ), поэтому, если мы хотим использовать --interactive --help и --interactive, это будет выглядеть примерно так:

 $ python fire_greet_cli.py -- --help --interactive 

Заключение

Библиотека Google Python Fire - это быстрый и простой способ создания интерфейсов командной строки (CLI) практически для любого объекта Python.

В этой статье мы рассмотрели, как установить Python Fire, а также сгенерировать простые интерфейсы командной строки.

comments powered by Disqus