-
Notifications
You must be signed in to change notification settings - Fork 0
Frequently Asked Questions
Q: What is qbt-rules?
A: qbt-rules is a Python-based rules engine that automates torrent management tasks through the qBittorrent Web API. It allows you to define YAML-based rules that automatically categorize, tag, pause, resume, delete, and manage torrents based on conditions you specify.
Q: Why not use qBittorrent's built-in RSS automation?
A: qBittorrent's RSS automation only works for adding new torrents based on RSS feeds. This system provides:
- Management of existing torrents based on conditions
- Multiple trigger types (manual, scheduled, webhooks)
- Complex condition logic (AND/OR/NOT groups)
- Access to all torrent fields and metadata
- Idempotent actions that won't repeat unnecessarily
- Dry-run mode for safe testing
Q: Does this work with qBittorrent v4.x?
A: This system is designed for qBittorrent Web API v5.0+ which introduced breaking changes (e.g., pause→stop, resume→start). If you're using qBittorrent v4.x, you'll need to modify the API client to use the old endpoint names.
Q: Is this safe to run on my existing torrents?
A: Yes! The system has several safety features:
-
Dry-run mode (
--dry-run) shows what would happen without making changes - Idempotent actions skip if torrent already in desired state
- File-order execution allows predictable rule evaluation
- Comprehensive logging with trace mode for debugging
- stop_on_match prevents multiple rules from affecting the same torrent
Q: Can I run this on Windows?
A: Yes! The system is Python-based and works on Windows, Linux, and macOS. You'll need Python 3.8+ and can install via:
pip install qbt-rulesQ: Where should I put my config files?
A: By default, the system looks for:
-
~/.config/qbt-rules/config.yml- Connection and global settings -
~/.config/qbt-rules/rules.yml- Your automation rules
You can override the config directory with --config-dir /path/to/config.
Q: How do I use environment variables in config files?
A: Use ${VARIABLE_NAME} syntax:
qbittorrent:
username: ${QB_USERNAME}
password: ${QB_PASSWORD}The system expands these at runtime using os.environ.
Q: Can I have multiple rule files?
A: Currently, the system loads a single rules file. However, you can organize rules within the file using YAML comments and logical grouping:
# ===== Content Organization =====
- name: "Categorize movies"
# ...
# ===== Cleanup =====
- name: "Remove old torrents"
# ...Q: What happens if qBittorrent is unreachable?
A: The system will raise a ConnectionError and exit. For scheduled triggers, ensure you have proper error handling in your cron job or systemd timer.
Q: How do I enable trace logging?
A: Use the --trace flag:
qbt-rules --traceThis logs all API calls, field accesses, and condition evaluations.
Q: How do I know what fields are available?
A: See the Available Fields section (§7) for complete tables. You can also:
- Enable
--tracemode to see all field accesses - Check qBittorrent Web API documentation
- Use
/api/v2/torrents/infoto see raw torrent data
Q: What's the difference between info.size and info.total_size?
A:
-
info.size- Total size of the torrent (all files) -
info.total_size- Same asinfo.size(alias in qBittorrent API)
Both return the same value in bytes.
Q: Why is my files.* condition not working?
A: files.* is a collection field - it returns a list. Operators check if ANY item in the list matches:
# This checks if ANY file name contains "sample"
- field: files.name
operator: contains
value: "sample"If you need to check ALL files, use a none condition with the inverse:
# This ensures NO file is larger than 1GB
conditions:
none:
- field: files.size
operator: ">"
value: 1073741824Q: How do I check if a torrent has NO tags?
A: Check if the tags string is empty:
conditions:
all:
- field: info.tags
operator: "=="
value: ""Q: Can I use regex in conditions?
A: Yes! Use the matches operator:
- field: info.name
operator: matches
value: '(?i).*[Ss]\d{2}[Ee]\d{2}.*' # TV show patternUse (?i) for case-insensitive matching.
Q: How do older_than and newer_than work?
A: These operators compare Unix timestamps against a relative time in seconds:
# Torrents added more than 7 days ago
- field: info.added_on
operator: older_than
value: 604800 # 7 days in seconds
# Torrents completed less than 24 hours ago
- field: info.completion_on
operator: newer_than
value: 86400 # 24 hours in secondsQ: What does info.state return?
A: The current state string, one of:
-
downloading- Actively downloading -
uploading- Actively seeding -
pausedDL- Paused while incomplete -
pausedUP- Paused after completion -
stalledDL- No download progress -
stalledUP- No upload activity -
checkingUP- Checking files after completion -
checkingDL- Checking files while incomplete -
error- Torrent has errors -
missingFiles- Files missing on disk -
forcedUP- Force seeding -
forcedDL- Force downloading
Q: How often do scheduled triggers run?
A: You control the schedule using cron or systemd timers:
# Every hour
0 * * * * qbt-rules --trigger scheduled
# Every day at 3 AM
0 3 * * * qbt-rules --trigger scheduled
# Every Monday at 9 AM
0 9 * * 1 qbt-rules --trigger scheduledQ: Can I test scheduled rules without waiting?
A: Yes! Use manual trigger with dry-run:
qbt-rules --dry-runThis evaluates all enabled rules immediately.
Q: How do webhooks work?
A: Configure qBittorrent to execute qbt-rules when torrents are added or completed:
- Open qBittorrent → Tools → Options → Downloads
- Set "Run external program on torrent added":
qbt-rules --trigger on_added --hash "%I"- Set "Run external program on torrent completion":
qbt-rules --trigger on_completed --hash "%I"- Rules with
trigger: on_addedortrigger: on_completedwill be evaluated for the specific torrent
Q: Can I filter which torrents a trigger processes?
A: Yes! Use the filter section in trigger conditions:
conditions:
trigger: manual
filter:
category: "Movies" # Only process Movies category
state: "downloading" # Only downloading torrents
all:
- field: info.ratio
operator: "<"
value: 1.0Q: What's the difference between manual and scheduled triggers?
A: Both process all torrents, but differ in how rules filter them:
-
manual (default) - Run on-demand via
qbt-rules(useful for testing or one-time bulk operations) -
scheduled - Run via
qbt-rules --trigger scheduledfrom cron/systemd timer (designed for automated maintenance)
Rules can specify which trigger types they respond to using trigger: manual or trigger: scheduled in conditions.
Q: Will stop action pause a torrent that's already paused?
A: No - actions are idempotent. The system checks the current state:
if torrent["state"] in ["pausedUP", "pausedDL"]:
logger.info(f"Torrent already stopped, skipping")
returnQ: What's the difference between start and force_start?
A:
- start - Resume normal downloading/seeding (respects queue limits)
- force_start - Force the torrent to start regardless of queue limits (useful for private trackers or low-seeded content)
Q: Does delete_torrent remove files from disk?
A: Only if you specify delete_files: true:
actions:
- type: delete_torrent
params:
delete_files: true # Remove from diskIf false or omitted, only removes from qBittorrent (files stay on disk).
Q: Can I set multiple tags at once?
A: Yes! Use set_tags:
actions:
- type: set_tags
params:
tags: "movies,hd,private"This replaces all existing tags. To add tags while keeping existing ones, use add_tag.
Q: How do I remove all tags?
A: Use set_tags with an empty string:
actions:
- type: set_tags
params:
tags: ""Q: What does limit: -1 mean for upload/download limits?
A: -1 means unlimited (removes any speed limit).
Q: Can I run multiple actions for the same torrent?
A: Yes! Actions execute in order:
actions:
- type: set_category
params:
category: "Movies"
- type: add_tag
params:
tag: "auto-categorized"
- type: stopAll three actions will execute if conditions match.
Q: How many API calls does the system make?
A: The system optimizes API calls through caching:
Per-Trigger API Calls:
- Initial torrent list fetch (1 call)
- Per-torrent metadata fetches (only if fields accessed):
-
trackers.*→/api/v2/torrents/trackers(1 call per torrent) -
files.*→/api/v2/torrents/files(1 call per torrent) -
properties.*→/api/v2/torrents/properties(1 call per torrent) -
peers.*→/api/v2/sync/torrentPeers(1 call per torrent) -
webseeds.*→/api/v2/torrents/webseeds(1 call per torrent)
-
Example: If you have 100 torrents and rules only check info.* fields, that's 1 API call total. If rules also check trackers.url, that's 1 + 100 = 101 calls.
Q: How can I reduce API calls?
A: Optimize your rules:
- Use filters to limit torrents processed:
conditions:
filter:
category: "Movies" # Only fetch Movies category-
Avoid expensive fields if possible:
-
info.*- Free (included in main list) -
trackers.*,files.*,properties.*- Expensive (1 call per torrent)
-
-
Use
stop_on_match: trueto prevent redundant rule evaluation:
- name: "First matching rule"
stop_on_match: trueQ: Can I run this on a system with 10,000+ torrents?
A: Yes, but optimize carefully:
- Use aggressive filtering:
filter:
state: "downloading" # Process only active torrents-
Avoid expensive fields in high-frequency rules
-
Run scheduled triggers less frequently (every 6-12 hours instead of hourly)
-
Consider breaking rules into multiple files run at different intervals
Q: How long does execution take?
A: Depends on:
- Number of torrents
- Number of rules
- Fields accessed
- Network latency to qBittorrent
Typical performance:
- 100 torrents, simple rules (info.* only): < 1 second
- 100 torrents, complex rules (all fields): 5-10 seconds
- 1000 torrents, simple rules: 2-5 seconds
- 1000 torrents, complex rules: 30-60 seconds
Use --trace to see timing breakdowns.
Q: I'm getting 401 Unauthorized errors
A: Check your credentials in config/config.yml:
qbittorrent:
username: "admin"
password: "your_password"Also verify qBittorrent Web UI authentication is enabled.
Q: Rules aren't matching torrents I expect
A: Enable --trace mode to see condition evaluation:
qbt-rules --traceLook for lines like:
[TRACE] Evaluating condition: info.ratio >= 2.0
[TRACE] Result: False (actual value: 1.5)
Q: Getting KeyError when accessing fields
A: Not all fields exist for all torrents. The system handles missing fields gracefully:
# If field doesn't exist, comparison returns FalseCheck that you're using correct field names from the Available Fields table.
Q: scheduled trigger isn't running
A: Scheduled triggers don't run automatically - you need to set up cron or systemd timer:
Cron example:
0 * * * * qbt-rules --trigger scheduled >> /var/log/qbt-rules.log 2>&1Q: Webhooks aren't triggering
A: Verify qBittorrent webhook configuration:
- Check qBittorrent logs for errors
- Ensure
qbt-rulesis in PATH or use absolute path:
/usr/local/bin/qbt-rules --trigger on_added --hash "%I"- Test manually:
qbt-rules --trigger on_added --hash <actual_torrent_hash>Q: Changes aren't applying to torrents
A: Check:
-
Dry-run mode: Are you using
--dry-run? Remove it to apply changes. - Idempotency: Action may be skipped if torrent already in desired state (check logs)
-
Conditions: Rule may not be matching (use
--trace) - stop_on_match: Earlier rule may have matched first
Q: Can I run this in Docker?
A: Yes! Example Dockerfile:
FROM python:3.11-slim
# Install qbt-rules
RUN pip install qbt-rules
# Copy config
COPY config/ /root/.config/qbt-rules/
# Run scheduled trigger every hour
CMD ["sh", "-c", "while true; do qbt-rules --trigger scheduled; sleep 3600; done"]Q: How do I deploy with systemd?
A: Create a service file and timer:
/etc/systemd/system/qbt-rules.service:
[Unit]
Description=qBittorrent Rules Automation
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/qbt-rules --trigger scheduled
User=qbittorrent
Environment="HOME=/home/qbittorrent"/etc/systemd/system/qbt-rules.timer:
[Unit]
Description=Run qBittorrent Rules hourly
[Timer]
OnCalendar=hourly
Persistent=true
[Install]
WantedBy=timers.targetEnable and start:
sudo systemctl enable qbt-rules.timer
sudo systemctl start qbt-rules.timerQ: Can I run multiple instances?
A: Yes, but ensure they don't conflict:
- Use different config directories:
qbt-rules --config-dir /config/cleanup
qbt-rules --config-dir /config/categorization- Or use different trigger types (manual, scheduled, webhooks) simultaneously
Q: How do I integrate with Sonarr/Radarr?
A: Configure qBittorrent webhooks to auto-categorize/tag torrents added by Sonarr/Radarr:
- In qBittorrent → Tools → Options → Downloads
- Set "Run external program on torrent added":
qbt-rules --trigger on_added --hash "%I"- Create rules with
trigger: on_addedthat match naming patterns:
- name: "Auto-categorize Sonarr downloads"
conditions:
trigger: on_added
all:
- field: info.category
operator: "=="
value: "tv-sonarr"
actions:
- type: add_tag
params:
tags: ["sonarr", "tv"]qbt-rules v0.3.0 | Python-based rules engine for qBittorrent automation
GitHub • PyPI • Issues • Discussions • Contributing • License
Requirements: Python 3.8+ • qBittorrent 5.0+
Made with ❤️ by the qbt-rules community | Licensed under MIT
v0.3.0 | GitHub
- ✅ Unified CLI (
qbt-rules) - ✅ Custom triggers
- ✅ Trigger-agnostic mode
- ✅ Size operators (
50GB)