Skip to content

Python Examples

Complete Python examples for using the SubX API.

Installation

pip install requests python-dotenv

Basic Setup

import os
import requests
from dotenv import load_dotenv

# Load environment variables
load_dotenv()

API_KEY = os.getenv('SUBX_API_KEY')
BASE_URL = "https://subx-api.duckdns.org"

headers = {
    "Authorization": f"Bearer {API_KEY}"
}

Complete Examples

1. Search and Download Workflow

import requests
import os
from pathlib import Path

class SubXClient:
    def __init__(self, api_key):
        self.api_key = api_key
        self.base_url = "https://subx-api.duckdns.org"
        self.headers = {"Authorization": f"Bearer {api_key}"}

    def search(self, **kwargs):
        """Search for subtitles."""
        response = requests.get(
            f"{self.base_url}/api/subtitles/search",
            headers=self.headers,
            params=kwargs
        )
        response.raise_for_status()
        return response.json()

    def get_subtitle(self, subtitle_id):
        """Get subtitle details."""
        response = requests.get(
            f"{self.base_url}/api/subtitles/{subtitle_id}",
            headers=self.headers
        )
        response.raise_for_status()
        return response.json()

    def download(self, subtitle_id, output_path):
        """Download subtitle file."""
        response = requests.get(
            f"{self.base_url}/api/subtitles/{subtitle_id}/download",
            headers=self.headers
        )
        response.raise_for_status()

        # Save file
        Path(output_path).parent.mkdir(parents=True, exist_ok=True)
        with open(output_path, "wb") as f:
            f.write(response.content)

        return output_path

# Usage
client = SubXClient(os.getenv('SUBX_API_KEY'))

# Search
results = client.search(title="Dexter", limit=10)
print(f"Found {results['total']} subtitles")

# Download first result
if results['items']:
    subtitle = results['items'][0]
    output = client.download(subtitle['id'], f"subtitles/{subtitle['title']}.srt")
    print(f"Downloaded: {output}")

2. Advanced Search with Filters

def search_series_episode(client, imdb_id, season, episode):
    """Search for a specific TV episode."""
    results = client.search(
        imdb_id=imdb_id,
        video_type="episode",
        limit=200
    )

    # Filter by season and episode
    matches = [
        sub for sub in results['items']
        if sub.get('season') == season and sub.get('episode') == episode
    ]

    return matches

# Find Dexter S01E01
episodes = search_series_episode(client, "tt0773262", season=1, episode=1)
print(f"Found {len(episodes)} matching subtitles")

3. Batch Download with Progress

from concurrent.futures import ThreadPoolExecutor, as_completed
from tqdm import tqdm

def batch_download(client, subtitle_ids, output_dir="subtitles", max_workers=3):
    """Download multiple subtitles concurrently with progress bar."""
    os.makedirs(output_dir, exist_ok=True)

    def download_one(sub_id):
        try:
            # Get details for filename
            details = client.get_subtitle(sub_id)
            filename = f"{details['title']}_S{details.get('season', 0):02d}E{details.get('episode', 0):02d}.srt"
            output = os.path.join(output_dir, filename)

            client.download(sub_id, output)
            return {'id': sub_id, 'success': True, 'file': filename}
        except Exception as e:
            return {'id': sub_id, 'success': False, 'error': str(e)}

    results = []
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = {executor.submit(download_one, sid): sid for sid in subtitle_ids}

        for future in tqdm(as_completed(futures), total=len(subtitle_ids), desc="Downloading"):
            results.append(future.result())

    success_count = sum(1 for r in results if r['success'])
    print(f"\nCompleted: {success_count}/{len(subtitle_ids)} successful")

    return results

See the Quickstart Guide for more basic examples.