Artigo original: How to Build Your Very First Python Package

Há alguns meses, decidi lançar o Caer, um pacote de Computer Vision disponível em Python. Achei o processo excruciantemente doloroso. Você provavelmente pode adivinhar o porquê - pouca (e confusa) documentação, falta de bons tutoriais e assim por diante.

Por isso, decidi escrever este artigo na esperança de que ele ajude as pessoas que estão tendo dificuldades para fazer isso. Vamos construir um módulo muito simples e torná-lo disponível para qualquer pessoa no mundo.

O conteúdo desse módulo segue uma estrutura muito básica. Existem, no total, quatro arquivos em Python, cada um deles com um único método dentro de si. Vamos manter isso realmente simples, por enquanto.

base-verysimplemodule  --> Base
└── verysimplemodule   --> Módulo real
    ├── extras
    │   ├── multiply.py
    │   ├── divide.py
    ├── add.py
    ├── subtract.py

Você vai notar que tenho uma pasta chamada verysimplemodule que, por sua vez, tem dois arquivos em Python: add.py e subtract.py. Há também uma pasta chamada extras (que contém multiply.py e divide.py). Essa pasta formará a base do nosso módulo em Python.

Revelando os __init__s

Algo que você sempre encontrará em cada pacote Python é um arquivo __init__.py. Esse arquivo dirá ao Python para tratar os diretórios como módulos (ou submódulos).

De modo simples, ele conterá os nomes de todos os métodos em todos os arquivos em Python que estão em seu diretório imediato.

Um arquivo __init__.py típico tem o seguinte formato:

from arquivo import metodo 

# onde 'metodo' é uma função que está presente em um arquivo chamado 'arquivo.py'.

Ao criar pacotes em Python, você é obrigado a adicionar um arquivo __init__.py a cada subdiretório de seu pacote. Esses subdiretórios são os submódulos do seu pacote.

Para o nosso caso, adicionaremos nossos arquivos __init__.py ao diretório verysimplemodule (o "módulo real"), assim:

from add import add
from subtract import subtract

Vamos fazer o mesmo para a pasta extra, deste modo:

from multiply import multiply
from divide import divide

Uma vez feito isso, estamos praticamente na metade do processo!

Como configurar o setup.py

Dentro da pasta base-verysimplemodule (e no mesmo diretório que o nosso módulo verysimplemodule), precisamos adicionar um arquivo setup.py. Esse arquivo é essencial se você pretende criar o módulo real em questão.

Observação: fique à vontade para nomear o arquivo setup.py como você desejar. Esse nome não é específico do arquivo como no caso do nosso arquivo __init__.py.

Possíveis escolhas de nomes são setup_incrivel_do_pacote_python.py e python_setup_do_pacote.py, mas, geralmente, a prática recomendada é ficar com setup.py.

O arquivo setup.py conterá informações sobre o seu pacote, especificamente o nome do pacote, a sua versão, as dependências de plataforma e muito mais.

Para os nossos propósitos, não vamos exigir meta informações avançadas. Portanto, o código a seguir deve se adequar à maioria dos pacotes que você for criar:

from setuptools import setup, find_packages

VERSION = '0.0.1' 
DESCRIPTION = 'Meu primeiro pacote em Python'
LONG_DESCRIPTION = 'Meu primeiro pacote em Python com uma descrição um pouco mais longa'

# Setting up
setup(
       # 'name' deve corresponder ao nome da pasta 'verysimplemodule'
        name="verysimplemodule", 
        version=VERSION,
        author="Jason Dsouza",
        author_email="<seu_email@email.com>",
        description=DESCRIPTION,
        long_description=LONG_DESCRIPTION,
        packages=find_packages(),
        install_requires=[], # adicione outros pacotes que 
        # precisem ser instalados com o seu pacote. Ex: 'caer'
        
        keywords=['python', 'first package'],
        classifiers= [
            "Development Status :: 3 - Alpha",
            "Intended Audience :: Education",
            "Programming Language :: Python :: 2",
            "Programming Language :: Python :: 3",
            "Operating System :: MacOS :: MacOS X",
            "Operating System :: Microsoft :: Windows",
        ]
)

Com isso feito, tudo o que temos que fazer a seguir é executar o seguinte comando no mesmo diretório que o base-verysimplemodule:

python setup.py sdist bdist_wheel

Isso criará todos os pacotes necessários de que o Python precisará. Os comandos sdist e bdist_wheel criarão uma distribuição de fonte e uma roda que você poderá enviar mais tarde pelo PyPi.

PyPi — aqui vamos nós!

O PyPi é o repositório oficial do Python onde todos os pacotes são armazenados. Você pode pensar nele como um Github para os pacotes do Python.

Para disponibilizar o seu pacote Python para pessoas de todo o mundo, você precisará ter uma conta no PyPi.

Com isso feito, estamos todos prontos para enviar o nosso pacote ao PyPi. Você se lembra da distribuição da fonte e da roda que foram criadas quando executamos o python setup.py? Bom, são eles que serão realmente enviados para o PyPi.

Antes de fazer isso, porém, é preciso instalar o twine se ainda não o tiver instalado. Basta digitar o comando pip install twine.

Como enviar o seu pacote para o PyPi

Assumindo que você tenha o twine instalado, vá em frente e execute:

twine upload dist/*

Esse comando carregará o conteúdo da pasta dist que foi gerada automaticamente quando executamos o python setup.py. Você receberá uma mensagem pedindo o seu nome de usuário e senha do PyPi. Portanto, vá em frente e digite-os.

Agora, se você seguiu esse tutorial minuciosamente, poderá receber um erro ao longo das linhas dizendo que o repositório já existe.

Isso geralmente acontece porque há um conflito entre o nome do seu pacote e um pacote que já existe. Em outras palavras, mude o nome do pacote - outra pessoa já tomou esse nome.

É isso! Para instalar o seu módulo pip com todo orgulho, acione um terminal e execute:

pip install <nome_do_pacote> 

# em nosso caso, pip install verysimplemodule

Veja como o Python instala perfeitamente o seu pacote a partir dos binários que foram gerados anteriormente.

Abra um shell interativo do Python e tente importar o seu pacote:

>> import verysimplemodule as vsm

>> vsm.add(2,5)
7
>> vsm.subtract(5,4)
1

Para acessar os métodos de divisão e multiplicação (você se lembra de que eles estavam em uma pasta chamada extras?), execute:

>> import verysimplemodule as vsm

>> vsm.extras.divide(4,2)
2
>> vsm.extras.multiple(5,3)
15

É simples assim.

Parabéns! Você acabou de construir o seu primeiro pacote do Python. Embora seja muito simples, o seu pacote agora está disponível para ser baixado por qualquer pessoa do mundo (desde que essa pessoa tenha o Python instalado, é claro).

O que vem a seguir?

Teste do PyPi

O pacote que usamos nesse tutorial foi um módulo extremamente simples – operações matemáticas básicas de adição, subtração, multiplicação e divisão. Não faz sentido enviá-las diretamente ao PyPi, especialmente porque você está tentando isso pela primeira vez.

Felizmente, para nós, existe o Test PyPi, uma instância separada do PyPi onde você pode testar e experimentar o seu pacote (você precisará se registrar para uma conta própria na plataforma).

O processo que você segue para enviar ao Test PyPi é praticamente o mesmo, com algumas pequenas mudanças.

# O comando a seguir fará o upload do pacote ao Test PyPi
# Será solicitado que você forneça suas credenciais do Test PyPi

twine upload --repository testpypi dist/*

Para baixar projetos do Test PyPi:

pip install --index-url "https://test.pypi.org/simple/<nome_do_pacote>"

Metainformação avançada

A metainformação que usamos no arquivo era muito básica. Você pode adicionar informações adicionais, como múltiplos gestores (se houver), e-mail do autor, informações de licença e toda uma série de outros dados.

Este artigo (texto em inglês) será particularmente útil se você pretende fazer isso.

Veja outros repositórios

Olhando como outros repositórios criaram seus pacotes pode ser muito útil para você.

Ao criar o Caer, eu observava constantemente como o Numpy e o Sonnet preparavam os seus pacotes. Eu recomendaria dar uma olhada nos repositórios do Caer, do Numpy e do Tensorflow se você planeja criar pacotes um pouco mais avançados.