С Тайпер , вы можете написать инструменты командной строки в Python, интуитивно и легко. В то же время Тайпер достаточно гибкий, чтобы справиться с сложности, брошенной на него.
Тип подсказки
Среди командной линии помощников библиотеки для Python (например, argparse и Нажмите ), Тайпер уникален в использовании Тип подсказки Анкет
Python является языком программирования, который не требует объявлений статического типа. Другими словами, я могу написать my_variable
без необходимости указать, что my_variable
действительно целое число, а не строка.
Несмотря на необязательное, Python поддерживает подсказки статического типа. Другими словами, я могу написать my_variable:
Намекнуть на это my_variable
Всегда должно быть целым числом. Как это использовать? Инструмент mypy Можно запустить на модулях и пакетах Python, чтобы выручить проблемы или подтвердить вашу удивительность.
Конечный результат? Я постоянно впечатляю, как даже на небольших проектах, mypy и подсказки типа определяют проблемы в моем коде, которые вызвали бы значительные диагностические головные боли.
Если вы все равно пишете подсказки типа, используя Тайпер Для создания интерфейса командной строки имеет большой смысл. Давайте пройдемся по простому примеру того, как это может выглядеть.
Создайте проект и добавьте модуль
Чтобы управлять проектом, я использую поэзию. Поэзия является зрелым и современным инструментом для управления проектом Python и его зависимостей. Вам может понравиться чтение Мое введение в поэзию а также краткое Объяснение использования поэзии для разоблачения сценариев командной строки в вашем проекте.
Вам, конечно, не нужно использовать поэзию для построения и поддержания проекта. Я рекомендую рассматривать ваш проект как пакет Python и использовать виртуальные среды. Не стесняйтесь просматривать мой Демонстрация и обзор инструментов для управления виртуальными средами Анкет Что касается упаковки проекта Python традиционным способом, используя setup.py
, не поэзия, вам может понравиться Моя среда Python Dev Intro Анкет
Чтобы создать проект с поэзией, что -то подобное должно работать:
poetry new --name greet --src typergreet cd typergreet
Обратите внимание, что в этом случае я называю внутренний пакет приветствовать
Но каталог проектов назван Typergreet
Анкет
Вам не нужно использовать SRC
Структура для вашего пакета, но я использую его по причинам Анкет
Затем я добавляю файл с именем Greet.py
в SRC/Greet
подкаталог со следующим содержанием:
"""Send greetings.""" import time import arrow # type: ignore def greet(tz: str, repeat: int = 1, interval: int = 3) -> None: """Parse a timezone and greet a location a number of times.""" for i in range(repeat): if i > 0: # no delay needed on first round time.sleep(interval) now = arrow.now(tz) friendly_time = now.format("h:mm a") seconds = now.format("s") location = tz.split("/")[-1].replace("_", " ") print(f"Hello, {location}!") print(f"The time is {friendly_time} and {seconds} seconds.\n")
Обратите внимание на подсказки типа по каждому параметру функции, а также возвращаемое значение. Потому что в этой функции нет возврата (позор!) Возвратный тип Нет
Анкет
Установить зависимости
Нам нужно Стрелка и будет использовать Тайпер , поэтому они должны быть добавлены сейчас:
poetry add arrow typer[all]
Это даст нам стрелу, плюс Тайпер со всеми наворотами. Если вы не хотите расцветать вывод и обнаружение оболочки, вы можете опустить [Все]
Анкет
Мы используем подсказки типа, поэтому мы также хотим mypy
, но как Развитие зависимость. С Поэзия добавить
, это означает передачу -Д
флаг:
poetry add -D mypy
Проверьте подсказки типа
Чтобы убедиться, что у нас есть правильные подсказки типа, и код считает их, запустите mypy
:
poetry run mypy src/greet/greet.py
Проблемы не обнаружено? Превосходно.
При импорте этого пакета, даже при проведении тестов позже, мы захотим знать, что это тип намекает. Для этого создайте пустой py.typed
Файл в пакете. Есть много способов сделать это (даже с вашим текстовым редактором). Это работает в Bash и PowerShell:
echo "" | tee ./src/greet/py.typed
Добавить конечную точку сценария в pyproject.toml
Разоблачить Приветствую
Функция как сценарий командной строки, добавьте Tool.poetry.scripts
раздел к pyproject.toml
Анкет
[tool.poetry.scripts] greet = "greet.greet:greet"
Это устанавливает приветствовать
(скрипт), чтобы посмотреть в Приветствую
(пакет) для Приветствую
(модуль) и используйте приветствовать
(функция). Если у вас больше творчества для именования, сделайте это.
Теперь, когда сценарий настроен, установите пакет и сценарий с помощью
poetry install
Теперь давайте запустим недавно установленный скрипт:
$ poetry run greet Traceback (most recent call last): File "", line 1, in TypeError: greet() missing 1 required positional argument: 'tz'
Неудача – это путь к обучению. И мы учимся.
Использование аргументов командной строки Typer для анализа командной строки
Нам нужен способ проанализировать аргументы командной строки и передать их в качестве параметров функции. Тайпер Обнаружает типовые подсказки и выясняет аргументы и параметры командной строки соответственно.
Вот исходная функция, с добавлением Тайпера:
"""Send greetings.""" import time import arrow # type: ignore import typer app = typer.Typer() @app.command() def greet(tz: str, repeat: int = 1, interval: int = 3) -> None: """Parse a timezone and greet a location a number of times.""" for i in range(repeat): if i > 0: # no delay needed on first round time.sleep(interval) now = arrow.now(tz) friendly_time = now.format("h:mm a") seconds = now.format("s") location = tz.split("/")[-1].replace("_", " ") print(f"Hello, {location}!") print(f"The time is {friendly_time} and {seconds} seconds.\n") def run() -> None: """Run commands.""" app()
Что изменилось? Мы создали создание приложения Typer во всем мире с приложение. Typer ()
Анкет Таким образом, мы можем украсить любую функцию, которую мы хотим вызывать из командной строки, используя @app.command ()
декоратор.
Затем нам нужно было добавить командный бегун, чтобы выполнить приложение Typer. Это то, что run ()
функция выполняет.
Учитывая, что мы изменили точку записи сценария с Приветствую
к запустить
, это должно быть уточнено в pyproject.toml
Анкет Итак, необходимо следующее изменение:
[tool.poetry.scripts] greet = "greet.greet:run"
Теперь запустить
это функция, которую Приветствую
Команда будет указывать, а не Приветствую
Анкет
Со всем этим на месте у нас есть интерфейс рабочей командной строки.
$ poetry run greet --help Usage: greet [OPTIONS] TZ Parse a timezone and greet a location a number of times. Arguments: TZ [required] Options: --repeat INTEGER [default: 1] --interval INTEGER [default: 3] --install-completion Install completion for the current shell. --show-completion Show completion for the current shell, to copy it or customize the installation. --help Show this message and exit. $ $ poetry run greet --repeat 2 --interval 1 Africa/Johannesburg Hello, Johannesburg! The time is 1:06 pm and 38 seconds. Hello, Johannesburg! The time is 1:06 pm and 39 seconds.
Какой у нас вежливый и информированный инструмент командной строки.
Примечание. Дополнительные функции Typer добавляет по умолчанию: -Хельп
С описаниями, детализирующими аргументы и параметры, и возможность добавлять завершение оболочки, если пользователь желает.
Тестирование интерфейсов Typer с pytest
Интерфейсы тестирования командной строки могут потребовать небольшого творчества. К счастью, Тайпер предоставляет Clirunner
, бегун командной строки для тестирования. Если вы знакомы с Нажмите , он очень похож на Clirunner’s Clirunner. (Не удивительно, так как клик является зависимостью Тайпера.)
Поместите следующее в файле tests/test_greet.py
from typer.testing import CliRunner from greet.greet import app def test_greet_cli(): runner = CliRunner() result = runner.invoke(app, ["Europe/Madrid"]) assert result.exit_code == 0 assert "Hello, Madrid!" in result.output
Запустите вышеприведенное с Поэзия запустить pytest
Анкет
Тест проходит?
Счастье.
Альтернативы и дальнейшее чтение
Python является логическим выбором при создании инструментов командной строки, поэтому неудивительно, что существует множество вариантов для облегчения процесса.
- Можно проанализировать ваши собственные аргументы командной строки через Список предоставил
sys.argv
, как мы делали в ранее упомянутых Поэзия/CLI статья Анкет - Тем не менее, собственная библиотека Python’s Standard Argparse обеспечивает гораздо лучшую функциональность, простоту и эффективность. Я написал статью, похожую на эту, о Использование поэзии, Argparse и Pytest Анкет
- Я также написал краткие введения в следующие библиотеки командной строки:
- Питон Огнен
- Нажимать
- Я слышал отличные отзывы о Plumbum и Клео , но еще не попробовали их
- Для совершенно другого способа определения интерфейсов командной строки попробуйте docopt Анкет Определите интерфейсы в ваших докторах. Это не часто поддерживается, так что есть вилка docopt-ng .
Наслаждайтесь командной строкой!
Оригинал: “https://dev.to/bowmanjd/command-line-tools-in-python-with-typer-and-pytest-type-hints-are-useful-khg”