Skip to main content

animesubinfo

Python client for searching and downloading anime subtitles from AnimeSub.info.

Installation

pip install animesubinfo

Or with uv:

uv add animesubinfo

Quick Start

All main functions, types, and exceptions can be imported directly from animesubinfo:

from animesubinfo import (
    search,
    find_subtitles,
    find_best_subtitles,
    download_subtitles,
    download_and_extract_subtitle,
    set_default_concurrency,
    ExtractedSubtitle,
    SubtitleCache,
    SortBy,
    TitleType,
    Subtitles,
    SecurityError,
    SessionDataError,
)

Search for subtitles

import asyncio
from animesubinfo import search, SortBy, TitleType

async def main():
    # Simple search
    async for subtitle in search("Naruto"):
        print(f"{subtitle.original_title} - Episode {subtitle.episode}")
        print(f"  Author: {subtitle.author}")
        print(f"  Downloads: {subtitle.downloaded_times}")
        print()

    # Advanced search with filters
    async for subtitle in search(
        "Attack on Titan",
        sort_by=SortBy.DOWNLOADS,
        title_type=TitleType.ENGLISH,
        page_limit=2
    ):
        print(f"{subtitle.english_title} - Episode {subtitle.episode}")

asyncio.run(main())

Find best match for your file

import asyncio
from animesubinfo import find_best_subtitles

async def main():
    # Automatically finds the best subtitle match
    filename = "[HorribleSubs] Attack on Titan - 12 [BD 1080p].mkv"

    subtitle = await find_best_subtitles(filename)

    if subtitle:
        print(f"Best match: {subtitle.original_title}")
        print(f"Episode: {subtitle.episode}")
        print(f"Author: {subtitle.author}")
        print(f"Fitness score: {subtitle.calculate_fitness(filename)}")

asyncio.run(main())

Find all ranked matches for your file

import asyncio
from animesubinfo import find_subtitles

async def main():
    filename = "[HorribleSubs] Attack on Titan - 12 [BD 1080p].mkv"

    # Compatible results are ordered by fitness, then by newest upload.
    for subtitle in await find_subtitles(filename):
        print(subtitle.author, subtitle.added_by, subtitle.date)

asyncio.run(main())

Batch processing with cache

When processing multiple files from the same anime, use SubtitleCache to avoid redundant network requests:

import asyncio
from animesubinfo import find_best_subtitles, download_and_extract_subtitle, SubtitleCache

async def main():
    files = [
        "[HorribleSubs] Attack on Titan - 01 [1080p].mkv",
        "[HorribleSubs] Attack on Titan - 02 [1080p].mkv",
        "[HorribleSubs] Attack on Titan - 03 [1080p].mkv",
    ]

    # Shared cache - searches once per title, reuses results for all episodes
    cache = SubtitleCache()

    for filename in files:
        subtitle = await find_best_subtitles(filename, cache=cache)
        if subtitle:
            extracted = await download_and_extract_subtitle(filename, subtitle.id)
            print(f"{filename} -> {extracted.filename}")

asyncio.run(main())

The cache is keyed by (normalized_title, year, season), so all episodes of the same anime share cached search results.

Download subtitles

import asyncio
from animesubinfo import find_best_subtitles, download_subtitles, SecurityError, SessionDataError

async def main():
    filename = "[HorribleSubs] Attack on Titan - 12 [BD 1080p].mkv"

    # Find best match
    subtitle = await find_best_subtitles(filename)

    if subtitle:
        try:
            # Download the subtitle file
            async with download_subtitles(subtitle.id) as download:
                print(f"Downloading: {download.filename}")
                print(f"Size: {download.content_length} bytes")

                # Save to disk
                with open(download.filename, 'wb') as f:
                    async for chunk in download.content:
                        f.write(chunk)

                print("Download complete!")

        except SessionDataError as e:
            print(f"Failed to get session data: {e}")

        except SecurityError as e:
            print(f"Security error: {e}")
            print(f"Debug info - sh: {e.sh}, cookie: {e.cookie}")

asyncio.run(main())

Download and extract subtitle automatically

import asyncio
from animesubinfo import find_best_subtitles, download_and_extract_subtitle

async def main():
    filename = "[HorribleSubs] Attack on Titan - 12 [BD 1080p].mkv"

    # Find best match
    subtitle = await find_best_subtitles(filename)

    if subtitle:
        # Download ZIP and extract the best matching file
        extracted = await download_and_extract_subtitle(filename, subtitle.id)

        print(f"Extracted: {extracted.filename}")
        print(f"Size: {len(extracted.content)} bytes")

        # Save to disk
        with open(extracted.filename, 'wb') as f:
            f.write(extracted.content)

        print("Subtitle saved!")

asyncio.run(main())

This function automatically:

  • Downloads the subtitle ZIP archive
  • Extracts it in memory (no temp files)
  • Selects the best matching file based on episode number and metadata
  • Falls back to the first file if no matches are found

API Reference

search(phrase, *, sort_by=None, title_type=None, page_limit=None, semaphore=None)

Search for subtitles on AnimeSub.info.

Parameters:

  • phrase (str): Search query
  • sort_by (SortBy, optional): Sort order (FITNESS, DOWNLOADS, ADDED_DATE, etc.)
  • title_type (TitleType, optional): Search in ORIGINAL, ENGLISH, or ALTERNATIVE titles
  • page_limit (int, optional): Maximum number of pages to fetch
  • semaphore (asyncio.Semaphore, optional): Semaphore for limiting concurrent requests (default: 3 concurrent)

Yields:

  • Subtitles: Individual subtitle results

find_best_subtitles(filename_or_dict, *, normalizer=None, semaphore=None, cache=None)

Find the best matching subtitles for an anime file.

Parameters:

  • filename_or_dict (str | dict): Anime filename or anitopy-parsed dict
  • normalizer (callable, optional): Custom normalization function
  • semaphore (asyncio.Semaphore, optional): Semaphore for limiting concurrent requests (default: 3 concurrent)
  • cache (SubtitleCache, optional): Cache for storing/retrieving search results by title. Enables efficient batch processing without repeated network requests.

Returns:

  • Subtitles | None: Best matching subtitle or None if not found

find_subtitles(filename_or_dict, *, normalizer=None, semaphore=None, cache=None)

Find all compatible subtitles for an anime file, ordered by descending fitness score and then by newest upload date.

Parameters:

  • filename_or_dict (str | dict): Anime filename or anitopy-parsed dict
  • normalizer (callable, optional): Custom normalization function
  • semaphore (asyncio.Semaphore, optional): Semaphore for limiting concurrent requests
  • cache (SubtitleCache, optional): Shared title search cache

Returns:

  • list[Subtitles]: Ranked compatible subtitle matches

set_default_concurrency(limit)

Set the default concurrency limit for network requests.

Parameters:

  • limit (int): Maximum number of concurrent requests (must be >= 1)

download_subtitles(subtitle_id, *, semaphore=None)

Download subtitles as a ZIP file (async context manager).

Parameters:

  • subtitle_id (int): The ID of the subtitle to download
  • semaphore (asyncio.Semaphore, optional): Semaphore for limiting concurrent requests (default: shared)

Yields:

  • DownloadResult: Named tuple with filename, content (async iterable), and content_length

Raises:

  • SessionDataError: If session data cannot be obtained for the subtitle
  • SecurityError: If AnimeSub.info returns a security error (HTML instead of ZIP). This typically happens when session tokens are invalid or expired. The exception includes sh and cookie attributes for debugging.

download_and_extract_subtitle(filename_or_dict, subtitle_id, *, normalizer=None, semaphore=None)

Download subtitle ZIP and automatically extract the best matching file.

Parameters:

  • filename_or_dict (str | dict): Target filename or anitopy-parsed dict to match against
  • subtitle_id (int): The ID of the subtitle to download
  • normalizer (callable, optional): Custom normalization function
  • semaphore (asyncio.Semaphore, optional): Semaphore for limiting concurrent requests (default: shared)

Returns:

  • ExtractedSubtitle: Named tuple with filename (str) and content (bytes)

Raises:

  • SessionDataError: If session data cannot be obtained
  • SecurityError: If AnimeSub.info returns a security error
  • ValueError: Only if the archive is completely empty

Behavior:

  • For single-file archives: Returns that file
  • For multi-file archives: Calculates fitness score based on:
    • Episode number (must match)
    • Subtitle extension preference (.srt, .ass, .ssa, .sub, .vtt)
    • File metadata (checksum, source, release group, resolution, video terms)
  • If no files match (all scores are 0): Returns the first file in the archive
  • Extracts in memory without creating temporary files

Exception Handling

SessionDataError

Raised when session data (sh token and cookie) cannot be obtained for a subtitle.

Attributes:

  • subtitle_id (int): The ID of the subtitle that failed

SecurityError

Raised when AnimeSub.info returns a security error ("błąd zabezpieczeń"). This happens when the server returns HTML instead of a ZIP file, typically due to invalid or expired session tokens.

Attributes:

  • subtitle_id (int): The ID of the subtitle that failed
  • sh (str): The sh token that was used (for debugging)
  • cookie (str): The cookie value that was used (for debugging)

Development

Setup

# Install uv if not already installed
curl -LsSf https://astral.sh/uv/install.sh | sh

# Sync dependencies (from workspace root)
cd ../..
uv sync --all-packages

# Run tests for this package
uv run --package animesubinfo pytest

Running tests

uv run --package animesubinfo pytest

Download files

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

Source Distribution

animesubinfo-0.4.0.tar.gz (18.5 kB view details)

Uploaded Source

Built Distribution

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

animesubinfo-0.4.0-py3-none-any.whl (22.8 kB view details)

Uploaded Python 3

File details

Details for the file animesubinfo-0.4.0.tar.gz.

File metadata

  • Download URL: animesubinfo-0.4.0.tar.gz
  • Upload date:
  • Size: 18.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for animesubinfo-0.4.0.tar.gz
Algorithm Hash digest
SHA256 7b17c6e46e1552ea5b8ad35a0fe131863944f315c2d3b99e2c0a2bccf43aa98e
MD5 4c24885694bb2c456a370b00033cc58c
BLAKE2b-256 d4ea05b6cd06c0dd51947953f7f2047e622ac777d530db2e6ba12785f83482ae

See more details on using hashes here.

File details

Details for the file animesubinfo-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: animesubinfo-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 22.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for animesubinfo-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 807c9d7fc1502acea09aa6047081fd740ec5dba103d918f9a6b4a6080a652bf9
MD5 4262ccd23044682627b1d4762088c62e
BLAKE2b-256 5e30afda3f574b23c0eb64b0428c19f8029bb454559cfe0f412b62ec3348c9fb

See more details on using hashes here.

Release history Release notifications | RSS feed

0.5.1

2 files

0.5.0

2 files

0.4.1

2 files

This release

0.4.0 This release

2 files

0.3.0

2 files

0.2.0

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page