Mobileclient Interface

class gmusicapi.clients.Mobileclient(debug_logging=True, validate=True, verify_ssl=True)

Allows library management and streaming by posing as the googleapis.com mobile clients.

Uploading is not supported by this client (use the Musicmanager to upload).

Setup and login

Mobileclient.__init__(debug_logging=True, validate=True, verify_ssl=True)
Parameters:
  • debug_logging

    each Client has a logger member. The logger is named gmusicapi.<client class><client number> and will propogate to the gmusicapi root logger.

    If this param is True, handlers will be configured to send this client’s debug log output to disk, with warnings and above printed to stderr. Appdirs user_log_dir is used by default. Users can run:

    from gmusicapi.utils import utils
    print utils.log_filepath
    

    to see the exact location on their system.

    If False, no handlers will be configured; users must create their own handlers.

    Completely ignoring logging is dangerous and not recommended. The Google Music protocol can change at any time; if something were to go wrong, the logs would be necessary for recovery.

  • validate

    if False, do not validate server responses against known schemas. This helps to catch protocol changes, but requires significant cpu work.

    This arg is stored as self.validate and can be safely modified at runtime.

  • verify_ssl – if False, exceptions will not be raised if there are problems verifying SSL certificates. Be wary of using this option; it’s almost always better to fix the machine’s SSL configuration than to ignore errors.
classmethod Mobileclient.perform_oauth(storage_filepath=<object object>, open_browser=False)

Provides a series of prompts for a user to follow to authenticate. Returns oauth2client.client.OAuth2Credentials when successful.

In most cases, this should only be run once per machine to store credentials to disk, then never be needed again.

If the user refuses to give access, oauth2client.client.FlowExchangeError is raised.

Parameters:
  • storage_filepath

    a filepath to write the credentials to, or None to not write the credentials to disk (which is not recommended).

    Appdirs user_data_dir is used by default. Check the OAUTH_FILEPATH field on this class to see the exact location that will be used.

  • open_browser – if True, attempt to open the auth url in the system default web browser. The url will be printed regardless of this param’s setting.

This flow is intentionally very simple. For complete control over the OAuth flow, pass an oauth2client.client.OAuth2Credentials to login() instead.

Mobileclient.oauth_login(device_id, oauth_credentials='/home/docs/.local/share/gmusicapi/mobileclient.cred', locale='en_US')

Authenticates the mobileclient with pre-existing OAuth credentials. Returns True on success, False on failure.

Raises gmusicapi.exceptions.InvalidDeviceId if device_id is not valid (ie, it is not returned by Mobileclient.get_registered_devices). If unhandled, it will print possible valid device ids with the traceback. If handled, the list is available on the valid_device_ids field.

Parameters:
  • oauth_credentials

    oauth2client.client.OAuth2Credentials or the path to a oauth2client.file.Storage file. By default, the same default path used by perform_oauth() is used.

    Endusers will likely call perform_oauth() once to write credentials to disk and then ignore this parameter.

    This param is mostly intended to allow flexibility for developers of a 3rd party service who intend to perform their own OAuth flow (eg on their website).

  • device_id

    A string of 16 hex digits for Android or “ios:<uuid>” for iOS.

    Alternatively, pass Mobileclient.FROM_MAC_ADDRESS to attempt to use this machine’s MAC address as an id. If a valid MAC address cannot be determined on this machine (which is often the case when running on a VPS), raise OSError.

    This will likely be deprecated, since Google now rejects ids of this form.

  • localeICU locale used to localize certain responses. This must be a locale supported by Android. Defaults to 'en_US'.
Mobileclient.login(email, password, android_id, locale='en_US')

Authenticates the Mobileclient using full account credentials. Returns True on success, False on failure.

Behind the scenes, this performs a Google-specific Android login flow with the provided credentials, then trades those for a Google Music auth token. It is deprecated in favor of the more robust oauth_login(), which performs a normal OAuth flow instead of taking account credentials.

Parameters:
  • email – eg 'test@gmail.com' or just 'test'.
  • password – password or app-specific password for 2-factor users. This is not stored locally, and is sent securely over SSL.
  • android_id

    16 hex digits, eg '1234567890abcdef'.

    Pass Mobileclient.FROM_MAC_ADDRESS instead to attempt to use this machine’s MAC address as an android id. Use this at your own risk: the id will be a non-standard 12 characters, but appears to work fine in testing. If a valid MAC address cannot be determined on this machine (which is often the case when running on a VPS), raise OSError.

  • localeICU locale used to localize certain responses. This must be a locale supported by Android. Defaults to 'en_US'.
Mobileclient.logout()

Forgets local authentication and cached properties in this Api instance. Returns True on success.

Mobileclient.is_authenticated()

Returns True if the Api can make an authenticated request.

Mobileclient.locale

The locale of the Mobileclient session used to localize some responses.

Should be an ICU locale supported by Android.

Set during login but can be changed at any time.

Account Management

Mobileclient.is_subscribed

Returns the subscription status of the Google Music account.

Result is cached with a TTL of 10 minutes. To get live status before the TTL is up, delete the is_subscribed property of the Mobileclient instance.

>>> mc = Mobileclient()
>>> mc.is_subscribed  # Live status.
>>> mc.is_subscribed  # Cached status.
>>> del mc.is_subscribed  # Delete is_subscribed property.
>>> mc.is_subscribed  # Live status.
Mobileclient.get_registered_devices()

Returns a list of dictionaries representing devices associated with the account.

Performing the Musicmanager OAuth flow will register a device of type 'DESKTOP_APP'.

Installing the Android or iOS Google Music app and logging into it will register a device of type 'ANDROID' or 'IOS' respectively, which is required for streaming with the Mobileclient.

Here is an example response:

[
  {
    u'kind':               u'sj#devicemanagementinfo',
    u'friendlyName':       u'my-hostname',
    u'id':                 u'AA:BB:CC:11:22:33',
    u'lastAccessedTimeMs': u'1394138679694',
    u'type':               u'DESKTOP_APP'
  },
  {
    u"kind":               u"sj#devicemanagementinfo",
    u'friendlyName':       u'Nexus 7',
    u'id':                 u'0x00112233aabbccdd',  # remove 0x when streaming
    u'lastAccessedTimeMs': u'1344808742774',
    u'type':               u'ANDROID'
    u'smartPhone':         True
  },
  {
    u"kind":               u"sj#devicemanagementinfo",
    u'friendlyName':       u'iPhone 6',
    u'id':                 u'ios:01234567-0123-0123-0123-0123456789AB',
    u'lastAccessedTimeMs': 1394138679694,
    u'type':               u'IOS'
    u'smartPhone':         True
  }
  {
    u'kind':               u'sj#devicemanagementinfo',
    u'friendlyName':       u'Google Play Music for Chrome on Windows',
    u'id':                 u'rt2qfkh0qjhos4bxrgc0oae...',  # 64 characters, alphanumeric
    u'lastAccessedTimeMs': u'1425602805052',
    u'type':               u'DESKTOP_APP'
  },
]
Mobileclient.deauthorize_device(device_id)

Deauthorize a registered device.

Returns True on success, False on failure.

Parameters:device_id

A mobile device id as a string. Android ids are 16 characters with ‘0x’ prepended, iOS ids are uuids with ‘ios:’ prepended, while desktop ids are in the form of a MAC address.

Providing an invalid or unregistered device id will result in a 400 HTTP error.

Google limits the number of device deauthorizations to 4 per year. Attempts to deauthorize a device when that limit is reached results in a 403 HTTP error with: X-Rejected-Reason: TOO_MANY_DEAUTHORIZATIONS.

Songs

Songs are uniquely referred to within a library with a track id in uuid format.

Store tracks also have track ids, but they are in a different format than library track ids. song_id.startswith('T') is always True for store track ids and False for library track ids.

Adding a store track to a library will yield a normal song id.

Store track ids can be used in most places that normal song ids can (e.g. playlist addition or streaming). Note that sometimes they are stored under the 'nid' key, not the 'id' key.

Mobileclient.get_all_songs(incremental=False, include_deleted=None, updated_after=None)

Returns a list of dictionaries that each represent a song.

Parameters:
  • incremental – if True, return a generator that yields lists of at most 1000 tracks as they are retrieved from the server. This can be useful for presenting a loading bar to a user.
  • include_deleted – ignored. Will be removed in a future release.
  • updated_after – a datetime.datetime; defaults to unix epoch. If provided, deleted songs may be returned.

Here is an example song dictionary:

{
   'comment':'',
   'rating':'0',
   'albumArtRef':[
     {
       'url': 'http://lh6.ggpht.com/...'
     }
   ],
   'artistId':[
     'Aod62yyj3u3xsjtooghh2glwsdi'
   ],
   'composer':'',
   'year':2011,
   'creationTimestamp':'1330879409467830',
   'id':'5924d75a-931c-30ed-8790-f7fce8943c85',
   'album':'Heritage ',
   'totalDiscCount':0,
   'title':'Haxprocess',
   'recentTimestamp':'1372040508935000',
   'albumArtist':'',
   'trackNumber':6,
   'discNumber':0,
   'deleted':False,
   'storeId':'Txsffypukmmeg3iwl3w5a5s3vzy',
   'nid':'Txsffypukmmeg3iwl3w5a5s3vzy',
   'totalTrackCount':10,
   'estimatedSize':'17229205',
   'albumId':'Bdkf6ywxmrhflvtasnayxlkgpcm',
   'beatsPerMinute':0,
   'genre':'Progressive Metal',
   'playCount':7,
   'artistArtRef':[
     {
       'url': 'http://lh3.ggpht.com/...'
     }
   ],
   'kind':'sj#track',
   'artist':'Opeth',
   'lastModifiedTimestamp':'1330881158830924',
   'clientId':'+eGFGTbiyMktbPuvB5MfsA',
   'durationMillis':'418000'
 }
Mobileclient.get_stream_url(song_id, device_id=None, quality='hi')

Returns a url that will point to an mp3 file.

Parameters:
  • song_id – A single song id. This can be 'storeId' from a store song, 'id' from an uploaded song, or 'trackId' from a playlist entry.
  • device_id

    (optional) defaults to android_id from login.

    Otherwise, provide a mobile device id as a string. Android device ids are 16 characters, while iOS ids are uuids with ‘ios:’ prepended.

    If you have already used Google Music on a mobile device, Mobileclient.get_registered_devices will provide at least one working id. Omit '0x' from the start of the string if present.

    Registered computer ids (a MAC address) will not be accepted and will 403.

    Providing an unregistered mobile device id will register it to your account, subject to Google’s device limits. Registering a device id that you do not own is likely a violation of the TOS.

  • quality – (optional) stream bits per second quality One of three possible values, hi: 320kbps, med: 160kbps, low: 128kbps. The default is hi
When handling the resulting url, keep in mind that:
  • you will likely need to handle redirects
  • the url expires after a minute
  • only one IP can be streaming music at once. This can result in an http 403 with X-Rejected-Reason: ANOTHER_STREAM_BEING_PLAYED.

The file will not contain metadata. Use Webclient.get_song_download_info or Musicmanager.download_song to download files with metadata.

Mobileclient.rate_songs(songs, rating)

Rate library or store songs.

Returns rated song ids.

Parameters:
  • songs – a list of song dictionaries or a single song dictionary. required keys: ‘id’ for library songs or ‘nid’ and ‘trackType’ for store songs.
  • rating – set to '0' (no thumb), '1' (down thumb), or '5' (up thumb).
Mobileclient.change_song_metadata(songs)

Changes the metadata of tracks. Returns a list of the song ids changed.

Parameters:songs – a list of song dictionaries or a single song dictionary.

Currently, only the rating key can be changed. Set it to '0' (no thumb), '1' (down thumb), or '5' (up thumb).

You can also use this to rate store tracks that aren’t in your library, eg:

song = mc.get_track_info('<some store track id>')
song['rating'] = '5'
mc.change_song_metadata(song)
Mobileclient.delete_songs(library_song_ids)

Deletes songs from the library. Returns a list of deleted song ids.

Parameters:song_ids – a list of song ids, or a single song id.
Mobileclient.get_top_songs()

Returns a list of dictionaries that each represent a track.

Only store tracks will be returned.

Tops songs seem to be an auto-generated playlist of positively-rated songs (Thumbs up).

See get_track_info() for the format of a track dictionary.

Mobileclient.increment_song_playcount(song_id, plays=1, playtime=None)

Increments a song’s playcount and returns its song id.

Params song_id:a song id. Providing the id of a store track that has been added to the library will not increment the corresponding library song’s playcount. To do this, use the ‘id’ field (which looks like a uuid and doesn’t begin with ‘T’), not the ‘nid’ field.
Params plays:(optional) positive number of plays to increment by. The default is 1.
Params playtime:
 (optional) a datetime.datetime of the time the song was played. It will default to the time of the call.
Mobileclient.add_store_track(store_song_id)

Adds a store track to the library

Returns the library track id of added store track.

Parameters:store_song_id – store song id
Mobileclient.add_store_tracks(store_song_ids)

Add store tracks to the library

Returns a list of the library track ids of added store tracks.

Parameters:store_song_ids – a list of store song ids or a single store song id
Mobileclient.get_station_track_stream_url(song_id, wentry_id, session_token, quality='hi')

Returns a url that will point to an mp3 file.

This is only for use by free accounts, and requires a call to get_station_info() first to provide wentry_id and session_token. Subscribers should instead use get_stream_url().

Parameters:
  • song_id – a single song id
  • wentry_id – a free radio station track entry id (wentryid from get_station_info())
  • session_token – a free radio station session token (sessionToken from get_station_info())
  • quality – (optional) stream bits per second quality One of three possible values, hi: 320kbps, med: 160kbps, low: 128kbps. The default is hi

Playlists

Like songs, playlists have unique ids within a library. However, their names do not need to be unique.

The tracks making up a playlist are referred to as ‘playlist entries’, and have unique entry ids within the entire library (not just their containing playlist).

Mobileclient.get_all_playlists(incremental=False, include_deleted=None, updated_after=None)

Returns a list of dictionaries that each represent a playlist.

Parameters:
  • incremental – if True, return a generator that yields lists of at most 1000 playlists as they are retrieved from the server. This can be useful for presenting a loading bar to a user.
  • include_deleted – ignored. Will be removed in a future release.
  • updated_after – a datetime.datetime; defaults to unix epoch If provided, deleted playlists may be returned.

Here is an example playlist dictionary:

{
     # can also be SHARED (public/subscribed to), MAGIC or omitted
    'type': 'USER_GENERATED',

    'kind': 'sj#playlist',
    'name': 'Something Mix',
    'deleted': False,
    'lastModifiedTimestamp': '1325458766483033',
    'recentTimestamp': '1325458766479000',
    'shareToken': '<long string>',
    'ownerProfilePhotoUrl': 'http://lh3.googleusercontent.com/...',
    'ownerName': 'Simon Weber',
    'accessControlled': False,  # has to do with shared playlists
    'creationTimestamp': '1325285553626172',
    'id': '3d72c9b5-baad-4ff7-815d-cdef717e5d61'
}
Mobileclient.get_all_user_playlist_contents()

Retrieves the contents of all user-created playlists – the Mobileclient does not support retrieving only the contents of one playlist.

This will not return results for public playlists that the user is subscribed to; use get_shared_playlist_contents() instead.

The same structure as get_all_playlists() will be returned, but with the addition of a 'tracks' key in each dict set to a list of properly-ordered playlist entry dicts.

Here is an example playlist entry for an individual track:

{
    'kind': 'sj#playlistEntry',
    'deleted': False,
    'trackId': '2bb0ab1c-ce1a-3c0f-9217-a06da207b7a7',
    'lastModifiedTimestamp': '1325285553655027',
    'playlistId': '3d72c9b5-baad-4ff7-815d-cdef717e5d61',
    'absolutePosition': '01729382256910287871',  # denotes playlist ordering
    'source': '1',  # '2' if hosted on Google Music, '1' otherwise (see below)
    'creationTimestamp': '1325285553655027',
    'id': 'c9f1aff5-f93d-4b98-b13a-429cc7972fea' ## see below
}

If a user uploads local music to Google Music using the Music Manager, Google will attempt to match each uploaded track to a track already hosted on its servers. If a match is found for a track, the playlist entry key 'source' has the value '2', and the entry will have a key 'track' with a value that is a dict of track metadata (title, artist, etc).

If a track is not hosted on Google Music, then the playlist entry key 'source' has the value '1', and may not have a 'track' key (e.g., for an MP3 without ID3 tags). In this case, the key 'trackId' corresponds to the column ServerId in the table XFILES in Music Manager’s local SQLite database (stored, e.g., at ~/Library/ApplicationSupport/Google/MusicManager/ServerDatabase.db on OS X). Among other things, the SQLite database exposes the track’s local file path, and Music Manager’s imputed metadata.

(Note that the above behavior is documented for the Music Manager set to sync from local Folders, and may differ if it instead syncs from iTunes.)

Mobileclient.get_shared_playlist_contents(share_token)

Retrieves the contents of a public playlist.

Parameters:share_token

from playlist['shareToken'], or a playlist share url (https://play.google.com/music/playlist/<token>).

Note that tokens from urls will need to be url-decoded, eg AM...%3D%3D becomes AM...==.

For example, to retrieve the contents of a playlist that the user is subscribed to:

subscribed_to = [p for p in mc.get_all_playlists() if p.get('type') == 'SHARED']
share_tok = subscribed_to[0]['shareToken']
tracks = mc.get_shared_playlist_contents(share_tok)

The user need not be subscribed to a playlist to list its tracks.

Returns a list of playlist entries with structure the same as those returned by get_all_user_playlist_contents(), but without the 'clientId' or 'playlistId' keys.

Mobileclient.create_playlist(name, description=None, public=False)

Creates a new empty playlist and returns its id.

Parameters:
  • name – the desired title. Creating multiple playlists with the same name is allowed.
  • description – (optional) the desired description
  • public – (optional) if True and the user has a subscription, share playlist.
Mobileclient.delete_playlist(playlist_id)

Deletes a playlist and returns its id.

Parameters:playlist_id – the id to delete.
Mobileclient.edit_playlist(playlist_id, new_name=None, new_description=None, public=None)

Changes the name of a playlist and returns its id.

Parameters:
  • playlist_id – the id of the playlist
  • new_name – (optional) desired title
  • new_description – (optional) desired description
  • public – (optional) if True and the user has a subscription, share playlist.
Mobileclient.add_songs_to_playlist(playlist_id, song_ids)

Appends songs to the end of a playlist. Returns a list of playlist entry ids that were added.

Parameters:
  • playlist_id – the id of the playlist to add to.
  • song_ids – a list of song ids, or a single song id. These can be 'storeId' from a store song, 'id' from an uploaded song, or 'trackId' from a playlist entry.

Playlists have a maximum size of 1000 songs. Calls may fail before that point (presumably) due to an error on Google’s end (see #239).

Mobileclient.remove_entries_from_playlist(entry_ids)

Removes specific entries from a playlist. Returns a list of entry ids that were removed.

Parameters:entry_ids – a list of entry ids, or a single entry id.
Mobileclient.reorder_playlist_entry(entry, to_follow_entry=None, to_precede_entry=None)

Reorders a single entry in a playlist and returns its id.

Read reorder_playlist_entry(foo, bar, gaz) as “reorder playlist entry foo to follow entry bar and precede entry gaz.”

Parameters:
  • entry – the playlist entry to move.
  • to_follow_entry – the playlist entry that will come before entry in the resulting playlist, or None if entry is to be the first entry in the playlist.
  • to_precede_entry – the playlist entry that will come after entry in the resulting playlist or None if entry is to be the last entry in the playlist.

reorder_playlist_entry(foo) is invalid and will raise ValueError; provide at least one of to_follow_entry or to_precede_entry.

Leaving to_follow_entry or to_precede_entry as None when entry is not to be the first or last entry in the playlist is undefined.

All params are dicts returned by get_all_user_playlist_contents() or get_shared_playlist_contents().

Radio Stations

Radio Stations are available for free in the US only. A subscription is required in other countries.

Mobileclient.get_all_stations(incremental=False, include_deleted=None, updated_after=None)

Retrieve all library stations.

Returns a list of dictionaries that each represent a radio station.

This includes any stations listened to recently, which might not be in the library.

Parameters:
  • incremental – if True, return a generator that yields lists of at most 1000 stations as they are retrieved from the server. This can be useful for presenting a loading bar to a user.
  • include_deleted – ignored. Will be removed in a future release.
  • updated_after – a datetime.datetime; defaults to unix epoch

Here is an example station dictionary:

{
    'imageUrl': 'http://lh6.ggpht.com/...',
    'kind': 'sj#radioStation',
    'name': 'station',
    'deleted': False,
    'lastModifiedTimestamp': '1370796487455005',
    'recentTimestamp': '1370796487454000',
    'clientId': 'c2639bf4-af24-4e4f-ab37-855fc89d15a1',
    'seed':
    {
        'kind': 'sj#radioSeed',
        'trackLockerId': '7df3aadd-9a18-3dc1-b92e-a7cf7619da7e'
        # possible keys:
        #  albumId, artistId, genreId, trackId, trackLockerId
    },
    'id': '69f1bfce-308a-313e-9ed2-e50abe33a25d',
    'inLibrary': True
},
Mobileclient.create_station(name, track_id=None, artist_id=None, album_id=None, genre_id=None, playlist_token=None, curated_station_id=None)

Creates a radio station and returns its id.

Parameters:
  • name – the name of the station to create
  • *_id – the id of an item to seed the station from.
  • playlist_token – The shareToken of a playlist to seed the station from.

Exactly one of the id/token params must be provided, or ValueError will be raised.

Mobileclient.delete_stations(station_ids)

Deletes radio stations and returns their ids.

Parameters:station_ids – a single id, or a list of ids to delete
Mobileclient.get_station_tracks(station_id, num_tracks=25, recently_played_ids=None)

Returns a list of dictionaries that each represent a track.

Each call performs a separate sampling (with replacement?) from all possible tracks for the station.

Nonexistent stations will return an empty list.

Parameters:
  • station_id – the id of a radio station to retrieve tracks from. Use the special id 'IFL' for the “I’m Feeling Lucky” station.
  • num_tracks – the number of tracks to retrieve
  • recently_played_ids – a list of recently played track ids retrieved from this station. This avoids playing duplicates.

See get_all_songs() for the format of a track dictionary.

Podcasts

Mobileclient.get_all_podcast_series(device_id=None, incremental=False, include_deleted=None, updated_after=None)

Retrieve list of user-subscribed podcast series.

Parameters:
  • device_id

    (optional) defaults to android_id from login.

    Otherwise, provide a mobile device id as a string. Android device ids are 16 characters, while iOS ids are uuids with ‘ios:’ prepended.

    If you have already used Google Music on a mobile device, Mobileclient.get_registered_devices will provide at least one working id. Omit '0x' from the start of the string if present.

    Registered computer ids (a MAC address) will not be accepted and will 403.

    Providing an unregistered mobile device id will register it to your account, subject to Google’s device limits. Registering a device id that you do not own is likely a violation of the TOS.

  • incremental – if True, return a generator that yields lists of at most 1000 podcast series as they are retrieved from the server. This can be useful for presenting a loading bar to a user.
  • include_deleted – ignored. Will be removed in a future release.
  • updated_after – a datetime.datetime; defaults to unix epoch

Returns a list of podcast series dicts.

Here is an example podcast series dict:

{
    'art': [
        {
            'aspectRatio': '1',
            'autogen': False,
            'kind': 'sj#imageRef',
            'url': 'http://lh3.googleusercontent.com/bNoyxoGTwCGkUscMjHsvKe5W80uMOfq...'
        }
    ],
    'author': 'Chris Hardwick',
    'continuationToken': '',
    'description': 'I am Chris Hardwick. I am on TV a lot and have a blog at '
                   'nerdist.com. This podcast is basically just me talking about '
                   'stuff and things with my two nerdy friends Jonah Ray and Matt '
                   'Mira, and usually someone more famous than all of us. '
                   'Occasionally we swear because that is fun. I hope you like '
                   "it, but if you don't I'm sure you will not hesitate to unfurl "
                   "your rage in the 'reviews' section because that's how the "
                   'Internet works.',
    'explicitType': '1',
    'link': 'http://nerdist.com/',
    'seriesId': 'Iliyrhelw74vdqrro77kq2vrdhy',
    'title': 'The Nerdist',
    'totalNumEpisodes': 829,
    'userPreferences': {
        'autoDownload': False,
        'notifyOnNewEpisode': False,
        'subscribed': True
    }
}
Mobileclient.get_all_podcast_episodes(device_id=None, incremental=False, include_deleted=None, updated_after=None)

Retrieve list of episodes from user-subscribed podcast series.

Parameters:
  • device_id

    (optional) defaults to android_id from login.

    Otherwise, provide a mobile device id as a string. Android device ids are 16 characters, while iOS ids are uuids with ‘ios:’ prepended.

    If you have already used Google Music on a mobile device, Mobileclient.get_registered_devices will provide at least one working id. Omit '0x' from the start of the string if present.

    Registered computer ids (a MAC address) will not be accepted and will 403.

    Providing an unregistered mobile device id will register it to your account, subject to Google’s device limits. Registering a device id that you do not own is likely a violation of the TOS.

  • incremental – if True, return a generator that yields lists of at most 1000 podcast episodes as they are retrieved from the server. This can be useful for presenting a loading bar to a user.
  • include_deleted – ignored. Will be removed in a future release.
  • updated_after – a datetime.datetime; defaults to unix epoch

Returns a list of podcast episode dicts.

Here is an example podcast episode dict:

{
    'art': [
        {
            'aspectRatio': '1',
            'autogen': False,
            'kind': 'sj#imageRef',
            'url': 'http://lh3.googleusercontent.com/bNoyxoGTwCGkUscMjHsvKe5W80uMOfq...'
        }
    ],
    'deleted': False,
    'description': 'Comedian Bill Burr yelled at Philadelphia, Chris vaguely '
                   'understands hockey, Jonah understands it even less, and Matt '
                   'is weirdly not tired of the running "Matt loves the Dave '
                   'Matthews Band" joke, though I'm sure all of you are.',
    'durationMillis': '4310000',
    'episodeId': 'D6i26frpxu53t2ws3lpbjtpovum',
    'explicitType': '2',
    'fileSize': '69064793',
    'publicationTimestampMillis': '1277791500000',
    'seriesId': 'Iliyrhelw74vdqrro77kq2vrdhy',
    'seriesTitle': 'The Nerdist',
    'title': 'Bill Burr'
}
Mobileclient.add_podcast_series(podcast_id, notify_on_new_episode=False)

Subscribe to a podcast series.

Parameters:
  • podcast_id – A podcast series id (hint: they always start with ‘I’).
  • notify_on_new_episode – Get device notifications on new episodes.

Returns podcast series id of added podcast series

Mobileclient.delete_podcast_series(podcast_id)

Unsubscribe to a podcast series.

Parameters:podcast_id – A podcast series id (hint: they always start with ‘I’).

Returns podcast series id of removed podcast series

Mobileclient.edit_podcast_series(podcast_id, subscribe=True, notify_on_new_episode=False)

Edit a podcast series subscription.

Parameters:
  • podcast_id – A podcast series id (hint: they always start with ‘I’).
  • subscribe – Subscribe to podcast.
  • notify_on_new_episode – Get device notifications on new episodes.

Returns podcast series id of edited podcast series

Mobileclient.get_podcast_episode_stream_url(podcast_episode_id, device_id=None, quality='hi')

Returns a url that will point to an mp3 file.

Parameters:
  • podcast_episde_id – a single podcast episode id (hint: they always start with ‘D’).
  • device_id

    (optional) defaults to android_id from login.

    Otherwise, provide a mobile device id as a string. Android device ids are 16 characters, while iOS ids are uuids with ‘ios:’ prepended.

    If you have already used Google Music on a mobile device, Mobileclient.get_registered_devices will provide at least one working id. Omit '0x' from the start of the string if present.

    Registered computer ids (a MAC address) will not be accepted and will 403.

    Providing an unregistered mobile device id will register it to your account, subject to Google’s device limits. Registering a device id that you do not own is likely a violation of the TOS.

  • quality – (optional) stream bits per second quality One of three possible values, hi: 320kbps, med: 160kbps, low: 128kbps. The default is hi
When handling the resulting url, keep in mind that:
  • you will likely need to handle redirects
  • the url expires after a minute
  • only one IP can be streaming music at once. This can result in an http 403 with X-Rejected-Reason: ANOTHER_STREAM_BEING_PLAYED.

The file will not contain metadata.

Misc

Mobileclient.get_browse_podcast_hierarchy()

Retrieve the hierarchy of podcast browse genres.

Returns a list of podcast genres and subgenres:

{
    "groups": [
        {
            "id": "JZCpodcasttopchart",
            "displayName": "Top Charts",
            "subgroups": [
                {
                 "id": "JZCpodcasttopchartall",
                 "displayName": "All categories"
                },
                {
                 "id": "JZCpodcasttopchartarts",
                 "displayName": "Arts"
                },
                {
                 "id": "JZCpodcasttopchartbusiness",
                 "displayName": "Business"
                },
                {
                 "id": "JZCpodcasttopchartcomedy",
                 "displayName": "Comedy"
                },
                {
                 "id": "JZCpodcasttopcharteducation",
                 "displayName": "Education"
                },
                {
                 "id": "JZCpodcasttopchartgames",
                 "displayName": "Games & hobbies"
                },
                {
                 "id": "JZCpodcasttopchartgovernment",
                 "displayName": "Government & organizations"
                },
                {
                 "id": "JZCpodcasttopcharthealth",
                 "displayName": "Health"
                },
                {
                 "id": "JZCpodcasttopchartkids",
                 "displayName": "Kids & families"
                },
                {
                 "id": "JZCpodcasttopchartmusic",
                 "displayName": "Music"
                },
                {
                 "id": "JZCpodcasttopchartnews",
                 "displayName": "News & politics"
                },
                {
                 "id": "JZCpodcasttopchartreligion",
                 "displayName": "Religion & spirituality"
                },
                {
                 "id": "JZCpodcasttopchartscience",
                 "displayName": "Science & medicine"
                },
                {
                 "id": "JZCpodcasttopchartsociety",
                 "displayName": "Society & culture"
                },
                {
                 "id": "JZCpodcasttopchartsports",
                 "displayName": "Sports & recreation"
                },
                {
                 "id": "JZCpodcasttopcharttechnology",
                 "displayName": "Technology"
                },
                {
                 "id": "JZCpodcasttopcharttv",
                 "displayName": "TV & film"
                }
            ]
        }
    ]
}
Mobileclient.get_browse_podcast_series(genre_id='JZCpodcasttopchartall')

Retrieve podcast series from browse podcasts by genre.

Parameters:genre_id – A podcast genre id as returned by get_podcast_browse_hierarchy(). Defaults to Top Chart ‘All categories’.

Returns a list of podcast series dicts.

Here is an example podcast series dict:

{
    'art': [
        {
            'aspectRatio': '1',
            'autogen': False,
            'kind': 'sj#imageRef',
            'url': 'http://lh3.googleusercontent.com/liR-Pm7EhB58wrAa4uo9Y33LcJJ8keU...'
        }
    ],
    'author': 'NBC Sports Radio',
    'continuationToken': '',
    'description': 'Mike Florio talks about the biggest NFL topics with the '
                  'people who are most passionate about the game: League execs, '
                  'players, coaches and the journalists who cover pro football.',
    'explicitType': '2',
    'link': 'https://audioboom.com/channel/pro-football-talk-live-with-mike-florio',
    'seriesId': 'I3iad5heqorm3nck6yp7giruc5i',
    'title': 'Pro Football Talk Live with Mike Florio',
    'totalNumEpisodes': 0
}
Mobileclient.get_listen_now_items()

Returns a list of dictionaries of Listen Now albums and stations.

See get_listen_now_situations() for Listen Now situations.

Here is an example Listen Now album:

{
  'album': {
    'artist_metajam_id': 'A2mfgoustq7iqjdbvlenw7pnap4',
    'artist_name': 'Justin Bieber',
    'artist_profile_image': {
      'url': 'http://lh3.googleusercontent.com/XgktDR74DWE9xD...'',
    },
    'description': 'Purpose is the fourth studio album by Canadian...',
    'description_attribution': {
      'kind': 'sj#attribution',
      'license_title': 'Creative Commons Attribution CC-BY-SA 4.0',
      'license_url': 'http://creativecommons.org/licenses/by-sa/4.0/legalcode',
      'source_title': 'Wikipedia',
      'source_url': 'http://en.wikipedia.org/wiki/Purpose_(Justin_Bieber_album)',
    },
    'id': {
      'artist': 'Justin Bieber',
      'metajamCompactKey': 'Bqpez5cimsze2fh6w7j2rcf55xa',
      'title': 'Purpose (Deluxe)',
    },
    'title': 'Purpose (Deluxe)'
    'images': [
      {
        'kind': 'sj#imageRef',
        'url': 'http://lh3.googleusercontent.com/m66cbl4Jl3VNz...',
      },
    ],
  }
  'kind': 'sj#listennowitem',
  'suggestion_reason': '9',
  'suggestion_text': 'Popular album on Google Play Music',
  'type': '1'
}

Here is an example Listen Now station:

{
  'radio_station': {
    'id': {
      'seeds': [
        {
          'artistId': 'Ax6ociylvowozcz2iepfqsar54i',
          'kind': 'sj#radioSeed',
          'metadataSeed': {
            'artist': {
              'artistArtRef': 'http://lh3.googleusercontent.com/x9qukAx...',
              'artistArtRefs': [
                {
                  'aspectRatio': '2',
                  'autogen': False,
                  'kind': 'sj#imageRef',
                  'url': 'http://lh3.googleusercontent.com/x9qukAx...',
                },
              ],
              'artistId': 'Ax6ociylvowozcz2iepfqsar54i',
              'artist_bio_attribution': {
              'kind': 'sj#attribution',
              'source_title': 'artist representative',
              },
              'kind': 'sj#artist',
              'name': 'Drake',
            },
            'kind': 'sj#radioSeedMetadata',
          },
         'seedType': '3',
        },
      ]
    },
    'title': 'Drake',
  },
  'compositeArtRefs': [
    {
      'aspectRatio': '2',
      'kind': 'sj#imageRef',
      'url': 'http://lh3.googleusercontent.com/rE39ky1yZN...',
    },
    {
      'aspectRatio': '1',
      'kind': 'sj#imageRef',
      'url': 'http://lh3.googleusercontent.com/Pcwg_HngBr...',
    },
  ],
  'images': [
    {
      'aspectRatio': '2',
      'autogen': False,
      'kind': 'sj#imageRef',
      'url': 'http://lh3.googleusercontent.com/x9qukAx_TMam...',
    },
  ],
  'suggestion_reason': '9',
  'suggestion_text': 'Popular artist on Google Play Music',
  'type': '3'
}
Mobileclient.get_listen_now_situations()

Returns a list of dictionaries that each represent a Listen Now situation.

See get_listen_now_items() for Listen Now albums and stations.

A situation contains a list of related stations or other situations.

Here is an example situation:

{
    'description': 'Select a station of today's most popular songs.',
    'id': 'Ntiiwllegkw73p27o236mfsj674',
    'imageUrl': 'http://lh3.googleusercontent.com/egm4NgIK-Cmh84GjVgH...',
    'stations': [
        {
            'compositeArtRefs': [
                {
                    'aspectRatio': '2',
                    'kind': 'sj#imageRef',
                    'url': 'http://lh3.googleusercontent.com/ffDI377y...',
                },
            ],
            'contentTypes': ['1'],
            'description': "This playlist features today's biggest pop songs...",
            'imageUrls': [
                {
                    'aspectRatio': '1',
                    'autogen': False,
                    'kind': 'sj#imageRef',
                    'url': 'http://lh3.googleusercontent.com/B4iKX23Z...',
                },
            ],
            'kind': 'sj#radioStation',
            'name': "Today's Pop Hits",
            'seed': {
                'curatedStationId': 'Lgen6kdn43tz5b3edimqd5e4ckq',
                'kind': 'sj#radioSeed',
                'seedType': '9',
            },
            'skipEventHistory': [],
            'stationSeeds': [
                {
                    'curatedStationId': 'Lgen6kdn43tz5b3edimqd5e4ckq',
                    'kind': 'sj#radioSeed',
                    'seedType': '9',
                },
            ],
        }
    ],
    'title': "Today's Biggest Hits",
    'wideImageUrl': 'http://lh3.googleusercontent.com/13W-bm3sNmSfOjUkEqY...'
}