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.pyO 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.pyzO parâmetro -o define o arquivo de saída. Depois, execute com:
python meu_app.pyzEm 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.pyzA 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.pyzA 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.







