Alejandrina Lara Tovar
Luis Rodrigo Alvarez Herrera
Gilberto A. Guerrero Caballero
Crear un CLI en Python con Click es más claro y mantenible cuando organizas bien tu proyecto, defines comandos con decoradores y configuras setup.py para instalar un ejecutable. Aquí tienes el esqueleto base: estructura de archivos, comandos create/list/update/delete y un flujo de instalación editable en un virtualenv.
¿Cómo organizar la estructura de archivos en Python para un CLI con Click?
Diseñar con múltiples archivos hace el código más legible y escalable. Un subdirectorio funciona como módulo en Python y agrupa responsabilidades específicas.
Estructura sugerida:
PlatziVentas/ ├─ PV.py ├─ setup.py └─ clients/ └─ commands.py
Claves prácticas:
¿Qué comandos y decoradores definen el CLI de clientes?
Los decoradores de Click convierten funciones en comandos. Se usa @click.group() para declarar un grupo y @clients.command() para registrar subcomandos. Con @click.pass_context se recibe un contexto mutable; aquí se inicializa como diccionario literal vacío.
¿Cómo inicializar el contexto con click pass context?
En tu punto de entrada se importa Click, se define un group y se inicializa el objeto contexto:
# PV.py import click @click.group() @click.pass_context def CLI(ctx): # inicializar el contexto como diccionario literal vacío ctx.obj = {} # registrar el grupo de clientes desde el módulo clients.commands from clients import commands as clients_commands CLI.add_command(clients_commands.all)
Puntos clave:
clients.commands como alias y se registra con add_command.¿Cómo convertir funciones en comandos del grupo clients?
Define el grupo clients y sus comandos básicos. Los docstrings alimentan la ayuda de Click, es decir: la interfaz basada en texto del CLI.
# clients/commands.py import click @click.group() def clients(): """Manages the client's life cycle.""" pass # placeholder para evitar error @clients.command() @click.pass_context def create(ctx, name, company, email, position): """Create a new client.""" pass @clients.command("list") # evitar colisión con palabra reservada list @click.pass_context def list_cmd(ctx): """List all clients.""" pass @clients.command() @click.pass_context def update(ctx, uid): """Updates a client.""" pass @clients.command() @click.pass_context def delete(ctx, uid): """Delete a client.""" pass # alias para registrar todo el grupo desde PV.py all = clients
Detalles importantes:
@clients.command() marca cada función como comando.--help.¿Cómo instalar y ejecutar el comando con setup.py y un virtualenv?
La instalación convierte tu CLI en un ejecutable del sistema: sin invocar directamente al intérprete de Python. Se declara el nombre del comando, la versión y el entry point hacia CLI dentro de PV.py.
Ejemplo mínimo de setup.py:
# setup.py from setuptools import setup setup( name='PV', # nombre del comando instalado version='0.1', # versión semántica py_modules=['PV'], # módulo de entrada install_requires=[ 'click', # dependencia principal ], entry_points={ 'console_scripts': [ 'PV=PV:CLI', # comando=modulo:funcion_de_entrada ], }, )
Instalar en modo editable dentro de un virtualenv permite ver cambios al instante:
# crear y activar el ambiente virtual virtualenv -p python3 venv source venv/bin/activate # instalar en modo editable pip install --editable . # verificar e inspeccionar la ayuda which PV PV --help PV clients --help
Qué observarás al usar --help:
¿Te gustaría extender estos comandos con opciones y validar entradas? Deja tus dudas o ideas para explorar el siguiente paso juntos.
Alejandrina Lara Tovar
Luis Rodrigo Alvarez Herrera
Gilberto A. Guerrero Caballero
Joan Rincón Sarmiento
Francisco Garcia [C6]
Omar Daniel Centeno
JONATAN CADAVID TORRES
Omar Daniel Centeno
Cesar Hernández Ramírez
Eduardo Acosta
Omar Daniel Centeno
Omar Daniel Centeno
platzerito02112019 platzerito02112019
Julian Crispin
Javier Alejandro Flores Gomez
Alejandro Avila Reina
Alvaro Daniel Vidal Velasque
Edwin Jesset Barrientos Gonzales
Carolina Acosta Muñoz
Boris Saavedra
Isabela Jimenez Salazar
Juan Mercado
Néstor Arellano
Raúl Asperilla
Santiago Gomez Florez
Lucas Ezequiel Veliz
Gabriel Calero Gutiérrez
Cesar Hernández Ramírez
Wilson Fernando Antury Torres
Miguel Torres
Luis Fernando Úbeda Camacho
Martin Mendez
Andres David Peña Velandia
Rodolfo Esteban Crisanto Rosas
Pedro Alvarado Garcia
Perla Godinez Castillo
Manuel Alejandro González Cabello
Roman Oswaldo Barahona
Emmanuel Octavio Martinez C
marco antonio
Marines Millan
Facundo Nicolás García Martoni
ProfesorJulian Benegas
Facundo Nicolás García Martoni
ProfesorNo copie bien la “receta” del setup, y me tarde dos días en darme cuenta . Aquí les dejo la receta bien escrita
from setuptools import setup setup( name='pv', version='0.1', py_modules=['pv'], install_requires=[ 'Click', ], entry_points=''' [console_scripts] pv=pv:cli ''', )
gracias, estuve buscando la solucion
Muchas gracias, también la había copiado mal :)
Me desmotive bastante desde esta clase, creo que no se explica muchas con claridad, por lo que veo a muchos nos salieron errores que debieron ser validados previamente en la clase, la verdad es el curso que mas me ha decepcionado en lo que llevo de platzi. Creo que buscare profundizar en otro lado.
creo que como todo, hay cosas muy precisas que se deben escribir a mi me salio un error sin embargo revise a profundidad y tenia un par de errores typo como le dicen. Creo que es normal este tipo de cosas la cuestión es tener paciencia y revisar. Si copia y pega el codigo de ejemplo no te enteras de cual fue el error. Por el contrario considero que la clase es muy buena y cada uno tenemos un ruta de aprendizaje diferente y claro es necesario profundizar y buscar por otro lado las cosas que en ocasiones no entendemos. Ahora bien en una clase pre grabada de 15 minutos nunca encontraras todas las respuestas. Con todo y ello las clases del profesor Aoresti son de las mejores que tiene Platzi
A mi este curso me parece fenomenal, te lleva desde lo más básico hasta cosas avanzadas para realmente aplicar lo aprendido y saltar a hacer cosas prácticas. ¿No te pareció increíble poder generar u propia línea de comandos? es algo que nunca pensé en hacer, pero estoy maravillado. . Ciertamente el curso requiere que además de dominar los conceptos de Python, también, que conozcas sobre la terminal. Por eso está bien que sea un curso intermedio. No te desanimes, haz una pausa y repasa clases anteriores así como conceptos que no entiendas y regresa. . Espero que hayas terminado el curso. . A un año de este comentario ¿Cómo vas con Python?
Al igual que en el curso básico de python cuando tratamos temas avanzados el curso va muy rápido y no nos muestran detalles, tampoco soluciones para los que estamos en windows, pero no voy a enfocar solo en las debilidades del curso ya que de verdad lo he disfrutado bastante, mi solución es utilizar el bash de Git y con el bash o linea de comandos dirigirse a la carpeta de Platzi-ventas, luego seguir estos pasos:
1- pip install virtualenv 2- python -m venv venv
Ahora ya tenemos creado el ambiente virtual, debemos activarlo:
Posicionados en la misma carpeta de Platzi-Ventas ingresamos en el dash el comando:
source venv/Scripts/activate
Ahora podemos seguir los pasos que el profe nos explica en el curso, esto lo encontre en el siguiente video:
Espero les funcione.
Me gusta el enfoque que le das a tu comentario, no te desesperas y buscas la forma de solucionarlo, además, compartes tu solución con los demas. Gracias.
Link please
Se perdio todo el manejo en este punto, veniamos lento en cosas basicas y luego cuando se va a algo un poco mas complejo, el instructor da por sentadas muchas cosas y pasa demasiado rapido. Seria bueno que leyeran los comentarios de los estudiantes, no soy el unico que sintio que se perdio la calidad.
¿Cómo te fue con el curso? . Se notó el cambio de ritmo, sin embargo, este curso repasó desde los conceptos básicos hasta más avanzados y eso me gustó bastante.
Creo que la calidad va en aumento, se aplica lo que se ha visto antes, no solo en el curso sino en otros anteriores que son básicos. A partir de este punto viene lo bueno y eso me emociona, poder aplicarlo en un ambiente fuera del intérprete de Python. . Creo que todos pasamos por momentos de frustración con los errores que salen o por falta de entendimiento, pero hay que ir a tomar aire y regresar. . ¡Ánimo! . ¿Terminaste el curso?¿Qué te llevaste al final?
-----ENTORNO VIRTUAL EN WINDOWS----
luego seguí estos pasos.
1. pip Install virtualenv
2. Pip Install virtualenvwrapper-win:
**3. ** una vez echo esto anote el comando que dice el profe con una ligera modificación
estando en la carpeta “platzi-ventas” ejecuto el comando:
• virtualenv --python=python venv
muchas gracias no olvidar: pip install --editable .
inlcuido el espacio despues de editable y el punto
me salvaste la vida
Un millon de errores, hasta este punto no pude solucionar nada a pesar de haber tomado un curso previo de python. Como raro todos los cursos de platzi son a la carrera y bastante incompletos en sus partes mas complejas.
x2
Si tuvieron algun error con virtualenv y estan usando windows esto me sirvio.
virtualenv venv python -m venv venv venv\scripts\activate
Gracias! Me sirvió!
Muchas gracias!
ni si quiera explican bien para que funciona el framework click, que sentido tiene?
HOLA! AL FINAL DESPUES DE COMO PUDIERON VER TODAS LAS PREGUNTAS QUE HICE, LES DEJO MI SOLUCIÓN! PARA TODOS LOS QUE ESTÁN EN
¡¡WINDOWS 10!!
0)Abrir la consola(cmd), y entrar a la carpeta que contiene todos los archivos y subdirectorios
1)python -m virtualenv <nombre del entorno>
2)venv\Scripts\activate.bat
3)pip install --editable .
4)where pv
Muchas gracias por la información. :)
Si al poner el comando python -m virtualenv venv le da un error: No module named virtualenv, esto quiere decir que tu versión de python no tiene instalado virtualenv asi que estando en Windows necesitarán bajarse los paquetes usando pip install virtualenv y después volver a lanzar el comando que dio error.
Para quien presente errores
O saldra este error: bad interpreter: No such file or directory
intento instalar pero pip o pip3 no lo reconoce como un comando
No es el mejor tema que se trató de éste curso, no se entendió nada. Está todo bien con buscar y revisar en otros sitios para ampliar más los temas, pero al menos los conceptos deberían quedar claros o que al menos se sepa que es lo que se quiere hacer.
Cierto, este curso no es para alguien que va comenzando, igualmente creo que debimos ver que hay debajo del cofre de CLICK para comprender qué estamos usando, aunque sea un poco más
Para los que no tienen tree en su sitema: sudo apt-get install tree
Esto está buenísimo. Gracias! :D
Muchas gracias!!!
En windows si no tienen virtual env
# pip install virtualenv # python -m venv env # .\env\Scripts\activate.bat # .\env\Scripts\activate # deactivate (este es para salir)
El profesor da por hecho que tenemos mac y pone puntos y cosas que solo se utilizan en mac, ¿pero los de windows qué? Aparte ya tomé el curso anterior de python y fue exactamente igual y al llegar a este punto de ambiente virtual todo se complicó y avanza muy rápido como si supiésemos ya todo.
Hola, te lo digo en buena, no creo que sea por mac, los comandos que utiliza son de entorno Unix, sea linux o mac, en windows puedes instalarte algunas herramientas que te ayudaran a utilizar estos comandos o cosas que no entiendes, pero mi mejor recomendación si te dedicaras a la programación es que uses Linux, y si tienes la oportunidad una Mac, cuando ya domines el entorno Unix. Saludos y éxitos.
Instalen esto primero,
pip3 install virtualenv
sino les saldra un error al hacer
virtualenv --python=python3 venv
gracias
Me parece que no quedo muy claro el uso de click o al menos para mi no lo fue.
Click es un paquete de Python para crear "bonitas" interfaces de línea de comandos de una manera componible con tan poco código como sea necesario. Es el "Kit de creación de interfaz de línea de comandos". Es altamente configurable pero viene con valores predeterminados sensibles listos para usar.
Supongo que si no se utilizara, trabajar con la linea de comandos seria mas engorroso. Es lo que yo creo.
Aquí el archivo (Y)
from setuptools import setup setup( name='pv', version='0.1', py_modules=['pv'], install_requires=[ 'Click', ], entry_poinst = ''' [console_scripts] pv=pv:cli ''', )
!programa
Mi corazón esta escrito en C así que quería usar un framework al que le tengo mucho cariño el cual es Qt por suerte es casi universal y funciona con Python
Bien el ejercicio de la lista de clientes lo hice con una interfaz grafica, me gusto como se ve :D si quiere puedes ver mi código y jugar con el, esta en mi github
aqui esta el codigo para consola:
--sin click-- XD
import sys import os CLIENTES = [] MENU_DICCIONARIO = {'N':'NOMBRE', 'P':'POSICION', 'C':'COMPANIA', 'E':'EMAIL'} BASE_TXT = './lista_de_clientes.txt' BASE_TEMP = 'lista_de_clientes.temp' def AbrirBase_Declientes(): global BASE_TXT, CLIENTES try: with open(BASE_TXT,'r',encoding='utf-8') as __ARCHIVO__: base_de_clientes = __ARCHIVO__.read() limite = 0 un_cliente = dict() un_dato_del_cliente = base_de_clientes.split(',') for index, dato in enumerate(un_dato_del_cliente): if index % 2 != 0: un_cliente[un_dato_del_cliente[index - 1]] = dato limite += 1 if limite == 4: CLIENTES.append(un_cliente) un_cliente = dict() limite = 0 except FileNotFoundError: with open(BASE_TXT,'w',encoding='utf-8') as __ARCHIVO__: return def GuardarBase_DeClientes(): global BASE_TXT, CLIENTES with open('lista_de_clientes.temp','w', encoding='utf-8') as __ARCHIVO__: for cliente in CLIENTES: for llave, valor in cliente.items(): __ARCHIVO__.write(f'{llave},{valor},') os.remove(BASE_TXT) os.rename(BASE_TEMP, BASE_TXT) def Agrega_Cliente(): global CLIENTES cliente = dict() print('por favor agrega:') for valor in MENU_DICCIONARIO.values(): cliente[valor] = input(f'{valor} :') CLIENTES.append(cliente) Mostrar_Clientes() GuardarBase_DeClientes() def Elimina_Cliente(): print('Como desea localizar a su cliente a eliminar: ') cliente = busqueda_de_cliente() if cliente: accion =__Dame_comando(texto = 'deseas continuar [S]i / [TECLA] no : ') if accion == 'S': indice = cliente[0] if len(cliente) > 1: indice = __Dame_comando(cliente,'Elige el indice de quien deseas eliminar : ') CLIENTES.pop(indice) GuardarBase_DeClientes() def Actualiza_Cliente(): print('Localize su cliente para actualizar: ') cliente = busqueda_de_cliente() if cliente: accion = __Dame_comando(texto ="deseas hacer una actualizacion [S]i / [TECLA] no : ") indice = -1 while accion == 'S': if indice == -1 and len(cliente) == 1: indice = cliente[0] elif indice == -1: indice = __Dame_comando(cliente,"Elige el indice de quien deseas actualizar : ") llave = __Dame_comando(MENU_DICCIONARIO,'que deseas actualizar :') CLIENTES[indice][llave] = input(f'actualiza {llave} : ') print('¿Quieres continuar ACTUALIZANDO a') Mostrar_Clientes([indice]) GuardarBase_DeClientes() accion = __Dame_comando(texto='[S]i /[TECLA] no : ') def busqueda_de_cliente(): llave = __Dame_comando(MENU_DICCIONARIO,'Buscar por: ') valor = input(f'ingresa el {llave} : ') return Busca_Cliente(llave,valor,CLIENTES) def Busca_Cliente(llave,valor,lista_de_diccionarios): print(f'{llave} : {valor}') cliente_localizado = [] cliente_localizado = __localiza_por_medio_de(llave,valor,lista_de_diccionarios) if cliente_localizado: print('mostrando informacion: ') Mostrar_Clientes(cliente_localizado) else: print('el cliente no ha sido localizado') return cliente_localizado def __localiza_por_medio_de(llave,valor,lista_de_diccionarios): objeto = valor.lower() indice = [] for i , cliente in enumerate(lista_de_diccionarios): if cliente[llave] == objeto: indice.append(i) return indice def Mostrar_Clientes(indice = None): global CLIENTES if indice == None: for ind, cliente in enumerate(CLIENTES): print(f'[{ind}] : ',end='') for llave, valor in cliente.items(): print(f'[{llave} = {valor}]', end=' ') print("") else: for i in indice: print(f'[{i}] : ',end='') for llave, valor in CLIENTES[i].items(): print(f'[{llave} = {valor}]',end=' ') print('') MENU = ''' BIENVENIDO ******************** ¿Que desea realizar? [I]ngresar cliente [B]uscar cliente [E]liminar cliente [A]ctualizar cliente [M]ostrar clientes [TECLA] para salir ''' def Interfaz(): AbrirBase_Declientes() while True: print('') comando = __Dame_comando(texto=MENU) if comando == 'I': Agrega_Cliente() elif comando == 'B': busqueda_de_cliente() elif comando == 'E': Elimina_Cliente() elif comando == 'A': Actualiza_Cliente() elif comando == 'M': Mostrar_Clientes() else: break def __Dame_comando(menu_de_intercion = None, texto = ''): while True: print(texto) if type(menu_de_intercion) == dict: for llave , valor in menu_de_intercion.items(): print(f'[{llave}] : [{valor}] ') comando = input().upper() if type(menu_de_intercion) == dict: try: return menu_de_intercion[comando] except KeyError: pass elif menu_de_intercion == None: if len(comando) == 1: return comando.upper() elif type(menu_de_intercion) == list: try: if int(comando) in menu_de_intercion: return int(comando) except ValueError: pass print('intentalo de nuevo ') if __name__ == "__main__": Interfaz() ```
Esta clase hubiera sido mejor si se dividia en mas, para aprovechar de explicar todo con detalle, o hubieran dejado algo de documentacion para leer. Ni modo tocara googlear. Ibamos muy bien, pero esta clase no me gusto mucho
¡Hola @MDCMC! ¿Puedo ayudarte con algo? ¿Hay cierta parte en específico que no entendiste? Te dejo el link de la documentación oficial de click --> https://click.palletsprojects.com/en/7.x/
Estos temas mas complejos tendrían que desarrollarse en 2 o 3 clases mínimo... No vale la pena así. Sirve poco y nada esto. Nadie viene sin saber este tema y termina teniendolo claro despues de esta clase. Es preferible leer documentación de Python y consultar con google.
Así con videitos de 15 minutos, superficiales, Platzi no tiene sentido. Youtube es gratis y mucho mejor que esto.
¡Hola Julián! Gracias por tu feedback, quiero que sepas que la actualización del Curso de Python no va a tener estos errores, el equipo está trabajando muy duro para darte la mejor experiencia 💪🏼