Ir para o conteúdo

Boas práticas no desenvolvimento de automações em Python

Agora que discutimos a legibilidade e manutenibilidade de código, o guia de estilo de código, o uso efetivo de comentários e documentação, a tipagem (typing), a validação de dados de entrada e a importância dos testes automatizados, podemos aplicar esses conceitos a um contexto prático muito comum com Python RPA que é a modularização e criação de pacotes escaláveis.

Modularização e Criação de Pacotes

A modularização é muito importante em projetos de automação, onde diversas ações, como interação com APIs, leitura de bancos de dados ou envio de e-mails, podem ser reutilizadas na mesma ou em diferentes automações.

Vantagens da Modularização em automações com Python

A modularização do código permite dividir a lógica de automação em módulos reutilizáveis. Isso traz diversas vantagens:

  • Reusabilidade: Módulos podem ser reutilizados em diferentes processos ou projetos sem necessidade de reescrever o código.
  • Manutenibilidade: Alterações em um módulo não afetam diretamente outros módulos, facilitando a atualização e correção de erros.
  • Escalabilidade: À medida que o número de processos aumenta, a modularização permite que você adicione novos módulos sem complicações.
  • Facilidade de Testes: Testar módulos individualmente facilita a identificação e resolução de problemas.

Como Modularizar um projeto Python?

1 - Identificar Componentes Reutilizáveis

Primeiro, divida o fluxo do seu processo de automação em partes funcionais que podem ser modularizadas. Abaixo alguns exemplos comuns de componentes que podem ser modularizados:

  • Conexões com sistemas: Como interação com bancos de dados, APIs e ERP.
  • Ações repetitivas: Como logins, navegação em aplicativos e interações com interfaces de usuário.
  • Processamento de dados: Leitura, transformação e armazenamento de dados.
  • Geração de relatórios e notificações: Geração de logs, e-mails e alertas.

2 - Criar Módulos Reutilizáveis

Agora que você identificou os componentes reutilizáveis, crie módulos Python que encapsulam essas funcionalidades. Aqui estão alguns exemplos:

Módulo de Conexão com Banco de Dados:

# first_py/db_functions.py

import psycopg2
from typing import Optional

def conectar_db(host: str, usuario: str, senha: str, banco: str) -> Optional[psycopg2.extensions.connection]:
    """
    Função para conectar a um banco de dados PostgreSQL.

    Args:
        host (str): Endereço do servidor do banco de dados.
        usuario (str): Nome de usuário do banco de dados.
        senha (str): Senha do banco de dados.
        banco (str): Nome do banco de dados.

    Returns:
        Optional[psycopg2.extensions.connection]: Conexão com o banco de dados ou None em caso de erro.
    """    
    try:
        conexao = psycopg2.connect(host=host, user=usuario, password=senha, database=banco)
        return conexao
    except Exception as e:
        print(f"Erro ao conectar ao banco de dados: {e}")
        return None

Módulo de leitura CSV:

# first_py/csv_functions.py

import csv
import os

def ler_csv(arquivo: str) -> list:
    """
    Função para ler um arquivo CSV e retornar o conteúdo como uma lista de dicionários.

    Args:
        arquivo (str): Caminho do arquivo CSV.

    Returns:
        list: Lista de dicionários com o conteúdo do CSV.
    """
    dados = []

    if not os.path.exists(arquivo):
        raise FileNotFoundError(f"O arquivo {arquivo} não foi encontrado.")
    with open(arquivo, mode='r', newline='', encoding='utf-8') as file:
        leitor = csv.DictReader(file)
        for linha in leitor:
            dados.append(linha)

    return dados

Módulo que procura e lê e-mails:

# first_py/email_functions.py

from botcity.plugins.email import BotEmailPlugin

def ler_email(usuario: str, senha: str, assunto: str) -> list:
    """
    Função para ler e-mails de uma conta do Gmail com base em um assunto.
    Args:
        usuario (str): Endereço de e-mail do usuário.
        senha (str): Senha do e-mail do usuário.
        assunto (str): Assunto a ser procurado.
    Returns:
        list: Lista de e-mails encontrados.
    """

    email = BotEmailPlugin.config_email(MailServers.GMAIL, usuario, senha)

    messages = email.search(f'SUBJECT "{assunto}"')

    emails_info = []

    for msg in messages:
        email_data = {
            "Date": msg.date_str,
            "From": msg.from_,
            "Message": msg.text
        }
        emails_info.append(email_data)

    return emails_info

Importante

No exemplo estamos lidando com módulos de funções seguindo a programação funcional que foca em funções independentes que executam tarefas específicas. Mas, para projetos mais complexos a utilização de POO pode ser utilizada também, abaixo alguns motivos para seguir com a programação orientada a objetos:

  • Quando a automação envolve entidades complexas, como robôs, usuários, tarefas ou sistemas.

  • Quando a automação envolve interações complexas com múltiplas APIs, fluxos de trabalho e estados.

  • Quando você precisa de herança (por exemplo, diferentes tipos de robôs com comportamentos distintos, mas compartilhando algumas funcionalidades).

Veja a etapa de empacotamento detalhada no Lab seguinte.