CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-spotipy

A light weight Python library for the Spotify Web API

Overview
Eval results
Files

podcasts.mddocs/

Podcasts and Shows

Access podcast shows, episodes, and audiobook content with comprehensive metadata and user library integration. Spotify provides extensive podcast catalog with detailed episode information and user management features.

Capabilities

Show Information

Access podcast show details and metadata.

def show(self, show_id, market=None):
    """
    Get show information.
    
    Args:
        show_id (str): Spotify show ID or URI
        market (str, optional): ISO 3166-1 alpha-2 country code
        
    Returns:
        dict: Show object with metadata, episodes, and publisher info
    """

def shows(self, shows, market=None):
    """
    Get multiple shows.
    
    Args:
        shows (list): List of show IDs or URIs (max 50)
        market (str, optional): ISO 3166-1 alpha-2 country code
        
    Returns:
        dict: Shows object containing list of show objects
    """

Show Episodes

Access episodes within podcast shows.

def show_episodes(self, show_id, limit=50, offset=0, market=None):
    """
    Get episodes from a show.
    
    Args:
        show_id (str): Spotify show ID or URI
        limit (int): Number of episodes to return (1-50, default: 50)
        offset (int): Index of first episode (default: 0)
        market (str, optional): ISO 3166-1 alpha-2 country code
        
    Returns:
        dict: Paging object of simplified episode objects
    """

Episode Information

Access individual episode details and metadata.

def episode(self, episode_id, market=None):
    """
    Get episode information.
    
    Args:
        episode_id (str): Spotify episode ID or URI
        market (str, optional): ISO 3166-1 alpha-2 country code
        
    Returns:
        dict: Episode object with metadata, show info, and playback details
    """

def episodes(self, episodes, market=None):
    """
    Get multiple episodes.
    
    Args:
        episodes (list): List of episode IDs or URIs (max 50)
        market (str, optional): ISO 3166-1 alpha-2 country code
        
    Returns:
        dict: Episodes object containing list of episode objects
    """

Audiobook Content

Access audiobook information and chapters.

def get_audiobook(self, id, market=None):
    """
    Get audiobook information.
    
    Args:
        id (str): Spotify audiobook ID or URI
        market (str, optional): ISO 3166-1 alpha-2 country code
        
    Returns:
        dict: Audiobook object with metadata, authors, and narrator info
    """

def get_audiobooks(self, ids, market=None):
    """
    Get multiple audiobooks.
    
    Args:
        ids (list): List of audiobook IDs or URIs (max 50)
        market (str, optional): ISO 3166-1 alpha-2 country code
        
    Returns:
        dict: Audiobooks object containing list of audiobook objects
    """

def get_audiobook_chapters(self, id, market=None, limit=20, offset=0):
    """
    Get chapters from an audiobook.
    
    Args:
        id (str): Spotify audiobook ID or URI
        market (str, optional): ISO 3166-1 alpha-2 country code
        limit (int): Number of chapters to return (1-50, default: 20)
        offset (int): Index of first chapter (default: 0)
        
    Returns:
        dict: Paging object of simplified chapter objects
    """

Usage Examples

Exploring Podcast Shows

import spotipy
from spotipy.oauth2 import SpotifyClientCredentials

sp = spotipy.Spotify(client_credentials_manager=SpotifyClientCredentials())

# Search for popular podcast shows
results = sp.search(q='true crime', type='show', limit=10)
shows = results['shows']['items']

print("🎙️ True Crime Podcast Shows:")
for show in shows:
    print(f"\\n📻 {show['name']}")
    print(f"   Publisher: {show['publisher']}")
    print(f"   Description: {show['description'][:100]}...")
    print(f"   Total Episodes: {show['total_episodes']}")
    print(f"   Languages: {', '.join(show['languages'])}")
    print(f"   Explicit: {'Yes' if show['explicit'] else 'No'}")
    
    if show['images']:
        print(f"   Cover: {show['images'][0]['url']}")

# Get detailed information for a specific show
if shows:
    show_id = shows[0]['id']
    detailed_show = sp.show(show_id)
    
    print(f"\\n🔍 Detailed info for '{detailed_show['name']}':")
    print(f"   Media Type: {detailed_show['media_type']}")
    print(f"   Available Markets: {len(detailed_show['available_markets'])} markets")
    print(f"   Copyright: {detailed_show['copyrights'][0]['text'] if detailed_show['copyrights'] else 'N/A'}")

Browsing Episodes

# Get episodes from a show
show_id = "4rOoJ6Egrf8K2IrywzwOMk"  # Example show ID

# Get recent episodes
episodes = sp.show_episodes(show_id, limit=20)
print(f"📺 Recent episodes ({episodes['total']} total):")

for episode in episodes['items']:
    print(f"\\n🎧 {episode['name']}")
    print(f"   Description: {episode['description'][:150]}...")
    print(f"   Duration: {episode['duration_ms'] // 60000} minutes")
    print(f"   Release Date: {episode['release_date']}")
    print(f"   Language: {', '.join(episode['languages'])}")
    print(f"   Explicit: {'Yes' if episode['explicit'] else 'No'}")
    
    # Check if episode has external URLs
    if episode['external_urls']:
        print(f"   Spotify URL: {episode['external_urls']['spotify']}")

# Get detailed episode information
if episodes['items']:
    episode_id = episodes['items'][0]['id']
    detailed_episode = sp.episode(episode_id)
    
    print(f"\\n🔍 Detailed episode info:")
    print(f"   Show: {detailed_episode['show']['name']}")
    print(f"   Episode Type: {detailed_episode.get('type', 'episode')}")
    print(f"   Resume Point: {detailed_episode.get('resume_point', {}).get('resume_position_ms', 0) // 1000}s")
    print(f"   Fully Played: {detailed_episode.get('resume_point', {}).get('fully_played', False)}")

Audiobook Exploration

# Search for audiobooks
audiobook_results = sp.search(q='mystery', type='audiobook', limit=5)
audiobooks = audiobook_results['audiobooks']['items']

print("📚 Mystery Audiobooks:")
for audiobook in audiobooks:
    print(f"\\n📖 {audiobook['name']}")
    print(f"   Authors: {', '.join([author['name'] for author in audiobook['authors']])}")
    print(f"   Narrators: {', '.join([narrator['name'] for narrator in audiobook['narrators']])}")
    print(f"   Publisher: {audiobook['publisher']}")
    print(f"   Description: {audiobook['description'][:100]}...")
    print(f"   Total Chapters: {audiobook['total_chapters']}")
    print(f"   Languages: {', '.join(audiobook['languages'])}")
    print(f"   Explicit: {'Yes' if audiobook['explicit'] else 'No'}")

# Get chapters from an audiobook
if audiobooks:
    audiobook_id = audiobooks[0]['id']
    chapters = sp.get_audiobook_chapters(audiobook_id, limit=10)
    
    print(f"\\n📑 Chapters from '{audiobooks[0]['name']}':")
    for i, chapter in enumerate(chapters['items'], 1):
        duration_min = chapter['duration_ms'] // 60000
        print(f"   Chapter {i}: {chapter['name']} ({duration_min} min)")
        print(f"      Description: {chapter['description'][:80]}...")
        print(f"      Chapter Number: {chapter.get('chapter_number', 'N/A')}")

Podcast Discovery and Analysis

def analyze_podcast_show(show_id):
    """Analyze a podcast show's episodes and patterns."""
    
    show = sp.show(show_id)
    print(f"📊 Analysis for '{show['name']}':")
    print(f"Publisher: {show['publisher']}")
    print(f"Total Episodes: {show['total_episodes']}")
    
    # Get all episodes
    all_episodes = []
    episodes = sp.show_episodes(show_id, limit=50)
    all_episodes.extend(episodes['items'])
    
    while episodes['next']:
        episodes = sp.next(episodes)
        all_episodes.extend(episodes['items'])
    
    if all_episodes:
        # Calculate statistics
        durations = [ep['duration_ms'] for ep in all_episodes]
        avg_duration = sum(durations) / len(durations)
        
        # Count explicit episodes
        explicit_count = sum(1 for ep in all_episodes if ep.get('explicit', False))
        
        # Get release pattern (episodes per month)
        from collections import defaultdict
        import datetime
        
        release_months = defaultdict(int)
        for episode in all_episodes:
            if episode['release_date']:
                try:
                    date = datetime.datetime.strptime(episode['release_date'], '%Y-%m-%d')
                    month_key = f"{date.year}-{date.month:02d}"
                    release_months[month_key] += 1
                except:
                    pass
        
        print(f"\\n📈 Episode Statistics:")
        print(f"   Average Duration: {avg_duration / 60000:.1f} minutes")
        print(f"   Longest Episode: {max(durations) / 60000:.1f} minutes")
        print(f"   Shortest Episode: {min(durations) / 60000:.1f} minutes")
        print(f"   Explicit Episodes: {explicit_count}/{len(all_episodes)} ({explicit_count/len(all_episodes)*100:.1f}%)")
        
        print(f"\\n📅 Recent Release Pattern:")
        recent_months = sorted(release_months.keys())[-6:]  # Last 6 months
        for month in recent_months:
            print(f"   {month}: {release_months[month]} episodes")
        
        # Show recent episodes
        print(f"\\n🆕 Most Recent Episodes:")
        for episode in all_episodes[:5]:
            print(f"   • {episode['name']} ({episode['release_date']})")
            print(f"     {episode['duration_ms'] // 60000} min - {episode['description'][:60]}...")

# Analyze a popular podcast
# Example: The Joe Rogan Experience (if available in your market)
try:
    # You would need to find the actual show ID
    # analyze_podcast_show("4rOoJ6Egrf8K2IrywzwOMk")
    pass
except Exception as e:
    print(f"Could not analyze show: {e}")

Content Discovery by Category

def discover_podcasts_by_genre(genre_query, limit=10):
    """Discover podcasts by genre or topic."""
    
    # Search for shows
    results = sp.search(q=genre_query, type='show', limit=limit)
    shows = results['shows']['items']
    
    print(f"🎭 '{genre_query.title()}' Podcasts:")
    
    show_stats = []
    
    for show in shows:
        print(f"\\n📻 {show['name']}")
        print(f"   Publisher: {show['publisher']}")
        print(f"   Episodes: {show['total_episodes']}")
        print(f"   Languages: {', '.join(show['languages'])}")
        
        # Get a few recent episodes to analyze
        try:
            recent_episodes = sp.show_episodes(show['id'], limit=5)
            if recent_episodes['items']:
                avg_duration = sum(ep['duration_ms'] for ep in recent_episodes['items']) / len(recent_episodes['items'])
                print(f"   Avg Episode Length: {avg_duration / 60000:.1f} minutes")
                
                # Check update frequency
                episodes = recent_episodes['items']
                if len(episodes) >= 2:
                    try:
                        from datetime import datetime
                        date1 = datetime.strptime(episodes[0]['release_date'], '%Y-%m-%d')
                        date2 = datetime.strptime(episodes[1]['release_date'], '%Y-%m-%d')
                        days_between = abs((date1 - date2).days)
                        print(f"   Update Frequency: ~{days_between} days between episodes")
                    except:
                        pass
        except:
            pass
        
        show_stats.append({
            'name': show['name'],
            'episodes': show['total_episodes'],
            'publisher': show['publisher']
        })
    
    # Summary statistics
    if show_stats:
        total_episodes = sum(s['episodes'] for s in show_stats)
        avg_episodes = total_episodes / len(show_stats)
        
        print(f"\\n📊 Genre Summary:")
        print(f"   Total Shows Found: {len(show_stats)}")
        print(f"   Total Episodes: {total_episodes}")
        print(f"   Average Episodes per Show: {avg_episodes:.1f}")
        
        # Top publishers
        publishers = {}
        for show in show_stats:
            pub = show['publisher']
            publishers[pub] = publishers.get(pub, 0) + 1
        
        print(f"   Top Publishers:")
        for pub, count in sorted(publishers.items(), key=lambda x: x[1], reverse=True)[:3]:
            print(f"     {pub}: {count} shows")

# Discover different podcast genres
genres = ['technology', 'comedy', 'news', 'business', 'health']
for genre in genres:
    discover_podcasts_by_genre(genre, 5)
    print("-" * 60)

Episode Queue Management

def create_podcast_queue(show_ids, episodes_per_show=3):
    """Create a listening queue from multiple podcast shows."""
    
    queue = []
    
    for show_id in show_ids:
        try:
            show = sp.show(show_id)
            episodes = sp.show_episodes(show_id, limit=episodes_per_show)
            
            for episode in episodes['items']:
                queue.append({
                    'show_name': show['name'],
                    'episode_name': episode['name'],
                    'duration_minutes': episode['duration_ms'] // 60000,
                    'release_date': episode['release_date'],
                    'description': episode['description'][:100] + '...',
                    'uri': episode['uri']
                })
        except Exception as e:
            print(f"Error processing show {show_id}: {e}")
    
    # Sort by release date (newest first)
    queue.sort(key=lambda x: x['release_date'], reverse=True)
    
    print(f"🎧 Podcast Listening Queue ({len(queue)} episodes):")
    total_duration = sum(ep['duration_minutes'] for ep in queue)
    print(f"Total Duration: {total_duration // 60}h {total_duration % 60}m\\n")
    
    for i, episode in enumerate(queue, 1):
        print(f"{i:2d}. [{episode['show_name']}] {episode['episode_name']}")
        print(f"    {episode['duration_minutes']} min | {episode['release_date']} | {episode['description']}")
        print(f"    URI: {episode['uri']}")
        print()
    
    return queue

# Example usage (you would need actual show IDs)
# show_ids = ["show_id_1", "show_id_2", "show_id_3"]
# podcast_queue = create_podcast_queue(show_ids, 2)

Language and Market Analysis

def analyze_content_by_market(content_type='show', query='news', markets=['US', 'GB', 'DE', 'ES']):
    """Analyze how content varies across different markets."""
    
    print(f"🌍 {content_type.title()} Content Analysis: '{query}'\\n")
    
    for market in markets:
        print(f"📍 Market: {market}")
        
        try:
            results = sp.search(q=query, type=content_type, market=market, limit=5)
            items = results[f"{content_type}s"]['items']
            
            if items:
                languages = set()
                publishers = set()
                
                print(f"   Top {content_type}s:")
                for item in items:
                    name = item['name']
                    publisher = item.get('publisher', 'Unknown')
                    item_languages = item.get('languages', [])
                    
                    print(f"   • {name} ({publisher})")
                    if item_languages:
                        print(f"     Languages: {', '.join(item_languages)}")
                        languages.update(item_languages)
                    publishers.add(publisher)
                
                print(f"\\n   Summary for {market}:")
                print(f"   • Languages found: {', '.join(sorted(languages))}")
                print(f"   • Unique publishers: {len(publishers)}")
            else:
                print(f"   No {content_type}s found")
                
        except Exception as e:
            print(f"   Error: {e}")
        
        print("-" * 40)

# Analyze podcast content across markets
analyze_content_by_market('show', 'politics', ['US', 'GB', 'CA', 'AU'])
analyze_content_by_market('audiobook', 'fiction', ['US', 'GB', 'DE'])

Content Types

Show Object Fields

  • id, name, description, publisher
  • total_episodes, languages, explicit
  • images, available_markets
  • copyrights, media_type

Episode Object Fields

  • id, name, description, duration_ms
  • release_date, languages, explicit
  • images, show (simplified show object)
  • resume_point (for authenticated users)

Audiobook Object Fields

  • id, name, description, publisher
  • authors, narrators, total_chapters
  • languages, explicit, images
  • available_markets, copyrights

Note: Podcast and audiobook availability varies by market. Some content may not be accessible in all regions due to licensing restrictions.

Install with Tessl CLI

npx tessl i tessl/pypi-spotipy

docs

authentication.md

browse.md

cache.md

client.md

index.md

playback.md

playlists.md

podcasts.md

user-library.md

tile.json