font - title plt python
¿Cómo puedo dividir mis comandos Click, cada uno con un conjunto de subcomandos, en varios archivos? (4)
Estoy buscando algo como esto en este momento, en su caso es simple porque tiene grupos en cada uno de los archivos, puede resolver este problema como se explica en la documentation :
En el archivo
init.py
:
import click
from command_cloudflare import cloudflare
from command_uptimerobot import uptimerobot
cli = click.CommandCollection(sources=[cloudflare, uptimerobot])
if __name__ == ''__main__'':
cli()
La mejor parte de esta solución es que es totalmente compatible con pep8 y otras listas porque no necesita importar algo que no usaría y no necesita importar * desde cualquier lugar.
Tengo una aplicación de clic grande que he desarrollado, pero navegar por los diferentes comandos / subcomandos se está volviendo difícil. ¿Cómo organizo mis comandos en archivos separados? ¿Es posible organizar comandos y sus subcomandos en clases separadas?
Aquí hay un ejemplo de cómo me gustaría separarlo:
en eso
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_uptimerobot.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
La desventaja de usar
CommandCollection
para esto es que combina sus comandos y funciona solo con grupos de comandos.
La mejor alternativa de
add_command
es usar
add_command
para lograr el mismo resultado.
Tengo un proyecto con el siguiente árbol:
cli/
├── __init__.py
├── cli.py
├── group1
│ ├── __init__.py
│ ├── commands.py
└── group2
├── __init__.py
└── commands.py
Cada subcomando tiene su propio módulo, lo que hace que sea increíblemente fácil administrar incluso implementaciones complejas con muchas más clases y archivos auxiliares.
En cada módulo, el archivo
@click
contiene las anotaciones
@click
.
Ejemplo
group2/commands.py
:
import click
@click.command()
def version():
"""Display the current version."""
click.echo(_read_version())
Si es necesario, puede crear fácilmente más clases en el módulo e
import
y usarlas aquí, dando así a su CLI todo el poder de las clases y módulos de Python.
Mi
cli.py
es el punto de entrada para toda la 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)
Con esta configuración, es muy fácil separar sus comandos por inquietudes, y también crear funcionalidades adicionales a su alrededor que puedan necesitar. Me ha servido muy bien hasta ahora ...
Referencia: http://click.pocoo.org/6/quickstart/#nesting-commands
No soy un experto en clics, pero debería funcionar simplemente importando sus archivos al principal. Movería todos los comandos en archivos separados y tendría un archivo principal importando los otros. De esa manera, es más fácil controlar el orden exacto, en caso de que sea importante para usted. Entonces su archivo principal se vería así:
import commands_main
import commands_cloudflare
import commands_uptimerobot
Supongamos que su proyecto tiene la siguiente estructura:
project/
├── __init__.py
├── init.py
└── commands
├── __init__.py
└── cloudflare.py
Los grupos no son más que múltiples comandos y los grupos se pueden anidar.
Puede separar sus grupos en módulos e importarlos en su archivo
init.py
y agregarlos al grupo
cli
usando el comando add_command.
Aquí hay un ejemplo de
init.py
:
import click
from .commands.cloudflare import cloudflare
@click.group()
def cli():
pass
cli.add_command(cloudflare)
Debe importar el grupo cloudflare que vive dentro del archivo cloudflare.py.
Sus
commands/cloudflare.py
verían así:
import click
@click.group()
def cloudflare():
pass
@cloudflare.command()
def zone():
click.echo(''This is the zone subcommand of the cloudflare command'')
Luego puede ejecutar el comando cloudflare de esta manera:
$ python init.py cloudflare zone
Esta información no es muy explícita en la documentación, pero si observa el código fuente, que está muy bien comentado, puede ver cómo se pueden anidar los grupos.