# Hook Class in abx_dl/plugins.py: Role and Priority Sorting System

> Learn about the Hook class in abx_dl/plugins.py and how it manages plugin execution order using a priority sorting system for predictable pipeline processing.

- Repository: [ArchiveBox/abx-dl](https://github.com/archivebox/abx-dl)
- Tags: internals
- Published: 2026-02-25

---

**The Hook class in [`abx_dl/plugins.py`](https://github.com/archivebox/abx-dl/blob/main/abx_dl/plugins.py) serves as the core data model representing individual plugin hooks in archivebox/abx-dl, using a `(step, priority, name)` tuple via the `sort_key` property to deterministically sort execution order across the data pipeline.**

In the archivebox/abx-dl repository, the Hook class defines how plugin hooks are structured, discovered, and scheduled. This lightweight data model captures metadata from hook filenames and provides the sorting logic that determines when each script executes. Understanding the Hook class and its priority sorting mechanism is essential for developing plugins that integrate correctly into the abx-dl execution flow.

## Understanding the Hook Class Data Model

The **Hook class**, defined in [`abx_dl/plugins.py`](https://github.com/archivebox/abx-dl/blob/main/abx_dl/plugins.py) at lines 18-27, represents a single plugin hook discovered during the directory scanning process. When `load_plugin` scans a plugin directory, it parses filenames matching the pattern `on_{Event}__{step}{priority}_{description}[.bg].{ext}` using `parse_hook_filename`, converting each valid file into a Hook instance with specific execution metadata.

### Hook Attributes and Storage Properties

Each Hook instance stores critical execution metadata derived from its filename and location:

- **name**: The filename without extension (e.g., `on_Crawl__10_save`)
- **plugin_name**: The parent plugin directory identifier
- **path**: Full `Path` object pointing to the hook file on disk
- **step**: Integer (0-9) determining the pipeline phase where the hook executes
- **priority**: Integer (0-9) determining execution precedence within the same step (lower values run first)
- **is_background**: Boolean indicating daemon mode when the filename ends with `.bg`
- **language**: Script type identifier (`py`, `js`, or `sh`)

The class provides two computed properties defined at lines 30-36. The **`full_name`** property returns a human-readable string formatted as `"{plugin}/{hook}"` (lines 30-32). The **`sort_key`** property generates the sorting tuple used for ordering (lines 34-36).

### The sort_key Property and Ordering Logic

The **`sort_key`** property implements the deterministic ordering mechanism for hook execution. As defined in lines 34-36, it returns a tuple of `(step, priority, name)`. This three-tier sorting system ensures predictable execution: first by pipeline step number, then by priority value within that step, and finally alphabetical by hook name to resolve any remaining ties.

## How Hooks Are Sorted by Priority in abx-dl

The sorting process occurs across three distinct phases during the plugin lifecycle, utilizing the `sort_key` property consistently to maintain execution order across the entire system.

### Discovery and Plugin Population

During the discovery phase, **`load_plugin`** populates the `plugin.hooks` collection with Hook instances parsed from the filesystem. Each discovered hook retains its computed `sort_key` tuple for subsequent ordering operations.

### Filtering and Local Sorting

Helper methods **`get_snapshot_hooks`** and **`get_crawl_hooks`** (lines 52-64) filter the hook collection based on event name patterns matching `'Snapshot'` or `'Crawl'`. Each method sorts the filtered results using the `hook.sort_key` attribute, ensuring that within each individual plugin, hooks are ordered by step and priority before any global aggregation occurs.

### Global Aggregation and Final Ordering

The **`get_all_snapshot_hooks`** function (lines 64-70) aggregates snapshot hooks from every discovered plugin and applies a final sort using the same `sort_key` lambda. This global sorting guarantees a unified execution sequence across the entire plugin ecosystem, respecting the two-dimensional priority system where step takes precedence over priority.

## Working with the Hook Class in Practice

Developers interact with Hook objects through the discovery and retrieval APIs exported from [`abx_dl/plugins.py`](https://github.com/archivebox/abx-dl/blob/main/abx_dl/plugins.py).

### Creating Hook Instances Manually

For testing or custom tooling, instantiate Hook objects directly with the required parameters:

```python
from pathlib import Path
from abx_dl.plugins import Hook

hook = Hook(
    name="on_Crawl__10_save",
    plugin_name="chrome",
    path=Path("/path/to/plugins/chrome/on_Crawl__10_save.py"),
    step=1,
    priority=0,
    is_background=False,
    language="py",
)

print(hook.full_name)   # → chrome/on_Crawl__10_save

print(hook.sort_key)    # → (1, 0, 'on_Crawl__10_save')

```

### Retrieving Sorted Hooks from Discovered Plugins

Access hooks in their proper execution order using the discovery API:

```python
from abx_dl.plugins import discover_plugins, get_all_snapshot_hooks

plugins = discover_plugins()                     # scans abx_dl/plugins/

snapshot_hooks = get_all_snapshot_hooks(plugins)

for h in snapshot_hooks:
    print(f"{h.step}:{h.priority} – {h.full_name}")

```

This outputs hooks sorted by the `(step, priority, name)` tuple defined in `Hook.sort_key`, ensuring step 0 hooks execute before step 1, and priority 0 before priority 1 within each step.

### Filtering by Plugin and Event Type

Filter specific plugin subsets while maintaining the sorted order:

```python
from abx_dl.plugins import discover_plugins, filter_plugins

all_plugins = discover_plugins()
selected = filter_plugins(all_plugins, ["chrome", "title"])

for plugin in selected.values():
    for hook in plugin.get_crawl_hooks():
        print(hook.sort_key, hook.full_name)

```

Each call to `plugin.get_crawl_hooks()` returns hooks pre-sorted by the `sort_key` property according to the implementation at lines 52-64.

## Summary

- The **Hook class** in [`abx_dl/plugins.py`](https://github.com/archivebox/abx-dl/blob/main/abx_dl/plugins.py) (lines 18-27) serves as the immutable data model for individual plugin hooks, parsing filenames to extract execution metadata.
- The **`sort_key`** property (lines 34-36) generates a `(step, priority, name)` tuple that deterministically orders hook execution via Python's tuple comparison.
- **Step values** (0-9) determine the pipeline phase, while **priority values** (0-9) determine order within that phase, with lower numbers executing first.
- The **`get_snapshot_hooks`** and **`get_crawl_hooks`** methods (lines 52-64) sort hooks locally per plugin, while **`get_all_snapshot_hooks`** (lines 64-70) provides global sorted aggregation.
- The **two-dimensional priority system** ensures predictable, deterministic execution across all plugins in the abx-dl ecosystem.

## Frequently Asked Questions

### What is the Hook class in abx_dl/plugins.py?

The **Hook class** is the core data model representing a single plugin hook in the archivebox/abx-dl repository. Defined at lines 18-27 in [`abx_dl/plugins.py`](https://github.com/archivebox/abx-dl/blob/main/abx_dl/plugins.py), it encapsulates execution metadata parsed from hook filenames and provides the `sort_key` property that determines when the hook runs relative to other plugins.

### How does the sort_key property determine execution order?

The **`sort_key`** property returns a tuple of `(step, priority, name)` as implemented at lines 34-36. When Python sorts Hook instances, it compares these tuples element-wise: first by step number (ascending), then by priority within that step (ascending), and finally by hook name alphabetically to break ties. Lower step and priority values execute earlier in the pipeline.

### What is the difference between step and priority in abx-dl hooks?

**Step** (values 0-9) specifies the pipeline phase in which a hook executes, controlling its position relative to major workflow stages. **Priority** (values 0-9) specifies the execution order within that specific step, with priority 0 running before priority 1. This separation allows hooks to be scheduled for specific phases while maintaining fine-grained ordering within those phases.

### How do I retrieve all snapshot hooks in sorted order?

Use the **`get_all_snapshot_hooks`** function defined at lines 64-70, passing the result of `discover_plugins()` as the argument. This function aggregates snapshot hooks from all discovered plugins and sorts them using the `sort_key` property, returning a list ordered by step, priority, and name for deterministic execution.