From 7b18a244d11f6e94c21348a79e0b0ff91b572070 Mon Sep 17 00:00:00 2001 From: Kim Chee Leong Date: Fri, 16 Jan 2026 15:43:22 +0100 Subject: [PATCH 01/11] Add ci/tests --- .github/workflows/ci.yml | 36 +++++++++++++++++++++ README.md | 4 +-- pyproject.toml | 12 ++++++- src/django_huey_log/tests/__init__.py | 0 src/django_huey_log/tests/test_log_tasks.py | 16 +++++++++ 5 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 src/django_huey_log/tests/__init__.py create mode 100644 src/django_huey_log/tests/test_log_tasks.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..3629746 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,36 @@ +name: CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10", "3.11", "3.12", "3.13"] + django-version: ["4.2", "5.0", "5.1"] + + steps: + - uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + enable-cache: true + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + uv pip install "django==${{ matrix.django-version }}" + uv pip install -e ".[test]" || uv pip install -e . pytest pytest-django huey + + - name: Run Tests + run: uv run pytest \ No newline at end of file diff --git a/README.md b/README.md index dad54a4..13bd101 100644 --- a/README.md +++ b/README.md @@ -15,14 +15,14 @@ Log and monitor [Huey](https://huey.readthedocs.io/en/latest/) task attempts dir 1. Install the package using [uv](https://docs.astral.sh/uv/): ```bash - uv add django-huey-log + uv add git+https://github.com/PythonUnited/django-huey-log.git ``` 2. Add `huey_log` to your `INSTALLED_APPS` in `settings.py`: ```python INSTALLED_APPS = [ # ... - "huey_log", + "django_huey_log", # ... ] ``` diff --git a/pyproject.toml b/pyproject.toml index 9dd55ad..d33f7bf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,4 +17,14 @@ build-backend = "hatchling.build" packages = ["src/django_huey_log"] [tool.hatch.build.targets.wheel.sources] -"src" = "django_huey_log" \ No newline at end of file +"src" = "django_huey_log" + +[project.optional-dependencies] +test = [ + "pytest>=7.0", + "pytest-django>=4.5", +] + +[tool.pytest.ini_options] +DJANGO_SETTINGS_MODULE = "example.settings" +python_files = ["tests.py", "test_*.py"] \ No newline at end of file diff --git a/src/django_huey_log/tests/__init__.py b/src/django_huey_log/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/django_huey_log/tests/test_log_tasks.py b/src/django_huey_log/tests/test_log_tasks.py new file mode 100644 index 0000000..ec68780 --- /dev/null +++ b/src/django_huey_log/tests/test_log_tasks.py @@ -0,0 +1,16 @@ +import pytest +from ..models import HueyTaskAttempt +from example.tasks import success_task + + +@pytest.mark.django_db +def test_task_logging_success(): + # Trigger the task (calling .task_id usually triggers huey logic in testing) + task_result = success_task("test-user") + + # Check if an attempt was logged + attempt = HueyTaskAttempt.objects.first() + assert attempt is not None + assert attempt.task_name == "example.tasks.success_task" + # Note: In synchronous testing, you might need to manually trigger signals + # depending on your HUEY configuration in tests. \ No newline at end of file From 44d633b494981cb65ab0776f4951a1057b717a82 Mon Sep 17 00:00:00 2001 From: Kim Chee Leong Date: Fri, 16 Jan 2026 15:46:31 +0100 Subject: [PATCH 02/11] Trying to fix CI pipeline --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3629746..443dcd1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,8 +29,8 @@ jobs: - name: Install dependencies run: | - uv pip install "django==${{ matrix.django-version }}" - uv pip install -e ".[test]" || uv pip install -e . pytest pytest-django huey + uv pip install --system "django==${{ matrix.django-version }}" + uv pip install --system -e ".[test]" || uv pip install -e . pytest pytest-django huey - name: Run Tests run: uv run pytest \ No newline at end of file From 54f8c1aeae5803e9a5fa3acdddaeddd3d45f7455 Mon Sep 17 00:00:00 2001 From: Kim Chee Leong Date: Fri, 16 Jan 2026 15:53:53 +0100 Subject: [PATCH 03/11] Trying to fix CI pipeline #2 --- .github/workflows/ci.yml | 4 ++-- pyproject.toml | 3 ++- src/django_huey_log/tests/test_log_tasks.py | 4 +--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 443dcd1..2fb4a80 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,7 @@ jobs: - name: Install dependencies run: | uv pip install --system "django==${{ matrix.django-version }}" - uv pip install --system -e ".[test]" || uv pip install -e . pytest pytest-django huey + uv pip install --system -e ".[test]" || uv pip install --system -e . pytest pytest-django huey - name: Run Tests - run: uv run pytest \ No newline at end of file + run: PYTHONPATH=. pytest \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index d33f7bf..1dd81fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,4 +27,5 @@ test = [ [tool.pytest.ini_options] DJANGO_SETTINGS_MODULE = "example.settings" -python_files = ["tests.py", "test_*.py"] \ No newline at end of file +python_files = ["tests.py", "test_*.py"] +pythonpath = ["."] \ No newline at end of file diff --git a/src/django_huey_log/tests/test_log_tasks.py b/src/django_huey_log/tests/test_log_tasks.py index ec68780..1f2a18d 100644 --- a/src/django_huey_log/tests/test_log_tasks.py +++ b/src/django_huey_log/tests/test_log_tasks.py @@ -11,6 +11,4 @@ def test_task_logging_success(): # Check if an attempt was logged attempt = HueyTaskAttempt.objects.first() assert attempt is not None - assert attempt.task_name == "example.tasks.success_task" - # Note: In synchronous testing, you might need to manually trigger signals - # depending on your HUEY configuration in tests. \ No newline at end of file + assert attempt.task_name == "success_task" From 7ad5390bd67c4eeca87df8e282c283f600c68feb Mon Sep 17 00:00:00 2001 From: Kim Chee Leong Date: Fri, 16 Jan 2026 15:58:28 +0100 Subject: [PATCH 04/11] Add more tests --- src/django_huey_log/tests/test_log_tasks.py | 29 ++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/django_huey_log/tests/test_log_tasks.py b/src/django_huey_log/tests/test_log_tasks.py index 1f2a18d..69d19d9 100644 --- a/src/django_huey_log/tests/test_log_tasks.py +++ b/src/django_huey_log/tests/test_log_tasks.py @@ -1,6 +1,6 @@ import pytest from ..models import HueyTaskAttempt -from example.tasks import success_task +from example.tasks import success_task, failure_task @pytest.mark.django_db @@ -12,3 +12,30 @@ def test_task_logging_success(): attempt = HueyTaskAttempt.objects.first() assert attempt is not None assert attempt.task_name == "success_task" + + +@pytest.mark.django_db +def test_task_logging_failure(): + # Trigger a failing task. + # We don't necessarily need pytest.raises if Huey handles the exception internally, + # we just need to verify that the SIGNAL_ERROR was caught and logged. + failure_task() + + # Check if a failure attempt was logged + attempt = HueyTaskAttempt.objects.filter(task_name="failure_task").first() + assert attempt is not None + assert attempt.status == HueyTaskAttempt.Status.ERROR + assert attempt.exc_type == "ValueError" + assert "This task was designed to fail!" in attempt.exc_message + assert len(attempt.traceback) > 0 + + + +@pytest.mark.django_db +def test_task_logging_arguments(): + # Test complex argument capturing. + # Note: 'name' is a keyword argument here, so it goes into kwargs_repr. + success_task(name={"complex": [1, 2, 3]}) + + attempt = HueyTaskAttempt.objects.filter(task_name="success_task").first() + assert "{'complex': [1, 2, 3]}" in attempt.kwargs_repr \ No newline at end of file From d91a462ba0cda4dde7e524ca8f1d94ea4f022bcd Mon Sep 17 00:00:00 2001 From: Kim Chee Leong Date: Fri, 16 Jan 2026 16:01:09 +0100 Subject: [PATCH 05/11] Change django version in pyproject.toml and CI config --- .github/workflows/ci.yml | 4 ++-- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2fb4a80..afcb4f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,8 +11,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13"] - django-version: ["4.2", "5.0", "5.1"] + python-version: ["3.10", "3.11", "3.12", "3.13"] + django-version: ["5.0", "5.1", "6.0"] steps: - uses: actions/checkout@v4 diff --git a/pyproject.toml b/pyproject.toml index 1dd81fc..77bc771 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ description = "Log and monitor Huey task attempts in the Django admin" readme = "README.md" requires-python = ">=3.10" dependencies = [ - "django>=4.2", + "django>=5.0", "huey>=2.5.0", ] From 2cfead46892ddca965cb1d34a07eee00ff7b622c Mon Sep 17 00:00:00 2001 From: Kim Chee Leong Date: Fri, 16 Jan 2026 16:03:18 +0100 Subject: [PATCH 06/11] Change django version in pyproject.toml and CI config #2 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index afcb4f9..b74d615 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13"] + python-version: ["3.11", "3.12", "3.13"] django-version: ["5.0", "5.1", "6.0"] steps: From cbed6fffdd9a509a965b9b264bc2e53152c31d4c Mon Sep 17 00:00:00 2001 From: Kim Chee Leong Date: Fri, 16 Jan 2026 16:07:37 +0100 Subject: [PATCH 07/11] Add ruff linter --- .github/workflows/ci.yml | 20 ++++++++++++++++++++ example/manage.py | 2 +- example/settings.py | 3 +-- example/tasks.py | 6 ++++-- example/urls.py | 2 +- pyproject.toml | 20 +++++++++++++++++++- src/django_huey_log/admin.py | 1 + src/django_huey_log/signals.py | 6 ++++-- src/django_huey_log/tests/test_log_tasks.py | 8 +++++--- 9 files changed, 56 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b74d615..b0990a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,27 @@ on: branches: [ main ] jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v5 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Run Ruff + run: | + uv pip install ruff + uv run ruff check . + uv run ruff format --check . + test: + needs: lint runs-on: ubuntu-latest strategy: matrix: diff --git a/example/manage.py b/example/manage.py index 37c9914..1b243ab 100644 --- a/example/manage.py +++ b/example/manage.py @@ -19,4 +19,4 @@ def main(): if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/example/settings.py b/example/settings.py index 99e1fe3..f189ac5 100644 --- a/example/settings.py +++ b/example/settings.py @@ -1,4 +1,3 @@ -import os from pathlib import Path BASE_DIR = Path(__file__).resolve().parent.parent @@ -58,4 +57,4 @@ 'huey_class': 'huey.SqliteHuey', 'name': 'test-huey', 'filename': BASE_DIR / 'huey_db.sqlite3', -} \ No newline at end of file +} diff --git a/example/tasks.py b/example/tasks.py index 0e5c61a..8eef32a 100644 --- a/example/tasks.py +++ b/example/tasks.py @@ -1,6 +1,8 @@ -from huey.contrib.djhuey import task, db_task import time +from huey.contrib.djhuey import task + + @task() def success_task(name): print(f"Hello {name}!") @@ -10,4 +12,4 @@ def success_task(name): @task() def failure_task(): time.sleep(0.5) - raise ValueError("This task was designed to fail!") \ No newline at end of file + raise ValueError("This task was designed to fail!") diff --git a/example/urls.py b/example/urls.py index 0757f2b..083932c 100644 --- a/example/urls.py +++ b/example/urls.py @@ -3,4 +3,4 @@ urlpatterns = [ path("admin/", admin.site.urls), -] \ No newline at end of file +] diff --git a/pyproject.toml b/pyproject.toml index 77bc771..5cccc89 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,8 +24,26 @@ test = [ "pytest>=7.0", "pytest-django>=4.5", ] +dev = [ + "ruff>=0.1.0", +] [tool.pytest.ini_options] DJANGO_SETTINGS_MODULE = "example.settings" python_files = ["tests.py", "test_*.py"] -pythonpath = ["."] \ No newline at end of file +pythonpath = ["."] + +[tool.ruff] +# Target version for the generated code +target-version = "py310" +line-length = 88 + +[tool.ruff.lint] +# Enable Pyflakes (F) and pycodestyle (E, W) codes by default. +# Also common: I (isort), B (flake8-bugbear), UP (pyupgrade) +select = ["E", "F", "W", "I", "B", "UP"] +ignore = [] + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" \ No newline at end of file diff --git a/src/django_huey_log/admin.py b/src/django_huey_log/admin.py index d35871d..a731c60 100644 --- a/src/django_huey_log/admin.py +++ b/src/django_huey_log/admin.py @@ -1,4 +1,5 @@ from django.contrib import admin + from .models import HueyTaskAttempt diff --git a/src/django_huey_log/signals.py b/src/django_huey_log/signals.py index 4282328..6e91ac5 100644 --- a/src/django_huey_log/signals.py +++ b/src/django_huey_log/signals.py @@ -1,7 +1,8 @@ from __future__ import annotations import traceback as tb -from datetime import datetime, timezone as dt_timezone +from datetime import datetime +from datetime import timezone as dt_timezone from django.utils import timezone from huey.contrib.djhuey import HUEY @@ -48,7 +49,8 @@ def _task_eta(task): def _upsert_attempt(task, status: str, **fields): # Single-row “current attempt” strategy keyed by task_id + started_at bucket: - # For simplicity: just create new rows for EXECUTING, then update the latest row for completion/error. + # For simplicity: just create new rows for EXECUTING, then update the latest + # row for completion/error. task_id = str(getattr(task, "id", "") or getattr(task, "task_id", "")) if status == HueyTaskAttempt.Status.EXECUTING: diff --git a/src/django_huey_log/tests/test_log_tasks.py b/src/django_huey_log/tests/test_log_tasks.py index 69d19d9..ee7ca26 100644 --- a/src/django_huey_log/tests/test_log_tasks.py +++ b/src/django_huey_log/tests/test_log_tasks.py @@ -1,12 +1,14 @@ import pytest + +from example.tasks import failure_task, success_task + from ..models import HueyTaskAttempt -from example.tasks import success_task, failure_task @pytest.mark.django_db def test_task_logging_success(): # Trigger the task (calling .task_id usually triggers huey logic in testing) - task_result = success_task("test-user") + success_task("test-user") # Check if an attempt was logged attempt = HueyTaskAttempt.objects.first() @@ -38,4 +40,4 @@ def test_task_logging_arguments(): success_task(name={"complex": [1, 2, 3]}) attempt = HueyTaskAttempt.objects.filter(task_name="success_task").first() - assert "{'complex': [1, 2, 3]}" in attempt.kwargs_repr \ No newline at end of file + assert "{'complex': [1, 2, 3]}" in attempt.kwargs_repr From ab1dc0cb1f2c4694103e636cce0529cf0de51b53 Mon Sep 17 00:00:00 2001 From: Kim Chee Leong Date: Fri, 16 Jan 2026 16:08:48 +0100 Subject: [PATCH 08/11] Add ruff linter #2 --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b0990a1..c925109 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,9 +22,9 @@ jobs: - name: Run Ruff run: | - uv pip install ruff - uv run ruff check . - uv run ruff format --check . + uv pip install --system ruff + ruff check . + ruff format --check . test: needs: lint From 0802d995cffd16c0a8ba495aa4eecc98e00becb0 Mon Sep 17 00:00:00 2001 From: Kim Chee Leong Date: Fri, 16 Jan 2026 16:12:52 +0100 Subject: [PATCH 09/11] Add ruff linter #4 --- example/manage.py | 5 +++-- example/settings.py | 6 +++--- example/tasks.py | 1 + pyproject.toml | 2 +- src/django_huey_log/migrations/0001_initial.py | 1 - src/django_huey_log/tests/test_log_tasks.py | 1 - 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/example/manage.py b/example/manage.py index 1b243ab..80a63d1 100644 --- a/example/manage.py +++ b/example/manage.py @@ -1,12 +1,13 @@ #!/usr/bin/env python """Django's command-line utility for administrative tasks.""" + import os import sys def main(): """Run administrative tasks.""" - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings') + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") try: from django.core.management import execute_from_command_line except ImportError as exc: @@ -18,5 +19,5 @@ def main(): execute_from_command_line(sys.argv) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/example/settings.py b/example/settings.py index f189ac5..7c59bd6 100644 --- a/example/settings.py +++ b/example/settings.py @@ -54,7 +54,7 @@ STATIC_URL = "static/" HUEY = { - 'huey_class': 'huey.SqliteHuey', - 'name': 'test-huey', - 'filename': BASE_DIR / 'huey_db.sqlite3', + "huey_class": "huey.SqliteHuey", + "name": "test-huey", + "filename": BASE_DIR / "huey_db.sqlite3", } diff --git a/example/tasks.py b/example/tasks.py index 8eef32a..1c062ab 100644 --- a/example/tasks.py +++ b/example/tasks.py @@ -9,6 +9,7 @@ def success_task(name): time.sleep(1) return f"Done {name}" + @task() def failure_task(): time.sleep(0.5) diff --git a/pyproject.toml b/pyproject.toml index 5cccc89..a0eed26 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ test = [ "pytest-django>=4.5", ] dev = [ - "ruff>=0.1.0", + "ruff==0.14.13", ] [tool.pytest.ini_options] diff --git a/src/django_huey_log/migrations/0001_initial.py b/src/django_huey_log/migrations/0001_initial.py index fa588d0..3d6326b 100644 --- a/src/django_huey_log/migrations/0001_initial.py +++ b/src/django_huey_log/migrations/0001_initial.py @@ -5,7 +5,6 @@ class Migration(migrations.Migration): - initial = True dependencies = [] diff --git a/src/django_huey_log/tests/test_log_tasks.py b/src/django_huey_log/tests/test_log_tasks.py index ee7ca26..8b7b5f7 100644 --- a/src/django_huey_log/tests/test_log_tasks.py +++ b/src/django_huey_log/tests/test_log_tasks.py @@ -32,7 +32,6 @@ def test_task_logging_failure(): assert len(attempt.traceback) > 0 - @pytest.mark.django_db def test_task_logging_arguments(): # Test complex argument capturing. From b4ee8fb58baecaf852cef79b09615531caac0d4b Mon Sep 17 00:00:00 2001 From: Kim Chee Leong Date: Fri, 16 Jan 2026 16:14:24 +0100 Subject: [PATCH 10/11] Add ruff linter #5 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c925109..8ad774b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,8 +31,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.11", "3.12", "3.13"] - django-version: ["5.0", "5.1", "6.0"] + python-version: ["3.13"] + django-version: ["6.0"] steps: - uses: actions/checkout@v4 From 4a26090861d1d4b68e923fe898323018ae06839c Mon Sep 17 00:00:00 2001 From: Kim Chee Leong Date: Fri, 16 Jan 2026 16:15:33 +0100 Subject: [PATCH 11/11] Update versions --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8ad774b..5734b3d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.13"] + python-version: ["3.12", "3.13", "3.14"] django-version: ["6.0"] steps: