Skip to main content

qbittorrent-orphaned banner

PyPI version License: GPL-3.0 Python 3.8+ requests


qbittorrent-orphaned is a lightweight utility that identifies orphaned files -- files that exist on disk but are not tracked by any torrent in your qBittorrent instance. It connects to the qBittorrent Web API v2, walks the directories you configure, cross-references every file against every torrent, and reports what does not belong.

What Are Orphaned Files?

When you remove a torrent from qBittorrent but keep the data on disk, or when external tools (transcoders, renaming scripts, etc.) create files that were never part of a torrent, those files become orphans. They consume storage without being seeded or managed. This tool finds them so you can decide what to keep and what to reclaim.

Features

  • Single-file, pure Python -- no build step, no complex dependencies, just requests.
  • Web API v2 -- authenticates and queries qBittorrent over HTTP; works locally or across a network.
  • Case-insensitive matching -- handles mixed-case filenames on Windows and Linux alike.
  • Category-aware grouping -- results are organized by qBittorrent category, with uncategorized torrents collected under __UNCATEGORIZED__.
  • Human-readable sizes -- every orphan is printed alongside its size in KiB, MiB, GiB, etc.
  • Configurable metadata ignore list -- common metadata files (.nfo, .jpg, .png, .srt, .sub, .idx, .txt, .bin, .svg) are skipped by default. You can extend this list.
  • Exclude patterns -- filter out known non-torrent files (e.g., transcoded 720p copies) by substring match.
  • macOS-safe -- automatically skips ._ resource fork files.

Quick Start

Install from PyPI

pip install qbittorrent-orphaned

Standalone

QBIT_HOST=http://localhost:8080 \
QBIT_USER=admin \
QBIT_PASS=yourpassword \
CATEGORY_FOLDERS="Films=/mnt/media/films;Shows=/mnt/media/shows" \
qbittorrent-orphaned

You can also run the script directly without installing:

pip install requests

QBIT_HOST=http://localhost:8080 \
QBIT_USER=admin \
QBIT_PASS=yourpassword \
CATEGORY_FOLDERS="Films=/mnt/media/films;Shows=/mnt/media/shows" \
python orphan_detector.py

Docker

There is no pre-built image yet, but you can run it easily with a one-liner:

docker run --rm \
  -e QBIT_HOST=http://qbittorrent:8080 \
  -e QBIT_USER=admin \
  -e QBIT_PASS=yourpassword \
  -e CATEGORY_FOLDERS="Films=/media/films;Shows=/media/shows" \
  -v /mnt/media:/media:ro \
  --network=host \
  python:3-alpine sh -c "pip install --quiet requests && python /app/orphan_detector.py"

Mount the script into the container if you prefer a cleaner approach:

docker run --rm \
  -v "$(pwd)/orphan_detector.py:/app/orphan_detector.py:ro" \
  -v /mnt/media:/media:ro \
  -e QBIT_HOST=http://qbittorrent:8080 \
  -e QBIT_USER=admin \
  -e QBIT_PASS=yourpassword \
  -e CATEGORY_FOLDERS="Films=/media/films;Shows=/media/shows" \
  python:3-alpine sh -c "pip install --quiet requests && python /app/orphan_detector.py"

Tip: If qBittorrent runs in its own container, make sure both containers share a Docker network (or use --network=host) so the hostname resolves.

Configuration

All configuration is done through environment variables.

Variable Default Description
QBIT_HOST http://qbittorrent:8080 qBittorrent Web UI URL
QBIT_USER admin Username for Web UI authentication
QBIT_PASS password Password for Web UI authentication
CATEGORY_FOLDERS Films=W:\Films;Shows=X:\Series Semicolon-separated Category=Path pairs. Categories must match those configured in qBittorrent.
EXCLUDE_PATTERNS (empty) Comma-separated substrings. Any file whose relative path contains one of these patterns (case-insensitive) is skipped.
IGNORE_SUFFIXES (empty) Comma-separated file extensions to ignore in addition to the built-in list. Leading dots are optional (e.g., ass,ssa or .ass,.ssa).

Category Folders Format

CATEGORY_NAME=ABSOLUTE_PATH;CATEGORY_NAME2=ABSOLUTE_PATH2

Each category name must match exactly what is configured in qBittorrent. Torrents with no category are grouped under the key __UNCATEGORIZED__.

Example Output

===== Films =====
/mnt/media/films/Some.Movie.2023/Some.Movie.2023.mkv    (4,215 MiB)
/mnt/media/films/Old.Film.1999/Old.Film.1999.avi        (702 MiB)

===== Shows =====
/mnt/media/shows/Series.Name.S01/Episode.05.mkv          (1,102 MiB)

When no orphans are found the output is simply:

No orphaned files found.

How It Works

  1. Authenticate -- the script logs in to qBittorrent via /api/v2/auth/login and obtains a session cookie.
  2. Fetch torrents -- it retrieves the full torrent list from /api/v2/torrents/info, then for each torrent calls /api/v2/torrents/files to get every file path the torrent manages.
  3. Index by category -- all torrent file paths are normalized (forward slashes, lowercase) and grouped into a lookup set per category.
  4. Walk the filesystem -- for each configured category folder, the script recursively enumerates files, skipping ignored suffixes, macOS resource forks, and exclude-pattern matches.
  5. Cross-reference -- every disk file is checked against the corresponding category set. Files not present in any torrent are reported as orphans with their absolute path and human-readable size.

License

GPL-3.0

Download files

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

Source Distribution

qbittorrent_orphaned-1.0.0.tar.gz (18.9 kB view details)

Uploaded Source

Built Distribution

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

qbittorrent_orphaned-1.0.0-py3-none-any.whl (19.5 kB view details)

Uploaded Python 3

File details

Details for the file qbittorrent_orphaned-1.0.0.tar.gz.

File metadata

  • Download URL: qbittorrent_orphaned-1.0.0.tar.gz
  • Upload date:
  • Size: 18.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for qbittorrent_orphaned-1.0.0.tar.gz
Algorithm Hash digest
SHA256 5d66ca7e10347d0425bcef1cca426d37507f0cc6f98b21af4f3d8f3be008f9a4
MD5 4c3a25f814228ced749464195692c279
BLAKE2b-256 1c73dea0b21d5ea80fa4125e70b9832183d65318049a4384400f80b910d0944b

See more details on using hashes here.

File details

Details for the file qbittorrent_orphaned-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for qbittorrent_orphaned-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 03f03d2c1a2bae915f64abcf1c60354415a438baef2d4805927c6d36217c5bb8
MD5 7929dbbe0a51d631734a0ba76073199a
BLAKE2b-256 aa9e588cde538091282efe492af7ebb589e683701e85d66cdaebceb6c902d81d

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

Supported by

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