paint-brush
Apresentando Huey: uma alternativa de aipo para Djangopor@udit001
468 leituras
468 leituras

Apresentando Huey: uma alternativa de aipo para Django

por Udit11m2024/06/14
Read on Terminal Reader

Muito longo; Para ler

Huey é uma alternativa leve e fácil de configurar à fila de tarefas assíncronas em segundo plano do Celery. Se você está procurando uma solução mais simples que reduza a complexidade e ao mesmo tempo forneça gerenciamento de tarefas confiável, Huey pode ser a escolha perfeita para o seu projeto. Descubra como Huey agiliza o processo sem comprometer a funcionalidade.
featured image - Apresentando Huey: uma alternativa de aipo para Django
Udit HackerNoon profile picture
0-item


Fundo

Então, hoje falarei sobre uma alternativa ao Celery chamada Huey , que vem com uma configuração muito mais fácil do que o Celery e é muito menor em tamanho comparado ao Celery.


A razão pela qual decidi experimentar o Huey é porque às vezes enfrentei alguns problemas com o Celery ao realizar algumas tarefas comuns porque a documentação não é muito boa.


Para quem não sabe o que é Celery ou nunca o usou antes, Huey é uma fila de tarefas assíncronas que permite executar tarefas agendadas ou de longa duração em segundo plano.

Pré-requisitos

Estaremos instalando os seguintes pacotes:

  • redis
  • Django
  • Huey
  • solicitações (opcional, necessária para a demonstração)

Repositório GitHub

O blog a seguir vem acompanhado de um repositório GitHub que você pode usar para testar o projeto de demonstração que iremos criar.


Clique aqui para ver o repositório.

Configuração do projeto

Crie o diretório do projeto

Abra o terminal e digite o seguinte para criar um diretório; você pode pular esta etapa e fazer isso no próprio File Explorer.

 mkdir huey_demo

Ambiente Virtual

  • Vamos criar primeiro um virtualenv para instalar as dependências do nosso projeto:

     python -m venv venv


  • Ative o virtualenv (Linux):

     source venv/bin/activate

Instalando Dependências

Digite o seguinte comando no terminal para instalar todas as dependências:

 pip install Django==4.0.4 redis==4.2.2 huey==2.4.3


No momento em que escrevo este artigo, essas foram as versões com as quais testei esta configuração. Fique de olho no repositório do Github para obter quaisquer atualizações da versão mais recente no futuro.

Crie o projeto

  • Crie o projeto Django digitando o seguinte comando no terminal:

     django-admin startproject django_huey_demo


  • Mude o diretório para o diretório do projeto Django:

     cd django_huey_demo


  • Crie o aplicativo em nosso projeto:

     python manage.py startapp demo


  • Inclua o aplicativo criado no projeto settings.py , faça as seguintes alterações:

     INSTALLED_APPS = [ # Existing Apps "demo.apps.DemoConfig", # <== Add this line ]


  • Defina o modo de depuração como False em settings.py :

     DEBUG=False

    Estamos definindo Debug como False para que possamos ver como Huey funciona em produção, falaremos mais sobre isso mais tarde.

Visão Geral do Projeto

Agora que terminamos de configurar nosso projeto, é um bom momento para falar sobre o que construiremos hoje.


Buscaremos a "Palavra do Dia" diariamente na API do Wordnik . Em seguida, armazenaremos a palavra, sua definição e um exemplo da palavra em uma frase em nosso banco de dados.


Configuraremos uma tarefa periódica usando Huey que irá buscar a Palavra do Dia e armazená-la.


Para armazenar a palavra estaremos criando um modelo Django da mesma.

Obtendo a chave da API Wordnik

Você pode seguir este guia para obter a chave API.

Codificando Nosso Projeto

Adicione Huey ao nosso projeto

Precisamos adicionar Huey aos aplicativos instalados em nosso projeto, então faça as seguintes alterações no arquivo settings.py :

 INSTALLED_APPS = [ # Existing apps 'huey.contrib.djhuey', # <== Add this line ]

Instalar Redis

Precisamos instalar o Redis for Huey para armazenar informações sobre tarefas na fila, como costumávamos fazer com o Celery. Você pode consultar o link a seguir para instalar o Redis com base em seu sistema operacional específico.


Se você se sentir confortável em usar o Docker, poderá usar o seguinte comando:

 docker run --name redis_huey -p 6379:6379 -d redis

Por padrão, Huey tentará se conectar ao servidor Redis em execução em localhost:6379 . Se não estiver presente, ocorrerá um erro.

Definição de modelo

  1. Adicione o seguinte código ao seu arquivo demo/models.py :

     from django.db import models class Word(models.Model): word = models.CharField(max_length=200) part_of_speech = models.CharField(max_length=100) definition = models.TextField() example = models.TextField() def __str__(self): return self.word


  2. Faça migrações:

     python manage.py makemigrations demo


  3. Aplicar migrações:

     python manage.py migrate demo

Definição de Tarefa

Crie um arquivo chamado tasks.py no diretório do aplicativo de demonstração. A razão pela qual nomeamos nosso arquivo tasks.py é para ajudar Huey a descobrir automaticamente as tarefas presentes em nossos aplicativos registrados. Se nomeássemos nosso arquivo com outro nome, teríamos que registrar manualmente nossa tarefa. Se quiser saber mais, você pode conferir a documentação do Huey aqui .


Antes de escrevermos a definição da tarefa, precisamos instalar requests de dependência adicionais. Instale-o digitando o seguinte em seu terminal:

 pip install requests==2.27.1


Agora vem o código:

 import requests from django.conf import settings from huey import crontab from huey.contrib.djhuey import db_periodic_task from demo.models import Word @db_periodic_task(crontab(hour="18", minute="00")) def fetch_daily_word(): r = requests.get( f"https://api.wordnik.com/v4/words.json/wordOfTheDay?api_key={settings.WORDNIK_API_KEY}") data = r.json() Word.objects.get_or_create( word=data["word"], part_of_speech=data["definitions"][0]["partOfSpeech"], definition=data["definitions"][0]["text"], example=data["examples"][0]["text"] )


Adicione a seguinte linha nas configurações do seu projeto:

 WORDNIK_API_KEY = "api-key-here"


Este bloco de código pode ser muito difícil de entender, então vamos examinar tudo nele um por um:


  1. Huey Decorador

     from huey.contrib.djhuey import db_periodic_task

    Este é um decorador fornecido pela Huey para registrar tarefas periódicas que envolvem o trabalho com o banco de dados, este decorador fecha automaticamente a conexão com o banco de dados após a conclusão da tarefa, para mais detalhes, você pode consultar aqui.


  2. Cronograma Crontab

     @db_periodic_task(crontab(hour="18", minute="00"))


    Estamos passando o argumento crontab(hour="18", minute="00") para nosso decorador de tarefas periódicas, isso diz a Huey para executar nossa tarefa às 18h todos os dias. Você pode usar este site para criar suas programações de crontab, eu sempre uso.


  3. Chave API do Wordnik

     from django.conf import settings # Usage ## settings.WORDNIK_API_KEY

    from django.conf import settings é a maneira padrão de importar quaisquer dados das configurações do nosso projeto, é útil nos casos em que temos vários arquivos de configurações configurados para ambientes diferentes para que ele saiba qual arquivo escolher sem que tenhamos que nos preocupar isto. Ele descobre qual arquivo de configurações estamos usando a partir da variável de ambiente DJANGO_SETTINGS_MODULE . Mas você não precisa se preocupar com esses detalhes.


    Em seguida, usamos a chave em nossa chamada de API do Wordnik.


  4. Chamada de API Wordnik

     r = requests.get( f"https://api.wordnik.com/v4/words.json/wordOfTheDay?api_key={settings.WORDNIK_API_KEY}")

    Aqui, estamos usando o módulo requests para fazer uma solicitação GET para a API Wordnik enquanto passamos nossa chave API para autenticação.


  5. Armazenando palavra no banco de dados

     data = r.json() Word.objects.get_or_create( word=data["word"], part_of_speech=data["definitions"][0]["partOfSpeech"], definition=data["definitions"][0]["text"], example=data["examples"][0]["text"] )

    Depois de analisar a resposta da API, armazenamos a definição da palavra em nosso banco de dados. Estamos usando o método get_or_create em vez do método create aqui para não criarmos múltiplas cópias da mesma palavra em nosso banco de dados se essa palavra for repetida pela API do Wordnik.


  6. Resposta da API Wordnik

    Esta é a aparência da resposta da API Wordnik para o endpoint Word of the Day. Algumas das seções irrelevantes da resposta foram truncadas por questões de brevidade.

     { "word": "stolon", "definitions": [ { "source": "ahd-5", "text": "A long thin stem that usually grows horizontally along the ground and produces roots and shoots at widely spaced nodes, as in a strawberry plant.", "note": null, "partOfSpeech": "noun" }, // More definitions here... ], "publishDate": "2022-05-08T03:00:00.000Z", "examples": [ { "title": "4.1 Nursery establishment", "text": "A stolon is a stem that grows along the ground, producing at its nodes new plants with roots and upright stems.", // Additional data here... }, // More examples here... ], // Additional fields here... }

Executando o Huey Worker

Você pode iniciar o trabalhador Huey digitando o seguinte comando em seu terminal:

 python manage.py run_huey


Você pode passar vários sinalizadores para o comando acima, o que alterará o que é registrado no console, como:

  • -v, --verbose - registro detalhado (inclui nível DEBUG)
  • -q, --quiet – registro mínimo
  • -S, --simple - formato de registro simples (“mensagem de tempo”)


Para ver várias outras opções de registro, confira a documentação aqui .

O que mais você pode fazer com Huey?

Decoradores de tarefas

Huey vem com vários decoradores de tarefas, dependendo de quais operações você está executando na tarefa.


Explicarei resumidamente o que todos eles fazem abaixo.


Aqui está a declaração de importação para todos os decoradores:

 from huey.contrib.djhuey import task, periodic_task, db_task, db_periodic_task
  • task : Uma tarefa regular.
  • periodic_task : quando você deseja executar uma tarefa periodicamente com base em um agendamento.
  • db_task : quando você deseja executar operações de banco de dados em sua tarefa.
  • db_periodic_task : quando você deseja executar operações de banco de dados em uma tarefa periódica.

Exemplos de Crontab

Deixe-me mostrar mais alguns exemplos de como você pode usar o crontab para agendar suas tarefas.

  • crontab(minute='*/3') agendaria a tarefa para ser executada a cada três minutos.
  • crontab(hour='*/3', minute='5') criaria uma tarefa que será executada 5 minutos após cada terceira hora.
  • crontab(minute='00', hour='10', month='*/2', day_of_week='*/5') criaria uma tarefa que seria executada a cada 5º dia da semana, de cada 2º mês às 10:00 DA MANHÃ.

Agendamento de tarefas

Por exemplo, você tem a seguinte tarefa definida em tasks.py :

 from huey.contrib.djhuey import task @task() def count(): for i in range(10): print(i)


Agora, se você deseja chamar esta tarefa, mas deseja que ela seja executada após 5 segundos, você pode fazer o seguinte:

 count.schedule(delay=5)

O parâmetro delay assume valores em segundos, portanto, se você deseja que ele seja executado após 5 minutos, especifique 300 segundos.

Tentando novamente tarefas que falharam

Suponha que você adicione a seguinte lógica à nossa tarefa existente:

 @db_periodic_task(crontab(hour="18", minute="00"), retries=2) def fetch_daily_word(): r = requests.get( f"https://api.wordnik.com/v4/words.json/wordOfTheDay?api_key={settings.WORDNIK_API_KEY}") if r.status_code != 200: raise Exception("Unable to fetch data from Wordnik API") ## Add this logic else: data = r.json() Word.objects.get_or_create( word=data["word"], part_of_speech=data["definitions"][0]["partOfSpeech"], definition=data["definitions"][0]["text"], example=data["examples"][0]["text"] )


Assim, adicionamos a lógica para verificar o código de status da resposta, e se for diferente de 200, ele tentará novamente a tarefa até 2 vezes. Mas essas novas tentativas aconteceriam sem qualquer intervalo de tempo entre as duas tentativas. Agora, e se você quiser atrasar várias tentativas desta tarefa? Podemos fazer isso passando o argumento retry_delay , ele aceita valores em segundos.


 @db_periodic_task(crontab(hour="18", minute="00"), retries=2, retry_delay=10)

Isso causará um atraso de 10 segundos entre várias tentativas.

Modo de Desenvolvimento

Huey vem com uma configuração padrão que facilita o trabalho com Huey durante o desenvolvimento no Django. Portanto, sempre que você tiver DEBUG=True presente em seu arquivo settings.py , as tarefas serão executadas de forma síncrona, como chamadas de função normais. O objetivo disso é evitar a execução do Redis e de um processo de consumidor adicional durante o desenvolvimento ou execução de testes. Você pode ler mais sobre isso aqui .


Para isso, precisamos adicionar a seguinte linha em settings.py :

 HUEY = {}


No entanto, se quiser substituir esse comportamento, você pode adicionar a seguinte configuração do Huey:

 HUEY = { "immediate": False }

Se você tiver a configuração acima mencionada em settings.py , embora tenha DEBUG=True , Huey exigirá que você configure o Redis e execute o Huey Worker usando o comando run_huey .

Aipo vs Huey

Algumas observações sobre o Huey em comparação com o Aipo são:

  • Menor pegada de dependências em comparação com o Celery. O aipo instala kombu e bilhar junto com ele. Enquanto isso, Huey não tem nenhuma dependência.


  • Serviços menores precisam ser executados para tarefas periódicas, o Celery requer a execução do serviço beat e um serviço de trabalho para trabalhar com tarefas periódicas, enquanto só precisamos executar um serviço usando o comando run_huey .

Referências

  1. Documentos Huey
  2. API do Wordnik
  3. Repositório Github associado