Командная строка Python: как создать гибкие CLI-интерфейсы

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Python-разработчики, желающие улучшить свои навыки в создании CLI-приложений
  • Студенты и начинающие программисты, интересующиеся автоматизацией задач с помощью Python
  • Профессиональные разработчики, ищущие эффективные инструменты для обработки командных аргументов и улучшения рабочего процесса

    Командная строка — тот интерфейс, который позволяет Python-разработчикам превратить код в мощный инструмент для повседневного использования. Представьте: вы автоматизировали сложную задачу, но каждый раз приходится редактировать скрипт для изменения параметров работы — неэффективно и утомительно. Грамотная обработка аргументов командной строки решает эту проблему. Независимо от того, создаёте ли вы утилиту для внутреннего использования или полноценное CLI-приложение для распространения, понимание инструментов Python для работы с аргументами — критически важный навык, способный радикально повысить гибкость и удобство ваших решений. 🚀

Хотите стать мастером CLI-интерфейсов и создавать профессиональные Python-приложения? Обучение Python-разработке от Skypro погрузит вас в мир создания эффективных командных интерфейсов. Вы научитесь проектировать интуитивные CLI-приложения с элегантной обработкой аргументов, которые впечатлят ваших пользователей и потенциальных работодателей. Превратите базовые скрипты в профессиональные инструменты под руководством опытных экспертов!

Основные принципы работы с аргументами командной строки

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

При запуске Python-скрипта в формате python script.py arg1 arg2 --option value вы можете получить доступ к этим аргументам и опциям, чтобы настроить выполнение программы.

Алексей Петров, Lead Python Developer

Однажды я оптимизировал процесс обработки данных в проекте, где команда ежедневно запускала скрипт для генерации отчетов. Каждый запуск требовал редактирования кода под конкретные параметры отчёта: даты, форматы, источники данных. Это занимало минимум 10 минут и создавало риск ошибок.

Я переработал скрипт с использованием argparse, что позволило указывать все параметры при запуске. Вместо 10 минут настройка стала занимать 30 секунд, а риск ошибок исчез. Особенно ценным оказалась возможность создавать bash-скрипты с заранее заданными наборами параметров для типовых отчетов.

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

Рассмотрим ключевые принципы работы с аргументами командной строки:

  • Позиционные аргументы — обязательные параметры, последовательность которых имеет значение.
  • Именованные аргументы (опции) — необязательные параметры, обозначаемые ключами, например --output или -o.
  • Флаги — булевы переключатели, не требующие значений (присутствие флага активирует опцию).
  • Подкоманды — ветвление логики программы на основе первого аргумента (как в git commit, git push).
  • Значения по умолчанию — предустановленные параметры, если пользователь не указал иное.
Тип аргумента Пример использования Типичное применение
Позиционные script.py input.txt output.txt Входные/выходные файлы, основные параметры
Именованные script.py --format json Настройка поведения, опциональные параметры
Флаги script.py --verbose Включение/выключение функций
Подкоманды script.py convert input.txt Структурирование CLI-приложений

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

Пошаговый план для смены профессии

Модуль sys.argv: базовый подход к получению аргументов

Модуль sys.argv — самый простой и низкоуровневый способ получения аргументов командной строки в Python. Он представляет собой список строк, содержащий имя скрипта в качестве первого элемента (sys.argv[0]), за которым следуют все переданные аргументы. Несмотря на простоту, этот подход требует ручной обработки и валидации каждого аргумента. 🔨

Рассмотрим простой пример использования sys.argv:

Python
Скопировать код
import sys

# Проверяем количество аргументов
if len(sys.argv) < 3:
print("Использование: python script.py <input_file> <output_file>")
sys.exit(1)

input_file = sys.argv[1]
output_file = sys.argv[2]
verbose = "--verbose" in sys.argv

print(f"Входной файл: {input_file}")
print(f"Выходной файл: {output_file}")
print(f"Подробный вывод: {'включен' if verbose else 'выключен'}")

# Дополнительная логика обработки...

При запуске python script.py data.txt results.csv --verbose скрипт получит доступ к параметрам через список sys.argv.

Преимущества использования sys.argv:

  • Встроен в стандартную библиотеку Python, не требует дополнительных зависимостей
  • Минималистичный подход с низкими накладными расходами
  • Полный контроль над процессом парсинга аргументов
  • Идеален для простых скриптов с минимальным числом параметров

Недостатки sys.argv:

  • Отсутствие автоматической генерации справки по использованию
  • Необходимость ручной валидации типов и значений параметров
  • Трудоемкая обработка сложных сценариев (опции с несколькими значениями, подкоманды)
  • Код становится запутанным при большом количестве параметров

Рассмотрим более сложный пример с ручной обработкой именованных параметров:

Python
Скопировать код
import sys

args = sys.argv[1:]
params = {}

i = 0
while i < len(args):
if args[i].startswith('--'):
param_name = args[i][2:] # Убираем '--'
if i + 1 < len(args) and not args[i+1].startswith('--'):
params[param_name] = args[i+1]
i += 2
else:
params[param_name] = True # Флаг без значения
i += 1
else:
# Позиционный аргумент
if 'positional' not in params:
params['positional'] = []
params['positional'].append(args[i])
i += 1

print("Параметры:", params)

Хотя sys.argv предоставляет базовую функциональность, для создания профессиональных CLI-приложений рекомендуется использовать более высокоуровневые библиотеки, такие как argparse, которые обеспечивают лучшую читаемость кода и более богатый функционал.

Библиотека argparse: структурированное управление опциями

argparse — стандартная библиотека Python, предназначенная для создания удобных интерфейсов командной строки. Она значительно упрощает определение аргументов, их валидацию, автоматически генерирует справку и сообщения об ошибках, что делает её идеальным выбором для создания профессиональных CLI-приложений. 📊

Основные возможности argparse:

  • Определение позиционных и именованных аргументов
  • Автоматическое преобразование типов данных
  • Валидация значений с помощью пользовательских функций
  • Поддержка подкоманд для создания иерархических интерфейсов
  • Генерация справки с использованием аргумента --help
  • Обработка конфликтов и зависимостей между аргументами

Рассмотрим базовый пример использования argparse:

Python
Скопировать код
import argparse

# Создаем парсер аргументов
parser = argparse.ArgumentParser(description='Обработка файлов данных')

# Добавляем позиционные аргументы
parser.add_argument('input', help='Входной файл')
parser.add_argument('output', help='Выходной файл')

# Добавляем опциональные аргументы
parser.add_argument('--format', choices=['csv', 'json', 'xml'], 
default='csv', help='Формат выходного файла')
parser.add_argument('--verbose', '-v', action='store_true', 
help='Включить подробный вывод')
parser.add_argument('--max-lines', type=int, default=1000,
help='Максимальное число строк для обработки')

# Парсим аргументы командной строки
args = parser.parse_args()

# Используем аргументы в программе
print(f"Входной файл: {args.input}")
print(f"Выходной файл: {args.output}")
print(f"Формат: {args.format}")
print(f"Подробный вывод: {args.verbose}")
print(f"Макс. строк: {args.max_lines}")

При запуске с параметром --help скрипт автоматически генерирует справку по использованию:

usage: script.py [-h] [--format {csv,json,xml}] [--verbose] [--max-lines MAX_LINES] input output

Обработка файлов данных

positional arguments:
input Входной файл
output Выходной файл

optional arguments:
-h, --help show this help message and exit
--format {csv,json,xml}
Формат выходного файла (default: csv)
--verbose, -v Включить подробный вывод
--max-lines MAX_LINES
Максимальное число строк для обработки (default: 1000)

Рассмотрим более сложный пример с подкомандами:

Python
Скопировать код
import argparse

# Создаем основной парсер
parser = argparse.ArgumentParser(description='Утилита для работы с данными')
subparsers = parser.add_subparsers(dest='command', help='Доступные команды')

# Создаем парсер для команды "convert"
convert_parser = subparsers.add_parser('convert', help='Конвертировать данные')
convert_parser.add_argument('input', help='Входной файл')
convert_parser.add_argument('output', help='Выходной файл')
convert_parser.add_argument('--format', default='json', 
choices=['json', 'csv', 'xml'],
help='Формат конвертации')

# Создаем парсер для команды "analyze"
analyze_parser = subparsers.add_parser('analyze', help='Анализировать данные')
analyze_parser.add_argument('file', help='Файл для анализа')
analyze_parser.add_argument('--stats', action='store_true',
help='Показать статистику')

# Парсим аргументы
args = parser.parse_args()

# Обрабатываем различные команды
if args.command == 'convert':
print(f"Конвертация {args.input} в {args.output} в формате {args.format}")
elif args.command == 'analyze':
print(f"Анализ файла {args.file}")
if args.stats:
print("С вычислением статистики")
else:
parser.print_help()

Функция argparse Описание Пример использования
add_argument() Добавляет аргумент с указанием типа, значений и справки parser.add_argument('--count', type=int)
add_subparsers() Создает структуру для подкоманд CLI subparsers = parser.add_subparsers(dest='command')
set_defaults() Устанавливает значения по умолчанию для аргументов parser.set_defaults(feature=True)
parse_args() Выполняет парсинг аргументов из командной строки args = parser.parse_args()
parse_known_args() Обрабатывает известные аргументы, игнорируя остальные args, unknown = parser.parse_known_args()

Библиотека argparse является мощным инструментом для создания CLI-интерфейсов и подходит для большинства задач. Однако для особенно сложных интерфейсов или при необходимости более декларативного подхода стоит обратить внимание на альтернативные библиотеки.

Альтернативные модули: click, docopt и fire для CLI

Хотя argparse является стандартным решением для обработки аргументов командной строки, существуют альтернативные библиотеки, предлагающие более элегантный синтаксис или специфические возможности. Рассмотрим три популярных альтернативы: click, docopt и fire. 🧩

Click: декларативный подход с декораторами

Click — современная библиотека с акцентом на композицию и юзабилити. Она использует декораторы Python для создания команд и опций, что делает код более лаконичным и выразительным.

Основные особенности Click:

  • Декларативный подход с использованием декораторов
  • Вложенные команды и группы команд
  • Автоматическое форматирование справки и сообщений об ошибках
  • Мощная система типов и валидации
  • Поддержка автозаполнения в shell
  • Возможность создания переиспользуемых параметров

Пример использования Click:

Python
Скопировать код
import click

@click.group()
def cli():
"""Утилита для обработки файлов."""
pass

@cli.command()
@click.argument('input_file', type=click.Path(exists=True))
@click.argument('output_file', type=click.Path())
@click.option('--format', '-f', type=click.Choice(['json', 'csv', 'xml']),
default='json', help='Формат выходного файла.')
@click.option('--verbose', '-v', is_flag=True, help='Включить подробный вывод.')
def convert(input_file, output_file, format, verbose):
"""Конвертирует файл из одного формата в другой."""
click.echo(f"Конвертация {input_file} в {output_file} (формат: {format})")
if verbose:
click.echo("Режим подробного вывода активирован")
# Логика конвертации...

@cli.command()
@click.argument('file', type=click.Path(exists=True))
@click.option('--lines', '-l', is_flag=True, help='Подсчитать количество строк.')
@click.option('--words', '-w', is_flag=True, help='Подсчитать количество слов.')
def analyze(file, lines, words):
"""Анализирует содержимое файла."""
click.echo(f"Анализ файла {file}")
if lines:
with open(file, 'r') as f:
line_count = sum(1 for _ in f)
click.echo(f"Количество строк: {line_count}")
if words:
with open(file, 'r') as f:
word_count = sum(len(line.split()) for line in f)
click.echo(f"Количество слов: {word_count}")

if __name__ == '__main__':
cli()

Docopt: CLI-интерфейс на основе документации

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

Особенности docopt:

  • Интерфейс определяется в формате документации (docstring)
  • Синтаксис, соответствующий стандартам POSIX
  • Минимальный код для настройки парсера
  • Подходит для небольших утилит с чётко определённым интерфейсом

Пример использования docopt:

Python
Скопировать код
"""Naval Fate.

Usage:
naval_fate.py ship new <name>...
naval_fate.py ship <name> move <x> <y> [--speed=<kn>]
naval_fate.py ship shoot <x> <y>
naval_fate.py mine (set|remove) <x> <y> [--moored | --drifting]
naval_fate.py (-h | --help)
naval_fate.py --version

Options:
-h --help Show this screen.
--version Show version.
--speed=<kn> Speed in knots [default: 10].
--moored Moored (anchored) mine.
--drifting Drifting mine.

"""
from docopt import docopt

if __name__ == '__main__':
arguments = docopt(__doc__, version='Naval Fate 2.0')
print(arguments)

# Используем аргументы для управления логикой
if arguments['ship'] and arguments['new']:
print(f"Создаём корабль с именем: {' '.join(arguments['<name>'])}")
elif arguments['ship'] and arguments['move']:
print(f"Перемещаем {arguments['<name>']} к координатам ({arguments['<x>']}, {arguments['<y>']}) со скоростью {arguments['--speed']} узлов")
# ... и т.д. для других команд

Fire: автоматическая генерация CLI из кода

Fire от Google — это библиотека, которая автоматически превращает любую Python-функцию или класс в CLI-интерфейс без необходимости явного описания аргументов.

Ключевые особенности Fire:

  • Минимальный код для создания интерфейса
  • Автоматическое отображение сигнатуры функции на аргументы CLI
  • Поддержка вложенных команд через атрибуты классов
  • Генерация интерактивной справки и автоматической документации
  • Идеально подходит для прототипирования и внутренних инструментов

Пример использования Fire:

Python
Скопировать код
import fire

class FileProcessor:
def convert(self, input_file, output_file, format='json', verbose=False):
"""Конвертирует файл из одного формата в другой.

Args:
input_file: Путь к входному файлу
output_file: Путь к выходному файлу
format: Формат выходного файла (json, csv, xml)
verbose: Включить подробный вывод
"""
print(f"Конвертация {input_file} в {output_file} (формат: {format})")
if verbose:
print("Режим подробного вывода активирован")
# Логика конвертации...

def analyze(self, file, count_lines=False, count_words=False):
"""Анализирует содержимое файла.

Args:
file: Путь к файлу для анализа
count_lines: Подсчитать количество строк
count_words: Подсчитать количество слов
"""
print(f"Анализ файла {file}")
if count_lines:
with open(file, 'r') as f:
line_count = sum(1 for _ in f)
print(f"Количество строк: {line_count}")
if count_words:
with open(file, 'r') as f:
word_count = sum(len(line.split()) for line in f)
print(f"Количество слов: {word_count}")

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

Мария Соколова, Python Backend Developer

Во время разработки утилиты для аналитического отдела я экспериментировала с разными подходами к CLI. Сначала использовала argparse, но столкнулась с сопротивлением коллег: "Слишком много кода для такого простого интерфейса".

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

Интересный момент: аналитики, которые редко работали с Python, спонтанно начали расширять утилиту — декораторы Click были настолько интуитивны, что даже с минимальными навыками программирования они могли добавить новые команды.

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

Сравнение модулей для работы с аргументами командной строки:

Библиотека Преимущества Недостатки Идеально для
sys.argv Стандартная библиотека, низкоуровневый контроль Ручная валидация, без автоматической справки Простых скриптов с минимумом аргументов
argparse Стандартная библиотека, богатый функционал Относительно многословный синтаксис Большинства CLI-приложений
Click Элегантный синтаксис, композиция через декораторы Внешняя зависимость Сложных CLI с вложенными командами
docopt Интерфейс через документацию, минимум кода Сложно динамически модифицировать Утилит с чётко определённым интерфейсом
Fire Автоматическая генерация CLI из функций Меньший контроль над форматом справки Прототипирования и внутренних инструментов

Выбор библиотеки зависит от конкретных требований проекта, предпочтений команды разработчиков и того, насколько сложным является CLI-интерфейс вашего приложения. Для простых утилит argparse или Fire могут быть идеальными, в то время как сложные многоуровневые интерфейсы могут выиграть от использования Click.

Практические сценарии использования аргументов командной строки

Теоретические знания модулей для работы с аргументами командной строки важны, но настоящее понимание приходит при их практическом применении в реальных сценариях. Рассмотрим несколько типичных случаев использования аргументов командной строки, которые встречаются в повседневной разработке. 🛠️

1. Обработка файлов в пакетном режиме

Один из наиболее распространенных сценариев — обработка файлов с настраиваемыми параметрами. Например, скрипт для конвертации изображений:

Python
Скопировать код
import argparse
from PIL import Image
import os

def main():
parser = argparse.ArgumentParser(description='Инструмент для обработки изображений')
parser.add_argument('input', help='Входное изображение или директория')
parser.add_argument('-o', '--output', help='Выходная директория')
parser.add_argument('-f', '--format', choices=['jpg', 'png', 'webp'], 
default='jpg', help='Формат выходного изображения')
parser.add_argument('-q', '--quality', type=int, choices=range(1, 101),
default=85, help='Качество (1-100)')
parser.add_argument('-r', '--resize', type=int, nargs=2, 
metavar=('WIDTH', 'HEIGHT'),
help='Изменить размер до WIDTHxHEIGHT')
parser.add_argument('--recursive', action='store_true', 
help='Рекурсивная обработка директорий')

args = parser.parse_args()

# Определяем, это файл или директория
if os.path.isfile(args.input):
process_image(args.input, args)
elif os.path.isdir(args.input):
process_directory(args.input, args)
else:
print(f"Ошибка: {args.input} не существует")

def process_image(image_path, args):
try:
img = Image.open(image_path)

# Изменение размера, если указано
if args.resize:
img = img.resize((args.resize[0], args.resize[1]), Image.LANCZOS)

# Определение выходного пути
if args.output:
output_dir = args.output
else:
output_dir = os.path.dirname(image_path) or '.'

if not os.path.exists(output_dir):
os.makedirs(output_dir)

# Формирование имени файла
filename = os.path.basename(image_path)
name, _ = os.path.splitext(filename)
output_path = os.path.join(output_dir, f"{name}.{args.format}")

# Сохранение с указанным качеством
img.save(output_path, quality=args.quality)
print(f"Обработано: {image_path} -> {output_path}")

except Exception as e:
print(f"Ошибка при обработке {image_path}: {e}")

def process_directory(dir_path, args):
for item in os.listdir(dir_path):
item_path = os.path.join(dir_path, item)

if os.path.isfile(item_path) and item.lower().endswith(('jpg', 'jpeg', 'png')):
process_image(item_path, args)
elif os.path.isdir(item_path) and args.recursive:
process_directory(item_path, args)

if __name__ == '__main__':
main()

Этот скрипт можно использовать как для обработки отдельных изображений, так и для пакетной обработки директорий:

  • python image_processor.py photo.jpg -o processed -f webp -q 90 — конвертирует одно изображение в WebP с качеством 90%
  • python image_processor.py images/ --recursive -r 800 600 — обрабатывает все изображения в директории и поддиректориях, изменяя их размер до 800x600

2. Создание скриптов для работы с API

CLI-инструменты часто используются для взаимодействия с API. Например, скрипт для работы с GitHub API:

Python
Скопировать код
import argparse
import requests
import json
import os

def main():
parser = argparse.ArgumentParser(description='GitHub API CLI')
subparsers = parser.add_subparsers(dest='command', help='Команды')

# Команда для просмотра репозиториев
repos_parser = subparsers.add_parser('repos', help='Работа с репозиториями')
repos_parser.add_argument('--user', '-u', required=True,
help='Имя пользователя GitHub')
repos_parser.add_argument('--sort', choices=['updated', 'created', 'pushed'],
default='updated', help='Сортировка репозиториев')
repos_parser.add_argument('--limit', type=int, default=10,
help='Максимальное количество репозиториев')

# Команда для работы с issues
issues_parser = subparsers.add_parser('issues', help='Работа с issues')
issues_parser.add_argument('--repo', '-r', required=True,
help='Репозиторий в формате owner/repo')
issues_parser.add_argument('--state', choices=['open', 'closed', 'all'],
default='open', help='Статус issues')
issues_parser.add_argument('--assignee',
help='Фильтр по назначенному пользователю')

# Общие аргументы
parser.add_argument('--token', help='GitHub API token')
parser.add_argument('--output', '-o', help='Файл для сохранения результатов')

args = parser.parse_args()

# Получение токена из аргументов или переменных окружения
token = args.token or os.environ.get('GITHUB_TOKEN')
headers = {'Authorization': f'token {token}'} if token else {}

# Обработка команд
if args.command == 'repos':
url = f"https://api.github.com/users/{args.user}/repos"
params = {'sort': args.sort, 'per_page': args.limit}
process_request(url, headers, params, args.output)
elif args.command == 'issues':
url = f"https://api.github.com/repos/{args.repo}/issues"
params = {'state': args.state}
if args.assignee:
params['assignee'] = args.assignee
process_request(url, headers, params, args.output)
else:
parser.print_help()

def process_request(url, headers, params, output_file):
try:
response = requests.get(url, headers=headers, params=params)
response.raise_for_status()
data = response.json()

if output_file:
with open(output_file, 'w') as f:
json.dump(data, f, indent=2)
print(f"Результаты сохранены в {output_file}")
else:
print(json.dumps(data, indent=2))
except requests.exceptions.RequestException as e:
print(f"Ошибка запроса: {e}")
except Exception as e:
print(f"Ошибка: {e}")

if __name__ == '__main__':
main()

Этот скрипт демонстрирует использование подкоманд и взаимодействие с внешним API:

  • python github_cli.py repos --user octocat --limit 5 — получает 5 последних репозиториев пользователя octocat
  • python github_cli.py issues --repo octocat/Hello-World --state all --output issues.json — получает все issues из репозитория и сохраняет их в файл

3. Автоматизация сложных рабочих процессов

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

Python
Скопировать код
import argparse
import subprocess
import os
import sys
import datetime

def main():
parser = argparse.ArgumentParser(description='Инструмент для автоматизации деплоя')
parser.add_argument('environment', choices=['dev', 'staging', 'production'],
help='Среда для деплоя')
parser.add_argument('--version', help='Версия для деплоя (по умолчанию – текущая дата)')
parser.add_argument('--skip-tests', action='store_true',
help='Пропустить запуск тестов')
parser.add_argument('--skip-build', action='store_true',
help='Пропустить сборку проекта')
parser.add_argument('--notify', nargs='+',
help='Email-адреса для оповещения о результатах')
parser.add_argument('--dry-run', action='store_true',
help='Вывести команды без их выполнения')

args = parser.parse_args()

# Генерация версии, если не указана
version = args.version or datetime.datetime.now().strftime('%Y%m%d_%H%M')

# Логирование
log_file = f"deploy_{args.environment}_{version}.log"
print(f"Начинаем деплой в {args.environment} (версия: {version})")
print(f"Лог будет сохранен в {log_file}")

try:
# Запуск тестов
if not args.skip_tests:
run_command("Запуск тестов", ["pytest", "--verbose"], args.dry_run, log_file)

# Сборка проекта
if not args.skip_build:
run_command("Сборка проекта", ["npm", "run", "build"], args.dry_run, log_file)

# Деплой в выбранную среду
deploy_command = ["ansible-playbook", f"deploy_{args.environment}.yml",
"-e", f"version={version}"]
run_command(f"Деплой в {args.environment}", deploy_command, args.dry_run, log_file)

# Проверка статуса после деплоя
health_check_command = ["curl", "-s", f"https://{args.environment}.example.com/health"]
run_command("Проверка статуса", health_check_command, args.dry_run, log_file)

# Отправка уведомлений
if args.notify:
for email in args.notify:
notify_command = ["mail", "-s", f"Деплой в {args.environment} успешен", email]
run_command(f"Отправка уведомления на {email}", notify_command, args.dry_run, log_file)

print(f"Деплой в {args.environment} (версия: {version}) успешно завершен")

except Exception as e:
print(f"Ошибка при деплое: {e}")
sys.exit(1)

def run_command(step_name, command, dry_run, log_file):
print(f"\n### {step_name} ###")
print(f"Выполняем: {' '.join(command)}")

if dry_run:
print("(dry-run, команда не выполнена)")
return

try:
with open(log_file, 'a') as log:
log.write(f"\n### {step_name} ###\n")
log.write(f"$ {' '.join(command)}\n")

result = subprocess.run(command, capture_output=True, text=True)
log.write(result.stdout)

if result.stderr:
log.write(f"STDERR:\n{result.stderr}\n")

if result.returncode != 0:
error_msg = f"Ошибка при выполнении {step_name} (код {result.returncode})"
log.write(f"{error_msg}\n")
raise Exception(error_msg)

except subprocess.SubprocessError as e:
print(f"Ошибка при выполнении команды: {e}")
raise

if __name__ == '__main__':
main()

Такой скрипт можно использовать для автоматизации процесса деплоя:

  • python deploy.py dev --skip-tests — деплой в dev-окружение без запуска тестов
  • python deploy.py production --notify admin@example.com team@example.com --version 1.2.3 — деплой в production с указанием версии и отправкой уведомлений
  • python deploy.py staging --dry-run — симуляция деплоя в staging для проверки процесса

Эти примеры демонстрируют, как аргументы командной строки превращают Python-скрипты в мощные и гибкие инструменты для решения практических задач. Грамотно спроектированный CLI-интерфейс делает ваши инструменты более понятными для пользователей и значительно расширяет их применимость.

Командная строка — это не просто интерфейс для взаимодействия с программами, это мощный инструмент автоматизации и повышения эффективности разработки. Овладение работой с аргументами командной строки в Python открывает широкие возможности для создания профессиональных инструментов, которые можно использовать в повседневных задачах, включать в конвейеры CI/CD или передавать другим разработчикам. Независимо от того, выберете ли вы строгий структурированный подход argparse, элегантный декоративный синтаксис Click, декларативный docopt или минималистичный Fire — правильная обработка аргументов командной строки поднимет ваши Python-скрипты на новый уровень полезности и профессионализма.

Читайте также

Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Что такое аргументы командной строки в Python?
1 / 5

Загрузка...