Мощный инструмент автоматизации задач Python! Руководство по началу работы с Invoke Ten Minute

Python

Тогда предыдущий "токсик учебник", и только что переведённый"nox-документация", мы продолжаем говорить на тему автоматизации задач Python.

Автор nox выступил с докладом под названием «Break the Cycle: Three excellent Python tools to automate repetitive tasks"Sharing (адрес просмотра станции B: https://b23.tv/av86640235) она представила три инструмента автоматизации задач: Tox, NOx и Invoke, последняя тема этой статьи - Invoke.

1. Что может делать призыв?

Invoke отделен от известного инструмента удаленного развертывания Fabric и вместе с paramiko является двумя основными базовыми компонентами Fabric.

Помимо того, что это инструмент командной строки, он фокусируется на «выполнении задач», который может маркировать и организовывать задачи, а также выполнять задачи через CLI (интерфейс командной строки или интерфейс командной строки) и команды оболочки.

Кроме того, инструмент автоматизации задач, invoke отличается от tox/nox, который мы представили ранее:

  • TOX / NOX в основном для автоматизации в упаковке, тестировании, непрерывной интеграции и т. Д. (Конечно, они могут сделать больше, чем это)
  • Invoke является более универсальным, его можно использовать в любом сценарии, требующем «задач выполнения», которые могут быть группами задач без параллелей или рабочим процессом для последовательных зависимых шагов.

У invoke есть звезда 2,7 тыс. на Github, и он очень популярен Давайте посмотрим, как он используется?

2. Как использовать вызов?

Во-первых, установка проста:pip install invoke.

Во-вторых, в простом использовании есть следующие элементы:

  • файл задания. Создайте файл tasks.py.
  • @task декоратор. Добавление декоратора @task к функции может пометить функцию как задачу и принять управление планированием вызова.
  • параметр контекста. Добавьте аргумент контекста в украшенную функцию, обратите внимание, что это должен быть первый параметр, и соглашение об именах может быть изменено.cилиctxилиcontext.
  • выполнение командной строки. выполнить в командной строкеinvoke --listЧтобы просмотреть все задачи, запуститеinvoke xxxдля выполнения задачи с именем xxx. «вызов» в командной строке можно сократить до «inv».

Вот простой пример:

# 文件名:tasks.py
from invoke import task

@task
def hello(c):
    print("Hello world!")

@task
def greet(c, name):
    c.run(f"echo {name}加油!")

В приведенном выше коде мы определили две задачи:

  • Задача «hello» вызывает встроенную функцию печати Python, которая печатает строку «Hello world!»
  • Задача «greet» вызывает метод run() с параметром контекста, может выполнять команду оболочки и в этом случае также принимает аргумент. В команде оболочки эхо можно понимать как печать, так что это также задача печати, которая напечатает «xxx Давай!» (xxx — это переданный нами параметр)

Приведенный выше код написан в файле tasks.py, сначала импортируйте декораторfrom invoke import task, декоратор @task может не принимать параметров или принимать параметры (см. следующий раздел), а декорируемая им функция является задачей.

Параметр контекста (то есть "c" в приведенном выше примере) должен быть указан явно. Если этот параметр отсутствует, во время выполнения будет выдано исключение: "TypeError: Tasks must have initial Context arguments!"

Затем в том же каталоге файла tasks.py откройте окно командной строки и выполните команду. Если файл задачи не найден в месте выполнения, будет сообщено об ошибке: «Не удается найти коллекцию с именем «задачи»!»

Обычно, выполняяinv --listилиinv -l, вы можете увидеть список всех задач (отсортированных по алфавиту):

>>> inv -l
Available tasks:

  greet
  hello

Выполняем эти две задачи по очереди.При передаче параметров можно передавать параметры по умолчанию позиционными параметрами, либо можно указать ключевые слова для передачи параметров. оказаться:

>>> inv hello
Hello world!
>>> inv greet 武汉
武汉加油!
>>> inv greet --name="武汉"
武汉加油!

Когда аргументы отсутствуют, сообщается об ошибке: 'greet' не получил требуемых позиционных аргументов: 'имя'; когда есть избыточные аргументы, сообщается об ошибке: Не знаю, что такое '???'!

3. Как хорошо использовать вызов?

После введения простого использования вызова мы знаем несколько необходимых ему элементов, а также приблизительно знаем этапы его использования, за которыми следуют другие его применения.

3.1 Добавить справочную информацию

В приведенном выше примере «inv -l» может видеть только имя задачи, без необходимой вспомогательной информации, для повышения читабельности мы можем написать:

@task(help={'name': 'A param for test'})
def greet(c, name):
    """
    A test for shell command.
    Second line.
    """
    c.run(f"echo {name}加油!")

Среди них первая строка строки документации будет использоваться как выдержка и отображаться в результате запроса «inv -l», а полное содержимое и содержимое справки @task будут отображаться в «inv --help» соответственно. :

>>> inv -l
Available tasks:

  greet   A test for shell command.
>>> inv --help greet
Usage: inv[oke] [--core-opts] greet [--options] [other tasks here ...]

Docstring:
  A test for shell command.
  Second line.

Options:
  -n STRING, --name=STRING   A param for test

3.2 Декомпозиция и состав задач

Обычно крупную задачу можно разбить на набор мелких задач, и наоборот, серию мелких задач можно объединить в большую задачу. При декомпозиции, абстрагировании и объединении задач есть две идеи:

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

Первая идея проста для понимания, проста в реализации и использовании, но ее недостаток в том, что ей не хватает гибкости, и в одиночку сложно выполнять некоторые/некоторые подзадачи. Он подходит для относительно независимых одиночных задач и обычно может выполняться без вызова (преимущество использования вызова состоит в том, что оно поддерживает командную строку).

Второй способ мышления более гибкий, что облегчает выполнение как одной задачи, так и совместное выполнение нескольких задач. На самом деле, этот сценарий является сценарием, в котором вызов имеет наибольшую ценность.

Итак, как же в invoke реализуется композиция пошаговых задач? Его можно указать в параметрах «pre» и «post» декоратора @task, представляя пред-задачу и пост-задачу соответственно:

@task
def clean(c):
    c.run("echo clean")

@task
def message(c):
    c.run("echo message")

@task(pre=[clean], post=[message])
def build(c):
    c.run("echo build")

Задачи очистки и сообщения — это подзадачи, которые можно вызывать по отдельности или объединять как пред- и пост-задачи задачи сборки:

>>> inv clean
clean
>>> inv message
message
>>> inv build
clean
build
message

Эти два параметра являются типами списка, и можно задать несколько задач. Кроме того, по умолчанию позиционные параметры декоратора @task рассматриваются как предварительные задачи.Следуя приведенному выше коду, мы пишем один:

@task(clean, message)
def test(c):
    c.run("echo test")

Затем выполните, вы обнаружите, что оба параметра считаются предварительными задачами:

>>> inv test
clean
message
test

3.3 Разделение и интеграция модулей

Если вы хотите управлять множеством относительно независимых крупномасштабных задач или если вам нужно, чтобы несколько команд поддерживали свои собственные задачи, то необходимо разделить и интегрировать tasks.py.

Например, теперь есть несколько tasks.py, которые представляют собой относительно полные и независимые модули задач. Неудобно помещать все содержимое в один файл. Итак, как их эффективно интегрировать и управлять ими?

Invoke обеспечивает поддержку для этого. Во-первых, сохраните только один файл с именем «tasks.py», во-вторых, импортируйте другие переименованные файлы задач в этот файл и, наконец, используйте класс Collection вызова, чтобы связать их.

Мы переименовали первый файл примера в этой статье в task1.py и создали новый файл tasks.py со следующим содержимым:

# 文件名:tasks.py
from invoke import Collection, task
import task1

@task
def deploy(c):
    c.run("echo deploy")

namespace = Collection(task1, deploy)

Каждый py-файл имеет независимое пространство имен, и здесь мы можем использовать Collection для создания нового пространства имен для обеспечения единого управления всеми задачами. Эффект следующий:

>>> inv -l
Available tasks:

  deploy
  task1.greet
  task1.hello
>>> inv deploy
deploy
>>> inv task1.hello
Hello world!
>>> inv task1.greet 武汉
武汉加油!

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

3.4 Интерактивная работа

Для некоторых задач может потребоваться интерактивный ввод, например запрос "y" и нажатие клавиши ввода перед продолжением. Если во время выполнения задачи требуется участие человека, возможность автоматизации задач сильно снижается.

Invoke предоставляет возможности мониторинга во время выполнения программы и может отслеживатьstdoutиstderrи поддерживаетstdinВведите необходимую информацию в .

Например, предположим, что задача (возбудимая программа) запрашивает «Вы готовы? [д/н]» при выполнении, а последующие операции будут выполняться только в том случае, если введено «д» и нажата клавиша «Ввод».

Затем укажите в коде содержимое параметра responses, пока отслеживается совпадающая информация, программа автоматически выполнит соответствующую операцию:

responses = {r"Are you ready? \[y/n\] ": "y\n"}
ctx.run("excitable-program", responses=responses)

responses — это тип словаря, а пары ключ-значение — это содержимое прослушивателя и содержимое его ответа соответственно. Обратите внимание, что значения ключей обрабатываются как регулярные выражения, поэтому квадратные скобки, как в этом примере, должны быть экранированы в первую очередь.

3.5 Как библиотека инструментов командной строки

В Python есть много полезных библиотек инструментов командной строки, например, в стандартной библиотеке.argparse, Открытый исходный код автора FlaskclickОткрытый исходный код с Googlefireи т. д., и Invoke также доступен в виде библиотеки инструментов командной строки.

(PS: Одноклассник Prodesire написал серию статей «Путешествие по командной строке Python», в которых подробно рассказывается об использовании нескольких других библиотек инструментов командной строки. Я перепечатал большинство из них в публичном аккаунте «Python Cat». Студенты могут просмотреть исторические статьи.)

На самом деле, проект Fabric изначально выделил вызов в отдельную библиотеку, чтобы он взял на себя задачу разбора командной строки и выполнения подкоманд. Таким образом, Invoke не только является инструментом автоматического управления задачами, но и может использоваться для разработки инструментов командной строки.

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

Предположим, мы хотим разработать инструмент для тестирования, который позволяет пользователямpip install testerустановлен, и этот инструмент предоставляет две команды выполнения:tester unitиtester intergration.

Эти две подкоманды должны быть определены в файле tasks.py:

# tasks.py
from invoke import task

@task
def unit(c):
    print("Running unit tests!")

@task
def integration(c):
    print("Running integration tests!")

Затем введите его в файл входа в программу:

# main.py
from invoke import Collection, Program
from tester import tasks

program = Program(namespace=Collection.from_module(tasks), version='0.1.0')

Наконец, объявите функцию входа в файле пакета:

# setup.py
setup(
    name='tester',
    version='0.1.0',
    packages=['tester'],
    install_requires=['invoke'],
    entry_points={
        'console_scripts': ['tester = tester.main:program.run']
    }
)

Библиотека, упакованная и выпущенная таким образом, представляет собой полнофункциональный инструмент командной строки:

$ tester --version
Tester 0.1.0
$ tester --help
Usage: tester [--core-opts] <subcommand> [--subcommand-opts] ...

Core options:
  ... core options here, minus task-related ones ...

Subcommands:
  unit
  integration

$ tester --list
No idea what '--list' is!
$ tester unit
Running unit tests!

Простой в использовании, готовый к работе, Invoke — это библиотека инструментов командной строки, которую стоит рассмотреть. Для более подробного использования см.Документация.

4. Резюме

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

Эта статья представляет его основное использование и промежуточное содержание в аспектах 5. Я полагаю, что читатели будут иметь определенное представление об этом. Официальная документация Invoke очень подробная, из-за ограничений по объему эта статья не будет подробно расширяться, если вам интересно, пожалуйста, сделайте это самостоятельно.Проверьте документОй.

--------------

Публичный номер: Python cat (ID: python_cat)

Номер заголовка: Кот-питон

Зная: Кот под цветком гороха

Наггетс: Кошки под горошком

публика【Питон кот], в этом выпуске публикуется серия высококачественных статей, в том числе серия Meow Star Philosophy Cat, расширенная серия Python, серия рекомендаций по хорошим книгам, технические статьи, высококачественные рекомендации и перевод на английский язык и т. д. Добро пожаловать, обратите внимание.