Backend API desarrollado con Django REST Framework para consultar facturas desde una tabla existente en base de datos.
Este proyecto expone un endpoint REST para consultar facturas almacenadas en la tabla invoices.
La tabla es externa/existente, por lo que el modelo Invoice usa:
managed = FalseEsto significa que Django no intentará crear, modificar ni migrar la tabla invoices.
El sistema ejecuta una tarea programada diariamente usando Celery Beat.
Todos los días a las 8:00 AM (hora de México), el sistema ejecuta una tarea background que:
- Consulta los 10 días con mayores ventas.
- Genera un resumen.
- Envía el reporte por email.
Esta aplicación backend fue desarrollada y probada utilizando:
- Ubuntu Linux
- Python 3
- pip
Se espera compatibilidad con macOS y Windows, aunque no fue validada formalmente durante el desarrollo.
- Python
- Django
- Django REST Framework
- django-filter
- PostgreSQL
- Celery
- Redis
Redis es requerido para ejecutar Celery y Celery Beat.
sudo apt update
sudo apt install redis-serverredis-cli pingRespuesta esperada:
PONGEl siguiente comando debe ejecutarse en la carpeta invoice-query-backend.
python3 -m venv .venvSi surge algún error en el comando anterior. Instalar `python-venv ejecutando el siguiente comando y volver a ejecutar el paso anterior:
sudo apt install python3.14-venvEl siguiente comando debe ejecutarse en la carpeta invoice-query-backend.
source .venv/bin/activateEl siguiente comando debe ejecutarse en la carpeta invoice-query-backend.
python3 -m pip install -r requirements.txtCrear un archivo .env basado en .env.example, el siguiente comando debe ejecutarse en la carpeta invoice-query-backend.
cp .env.example .envEjemplo de variables necesarias:
DB_NAME=your_database_name
DB_USER=your_database_user
DB_PASSWORD=your_database_password
DB_HOST=localhost
DB_PORT=5432
EMAIL_HOST_USER=your_email@gmail.com
EMAIL_HOST_PASSWORD=your_app_password
REPORT_RECIPIENT_EMAIL=recipient_email@example.comEl proyecto utiliza SMTP de Gmail para enviar el reporte diario de ventas.
Variables requeridas:
EMAIL_HOST_USER=your_email@gmail.com
EMAIL_HOST_PASSWORD=your_app_password
REPORT_RECIPIENT_EMAIL=recipient_email@example.comPara usar Gmail SMTP es necesario generar un App Password:
- Activar 2FA en la cuenta Gmail.
- Ir a Google Account Settings.
- Security → App Passwords.
- Generar una contraseña para la aplicación.
La contraseña generada debe usarse en:
EMAIL_HOST_PASSWORD=your_app_passwordver más: https://youtu.be/srGxqsPwAlw?si=x5fHS7jld2UYaHZy
Para evitar enviar emails reales durante desarrollo, puede usarse en el archivo invoice-query-backend/app/app/settings.py la siguiente variable:
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"Con esto los emails se imprimirán en consola.
El siguiente comando debe ejecutarse en la carpeta invoice-query-backend/app y con el ambiente virtual encendido Ir a la sección de activar entorno virtual.
python3 manage.py runserverEl backend quedará disponible en:
http://localhost:8000En una nueva terminal ejecutar:
redis-serverEl siguiente comando debe ejecutarse en una nueva terminal y dentro de la carpeta invoice-query-backend/app teniendo en cuenta que el ambiente virtual debe estar activo Ir a la sección de activar entorno virtual.
celery -A app worker -l infoEl siguiente comando debe ejecutarse en una nueva terminal y dentro de la carpeta invoice-query-backend/app teniendo en cuenta que el ambiente virtual debe estar activo Ir a la sección de activar entorno virtual.
celery -A app beat -l infoGET /api/v1/invoices/Ejemplo:
curl "http://localhost:8000/api/v1/invoices/"La API permite filtrar por:
invoice_date__gte(Filtrar invoices con fecha mayores a)invoice_date__lte(Filtrar invoices con fecha menores a)active(Si existe puede filtrar por facturas activas (true) o inactivas (false))
curl "http://localhost:8000/api/v1/invoices/"curl "http://localhost:8000/api/v1/invoices/?active=true"curl "http://localhost:8000/api/v1/invoices/?active=false"curl "http://localhost:8000/api/v1/invoices/?invoice_date__gte=2024-01-01"curl "http://localhost:8000/api/v1/invoices/?invoice_date__lte=2024-12-31"curl "http://localhost:8000/api/v1/invoices/?invoice_date__gte=2024-01-01&invoice_date__lte=2024-12-31"curl "http://localhost:8000/api/v1/invoices/?active=true&invoice_date__gte=2024-01-01&invoice_date__lte=2024-12-31"El proyecto usa paginación tipo limit y offset.
Ejemplo:
curl "http://localhost:8000/api/v1/invoices/?limit=10&offset=0"Siguiente página:
curl "http://localhost:8000/api/v1/invoices/?limit=10&offset=10"Ejemplo de respuesta:
{
"count": 100,
"next": "http://localhost:8000/api/v1/invoices/?limit=50&offset=50",
"previous": null,
"results": [
{
"id": 1,
"invoice_number": "INV-001",
"total": "1500.00",
"invoice_date": "2024-01-15T10:30:00",
"status": "paid",
"active": true
}
]
}- La tabla
invoicesdebe existir previamente en la base de datos. - Django no administrará la tabla
invoices. - El endpoint principal está versionado usando URL versioning.
- La versión actual soportada es
v1. - Redis es necesario para ejecutar Celery y Celery Beat.
El proyecto utiliza Redis para cachear respuestas del endpoint de facturas.
redis-cli -n 1KEYS *
Ejemplo de keys generadas por Django:
:1:views.decorators.cache.cache_page...
:1:views.decorators.cache.cache_header...redis-cli -n 1 monitorDespués ejecutar una request:
curl "http://localhost:8000/api/v1/invoices/?active=true"Redis mostrará operaciones como:
GET ...
SET ...
EXPIRE ...Celery utiliza una base Redis distinta (/0).
Entrar:
redis-cli -n 0Ver keys:
KEYS *
Ejemplo:
celery-task-meta-...
_kombu.binding...El siguiente comando debe ejecutarse en una nueva terminal y dentro de la carpeta invoice-query-backend/app teniendo en cuenta que el ambiente virtual debe estar activo Ir a la sección de activar entorno virtual.
python3 manage.py test