Argparse: O que É e Como Funciona | Python Brasil
Domine argparse em Python: crie interfaces de linha de comando profissionais com argumentos posicionais, flags, subcomandos e validacao automatica.
O que e Argparse?
Argparse e o modulo da biblioteca padrao do Python para criar interfaces de linha de comando (CLI). Ele permite definir quais argumentos o programa aceita, gerar mensagens de ajuda automaticamente, validar entradas do usuario e converter tipos de dados. Com argparse, voce transforma scripts simples em ferramentas profissionais de linha de comando.
Embora existam bibliotecas de terceiros como Click e Typer que oferecem APIs mais modernas, argparse nao requer instalacao adicional e e suficiente para a maioria dos casos de uso.
Uso Basico
import argparse
# Criar o parser
parser = argparse.ArgumentParser(
description='Ferramenta para processar arquivos de texto.',
epilog='Exemplo: python script.py arquivo.txt --formato csv',
)
# Argumento posicional (obrigatorio)
parser.add_argument('arquivo', help='Caminho do arquivo de entrada')
# Argumento opcional (flag)
parser.add_argument('-f', '--formato', default='txt',
choices=['txt', 'csv', 'json'],
help='Formato de saida (padrao: txt)')
parser.add_argument('-v', '--verbose', action='store_true',
help='Ativar modo detalhado')
# Parsear argumentos
args = parser.parse_args()
print(f'Arquivo: {args.arquivo}')
print(f'Formato: {args.formato}')
print(f'Verbose: {args.verbose}')
Tipos de Argumentos
import argparse
parser = argparse.ArgumentParser(description='Exemplo de tipos de argumentos')
# Argumento com tipo especifico
parser.add_argument('--porta', type=int, default=8000,
help='Numero da porta (padrao: 8000)')
parser.add_argument('--taxa', type=float, default=0.5,
help='Taxa de processamento')
# Argumento que aceita multiplos valores
parser.add_argument('--arquivos', nargs='+',
help='Lista de arquivos para processar')
parser.add_argument('--dimensoes', nargs=2, type=int,
metavar=('LARGURA', 'ALTURA'),
help='Dimensoes da imagem')
# Argumento opcional com valor padrao quando presente sem valor
parser.add_argument('--log', nargs='?', const='app.log', default=None,
help='Arquivo de log (padrao: app.log se flag presente)')
# Argumento que conta ocorrencias
parser.add_argument('-v', '--verbose', action='count', default=0,
help='Nivel de verbosidade (-v, -vv, -vvv)')
# Argumentos mutuamente exclusivos
grupo = parser.add_mutually_exclusive_group()
grupo.add_argument('--json', action='store_true', help='Saida em JSON')
grupo.add_argument('--csv', action='store_true', help='Saida em CSV')
args = parser.parse_args()
Subcomandos
import argparse
parser = argparse.ArgumentParser(description='Gerenciador de banco de dados')
subparsers = parser.add_subparsers(dest='comando', help='Comandos disponiveis')
# Subcomando: criar
parser_criar = subparsers.add_parser('criar', help='Criar novo banco')
parser_criar.add_argument('nome', help='Nome do banco')
parser_criar.add_argument('--tipo', default='sqlite',
choices=['sqlite', 'postgres', 'mysql'])
# Subcomando: migrar
parser_migrar = subparsers.add_parser('migrar', help='Executar migrations')
parser_migrar.add_argument('--ate', type=int, help='Migrar ate a versao N')
parser_migrar.add_argument('--reverter', action='store_true',
help='Reverter ultima migration')
# Subcomando: backup
parser_backup = subparsers.add_parser('backup', help='Fazer backup')
parser_backup.add_argument('destino', help='Diretorio de destino')
parser_backup.add_argument('--compactar', action='store_true')
args = parser.parse_args()
if args.comando == 'criar':
print(f'Criando banco {args.nome} ({args.tipo})')
elif args.comando == 'migrar':
print(f'Executando migrations...')
elif args.comando == 'backup':
print(f'Backup para {args.destino}')
else:
parser.print_help()
Validacao Customizada
import argparse
from pathlib import Path
def arquivo_existente(caminho: str) -> Path:
"""Valida que o arquivo existe."""
p = Path(caminho)
if not p.exists():
raise argparse.ArgumentTypeError(f'Arquivo nao encontrado: {caminho}')
if not p.is_file():
raise argparse.ArgumentTypeError(f'Nao e um arquivo: {caminho}')
return p
def porta_valida(valor: str) -> int:
"""Valida que a porta esta no range valido."""
porta = int(valor)
if not (1 <= porta <= 65535):
raise argparse.ArgumentTypeError(f'Porta deve ser entre 1 e 65535')
return porta
parser = argparse.ArgumentParser()
parser.add_argument('entrada', type=arquivo_existente,
help='Arquivo de entrada')
parser.add_argument('--porta', type=porta_valida, default=8000,
help='Porta do servidor')
args = parser.parse_args()
print(f'Processando: {args.entrada}')
Exemplo Completo: CLI Profissional
#!/usr/bin/env python3
"""Ferramenta CLI para analise de logs."""
import argparse
import sys
from pathlib import Path
from datetime import datetime
def analisar(args):
"""Analisa o arquivo de log."""
print(f'Analisando {args.arquivo}...')
print(f'Nivel minimo: {args.nivel}')
if args.saida:
print(f'Salvando em: {args.saida}')
def resumir(args):
"""Gera resumo dos logs."""
print(f'Resumo do periodo: {args.inicio} ate {args.fim}')
def main():
parser = argparse.ArgumentParser(
prog='logtools',
description='Ferramentas para analise de arquivos de log.',
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument('--version', action='version', version='%(prog)s 1.0.0')
sub = parser.add_subparsers(dest='comando', required=True)
# Subcomando: analisar
p_analisar = sub.add_parser('analisar', help='Analisar logs')
p_analisar.add_argument('arquivo', type=Path)
p_analisar.add_argument('--nivel', default='WARNING',
choices=['DEBUG', 'INFO', 'WARNING', 'ERROR'])
p_analisar.add_argument('-o', '--saida', type=Path)
p_analisar.set_defaults(func=analisar)
# Subcomando: resumir
p_resumir = sub.add_parser('resumir', help='Resumo dos logs')
p_resumir.add_argument('--inicio', required=True)
p_resumir.add_argument('--fim', required=True)
p_resumir.set_defaults(func=resumir)
args = parser.parse_args()
args.func(args)
if __name__ == '__main__':
main()
Grupos de Argumentos
import argparse
parser = argparse.ArgumentParser(description='Ferramenta de deploy')
# Grupo logico para organizacao da ajuda
grupo_servidor = parser.add_argument_group('opcoes do servidor')
grupo_servidor.add_argument('--host', default='localhost')
grupo_servidor.add_argument('--porta', type=int, default=8000)
grupo_banco = parser.add_argument_group('opcoes do banco de dados')
grupo_banco.add_argument('--db-host', default='localhost')
grupo_banco.add_argument('--db-nome', required=True)
args = parser.parse_args()
Erros Comuns
O erro mais frequente e confundir argumentos posicionais (obrigatorios) com opcionais (flags com --). Outro erro e nao tratar o caso em que nenhum subcomando e fornecido, resultando em AttributeError. Tambem e comum esquecer que nargs='*' pode capturar zero argumentos, retornando uma lista vazia. Usar type=bool nao funciona como esperado — use action='store_true' ou action='store_false' para flags booleanas.
Boas Praticas
Inclua descricoes claras no parser e em cada argumento. Use choices para restringir valores validos. Crie funcoes de tipo customizadas para validacoes complexas. Use subcomandos para CLIs com multiplas funcionalidades. Adicione --version e --verbose como opcoes padrao. Forneca exemplos no epilog do parser. Para CLIs mais complexas, considere bibliotecas como Typer ou Click.
Quando Usar
Argparse e ideal para scripts que precisam receber configuracoes via linha de comando, ferramentas de automacao, utilitarios de sistema e qualquer programa que sera executado no terminal. Para aplicacoes simples com poucos argumentos, sys.argv pode ser suficiente, mas argparse escala muito melhor conforme a complexidade aumenta.