nyaa-downloader
Python package to search and download torrents from nyaa.si.
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}")
Metadata
Release files for nyaa-downloader 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| nyaa_downloader-1.0.1.tar.gz | 24.7 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nyaa_downloader-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 51.5 kB
Release files / nyaa_downloader-1.0.1.tar.gz
| Download URL | nyaa_downloader-1.0.1.tar.gz |
|---|---|
| Size | 24.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
542ffdeba86b83e2eddb40669dd2f00851d5b6ef35ea1e06c99928f7ad81f24e
|
|
BLAKE2b-256 checksum How to use checksums |
913fe21f1626d66d8c96d5246448357c0100c5e5c94322a04e3a32a04fa2ada9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 19, 2026.
Transparency logRelease files / nyaa_downloader-1.0.1-py3-none-any.whl
| Download URL | nyaa_downloader-1.0.1-py3-none-any.whl |
|---|---|
| Size | 26.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d8cc4ad95acfa86307a7cd81d61670766dee5fbae25a372d1ca51877dff8c2e0
|
|
BLAKE2b-256 checksum How to use checksums |
62383f2e39c800277a81d0584632e87aefe6d57efa42fa2151aeb16b760659b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 19, 2026.
Transparency logSecurity for nyaa-downloader 1.0.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for nyaa_downloader-1.0.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 19, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.