Criando CLI com Python — 2025 | Python Brasil
Aprenda a criar ferramentas de linha de comando com Python usando argparse e Click. Exemplos praticos com subcomandos, opcoes e formatacao.
Ferramentas de linha de comando sao parte essencial do dia a dia de qualquer desenvolvedor. Python oferece otimas opcoes para criar CLIs profissionais, desde o argparse da biblioteca padrao ate o Click, uma biblioteca externa muito popular. Neste artigo, a gente vai explorar as duas abordagens com exemplos praticos.
Por Que Criar CLIs com Python?
CLIs sao ideais para automacao, scripts de deploy, ferramentas de desenvolvimento e processamento de dados. Python e perfeito para isso porque tem excelente suporte a manipulacao de strings, acesso ao sistema operacional e uma vasta colecao de bibliotecas.
Usando argparse (Biblioteca Padrao)
O argparse ja vem incluso no Python e e a forma mais basica de criar CLIs:
#!/usr/bin/env python3
"""Ferramenta CLI para gerenciar tarefas."""
import argparse
import json
from pathlib import Path
from datetime import datetime
ARQUIVO_TAREFAS = Path.home() / ".tarefas.json"
def carregar_tarefas():
"""Carrega tarefas do arquivo JSON."""
if ARQUIVO_TAREFAS.exists():
return json.loads(ARQUIVO_TAREFAS.read_text())
return []
def salvar_tarefas(tarefas):
"""Salva tarefas no arquivo JSON."""
ARQUIVO_TAREFAS.write_text(json.dumps(tarefas, indent=2, ensure_ascii=False))
def adicionar(args):
"""Adiciona uma nova tarefa."""
tarefas = carregar_tarefas()
tarefa = {
"id": len(tarefas) + 1,
"titulo": args.titulo,
"prioridade": args.prioridade,
"concluida": False,
"criada_em": datetime.now().isoformat()
}
tarefas.append(tarefa)
salvar_tarefas(tarefas)
print(f"Tarefa #{tarefa['id']} adicionada: {args.titulo}")
def listar(args):
"""Lista todas as tarefas."""
tarefas = carregar_tarefas()
if not tarefas:
print("Nenhuma tarefa encontrada.")
return
for t in tarefas:
status = "concluida" if t["concluida"] else "pendente"
print(f" [{t['id']}] {t['titulo']} ({t['prioridade']}) - {status}")
def concluir(args):
"""Marca uma tarefa como concluida."""
tarefas = carregar_tarefas()
for t in tarefas:
if t["id"] == args.id:
t["concluida"] = True
salvar_tarefas(tarefas)
print(f"Tarefa #{args.id} concluida!")
return
print(f"Tarefa #{args.id} nao encontrada.")
def main():
parser = argparse.ArgumentParser(
description="Gerenciador de tarefas via terminal"
)
subparsers = parser.add_subparsers(dest="comando", help="Comandos disponiveis")
# Subcomando: adicionar
parser_add = subparsers.add_parser("adicionar", help="Adiciona uma tarefa")
parser_add.add_argument("titulo", help="Titulo da tarefa")
parser_add.add_argument(
"-p", "--prioridade",
choices=["baixa", "media", "alta"],
default="media",
help="Prioridade da tarefa (padrao: media)"
)
parser_add.set_defaults(func=adicionar)
# Subcomando: listar
parser_list = subparsers.add_parser("listar", help="Lista todas as tarefas")
parser_list.set_defaults(func=listar)
# Subcomando: concluir
parser_done = subparsers.add_parser("concluir", help="Conclui uma tarefa")
parser_done.add_argument("id", type=int, help="ID da tarefa")
parser_done.set_defaults(func=concluir)
args = parser.parse_args()
if hasattr(args, "func"):
args.func(args)
else:
parser.print_help()
if __name__ == "__main__":
main()
Usando no terminal:
python tarefas.py adicionar "Estudar Python" -p alta
python tarefas.py listar
python tarefas.py concluir 1
Usando Click (Biblioteca Externa)
O Click simplifica muito a criacao de CLIs com decoradores intuitivos:
pip install click
Vamos recriar o gerenciador de tarefas com Click:
#!/usr/bin/env python3
"""Gerenciador de tarefas com Click."""
import click
import json
from pathlib import Path
from datetime import datetime
ARQUIVO = Path.home() / ".tarefas_click.json"
def carregar():
if ARQUIVO.exists():
return json.loads(ARQUIVO.read_text())
return []
def salvar(tarefas):
ARQUIVO.write_text(json.dumps(tarefas, indent=2, ensure_ascii=False))
@click.group()
@click.version_option(version="1.0.0")
def cli():
"""Gerenciador de tarefas via terminal."""
pass
@cli.command()
@click.argument("titulo")
@click.option(
"-p", "--prioridade",
type=click.Choice(["baixa", "media", "alta"]),
default="media",
help="Prioridade da tarefa."
)
def adicionar(titulo, prioridade):
"""Adiciona uma nova tarefa."""
tarefas = carregar()
tarefa = {
"id": len(tarefas) + 1,
"titulo": titulo,
"prioridade": prioridade,
"concluida": False,
"criada_em": datetime.now().isoformat()
}
tarefas.append(tarefa)
salvar(tarefas)
click.echo(click.style(f"Tarefa #{tarefa['id']} adicionada!", fg="green"))
@cli.command()
@click.option("--todas", is_flag=True, help="Mostra tarefas concluidas tambem.")
def listar(todas):
"""Lista tarefas pendentes."""
tarefas = carregar()
if not tarefas:
click.echo("Nenhuma tarefa encontrada.")
return
for t in tarefas:
if not todas and t["concluida"]:
continue
cor = "green" if t["concluida"] else "yellow"
status = "OK" if t["concluida"] else "pendente"
click.echo(
f" [{t['id']}] "
+ click.style(f"{t['titulo']}", fg=cor)
+ f" ({t['prioridade']}) - {status}"
)
@cli.command()
@click.argument("tarefa_id", type=int)
def concluir(tarefa_id):
"""Marca uma tarefa como concluida."""
tarefas = carregar()
for t in tarefas:
if t["id"] == tarefa_id:
t["concluida"] = True
salvar(tarefas)
click.echo(click.style(f"Tarefa #{tarefa_id} concluida!", fg="green"))
return
click.echo(click.style(f"Tarefa #{tarefa_id} nao encontrada.", fg="red"))
@cli.command()
@click.argument("tarefa_id", type=int)
@click.confirmation_option(prompt="Tem certeza que deseja remover?")
def remover(tarefa_id):
"""Remove uma tarefa permanentemente."""
tarefas = carregar()
tarefas = [t for t in tarefas if t["id"] != tarefa_id]
salvar(tarefas)
click.echo(f"Tarefa #{tarefa_id} removida.")
if __name__ == "__main__":
cli()
Click vs argparse: Comparacao
A principal diferenca entre as duas abordagens esta na ergonomia. O argparse exige construcao manual dos parsers e subparsers, enquanto o Click usa decoradores declarativos. Para CLIs simples, argparse resolve bem. Para projetos maiores, Click oferece vantagens como grupos de comandos aninhados, validacao automatica e coloracao no terminal.
Outro ponto forte do Click e a integracao com setuptools para distribuicao:
# setup.py ou pyproject.toml
# entry_points = {"console_scripts": ["tarefas=tarefas:cli"]}
Isso permite instalar a CLI com pip install . e usa-la diretamente no terminal.
Adicionando Barras de Progresso
Ambas as bibliotecas suportam indicadores de progresso. Com Click:
import click
import time
@click.command()
@click.argument("arquivos", nargs=-1)
def processar(arquivos):
"""Processa uma lista de arquivos."""
with click.progressbar(arquivos, label="Processando") as barra:
for arquivo in barra:
time.sleep(0.5) # Simula processamento
click.echo("Concluido!")
Formatando Saida com Tabelas
Para saidas mais profissionais, use a biblioteca tabulate:
from tabulate import tabulate
def mostrar_tabela(tarefas):
"""Mostra tarefas em formato de tabela."""
dados = [
[t["id"], t["titulo"], t["prioridade"],
"Sim" if t["concluida"] else "Nao"]
for t in tarefas
]
headers = ["ID", "Titulo", "Prioridade", "Concluida"]
print(tabulate(dados, headers=headers, tablefmt="grid"))
# +------+------------------+-------------+------------+
# | ID | Titulo | Prioridade | Concluida |
# +======+==================+=============+============+
# | 1 | Estudar Python | alta | Sim |
# +------+------------------+-------------+------------+
Empacotando Sua CLI
Para distribuir sua ferramenta, configure o pyproject.toml:
[project]
name = "tarefas-cli"
version = "1.0.0"
description = "Gerenciador de tarefas via terminal"
requires-python = ">=3.9"
dependencies = ["click>=8.0"]
[project.scripts]
tarefas = "tarefas:cli"
Depois basta instalar em modo de desenvolvimento com pip install -e . e o comando tarefas estara disponivel globalmente.
Boas Praticas para CLIs
Ao criar ferramentas de linha de comando, siga estas recomendacoes:
- Sempre inclua
--helpcom descricoes claras para todos os comandos e opcoes - Use codigos de saida adequados: 0 para sucesso, 1 para erro
- Adicione
--versionpara facilitar debug - Formate a saida com cores e tabelas para melhor legibilidade
- Trate erros de forma amigavel com mensagens claras
- Adicione confirmacao para operacoes destrutivas
- Escreva testes para os comandos usando
CliRunnerdo Click
Conclusao
Python e uma escolha excelente para criar ferramentas de linha de comando. O argparse atende bem para scripts simples, enquanto o Click brilha em projetos maiores com multiplos subcomandos e opcoes. Independente da escolha, o importante e criar CLIs com boa documentacao, tratamento de erros e uma experiencia agradavel para o usuario. Comece com os exemplos deste guia e evolua conforme a complexidade do seu projeto.
Equipe Python Brasil
Contribuidor do Python Brasil — Aprenda Python em Português