PublicUser provides basic public profile information (id, display name, URI)
CurrentUser extends PublicUser and adds private details like email, country, subscription level, and settings
Use PublicUser when accessing other users’ profiles or when user data is embedded in playlists. Use CurrentUser when fetching the authenticated user’s profile from /v1/me.
Different user profile fields require different authorization scopes:No scope required:
id, display_name, uri, external_urls, href, type
user-read-private scope:
country, product, explicit_content
user-read-email scope:
email
Fields that require scopes you don’t have will be None:
if current_user.email is None: print("Email not available - user-read-email scope not granted")if current_user.country is None: print("Country not available - user-read-private scope not granted")
Show Checking Subscription Level
The product field indicates the user’s subscription tier:
if current_user.product == "premium": print("Premium subscriber - full access to features")elif current_user.product == "free": print("Free tier - limited playback")else: print(f"Subscription: {current_user.product}")
Common values:
"premium": Spotify Premium subscriber
"free": Free tier user
"open": User with limited access
Show Working with Profile Images
User profile images work the same as other images in the API:
if current_user.images: # Images are typically provided in descending size order largest = current_user.images[0] print(f"Profile picture: {largest.url}") if largest.width and largest.height: print(f"Dimensions: {largest.width}x{largest.height}")else: print("No profile picture set")
Note that user-uploaded images may not have width/height information.
Show PublicUser vs CurrentUser
Use the appropriate model based on context:PublicUser for:
Playlist owners (playlist.owner)
Users who added tracks to playlists (playlist_track.added_by)
Fetching other users’ public profiles
CurrentUser for:
The authenticated user’s profile from /v1/me
Accessing private user data (email, country, subscription)
# Current user - private datame = CurrentUser(**me_response)print(f"My email: {me.email}")# Public user - limited dataowner = PublicUser(**owner_data)print(f"Playlist by: {owner.display_name}")# owner.email would not exist