Python Packaging 101#

Um tutorial para iniciantes, do começo ao fim

Boas-vindas à série de tutoriais de empacotamento Python da pyOpenSci. As lições nas próximas páginas vão orientar pelos passos essenciais para criar um pacote Python.

Diagrama mostrando as lições do nosso tutorial de empacotamento. São 6 ao todo: o que é um pacote Python, tornar o código instalável com pip, publicar seu pacote no PyPI, adicionar arquivos README e LICENSE, adicionar metadata para o PyPI e, por fim, publicar no conda-forge.

Esta lição é a primeira de uma série de lições para ajudar você a começar com o empacotamento em Python.#

Para quem são estes tutoriais?#

O conteúdo desta série de tutoriais é adequado para iniciantes e parte do pressuposto de que você ainda não criou um pacote Python. No entanto, o conteúdo ainda será útil se você estiver interessado(a) em entender melhor as etapas envolvidas na criação de um pacote Python.

  • Nesta série, você aprenderá sobre os elementos essenciais de que precisa para publicar seu pacote no PyPI.

  • Na segunda série, você aprenderá sobre a infraestrutura e a documentação necessárias para dar suporte à manutenção do pacote.

Objetivos de Aprendizagem

Esta lição apresenta os componentes básicos de um pacote Python. Depois de ler esta lição, você será capaz de:

  • Entender o que é um pacote Python

  • Ser capaz de listar os 5 componentes centrais de um pacote Python

  • Ser capaz de explicar a diferença entre código generalizável e código que dá suporte a uma aplicação científica específica

O que é um pacote Python?#

Em um nível geral, você pode pensar em um pacote Python como uma caixa de ferramentas que pode ser usada para realizar diversas tarefas.

Um pacote Python é basicamente um diretório com uma estrutura de arquivos específica. Dentro da estrutura de diretórios do pacote, há objetos módulo, que são arquivos que terminam em .py (a mesma extensão que você vê em um script Python). Esses módulos permitem agrupar e organizar o seu código Python. Cada módulo contém funções e classes, que você pode imaginar como as ferramentas dentro da sua caixa de ferramentas.

Diagrama mostrando um esboço de uma caixa de ferramentas cheia de diferentes ferramentas, incluindo um martelo e um serrote.

Você pode pensar em um pacote como uma caixa de ferramentas cheia de ferramentas de código. Cada ferramenta pode ser uma função ou uma classe. Cada ferramenta faz bem uma coisa específica.#

Pacotes Python são instaláveis#

Um pacote é instalável, o que significa que você pode adicionar a funcionalidade do código do pacote a qualquer ambiente Python e importar essa funcionalidade como faria com pacotes científicos centrais do Python, como NumPy ou Matplotlib.

import numpy

Instalar um pacote em um ambiente facilita gerenciar e reutilizar seu código em projetos diferentes. Estruturar seu código como um pacote é o primeiro passo que você precisa dar para compartilhar as ferramentas da caixa de ferramentas que criou e permitir que outras pessoas construam com elas.

Por que criar um pacote Python?#

Você pode criar um pacote Python porque deseja:

  • Usar seu código em projetos diferentes: No nível mais básico, criar um pacote permite instalar seu código em um ambiente Python. Isso permite importar funções e classes em quaisquer workflows, tanto localmente quanto na nuvem.

  • Compartilhar seu código: Se você publicar um pacote em um repositório público como PyPI ou conda-forge, seu pacote pode ser instalado em qualquer máquina usando pip ou conda com um único comando.

  • Construir comunidade em torno do seu código: pacotes facilitam que várias pessoas trabalhem no mesmo projeto (especialmente quando publicado no GitHub). Um sistema de controle de versão como git (o sistema usado pelo GitHub) também facilita acompanhar mudanças na base de código ao longo do tempo. Ferramentas como issues e pull requests facilitam que usuários externos contribuam com correções de bugs e estabeleçam processos de revisão para aceitar mudanças na base de código.

  • Organizar seu código: pacotes podem ser usados para organizar grandes projetos de código, dividindo-os em componentes menores e mais gerenciáveis. Essa estrutura ajuda tanto na manutenção da base de código quanto na compreensão dela.

O que considerar antes de criar um pacote#

Criar um pacote Python que outras pessoas usem exige tempo e esforço consideráveis. Antes de começar, pense nos seus objetivos, incluindo:

  • Quem você acha que usará seu pacote

  • Como as pessoas podem usar seu pacote e com quais dados (se dados forem relevantes)

  • Se você tem tempo para adicionar coisas como documentação e testes

  • Por quanto tempo você poderá mantê-lo: lembre-se de que, quando as pessoas começarem a usar seu pacote, elas dependerão da sua equipe de mantenedores para atualizá-lo, corrigir bugs e responder perguntas.

Antes de criar um pacote voltado para usuários, é importante considerar tudo acima.

Os elementos de um pacote Python#

Diagrama mostrando .. mais aqui se isto permanecer.

Os elementos de um pacote Python incluem código, documentação, testes,uma license aprovada pela OSI e infraestrutura. Os mantenedores estão no centro, garantindo que tudo funcione e esteja atualizado, corrigindo bugs e atendendo preocupações dos usuários.#

Os elementos centrais de um pacote Python incluem:

  • Code: Funções e classes que fornecem funcionalidade para um usuário do seu pacote

  • Documentation: Instruções de instalação, tutoriais e exemplos que ajudam usuários a começar a usar seu pacote e contributors e mantenedores a corrigir bugs e manter o pacote.

    • Documentação para contributors na forma de um arquivo CONTRIBUTING.md é útil para ajudar pessoas a contribuir com seu pacote.

    • Documentação de desenvolvimento ajuda mantenedores e contribuidores a entender como manter a infraestrutura de um pacote.

  • Tests: que garantem que seu código funciona como deveria e facilitam que você e outras pessoas contribuam, modifiquem e atualizemo código no futuro

  • License: Uma open source license, ou license aprovada pela OSI, permite que outras pessoas usem seu pacote. Ela também fornece orientação legal sobre como os elementos do pacote podem ou não ser reutilizados.

  • Infrastructure que automatiza atualizações, workflows de publicação e executa suites de testes. A infraestrutura inclui um conjunto de coisas, como plataformas como GitHub e GitLab, ferramentas para executar testes e ferramentas locais como nox e tox, e integração contínua que automatiza etapas de manutenção do pacote.

O que a pyOpenSci busca em um pacote

A pyOpenSci realiza um conjunto inicial de verificações do editor para qualquer pacote enviado para revisão por pares. Você pode achar essas verificações úteis ao criar seu pacote como linha de base do que seu pacote deve ter.

Pacotes são mais do que apenas código - Infraestrutura#

Um pacote em qualquer linguagem é mais do que apenas código. Se você espera que outras pessoas usem seu pacote, além de você mesmo, considere não apenas escrever código de alta qualidade, mas também os diversos elementos de um pacote que o tornam um recurso útil para a comunidade.

Controle de versão e armazenamento do seu pacote no GitHub ou GitLab#

A maioria dos pacotes Python fica em uma plataforma online de controle de versão como GitHub ou GitLab. GitHub e GitLab executam git para controle de versão. Ter seu software sob controle de versão é importante porque permite acompanhar mudanças ao longo do tempo e também voltar no histórico e desfazer mudanças caso uma alteração na base de código quebre algo inesperadamente.

Ao publicar seu pacote no GitHub ou GitLab, você o torna público. Isso significa que outras pessoas podem ver seu código e também contribuir usando um pull request (GitHub) / merge request (GitLab) / workflow decode review.

GitHub e GitLab vs. Git

GitHub e GitLab são plataformas online (na nuvem) que executam git (software de controle de versão) no backend. Executar git localmente no seu computador permite enviar (git push) e baixar (git pull) arquivos para GitHub e GitLab.

Issues ou rastreadores de tickets#

GitHub e GitLab também oferecem recursos de comunidade, como issues, que permitem:

  • que você se comunique com sua equipe de mantenedores e a comunidade de contribuidores

  • que usuários reportem bugs, façam perguntas e solicitem novos recursos

  • que você acompanhe publicamente melhorias e recursos que deseja desenvolver para seu pacote.

Integração contínua e implantação contínua#

GitHub e GitLab também fornecem integração contínua e implantação contínua (CI/CD). Integração contínua (CI) refere-se a uma plataforma que executa automaticamente um job específico quando um determinado evento ocorre, enquanto implantação contínua (CD) é uma extensão da CI que se refere não apenas a executar ou fazer build, mas também a publicar os outputs finais em algum lugar.

Um exemplo de integração contínua:

  • Quando alguém envia uma mudança no seu código, seus testes serão executados em diferentes sistemas operacionais e o código será verificado quanto a problemas de formatação.

Um exemplo de implantação contínua:

  • Quando você estiver pronto para fazer release do seu pacote no PyPI, uma operação de implantação contínua pode ser acionada no release para publicar seu pacote no PyPI.

CI/CD integrado ajudará você a manter seu software, garantindo que mudanças no código não quebrem coisas inesperadamente. Também pode ajudar a manter consistência de estilo e formatação do código a cada nova mudança.

Diagrama mostrando .. mais aqui se isto permanecer.

O ciclo de vida de um pacote Python científico.#

Quando você deve transformar seu código em um pacote Python?#

Você pode estar se perguntando quais tipos de código devem se tornar um pacote Python que esteja tanto no GitHub quanto publicado no PyPI e/ou conda-forge.

Há alguns casos de uso a considerar:

  1. Criar um pacote básico para você mesmo: Às vezes você quer criar um pacote para uso pessoal. Isso pode significar tornar seu código instalável localmente com pip e também publicá-lo no GitHub. Nesse caso, você não espera que outras pessoas usem seu código e, portanto, pode ter documentação apenas para você e seu eu futuro, caso precise atualizar o pacote.

Um exemplo desse tipo de pacote pode ser um conjunto de funções que você escreveu e que são úteis em vários dos seus projetos. Pode ser útil ter essas funções disponíveis para todos os seus projetos.

  1. Criar um pacote para a comunidade: Em outros casos, você pode criar código que logo percebe ser útil não só para você, mas também para outras pessoas. Nesse caso, pode considerar criar o pacote, publicá-lo no GitHub e, como outros usuários podem usá-lo, aproveitar a infraestrutura do GitHub, incluindo pipelines de CI/CD e rastreadores de issues. Como você quer que outras pessoas usem seu pacote, também incluirá informações de LICENSE, documentação para usuários e contributors e testes. Esse tipo de pacote costuma ser publicado no PyPI.

Por exemplo, todos os pacotes da pyOpenSci são voltados para o público, com audiência além dos mantenedores.

Pacotes que você espera que outras pessoas usem devem ter escopo bem definido#

Idealmente, o código do seu pacote Python está focado em um tema ou caso de uso específico. Esse tema é importante, pois é uma forma de delimitar o conteúdo do seu pacote.

Pode ser difícil decidir quando seu código se torna algo que pode ser mais amplamente útil para outras pessoas. Mas uma pergunta que você pode fazer é: seu código foi escrito especificamente para um único projeto de pesquisa? Ou poderia ter aplicação mais ampla em vários projetos do seu domínio?

Como isso se relaciona com código de um projeto de pesquisa?

Um Research Compendiumé um conjunto organizado de código, dados e documentação que sustenta um projeto de pesquisa específico. Ele visa aumentar a reprodutibilidade e a transparência da pesquisa, fornecendo um registro abrangente dos métodos, dados e análises usados em um estudo.

Um pacote Python é uma coleção de modules que podem ser usados para executar um conjunto específico de tarefas. Essas tarefas devem ser aplicáveis a muitos workflows. Assim, um pacote Python é mais generalizável do que um Research Compendium, que sustenta um projeto específico.

Abaixo estão alguns exemplos de pacotes da pyOpenSci com escopo bem definido:

  • Crowsetta: é um pacote projetado para trabalhar com anotação de vocalizações animais e dados de bioacústica. Este pacote ajuda cientistas a processar diferentes tipos de dados bioacústicos, em vez de focar em uma aplicação de pesquisa específica associada a um workflow de pesquisa de um usuário.

  • Pandera é outro pacote Python de uso mais amplo. Pandera suporta testes de dados e, portanto, também tem aplicação de pesquisa mais ampla.

Matplotlib como exemplo

No extremo maior do espectro de usuários, Matplotlib é um ótimo exemplo. Matplotlib faz uma coisa muito bem:

Ele cria gráficos visuais de dados.

Milhares de pessoas usam Matplotlib para diferentes aplicações de plotagem com diferentes tipos de dados. Embora poucos pacotes científicos tenham a mesma aplicação ampla e base de usuários grande que Matplotlib, a ideia de delimitar o que seu pacote faz ainda é importante.

O código também deve ser limpo, legível e documentado#

O código do seu pacote também deve ser limpo, legível e bem documentado.

Clean code: Clean code refere-se a código que usa nomes de variáveis expressivos, é conciso e não se repete. Você pode aprender sobre boas práticas de clean code em tutoriais futuros da pyOpenSci.

Readable code: Readable code é código escrito com um estilo consistente. Você pode usar linters e formatadores de código como black e flake8 para garantir essa consistência em todo o pacote. Saiba mais sobre formatadores de código aqui.

Documented code: Documented code é escrito usando docstrings que ajudam o usuário a entender tanto o que as funções e methods do seu código fazem quanto quais são os elementos de input e output de cada função. Você pode saber mais sobre docstrings em nosso guia, aqui.

Tornar seu pacote instalável - publicação no PyPI e conda-forge#

Pacotes Python e ambientes#

Você pode instalar um pacote Python em um ambiente Python da mesma forma que instalaria NumPy ou Pandas. Instalar seu pacote em um ambiente permite acessá-lo a partir de qualquer código executado com aquele ambiente Python específico ativado.

Diagrama mostrando as etapas associadas à criação de um pacote e depois à sua instalação. A primeira seta diz seu pacote e a segunda diz pip install pacote. A segunda seta leva a uma caixa que representaum ambiente Python que já tem alguns pacotes instalados, como Pandas e NumPy. Seu pacote também será instalado nesse mesmo ambiente quando você fizer pip install.

Você não precisa publicar no PyPI para tornar seu código instalável. Com a estrutura de arquivos correta e metadata do projeto, você pode tornar seu código instalável localmente no seu computador e usá-lo em projetos em que está trabalhando sem precisar publicar no PyPI. Publicar no PyPI é útil quando você quer tornar seu código público e compartilhá-lo com outras pessoas.#

Publicar um pacote no PyPI / Conda-Forge#

Se você quer tornar seu pacote diretamente instalável sem precisar baixar o código para o seu computador localmente, precisa publicá-lo em um repositório como PyPI ou conda-forge.

Aprenda como publicar seu pacote no PyPI neste tutorial.

Depois você pode criar uma recipe do conda-forge usando a ferramenta Grayskull. Em seguida, envie essa recipe para o conda-forge.

Você aprenderá mais sobre o processo de publicação no conda-forge aqui.

Gráfico mostrando o workflow de alto nível de empacotamento. À esquerda você vê um gráfico com código, metadata e testes. Esses itens entram no seu pacote. Documentação e dados ficam abaixo dessa caixa porque normalmente não são publicados na wheel distribution do empacotamento. Uma seta à direita leva a uma caixa de arquivos de build distribution. Essa caixa leva à publicação no TestPyPI ou no PyPI real. A partir do PyPI, você pode conectar ao conda-forge para um build automatizado que envia distributions do PyPI para o conda-forge.

Na imagem acima, você pode ver as etapas associadas à publicação do seu pacote no PyPI e conda-forge. O PyPI suporta arquivos sdist e wheel. Quando estiver pronto para tornar seu código publicamente instalável, você pode publicá-lo no PyPI. Depois que seu código estiver no PyPI, é simples publicar no conda-forge. Você cria uma recipe usando o pacote Grayskull e depois abre um pr no repositório de recipes do conda-forge. Você aprenderá mais sobre esse processo na lição do conda-forge.#

Ótimo, seu pacote tem usuários! E agora?#

À medida que a comunidade que usa seu pacote cresce, você também pode se ver gerenciando usuários, contributors e outras pessoas que querem interagir com seu pacote. É importante considerar tudo isso antes de mergulhar no desenvolvimento. Quando você tiver uma base de usuários na comunidade, as pessoas dependerão do seu código funcionar e precisarão de orientação sobre como usá-lo.

Para apoiar sua comunidade, você vai querer adicionar coisas como:

Suporte para contributors e mantenedores

Se você pretende que outras pessoas usem e contribuam com seu código, considere quem o manterá ao longo do tempo. Você vai querer um guia de contribuição e desenvolvimento para ajudar novos contributors potenciais a começar a contribuir com seu pacote, além de um code of conduct para garantir que as interações da comunidade permaneçam saudáveis tanto para você quanto para seus contributors e equipe de mantenedores.

Os elementos acima também são importantes para a manutenção futura do seu pacote. Caso você não consiga mais mantê-lo ou simplesmente queira ajuda extra, a documentação de desenvolvimento e contribuição ajudará você a integrar novos maintainers.


Próximos passos#

Em lições futuras você aprenderá mais sobre a infraestrutura em torno de um pacote Python publicado que facilita a manutenção, a contribuição de outras pessoas e o uso por outros cientistas. No entanto, primeiro queremos levá-lo ao seu objetivo inicial de publicarum pacote Python.

Nessa próxima lição você aprenderá como criar um pacote Python básico instalável. Torne seu código pip instalável