Dev Life

Verificando e-mails usando Python 3.9+ e a API do Mailgun

Aprenda a integrar a API de validação de e-mail em massa do Mailgun com Python. Este guia abrange a configuração, o uso seguro da API e a verificação eficiente de listas de e-mails.
Imagem para Verificando e-mails usando Python 3.9+ e a API do Mailgun

Quer você envie e-mails transacionais, newsletters ou conteúdo promocional, manter uma lista de e-mails limpa e verificada pode melhorar significativamente a entregabilidade, evitar que suas mensagens acabem em pastas de spam e proteger a reputação do seu domínio. Endereços de e-mail inválidos ou digitados incorretamente podem levar a taxas de devolução mais altas, resultando em penalidades de provedores de serviços de e-mail e redução do engajamento. Neste guia, você aprenderá como verificar seus e-mails com a API do Mailgun.

O que é a API de validação de e-mail em massa do Mailgun?

A API de validação de e-mail em massa do Mailgun foi desenvolvida para tornar a verificação de e-mails escalável e eficiente. Com ela, a equipe de desenvolvimento pode validar listas inteiras de endereços de e-mail, verificando problemas comuns como erros de sintaxe, e-mails descartáveis ou endereços com servidores de e-mail inativos. A API fornece resultados detalhados para cada e-mail, facilitando a tomada de ação adequada.

Neste tutorial, você aprenderá como integrar a API de validação de e-mail em massa do Mailgun aos seus aplicativos Python. Desde a configuração da sua conta do Mailgun e o manuseio seguro de credenciais até a programação que valida e-mails e processa os resultados, este guia fornece instruções passo a passo para verificar grandes listas de e-mails de forma eficiente.

Implementando a validação de e-mail em massa com Python e a API do Mailgun

Antes de começar a seguir este tutorial, certifique-se de ter o seguinte:

  • Um conhecimento básico de programação em Python
  • Python 3.9+
  • Um conta do Mailgun; uma conta paga é necessária para este tutorial
  • Experiência com desenvolvimento de aplicativos baseados no Django REST framework

Este tutorial usa o sistema operacional Windows. Embora todas as instruções também devam funcionar para Linux e macOS, certifique-se de alterar os delimitadores de caminho do sistema operacional ou as referências de sintaxe conforme necessário.

Configurando o Mailgun para validação de e-mail em massa

Para começar, faça login na sua conta do Mailgun e navegue até o painel. Role para baixo e selecione a opção “API keys”:

API keys option scrfeen

Clique em “Add new key” para adicionar uma nova chave de API:

Add new key to add a new API key screen

Digite uma descrição (como “Bulk Email Validation API Key”) e clique em “Create Key”:

Create Key screen

Assim que a chave de API for criada, copie as informações da chave, pois você precisará delas mais tarde. Se você esquecer de copiar as informações ou perder a chave, não se preocupe; você pode excluir sua chave de API e criar uma nova.

Configurando um diretório de projeto e dependências

Crie um diretório de projeto na sua máquina e mude para esse diretório. Em seguida, abra um terminal com um caminho definido para o diretório do projeto atual e execute o seguinte comando para criar um ambiente virtual Python para este tutorial:

python -m venv venv

Ative o ambiente virtual:

venvScriptsactivate

Em seguida, instale a biblioteca requests, que será usada para interagir com os endpoints do Mailgun:

pip install requests

Criando um projeto Python e um script de configuração

Após ativar seu ambiente virtual, crie um novo diretório dentro do diretório do projeto chamado standalone_python_scripts, onde você desenvolverá os módulos Python necessários para realizar a validação de e-mail em massa usando os endpoints do Mailgun.

Neste novo diretório, crie um novo arquivo Python chamado config.py e cole o seguinte código para configurar o aplicativo de script Python autônomo:

                                

                                    import osrnrn# Retrieve the API key from the environment variablernrnAPI_KEY = os.getenv("MAILGUN_API_KEY")rnrn# Mailgun API base URLrnrnMAILGUN_API_URL = "https://api.mailgun.net/v4/address/validate/bulk"rnrnLIST_NAME = "bulk_mailing_list_validation_1"rnrnFILE_PATH = "mailing_list.csv"rnrnCOMMAND = "submit_job" # Possible values are "submit_job" and "get_job_status"rn
                                
                            

Este módulo de configuração contém as variáveis de configuração necessárias para realizar a solicitação de validação de e-mail em massa.

Configure uma nova variável de ambiente, MAILGUN_API_KEY, na sua máquina host executando o seguinte comando:

SET MAILGUN_API_KEY=

Isso atribui a chave de API que você gerou anteriormente durante a configuração da conta do Mailgun.

Se você usa Linux ou Mac, execute o seguinte comando:

export MAILGUN_API_KEY=

Ao armazenar a chave de API em uma variável de ambiente em vez de codificá-la no arquivo de configuração, você mantém as informações confidenciais protegidas.

Deixe os valores das outras variáveis como estão por enquanto. A variável LIST_NAME contém o nome identificador da sua lista de e-mails a ser validada. FILE_PATH contém o caminho para o arquivo CSV de entrada que contém a lista de e-mails a serem validados.

Preparando o arquivo da sua lista de e-mails

Agora que o script de configuração se refere a um caminho de arquivo de lista de e-mails por meio da variável FILE_PATH, você precisa de uma lista de e-mails real com endereços de e-mail para validar. Crie um arquivo chamado mailing_list.csv no standalone_python_scripts directory e cole alguns exemplos de endereços de e-mail para começar:

email
dummy_email@dummydomain.com
test_email@testemaildomain.com
non_existent_email_id_123456789@gmail.com
hellojohnsemail123@gmail.com

Os endereços de e-mail usados aqui não são válidos. Você pode adicionar mais endereços válidos ou inválidos no mesmo formato com a sua própria lista desejada de endereços de e-mail.

Criando um job de validação em massa

Com a lista de e-mails pronta e a configuração para o processo de validação concluída, é hora de configurar uma função para criar um job de validação de e-mail em massa com o Mailgun.

No mesmo diretório, crie um arquivo de script Python chamado bulk_email_validation.py e defina uma função create_bulk_validation_job que aceita dois parâmetros, list_name (nome da lista de e-mails) e file_path (caminho para o arquivo que contém os e-mails):

                                

                                    def create_bulk_validation_job(list_name, file_path):rn    """rn    This function creates a bulk validation job using the Mailgun API.rnrn    :param list_name: The name of the mailing list for validation.rn    :param file_path: The path to the CSV file containing emails to validate.rn    :return: Response object containing the job details.rn    """rn    url = f"{MAILGUN_API_URL}/{list_name}"rnrn    try:rn        # Send a POST request with the file to Mailgun's APIrn        with open(file_path, "rb") as file_data:rn            response = requests.post(rn                url, auth=("api", API_KEY), files={"file": file_data}rn            )rnrn        # Check if the request was successfulrn        if response.status_code == 202:rn            logging.info(f"Bulk validation job created successfully for {list_name}")rn        else:rn            logging.error(rn                f"Error creating validation job: {response.status_code} {response.text}"rn            )rnrn        return response.json()rnrn    except Exception as e:rn        logging.error(f"An error occurred while creating bulk validation job: {str(e)}")rn        return Nonern
                                
                            

A função envia uma solicitação POST para a API do Mailgun para iniciar o processo de validação de e-mail em massa. A solicitação inclui o arquivo de endereços de e-mail que precisam ser validados.

Desenvolvendo funções para verificar o status do job e baixar os resultados

Agora, escreva outra função chamada get_bulk_validation_status no mesmo script bulk_email_validation.py que verifica o status do job de validação enviado. A resposta inclui um link para baixar os resultados da validação nos formatos CSV e JSON. Neste tutorial, você usará JSON para baixar e processar ainda mais os resultados.

Para baixar os resultados da validação, a função get_bulk_validation_status faz uma chamada para outra função chamada download_validation_results. O resultado baixado é colocado dentro do diretório validation_results no formato de um arquivo JSON. Vá em frente e crie este diretório dentro do diretório standalone_python_scripts, em seguida, cole o seguinte código que define essas duas funções em bulk_email_validation.py:

                                

                                    def get_bulk_validation_status(list_name):rn    """rn    This function checks the status of a bulk validation job and downloads the validation results.rnrn    :param list_name: The name of the mailing list for which the status is being checked.rn    :return: Validation results or None in case of failure.rn    """rn    url = f"{MAILGUN_API_URL}/{list_name}"rnrn    try:rn        # Send a GET request to Mailgun's API to fetch the job statusrn        response = requests.get(url, auth=("api", API_KEY))rnrn        # Check if the request was successfulrn        if response.status_code == 200:rn            logging.info(f"Successfully retrieved validation status for {list_name}")rnrn            # Parse the JSON responsern            result = response.json()rnrn            # Fetch the download URL for JSON resultsrn            download_url = result.get("download_url", {}).get("json")rn            if download_url:rn                # Fetch and return the validation resultsrn                return download_validation_results(download_url)rn            else:rn                logging.info("Download URL not available.")rn                return Nonernrn        else:rn            logging.error(rn                f"Error fetching job status: {response.status_code} {response.text}"rn            )rn            return Nonernrn    except Exception as e:rn        logging.error(rn            f"An error occurred while fetching bulk validation status: {str(e)}"rn        )rn        return Nonernrndef download_validation_results(download_url):rn    """rn    This function downloads and processes the bulk validation results from the provided URL.rnrn    :param download_url: The URL to download the validation results in JSON format.rn    :return: Parsed results or None in case of failure.rn    """rn    try:rn        response = requests.get(download_url)rnrn        # Check if the request was successfulrn        if response.status_code == 200:rn            logging.info("Successfully downloaded validation results.")rnrn            with zipfile.ZipFile(io.BytesIO(response.content)) as zip_ref:rn                validation_results_path = os.path.join(rn                    os.getcwd(), "validation_results"rn                )rn                zip_ref.extractall(path=validation_results_path)rnrn            with zipfile.ZipFile(io.BytesIO(response.content)) as zip_ref:rn                for file in zip_ref.namelist():rn                    if file.endswith(".json"):rn                        with zip_ref.open(file) as json_file:rn                            validation_results = json.load(json_file)rnrn            # Process the results (handle invalid emails, etc.)rn            process_validation_results(validation_results)rnrn            return validation_resultsrnrn        else:rn            logging.error(rn                f"Error downloading results: {response.status_code} {response.text}"rn            )rn            return Nonernrn    except Exception as e:rn        logging.error(rn            f"An error occurred while downloading validation results: {str(e)}"rn        )rn        return Nonern
                                
                            

A função envia uma solicitação POST para a API do Mailgun para iniciar o processo de validação de e-mail em massa. A solicitação inclui o arquivo de endereços de e-mail que precisam ser validados.

Desenvolvendo funções para verificar o status do job e baixar os resultados

Agora, escreva outra função chamada get_bulk_validation_status no mesmo script bulk_email_validation.py que verifica o status do job de validação enviado. A resposta inclui um link para baixar os resultados da validação nos formatos CSV e JSON. Neste tutorial, você usará JSON para baixar e processar ainda mais os resultados.

Para baixar os resultados da validação, a função get_bulk_validation_status faz uma chamada para outra função chamada download_validation_results. O resultado baixado é colocado dentro do diretório validation_results no formato de um arquivo JSON. Vá em frente e crie este diretório dentro do diretório standalone_python_scripts, em seguida, cole o seguinte código que define essas duas funções em bulk_email_validation.py:

                                

                                    def get_bulk_validation_status(list_name):rn    """rn    This function checks the status of a bulk validation job and downloads the validation results.rnrn    :param list_name: The name of the mailing list for which the status is being checked.rn    :return: Validation results or None in case of failure.rn    """rn    url = f"{MAILGUN_API_URL}/{list_name}"rnrn    try:rn        # Send a GET request to Mailgun's API to fetch the job statusrn        response = requests.get(url, auth=("api", API_KEY))rnrn        # Check if the request was successfulrn        if response.status_code == 200:rn            logging.info(f"Successfully retrieved validation status for {list_name}")rnrn            # Parse the JSON responsern            result = response.json()rnrn            # Fetch the download URL for JSON resultsrn            download_url = result.get("download_url", {}).get("json")rn            if download_url:rn                # Fetch and return the validation resultsrn                return download_validation_results(download_url)rn            else:rn                logging.info("Download URL not available.")rn                return Nonernrn        else:rn            logging.error(rn                f"Error fetching job status: {response.status_code} {response.text}"rn            )rn            return Nonernrn    except Exception as e:rn        logging.error(rn            f"An error occurred while fetching bulk validation status: {str(e)}"rn        )rn        return Nonernrndef download_validation_results(download_url):rn    """rn    This function downloads and processes the bulk validation results from the provided URL.rnrn    :param download_url: The URL to download the validation results in JSON format.rn    :return: Parsed results or None in case of failure.rn    """rn    try:rn        response = requests.get(download_url)rnrn        # Check if the request was successfulrn        if response.status_code == 200:rn            logging.info("Successfully downloaded validation results.")rnrn            with zipfile.ZipFile(io.BytesIO(response.content)) as zip_ref:rn                validation_results_path = os.path.join(rn                    os.getcwd(), "validation_results"rn                )rn                zip_ref.extractall(path=validation_results_path)rnrn            with zipfile.ZipFile(io.BytesIO(response.content)) as zip_ref:rn                for file in zip_ref.namelist():rn                    if file.endswith(".json"):rn                        with zip_ref.open(file) as json_file:rn                            validation_results = json.load(json_file)rnrn            # Process the results (handle invalid emails, etc.)rn            process_validation_results(validation_results)rnrn            return validation_resultsrnrn        else:rn            logging.error(rn                f"Error downloading results: {response.status_code} {response.text}"rn            )rn            return Nonernrn    except Exception as e:rn        logging.error(rn            f"An error occurred while downloading validation results: {str(e)}"rn        )rn        return Nonern
                                
                            

Analisando e lidando com resultados de validação

Assim que tiver baixado e obtido acesso aos resultados da validação, você precisará analisá-los e processá-los. Esta etapa é crucial para identificar e-mails entregáveis e não entregáveis.

Cole o seguinte código para definir a função em bulk_email_validation.py que realiza esta tarefa descrita:

                                

                                    def process_validation_results(results):rn    """rn    This function processes the validation results and handles invalid and risky emails.rnrn    :param results: The JSON object containing the validation results.rn    """rn    try:rn        count_of_deliverable_addresses: int = 0rn        emails_tobe_verified = set()rnrn        # Extract the results summaryrn        logging.info(f"Total email addresses validated: {len(results)}")rnrn        for result in results:rn            # Access data within each dictionaryrn            deliverable = (rn                result["result"] == "deliverable"rn            )  # Check if result is deliverablern            undeliverable = result["result"] != "deliverable"rn            risk = result["risk"]rnrn            # Count the number of deliverable addressesrn            if deliverable:rn                count_of_deliverable_addresses += 1rnrn            # Count the number of undeliverable addresses and add them to the list for verificationrn            if undeliverable:rn                emails_tobe_verified.add(result["address"])rnrn            # Count the number of risky addresses and add them to the list for verificationrn            if risk != "low":rn                emails_tobe_verified.add(result["address"])rnrn        # Log the results summaryrn        logging.info(f"Found {count_of_deliverable_addresses} deliverable emails")rnrn        if len(emails_tobe_verified) > 0:rn            logging.warning(rn                "Found some emails that need to be verified because of its risky or undeliverable state."rn            )rn            logging.warning(rn                "Total emails to be verified: {}".format(len(emails_tobe_verified))rn            )rn            logging.warning(f"Emails to be verified: {', '.join(emails_tobe_verified)}")rnrn    except Exception as e:rn        logging.error(rn            f"An error occurred while processing validation results: {str(e)}"rn        )rn
                                
                            

Agora, defina as instruções para chamar essas funções com o seguinte código:

                                

                                    if __name__ == "__main__":rnrn    if COMMAND == "submit_job":rn        create_bulk_validation_job(LIST_NAME, FILE_PATH)rn    elif COMMAND == "get_job_status":rn        get_bulk_validation_status(LIST_NAME)rn    else:rn        logging.error("Invalid command. Please use 'submit_job' or 'get_job_status'.")rn
                                
                            

O script final

No geral, todo o script bulk_email_validation.py faz o trabalho pesado de postar uma solicitação de validação de e-mail em massa, consultar o status da solicitação de job de validação enviada e processar os resultados. Depois de concluir todas as alterações, seu script bulk_email_validation.py deve ser parecido com esta.

Em todo o script, o uso de blocos try…except garante que quaisquer erros durante as chamadas da API sejam tratados. Isso é especialmente importante para ambientes de produção onde podem surgir problemas inesperados, como quando seu aplicativo não consegue acessar os endpoints do serviço do Mailgun ou quando você tenta enviar uma solicitação de job de validação com o mesmo nome de lista. As mensagens de erro e os comentários no código-fonte ajudam a explicar os vários outros cenários que são tratados.

Se você estiver reenviando a solicitação de job de validação com o mesmo nome de lista (você aprenderá a executar o script nas seções seguintes), o script também está equipado para lidar com tais cenários, lançando a mensagem de erro correspondente com uma descrição:

2024-09-28 07:34:39,081 - ERROR - create_bulk_validation_job - Error creating validation job: 409 {"message":"List already exists."}

Se você encontrar um erro de rede entre seu aplicativo e o serviço do Mailgun, poderá implementar um mecanismo de repetição. Você pode criar o seu próprio ou usar uma biblioteca como o tenacity para definir quantas vezes repetir a solicitação se ela falhar devido a problemas temporários de conectividade. Você também pode implementar outros cenários de tratamento de erros conforme as demandas do seu projeto ou negócio.

Neste ponto, você terminou de configurar o projeto e é hora de executá-lo.

Testando ao enviar uma solicitação de job de validação de e-mail em massa

Para executar o script a fim de enviar a solicitação de job de validação em massa, abra um terminal e mude para o diretório standalone_python_scripts. Execute o seguinte comando:

python bulk_email_validation.py

Você deve ver uma saída indicando que a solicitação de job foi enviada com sucesso para o serviço do Mailgun:

2024-09-28 19:47:34,012 - INFO - create_bulk_validation_job - Bulk validation job created successfully for bulk_mailing_list_validation_1

Testando ao buscar o status do job de validação de e-mail em massa

Às vezes, dependendo do volume de endereços de e-mail a serem validados, o job enviado levará tempos variados para ser concluído. Para obter o status da solicitação de job e processar os resultados se a solicitação estiver concluída, edite o código config.py para atualizar a configuração COMMAND para o valor get_job_status. Depois de concluído, execute o seguinte comando para realizar esta tarefa:

python bulk_email_validation.py

Você deve ver uma saída indicando que o job de validação foi concluído, os resultados foram baixados e, em seguida, processados:

2024-09-28 19:48:07,723 - INFO - get_bulk_validation_status - Successfully retrieved validation status for bulk_mailing_list_validation_1

2024-09-28 19:48:08,375 - INFO - download_validation_results - Successfully downloaded validation results.

2024-09-28 19:48:08,378 - INFO - process_validation_results - Total email addresses validated: 191

2024-09-28 19:48:08,378 - INFO - process_validation_results - Found 178 deliverable emails

2024-09-28 19:48:08,378 - WARNING - process_validation_results - Found some emails that need to be verified because of its risky or undeliverable state.

2024-09-28 19:48:08,378 - WARNING - process_validation_results - Total emails to be verified: 13

2024-09-28 19:48:08,378 - WARNING - process_validation_results - Emails to be verified:

dummy_email@dummydomain1.com, dummy_email@dummydomain2.com, hellojohnsemail123@gmail.com, dummy_email@dummydomain3.com, non_existent_email_id_123456789@gmail.com, dummy_email@dummydomain.com, dummy_email@dummydomain4.com, dummy_email@dummydomain5.com, dummy_email@dummydomain6.com, dummy_email@dummydomain7.com, dummy_email@dummydomain8.com, test_email@testemaildomain.com, electronix84@gmail.com

Esta saída indica que, dos 191 endereços de e-mail enviados para validação, 178 são categorizados como entregáveis, e os 13 restantes não.

O script identifica os endereços de e-mail a serem verificados analisando a resposta das APIs do Mailgun e exibindo a lista na saída. Agora cabe a você decidir qual curso de ação tomar com base nas necessidades do seu projeto ou negócio.

Integrando a validação de e-mail em massa em um aplicativo Django

Agora que você aprendeu essas técnicas, pode optar por aplicá-las em seu aplicativo Django criando endpoints para fazer o upload de uma lista de e-mails com endereços de e-mail em massa e validá-los.

Você pode consultar ou clonar este repositório do GitHub se quiser experimentar e acompanhar. O diretório bulk_email_validation contém o código-fonte do projeto Django. A seguir estão os principais arquivos envolvidos neste projeto:

  • A arquivo requirements.txt contém as dependências necessárias para este projeto Django.
  • A arquivo config.py contém as configurações relacionadas ao serviço do Mailgun.
  • A arquivo views.py contém a lógica para processar as solicitações e respostas relacionadas aos endpoints de validação de e-mail em massa.
  • A arquivo serializers.py contém classes que ajudam a traduzir dados entre objetos Python e formatos como JSON, facilitando o envio ou recebimento de dados para APIs de validação de e-mail em massa com apenas algumas linhas de código.
  • A arquivo urls.py contém os dois endpoints relacionados à validação de e-mail em massa. Um endpoint serve para enviar a solicitação do job de validação de e-mail em massa; o outro é para obter o status e processar os resultados.

As capturas de tela abaixo têm como objetivo ajudar você a entender os endpoints com os quais este aplicativo Django lida e as saídas que ele pode gerar.

A primeira captura de tela indica a solicitação POST com opções para fazer o upload do arquivo de lista de e-mails e definir um nome para a lista de e-mails, juntamente com a resposta recebida após o envio bem-sucedido da solicitação do job de validação de e-mail em massa:

validation job response after its completion:

A segunda captura de tela indica a recuperação bem-sucedida da resposta do job de validação após sua conclusão:

POST request  Screen

Você pode ter um aplicativo de frontend desenvolvido com qualquer tecnologia de frontend de sua preferência e chamar esses endpoints do aplicativo Django para atingir seu objetivo de validação de e-mail em massa.

Conclusão

Este tutorial ensinou como integrar a API de validação de e-mail em massa do Mailgun aos seus aplicativos Python para garantir a precisão e a entregabilidade das suas listas de e-mails. Desde a configuração da sua conta do Mailgun, a obtenção da chave de API e o manuseio seguro, até a implementação da validação em massa, o envio de solicitações POST e GET, além do processamento dos resultados, agora você sabe como automatizar o processo de verificação de e-mail. Você também explorou como gerenciar e-mails inválidos, lidar com erros comuns e integrar a validação de e-mail em aplicativos da web maiores como o Django. Todo o código-fonte apresentado para este tutorial está disponível em este repositório do GitHub.

Seguindo estas etapas, você pode identificar efetivamente os e-mails entregáveis da sua grande lista de e-mails, melhorando assim a qualidade das suas campanhas de e-mail, reduzindo as taxas de devolução e protegendo a reputação do remetente. O uso da poderosa API de validação de e-mail em massa do Mailgun não apenas simplifica esse processo, mas também garante que sua entrega de e-mail seja mais confiável e eficiente. À medida que você continua a otimizar sua estratégia de e-mail, confira Mailgun, explore as suas diversas ofertas de produtos e utilize-as para melhorar ainda mais suas campanhas de e-mail e maximizar o impacto delas.