Voltar ao Glossario
Glossario Python

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.