Skip to main content

A powerful Python-based rules engine for qBittorrent automation

Project description

qbt-rules

A powerful Python-based rules engine for automating torrent management in qBittorrent using declarative YAML configuration.

GitHub Release License: Unlicense


What is qbt-rules?

qbt-rules is a Python-based rules engine that automates torrent management through the qBittorrent Web API v5.0+. Define YAML-based rules to automatically categorize, tag, pause, resume, delete, and manage torrents based on flexible conditions.

Key Features:

  • Declarative YAML Rules - No coding required, just write rules
  • Multiple Trigger Types - Manual, scheduled (cron), webhooks (on_added, on_completed)
  • Powerful Conditions - Complex logic with AND/OR/NOT groups, 17+ operators
  • Rich Field Access - Dot notation access to all torrent metadata (info., trackers., files.*, etc.)
  • Idempotent Actions - Safe to run repeatedly, actions skip if already applied
  • Dry-Run Mode - Test rules without making changes
  • Comprehensive Logging - Trace mode for debugging

Quick Start

Installation

Option 1: Install from PyPI (recommended)

# Install the package
pip install qbt-rules

# Create config directory
mkdir -p ~/.config/qbt-rules

# Download example configs
curl -o ~/.config/qbt-rules/config.yml \
  https://raw.githubusercontent.com/andronics/qbt-rules/main/config/config.example.yml
curl -o ~/.config/qbt-rules/rules.yml \
  https://raw.githubusercontent.com/andronics/qbt-rules/main/config/rules.example.yml

# Edit config with your qBittorrent credentials
nano ~/.config/qbt-rules/config.yml

Option 2: Install from source

# Clone the repository
git clone https://github.com/andronics/qbt-rules.git
cd qbt-rules

# Install in editable mode with development dependencies
pip install -e ".[dev]"

# Copy example configs
cp config/config.example.yml config/config.yml
cp config/rules.example.yml config/rules.yml

# Edit config with your qBittorrent credentials
nano config/config.yml

Your First Rule

Create a simple rule in config/rules.yml:

rules:
  - name: "Auto-categorize HD movies"
    enabled: true
    stop_on_match: true
    conditions:
      trigger: on_added
      all:
        - field: info.name
          operator: matches
          value: '(?i).*(1080p|2160p|4k).*'
    actions:
      - type: set_category
        params:
          category: "Movies-HD"
      - type: add_tag
        params:
          tag: "movies"

Run It

Using console script (after pip install):

# Test with dry-run (shows what would happen)
qbt-rules --dry-run

# Apply rules (defaults to manual trigger)
qbt-rules

# Enable trace logging for debugging
qbt-rules --trace

# Run with specific trigger
qbt-rules --trigger scheduled

# Process specific torrent
qbt-rules --trigger on_completed --torrent-hash abc123...

Using Python module:

python -m qbt_rules.cli --dry-run

How It Works

┌─────────────────────────────────────────────────────────────┐
│                    TRIGGER ACTIVATION                       │
│  (Manual, Scheduled, on_added, on_completed)               │
└────────────────────────┬────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────┐
│              FETCH TORRENTS FROM qBittorrent               │
│         (Optional: Apply filters by category/state)         │
└────────────────────────┬────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────┐
│                   FOR EACH TORRENT:                        │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  Evaluate Rules in File Order                        │  │
│  │  ┌────────────────────────────────────────────────┐  │  │
│  │  │  Check Conditions (all/any/none groups)        │  │  │
│  │  │  ├─ Access fields (info.*, trackers.*, etc.)   │  │  │
│  │  │  ├─ Apply operators (==, >, contains, etc.)    │  │  │
│  │  │  └─ Combine with AND/OR/NOT logic             │  │  │
│  │  └────────────┬───────────────────────────────────┘  │  │
│  │               │                                       │  │
│  │               ├─ Match? ──► Execute Actions          │  │
│  │               │             (stop, categorize, etc.)  │  │
│  │               │                                       │  │
│  │               └─ No Match? ──► Next Rule             │  │
│  └──────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

Rules execute top-to-bottom. Use stop_on_match: true to prevent later rules from running after a match.


Core Concepts

Triggers

Trigger Description Use Case
manual Run on-demand via CLI Testing, one-time bulk operations
scheduled Run by cron/systemd timer Regular cleanup, maintenance
on_added Webhook when torrent added Auto-categorize new downloads
on_completed Webhook when download completes Post-processing, seeding rules

📖 Detailed Trigger Documentation

Conditions

Combine conditions with logical groups:

  • all - AND logic (all conditions must match)
  • any - OR logic (at least one condition must match)
  • none - NOT logic (no conditions can match)

Available Operators:

==, !=, >, <, >=, <=, contains, not_contains, matches, in, not_in, older_than, newer_than, smaller_than, larger_than

📖 Detailed Condition Documentation

Available Fields

Access torrent data using dot notation across 8 API categories:

Prefix Description Example Fields
info.* Main torrent info info.name, info.size, info.ratio, info.state
trackers.* Tracker data (collection) trackers.url, trackers.status, trackers.msg
files.* File list (collection) files.name, files.size, files.progress
properties.* Extended properties properties.save_path, properties.comment
transfer.* Global transfer stats transfer.dl_speed_global, transfer.up_speed_global
app.* Application info app.version, app.api_version
peers.* Peer data (collection) peers.ip, peers.client, peers.progress
webseeds.* Web seed data (collection) webseeds.url

📖 Complete Field Reference

Actions

Execute one or more actions when conditions match:

Action Description
stop / start / force_start Control torrent state
recheck / reannounce Maintenance operations
delete_torrent Remove torrent (optionally with files)
set_category Set torrent category
add_tag / remove_tag / set_tags Manage tags
set_upload_limit / set_download_limit Speed limiting

📖 Detailed Action Documentation


Example Rules

Auto-Categorize by Content Type

- name: "Categorize TV shows"
  enabled: true
  stop_on_match: true
  conditions:
    trigger: on_added
    all:
      - field: info.name
        operator: matches
        value: '(?i).*[Ss]\d{2}[Ee]\d{2}.*'
  actions:
    - type: set_category
      params:
        category: "TV-Shows"

Cleanup Old Completed Torrents

- name: "Delete old seeded torrents"
  enabled: true
  conditions:
    trigger: scheduled
    all:
      - field: info.state
        operator: in
        value: ["uploading", "pausedUP", "stalledUP"]
      - field: info.completion_on
        operator: older_than
        value: 2592000  # 30 days
      - field: info.ratio
        operator: ">="
        value: 2.0
  actions:
    - type: delete_torrent
      params:
        delete_files: false

Force Seed Low-Seeded Content

- name: "Force start underseded torrents"
  enabled: true
  conditions:
    trigger: scheduled
    all:
      - field: info.num_complete
        operator: "<="
        value: 2
      - field: info.state
        operator: in
        value: ["pausedUP", "stalledUP"]
  actions:
    - type: force_start

Pause Large Downloads

- name: "Pause very large downloads"
  enabled: true
  conditions:
    trigger: on_added
    all:
      - field: info.size
        operator: larger_than
        value: "50 GB"
      - field: info.state
        operator: in
        value: ["downloading", "metaDL"]
  actions:
    - type: stop
    - type: add_tag
      params:
        tag: "large-download"

📖 More Examples


Deployment

Scheduled Execution with Cron

# Run every hour
0 * * * * qbt-rules --trigger scheduled

# Run daily at 3 AM
0 3 * * * qbt-rules --trigger scheduled

# Custom trigger at midnight
0 0 * * * qbt-rules --trigger nightly_cleanup

Systemd Timer

Create /etc/systemd/system/qbt-rules.service:

[Unit]
Description=qbt-rules - qBittorrent Automation
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/qbt-rules --trigger scheduled
User=qbittorrent
Environment="PATH=/usr/local/bin:/usr/bin:/bin"

Create /etc/systemd/system/qbt-rules.timer:

[Unit]
Description=Run qbt-rules hourly

[Timer]
OnCalendar=hourly
Persistent=true

[Install]
WantedBy=timers.target

Enable:

sudo systemctl enable qbt-rules.timer
sudo systemctl start qbt-rules.timer

Docker

FROM python:3.11-slim

WORKDIR /app

# Install the package
RUN pip install qbt-rules

# Copy configuration files
COPY config/ /app/config/

# Run scheduled trigger every hour
CMD ["sh", "-c", "while true; do qbt-rules --trigger scheduled; sleep 3600; done"]

📖 Deployment Guide


Documentation

Complete documentation is available on the GitHub Wiki:


Requirements

  • Python 3.8+
  • qBittorrent v5.0+ with Web UI enabled
  • Dependencies: requests, pyyaml

Contributing

Contributions are welcome! Please see the Contributing Guide on the wiki.


Changelog

See CHANGELOG.md for version history and release notes.

Latest Release: v0.3.0 - 2024-12-13


License

This project is released into the public domain under the Unlicense.

You are free to use, modify, and distribute this software for any purpose without attribution.


Happy automating! 🚀

For detailed documentation, visit the GitHub Wiki.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qbt_rules-0.3.1.tar.gz (28.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qbt_rules-0.3.1-py3-none-any.whl (26.6 kB view details)

Uploaded Python 3

File details

Details for the file qbt_rules-0.3.1.tar.gz.

File metadata

  • Download URL: qbt_rules-0.3.1.tar.gz
  • Upload date:
  • Size: 28.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for qbt_rules-0.3.1.tar.gz
Algorithm Hash digest
SHA256 f23d61ff3231f986480e28f1ac15c2003a4961f57c1c5bc9586efd243aaa0712
MD5 f6f70ce74535b62e3c121b6d421b28c1
BLAKE2b-256 ecf3c6efb4768f2243405d66fb32c5c06064a7f34d842324f8c33a8b1e3c4f3c

See more details on using hashes here.

Provenance

The following attestation bundles were made for qbt_rules-0.3.1.tar.gz:

Publisher: release.yml on andronics/qbt-rules

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file qbt_rules-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: qbt_rules-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 26.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for qbt_rules-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0ab371f8e2f6bc4494a1a69f59d144aad6695f92bfd45337ca8a69788979828e
MD5 6b576f74c508294ef33ad048663ebd0f
BLAKE2b-256 b47aecb15eeac0ab4be192ab82bcad171926a5a53ae1caf5535fa165e7cb9f43

See more details on using hashes here.

Provenance

The following attestation bundles were made for qbt_rules-0.3.1-py3-none-any.whl:

Publisher: release.yml on andronics/qbt-rules

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page