zipapp no Python: crie apps executáveis

Publicado em: 01/09/2026
Tempo de leitura: 6 minutos
Aplicação Python empacotada como arquivo executável com zipapp

O módulo zipapp permite empacotar uma aplicação Python em um único arquivo executável com extensão .pyz. Esse formato usa um arquivo ZIP comum com um ponto de entrada definido em __main__.py. Na prática, você pode distribuir ferramentas de linha de comando, utilitários internos e pequenos serviços sem entregar dezenas de arquivos separados.

O recurso faz parte da biblioteca padrão e funciona melhor em projetos Python puros, sem extensões nativas. Ele não substitui ambientes virtuais, instaladores ou ferramentas como PyInstaller em todos os cenários, mas é uma solução simples e elegante quando o público já possui uma versão compatível do Python instalada.

Como funciona um arquivo pyz

Um arquivo .pyz é um ZIP que o interpretador consegue executar diretamente. O Python abre o pacote, procura por __main__.py e executa esse módulo como entrada da aplicação. Isso significa que a estrutura interna pode conter pacotes, módulos, arquivos de configuração e outros recursos compatíveis com importação por ZIP.

meu_app/
├── __main__.py
├── cli.py
└── util.py

O arquivo __main__.py pode importar uma função principal de outro módulo e chamá-la. Essa separação evita concentrar toda a lógica no ponto de entrada e facilita testes unitários.

from cli import main

if __name__ == "__main__":
    raise SystemExit(main())

Criando o primeiro zipapp

Com a pasta pronta, execute o módulo pela linha de comando:

python -m zipapp meu_app -o meu_app.pyz

O parâmetro -o define o arquivo de saída. Depois, execute com:

python meu_app.pyz

Em sistemas Unix, você também pode adicionar uma linha de interpretador e tornar o arquivo executável:

python -m zipapp meu_app -o meu_app.pyz -p "/usr/bin/env python3"
chmod +x meu_app.pyz
./meu_app.pyz

A opção -p grava o shebang no início do arquivo. No Windows, normalmente a execução continua sendo feita com python arquivo.pyz ou por associação de arquivos.

Definindo o ponto de entrada

Se a pasta não possui __main__.py, o parâmetro -m pode indicar uma função no formato modulo:funcao. O zipapp cria automaticamente o ponto de entrada.

python -m zipapp meu_app -m "cli:main" -o ferramenta.pyz

A função indicada deve ser importável e não receber argumentos obrigatórios. O retorno pode ser usado como código de saída quando combinado com SystemExit.

Usando a API em Python

O módulo também oferece a função zipapp.create_archive(). Ela é útil em scripts de build, pipelines de CI e automações que precisam gerar vários artefatos.

from zipapp import create_archive

create_archive(
    "meu_app",
    target="dist/meu_app.pyz",
    interpreter="/usr/bin/env python3",
    main="cli:main",
    compressed=True,
)

O argumento compressed=True reduz o tamanho do arquivo, embora possa aumentar levemente o tempo de abertura. Para aplicações pequenas, a diferença costuma ser irrelevante.

Dependências externas

O principal desafio é lidar com dependências. Bibliotecas Python puras podem ser copiadas para dentro da pasta do aplicativo antes do empacotamento. Uma abordagem comum é instalar as dependências em um diretório temporário com pip --target.

python -m pip install -r requirements.txt --target build/app
cp -r src/* build/app/
python -m zipapp build/app -o dist/app.pyz -m "cli:main"

Essa técnica não é indicada para pacotes que dependem de extensões compiladas, como arquivos .so, .pyd ou bibliotecas do sistema. O importador de ZIP não consegue carregar todos esses binários diretamente do arquivo compactado.

Compatibilidade de versão

O arquivo não inclui o interpretador. Portanto, a máquina de destino precisa ter Python instalado e uma versão compatível com o código e as dependências. Se o projeto usa recursos recentes da linguagem, documente claramente a versão mínima.

Também é importante considerar diferenças entre sistemas operacionais. Um pacote Python puro tende a ser portátil, mas caminhos, permissões, comandos externos e codificações podem variar.

Arquivos de dados

Recursos internos exigem cuidado. Em vez de assumir que existe um caminho físico ao lado do módulo, prefira importlib.resources. Essa API acessa dados empacotados mesmo quando eles estão dentro de um ZIP.

from importlib.resources import files

texto = files("meu_pacote").joinpath("modelo.txt").read_text(
    encoding="utf-8"
)

Evite usar diretamente Path(__file__).parent para recursos que precisam funcionar dentro do zipapp. Nem todo recurso interno corresponde a um arquivo tradicional no sistema.

Configuração externa

Senhas, tokens e configurações específicas do ambiente não devem ser embutidos no arquivo. Use variáveis de ambiente, argumentos de linha de comando ou arquivos externos com permissões adequadas. Empacotar segredos dentro do .pyz apenas os oculta superficialmente, pois qualquer pessoa pode abrir o arquivo como ZIP.

Atualizações e integridade

Um único artefato facilita distribuição e rollback. Você pode versionar o nome, calcular um hash SHA-256 e publicar o valor em um canal confiável. Antes da execução, o usuário ou o pipeline pode verificar se o download está íntegro.

python -c "import hashlib, pathlib; p=pathlib.Path('app.pyz'); print(hashlib.sha256(p.read_bytes()).hexdigest())"

Assinaturas digitais oferecem proteção adicional quando a origem do artefato precisa ser autenticada.

Testes antes do empacotamento

Teste a aplicação como pacote normal e depois teste o artefato final. Alguns problemas só aparecem no ZIP, especialmente acesso a recursos, importações dinâmicas e bibliotecas que dependem de caminhos físicos.

Inclua testes de ajuda da CLI, códigos de saída, entradas inválidas e execução em cada versão suportada do Python. Em CI, crie o arquivo e execute um smoke test real.

Quando usar zipapp

  • Ferramentas internas de linha de comando.
  • Scripts administrativos com vários módulos.
  • Aplicações Python puras distribuídas para ambientes controlados.
  • Artefatos simples para pipelines e servidores que já têm Python.
  • Utilitários educacionais fáceis de baixar e executar.

Quando escolher outra solução

Use wheels e instaladores quando o projeto deve integrar-se ao ecossistema de pacotes. Use containers quando precisa controlar sistema operacional, serviços e bibliotecas nativas. Use ferramentas que incluem o interpretador quando o usuário final não deve instalar Python.

Zipapp é melhor quando simplicidade, transparência e baixo custo de build são prioridades.

Boas práticas

Mantenha um ponto de entrada pequeno, separe lógica de negócio, fixe versões de dependências e gere o artefato em ambiente limpo. Não inclua caches, testes desnecessários ou credenciais. Documente a versão mínima do Python, os comandos de execução e as limitações conhecidas.

Para aprofundar conceitos relacionados, veja os conteúdos da Academify sobre importlib.resources, ambientes virtuais com venv, argparse no Python e subprocess no Python.

Conclusão

O módulo zipapp transforma uma aplicação Python em um arquivo único e executável sem ferramentas externas. Ele é especialmente útil para projetos Python puros e ambientes controlados. Ao combinar uma estrutura organizada, um ponto de entrada claro, dependências compatíveis, acesso correto a recursos e testes do artefato final, você obtém uma distribuição simples, reproduzível e fácil de atualizar.

Fontes externas

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Código Python usado para compor funções com functools.Placeholder
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    functools.Placeholder: partial com lacunas posicionais

    Aprenda functools.Placeholder no Python para preencher argumentos posicionais flexíveis com partial e criar APIs funcionais mais claras.

    Ler mais

    Tempo de leitura: 5 minutos
    31/08/2026
    Pessoa programando e analisando dados em Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    itertools.pairwise: compare elementos vizinhos

    Aprenda itertools.pairwise no Python para comparar elementos vizinhos, detectar mudanças e criar pipelines claros e eficientes.

    Ler mais

    Tempo de leitura: 4 minutos
    31/08/2026
    High-angle view of woman coding on a laptop, with a Python book nearby. Ideal for programming and tech content.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    types.new_class no Python: classes dinâmicas

    Aprenda types.new_class no Python para gerar classes dinâmicas com metaclasses, namespaces preparados, herança e metadados corretos.

    Ler mais

    Tempo de leitura: 4 minutos
    30/08/2026
    Detailed view of computer code highlighting syntax in colors on a screen.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    partialmethod: crie métodos especializados no Python

    Aprenda partialmethod no Python para criar métodos especializados com binding correto, menos wrappers e APIs de domínio mais claras.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    A detailed image of a reticulated python showcasing its patterned scales and intricate skin texture.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    inspect.getmembers_static: liste atributos sem executar

    Use inspect.getmembers_static no Python para listar atributos sem executar properties, descriptors ou resolução dinâmica indesejada.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    Close-up of a python snake curled up, showcasing its detailed scales.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    DynamicClassAttribute: descriptors e acesso dinâmico

    Entenda DynamicClassAttribute no Python, descriptors, acesso por classe e instância, metaclasses, Enum e introspecção segura.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026