Agent skill

Dj Signals

by dvf in dvf/opinionated-django

Add reliable signals (async side-effects via Celery) to a Django feature.

MITAuto-check: notesBackend & APIs

Install Dj Signals

skills CLI
$ npx skills add dvf/opinionated-django --skill dj-signals -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install dvf/opinionated-django dj-signals --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/dvf/opinionated-django.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/dj-signals .claude/skills/dj-signals && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
dj-signals
GitHub stars
109
Token cost
~1k tokens
SKILL.md length
356 words
Files
1
Skills in repo
9
Repo updated
First seen
Licence
MIT

At a glance

Add reliable signals (async side-effects via Celery) to a Django feature.

  • Works in 5 steps: Define the Signal → Send from the Service Layer → Write the Receiver → …
  • A business operation needs to trigger post-commit work like notifications
  • SKILL.md covers How It Works, BEFORE WRITING CODE, Step 1: Define the Signal and Step 2: Send from the Service…, plus 5 more sections
  • Calls uv

What it does

Dj Signals is an agent skill from dvf/opinionated-django. Add reliable signals (async side-effects via Celery) to a Django feature. Use when a business operation needs to trigger post-commit work like notifications, cache invalidation, analytics, or cross-service coordination — any time the user mentions side-effects, events, or async processing tied to a business action.

Its SKILL.md is about 1k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Backend & APIs, covering Backend development, Background jobs and Operations and SOPs. It works with Django. The repository describes itself as: An opinionated Django project with Repository pattern, Pydantic DTOs, svcs DI, and Stripe-style ULID IDs. The licence is MIT.

When your agent uses it

  • A business operation needs to trigger post-commit work like notifications
  • Cache invalidation
  • Cross-service coordination — any time the user mentions side-effects
  • Async processing tied to a business action

Example prompts

  • “/dj-signals”

Requirements

  • Python 3
  • Pre-approved tools (allowed-tools): Read, Write, Edit, Bash, Grep, Glob

Workflow steps

5 steps, taken from the step headings in SKILL.md.

  1. Define the Signal
  2. Send from the Service Layer
  3. Write the Receiver
  4. Load Receivers in apps.py
  5. Test

What it can do on your machine

Read from SKILL.md and the folder at commit f17fc2d. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Read
    • Write
    • Edit
    • Bash
    • Grep
    • Glob

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • uv

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • hakibenita.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Dj Signals loads about 1k tokens when it runs. Until then it costs about 82 tokens; SKILL.md has 356 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~82
When it runs · the whole SKILL.md, loaded when a task matches
~1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NotePre-approves every shell command (allowed-tools: Bash)SKILL.md
    allowed-tools: Read, Write, Edit, Bash, Grep, Glob

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from dvf/opinionated-django at commit f17fc2d, republished under its MIT licence (© dvf). 356 words, ~1,049 tokens.

Download SKILL.mdSave it as .claude/skills/dj-signals/SKILL.md (or your agent's skills folder).
name
dj-signals
description
Add reliable signals (async side-effects via Celery) to a Django feature. Use when a business operation needs to trigger post-commit work like notifications, cache invalidation, analytics, or cross-service coordination — any time the user mentions side-effects, events, or async processing tied to a business action.
allowed-tools
Read, Write, Edit, Bash, Grep, Glob

Add a Reliable Signal

You are adding a reliable signal to an opinionated Django project. Standard Django signals are synchronous and unreliable — receiver failures propagate to the sender, there's no delivery guarantee if the process crashes after commit, and there's no retry. This project uses the reliable signals pattern with Celery instead.

The pattern implemented here is adapted from Haki Benita's article Reliable Signals in Django. Credit for the original design goes to him — read the full article for the rationale and edge cases.

How It Works

Signal receiver tasks are enqueued inside the same database transaction as the business operation. If the transaction rolls back, the tasks roll back too. If it commits, the tasks are guaranteed to be in the queue. Celery processes them asynchronously with at-least-once delivery.

BEFORE WRITING CODE

  1. Find existing signals with Grep for ReliableSignal under src/
  2. Find existing receivers with Glob for src/**/receivers.py
  3. Identify which service method should emit the signal and what data needs to travel with it

Step 1: Define the Signal

File: src/<app>/signals.py

python
from project.signals import ReliableSignal

my_event = ReliableSignal()

Step 2: Send from the Service Layer

Call send_reliable() inside a transaction.atomic() block. Arguments MUST be JSON-serializable — pass entity IDs, never model instances:

python
from django.db import transaction

def create_entity(self, name: str) -> MyEntityDTO:
    with transaction.atomic():
        entity = self.repo.create(name=name)
        my_event.send_reliable(sender=None, entity_id=entity.id)
    return entity
Show full SKILL.md (158 more words)Show less

Step 3: Write the Receiver

File: src/<app>/receivers.py

python
from django.dispatch import receiver
from .signals import my_event

@receiver(my_event)
def on_my_event(obj_id: str, **kwargs):
    # Idempotent: guard against duplicate execution
    if already_processed(obj_id):
        return
    do_work(obj_id)

CRITICAL: Every receiver MUST be idempotent. The system guarantees at-least-once delivery, not exactly-once. A receiver may run more than once for the same event. Design accordingly:

  • Check if the action was already performed before performing it
  • Use database constraints or flags to prevent duplicate effects
  • Never assume a receiver runs exactly once

Step 4: Load Receivers in apps.py

python
class MyAppConfig(AppConfig):
    def ready(self):
        from . import receivers  # noqa: F401

Step 5: Test

Test receivers in isolation. Mock external dependencies. Verify idempotency by calling the receiver twice with the same arguments:

python
def test_receiver_is_idempotent(mocker):
    # First call: not yet processed; second call: guard kicks in.
    mocker.patch("my_app.receivers.already_processed", side_effect=[False, True])
    do_work = mocker.patch("my_app.receivers.do_work")

    on_my_event(obj_id="xxx_fake")
    on_my_event(obj_id="xxx_fake")  # second call must be safe

    assert do_work.call_count == 1

Rules

  • NEVER use standard Django send() for post-commit side-effects — use send_reliable()
  • Arguments MUST be JSON-serializable (strings, numbers, booleans) — never model instances
  • Receivers MUST be idempotent — this is non-negotiable
  • Receivers MUST NOT import or touch ORM models directly — use a repository if DB access is needed
  • Receivers MUST NOT call other services that emit signals (no cascading) without careful consideration of idempotency across the chain

VERIFY

bash
uv run ruff check src
uv run ruff format --check src
uv run pyrefly check src
uv run pytest

If anything fails, fix it and re-run.

© dvf, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/dj-signals of dvf/opinionated-django.

Open the folder on GitHubat commit f17fc2d

Compare with similar skills

Dj Signals next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Dj Signals compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Dj Signals this skilldvf/opinionated-django109—~1kAutomated safety check: NotesMIT
Django Celery Expertvintasoftware/django-ai-plugins153—~1.2kAutomated safety check: PassNone
Sentry Python SDKgetsentry/sentry-for-ai268—~4.1kAutomated safety check: PassApache-2.0
Django Prodavila7/claude-code-templates32k8 repos~1.7kAutomated safety check: PassMIT
Django Celeryaffaan-m/ECC276k1 repos~3.3kAutomated safety check: PassMIT
Django Celeryaffaan-m/ECC276k—~240Automated safety check: PassMIT

Similar skills

  • Django Celery Expert

    vintasoftware/django-ai-plugins

    Expert Django Celery guidance for asynchronous task processing.

    153 GitHub stars~1.2k tokensUpdated 2 mo ago
    Backend & APIsAuto-check passed
  • Sentry Python SDK

    getsentry/sentry-for-ai

    Official

    Full Sentry SDK setup for Python. An agent skill from getsentry/sentry-for-ai.

    268 GitHub stars~4.1k tokensUpdated yesterday
    Backend & APIsAuto-check passed
  • Django Pro

    davila7/claude-code-templates

    Master Django 5.x with async views, DRF, Celery, and Django Channels.

    32k GitHub starsUsed in 8 repos~1.7k tokens
    Backend & APIsAuto-check passed
  • Django Celery

    affaan-m/ECC

    Django + Celery async task patterns — configuration, task design, beat scheduling, retries, canvas workflows, monitoring, and testing.

    276k GitHub starsUsed in 1 repo~3.3k tokens
    Backend & APIsAuto-check passed
  • Django Celery

    affaan-m/ECC

    DjangoおよびCeleryを使用した非同期タスク処理。タスクキューイング、ワーカー管理、エラー処理、スケジューリング。Redis/RabbitMQ ブローカー統合。

    276k GitHub stars~240 tokensUpdated 4 days ago
    Backend & APIsAuto-check passed
  • Django Startup Time

    PostHog/posthog

    Official

    Keep heavy imports off the django.setup() path that every process (web, celery, temporal, migrate, shell, CI) pays for.

    40k GitHub stars~1.4k tokensUpdated today
    Backend & APIsAuto-check passed

More from dvf/opinionated-django

All 9 skills in this repo
  • Dj Architecture

    dvf/opinionated-django

    Implement a Django feature following the opinionated architecture — prefixed ULID IDs, repository pattern, Pydantic DTOs, svcs service locator, project-scoped django-ninja API, Celery reliable…

    109 GitHub stars~4k tokensUpdated 1 mo ago
    Auto-check: notes
  • Dj Models

    dvf/opinionated-django

    Structure Django models with proper Meta classes, verbose names, and optimized indexes.

    109 GitHub stars~4.9k tokensUpdated 1 mo ago
    Auto-check: notes
  • Dj Prefixed Ulids

    dvf/opinionated-django

    Use Stripe-style prefixed ULID primary keys (e.g. An agent skill from dvf/opinionated-django.

    109 GitHub stars~1.4k tokensUpdated 1 mo ago
    Auto-check: notes
  • Dj Pytest

    dvf/opinionated-django

    Set up and write pytest tests for an op-django project — pytest-django configuration, two-sided Celery testing (patched dispatch sites + plain-function task bodies, never eager mode), freezegun for…

    109 GitHub stars~4.3k tokensUpdated 1 mo ago
    Auto-check: notes
  • Dj Scaffold

    dvf/opinionated-django

    Set up a Django project into the op-django layout so the architecture, signals, and settings skills have a foundation to build on.

    109 GitHub stars~3.3k tokensUpdated 1 mo ago
    Auto-check: notes
  • Dj Services

    dvf/opinionated-django

    Structure Django business logic as plain services that receive their dependencies via constructor injection, and wire them through an svcs registry so they can be resolved anywhere — views, Celery…

    109 GitHub stars~3k tokensUpdated 1 mo ago
    Auto-check: notes

Works with

Categories

Questions about Dj Signals

What does Dj Signals do?

Add reliable signals (async side-effects via Celery) to a Django feature. Dj Signals is an agent skill from dvf/opinionated-django. Add reliable signals (async side-effects via Celery) to a Django feature.

When should I use Dj Signals?

Dj Signals fits situations like: A business operation needs to trigger post-commit work like notifications; cache invalidation; cross-service coordination — any time the user mentions side-effects; async processing tied to a business action.

How do I install Dj Signals in Claude Code?

Run `npx skills add dvf/opinionated-django --skill dj-signals -a claude-code`. Or copy the skill folder (skills/dj-signals in dvf/opinionated-django) into .claude/skills/dj-signals in your project. Claude Code loads it when a task matches its description.

How do I install Dj Signals in Codex?

Run `npx skills add dvf/opinionated-django --skill dj-signals -a codex`. Or copy the skill folder (skills/dj-signals in dvf/opinionated-django) into .agents/skills/dj-signals in your project. Codex loads it when a task matches its description.

Can I use Dj Signals in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add dvf/opinionated-django --skill dj-signals -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/dj-signals, .gemini/skills/dj-signals, .github/skills/dj-signals and .opencode/skills/dj-signals in your project.

What does Dj Signals need to run?

Going by SKILL.md and its folder, Dj Signals needs the command-line tools its instructions call (uv). Our summary lists: Python 3. Its frontmatter pre-approves these tools: Read, Write, Edit, Bash, Grep, Glob.

Does Dj Signals access the network?

SKILL.md names 1 domain. As links in the text: hakibenita.com. This is read from the text; nothing was executed.

Is Dj Signals safe to install?

Our automated static check of SKILL.md found notes only (pre-approves every shell command (allowed-tools: bash)), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.

What licence does Dj Signals use?

Dj Signals is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Dj Signals use?

About 1k tokens (SKILL.md is roughly 4.2k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Dj Signals?

Skills that share tags, products or a category with Dj Signals: Django Celery Expert (vintasoftware/django-ai-plugins, 153 stars), Sentry Python SDK (getsentry/sentry-for-ai, 268 stars), Django Pro (davila7/claude-code-templates, 32k stars) and Django Celery (affaan-m/ECC, 276k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Dj Signals?

dvf (a GitHub user) maintains it in dvf/opinionated-django, which has 109 GitHub stars. The repository holds 9 skills in this directory. The repository was last updated on August 14, 2026.

Source: dvf/opinionated-django on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.