paint-brush
Presentamos Huey: una alternativa de apio para Djangopor@udit001
468 lecturas
468 lecturas

Presentamos Huey: una alternativa de apio para Django

por Udit11m2024/06/14
Read on Terminal Reader

Demasiado Largo; Para Leer

Huey es una alternativa ligera y fácil de configurar a la cola de tareas asíncronas en segundo plano de Celery. Si está buscando una solución más simple que reduzca la complejidad y al mismo tiempo ofrezca una gestión de tareas confiable, Huey podría ser la opción perfecta para su proyecto. Descubra cómo Huey agiliza el proceso sin comprometer la funcionalidad.
featured image - Presentamos Huey: una alternativa de apio para Django
Udit HackerNoon profile picture
0-item


Fondo

Así que hoy hablaré de una alternativa de Celery llamada Huey , que viene con una configuración mucho más fácil que Celery y es mucho más pequeña en comparación con Celery.


La razón por la que decidí probar Huey es porque a veces he tenido algunos problemas con Celery al realizar algunas tareas comunes porque la documentación no es muy buena.


Para aquellos que no saben qué es Celery o no lo han usado antes, Huey es una cola de tareas asíncrona que permite realizar tareas programadas o de larga duración en segundo plano.

Requisitos previos

Instalaremos los siguientes paquetes:

  • Redistribuir
  • Django
  • huey
  • solicitudes (opcional, necesario para la demostración)

Repositorio de GitHub

El siguiente blog viene acompañado de un repositorio de GitHub que puede utilizar para probar el proyecto de demostración que crearemos.


Haga clic aquí para ver el repositorio.

Configuración del proyecto

Crear el directorio del proyecto

Abra la terminal y escriba lo siguiente para crear un directorio; Puedes omitir este paso y hacerlo desde el propio Explorador de archivos.

 mkdir huey_demo

Ambiente virtual

  • Primero creemos un virtualenv para instalar las dependencias de nuestro proyecto:

     python -m venv venv


  • Active el virtualenv (Linux):

     source venv/bin/activate

Instalación de dependencias

Escriba el siguiente comando en la terminal para instalar todas las dependencias:

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


Al momento de escribir este artículo, estas eran las versiones con las que probé esta configuración; esté atento al repositorio de Github para conocer cualquier actualización de la última versión en el futuro.

Crear el proyecto

  • Cree el proyecto Django escribiendo el siguiente comando en la terminal:

     django-admin startproject django_huey_demo


  • Cambie el directorio al directorio del proyecto Django:

     cd django_huey_demo


  • Crea la aplicación bajo nuestro proyecto:

     python manage.py startapp demo


  • Incluya la aplicación creada en el proyecto settings.py , realice los siguientes cambios:

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


  • Establezca el modo de depuración en False en settings.py :

     DEBUG=False

    Estamos configurando Debug en False para que podamos ver cómo se ejecuta Huey en producción; hablaremos más sobre esto más adelante.

Descripción del proyecto

Ahora que hemos terminado de configurar nuestro proyecto, es un buen momento para explicarle lo que construiremos hoy.


Obtendremos la "Palabra del día" diariamente desde la API de Wordnik . Luego almacenaremos la palabra, su definición y un ejemplo de la palabra en una oración en nuestra base de datos.


Configuraremos una tarea periódica usando Huey que buscará la Palabra del día y la almacenará.


Para almacenar la palabra crearemos un modelo Django de la misma.

Obtener la clave API de Wordnik

Puede seguir esta guía para obtener la clave API.

Codificando nuestro proyecto

Agrega Huey a nuestro proyecto

Necesitamos agregar Huey a las aplicaciones instaladas de nuestro proyecto, así que realice los siguientes cambios en el archivo settings.py :

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

Instalar Redis

Necesitamos instalar Redis para Huey para almacenar información sobre las tareas en cola como solíamos hacer con Celery también. Puede consultar el siguiente enlace para instalar Redis según su sistema operativo específico.


Si se siente cómodo usando Docker, puede usar el siguiente comando:

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

De forma predeterminada, Huey intentará conectarse al servidor Redis que se ejecuta en localhost:6379 . Si no está presente, generará un error.

Definición del modelo

  1. Agregue el siguiente código a su archivo 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. Realizar migraciones:

     python manage.py makemigrations demo


  3. Aplicar migraciones:

     python manage.py migrate demo

Definición de tarea

Cree un archivo llamado tasks.py en el directorio de la aplicación de demostración. La razón por la que nombramos nuestro archivo tasks.py es para ayudar a Huey a descubrir automáticamente las tareas presentes en nuestras aplicaciones registradas; si le pusiéramos a nuestro archivo un nombre distinto a ese, tendríamos que registrar nuestra tarea manualmente. Si desea saber más, puede consultar la documentación de Huey aquí .


Antes de escribir la definición de la tarea, necesitamos instalar requests de dependencia adicionales. Instálalo escribiendo lo siguiente en tu terminal:

 pip install requests==2.27.1


Ahora viene el 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"] )


Agregue la siguiente línea en la configuración de su proyecto:

 WORDNIK_API_KEY = "api-key-here"


Este bloque de código puede ser mucho para asimilar, así que repasemos los elementos que contiene uno por uno:


  1. Decorador Huey

     from huey.contrib.djhuey import db_periodic_task

    Este es un decorador proporcionado por Huey para registrar tareas periódicas que implican trabajar con la base de datos. Este decorador cierra automáticamente la conexión de la base de datos al finalizar la tarea. Para obtener más detalles, puede consultar aquí.


  2. Programación de crontab

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


    Estamos pasando el argumento crontab(hour="18", minute="00") a nuestro decorador de tareas periódicas, esto le dice a Huey que ejecute nuestra tarea a las 6 p.m. todos los días. Puede utilizar este sitio web para crear sus programaciones crontab, yo lo uso siempre.


  3. Clave API de Wordnik

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

    from django.conf import settings es la forma estándar de importar cualquier dato desde la configuración de nuestro proyecto, es útil en casos donde tenemos múltiples archivos de configuración configurados para diferentes entornos para que sepa qué archivo elegir sin que tengamos que preocuparnos. él. Descubre qué archivo de configuración estamos usando desde la variable de entorno DJANGO_SETTINGS_MODULE . Pero no tienes que preocuparte por estos detalles.


    Luego usamos la clave en nuestra llamada a la API de Wordnik.


  4. Llamada API de Wordnik

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

    Aquí, utilizamos el módulo de solicitudes para realizar una solicitud GET a la API de Wordnik mientras pasamos nuestra clave API para la autenticación.


  5. Almacenamiento de palabras en la base de datos.

     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"] )

    Después de analizar la respuesta de la API, almacenamos la definición de la palabra en nuestra base de datos. Estamos utilizando el método get_or_create en lugar del método create aquí para no crear múltiples copias de la misma palabra en nuestra base de datos si la API de Wordnik alguna vez repite esa palabra.


  6. Respuesta de la API de Wordnik

    Así es como se ve la respuesta de la API de Wordnik para el punto final de la Palabra del día. Algunas de las secciones irrelevantes de la respuesta se han truncado por motivos de brevedad.

     { "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... }

Ejecutando Huey Trabajador

Puede iniciar el trabajador Huey escribiendo el siguiente comando en su terminal:

 python manage.py run_huey


Puede pasar varios indicadores al comando anterior que cambiará lo que se registra en la consola, como por ejemplo:

  • -v, --verbose : registro detallado (incluye nivel DEBUG)
  • -q, --quiet - registro mínimo
  • -S, --simple - formato de registro simple (“mensaje de hora”)


Para ver otras opciones de inicio de sesión, consulte los documentos aquí .

¿Qué más puedes hacer con Huey?

Decoradores de tareas

Huey viene con múltiples decoradores de tareas dependiendo de las operaciones que esté realizando dentro de la tarea.


Explicaré brevemente qué hacen todos ellos a continuación.


Aquí está la declaración de importación para todos los decoradores:

 from huey.contrib.djhuey import task, periodic_task, db_task, db_periodic_task
  • task : Una tarea regular.
  • periodic_task : cuando desea ejecutar una tarea periódicamente según un cronograma.
  • db_task : cuando desea realizar operaciones de base de datos dentro de su tarea.
  • db_periodic_task : cuando desea realizar operaciones de base de datos en una tarea periódica.

Ejemplos de crontab

Déjame mostrarte algunos ejemplos más de cómo puedes usar crontab para programar tus tareas.

  • crontab(minute='*/3') programaría la tarea para que se ejecute cada tres minutos.
  • crontab(hour='*/3', minute='5') crearía una tarea que se ejecutará cada tres horas 5 minutos después.
  • crontab(minute='00', hour='10', month='*/2', day_of_week='*/5') crearía una tarea que se ejecutaría cada cinco días de la semana, de cada segundo mes a las 10:00 A.M.

Programación de tareas

Por ejemplo, tienes la siguiente tarea definida dentro de tasks.py :

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


Ahora, si desea llamar a esta tarea pero desea que se ejecute después de 5 segundos, puede hacer lo siguiente:

 count.schedule(delay=5)

El parámetro delay toma valores en segundos, por lo que si desea que se ejecute después de 5 minutos, especifique 300 segundos.

Reintentar tareas que fallan

Supongamos que agrega la siguiente lógica a nuestra tarea 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"] )


Entonces, agregamos la lógica para verificar el código de estado de la respuesta y, si es distinto de 200, reintentará esa tarea hasta 2 veces. Pero estos reintentos se producirían sin ningún intervalo de tiempo entre los dos intentos. Ahora bien, ¿qué sucede si desea retrasar varios intentos de esta tarea? Podemos hacerlo pasando el argumento retry_delay , acepta valores en segundos.


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

Esto provocará un retraso de 10 segundos entre múltiples intentos.

Modo de desarrollo

Huey viene con una configuración predeterminada que facilita el trabajo con Huey durante el desarrollo en Django. Entonces, siempre que tenga DEBUG=True presente en su archivo settings.py , las tareas se ejecutarán sincrónicamente como las llamadas a funciones normales. El propósito de esto es evitar ejecutar Redis y un proceso de consumidor adicional mientras se desarrollan o ejecutan pruebas. Puedes leer más sobre esto aquí .


Para esto, necesitamos agregar la siguiente línea en settings.py :

 HUEY = {}


Sin embargo, si desea anular este comportamiento, puede agregar la siguiente configuración de Huey:

 HUEY = { "immediate": False }

Si tiene la configuración anterior mencionada en settings.py , mientras tiene DEBUG=True , Huey le pedirá que configure Redis y ejecute Huey Worker usando el comando run_huey .

Apio vs Huey

Algunas observaciones sobre Huey en comparación con Apio son:

  • Menor huella de dependencias en comparación con Apio. Apio instala kombu y billar junto con él. Mientras tanto, Huey no tiene dependencias.


  • Es necesario ejecutar servicios menores para tareas periódicas, Celery requiere ejecutar el servicio beat y un servicio de trabajador para trabajar con tareas periódicas, mientras que solo necesitamos ejecutar un servicio usando el comando run_huey .

Referencias

  1. Huey Docs
  2. API de Wordnik
  3. Repositorio de Github asociado