لینوکس و terminal برنامه ها تقریبا مترادف هستند. اگر از برنامه هایی مانند grep، cat، sed و AWK استفاده کرده اید، اینها رابط های خط فرمان (CLI) هستند. و هنگامی که آنها با هم کار می کنند، به شما این امکان را می دهند که با ترکیب و تطبیق چند دستور، قدرت رایانه خود را آزاد کنید.

گاهی اوقات CLI بیش از حد پیچیده می شود – و در آن زمان است که می توانید آن را با نسخه های اکتشافی بیشتری از برنامه هایی به نام رابط کاربری متنی (TUI) تکمیل کنید.

TUI هایی مانند HTOP، Glances، Midnight Commander و موارد دیگر به شما امکان می دهند تا قدرت CLI را بدون از دست دادن سهولت استفاده ترکیب کنید.

بنابراین وقتی پایتون CLI شما گزینه های زیادی دارد و ترسناک می شود، چه کاری می توانید انجام دهید؟ خوب نیست اگر بتوانید راهی برای کشف برنامه داشته باشید و پس از آشنایی با آن، وظایف خود را با استفاده از گزینه های پشتیبانی شده توسط اسکریپت به سرعت انجام دهید؟

پایتون دارای یک اکوسیستم بسیار سالم از چارچوب‌های رابط کاربری گرافیکی و TUI است که می‌توانید از آن برای نوشتن برنامه‌های کاربردی زیبا و بصری استفاده کنید. در این آموزش ما در مورد Trogon و کارهایی که می‌توانید انجام دهید تا اپلیکیشن خود را برای کاربران جدید و باتجربه‌تر و در عین حال قدرتمندتر کنید، صحبت خواهیم کرد.

من دو مورد از آنها را به شما نشان خواهم داد که می توانند به شما در حل دو مشکل زیر کمک کنند:

  1. هنگام نوشتن برنامه‌ها از غرق شدن و استفاده از APIهای ترسناک اجتناب کنید. از بسته کلیکی پایتون برای حل آن مشکل استفاده خواهد کرد.
  2. امکان شناسایی این زمانی که برنامه‌ای دارید که از گزینه‌های زیادی پشتیبانی می‌کند یا مدتی است که از آن استفاده نکرده‌اید، بسیار مهم است. اینجاست که Trogon به کار می آید.

ما از کد منبع یکی از Open من دوباره استفاده خواهیم کرد Source برنامه ها، rpm_query به عنوان پایه. Rpm_query مجموعه ای از برنامه های کاربردی ساده است که می تواند پایگاه داده RPM سیستم شما را از خط فرمان پرس و جو کند.

آنچه شما برای این آموزش نیاز دارید

  1. توزیع لینوکس، ترجیحاً توزیعی که از RPM استفاده می کند (مانند لینوکس سازمانی فدورا یا RedHat)
  2. پایتون 3.8+
  3. Git
  4. آشنایی با محیط های مجازی پایتون
  5. اتصال به اینترنت برای دانلود وابستگی ها با استفاده از pip.

من قویاً پیشنهاد می کنم که مخزن را شبیه سازی کنید و یک محیط مجازی ایجاد کنید تا بتوانید آموزش را دنبال کنید:

git clone https://github.com/josevnz/CLIWithClickAndTrogon.git
cd CLIWithClickAndTrogon
python3 -m venv ~/virtualenv/CLIWithCLickAndTrogon 
. ~/virtualenv/CLIWithCLickAndTrogon/bin/activate

اگر آماده هستید، بیایید داخل شیرجه بزنیم.

یک CLI معمولی (رابط خط فرمان) چگونه به نظر می رسد – Refresher سریع

این اسکریپت از یک ماژول در داخل بسته پایتون گزارشگر برای پرس و جو از پایگاه داده RPM استفاده می کند.

#!/usr/bin/env python
"""
# rpmq_simple.py - A simple CLI to query the sizes of RPM روی your system
Author: Jose Vicente Nunez
"""
import argparse
import textwrap

from reporter import __is_valid_limit__
from reporter.rpm_query import QueryHelper

if __name__ == "__main__":

    parser = argparse.ArgumentParser(description=textwrap.dedent(__doc__))
    parser.add_argument(
        "--limit",
        type=__is_valid_limit__,  # Custom limit validator
        action="store",
        default=QueryHelper.MAX_NUMBER_OF_RESULTS,
        help="By default results are unlimited but you can cap the results"
    )
    parser.add_argument(
        "--name",
        type=str,
        action="store",
        help="You can filter by a package name."
    )
    parser.add_argument(
        "--sort",
        action="store_false",
        help="Sorted results are enabled bu default, but you fan turn it off"
    )
    args = parser.parse_args()

    with QueryHelper(
        name=args.name,
        limit=args.limit,
        sorted_val=args.sort
    ) as rpm_query:
        for package in rpm_query:
            print(f"{package['name']}-{package['version']}: {package['size']:,.0f}")

پیشنهاد می‌کنیم بخوانید:  روش نصب Docker روی اوبونتو

بیایید آن را در حالت قابل ویرایش نصب کنیم:

. ~/virtualenv/CLIWithCLickAndTrogon/bin/activate
pip install --editable .

و آن را در عمل ببینید:

(CLIWithClickAndTrogon) [josevnz@dmaf5 CLIWithClickAndTrogon]$ rpmq_simple.py --help
usage: rpmq_simple.py [-h] [--limit LIMIT] [--name NAME] [--sort]

# rpmq_simple.py - A simple CLI to query the sizes of RPM روی your system Author: Jose Vicente Nunez

options:
  -h, --help     show this help message and exit
  --limit LIMIT  By default results are unlimited but you can cap the results
  --name NAME    You can filter by a package name.
  --sort         Sorted results are enabled bu default, but you fan turn it off
(CLIWithClickAndTrogon) [josevnz@dmaf5 CLIWithClickAndTrogon]$ rpmq_simple.py --name kernel --limit 5
kernel-6.2.11: 0
kernel-6.2.14: 0
kernel-6.2.15: 0

بنابراین از بسیاری از کدها به نظر می رسد روی rpmq_simple.py اسکریپت برای رابط خط فرمان، با استفاده از کتابخانه استاندارد «ArgParse» به صورت boilerplate است.

ArgParse قدرتمند است، اما در ابتدا ترسناک است، به خصوص زمانی که مجبور به پشتیبانی از موارد استفاده چندگانه هستید.

روشی جدید برای پردازش CLI با کلیک

چارچوب کلیک قول می دهد که تجزیه آرگومان های خط فرمان را آسان تر کند. برای نشان دادن آن، بیایید اسکریپت خود را از ArgParse به Click تبدیل کنیم (هر دو گزینه‌ها را پشتیبانی می‌کنند اما Click چند گزینه جالب دارد که ما استفاده خواهیم کرد):

#!/usr/bin/env python
"""
# rpmq_click.py - A simple CLI to query the sizes of RPM روی your system
Author: Jose Vicente Nunez
"""
import click

from reporter.rpm_query import QueryHelper


@click.command()
@click.option('--limit', default=QueryHelper.MAX_NUMBER_OF_RESULTS,
              help="By default results are unlimited but you can cap the results")
@click.option('--name', help="You can filter by a package name.")
@click.option('--sort', default=True, help="Sorted results are enabled bu default, but you fan turn it off")
def command(
        name: str,
        limit: int,
        sort: bool
) -> None:
    with QueryHelper(
            name=name,
            limit=limit,
            sorted_val=sort
    ) as rpm_query:
        for package in rpm_query:
            click.echo(f"{package['name']}-{package['version']}: {package['size']:,.0f}")


if __name__ == "__main__":
    command()

بنابراین در اینجا متوجه تغییرات بزرگ خواهید شد:

  1. بیشتر کد دیگ بخار از ArgParse از بین رفته است و با حاشیه نویسی جایگزین شده است.
  2. کلیک با افزودن دکوراتورها به یک تابع جدید به نام “command” کار می کند که آرگومان ها را می گیرد و پرس و جوی RPM را اجرا می کند.

اگر اسکریپت جدید را اجرا کنید، خواهید دید که دقیقاً مانند قبل کار می کند:

(CLIWithClickAndTrogon) [josevnz@dmaf5 CLIWithClickAndTrogon]$ rpmq_click.py --help
Usage: rpmq_click.py [OPTIONS]

Options:
  --limit INTEGER  By default results are unlimited but you can cap the
                   results
  --name TEXT      You can filter by a package name.
  --sort BOOLEAN   Sorted results are enabled bu default, but you fan turn it
                   off
  --help           Show this message and exit.
(CLIWithClickAndTrogon) [josevnz@dmaf5 CLIWithClickAndTrogon]$ rpmq_click.py --name kernel --limit 5
kernel-6.2.11: 0
kernel-6.2.14: 0
kernel-6.2.15: 0

پس چه چیزی به دست آوردیم؟ کد ما کمی ساده تر است اما اکنون توسط Trogon پشتیبانی می شود، چارچوب جدیدی که به زودی در مورد آن صحبت خواهیم کرد.

روش استفاده از setuptools و کلیک کنید

مستندات کلیک توصیه می کند که ما باید از setuptools برای ایجاد یک پوشش برای ابزار خود به صورت خودکار استفاده کنیم. بنابراین باید تابعی را تعریف کنیم که در آن تمام گزینه‌های خط فرمان و منطق را مدیریت کنیم و wrapper یک اسکریپت معمولی برای ما ایجاد کند. روی مکان مناسب در هنگام نصب پکیج همچنین به نسخه مناسب پایتون، در میان چیزهای خوب دیگر اشاره می کند.

سند دارای نحو منسوخ برای راه اندازی است.py، بنابراین به جای آن از فرمت جدیدتر setup.cfg استفاده خواهیم کرد:

[metadata]
name = CLIWithClickAndTrogon
version = 0.0.1
author = Jose Vicente Nunez Zuleta
author-email = kodegeek.com@protonmail.com
license = Apache 2.0
summary = Simple TUI that queries the RPM database
home-page = https://github.com/josevnz/cliwithclickandtrogon
description = Simple TUI that queries the RPM database. A tutorial.
long_description = file: README.md
long_description_content_type = text/markdown

[options]
packages = reporter
setup_requires =
    setuptools
    wheel
    build
    pip
    twine
install_requires =
    importlib; python_version == "3.9"
    click
scripts =
    scripts/rpmq_simple.py
    scripts/rpmq_click.py
[options.entry_points]
console_scripts =
    rpmq = reporter.scripts:command

من یک بسته به نام “اسکریپت” در داخل بسته به نام “گزارشگر” با منطق CLI با استفاده از کلیک ایجاد کردم.

پیشنهاد می‌کنیم بخوانید:  روش نصب و استفاده از Docker در CentOS 7

setuptools یک اسکریپت به نام rpmq برای ما تولید می‌کند که دقیقاً مانند اسکریپت قبلی عمل می‌کند – اما باز هم، برای ارسال آرگومان‌ها به کلیک، به هیچ کد boilerplate نیاز نداریم:

CLIWithClickAndTrogon) [josevnz@dmaf5 CLIWithClickAndTrogon]$ pip install --editable .
(CLIWithClickAndTrogon) [josevnz@dmaf5 CLIWithClickAndTrogon]$ rpmq --help
Usage: rpmq [OPTIONS]

Options:
  --limit INTEGER  By default results are unlimited but you can cap the
                   results
  --name TEXT      You can filter by a package name.
  --sort BOOLEAN   Sorted results are enabled bu default, but you fan turn it
                   off
  --help           Show this message and exit.
(CLIWithClickAndTrogon) [josevnz@dmaf5 CLIWithClickAndTrogon]$ rpmq --name kernel --limit 5
kernel-6.2.11: 0
kernel-6.2.14: 0
kernel-6.2.15: 0

چگونه CLI خود را با Trogon قابل کشف کنیم

بیایید مشکل قابل کشف کردن CLI خود را با Trogon حل کنیم. علاوه بر اضافه کردن جدید trogon کتابخانه به عنوان بخشی از الزامات (requirements.txt و setup.cfg)، باید یک دکوراتور جدید به CLI خود اضافه کنیم:

#!/usr/bin/env python
"""
A simple CLI to query the sizes of RPM روی your system
Author: Jose Vicente Nunez
"""
import click
from trogon import tui

from reporter.rpm_query import QueryHelper

@tui()
@click.command()
@click.option('--limit', default=QueryHelper.MAX_NUMBER_OF_RESULTS,
              help="By default results are unlimited but you can cap the results")
@click.option('--name', help="You can filter by a package name.")
@click.option('--sort', default=True, help="Sorted results are enabled bu default, but you fan turn it off")
def command(
        name: str,
        limit: int,
        sort: bool
) -> None:
    with QueryHelper(
            name=name,
            limit=limit,
            sorted_val=sort
    ) as rpm_query:
        for package in rpm_query:
            click.echo(f"{package['name']}-{package['version']}: {package['size']:,.0f}")


if __name__ == "__main__":
    command()

فقط یک حاشیه، @tui، و جدید import.

زمان آن است که آن را در عمل ببینیم:

(CLIWithClickAndTrogon) [josevnz@dmaf5 CLIWithClickAndTrogon]$ rpmq_trogon.py --help
Usage: rpmq_trogon.py [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  command
  tui      Open Textual TUI.

نتایج یکسان است، اما دو تغییر را مشاهده خواهید کرد:

  1. اگر می‌خواهید از گزینه‌های CLI استفاده کنید، باید «فرمان» را قبل از سوئیچ‌ها اضافه کنید.
  2. یک چیز جدید وجود دارد tui فرمان

یک لحظه صبر کنید… با پرچم های دیگر چه اتفاقی افتاد؟ نگران نباشید، اگر برای “فرمان” کمک بیشتری بخواهید، آنها را در آنجا خواهید دید:

(CLIWithClickAndTrogon) [josevnz@dmaf5 CLIWithClickAndTrogon]$ rpmq_trogon.py command --help
Usage: rpmq_trogon.py command [OPTIONS]

Options:
  --limit INTEGER  By default results are unlimited but you can cap the
                   results
  --name TEXT      You can filter by a package name.
  --sort BOOLEAN   Sorted results are enabled bu default, but you fan turn it
                   off
  --help           Show this message and exit.

آه، خیلی بهتر بیایید CLI را مشابه روش قبلی اجرا کنیم:

(CLIWithClickAndTrogon) [josevnz@dmaf5 CLIWithClickAndTrogon]$ rpmq_trogon.py command --limit 5 --name kernel
kernel-6.2.11: 0
kernel-6.2.14: 0
kernel-6.2.15: 0

و در مورد پشتیبانی از setuptools چطور؟ فقط اضافه کنید import و حاشیه نویسی برای “عملکرد فرمان”:

import click
from trogon import tui

from reporter.rpm_query import QueryHelper
@tui()
@click.command()
@click.option('--limit', default=QueryHelper.MAX_NUMBER_OF_RESULTS,
              help="By default results are unlimited but you can cap the results")
@click.option('--name', help="You can filter by a package name.")
@click.option('--sort', default=True, help="Sorted results are enabled bu default, but you fan turn it off")
def command(
        name: str,
        limit: int,
        sort: bool
) -> None:
    # .... real code goes here
    pass

به من اجازه دهید اکنون با حالت TUI روش عملکرد حالت شناسایی خودکار را نشان دهم:

asciicast

خوب! ما یک TUI دریافت کردیم که در آن برخی از گزینه ها به طور خودکار برای ما پر می شوند. این به ما ایده روشنی می دهد که چگونه از برنامه ها استفاده کنیم بدون اینکه اطلاعات زیادی در مورد آنها داشته باشیم.

چه خبر بعدی

  1. کد منبع این آموزش را دانلود کنید و شروع به آزمایش کنید.
  2. هر دو کلیک و تروگون دارای اسناد عالی و پشتیبانی آنلاین هستند. از آنها بهره ببرید.
  3. کلیک نمونه‌های پیچیده‌تری دارد، به راحتی می‌توانید گالری آن‌ها را ببینید.