Distribuir um projeto python é complicado porque não raramente ele tem vários pacotes com dependências, pensando nisso eu fiz um mini artigo-tutorial sobre como fazer
1) Crie um ambiente virtual
Ele vai colocar em um container tudo que o seu script precisa pra funcionar ou seja, vai facilitar e muito a nossa vida, pra fazer um é extremamente simples, considerando que você já está na sua pasta de trabalho, basta rodar no terminal:
python3 -m venv . --copies
A flag --copies
ancapsua o python
2) Inicie seu ambiente virtual
No passo anterior nós criamos o ambiente virtual mas não o iniciamos, portanto vamos “entrar” nele agora, o seguinte comando inicia o ambiente virtual:
source ./bin/activate
3) Instale seus pacotes
Mesmo que você os tenha instalado no sistema eles não vão (e nem deveriam) ser carregados no ambiente virtual, mas nem se preocupe, a lógica é exatamente a mesma, você vai usar o pip
pra instalar, a única diferença é que você vai usar a flag --no-cache-dir
:
pip --no-cache-dir install pacote1 pacote2 pacote3...
Por exemplo, se o seu projeto usa os pacotes request
e beautifulsoup4
sua linha ficaria assim:
pip --no-cache-dir install request beautifulsoup4
Fácil né?
4) Crie ou copie o seu script
Sim, se você já fez o seu script e instalou todas as dependências dele, pode só copiar que ele vai funcionar de boas (veja as observações), pra exemplificar vou pegar o script desse tutorial sobre beautifulsoup:
import requests
from bs4 import BeautifulSoup
page = requests.get('https://web.archive.org/web/20121007172955/https://www.nga.gov/collection/anZ1.htm')
soup = BeautifulSoup(page.text, 'html.parser')
last_links = soup.find(class_='AlphaNav')
last_links.decompose()
artist_name_list = soup.find(class_='BodyText')
artist_name_list_items = artist_name_list.find_all('a')
# Usar .contents para pegar as tags <a> filhas
for artist_name in artist_name_list_items:
names = artist_name.contents[0]
print(names)
Nota: seu script não deve fazer chamadas para caminhos absolutos
5) Teste
Obviamente você precisa testar o seu script, basta chamar ele assim:
python3 seu_script.py
Assim como faria fora do ambiente virtual
6) Deixe seu ambiente Python portável
O ambiente funciona mas tem um problema, se você mandar ele pra outra pessoa ou mover seu ambiente pra outra pasta ele não vai funcionar, isso acontece porque atualmente ele está usando um caminho absoluto pra carregar o ambiente, pra resolver isso, use os seguintes comandos:
- Primeiro vamos adicionar a shebang “#!/usr/bin/env bash” no arquivo
bin/activate
e redirecionar a saída parabin/python3.wrap
echo '#!/usr/bin/env bash' | cat - bin/activate > bin/python3.wrap
- Aqui vai a mágica nós vamos substituir o caminho absoluto pela saída do comando
$(dirname $(dirname $(readlink -f $0)))
no arquivobin/python3.wrap
, ele pega o diretório superior de onde o script está
sed -i "s|$(pwd)|\$\(dirname \$\(dirname \$\(readlink -f \$0\)\)\)|" python3
- Agora nós adicionamos a chamada ao python ou seja vamos chamar o python que nós encapsumalos no passo 1:
echo '$VIRTUAL_ENV/bin/python3 ${@}' >> bin/python3.wrap
- Por fim nós vamos assegurar que
bin/python3.wrap
possa ser execuutado:
chmod +x bin/python3.wrap
Ok, mas todo esse trabalho pra que? Bem, atualmente pra nós rodarmos nosso script nós precisamos fazer isso:
source ./bin/activate
python3 seu_script.py
E ainda temos outro problema, se nós não executarmos esses comandos no exato caminho codificado em bin/activate
nosso ambiente não vai funcionar, agora já ficou beeem mais simples, basta digitar:
./bin/python3 seu_script.py
E o ambiente virtual pode ser executado a partir de qualquer diretório, mas não é o suficinte
5) Criando um AppDir
Um AppDir é um diretório que contém todos os arquivos que uma aplicação precisa pra funcionar, atualmente nós tempos quase tudo faltando apenas o arquivo AppRun, ele é o responsável por iniciar o aplicativo, é um jeio padronizado de fazer, como o python configurou tudo em bin/activate
nós basicamente só precisamos chamar o bin/python3.wrap
, basta criar um arquivo chamado “AppRun” com esse modelo:
#!/bin/sh
HERE="$(dirname "$(readlink -f "${0}")")"
export PATH="${HERE}"/usr/bin/:"${HERE}"/usr/sbin/:"${HERE}"/usr/games/:"${HERE}"/bin/:"${HERE}"/sbin/:"${PATH}"
export LD_LIBRARY_PATH="${HERE}"/usr/lib/:"${HERE}"/usr/lib/i386-linux-gnu/:"${HERE}"/usr/lib/x86_64-linux-gnu/:"${HERE}"/usr/lib32/:"${HERE}"/usr/lib64/:"${HERE}"/lib/:"${HERE}"/lib/i386-linux-gnu/:"${HERE}"/lib/x86_64-linux-gnu/:"${HERE}"/lib32/:"${HERE}"/lib64/:"${LD_LIBRARY_PATH}"
export XDG_DATA_DIRS="${HERE}"/usr/share/:"${XDG_DATA_DIRS}"
export PERLLIB="${HERE}"/usr/share/perl5/:"${HERE}"/usr/lib/perl5/:"${PERLLIB}"
export GSETTINGS_SCHEMA_DIR="${HERE}"/usr/share/glib-2.0/schemas/:"${GSETTINGS_SCHEMA_DIR}"
export QT_PLUGIN_PATH="${HERE}"/usr/lib/qt4/plugins/:"${HERE}"/usr/lib/i386-linux-gnu/qt4/plugins/:"${HERE}"/usr/lib/x86_64-linux-gnu/qt4/plugins/:"${HERE}"/usr/lib32/qt4/plugins/:"${HERE}"/usr/lib64/qt4/plugins/:"${HERE}"/usr/lib/qt5/plugins/:"${HERE}"/usr/lib/i386-linux-gnu/qt5/plugins/:"${HERE}"/usr/lib/x86_64-linux-gnu/qt5/plugins/:"${HERE}"/usr/lib32/qt5/plugins/:"${HERE}"/usr/lib64/qt5/plugins/:"${QT_PLUGIN_PATH}"
Agora você adiciona no final desse arquivo:
echo -e "\n" '$HERE/bin/python3 $HERE/seu_script.py "$@"' >> AppRun
Obviamente substituindo seu_script.py
pelo nome do arquivo do seu script.
Pra finalizar basta tornar o arquivo AppRun executável:
chmod a+x AppRun
6) O que vem depois depende do que você quer
Agora (considerando que você esteja na pasta do ambiente virtual) você pode executar o script assim:
./AppRun
E isso abre um leque imenso de posibilidades, a partir daqui você pode fazer um AppImage, um Snap, um Flatpak, um tarball, um .deb, um .rpm… enfim, qualquer coisa
Espero que tenha sido útil e até a próxima