gpsoauth
Python client library for Google Play Services OAuth.
gpsoauth allows python code to use the "master token" flow that KB Sriram described at
http://sbktech.blogspot.com/2014/01/inside-android-play-services-magic.html.
import gpsoauth
email = 'example@gmail.com'
password = 'my-password'
android_id = '0123456789abcdef'
master_response = gpsoauth.perform_master_login(email, password, android_id)
master_token = master_response['Token']
auth_response = gpsoauth.perform_oauth(
email, master_token, android_id,
service='sj', app='com.google.android.music',
client_sig='...')
token = auth_response['Auth']
This can be useful when writing code that poses as a Google app, like gmusicapi does here.
Many thanks to Dima Kovalenko for reverse engineering the EncryptedPasswd signature in https://web.archive.org/web/20150814054004/http://codedigging.com/blog/2014-06-09-about-encryptedpasswd/.
For an explanation of recent changes, see the changelog.
Alternative flow
There is an alternative login flow if you are experiencing BadAuthentication errors.
- Go to https://accounts.google.com/EmbeddedSetup
- Log into your Google Account
- Click on "I agree" when prompted. The page may show a loading screen forever; ignore it and move on to the next step.
- Obtain the value of the
oauth_tokencookie. For more details see the gpsoauth-java readme.
Then, perform the token exchange:
import gpsoauth
email = 'example@gmail.com'
android_id = '0123456789abcdef'
token = '...' # insert the oauth_token here
master_response = gpsoauth.exchange_token(email, token, android_id)
master_token = master_response['Token'] # if there's no token check the response for more details
auth_response = gpsoauth.perform_oauth(
email, master_token, android_id,
service='sj', app='com.google.android.music',
client_sig='...')
token = auth_response['Auth']
Using another HTTP client
perform_master_login(), exchange_token() and perform_oauth() send their requests with requests. To send them with another HTTP client, such as an async one, build the form fields with build_master_login_data(), build_exchange_token_data() or build_oauth_data(), which take the same arguments except proxy. For example, with aiohttp:
from urllib.parse import urlencode
import aiohttp
import gpsoauth
# Loading the certificates blocks: create the context once, outside the event loop.
ssl_context = gpsoauth.create_ssl_context()
async def perform_oauth(email, master_token, android_id):
data = gpsoauth.build_oauth_data(
email, master_token, android_id,
service='sj', app='com.google.android.music',
client_sig='...')
async with aiohttp.ClientSession() as session, session.post(
gpsoauth.AUTH_URL,
data=urlencode(data).encode('ascii'),
headers=gpsoauth.build_auth_headers(),
ssl=ssl_context,
) as response:
return gpsoauth.google.parse_auth_response(await response.text())
These functions give you the form fields, the headers gpsoauth sets and its TLS settings. Your client still adds its own default headers, and handles proxies, timeouts and HTTP errors as it does for its other requests. It must also URL-encode the fields, as in the example: build_master_login_data() returns EncryptedPasswd as bytes, which aiohttp would otherwise send as a file upload.
create_ssl_context() checks the server's certificate and hostname, and trusts the system's certificate authorities. gpsoauth's own functions may also trust the CA bundle requests uses, depending on its version and settings: certifi's, or the file named by REQUESTS_CA_BUNDLE or CURL_CA_BUNDLE. So a certificate that gpsoauth's functions accept can fail with another client. To trust the same certificates, add that bundle with ssl_context.load_verify_locations(), for example ssl_context.load_verify_locations(requests.certs.where()) for certifi's. This also blocks, so do it where you create the context, outside the event loop.
Ports
- Typescript: https://github.com/billgreenwald/gpsoauth-js
- C#: https://github.com/vemacs/GPSOAuthSharp
- Ruby: https://github.com/bryanmytko/gpsoauth
- Java: https://github.com/svarzee/gpsoauth-java
- C++: https://github.com/dvirtz/gpsoauth-cpp and https://github.com/Iciclelz/gpsoauthclient
Contributing
See Contributing guidelines. This is an open-source project and all contributions are highly welcomed.
Metadata
Release files for gpsoauth 3.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| gpsoauth-3.0.0.tar.gz | 8.0 kB | Without provenance | Details for gpsoauth-3.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| gpsoauth-3.0.0-py3-none-any.whl | Python 3 | none | any | Details for gpsoauth-3.0.0-py3-none-any.whl |
Total release size: 17.0 kB
Release files / gpsoauth-3.0.0.tar.gz
| Download URL | gpsoauth-3.0.0.tar.gz |
|---|---|
| Size | 8.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ea06cfeae32a7391c878ab1d275c024c07c3c32bc599b29fd28f80c82b313835
|
|
BLAKE2b-256 checksum How to use checksums |
a21a8d272e028eef326dddbd0da0255759e24e0e421d3d37992e96a0b8de9554
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.4
|
Release files / gpsoauth-3.0.0-py3-none-any.whl
| Download URL | gpsoauth-3.0.0-py3-none-any.whl |
|---|---|
| Size | 9.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c62ea43707d16d34047813bcf7c7ec5267388698b381b2252a12dfa8ca33355f
|
|
BLAKE2b-256 checksum How to use checksums |
9d33878d6aabe3b18e610d2a35daf3c94fa7b93792ce79dac862c1e8da90fea6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.4
|
Security for gpsoauth 3.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.