O poder de uma boa documentação em Python

Acho difícil alguém discordar o quão delicioso é para um desenvolvedor quando uma ferramenta necessária é devidamente documentada. E é ainda mais difícil alguém discordar da importância da documentação no desenvolvimento de API's, bibliotecas ou frameworks. A documentação é uma parte crucial do processo de desenvolvimento de software; uma ferramenta mal documentada pode não atrair desenvolvedores entusiastas e isso pode impactar diretamente no sucesso do seu projeto. Agora que chegamos a um acordo, aposto que você está pensando: "Eu comento todo o meu código, então eu não preciso ler esse artigo sobre documentação". E é por isso que eu preciso explicar:
A diferença entre documentação e comentários
Uma documentação é a receita de bolo do seu projeto. Ela diz para o usuário como usar a sua ferramenta sem que seja necessário acessar e entender o seu código. Comentários, por outro lado, são notas para você e outros desenvolvedores que estarão olhando o código-fonte. Eles explicam o porquê de uma determinada lógica, um workaround específico, ou marcam TODOs.
A documentação é voltada para o usuário da sua biblioteca, API ou framework. Os comentários são para os mantenedores e contribuidores do código.
Documentando no Python
Agora que você já entendeu que documentar é uma parte importante do processo. E você que é menos experiente deve estar se perguntando, como fazer isso e o custo de uma boa documentação. Eu trago boas notícias, uma documentação pode ser gerada automaticamente, e neste artigo vou te mostrar como e até o final da leitura você será um expert.
Antes de qualquer coisa eu gostaria de explicar o porquê da minha escolha por Python, já que a maioria das linguagens possui ferramentas para gerar documentações. A resposta é bem simples, primeiro, é a linguagem que eu mais tenho domínio, e fica mais fácil para mim abordar esse tema considerado tão importante, segundo, é uma das melhores linguagens quando se trata de documentação.
Docstrings
O coração da documentação em Python são as docstrings. Podem ser encontradas na PEP-257 Docstring Conventions ou na documentação do Python em 4.8.7. Documentation Strings. Resumindo a documentação, uma docstring é uma string literal que precede a primeira declaração em um módulo, função, classe ou método, tornando-se o atributo especial __doc__ (ou como chamamos dunder __doc__) desse objeto.
Existem dois formatos de docstrings:
One-line vs Multi-line docstrings
O primeiro caso é usado para descrições mais óbvias e resumos e tudo deve estar na mesma linha, a abertura e fechamento de aspas triplas e o texto. Veja esse exemplo tirado da própria documentação:
def kos_root():
"""Return the pathname of the KOS root directory."""
global kos_root
# ...
O segundo caso deve-se quebrar uma linha após a abertura de aspas triplas e o texto pode ser mais elaborado tendo o fechamento das aspas triplas na próxima linha.
def complex(real=0.0, imag=0.0):
"""Form a complex number.
Keyword arguments:
real -- the real part (default 0.0)
imag -- the imaginary part (default 0.0)
"""
if real == 0.0 and imag == 0.0:
return complex_zero
# ...
Agora que você já entendeu como funciona, vamos ver como a mágica acontece.
Gerando documentação com Python
Eu vou criar um exemplo de uma biblioteca de código de um mensageiro fictício e vamos gerar a documentação desse exemplo com Sphinx. Mas antes vamos entender as:
Convenções de documentação e formatadores de docstrings
Não existem muitos critérios e nem regras para a escolha da convenção ou o formatador, fica por sua escolha mas é importante que você escolha um formato que seja compatível com a ferramenta que irá gerar o site da sua documentação. Segue uma lista com os principais formatadores e todos são compatíveis com Sphinx:
Eu deixei o link para você estudar essas convenções no futuro, mas por enquanto não precisa focar nisso, todas são muito parecidas, com algumas pequenas diferenças. Nesse exemplo usaremos o reStructured Text pois é o padrão do Sphinx e é muito parecido com Markdown.
Gerando uma documentação com Sphinx
Como mencionei anteriormente, vou criar um exemplo de uma biblioteca de código de um mensageiro fictício e vamos gerar a documentação desse exemplo com Sphinx. Mas antes de botar a mão na massa, vamos entender o que é o Sphinx e por que ele é tão popular na comunidade Python.
O que é o Sphinx?
Sphinx é uma ferramenta poderosa que transforma arquivos de texto simples em diversos formatos de saída, como HTML, PDF, ePub e mais. Ele foi originalmente criado para a documentação da linguagem Python e, desde então, tornou-se a escolha padrão para muitos projetos Python e até mesmo para projetos em outras linguagens. Sua principal força reside na capacidade de processar reStructuredText (e Markdown, com extensões), uma linguagem de marcação fácil de ler, e integrá-lo perfeitamente com o código Python para extrair docstrings automaticamente.
Por que escolher o Sphinx?
Automação: Ele pode extrair automaticamente a documentação das docstrings do seu código Python usando a extensão
autodoc. Isso significa que sua documentação e seu código permanecem sincronizados com mais facilidade.Formatos de saída múltiplos: Precisa de um site HTML? Um PDF para impressão? O Sphinx cuida disso.
Referências cruzadas extensivas: Crie links facilmente entre diferentes partes da sua documentação, módulos, classes e funções.
Temas e extensibilidade: Customize a aparência da sua documentação com temas (como o popular
sphinx_rtd_themeusado pelo Read the Docs) e adicione funcionalidades com uma vasta gama de extensões.Suporte a reStructuredText e Markdown: Embora o reStructuredText seja o padrão e ofereça mais funcionalidades, o Sphinx também pode lidar com Markdown através de extensões, oferecendo flexibilidade.
Ampla adoção: Muitos projetos grandes utilizam o Sphinx, o que significa uma comunidade grande, muitos recursos e tutoriais disponíveis.
Mãos à obra: configurando o Sphinx
Instalação:
Primeiro, você precisará instalar o Sphinx. Recomendo também instalar o
sphinx_rtd_themepara um visual moderno:pip install sphinx sphinx-rtd-themeIniciando o projeto de documentação:
Navegue até o diretório raiz do seu projeto Python e execute o assistente de configuração do Sphinx:
sphinx-quickstartEste comando fará uma série de perguntas para configurar seu projeto de documentação. Algumas das opções importantes:
Nome do projeto: O nome da sua biblioteca ou aplicação.
Nome do autor: Seu nome ou o nome da sua organização.
Versão do projeto: A versão atual do seu projeto.
Extensões: Aqui é crucial habilitar algumas extensões. Pressione 'y' para:
sphinx.ext.autodoc: Para incluir documentação de docstrings.sphinx.ext.napoleon: Se você planeja usar docstrings no estilo Google ou NumPy.sphinx.ext.viewcode: Para adicionar links para o código fonte.sphinx.ext.githubpages: Se você planeja hospedar no GitHub Pages.
Após responder a todas as perguntas, o sphinx-quickstart criará um diretório docs (ou o nome que você escolheu) com vários arquivos, incluindo:
conf.py: O arquivo de configuração principal do Sphinx. É aqui que você define o tema, ativa extensões, e mais importante, informa ao Sphinx onde encontrar seu código Python.index.rst: A página inicial da sua documentação.Makefile(oumake.batno Windows): Arquivos de utilidade para construir sua documentação.
Configurando o conf.py:
Abra o arquivo docs/conf.py e faça algumas edições essenciais:
Descomente e ajuste o
sys.path: Para que oautodocencontre seus módulos Python, você precisa adicionar o diretório do seu código aosys.path. Se sua estrutura de projeto for algo como:meu_projeto/ ├── docs/ │ └── conf.py └── src/ └── meu_mensageiro/ └── __init__.py └── core.pyVocê adicionaria:
import os import sys sys.path.insert(0, os.path.abspath('../src')) # Ajuste conforme sua estruturaDefina o tema HTML: Para usar o tema Read the Docs:
html_theme = 'sphinx_rtd_theme'Verifique as extensões: Garanta que
sphinx.ext.autodocestá na listaextensions.
Exemplo prático: Documentando nossa biblioteca de mensageiro fictício
Vamos supor que temos um módulo core.py dentro de src/meu_mensageiro/ com o seguinte conteúdo:
# src/meu_mensageiro/core.py
"""
Módulo principal do Mensageiro Fictício.
Este módulo contém as funcionalidades centrais para enviar e receber mensagens.
"""
MAX_MESSAGE_LENGTH = 1024
"""Constante que define o tamanho máximo de uma mensagem."""
class Message:
"""
Representa uma mensagem no sistema.
:param sender: O remetente da mensagem.
:type sender: str
:param content: O conteúdo da mensagem.
:type content: str
:raises ValueError: Se o conteúdo da mensagem exceder `MAX_MESSAGE_LENGTH`.
"""
def __init__(self, sender: str, content: str):
if len(content) > MAX_MESSAGE_LENGTH:
raise ValueError("Conteúdo da mensagem muito longo.")
self.sender = sender
self.content = content
self.is_sent = False
def send(self) -> bool:
"""
Envia a mensagem.
Simula o envio de uma mensagem. Em um cenário real, isso se conectaria
a um serviço de mensageria.
:return: True se a mensagem foi enviada com sucesso, False caso contrário.
:rtype: bool
"""
print(f"Mensagem de {self.sender} enviada: {self.content}")
self.is_sent = True
return True
def receive_message(user: str) -> Message | None:
"""
Simula o recebimento de uma nova mensagem para um usuário.
:param user: O nome do usuário para verificar mensagens.
:type user: str
:return: Um objeto :class:`Message` se houver uma nova mensagem, ou None caso contrário.
:rtype: Message or None
"""
# Em um sistema real, haveria uma lógica para buscar mensagens
if user == "ricardo":
return Message("servidor_central", "Bem-vindo ao Mensageiro Fictício!")
return None
Neste exemplo, usamos o formato reStructuredText para as docstrings, como discutido. Observe como descrevemos parâmetros (:param:), tipos (:type:), o que é retornado (:return:, :rtype:) e exceções (:raises:). Informações detalhadas sobre como escrever docstrings podem ser encontradas em tutoriais como o do DataCamp sobre docstrings em Python.
Criando arquivos .rst para o autodoc:
Agora, vamos dizer ao Sphinx para gerar documentação para o nosso módulo core. Crie um arquivo chamado meu_mensageiro.rst dentro do diretório docs/ com o seguinte conteúdo:
.. automodule:: meu_mensageiro.core :members: :undoc-members: :show-inheritance:.. automodule:: meu_mensageiro.core: Diz ao Sphinx para documentar o módulomeu_mensageiro.core.:members:: Inclui todos os membros públicos (funções, classes, variáveis) do módulo.:undoc-members:: Inclui membros que não têm docstrings (use com cautela, o ideal é documentar tudo).:show-inheritance:: Mostra as classes base para as classes documentadas.
Agora, adicione este novo arquivo ao seu toctree principal no arquivo docs/index.rst:
.. toctree::
:maxdepth: 2
:caption: Conteúdo:
meu_mensageiro
Gerando a documentação:
Volte para o diretório docs/ no seu terminal e execute:
make htmlSe tudo estiver configurado corretamente, o Sphinx processará seus arquivos
.rste as docstrings do seu código, gerando a documentação em HTML no diretóriodocs/_build/html/. Abra o arquivoindex.htmlnesse diretório para ver sua documentação em ação!Você verá uma página bem formatada com a descrição do seu módulo, a constante
MAX_MESSAGE_LENGTH, a classeMessagecom seus métodos, e a funçãoreceive_message, tudo extraído das docstrings que você escreveu.
Dicas para uma documentação de qualidade com Sphinx:
Seja consistente: Escolha um estilo de docstring (reStructuredText, Google, NumPy) e mantenha-o em todo o projeto. A consistência é fundamental para a legibilidade.
Documente a API pública: Foque em documentar a interface que outros desenvolvedores (ou você mesmo no futuro) usarão. Uma boa documentação de API é crucial.
Inclua exemplos de uso: Docstrings são um ótimo lugar para pequenos exemplos. Para exemplos mais complexos, considere criar seções separadas na sua documentação ou até mesmo um diretório
examples/.Mantenha atualizado: Documentação desatualizada é pior do que nenhuma documentação. Faça da atualização da documentação parte do seu processo de desenvolvimento.
Use referências cruzadas: Sphinx facilita a criação de links para outras partes da sua documentação usando roles como
:mod:,:func:,:class:. Isso torna a navegação muito mais fluida.Explore extensões: O ecossistema de extensões do Sphinx é vasto. Precisa de diagramas? Suporte a Jupyter Notebooks? Provavelmente existe uma extensão para isso.
A documentação é uma parte vital de qualquer projeto de software, grande ou pequeno. Mesmo que você esteja trabalhando em projetos mais simples, como explorar a criação de um site com Python puro, sem framework (usando CGI), entender como articular a funcionalidade do seu código é uma habilidade valiosa que se reflete na qualidade da sua documentação.
Conclusão
Dominar ferramentas como o Sphinx e adotar boas práticas de escrita de docstrings pode parecer um esforço extra inicialmente, mas os benefícios a longo prazo são imensos. Uma documentação clara, concisa e abrangente economiza tempo, reduz a frustração, facilita a colaboração e, em última análise, contribui significativamente para o sucesso e a adoção do seu projeto Python.
Lembre-se: um código bem documentado não é apenas um presente para os outros, é um presente para o seu eu futuro. Invista tempo em documentar seu trabalho, e você colherá os frutos.
Espero que este guia tenha convencido você do poder de uma boa documentação em Python e o tenha preparado para começar a documentar seus próprios projetos como um verdadeiro expert!



