Skip to main content

Python client to search and download torrents from nyaa.si

Project description

nyaa-downloader

Python package to search and download torrents from nyaa.si.

Documentation en Français

Installation

pip install nyaa-downloader

On Windows, libtorrent (for direct content download) is installed automatically via libtorrent-windows-dll.

Dependencies: requests, feedparser, anitopy, libtorrent (optional on non-Windows, for direct torrent content download)

Quick Start

from nyaa_downloader import NyaaAnime, Preferences

# Simple search
nyaa = NyaaAnime.search("Jujutsu Kaisen", trusted_only=True)

# Enrich with MAL metadata (seasons, episode counts)
nyaa.enrich_from_mal()

# Get a season
s2 = nyaa.season(2)

# Get episode 1 of season 2
ep1 = s2.get(1)
print(f"Title: {ep1.title}")
print(f"Seeders: {ep1.seeders}")

API Reference

NyaaAnime

Main interface for searching anime torrents.

NyaaAnime.search(title, trusted_only=False, category="1_2", max_pages=1, filters=None)

Search for an anime on Nyaa.

from nyaa_downloader import NyaaAnime, SearchFilters

# Basic search
nyaa = NyaaAnime.search("Sousou no Frieren")

# Search with advanced filters
filters = SearchFilters(
    min_seeders=50,
    resolution="1080p",
    exclude_batches=True
)
nyaa = NyaaAnime.search("Jujutsu Kaisen",
    trusted_only=True,
    max_pages=2,  # More results
    filters=filters
)
Parameter Type Description
title str Anime title
trusted_only bool Only trusted releases
category str Nyaa category (default: "1_2" = Anime English)
max_pages int Pages to fetch (1 ≈ 75 results)
filters SearchFilters Advanced filters

nyaa.enrich_from_mal(mal_id=None)

Enrich results with MyAnimeList metadata (seasons, episodes).

nyaa = NyaaAnime.search("Jujutsu Kaisen")
nyaa.enrich_from_mal()

print(f"MAL ID: {nyaa.mal_id}")
print(f"Total episodes: {nyaa.total_episodes}")
print(f"Season info: {nyaa._season_episodes_info}")
# Example: {1: (1, 24), 2: (25, 47)} → S1: eps 1-24, S2: eps 25-47

nyaa.season(season_number)

Returns results for a given season.

s1 = nyaa.season(1)
s2 = nyaa.season(2)

print(f"S1: {len(s1.episodes)} results")
print(f"S2: {len(s2.episodes)} results")

nyaa.seasons

Full mapping {season_number: SeasonResults}.

for season_num, season_results in nyaa.seasons.items():
    print(f"Season {season_num}: {len(season_results.episodes)} releases")

nyaa.to_relative_episode(absolute_ep, season) / nyaa.to_absolute_episode(relative_ep, season)

Convert between absolute and relative episode numbering.

# Jujutsu Kaisen S2 starts at episode 25
nyaa.to_relative_episode(25, 2)  # → 1 (S2E1)
nyaa.to_absolute_episode(1, 2)   # → 25

nyaa.download_torrent(result, dest_dir="torrents")

Download the .torrent file.

s2 = nyaa.season(2)
ep1 = s2.get(1)
path = nyaa.download_torrent(ep1, "my_torrents")

SeasonResults

Results for a given season.

season.get(episode_number, preferences=None)

Returns the best torrent for an episode.

from nyaa_downloader import Preferences

s2 = nyaa.season(2)

# Best by seeders
ep1 = s2.get(1)

# With preferences
prefs = Preferences(
    preferred_resolution="1080p",
    preferred_release_groups=["SubsPlease", "Erai-raws"],
    min_seeders=10
)
ep1 = s2.get(1, preferences=prefs)

NyaaSearcher

Low-level client for direct searching.

from nyaa_downloader import NyaaSearcher, SearchFilters

searcher = NyaaSearcher(timeout=60)

# Simple search
results = searcher.search("Frieren", trusted_only=True)

# Paginated search
for page_results in searcher.search_paginated("Jujutsu Kaisen", max_pages=3):
    print(f"Page: {len(page_results)} results")

# Full search
all_results = searcher.search_all("Oshi no ko", max_pages=5)

# With filters
filters = SearchFilters(
    min_seeders=100,
    resolution="1080p",
    exclude_batches=True
)
filtered = searcher.search("Frieren", filters=filters)

SearchFilters

Advanced search filters.

from nyaa_downloader import SearchFilters
from datetime import datetime

filters = SearchFilters(
    min_seeders=50,              # Minimum seeders
    max_seeders=None,            # Maximum seeders
    min_size_mb=100,             # Minimum size in MB
    max_size_mb=2000,            # Maximum size in MB
    trusted_only=True,           # Trusted only
    batches_only=False,          # Batches only
    exclude_batches=True,        # Exclude batches
    resolution="1080p",          # Preferred resolution
    release_group="SubsPlease",  # Release group
    date_after=datetime(2024, 1, 1),  # After this date
    date_before=None,            # Before this date
)

Preferences

Preferences for sorting results.

from nyaa_downloader import Preferences

prefs = Preferences(
    preferred_resolution="1080p",           # Preferred resolution
    preferred_release_groups=["SubsPlease"], # Preferred groups
    excluded_release_groups=["HorribleSubs"], # Excluded groups
    min_seeders=10,                         # Minimum seeders
    prefer_trusted=True,                    # Prefer trusted
)

# Score a result
score = prefs.score(result)  # Lower = better

# Sort a list
sorted_results = prefs.sort_results(results)

download_torrent(result, dest_dir, timeout=30, retry_config=None)

Download a .torrent file.

from nyaa_downloader import download_torrent, RetryConfig

# Simple
path = download_torrent(result, "torrents")

# With custom retry
config = RetryConfig(max_retries=5, base_delay=2.0)
path = download_torrent(result, "torrents", timeout=60, retry_config=config)

TorrentSession (optional, requires libtorrent)

Direct torrent content download.

from nyaa_downloader import TorrentSession, TorrentConfig, download_torrent_content

# Optimized configuration
config = TorrentConfig(
    connections_limit=300,
    cache_size=1024,  # 16MB cache
    sequential_download=True,  # For streaming
)

# Usage with context manager
with TorrentSession(config) as session:
    handle = session.add_torrent(magnet_link, save_path)

    def on_progress(progress):
        print(f"[{progress.state}] {progress.progress:.1f}% - "
              f"↓{progress.download_rate//1024}KB/s - "
              f"Peers: {progress.num_peers}")

    await session.wait_for_download(handle, on_progress)

# Or directly
await download_torrent_content(magnet_link, "downloads", config)

Exceptions

from nyaa_downloader import (
    NyaaError,       # Base exception
    NetworkError,    # Network error (timeout, connection)
    DownloadError,   # Download error
    ParseError,      # RSS parsing error
    RateLimitError,  # API rate limit
    RetryConfig,     # Retry configuration
)

try:
    results = searcher.search("anime")
except NetworkError as e:
    print(f"Network error: {e}")
except ParseError as e:
    print(f"Parse error: {e}")

CLI

# Basic search
nyaa-downloader "Sousou no Frieren"

# Trusted only, download best result
nyaa-downloader "Jujutsu Kaisen" --trusted-only --best

# Limit results
nyaa-downloader "Frieren" --limit 20

# Custom destination folder
nyaa-downloader "Oshi no ko" --dest ./my_torrents

Result Structure

NyaaResult

@dataclass
class NyaaResult:
    title: str                    # Full title
    link: str                     # .torrent URL
    magnet: Optional[str]         # Magnet link
    size: str                     # Size (e.g. "1.4 GiB")
    date: str                     # Publication date
    seeders: int                  # Seeder count
    leechers: int                 # Leecher count
    downloads: int                # Total downloads
    trusted: bool                 # Trusted release
    anime_title: Optional[str]    # Parsed anime title
    episode: Optional[str]        # Parsed episode number
    release_group: Optional[str]  # Group (e.g. "SubsPlease")
    resolution: Optional[str]     # Resolution (e.g. "1080p")
    source: Optional[str]         # Source (e.g. "WEB-DL")
    season: Optional[int]         # Detected season
    parsed_episode: ParsedEpisode # Parsed episode object
    is_batch: bool                # Is a batch

ParsedEpisode

@dataclass
class ParsedEpisode:
    episode: Optional[int]              # Single episode
    episode_range: Optional[Tuple[int, int]]  # Range (1, 12)
    is_batch: bool                      # Is a batch

    def contains(self, ep: int) -> bool  # Episode is in range
    def episodes(self) -> List[int]      # List of episodes
    def sort_key(self) -> Tuple[int, int]  # For sorting

Full Example

from nyaa_downloader import NyaaAnime, Preferences, SearchFilters

# Search with filters
filters = SearchFilters(min_seeders=100, resolution="1080p")
nyaa = NyaaAnime.search("Jujutsu Kaisen",
    trusted_only=True,
    max_pages=2,
    filters=filters
)

# Enrich with MAL
nyaa.enrich_from_mal()
print(f"Detected seasons: {list(nyaa.seasons.keys())}")

# Download preferences
prefs = Preferences(
    preferred_resolution="1080p",
    preferred_release_groups=["SubsPlease"],
)

# Download S2E1
s2 = nyaa.season(2)
ep1 = s2.get(1, preferences=prefs)

if ep1:
    print(f"Choice: {ep1.title}")
    print(f"Group: {ep1.release_group}")
    print(f"Resolution: {ep1.resolution}")
    print(f"Seeders: {ep1.seeders}")

    # Download
    path = nyaa.download_torrent(ep1, "torrents")
    print(f"Downloaded: {path}")

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

nyaa_downloader-1.0.1.tar.gz (24.7 kB view details)

Uploaded Source

Built Distribution

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

nyaa_downloader-1.0.1-py3-none-any.whl (26.8 kB view details)

Uploaded Python 3

File details

Details for the file nyaa_downloader-1.0.1.tar.gz.

File metadata

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

File hashes

Hashes for nyaa_downloader-1.0.1.tar.gz
Algorithm Hash digest
SHA256 542ffdeba86b83e2eddb40669dd2f00851d5b6ef35ea1e06c99928f7ad81f24e
MD5 15c5833da992c5d5eb4914fd2ef4efa0
BLAKE2b-256 913fe21f1626d66d8c96d5246448357c0100c5e5c94322a04e3a32a04fa2ada9

See more details on using hashes here.

Provenance

The following attestation bundles were made for nyaa_downloader-1.0.1.tar.gz:

Publisher: publish.yml on matth-blt/nyaa-downloader

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

File details

Details for the file nyaa_downloader-1.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for nyaa_downloader-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d8cc4ad95acfa86307a7cd81d61670766dee5fbae25a372d1ca51877dff8c2e0
MD5 c613ed1989417d394569b2aff1a7b0ab
BLAKE2b-256 62383f2e39c800277a81d0584632e87aefe6d57efa42fa2151aeb16b760659b0

See more details on using hashes here.

Provenance

The following attestation bundles were made for nyaa_downloader-1.0.1-py3-none-any.whl:

Publisher: publish.yml on matth-blt/nyaa-downloader

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