Skip to main content

Search torrents from multiple websites via the CLI

Project description

Torrent Hound

CI PyPI version Python versions License

A terminal-first torrent search CLI. Type a query, get ranked results from multiple trackers in one live table, then act on a row with a single keystroke — copy magnet, open page, send to your default torrent client, or hand off to Real-Debrid.

$ torrent-hound ubuntu

3 sources  ·  23 results  ·  0.92s  —  'ubuntu'
trail: TPB ✓ 10 (180ms)  ·  YTS ✓ 8 (420ms · 1 retry)  ·  EZTV ⚡ 5 cached 3m
selected: TPB · ubuntu-24.04.1-desktop-amd64.iso

┏━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━┳━━━━┳━━━━━━┓
┃ No ┃ Name                                                 ┃      Size ┃  S ┃  L ┃  S/L ┃
┡━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━╇━━━━╇━━━━━━┩
│ 1  │ ubuntu-24.04.1-desktop-amd64.iso                     │   5.8 GB  │ 40 │  2 │ 20.0 │ ← amber
│ 2  │ Ubuntu 22.04 LTS                                     │   3.4 GB  │ 32 │  1 │ 32.0 │
│ …  │                                                      │           │    │    │      │
└────┴──────────────────────────────────────────────────────┴───────────┴────┴────┴──────┘

Magnet copied to clipboard
↑↓ move · ⏎/c copy · cs seedr · o open page · d download · r repeat · rd real-debrid · s search · / filter · q quit

Sources

Source Content Method
The Pirate Bay General HTML scrape, mirror chain
YTS Movies JSON API, mirror chain
EZTV TV shows JSON API via IMDB lookup

All sources are searched in parallel. Each source has a multi-mirror fallback chain — if one mirror is down, the next is tried automatically. Results are cached for the session (5-minute TTL).

Requirements

  • Python 3.10+
  • Runtime dependencies: beautifulsoup4, requests, pyperclip, rich, platformdirs, tomli_w, argcomplete

Install

pipx install torrent-hound          # recommended — isolated venv, on PATH
pip install torrent-hound           # plain pip

Pre-built standalone binaries (no Python required) for Linux / macOS / Windows are on the Releases page.

From source:

git clone https://github.com/baddymaster/torrent-hound.git
cd torrent-hound
pip install -e ".[dev]"             # installs deps + pytest + ruff

Shell completion

Tab-completion is provided by argcomplete. Add one line to your shell config:

bash (~/.bashrc):

eval "$(torrent-hound --print-completion bash)"

zsh (~/.zshrc):

autoload -U compinit && compinit
eval "$(torrent-hound --print-completion zsh)"

Restart your shell, then torrent-hound --<TAB> cycles through flags.

Note: Completion only works when installed via pip / pipx. The standalone binary doesn't expose the Python entry point that argcomplete hooks into.

Usage

torrent-hound ubuntu

Drops you into a single-screen TUI. Three header rows, results table below, mode-aware footer of keystroke hints at the bottom.

Header

  • Top: rotating verb spinner (during fetch) → run summary (3 sources · 23 results · 0.92s — 'ubuntu') once results land.
  • Middle: trail: line — per-source pip with mirror retry detail and inline timing. Persists above the table after fetch completes:
    trail: TPB ✓ 10 (180ms) · YTS ✓ 8 (420ms · 1 retry) · EZTV ⚡ 5 cached 3m
    
  • Bottom: selected: <source> · <name> of the highlighted row.

Keystrokes

Navigation

Key Action
/ Move selection (table scrolls when selection goes off-screen)
? Show / hide the keystroke help overlay
q Quit

Acting on the highlighted row

Key Action
c / Copy magnet to clipboard
cs Copy magnet and open Seedr.cc
m Show the full magnet in an overlay panel (any key returns)
o Open the torrent page in your default browser
d Hand the magnet to your default torrent client
rd Real-Debrid: submit, fetch hoster links, dispatch via configured action

cs and rd are chord commands — press the prefix (c or r) and the footer shows the available extensions plus the standalone meaning. After ~1 second without a follow-up, the standalone meaning fires (so c alone copies, r alone repeats the last search).

Search & filter

Key Action
/ Enter live filter mode — type to narrow visible results, arrows still nav
s Enter new-search mode — type a new query, to fetch
r Repeat the current search (cached sources reused; failed sources retry)

In filter mode, accepts the filter and exits to the results table; Esc clears it.

Scripting mode

torrent-hound --json ubuntu | jq '.tpb.results["0"].magnet'
torrent-hound --quiet ubuntu                     # plain Python repr to stdout

Either flag bypasses the TUI entirely and exits after printing.

Real-Debrid integration

Send the highlighted torrent to Real-Debrid and hand the resulting direct link to your download manager.

Setup

torrent-hound --configure-rd

Prompts for your API token (get one at real-debrid.com/apitoken) and the action to run against returned direct links, then writes them to a config file with restrictive permissions (0600 on the file, 0700 on the parent).

For ad-hoc use without saving anything:

export RD_TOKEN="..."

Action modes

Mode What happens with the direct link(s)
clipboard (default) Copied to clipboard. Multiple links are joined with newlines.
print Printed to stdout.
browser Opened in your default browser (works without a separate download manager).
downie Sent to Downie 4 via its downie:// URL scheme (macOS).

Convenience flags

torrent-hound --configure-rd      # interactive setup (token + action)
torrent-hound --config-path       # print the resolved config file path
torrent-hound --user-status       # show RD account info (premium, expiration, points)
torrent-hound --revoke-rd-token   # invalidate the current token on RD

Config file

Path:

  • macOS: ~/Library/Application Support/torrent-hound/config.toml
  • Linux: ~/.config/torrent-hound/config.toml
  • Windows: %APPDATA%\torrent-hound\config.toml

Managed by --configure-rd, but plain TOML if you ever want to edit directly:

[real_debrid]
token  = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
action = "downie"

Usage

After a search, navigate to a row, press rd. The flow submits the torrent to RD, waits for hoster links, and runs your configured action. Multi-file torrents drop into an interactive picker on first invocation.

If RD is still processing (common for larger uncached torrents), you'll see a "run again in a moment" message — re-running rd picks up where it left off without re-prompting the picker.

Troubleshooting

  • Real-Debrid rejected the token — run torrent-hound --configure-rd.
  • Connectivity errors (DNS lookup failed, block page, geo-block) — your ISP / network / proxy is filtering the RD API. Try a VPN or DoH resolver (1.1.1.1, 8.8.8.8).
  • Anything else — torrent-hound --user-status to check account state. Specific error messages reference RD's documented error_code values.

Development

pip install -e ".[dev]"
pytest tests/
ruff check .

Tests run fully offline — parser fixtures are captured HTML, network calls are mocked. The TUI is unit-tested at the read_key and handle_key layers (see tests/test_tui.py); the rich.live event loop is manual-tested only.

Package layout

torrent_hound/
  cli.py         — argparse + main() entry point
  tui.py         — rich.live TUI (single-screen app)
  state.py       — shared mutable state (results, urls, should_exit)
  cache.py       — per-session result cache
  config.py      — TOML config + Real-Debrid setup commands
  realdebrid.py  — RD API client + the rd flow
  ui.py          — rich Console singleton + table builders + JSON output
  sources/
    __init__.py  — _SOURCES registry + searchAllSites orchestrator
    base.py      — Source Protocol + shared helpers
    tpb.py       — The Pirate Bay
    yts.py       — YTS
    eztv.py      — EZTV
    legacy_1337x.py — dormant; kept for re-enable when CF landscape changes

Adding a source

  1. Create torrent_hound/sources/foo.py — implement searchFoo(search_string, quiet_mode, limit, timeout, progress) returning a list of result dicts with keys name, link, seeders, leechers, size, ratio, magnet. Call progress({"type": "mirror_attempt", "mirror": ...}) etc. so the trail line lights up.
  2. Register in sources/__init__.py._SOURCES.
  3. Add a parser test in tests/test_foo_parser.py.

Troubleshooting

  • SSL handshake errors: see these Stack Overflow answers for common fixes.
  • [PirateBay] Error : All known mirrors returned no results or were unreachable: every TPB domain in the fallback chain is blocked or down. Add a known-working mirror to TPB_DOMAINS in torrent_hound/sources/tpb.py.
  • Blocked by Cloudflare captcha: some sources serve a CF challenge that requires a real browser. 1337x is currently dormant for this reason.
  • Arrow keys not working / ESC press doesn't cancel filter: your terminal may be delivering escape sequences slowly. The TUI probes for 50ms after \x1b to distinguish bare ESC from arrow keys; if your terminal is slower than that, bump _ESC_PROBE_SECONDS at the top of torrent_hound/tui.py.

Disclaimer

This software is provided as-is, with no warranty of any kind. It is intended for discovering legally-distributable content and is not intended to be used for downloading, distributing, or facilitating access to copyrighted material without authorisation. You are responsible for complying with the laws of your jurisdiction.

License

AGPL-3.0 — see LICENSE.

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

torrent_hound-3.0.2.tar.gz (111.9 kB view details)

Uploaded Source

Built Distribution

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

torrent_hound-3.0.2-py3-none-any.whl (60.6 kB view details)

Uploaded Python 3

File details

Details for the file torrent_hound-3.0.2.tar.gz.

File metadata

  • Download URL: torrent_hound-3.0.2.tar.gz
  • Upload date:
  • Size: 111.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for torrent_hound-3.0.2.tar.gz
Algorithm Hash digest
SHA256 89d88ef2a29627bfe0cc609a844e4bf8985d7e0ab886c3cacc0a97087eda33a3
MD5 09d975af70c5c8f6ad13fa341056c856
BLAKE2b-256 55f42b552d509a561a5a051b8a844a92167a706e1e1bcbd93129044aea1c67e0

See more details on using hashes here.

Provenance

The following attestation bundles were made for torrent_hound-3.0.2.tar.gz:

Publisher: publish.yml on baddymaster/torrent-hound

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

File details

Details for the file torrent_hound-3.0.2-py3-none-any.whl.

File metadata

  • Download URL: torrent_hound-3.0.2-py3-none-any.whl
  • Upload date:
  • Size: 60.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for torrent_hound-3.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7517e989971a524f11c9ffa5f920cff9c7f11c9fc0ff5fb5be56f38ad47f71dc
MD5 8b5c8a6da6cd2b97079bd0e7063621b8
BLAKE2b-256 e2b798c1dd0084a4eb26006950a40ee4c81c2ad14bdfe907aa58c54d850983e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for torrent_hound-3.0.2-py3-none-any.whl:

Publisher: publish.yml on baddymaster/torrent-hound

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