programing

각각 하위 명령 집합이 있는 클릭 명령을 여러 파일로 분할하려면 어떻게 해야 합니까?

telecom 2023. 7. 24. 22:16
반응형

각각 하위 명령 집합이 있는 클릭 명령을 여러 파일로 분할하려면 어떻게 해야 합니까?

제가 개발한 큰 클릭 애플리케이션이 하나 있는데, 여러 명령/하위 명령을 탐색하는 것이 점점 어려워지고 있습니다.명령을 별도의 파일로 구성하려면 어떻게 해야 합니까?명령과 하위 명령을 별도의 클래스로 구성할 수 있습니까?

다음은 분리 방법에 대한 예입니다.

안에

import click

@click.group()
@click.version_option()
def cli():
    pass #Entry Point

command_cloudflare.py

@cli.group()
@click.pass_context
def cloudflare(ctx):
    pass

@cloudflare.group('zone')
def cloudflare_zone():
    pass

@cloudflare_zone.command('add')
@click.option('--jumpstart', '-j', default=True)
@click.option('--organization', '-o', default='')
@click.argument('url')
@click.pass_obj
@__cf_error_handler
def cloudflare_zone_add(ctx, url, jumpstart, organization):
    pass

@cloudflare.group('record')
def cloudflare_record():
    pass

@cloudflare_record.command('add')
@click.option('--ttl', '-t')
@click.argument('domain')
@click.argument('name')
@click.argument('type')
@click.argument('content')
@click.pass_obj
@__cf_error_handler
def cloudflare_record_add(ctx, domain, name, type, content, ttl):
    pass

@cloudflare_record.command('edit')
@click.option('--ttl', '-t')
@click.argument('domain')
@click.argument('name')
@click.argument('type')
@click.argument('content')
@click.pass_obj
@__cf_error_handler
def cloudflare_record_edit(ctx, domain):
    pass

command_commandimerobot.py

@cli.group()
@click.pass_context
def uptimerobot(ctx):
    pass

@uptimerobot.command('add')
@click.option('--alert', '-a', default=True)
@click.argument('name')
@click.argument('url')
@click.pass_obj
def uptimerobot_add(ctx, name, url, alert):
    pass

@uptimerobot.command('delete')
@click.argument('names', nargs=-1, required=True)
@click.pass_obj
def uptimerobot_delete(ctx, names):
    pass

을 사용할 CommandCollection즉, 명령을 병합하고 명령 그룹에서만 작동합니다.imho 더 나은 대안은 사용하는 것입니다.add_command동일한 결과를 얻기 위해.

다음 트리가 있는 프로젝트가 있습니다.

cli/
├── __init__.py
├── cli.py
├── group1
│   ├── __init__.py
│   ├── commands.py
└── group2
    ├── __init__.py
    └── commands.py

각 하위 명령에는 자체 모듈이 있으므로 더 많은 도우미 클래스와 파일을 사용하여 복잡한 구현도 관리하기가 매우 쉽습니다.에서, 각모에서는,commands.py파일은 다음을 포함합니다.@click 예 』group2/commands.py:

import click


@click.command()
def version():
    """Display the current version."""
    click.echo(_read_version())

필요한 경우 모듈에 더 많은 클래스를 쉽게 만들 수 있습니다.import여기서 사용하면 CLI에서 Python의 클래스와 모듈을 모두 사용할 수 있습니다.

나의cli.py입니다. CLI는 다음과 같습니다.

import click

from .group1 import commands as group1
from .group2 import commands as group2

@click.group()
def entry_point():
    pass

entry_point.add_command(group1.command_group)
entry_point.add_command(group2.version)

이 설정을 사용하면 문제별로 명령을 구분하고 필요한 추가 기능을 구축하는 것이 매우 쉽습니다.그것은 지금까지 저에게 매우 도움이 되었습니다...

참고 자료: http://click.pocoo.org/6/quickstart/ #http-sknowledge-message

프로젝트의 구조가 다음과 같다고 가정합니다.

project/
├── __init__.py
├── init.py
└── commands
    ├── __init__.py
    └── cloudflare.py

그룹은 여러 명령에 불과하며 그룹은 중첩될 수 있습니다.하여 사용자에게 수 .init.py파일을 작성하여 에 추가합니다.cli합니다.

여기 있습니다.init.py예:

import click
from .commands.cloudflare import cloudflare


@click.group()
def cli():
    pass


cli.add_command(cloudflare)

당신은 cloudflare.py 파일 안에 있는 클라우드 플레어 그룹을 가져와야 합니다.당신의.commands/cloudflare.py다음과 같이 표시됩니다.

import click


@click.group()
def cloudflare():
    pass


@cloudflare.command()
def zone():
    click.echo('This is the zone subcommand of the cloudflare command')

그런 다음 cloudflare 명령을 다음과 같이 실행할 수 있습니다.

$ python init.py cloudflare zone

이 정보는 설명서에 명시적이지 않지만 주석이 잘 달린 소스 코드를 보면 그룹이 중첩되는 방법을 알 수 있습니다.

이것을 알아내는 데 시간이 좀 걸렸지만, 제가 어떻게 해야 하는지를 다시 잊어버렸을 때 제 자신에게 상기시키기 위해 이것을 여기에 두기로 했습니다. 제 생각에 문제의 일부는 add_command 기능이 클릭의 github 페이지에서 언급되었지만 주요 예제 페이지에서는 언급되지 않았다는 것입니다.

먼저 root.py 이라는 초기 파이썬 파일을 생성합니다.

import click
from cli_compile import cli_compile
from cli_tools import cli_tools

@click.group()
def main():
    """Demo"""

if __name__ == '__main__':
    main.add_command(cli_tools)
    main.add_command(cli_compile)
    main()

다음으로 cli_tools.py라는 파일에 몇 가지 도구 명령을 입력합니다.

import click

# Command Group
@click.group(name='tools')
def cli_tools():
    """Tool related commands"""
    pass

@cli_tools.command(name='install', help='test install')
@click.option('--test1', default='1', help='test option')
def install_cmd(test1):
    click.echo('Hello world')

@cli_tools.command(name='search', help='test search')
@click.option('--test1', default='1', help='test option')
def search_cmd(test1):
    click.echo('Hello world')

if __name__ == '__main__':
    cli_tools()

다음으로 cli_compile.py라는 파일에 컴파일 명령을 몇 가지 입력합니다.

import click

@click.group(name='compile')
def cli_compile():
    """Commands related to compiling"""
    pass

@cli_compile.command(name='install2', help='test install')
def install2_cmd():
    click.echo('Hello world')

@cli_compile.command(name='search2', help='test search')
def search2_cmd():
    click.echo('Hello world')

if __name__ == '__main__':
    cli_compile()

root.py 을 운영하면 이제 우리에게 제공됩니다.

Usage: root.py [OPTIONS] COMMAND [ARGS]...

  Demo

Options:
  --help  Show this message and exit.

Commands:
  compile  Commands related to compiling
  tools    Tool related commands

"root.py 컴파일"을 실행하면 우리에게 제공됩니다.

Usage: root.py compile [OPTIONS] COMMAND [ARGS]...

  Commands related to compiling

Options:
  --help  Show this message and exit.

Commands:
  install2  test install
  search2   test search

또한 cli_tools.py 또는 cli_compile.py를 직접 실행할 수 있으며 여기에 주요 문을 포함했습니다.

현재는 이와 같은 것을 찾고 있습니다. 각 파일에 그룹이 있기 때문에 간단한 경우 설명서에서 설명한 대로 이 문제를 해결할 수 있습니다.

init.py파일 이름:

import click

from command_cloudflare import cloudflare
from command_uptimerobot import uptimerobot

cli = click.CommandCollection(sources=[cloudflare, uptimerobot])

if __name__ == '__main__':
    cli()

이 솔루션의 가장 좋은 점은 pep8 및 기타 린터와 완전히 호환된다는 것입니다. 사용하지 않는 것을 가져올 필요가 없고 어디서나 *를 가져올 필요가 없기 때문입니다.

편집: 제 대답/답변이 "사용자 지정 다중 명령" 섹션에서 Click의 공식 문서가 제공하는 것을 재탕한 것에 불과하다는 것을 방금 깨달았습니다. https://click.palletsprojects.com/en/7.x/commands/ #custom-multi-multi-multi-modules

, 가져오기 및 자동 추가 사용하는 해 냈습니다. 이 은 my @jdno의 보일러 .cli.py:

제 프로젝트 구조는 다음과 같습니다.

projectroot/
    __init__.py
    console/
    │
    ├── cli.py
    └── subcommands
       ├── bar.py
       ├── foo.py
       └── hello.py

각 하위 명령 파일은 다음과 같습니다.

import click

@click.command()
def foo():
    """foo this is for foos!"""
    click.secho("FOO", fg="red", bg="white")

(현재는 파일당 하위 명령이 하나뿐입니다.)

cli.py내가쓴것을 .add_subcommand()하위 명령/*.py로 글로 표시된 모든 파일 경로를 순환한 다음 가져오기 및 추가 명령을 수행하는 함수입니다.

다음은 cli.py 스크립트의 본문을 단순화한 것입니다.

import click
import importlib
from pathlib import Path
import re

@click.group()
def entry_point():
    """whats up, this is the main function"""
    pass

def main():
    add_subcommands()
    entry_point()

if __name__ == '__main__':
    main()

그리고 이것이 바로 그것입니다.add_subcommands()기능은 다음과 같습니다.


SUBCOMMAND_DIR = Path("projectroot/console/subcommands")

def add_subcommands(maincommand=entry_point):
    for modpath in SUBCOMMAND_DIR.glob('*.py'):
        modname = re.sub(f'/', '.',  str(modpath)).rpartition('.py')[0]
        mod = importlib.import_module(modname)
        # filter out any things that aren't a click Command
        for attr in dir(mod):
            foo = getattr(mod, attr)
            if callable(foo) and type(foo) is click.core.Command:
                maincommand.add_command(foo)

여러 수준의 중첩 및 컨텍스트 전환이 있는 명령을 설계할 경우 이 기능이 얼마나 강력한지 모르겠습니다.하지만 지금은 잘 될 것 같습니다 :)

클릭 전문가는 아니지만 기본 파일로 파일을 가져오는 것만으로 작동합니다.모든 명령어를 별도의 파일로 이동하고 하나의 메인 파일로 다른 명령어를 가져오도록 하겠습니다.그렇게 하면 당신에게 중요한 경우를 대비하여 정확한 순서를 제어하는 것이 더 쉽습니다.따라서 기본 파일은 다음과 같습니다.

import commands_main
import commands_cloudflare
import commands_uptimerobot

사용자가 "your_message"를 pip로 설치한 다음 명령을 사용하도록 하려면 setup.py 에서 명령을 추가할 수 있습니다.entry_points목록으로:

entry_points={
    'console_scripts': [
        'command_1 = src.cli:function_command_1',
        'command_2 = src.cli:function_command_2',
    ]

각 명령은 CLI 파일에서 작동하도록 제한됩니다.

언급URL : https://stackoverflow.com/questions/34643620/how-can-i-split-my-click-commands-each-with-a-set-of-sub-commands-into-multipl

반응형