An unofficial client library for Google Music.

gmusicapi: an unofficial API for Google Play Music

gmusicapi allows control of Google Music with Python.

from gmusicapi import Mobileclient

api = Mobileclient()
# after running api.perform_oauth() once:
api.oauth_login('<a previously-registered device id>')
# => True

library = api.get_all_songs()
sweet_track_ids = [track['id'] for track in library
                   if track['artist'] == 'The Cat Empire']

playlist_id = api.create_playlist('Rad muzak')
api.add_songs_to_playlist(playlist_id, sweet_track_ids)

gmusicapi is not supported nor endorsed by Google.

That said, it's actively maintained, and powers a bunch of cool projects:

Getting started

Start with the usage docs, which will guide you through installation and the available apis.

Once you're up and running, you can explore the rest of the docs at http://unofficial-google-music-api.readthedocs.io.

If the documentation doesn't answer your questions, or you just want to get in touch, either drop by #gmusicapi on Freenode or shoot me an email.

Status and updates

build_status

  • January 2020: Python 2 support dropped.
  • November 2018: proper OAuth support for the mobileclient.
  • February 2016: Python 3 support!
  • September 2015: Google switched to a new music uploading endpoint, breaking uploading for outdated versions of gmusicapi.
  • June 2015: Full mobileclient and webclient functionality was restored.
  • May 2015: Limited mobileclient functionality was restored.
  • April 2015: Google deprecated clientlogin, breaking both the webclient and mobileclient.
  • November 2013: I started working fulltime at Venmo, meaning this project is back to night and weekend development.

For fine-grained development updates, follow me on Twitter: @simonmweber.

Comments
  • GetUploadSession error 404: the request was rejected

    GetUploadSession error 404: the request was rejected

    pinned: here's a workaround to test: https://github.com/simon-weber/gmusicapi/issues/380#issuecomment-156743098


    Hello,

    Everytime I try to upload using gmupload.py from gmusicapi-scripts to google music I get :

    GetUploadSession error 404: the request was rejected
    

    for every song.

    Then if I retry I get `ALREADY EXISTS``.

    I can't see those songs in google music.

    gmusicapi 7.0.0 OpenSSL 1.0.1k 8 Jan 2015 Python 2.7.9

    log from gmusicapi.log

    2015-11-11 13:51:46,380 - gmusicapi.Musicmanager1 (shared:201) [DEBUG]: ProvideSample(args=[u'/path/to/my/song/1.mp3. ...', <gmusicapi.protocol.upload_pb2.SignedChallengeInfo object at 0x7fd2d5d059b0>, <gmusicapi.protocol.locker_pb2.Track object at 0x7fd2d5d05a28>, 'XX:XX:XX:XX:XX:XX', ''], kwargs={})
    2015-11-11 13:51:46,625 - gmusicapi.Musicmanager1 (shared:242) [DEBUG]: response_type: SAMPLE_RESPONSE
    sample_response {
      track_sample_response {
        client_track_id: "XXXXXXXXXXXXXXXXXXXXXX"
        response_code: UPLOAD_REQUESTED
        server_track_id: "XXXXXX-XXXXXX-XXXXXX-XXXX"
        expect_match: false
      }
    }
    policy {
      pause_uploads: false
      abort: false
      retry_in_minutes: 5
      bandwidth_cap_kbps: 12000
      pause_downloads: false
      download_bandwidth_cap_kbps: 16000
      send_analytics: false
      enable_gapless: true
      enable_m4p: true
    }
    
    2015-11-11 13:51:46,631 - gmusicapi.Musicmanager1 (shared:201) [DEBUG]: UpdateUploadState(args=['start', 'XX:XX:XX:XX:XX:XX'], kwargs={})
    2015-11-11 13:51:46,674 - gmusicapi.Musicmanager1 (shared:242) [DEBUG]: response_type: SAMPLE_RESPONSE
    sample_response {
    }
    policy {
      pause_uploads: false
      abort: false
      retry_in_minutes: 5
      bandwidth_cap_kbps: 12000
      pause_downloads: false
      download_bandwidth_cap_kbps: 16000
      send_analytics: false
      enable_gapless: true
      enable_m4p: true
    }
    2015-11-11 13:51:46,681 - gmusicapi.Musicmanager1 (shared:201) [DEBUG]: GetUploadSession(args=['XX:XX:XX:XX:XX:XX', 0, <gmusicapi.protocol.locker_pb2.Track object at 0x7fd2d5d05a28>, u'/path/to/my/song. ...', u'XXXXX-XXXXX-XXXXX-XXXXXX', False], kwargs={})
    2015-11-11 13:51:46,884 - gmusicapi.Musicmanager1 (shared:242) [DEBUG]: {u'errorMessage': {u'additionalInfo': {u'uploader_service.GoogleRupioAdditionalInfo': {u'completionInfo': {u'status': u'REJECTED', u'customerSpecificInfo': {u'ResponseCode': 404}}, u'requestRejectedInfo': {u'reasonDescription': u'agent_rejected'}}}, u'reason': u'REQUEST_REJECTED', u'upload_id': u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'}}
    2015-11-11 13:51:46,884 - gmusicapi.Musicmanager1 (musicmanager:538) [DEBUG]: problem getting upload session: the request was rejected
    code=404 retrying=False
    2015-11-11 13:51:52,888 - gmusicapi.Musicmanager1 (musicmanager:549) [WARNING]: giving up on upload session for '/path/to/my/song/1.mp3': GetUploadSession error 404: the request was rejected
    2015-11-11 13:51:52,893 - gmusicapi.Musicmanager1 (shared:201) [DEBUG]: UpdateUploadState(args=['stopped', 'XX:XX:XX:XX:XX:XX'], kwargs={})
    2015-11-11 13:51:52,937 - gmusicapi.Musicmanager1 (shared:242) [DEBUG]: response_type: SAMPLE_RESPONSE
    sample_response {
    }
    policy {
      pause_uploads: false
      abort: false
      retry_in_minutes: 5
      bandwidth_cap_kbps: 12000
      pause_downloads: false
      download_bandwidth_cap_kbps: 16000
      send_analytics: false
      enable_gapless: true
      enable_m4p: true
    }
    
  • Uploading broken: DecodeError, BadStatusLine, session response empty

    Uploading broken: DecodeError, BadStatusLine, session response empty

    Reports that it's uploaded correctly, but it's missed everything in my library.

    Running the tests, I see the following:

    2012-11-21 22:08:45,573 - gmusicapi.UnitTestedApi - WARNING - Received an unexpected response from call loadalltracks. 2012-11-21 22:08:45,821 - gmusicapi.UnitTestedApi - WARNING - error was: Failed to validate field 'playlist' list schema: additional properties not defined by 'properties' are not allowed in list item .2012-11-21 22:09:55,008 - gmusicapi.UnitTestedApi - WARNING - Received an unexpected response from call loadalltracks. 2012-11-21 22:09:55,250 - gmusicapi.UnitTestedApi - WARNING - error was: Failed to validate field 'playlist' list schema: additional properties not defined by 'properties' are not allowed in list item 2012-11-21 22:10:56,259 - gmusicapi.UnitTestedApi - WARNING - Received an unexpected response from call loadalltracks. 2012-11-21 22:10:56,488 - gmusicapi.UnitTestedApi - WARNING - error was: Failed to validate field 'playlist' list schema: additional properties not defined by 'properties' are not allowed in list item

    ....E

    ERROR: test_up_deletion (main.TestWCApiCalls)

    Traceback (most recent call last): File "/usr/local/lib/python2.7/dist-packages/gmusicapi/test/integration_test_api.py", line 211, in test_up_deletion self.run_steps("updel_") File "/usr/local/lib/python2.7/dist-packages/gmusicapi/test/utils.py", line 234, in run_steps step() File "/usr/local/lib/python2.7/dist-packages/gmusicapi/test/integration_test_api.py", line 185, in updel_1_upload result = self.api.upload(some_files) File "", line 2, in upload File "/usr/local/lib/python2.7/dist-packages/gmusicapi/utils/utils.py", line 136, in wrapper return function(_args, *_kw) File "", line 2, in upload File "/usr/local/lib/python2.7/dist-packages/gmusicapi/utils/utils.py", line 113, in wrapper return function(_args, *_kw) File "/usr/local/lib/python2.7/dist-packages/gmusicapi/api.py", line 690, in upload fname_to_id = self._upload_mp3s(map(lambda f: f.name, upload_files)) File "/usr/local/lib/python2.7/dist-packages/gmusicapi/api.py", line 781, in _upload_mp3s metadataresp = self._mm_pb_call("metadata", metadata_request) File "/usr/local/lib/python2.7/dist-packages/gmusicapi/api.py", line 887, in _mm_pb_call res.ParseFromString(self.session.post_protobuf(url, req)) File "/usr/local/lib/python2.7/dist-packages/gmusicapi/api.py", line 1058, in post_protobuf resp = self.android.getresponse() File "/usr/lib/python2.7/httplib.py", line 1030, in getresponse response.begin() File "/usr/lib/python2.7/httplib.py", line 407, in begin version, status, reason = self._read_status() File "/usr/lib/python2.7/httplib.py", line 371, in _read_status raise BadStatusLine(line) BadStatusLine: ''


    Ran 6 tests in 298.702s

    FAILED (errors=1)

  • OSError(

    OSError("a valid MAC could not be determined.")

    I started getting this error on every login attempt on a Windows 10 machine. Until a couple of days before it didn't complain and when I try this on a VirtualBox runnig Ubuntu it works perfectly. Any idea?

  • Add support for free radio stations

    Add support for free radio stations

    Hi,

    I have added support for free radios on the Kodi addon adding the missing calls in gmusicapi and changing others, please check fork below: https://github.com/simon-weber/gmusicapi/compare/develop...foreverguest:develop

    But this changes the data returned by create_station function, is that ok? Do you suggest another approach?

  • Request: Python3 support?

    Request: Python3 support?

    I use rhythmbox-gmusic to stream Google Play via Rhythmbox while I'm at work. I recently upgraded my Ubuntu laptop to 14.04 Trusty and found that the Rhythmbox version offered in the repos is 3.x, which uses Python 3 under the hood. I'm refraining from upgrading my workstation for the time being.

    I'm just wondering if there are any plans to update this API to support Python3? I realize it's not a simple task, especially considering that mutagen's maintainer seemed very passionate about his disdain for Python3. If it would help at all, in that thread it seems that someone forked mutagen and created mutagenx which works with py3k (also here on GitHub).

  • AA streaming broken: http 403 STREAM_ERROR_98

    AA streaming broken: http 403 STREAM_ERROR_98

    As of yesterday, two new params are required for AA streaming: slt and sig. Both need to be present and correct to stream, otherwise you'll get the 403.

    It looks like slt is a psuedo-random salt, which gets hashed with the songid and a secret embedded in the source to result in sig.

  • Mobileclient login stopped working with app passwords

    Mobileclient login stopped working with app passwords

    As of October 4, I'm no longer able to authenticate the Mobileclient interface using an app password on my 2FA-enabled account. It was working on October 3.

    I've tried:

    • Updated to gmusicapi 11.0.3 (Python 2.7)
    • Tried generating a new app password. The old one is still present and does not indicate expiration.
    • Verified that I can authenticate using Mobileclient to a different account that does not use 2FA.

    Is it just me, or is Mobileclient broken for other 2FA users as well?

  • Application specific password or two-factor auth

    Application specific password or two-factor auth

    This is not a feature request per se. I'd like to know whether it's (or will be) possible to use application specific password like the Google Music Manager does in case user has two-factor auth enabled. The question is more like, whether the API can handle it (currently it throws an exception)?

  • Cannot import Mobileclient in python app engine

    Cannot import Mobileclient in python app engine

    I first encountered a protobuf issue, but this fixed it: https://www.simonmweber.com/2013/06/18/python-protobuf-on-app-engine.html

    Now it cannot find pwd. I read that it might have something to do with requests, and I have tried multiple version with no luck.

    File "/Users/*/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 240, in Handle
        handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
      File "/Users/*/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 299, in _LoadHandler
        handler, path, err = LoadObject(self._handler)
      File "/Users/*/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 85, in LoadObject
        obj = __import__(path[0])
      File "/Users/*/git/*/main.py", line 30, in <module>
        from gmusicapi import Mobileclient
      File "libs/gmusicapi/__init__.py", line 9, in <module>
        from gmusicapi.clients import Webclient, Musicmanager, Mobileclient
      File "libs/gmusicapi/clients/__init__.py", line 1, in <module>
        from gmusicapi.clients.webclient import Webclient
      File "libs/gmusicapi/clients/webclient.py", line 6, in <module>
        from gmusicapi.clients.shared import _Base
      File "libs/gmusicapi/clients/shared.py", line 3, in <module>
        from gmusicapi.utils import utils
      File "libs/gmusicapi/utils/utils.py", line 44, in <module>
        log_filepath = os.path.join(my_appdirs.user_log_dir, 'gmusicapi.log')
      File "libs/appdirs.py", line 403, in user_log_dir
        version=self.version)
      File "libs/appdirs.py", line 356, in user_log_dir
        path = user_cache_dir(appname, appauthor, version)
      File "libs/appdirs.py", line 306, in user_cache_dir
        path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache'))
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.py", line 268, in expanduser
        import pwd
      File "/Users/*/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/python/sandbox.py", line 898, in load_module
        raise ImportError('No module named %s' % fullname)
    ImportError: No module named pwd
    
  • Add Python 3 compatibility

    Add Python 3 compatibility

    OK, here it is.

    17:25:17|stum:[~/gmusicapi] (python3-stage2 *%>)$ tox
    ...
    ________________________________________________ summary _________________________________________________
      py27: commands succeeded
      py34: commands succeeded
      py35: commands succeeded
      congratulations :)
    

    The tests work. The example script works. I wasn't able to run the All-Access tests, so if you could help out with that, I'd appreciate it (I'll give it a shot in my application, though).

    Please take a look at what I did in setup.py for protobuf. The 3.0.0b2 seems to be working fine, and since this whole thing is a bit experimental to begin with, it seemed OK. I'm happy to do something else, though.

    This will need a new release of gpsoauth, with the Python 3 compatibility. I've been manually installing it in each tox environment for now.

    I think I incorporated everything from last time, so please let me know what else you'd like me to tackle. Thanks for your patience

  • Upload session fails after a few uploads

    Upload session fails after a few uploads

    Using the latest gmusicapi release, I'm using a script (gmusicapi-scripts by @thebigmunch) to sync my library. After syncing a few tracks (uploading new ones that have been added to my local library recently), I always get this error:

    Traceback (most recent call last): File "./gmsync.py", line 219, in main() File "./gmsync.py", line 202, in main mmw.upload(songs_to_upload, enable_matching=cli['match'], delete_on_success=cli['delete-on-success']) File "/usr/local/lib/python3.5/dist-packages/gmusicapi_wrapper/decorators.py", line 22, in wrapper return function(*args, **kwargs) File "/usr/local/lib/python3.5/dist-packages/gmusicapi_wrapper/musicmanager.py", line 303, in upload for result in self._upload(filepaths, enable_matching=enable_matching, transcode_quality=transcode_quality): File "/usr/local/lib/python3.5/dist-packages/gmusicapi_wrapper/musicmanager.py", line 256, in _upload filepath, enable_matching=enable_matching, transcode_quality=transcode_quality File "", line 2, in upload File "/usr/local/lib/python3.5/dist-packages/gmusicapi/utils/utils.py", line 616, in wrapper return function(*args, **kw) File "", line 2, in upload File "/usr/local/lib/python3.5/dist-packages/gmusicapi/utils/utils.py", line 593, in wrapper return function(*args, **kw) File "/usr/local/lib/python3.5/dist-packages/gmusicapi/clients/musicmanager.py", line 578, in upload musicmanager.GetUploadSession.process_session(session) File "/usr/local/lib/python3.5/dist-packages/gmusicapi/protocol/musicmanager.py", line 463, in process_session ['completionInfo']['customerSpecificInfo']['ResponseCode']) KeyError: 'customerSpecificInfo'

    Things I already tried:

    • Re-auth gmusicapi
    • Reboot system
    • Manually updating files to gmusic using the browser (works)

    Any idea what might be the cause of this? Keep in mind that every time I run the sync script, a few tracks get uploaded succesfully (and play fine in gmusic), but after the fifth or sixth track, gmusicapi throws this error.

  • Looks like Google Play Music is going away

    Looks like Google Play Music is going away

  • UnicodeEncodeError with logging when using Mobileclient Search

    UnicodeEncodeError with logging when using Mobileclient Search

    New error popping up:

    --- Logging error ---
    Traceback (most recent call last):
      File "C:\Program Files\Python37\lib\logging\__init__.py", line 985, in emit
        stream.write(msg)
      File "C:\Program Files\Python37\lib\encodings\cp1252.py", line 19, in encode
        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
    UnicodeEncodeError: 'charmap' codec can't encode character '\U0001f49b' in position 32828: character maps to <undefined>
    
    Call Stack:
      File "C:\Program Files\Python37\lib\site-packages\gmusicapi\clients\mobileclient.py", line 1961, in search
        res = self._make_call(mobileclient.Search, query, max_results)
      File "C:\Program Files\Python37\lib\site-packages\gmusicapi\clients\mobileclient.py", line 48, in _make_call
        return super(Mobileclient, self)._make_call(protocol, *args, **kwargs)
      File "C:\Program Files\Python37\lib\site-packages\gmusicapi\clients\shared.py", line 90, in _make_call
        return protocol.perform(self.session, self.validate, *args, **kwargs)
      File "C:\Program Files\Python37\lib\site-packages\gmusicapi\protocol\shared.py", line 247, in perform
        log.debug(cls.filter_response(parsed_response))
    
    

    Happens when calling mobileclient.search("test") and the encoding used for the string doesnt seem to affect it.

  • Invalid artist and album ids on search

    Invalid artist and album ids on search

    When receiving the search results from mobileclient, the song_hits are not valid. So the artist and album Ids does not start with A or B as they are supposed to. Not sure if this affects the gmusicapi when working with that ID, if not it should be at least documented.

    (I am using mopidy-gmusic and there an ID without leading A,B or T is handled as an uploaded song).

  • Replace deprecated validictory with fastest fastjsonschema module

    Replace deprecated validictory with fastest fastjsonschema module

    Hi with this PR I want to propose a replacement for the deprecated validictory module. fastjsonschema module seems to be faster than jsonschema module too. Thanks for this amazing project

  • Mobileclient remove_entries_from_playlist() always returns the input parameters

    Mobileclient remove_entries_from_playlist() always returns the input parameters

    I've been using this function to remove playlist entries successfully, but I notice that according to the documentation, the function remove_entries_from_playlist():

    Returns a list of entry ids that were removed.

    However, it seems that the function will basically return whatever is specified as the input parameter. As a simple example:

    api.remove_entries_from_playlist(u'hello')
    

    Will return [u'hello]', where I would expect it to return None since no playlist entry ID exists with this value. Is my understanding correct here?

    I'm using version 12.0.0, but from the changelog I believe this also applies for the latest version.

    Cheers!

  • Searching for youtube video hits and info requires a GPM subscription

    Searching for youtube video hits and info requires a GPM subscription

    This might be an incredibly stupid issue, but it looks like users that don't subscribe to google play music aren't able to search for songs based on video_hits or extract a youtube video.

    Is there any possible workaround for this, or do you absolutely have to sub to GPM?

Easy Google Translate: Unofficial Google Translate API

easygoogletranslate Unofficial Google Translate API. This library does not need an api key or something else to use, it's free and simple. You can eit

Nov 6, 2022
veez music bot is a telegram music bot project, allow you to play music on voice chat group telegram.
veez music bot is a telegram music bot project, allow you to play music on voice chat group telegram.

?? Veez Music Bot Music bot for playing music on telegram voice chat group. Requirements ?? FFmpeg NodeJS nodesource.com Python 3.7+ PyTgCalls ?? Get

Jun 19, 2022
veez music is a telegram music bot project, allow you to play music on voice chat group telegram.
veez music is a telegram music bot project, allow you to play music on voice chat group telegram.

?? VEEZ MUSIC BOT Veez Music is a telegram bot project that's allow you to play music on telegram voice chat group. Requirements ?? FFmpeg NodeJS node

Aug 29, 2021
ELiza music is a telegram music bot project, allow you to play music on voice chat group telegram.
ELiza music is a telegram music bot project, allow you to play music on voice chat group telegram.

❤️ ?????????? ?????????? ❤️ Unmaintained. The new repo of @MrsElizaRobot is private. (It is no longer based on this source code. The completely rewrit

Dec 8, 2022
First Party data integration solution built for marketing teams to enable audience and conversion onboarding into Google Marketing products (Google Ads, Campaign Manager, Google Analytics).

Megalista Sample integration code for onboarding offline/CRM data from BigQuery as custom audiences or offline conversions in Google Ads, Google Analy

Dec 29, 2022
🐍 The official Python client library for Google's discovery based APIs.

Google API Client This is the Python client library for Google's discovery based APIs. To get started, please see the docs folder. These client librar

Jan 8, 2023
🐍 The official Python client library for Google's discovery based APIs.

Google API Client This is the Python client library for Google's discovery based APIs. To get started, please see the docs folder. These client librar

Dec 31, 2022
Python client library for Google Maps API Web Services

Python Client for Google Maps Services Description Use Python? Want to geocode something? Looking for directions? Maybe matrices of directions? This l

Jan 1, 2023
🔍 Google Search unofficial API for Python with no external dependencies

Python Google Search API Unofficial Google Search API for Python. It uses web scraping in the background and is compatible with both Python 2 and 3. W

Dec 28, 2022
(unofficial) Googletrans: Free and Unlimited Google translate API for Python. Translates totally free of charge.

Googletrans Googletrans is a free and unlimited python library that implemented Google Translate API. This uses the Google Translate Ajax API to make

Jan 4, 2023
rewise is an unofficial wrapper for google search's auto-complete feature

rewise is an unofficial wrapper for google search's auto-complete feature

Jul 19, 2022
Unofficial Python API client for Notion.so
Unofficial Python API client for Notion.so

notion-py Unofficial Python 3 client for Notion.so API v3. Object-oriented interface (mapping database tables to Python classes/attributes) Automatic

Jan 3, 2023
Unofficial Meteor Client wiki

Welcome to the Unofficial Meteor Client wiki! Meteor FAQs | A rewritten and better FAQ page. Installation Guide | A guide on how to install Meteor Cli

Feb 21, 2022
TeslaPy - A Python implementation based on unofficial documentation of the client side interface to the Tesla Motors Owner API
TeslaPy - A Python implementation based on unofficial documentation of the client side interface to the Tesla Motors Owner API

TeslaPy - A Python implementation based on unofficial documentation of the client side interface to the Tesla Motors Owner API, which provides functiona

Dec 30, 2022
JAKYM, Just Another Konsole YouTube-Music. A command line based Youtube music player written in Python with spotify and youtube playlist support
JAKYM, Just Another Konsole YouTube-Music. A command line based Youtube music player written in Python with spotify and youtube playlist support

Just Another Konsole YouTube-Music Overview I wanted to create this application so that I could use the command line to play music easily. I often pla

Jan 1, 2023
A Telegram Music Tag Editor Bot that can remove almost all usernames in the music tags and add own username instead.

Music Tag Editor Bot A Telegram Music Tag Editor Bot that can remove almost all usernames in the music tags and add own username instead. It can also

Oct 21, 2022
VC-Music , Playing music without bot.

VC-Userbot A Telegram Userbot to play or streaming Audio and Video songs / files in Telegram Voice Chats. It's made with PyTgCalls and Pyrogram Requir

Aug 4, 2022
Music bot for playing music on telegram voice chat group.
 Music bot for playing music on telegram voice chat group.

Somali X Music ?? Music bot for playing music on telegram voice chat group. Requirements FFmpeg NodeJS nodesource.com Python 3.8+ or Higher PyTgCalls

Dec 1, 2021
this is an op music pyrogram music bot.

amanrajputpytgcallmusic this is an op music pyrogram music bot..... this bot user music bot can play music without being admin...... TG-MusicPlayer A

Dec 27, 2021