CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pylast

A Python interface to Last.fm and Libre.fm for music data, scrobbling, and social features.

Pending
Overview
Eval results
Files

user-social.mddocs/

User and Social Features

User profiles, listening history, social interactions, library access, and community features. This covers comprehensive user data access, social networking capabilities, and music library management through PyLast's user-centric objects.

Capabilities

User Objects

Core user representation with profile information, statistics, and listening data access.

class User:
    """
    Represents a Last.fm user.
    
    Args:
        user_name (str): Username
        network: Network instance (LastFMNetwork or LibreFMNetwork)
    """
    def __init__(self, user_name: str, network): ...
    
    def get_name(self, properly_capitalized=False) -> str:
        """
        Get username.
        
        Args:
            properly_capitalized (bool): Return properly capitalized username
            
        Returns:
            str: Username
        """
    
    def get_playcount(self) -> int:
        """Get total play count for this user."""
    
    def get_country(self) -> Country:
        """Get user's country as Country object."""
    
    def is_subscriber(self) -> bool:
        """Check if user is a Last.fm subscriber."""
    
    def get_registered(self) -> str:
        """Get user registration date as string."""
    
    def get_unixtime_registered(self) -> int:
        """Get user registration date as Unix timestamp."""
    
    def get_image(self, size=2) -> str:
        """
        Get user avatar image URL.
        
        Args:
            size (int): Image size (SIZE_SMALL to SIZE_MEGA)
            
        Returns:
            str: Avatar image URL
        """
    
    def get_url(self, domain_name=0) -> str:
        """Get Last.fm profile URL for this user."""

class AuthenticatedUser(User):
    """
    Represents the authenticated user (inherits from User).
    Automatically uses the authenticated user's data without requiring username.
    
    Args:
        network: Network instance with valid session key
    """
    def __init__(self, network): ...

Listening History

Access to user's music listening data, including recent tracks, loved tracks, and now playing information.

def get_recent_tracks(self, limit=50, cacheable=True, stream=True, from_date=None, to_date=None, time_from=None, time_to=None) -> list[PlayedTrack]:
    """
    Get user's recent tracks.
    
    Args:
        limit (int): Maximum number of tracks to retrieve
        cacheable (bool): Enable caching for this request
        stream (bool): Include streaming tracks
        from_date (str, optional): Start date (YYYY-MM-DD)
        to_date (str, optional): End date (YYYY-MM-DD)
        time_from (int, optional): Start timestamp
        time_to (int, optional): End timestamp
        
    Returns:
        list[PlayedTrack]: Recent played tracks with timestamps
    """

def get_loved_tracks(self, limit=50, cacheable=True) -> list[LovedTrack]:
    """
    Get user's loved tracks.
    
    Args:
        limit (int): Maximum number of tracks to retrieve
        cacheable (bool): Enable caching for this request
        
    Returns:
        list[LovedTrack]: Loved tracks with timestamps
    """

def get_now_playing(self) -> Track | None:
    """
    Get currently playing track.
    
    Returns:
        Track | None: Currently playing track, or None if nothing playing
    """

def get_track_scrobbles(self, artist: str, track: str, from_date=None, to_date=None) -> list[PlayedTrack]:
    """
    Get scrobbles for a specific track.
    
    Args:
        artist (str): Artist name
        track (str): Track name
        from_date (str, optional): Start date (YYYY-MM-DD)
        to_date (str, optional): End date (YYYY-MM-DD)
        
    Returns:
        list[PlayedTrack]: Scrobbles for the specified track
    """

Statistics and Top Content

User's top artists, albums, tracks, and tags with customizable time periods.

def get_top_artists(self, period="overall", limit=None, cacheable=True) -> list[TopItem]:
    """
    Get user's top artists.
    
    Args:
        period (str): Time period (PERIOD_OVERALL, PERIOD_7DAYS, etc.)
        limit (int, optional): Maximum number of results
        cacheable (bool): Enable caching for this request
        
    Returns:
        list[TopItem]: Top artists with play counts
    """

def get_top_albums(self, period="overall", limit=None, cacheable=True) -> list[TopItem]:
    """Get user's top albums for specified time period."""

def get_top_tracks(self, period="overall", limit=None, cacheable=True) -> list[TopItem]:
    """Get user's top tracks for specified time period."""

def get_top_tags(self, limit=None, cacheable=True) -> list[TopItem]:
    """Get user's top tags (most used tags)."""

Tagged Content

Access to user's tagged music content organized by tags.

def get_tagged_artists(self, tag: str, limit=None, cacheable=True) -> list[TopItem]:
    """
    Get artists tagged by this user with specific tag.
    
    Args:
        tag (str): Tag name
        limit (int, optional): Maximum number of results
        cacheable (bool): Enable caching
        
    Returns:
        list[TopItem]: Artists tagged with specified tag
    """

def get_tagged_albums(self, tag: str, limit=None, cacheable=True) -> list[TopItem]:
    """Get albums tagged by this user with specific tag."""

def get_tagged_tracks(self, tag: str, limit=None, cacheable=True) -> list[TopItem]:
    """Get tracks tagged by this user with specific tag."""

Social Connections

User's social network including friends and neighbors (users with similar taste).

def get_friends(self, limit=50, cacheable=True) -> list[User]:
    """
    Get user's friends.
    
    Args:
        limit (int): Maximum number of friends to retrieve
        cacheable (bool): Enable caching
        
    Returns:
        list[User]: Friend users
    """

def get_neighbours(self, limit=50, cacheable=True) -> list[User]:
    """
    Get user's neighbors (users with similar music taste).
    
    Args:
        limit (int): Maximum number of neighbors to retrieve
        cacheable (bool): Enable caching
        
    Returns:
        list[User]: Neighbor users
    """

Library Management

Access to user's music library with detailed play and tag statistics.

class Library:
    """
    Represents a user's music library.
    
    Args:
        user: User object
        network: Network instance
    """
    def __init__(self, user, network): ...
    
    def get_user(self) -> User:
        """Get the User object this library belongs to."""
    
    def get_artists(self, limit=50, cacheable=True, stream=True) -> list[LibraryItem]:
        """
        Get artists in user's library.
        
        Args:
            limit (int): Maximum number of artists to retrieve
            cacheable (bool): Enable caching
            stream (bool): Stream results for large libraries
            
        Returns:
            list[LibraryItem]: Library artists with play counts and tag counts
        """

# Access library through user object
def get_library(self) -> Library:
    """
    Get user's library object.
    
    Returns:
        Library: User's music library
    """

Weekly Charts

Historical weekly chart data for tracking music trends over time.

def get_weekly_chart_dates(self) -> list[tuple[str, str]]:
    """
    Get available weekly chart date ranges.
    
    Returns:
        list[tuple[str, str]]: List of (from_date, to_date) tuples
    """

def get_weekly_artist_charts(self, from_date=None, to_date=None) -> list[TopItem]:
    """
    Get weekly artist charts for date range.
    
    Args:
        from_date (str, optional): Start date
        to_date (str, optional): End date
        
    Returns:
        list[TopItem]: Weekly top artists
    """

def get_weekly_album_charts(self, from_date=None, to_date=None) -> list[TopItem]:
    """Get weekly album charts for date range."""

def get_weekly_track_charts(self, from_date=None, to_date=None) -> list[TopItem]:
    """Get weekly track charts for date range."""

Data Types

Key data structures for user and social data.

from collections import namedtuple

PlayedTrack = namedtuple('PlayedTrack', ['track', 'album', 'playback_date', 'timestamp'])
"""
Represents a played track with timestamp.

Fields:
    track (Track): The played track
    album (Album): Album containing the track
    playback_date (str): Human-readable playback date
    timestamp (int): Unix timestamp of playback
"""

LovedTrack = namedtuple('LovedTrack', ['track', 'date', 'timestamp'])
"""
Represents a loved track with timestamp.

Fields:
    track (Track): The loved track
    date (str): Human-readable love date
    timestamp (int): Unix timestamp when loved
"""

LibraryItem = namedtuple('LibraryItem', ['item', 'playcount', 'tagcount'])
"""
Represents a library item with statistics.

Fields:
    item (Artist/Album/Track): The music item
    playcount (int): Number of plays by the user
    tagcount (int): Number of tags applied by the user
"""

TopItem = namedtuple('TopItem', ['item', 'weight'])
"""
Represents a top item with weight/ranking.

Fields:
    item (Artist/Album/Track/Tag): The ranked item
    weight (int): Ranking weight (higher = more popular)
"""

Usage Examples

User Profile and Statistics

import pylast

network = pylast.LastFMNetwork(api_key=API_KEY, api_secret=API_SECRET)

# Get user profile
user = network.get_user("username")
print(f"User: {user.get_name()}")
print(f"Country: {user.get_country().get_name()}")
print(f"Total plays: {user.get_playcount():,}")
print(f"Registered: {user.get_registered()}")
print(f"Subscriber: {user.is_subscriber()}")

# Get top artists for different periods
periods = [
    ("7day", "Last 7 Days"),
    ("1month", "Last Month"), 
    ("6month", "Last 6 Months"),
    ("overall", "All Time")
]

for period_key, period_name in periods:
    top_artists = user.get_top_artists(period=period_key, limit=5)
    print(f"\nTop Artists - {period_name}:")
    for i, artist_item in enumerate(top_artists, 1):
        artist = artist_item.item
        plays = artist_item.weight
        print(f"{i}. {artist.get_name()} ({plays} plays)")

Recent Listening Activity

# Get recent tracks
recent = user.get_recent_tracks(limit=20)
print("Recent Tracks:")
for played_track in recent:
    track = played_track.track
    album = played_track.album
    date = played_track.playback_date
    
    print(f"{track.get_artist().get_name()} - {track.get_title()}")
    if album:
        print(f"  from '{album.get_title()}' on {date}")
    else:
        print(f"  on {date}")

# Check what's currently playing
now_playing = user.get_now_playing()
if now_playing:
    print(f"\nNow Playing: {now_playing.get_artist().get_name()} - {now_playing.get_title()}")
else:
    print("\nNothing currently playing")

Loved Tracks and Tagged Content

# Get loved tracks
loved = user.get_loved_tracks(limit=10)
print("Loved Tracks:")
for loved_track in loved:
    track = loved_track.track
    date = loved_track.date
    print(f"{track.get_artist().get_name()} - {track.get_title()} (loved on {date})")

# Get tagged content
rock_artists = user.get_tagged_artists("rock", limit=10)
print("\nArtists tagged as 'rock':")
for artist_item in rock_artists:
    print(f"- {artist_item.item.get_name()}")

electronic_tracks = user.get_tagged_tracks("electronic", limit=5)
print("\nTracks tagged as 'electronic':")
for track_item in electronic_tracks:
    track = track_item.item
    print(f"- {track.get_artist().get_name()} - {track.get_title()}")

Social Features

# Get friends
friends = user.get_friends(limit=10)
print("Friends:")
for friend in friends:
    print(f"- {friend.get_name()} ({friend.get_playcount():,} total plays)")

# Get music neighbors (similar taste)
neighbors = user.get_neighbours(limit=5)
print("\nMusic Neighbors (similar taste):")
for neighbor in neighbors:
    print(f"- {neighbor.get_name()}")
    
    # Compare top artists
    neighbor_top = neighbor.get_top_artists(limit=3)
    common_artists = []
    user_top = user.get_top_artists(limit=10)
    user_artist_names = {item.item.get_name().lower() for item in user_top}
    
    for neighbor_artist in neighbor_top:
        if neighbor_artist.item.get_name().lower() in user_artist_names:
            common_artists.append(neighbor_artist.item.get_name())
    
    if common_artists:
        print(f"  Common artists: {', '.join(common_artists)}")

Library Analysis

# Access user's library
library = user.get_library()
library_artists = library.get_artists(limit=50)

print("Library Analysis:")
print(f"Artists in library: {len(library_artists)}")

# Find most played artists
sorted_artists = sorted(library_artists, key=lambda x: x.playcount, reverse=True)
print("\nMost played artists in library:")
for i, lib_item in enumerate(sorted_artists[:10], 1):
    artist = lib_item.item
    plays = lib_item.playcount
    tags = lib_item.tagcount
    print(f"{i:2d}. {artist.get_name()} - {plays} plays, {tags} tags")

# Find most tagged artists
most_tagged = sorted(library_artists, key=lambda x: x.tagcount, reverse=True)
print("\nMost tagged artists:")
for lib_item in most_tagged[:5]:
    if lib_item.tagcount > 0:
        artist = lib_item.item
        print(f"- {artist.get_name()} ({lib_item.tagcount} tags)")

Weekly Charts Analysis

# Get available chart periods
chart_dates = user.get_weekly_chart_dates()
if chart_dates:
    # Get recent weekly chart
    latest_from, latest_to = chart_dates[-1]
    weekly_artists = user.get_weekly_artist_charts(latest_from, latest_to)
    
    print(f"Weekly Chart ({latest_from} to {latest_to}):")
    for i, artist_item in enumerate(weekly_artists[:10], 1):
        artist = artist_item.item
        plays = artist_item.weight
        print(f"{i:2d}. {artist.get_name()} ({plays} plays)")
    
    # Compare with previous week if available
    if len(chart_dates) > 1:
        prev_from, prev_to = chart_dates[-2]
        prev_weekly = user.get_weekly_artist_charts(prev_from, prev_to)
        
        print(f"\nTrending (vs previous week):")
        current_names = {item.item.get_name(): item.weight for item in weekly_artists[:10]}
        prev_names = {item.item.get_name(): item.weight for item in prev_weekly}
        
        for name, current_plays in current_names.items():
            if name in prev_names:
                change = current_plays - prev_names[name]
                if change > 0:
                    print(f"↗ {name} (+{change} plays)")
                elif change < 0:
                    print(f"↘ {name} ({change} plays)")
            else:
                print(f"★ {name} (new entry)")

Authenticated User Features

# For authenticated users (requires session key)
if network.session_key:
    auth_user = network.get_authenticated_user()
    
    # Same methods as regular User, but automatically uses authenticated user's data
    my_recent = auth_user.get_recent_tracks(limit=5)
    my_loved = auth_user.get_loved_tracks(limit=5)
    
    print("My Recent Tracks:")
    for played_track in my_recent:
        track = played_track.track
        print(f"- {track.get_artist().get_name()} - {track.get_title()}")
    
    print("\nMy Loved Tracks:")
    for loved_track in my_loved:
        track = loved_track.track
        print(f"♥ {track.get_artist().get_name()} - {track.get_title()}")

Install with Tessl CLI

npx tessl i tessl/pypi-pylast

docs

index.md

music-objects.md

network-auth.md

scrobbling.md

search-discovery.md

user-social.md

tile.json