A criação de pacotes Python sempre foi algo que me chamou a atenção. Em meu trabalho atual, acabei me tornando um core developer da biblioteca de aprendizado de máquina de uso interno da empresa, além de contribuidor de alguns projetos open-source.
Sendo core developer, comecei a entender melhor como a construção de pacotes é feita e a conhecer diferentes ferramentas que podem auxiliar o desenvolvedor nessa tarefa.
Uma das ferramentas que mais me chamou a atenção foi o Poetry, que torna a construção de pacotes em Python cada vez mais simples. Essa ferramenta gera um ambiente virtual (isolado) para podermos trabalhar com nosso projeto, além de nos ajudar com o controle de versão, gerenciamento de dependências, build e compartilhamento no repositório de pacotes Python PyPI (que você provavelmente conhece).
A ideia deste artigo é criar um pacote Python (para fins educativos, somente) e compartilhá-lo no repositório PyPI, tudo isso com o auxílio da ferramenta Poetry. Todo o código fonte desenvolvido aqui poderá ser acessado no repositório GitHub do projeto:
https://github.com/felipesassi/random-data-gen
A ideia aqui é construirmos um pacote que gere tabelas de dados transacionais fictícios. Queremos gerar tabelas contendo o ID único do usuário (consumer_id), data da compra (transaction_created_at) e valor da compra (transaction_payment_value).
O nome do nosso pacote será RandomDataGen (eu não sou muito criativo hehe).
Basicamente, a ideia final é poder importar esse pacote e utilizá-lo da seguinte forma:
Como saída, devemos ter algo assim (lembrando que toda a geração de dados será aleatória):
Mas, antes de mais nada, precisamos entender como o Poetry funciona e como ele pode nos ajudar nessa tarefa.
A instalação do Poetry é muito simples, basta seguirmos os passos apresentados aqui.
Após a instalação, o Poetry estará pronto para ser utilizado. O primeiro passo é criarmos uma pasta chamada random-data-gen e navegarmos até ela com com o terminal. Após isso, devemos rodar o seguinte comando:
Este comando cria uma estrutura de pastas e de arquivos no diretório “.” (que no nosso caso deve ser um diretório chamado random-data-gen) com o nome desse diretório sendo utilizado como nome do projeto.
A estrutura de pastas gerada pelo Poetry tem a seguinte forma:
random-data-gen/
│ README.md
│ pyproject.toml
│
└───random_data_gen/
│ │ __init__.py
│
└───tests/
│ __init__.py
│ test_random_data_gen.py
Nessa estrutura, arquivo README.md deve ser utilizado para descrição do projeto. O arquivo pyproject.toml contém todas as informações do pacote que está sendo desenvolvido e é nele que toda a mágica do Poetry acontece. A pasta /random_data_gen será o diretório utilizado para armazenarmos todo o código do projeto. Por fim, a pasta /tests irá conter todos os testes funcionais presentes no projeto.
Entrando em detalhes, o arquivo pyproject.toml contém as seguintes informações:
Os campos name, version, description e authors são autoexplicativos. Os campos abaixo da seção tool.poetry.dependencies são referentes as dependências utilizadas pelo projeto (que no caso de um projeto vazio será somente a versão do Python desejada).
Os campos abaixo da seção tool.poetry.dev-dependencies indicam dependências que serão utilizadas somente durante desenvolvimento (que, no nosso caso, é somente a biblioteca pytest, para testes funcionais). Aqui, podemos incluir outras dependências, como black para formatação de código, mypy para verificação de tipos etc.
Um ponto interessante é a distinção entre as seções dependencies e dev-dependencies:
Essa distinção é muito interessante, pois evita que pacotes desnecessários tenham de ser instalados por quem vai utilizar o pacote, além de garantir mais organização na criação do projeto.
Os campos abaixo de build-system são campos padrão e não necessitaremos alterar durante esse projeto. Para quem quiser ler mais sobre os arquivos pyproject.toml, irei deixar uma referência ao final do artigo.
Agora que sabemos um pouco mais como o Poetry funciona, vamos utilizá-lo para construir nosso pacote. O primeiro passo é inicializar nosso ambiente virtual com o seguinte comando (passo muito semelhante ao uso do comando conda activate):
Antes de mais nada, precisamos especificar as dependências que vamos utilizar, que no nosso caso serão duas:
A instalação desses pacotes dentro do nosso ambiente virtual é muito simples, precisamos apenas do seguinte comando:
Após instalarmos esses pacotes, podemos verificar que as dependências no nosso arquivo pyproject.toml foram alteradas:
Basicamente essa seção está nos dizendo que:
Agora que criamos um ambiente virtual e instalamos tudo que é necessário, podemos começar a criação do nosso pacote Python. O primeiro passo é criar os seguintes arquivos e pastas na nossa estrutura inicial do projeto (em negrito para facilitar a leitura):
random-data-gen/
│ README.md
│ pyproject.toml
| poetry.lock
│
└───random_data_gen/
│ │ __init__.py
| | data_generator.py
| |
| └───features/
| | transactional_features.py
|
└───tests/
│ __init__.py
│ test_random_data_gen.py
A pasta /features irá conter o código para geração de cada uma das três colunas presentes na tabela final (código que está dentro do arquivo transactional_features.py). O arquivo data_generator.py irá conter a lógica principal da aplicação, que será responsável por criar o conjunto de dados transacionais.
O intuito não é entrar em detalhes nesses códigos, caso queira saber mais você pode visitar o repositório do projeto. A título de exemplificação, uma parte do código presente no arquivo transactional_features.py é apresentado na figura abaixo:
Com o intuito de padronizar nosso código e verificar erros de tipagem, iremos instalar três pacotes como dependência de desenvolvimento. Essas dependências não serão utilizadas pela versão final do pacote RandomDataGen, sendo instaladas somente quando alguém necessitar contribuir com seu desenvolvimento.
Nesse projeto iremos instalar três dependências:
A explicação em detalhes do funcionamento desses três pacotes pode ser vista em suas documentações oficiais, que estarão como referências no final desse artigo.
A instalação de dependências de desenvolvimento com o Poetry é extremamente simples:
Depois da instalação, nosso arquivo pyproject.toml ficará da seguinte forma:
Para configurar a ferramenta black, devemos adicionar a seguinte seção no nosso arquivo pyprojet.toml (nessa configuração estamos definindo basicamente a quantidade de caracteres máxima por linha):
A título de exemplo, as figuras abaixo apresentam o código antes e depois da aplicação da ferramenta black:
Podemos ver que a ferramenta inseriu quebras de linha nas linhas que excediam o máximo de caracteres esperado (que no nosso caso foi definido como 100 caracteres por linha).
Após finalizarmos o desenvolvimento do pacote devemos pública-lo no repositório de pacotes Python PyPI. Esse repositório pode ser acessado aqui (para publicar um pacote você precisa se cadastrar na plataforma).
Devemos incluir nosso README.md no cabeçalho de nosso arquivo pyproject.toml para que ele seja utilizado como descrição na página oficial do projeto:
Antes de publicarmos o pacote precisamos rodar o seguinte comando:
Esse comando cria os arquivos .whl e .tar.gz dentro de uma pasta /dist, na raiz do nosso projeto.
Após isso, podemos rodar o comando:
Esse comando irá guiá-lo pelo login no PyPI e após isso enviará o pacote para lá.
Caso você deseje publicar esse mesmo pacote, uma alteração no nome deverá ser realizada, pois o PyPI não permite pacotes com o mesmo nome (o que faz sentido, não é?!).
Agora que publicamos nosso pacote, podemos acessá-lo pelo link:
https://pypi.org/project/random-data-gen/
Nesse artigo vimos como a ferramenta Poetry pode nos ajudar a desenvolver pacotes Python de uma forma rápida e elegante. Passamos desde a instalação da ferramenta até a publicação do pacote no PyPI.
O Poetry abstraiu diversas etapas do desenvolvimento, tornando a tarefa do desenvolvedor mais focada em resolver a lógica do problema/criação do pacote do que nas tarefas secundárias que são necessárias para conclusão dessa tarefa.
Os nossos próximos passos serão:
Espero que tenham gostado!
Quer saber mais sobre o assunto ou descobrir como a Datarisk pode te ajudar nessas questões? Acesse o nosso site e leia também nossos outros artigos no blog. Até mais!
python-poetry.org
python-poetry.org
mypy-lang.org
github.com
flake8.pycqa.org
www.python.org
Thanks to João Paulo Nogueira and Emanuel Fontelles