Comando Create con Click: opciones y persistencia CSV
Resumen
Diseña un flujo sólido para crear clientes desde la línea de comando con Click en Python: define opciones con prompt, valida entradas, inicializa el modelo, persiste en CSV y corrige errores comunes sin perder tiempo. Aquí verás el patrón de interfaz con short name y long name, el uso de contexto y un cierre funcional con escritura en archivo.
¿Cómo definir opciones en Click para un comando create?
Configurar opciones en Click permite pedir datos al usuario de forma guiada. Se usa un short name y un long name para la opción principal, se define el tipo string, se activa prompt true para solicitar la entrada en consola y se añade una línea de ayuda clara.
Opción principal con alias: -n/--name.
Tipo de dato: string.
Solicitud interactiva: prompt True.
Ayuda contextual: "the client's name".
Repetición del patrón para: company, email, position.
¿Qué patrón de interfaz se aplica con short name y long name?
Alias breve para velocidad: -n.
Nombre largo legible: --name.
Consistencia al replicar el patrón en cada campo.
Ayuda clara para cada opción.
¿Cómo inicializar el cliente y usar el servicio?
Tras recolectar parámetros, se importan solo las clases necesarias mediante importación selectiva: ClientService desde clients.services y Client desde clients.models. Luego se inicializa el modelo con nombre, compañía, email y posición. El ID se deja vacío para que el sistema lo genere automáticamente. Finalmente, el servicio persiste la entidad con create_client.
Importaciones específicas: from clients.services import ClientService y from clients.models import Client.
Inicialización del modelo: name, company, email, position.
ID autogenerado: no se pasa manualmente.
Uso del servicio: create_client con la referencia del cliente.
Snippet representativo:
from clients.services import ClientService
from clients.models import Client
@click.pass_contextdefcreate(ctx, name, company, email, position): client = Client(name=name, company=company, email=email, position=position) service = ClientService(ctx.obj['clients_table']) service.create_client(client)
¿Cómo configurar el contexto con clients_table en pv.py?
Para persistir datos se define una variable global con el nombre del archivo y se agrega al contexto de la app, de modo que los comandos la consuman sin acoplamiento.
Archivo de almacenamiento: .clients.csv.
Variable global: clients_table.
Integración al contexto: uso de ctx.obj.
Ejemplo esquemático:
# pv.pyCLIENTS_TABLE ='.clients.csv'# En la inicialización del CLIdefcli(ctx): ctx.ensure_object(dict) ctx.obj['clients_table']= CLIENTS_TABLE
¿Cómo depurar errores comunes al ejecutar el comando?
Al probar con pv clients create se detectaron fallos típicos: import mal escrito y typo en atributos. La solución fue ajustar el nombre correcto del modelo y corregir el campo de posición para que coincida en todo el código.
Importación incorrecta: usar from clients.models import Client en lugar de un nombre inexistente.
Archivo involucrado: clients/commands.py.
Atributo mal escrito: positon corregido a position en clients/models.
Verificación rápida: limpiar consola, ejecutar de nuevo y revisar salida.
¿Cómo validar el archivo clients.csv generado?
Tras la ejecución, se inspecciona .clients.csv y se confirma que los datos están separados por comas. Esto permitirá manipularlos con DictReader más adelante.
Apertura del archivo y lectura manual.
Confirmación de formato: valores separados por comas.
Preparación para lectura con dict reader en próximos pasos.
¿Te gustaría comentar qué otros campos u opciones agregarías al comando y cómo validarías entradas como el email desde la línea de comando?
Creo que se debió explicar mejor el funcionamiento de click antes de empezar a usarlo de un modo profesional, en mi caso no logro entender del todo ctx.obj creo que en esta parte se va muy rápido y se pierde uno con facilidad, deberían mejorar esta parte del curso, corazón 💚 para que mejoren esta parte
e comparto el link con la documentacion de click, es importate entender click y vuelve a ver los videos, con eso entenderas el programa, slds
Comparto contigo, el curso falla en no dar una explicación un poco más detallada de ciertos conceptos. Debes investigar por tu cuenta y sacarte dudas que podría resolverse con unos minutos más de vídeo.
Ctx es un objeto, que pertenece a una clase que no conocemos su implementación ni atributos, debemos abstraernos. Lo mismo debemos hacer con los métodos de click, solamente conocemos la sintaxis y sabemos que resultado nos brinda (así es como se trabaja con librerías o funciones desarrollados por otros).
Y lo que hace el método ctx.obj es declarar una estructura de datos dentro del objeto Ctx, en este caso fue un diccionario vacío.
Tanto para que al final no explique bien lo más complicado.
Super complicado para mi lo que se refiere al contexto, no logre entender nada. A que se refiere, que valores tiene, porque se pasa de esa forma…
Me parece que es un buen ejercicio, porque si llegas a utilizar Django lo comprenderas más, pero el contexto es el ‘template’ en el que vas a trabajar, osea que esta va a ser tu base de datos para el proyecto. A eso se refiere.
Los valores que tiene son name, company, email y position, todos separados por comas pues es un csv (Comma Separeted Value)
Se pasan de esta forma pues un generador, pues te estas apoyando en el trabajo de alguien mas para hacer el proyecto, y esa persona lo creo así. En mi opinión es mejor asi.
Si tienes mas preguntas responde y tratare de responderte con lo que se.
¡Hola @Kerepakupai! Tu feedback nos sirve mucho para mejorar, ten sabido que lo vamos a tener en cuenta para la próxima actualización del curso 💪🏼
Si estás un poco perdido (como estaba yo) con el tema de importar paquetes entonces estos vídeos son para vos:
Para todos aquellos que estan confundidos con la logica que llevamos asta el momento esto es lo que yo entiendo:
Que es el modulo Click:
Click es un paquete de Python para crear hermosas interfaces de línea de comandos de una manera componible con el mínimo código necesario. Es el "Kit de creación de interfaz de línea de comandos". Es altamente configurable pero viene con valores predeterminados razonables listos para usar.
Su objetivo es hacer que el proceso de escribir herramientas de línea de comandos sea rápido y divertido, al mismo tiempo que evita cualquier frustración causada por la incapacidad de implementar una API CLI prevista.
Clic en tres puntos:
anidamiento de comandos
generación automática de páginas de ayuda
admite carga lenta de subcomandos en tiempo de ejecución
En pocas palabras el codigo donde el usuario selecciona las opciones se sustituye con el modulo Click
El modulo Setup
Unicamente lo utilizamos para poder instalarlo en el entorno virtual de pyton como si de un exe en windows o un dmg en mac
Los modulos en Client
toda la logica que aplicamos con las funciones se separa en tres archivos:
Models
Services
commands
Models.
aqui convertimos la estructura del Cliente en una clase
En este archivo ejecutmos los comandos necesarios para guardar la informacion en el archivo la unica diferencia es que en ves de guardar la información al final de la ejecución del codigo lo hacemos cada que se ejecuta un comando:
#en ves de esto:def_save_clients_to_storage():withopen(CLIENT_TABLE, mode='w')as f: writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA) writer.writerows(clients)#se hace esto:classClientService:def__init__(self, table_name): self.table_name = table_name
defcreate_client(self, client):withopen(self.table_name, mode='a')as f: writer = csv.DictWriter(f, fieldnames=Client.schema()) writer.writerow(client.to_dict())
####Commands
En este modulo realizamos la logica de la aplicación
#en ves de esto:defcrear_cliente(): client = _get_client_field('name')if search_client(client):print('Client already is in the clients\'s list')else: clients.append(_get_Client(client)) list_clients()deflist_clients():forid, client inenumerate(clients):print('{uid} | {name} | {company} | {email} | {position} |'.format( uid=id, name=client['name'], company=client['company'], email=client['email'], position=client['position']))defupdate_client(): client_name = _get_client_field('name')if search_client(client_name):for client in clients:if client['name']== client_name: index = clients.index(client) clients[index]= _get_Client(client_name) list_clients()breakelse:print('CLient is not in client\'s list')defdelete_client(): client_name = _get_client_field('name')if search_client(client_name):for client in clients:if client['name']== client_name: clients.remove(client) list_clients()else:print('CLient is not in client\'s list')defsearch_client(client_name):for client in clients:if client['name']!= client_name:continueelse:returnTruedef_print_welcome():print('Welcome to Platzi Ventas')print('*'*50)print('What would your like to do doing')print('[C]reate client')print('[L]ist client\'s')print('[U]pdate client')print('[D]elete client')print('[S]earch client')def_get_client_field(field_name): field =Nonewhilenot field: field =input('What is the client {}? '.format(field_name))if field =='exit': field =Nonebreakifnot field: sys.exit()return field
def_get_Client(client): client ={'name': client,"company": _get_client_field("company"),'email': _get_client_field('email'),"position": _get_client_field("position")}return client
#Vamos realizando cada comando asi@click.group()defclients():"""Manages the clients lifecycle"""pass@clients.command()@click.option('-n','--name',type=str, prompt=True,help='The client name')@click.option('-c','--company',type=str, prompt=True,help='The client company')@click.option('-e','--email',type=str, prompt=True,help='The client email')@click.option('-p','--position',type=str, prompt=True,help='The client position')@click.pass_contextdefcreate(ctx, name, company, email, position):"""Create a new client""" client = Client(name, company, email, position) client_service = ClientService(ctx.obj['clients_table']) client_service.create_client(client)@clients.command()@click.pass_contextdeflist(ctx):"""List of clients"""pass@clients.command()@click.pass_contextdefupdate(ctx, client_uid):"""Updates of clients"""pass@clients.command()@click.pass_contextdefdelete(ctx, client_uid):"""Delete clients"""passall= clients
Espero que les ayude en algo y no los confunda mas 😅
Muy buen aporte! lo agregare a mis notas :D
Programé todo (nunca lo probé porque nunca fuimos probando el código) y cuando le doy pv clients create, simplemente me aparece como si ejecutara el código y ya, pero no hace nada. Este problema lo tengo desde la clase pasada, siento que se volvió una carrera, llevo como 4 clases sin entender ni recibir una explicación de qué es lo que estamos usando y por qué lo estamos usando. La verdad bastante decepcionado, y más aún que ni siquiera explica los comandos.
Creo que tengo todo el código bien, pero fallé en la creación del entorno virtual, me aparece que estoy en un entorno virutal pero no cuando ejecutaba los help no recibía nada, cuando ejecuto los create no pasa nada, en fin, es bastante frustrante el ni siquiera saber qué es lo que tienes mal.
Para instalar el entorno virtual ejecuta en tu terminal
Recuerda ejecutarlos posicionado en el directorio de tu código.
Lo que ese está haciendo es aplicar los conceptos de las clases Decoradores, Decoradores en Python, ¿Qué es la programación orientada a objetos? y Programación orientada a objetos en python. Te recomiendo que las vuelvas a repasar.
Si sigues teniendo dudas, escribe tus preguntas y la comunidad te puede apoyar.
No te rindas, ¡ánimo! ¡tu puedes!
Tal vez necesites instalar algunos modulos de pv
por ejemplo: sudo apt install pv
para poder utilizar pv de python
Me arrepiento de haberme inscrito en Platzi
¡Hola Diego!
Cuéntanos si tienes algún problema con la plataforma para poder
ayudarte, puedes escribirnos a team@platzi.com o por un mensaje directo aquí mismo.
Saludos :)
x2
like si quedaste aún más confundido porque no explica el por qué de esa lógica.
BAsicamente esto fue. Así porque si y punto
El problema de este curso y del "curso de Python" es que una vez pasamos el temario de POO, el profesor se acelera mucho al explicar los módulos (en este caso Click y en el anterior curso Flask) y omite explicar los conceptos de lo que estamos viendo
Una de las ventajas de usar un IDE es que te ayuda con los errores de tipeo, tales como paso en esta clase. Les recomiendo PyCharm es muy bueno y es gratis.
Atom, VS code, y sublime tiene plugins que ayudan con eso.
tambien le puedes meter esteroides a vim instalando vundle :D, a eso le agregamos tmux y pues creo que supera a atom y vs :D
Sinceramente este curso me frustro muchisimo, empezo muy lento con cosas que ya vimos muchas veces en cursos anteriores, en cambio las cosas 'nuevas' no las explican mucho, tuve muchisimos errores y busque muchisima informacion en muchos lados para poder hacer funcionar el programa. sinceramente una decepcion y me hace considerar desuscribirme a platzi
La verdad el curso de python con Flask para mi fue un Fla"k"so jajaja xd, pero esto debido a que lo hacia con windows y es cierto que trabajar python con windows es horrible y en algunas otras cosas
Les recomiendo para que no tengan problema con el curso que instalen una distribución de Linux no es muy demorado aprenden bastante y se evitaran todos los problemas y errores de windows
NO se asusten Linux no muerde jeje, para que sea mas fácil creen una maquina virtual para tener una buena primera experiencia con este SO
Suerte y no es tan dificil como parece, es practica pericia y no frustrarse
Los errores de escritura a veces son algo frustrantes, especialmente cuando hay lenguajes fuertemente tipificados (que las mayúsculas y las minúsculas SON importantes).
Ej: “Clients” ¡no es igual! a “clients”
En serio piensan que así es la mejor forma de aprender? no entiendo nada...
Hey.
Recuerda que este curso hace parte de la Ruta de Aprendizaje de Desarrollo Backend con Python. Te recomiendo seguir el orden de cursos que se recomiendan en este carrera. Además, si tienes alguna pregunta puedes hacerla y con muchísimo gusto te respondemos. :muscle:
Quizá la terminal pueda complicar un poco al inicio pero con un poco de práctica se hace más fácil y a futuro nos va a facilitar la vida para realizar otras cosas.
seguí todas las instrucciones y cuando ejecuto pv clients createÑ
(venv) c:\PYTHON\PYTHON\CRUD\PLATZI-VENTAS>pv clientes create
"pv" no se reconoce como un comando interno o externo,programa o archivo por lotes ejecutable.
Hola, @KennedySaavedra.
Probablemente hay algún error en el archivo setup.py o al momento de instalar click. Otro detalle también podrían ser los decoradores en command.py.
Podrías revisar esas partes. Cuéntame si algo de esto te funcionó. 🤓
que hace específicamente el pass_context?
Me parece que hace que una función pueda compartir variables en forma de diccionario con las demás a través de los decoradores, por ejemplo como hicimos con la ['clients_table'], la compartimos a través de decoradores hacia otro módulo
Cuando voy a ejecutarlo me sale esto ,que debo o puedo hacer?
pv: create: No such file or directory
pv: clients: read failed: Is a directory
0.00 B 0:00:00 [0.00 B/s] [<=>
Y era un tipo en los decoradores de mis metodos create, uptdate, delete.
Me encanta este curso, he leido muchos comentarios de que ha sido un poco complicado entender estas ultimas clases y seguir al profesor en su explicacion.
Mi unico consejo sin generar polemica, es que si no entienden algo lo buscan en internet y practicar.
Así es, sin embargo también hay que tomar en cuenta que su inconformidad recae en que están pagando para ver un curso completo, no para tener que buscar en internet todo
El profeso es bastante bueno, prefiero a un profesor que tenga experticia en la materia que esta enseñando y que tenga bien definido como va a enseñar la materia, a un profesor que tenga vagos conocimientos sobre el tema que esta enseñando pero con carrera en educación. platzi es una gran herramienta de aprendizaje pero es eso, una herramienta, el proceso de aprendizaje esta compuesto de muchas cosas, entre ellas la investigacion. no pueden esperar a que ningún medio les de todo lo que ocupan para aprender y no tengan que hacer nada extra ustedes.
Hay que reforzar esta clase y las siguientes con videos externos acerca de click, es fundamental bros