Environment details
OS type and version:
Python version: 3.9.0
pip version: 22.0.4
google-api-python-client version: 2.48.0
Description
Hi, I'm running into an error when trying to fetch the Google Play Console reports of our mobile apps (such as installations, errors etc.). I first tried with this manual but it seems to be outdated and didn't work. So after some research I changed it similar to this one, that it fits to the current google api (see code snippet below).
Steps I have done:
Created a project on "console.cloud.google.com"
Created the service account
Created the json key file
Invited the service account on play.google.com/console and gave him full admin rights (normally "see app information and download bulk reports" should be enough)
Added the role "Storage Object Viewer" to the Service account in https://console.cloud.google.com/iam-admin/iam?authuser=1&project=myproject
waited for 24h to make sure there are no errors because of syncs or so.
(I anonymized some of the values below).
Code example
from googleapiclient.discovery import build
from google.oauth2 import service_account
scopes = ['https://www.googleapis.com/auth/devstorage.read_only','https://www.googleapis.com/auth/cloud-platform.read_only']
key_file_location = 'files/access_token/mykeyfile.json'
cloud_storage_bucket = r'pubsite_prod_rev_00123456789'
report_to_download = 'installs/installs_com.my.app_202201_country.csv'
creds = service_account.Credentials.from_service_account_file(key_file_location,scopes=scopes)
service = build('storage','v1', credentials=creds)
print(service.objects().get(bucket = cloud_storage_bucket, object= report_to_download).execute())
Stack trace
Traceback (most recent call last):
File "C:\Users\myuser\project\z_10_ext_google_play_store.py", line 46, in <module>
print(service.objects().get(bucket = cloud_storage_bucket, object= report_to_download).execute())
File "D:\Programs\Python\lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "D:\Programs\Python\lib\site-packages\googleapiclient\http.py", line 923, in execute
resp, content = _retry_request(
File "D:\Programs\Python\lib\site-packages\googleapiclient\http.py", line 191, in _retry_request
resp, content = http.request(uri, method, *args, **kwargs)
File "D:\Programs\Python\lib\site-packages\google_auth_httplib2.py", line 209, in request
self.credentials.before_request(self._request, method, uri, request_headers)
File "D:\Programs\Python\lib\site-packages\google\auth\credentials.py", line 133, in before_request
self.refresh(request)
File "D:\Programs\Python\lib\site-packages\google\oauth2\service_account.py", line 410, in refresh
access_token, expiry, _ = _client.jwt_grant(
File "D:\Programs\Python\lib\site-packages\google\oauth2\_client.py", line 199, in jwt_grant
six.raise_from(new_exc, caught_exc)
File "<string>", line 3, in raise_from
google.auth.exceptions.RefreshError: ('No access token in response.', {'id_token': 'eyJ...'})
I hope that I provided enough information and I'm sorry in advance if I made a stupid mistake.
Related
I would like to extract the reporting data of our mobile apps from Google Play Console.
According to this documentation, we have to use SignedJwtAssertionCredentials to authenticate. After some errors and research it seems that the code snippet in the doc is kind of outdated (since SignedJWTAssertionCredentials is not available anymore). Instead we tried the following to automatically download the reports:
from oauth2client.service_account import ServiceAccountCredentials
from apiclient.discovery import build
scopes = ['https://www.googleapis.com/auth/analytics.readonly']
key_file_location = 'files/access_token/mykeyfile.json'
credentials = ServiceAccountCredentials.from_json_keyfile_name(key_file_location, scopes)
cloud_storage_bucket = 'pubsite_prod_rev_123456789'
report_to_download = 'installs/installs_com.someapp.etc.etc_2021*'
storage = build('storage', 'v1', credentials=credentials)
print( storage.objects().get(bucket = cloud_storage_bucket,object = report_to_download).execute())
Now the problem is, that we receive the following error message:
Traceback (most recent call last):
File "C:\Users\dev\dev\z_10_ext_google_play_store.py", line 30, in <module>
print( storage.objects().get(bucket = cloud_storage_bucket,object = report_to_download).execute())
File "D:\Software\Python\lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "D:\Software\Python\lib\site-packages\googleapiclient\http.py", line 938, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://storage.googleapis.com/storage/v1/b/pubsite_prod_rev_123456789/o/installs%2Finstalls_com.someapp.etc.etc_2021%2A?alt=json returned "Insufficient Permission". Details: "[{'message': 'Insufficient Permission', 'domain': 'global', 'reason': 'insufficientPermissions'}]">
Does anyone have an idea? Our service account even has admin rights in play console (which normally would be to much..)
UPDATE
As DaImTo pointed out, I was missing some scopes which lead me to a different line of scope definition:
scopes = ['https://www.googleapis.com/auth/analytics.readonly', 'https://www.googleapis.com/auth/devstorage.read_only'
,'https://www.googleapis.com/auth/cloud-platform.read_only']
But I still receive some errors, now because of the missing access token which is weird because the .json file contains everything necessary:
Traceback (most recent call last):
File "C:\Users\andre\Desktop\DAWSE\z_10_ext_google_play_store.py", line 33, in <module>
print( storage.objects().get(bucket = cloud_storage_bucket,object = report_to_download).execute())
File "D:\Sonstige Programme\Python\lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "D:\Sonstige Programme\Python\lib\site-packages\googleapiclient\http.py", line 923, in execute
resp, content = _retry_request(
File "D:\Sonstige Programme\Python\lib\site-packages\googleapiclient\http.py", line 191, in _retry_request
resp, content = http.request(uri, method, *args, **kwargs)
File "D:\Sonstige Programme\Python\lib\site-packages\oauth2client\transport.py", line 159, in new_request
credentials._refresh(orig_request_method)
File "D:\Sonstige Programme\Python\lib\site-packages\oauth2client\client.py", line 749, in _refresh
self._do_refresh_request(http)
File "D:\Sonstige Programme\Python\lib\site-packages\oauth2client\client.py", line 785, in _do_refresh_request
self.access_token = d['access_token']
KeyError: 'access_token'
You appear to be using the objects.get method
The authenticated user must have sufficient permission to use this method. To start with i would ensure your service account has access.
After that i would check your scopes you are currently only loading the scope for google analytics api.
scopes = ['https://www.googleapis.com/auth/analytics.readonly']
This scope will not grant you access to the google cloud storage objects get method. For that you need to use one of the google cloud storage scopes
I have a Google Sheet https://docs.google.com/spreadsheets/d/1Ycg7zTxds9DZnDvTrFcyNNKuTUxg6Yy6WF0a8Wc02WQ/edit#gid=0 I can read only. I need to read it in Python. I uploaded a video of what I am doing https://youtu.be/4cK0g9Bm_7w
import gspread
from oauth2client.service_account import ServiceAccountCredentials
scope = ["https://docs.google.com/spreadsheets/d/1Ycg7zTxds9DZnDvTrFcyNNKuTUxg6Yy6WF0a8Wc02WQ/edit#gid=0",
"https://docs.google.com/spreadsheets/d/1Ycg7zTxds9DZnDvTrFcyNNKuTUxg6Yy6WF0a8Wc02WQ/edit?usp=sharing"]
creds = ServiceAccountCredentials.from_json_keyfile_name("creds.json", scope)
client = gspread.authorize(creds)
sheet = client.open("[XO] developer test data").sheet1
I have an error:
Traceback (most recent call last):
File "C:\Python379\lib\site-packages\google\oauth2\_client.py", line 196, in jwt_grant
access_token = response_data["access_token"]
KeyError: 'access_token'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "E:/Прогрммирование/Последние алгоритмы/Git/GoogleSheets/sheets.py", line 11, in <module>
sheet = client.open("[XO] developer test data").sheet1
File "C:\Python379\lib\site-packages\gspread\client.py", line 121, in open
self.list_spreadsheet_files(title),
File "C:\Python379\lib\site-packages\gspread\client.py", line 98, in list_spreadsheet_files
res = self.request('get', url, params=params).json()
File "C:\Python379\lib\site-packages\gspread\client.py", line 70, in request
headers=headers,
File "C:\Python379\lib\site-packages\requests\sessions.py", line 546, in get
return self.request('GET', url, **kwargs)
File "C:\Python379\lib\site-packages\google\auth\transport\requests.py", line 478, in request
self.credentials.before_request(auth_request, method, url, request_headers)
File "C:\Python379\lib\site-packages\google\auth\credentials.py", line 133, in before_request
self.refresh(request)
File "C:\Python379\lib\site-packages\google\oauth2\service_account.py", line 377, in refresh
request, self._token_uri, assertion
File "C:\Python379\lib\site-packages\google\oauth2\_client.py", line 199, in jwt_grant
six.raise_from(new_exc, caught_exc)
File "<string>", line 3, in raise_from
google.auth.exceptions.RefreshError: ('No access token in response.', {'id_token': 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjE5ZmUyYTdiNjc5NTIzOTYwNmNhMGE3NTA3OTRhN2JkOWZkOTU5NjEiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xWWNnN3pUeGRzOURabkR2VHJGY3lOTkt1VFV4ZzZZeTZXRjBhOFdjMDJXUS9lZGl0I2dpZD0wLGh0dHBzOi8vZG9jcy5nb29nbGUuY29tL3NwcmVhZHNoZWV0cy9kLzFZY2c3elR4ZHM5RFpuRHZUckZjeU5OS3VUVXhnNll5NldGMGE4V2MwMldRL2VkaXQ_dXNwPXNoYXJpbmciLCJhenAiOiJhY2MxMC0yMjhAcHJvamVjdC0xMC0zMTc0MDIuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJlbWFpbCI6ImFjYzEwLTIyOEBwcm9qZWN0LTEwLTMxNzQwMi5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJleHAiOjE2MjQxNjA4NTIsImlhdCI6MTYyNDE1NzI1MiwiaXNzIjoiaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tIiwic3ViIjoiMTA4OTUzMjg5ODAwOTQ4MzEyOTgxIn0.RYEt9eTvaCXSRPH-ddjB4s5wCE60tt2w-ZgL2aaeBT8ZTyKtlDbpMKV1zG8XRkxqCLs_xde-TEwTZoRQ8OKuJGQIZr6U8mSmqjW7xlhz5cvDLL03o-muks06FbLsgAFE2yEow5EdFcEL8hKt8LGuFoQWuiNWNT-sd-Z-vJMG0-XC6twrYgYp59tdmxCCG3MEprKbtgHpwAWHPoWjybKkETGXVnv17DSV99LIXY9FIzQVV4FV4reBn_4sgcT4y6IcbHqe6hpt4joEDYBsVxImzKk7IJjJfsRCg-kGpfc1yOC831qbupMlF45H75XMq9WWmnrn3Su4YFIBTugUxrMpdA'})
Issues:
You are not providing valid scopes. A scope is not the URL of a file you want to access. A scope determines what actions an API client can make, like reading user's spreadsheets, or reading and writing user's spreadsheets; it doesn't refer to specific files. Here you can see a list of the existing scopes in Sheets API: Authorizing requests with OAuth 2.0.
oauth2client is deprecated. Consider using google-auth instead.
Code sample:
import gspread
from google.oauth2.service_account import Credentials
scopes = [
'https://www.googleapis.com/auth/spreadsheets' # Change according to your preferences
]
credentials = Credentials.from_service_account_file(
'creds.json',
scopes=scopes
)
client = gspread.authorize(creds)
sheet = client.open("[XO] developer test data").sheet1
Notes:
gspread is not officially supported by Google. Here is the official library. And here is the corresponding quickstart for Sheets API.
I am assuming that creds.json refers to valid service account credentials.
If you store creds.json to ~/.config/gspread/creds.json, you should be able to do this, according to the gspread documentation:
import gspread
client = gspread.service_account()
sheet = client.open("[XO] developer test data").sheet1
Reference:
google.oauth2.service_account module
I would like to use python kubernetes-client to connect to my AKS cluster api.
To do that I try to use the example give by kubernetes:
config.load_kube_config()
v1 = client.CoreV1Api()
print("Listing pods with their IPs:")
ret = v1.list_pod_for_all_namespaces(watch=False)
for i in ret.items:
print("%s\t%s\t%s" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name))
It is supposed to load my local kubeconfig and get a pods list but I get the following error:
Traceback (most recent call last): File "test.py", line 4, in
config.load_kube_config() File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/kubernetes/config/kube_config.py",
line 661, in load_kube_config
loader.load_and_set(config) File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/kubernetes/config/kube_config.py",
line 469, in load_and_set
self._load_authentication() File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/kubernetes/config/kube_config.py",
line 203, in _load_authentication
if self._load_auth_provider_token(): File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/kubernetes/config/kube_config.py",
line 221, in _load_auth_provider_token
return self._load_azure_token(provider) File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/kubernetes/config/kube_config.py",
line 233, in _load_azure_token
self._refresh_azure_token(provider['config']) File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/kubernetes/config/kube_config.py",
line 253, in _refresh_azure_token
refresh_token, client_id, '00000002-0000-0000-c000-000000000000') File
"/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/adal/authentication_context.py",
line 236, in acquire_token_with_refresh_token
return self._acquire_token(token_func) File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/adal/authentication_context.py",
line 128, in _acquire_token
return token_func(self) File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/adal/authentication_context.py",
line 234, in token_func
return token_request.get_token_with_refresh_token(refresh_token, client_secret) File
"/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/adal/token_request.py",
line 343, in get_token_with_refresh_token
return self._get_token_with_refresh_token(refresh_token, None, client_secret) File
"/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/adal/token_request.py",
line 340, in _get_token_with_refresh_token
return self._oauth_get_token(oauth_parameters) File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/adal/token_request.py",
line 112, in _oauth_get_token
return client.get_token(oauth_parameters) File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/adal/oauth2_client.py",
line 291, in get_token
raise AdalError(return_error_string, error_response) adal.adal_error.AdalError: Get Token request returned http error: 400
and server response:
{"error":"invalid_grant","error_description":"AADSTS65001: The user or
administrator has not consented to use the application with ID
'' named 'Kubernetes AD Client
'. Send an interactive authorization request for this user and
resource.\r\nTrace ID:
\r\nCorrelation ID:
\r\nTimestamp: 2019-10-14
12:32:35Z","error_codes":[65001],"timestamp":"2019-10-14
12:32:35Z","trace_id":"","correlation_id":"","suberror":"consent_required"}
I really don't understand why it doesn't work.
When I use kubectl, all work fine.
I read some docs but I'm not sure to understand the adal error.
Thanks for your help
Login as a tenant admin to https://portal.azure.com
Open the registration for your app in the
Go to Settings then Required Permissions
Press the Grant Permissions button
If you are not a tenant admin, you cannot give admin consent
From https://github.com/Azure-Samples/active-directory-angularjs-singlepageapp-dotnet-webapi/issues/19
This is good post where you can find snippet to authenticate to AKS:
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.containerservice import ContainerServiceClient
from azure.mgmt.containerservice.models import (ManagedClusterAgentPoolProfile,
ManagedCluster)
credential = AzureCliCredential()
subscription_id = "XXXXX"
resource_group= 'MY-RG'
resouce_client=ResourceManagementClient(credential,subscription_id)
container_client=ContainerServiceClient(credential,subscription_id)
resouce_list=resouce_client.resources.list_by_resource_group(resource_group)
Note: You need to install respective Az Python SKD libraries.
Trying to search youtube videos using this code: https://github.com/youtube/api-samples/blob/master/python/search.py
But whatever I try I get below error even though I provided the api key:
Traceback (most recent call last):
File "search.py", line 56, in <module>
youtube_search(args)
File "search.py", line 18, in youtube_search
developerKey=DEVELOPER_KEY)
File "C:\Python27\Scripts\tvapp_env\lib\site-packages\oauth2client\_helpers.py", line 133, in positional_wrapper
return wrapped(*args, **kwargs)
File "C:\Python27\Scripts\tvapp_env\lib\site-packages\googleapiclient\discovery.py", line 226, in build
credentials=credentials)
File "C:\Python27\Scripts\tvapp_env\lib\site-packages\oauth2client\_helpers.py", line 133, in positional_wrapper
return wrapped(*args, **kwargs)
File "C:\Python27\Scripts\tvapp_env\lib\site-packages\googleapiclient\discovery.py", line 358, in build_from_document
credentials = _auth.default_credentials()
File "C:\Python27\Scripts\tvapp_env\lib\site-packages\googleapiclient\_auth.py", line 40, in default_credentials
return oauth2client.client.GoogleCredentials.get_application_default()
File "C:\Python27\Scripts\tvapp_env\lib\site-packages\oauth2client\client.py", line 1264, in get_application_default
return GoogleCredentials._get_implicit_credentials()
File "C:\Python27\Scripts\tvapp_env\lib\site-packages\oauth2client\client.py", line 1254, in _get_implicit_credentials
raise ApplicationDefaultCredentialsError(ADC_HELP_MSG)
oauth2client.client.ApplicationDefaultCredentialsError: The Application Default Credentials are not available. They are available if running in Google Compute Engine. Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.
Please help, im running this from windows machine.
Or is there better code to make youtube search.
Thanks
Seems like you are not running the app in either Google app engine or in Google compute engine. So there are not going to be any default credentials to use so you have to download the credentials from the google developer console first and use those credentials in your application. Please refer this document for further details.
Good evening, i've been trying to migrate my blogger python app to oauth2 since the good old Clientlogin() has been deprecated and erased.
So, basically i searched through the entire web and couldn't manage to make my application to work correctly.
This is the basic code im using for testing:
FLOW = flow_from_clientsecrets('/home/b/client_secret.json',scope='https://www.googleapis.com/auth/blogger',message="Client Secrets Not Found")
storage = Storage('blogger.dat')
credentials = storage.get()
parser = argparse.ArgumentParser(parents=[tools.argparser])
flags = parser.parse_args()
if credentials is None or credentials.invalid:
credentials = run_flow(FLOW, storage, flags)
if credentials.access_token_expired:
credentials.refresh(httplib2.Http())
SCOPE = 'https://www.blogger.com/feeds'
token = gdata.gauth.OAuth2TokenFromCredentials(credentials)
client = gdata.blogger.client.BloggerClient()
token.authorize(client)
post = client.add_post(blog_id, title="blah", body="blah", labels="label", draft=False, title_type="xhtml", body_type="html")
I get a 401 error code, unauthorized everytime i try to do this.
Traceback (most recent call last):
File "/home/b/.eclipse/org.eclipse.platform_4.4.2_1473617060_linux_gtk_x86_64/plugins/org.python.pydev_4.0.0.201504132356/pysrc/pydevd.py", line 2278, in <module>
globals = debugger.run(setup['file'], None, None)
File "/home/b/.eclipse/org.eclipse.platform_4.4.2_1473617060_linux_gtk_x86_64/plugins/org.python.pydev_4.0.0.201504132356/pysrc/pydevd.py", line 1704, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "/home/b/workspace/BloggerPy/simpleblogger.py", line 53, in <module>
post = client.add_post(blog_id, title="hola", body="holaaa", labels="label", draft=False, title_type="xhtml", body_type="html", token=token)
File "/usr/local/lib/python2.7/dist-packages/gdata/blogger/client.py", line 111, in add_post
return self.post(new_entry, BLOG_POST_URL % blog_id, auth_token=auth_token, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/gdata/client.py", line 690, in post
desired_class=desired_class, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/gdata/client.py", line 298, in request
**kwargs)
File "/usr/local/lib/python2.7/dist-packages/gdata/client.py", line 307, in request
response, Unauthorized)
gdata.client.Unauthorized: Unauthorized - Server responded with: 401, User does not have permission to create new post
Can someone help me out with this? I'd really appreciate it :)
Greetings
Finally i've fixed my issue with gdata.gauth:
I used auth2token = gdata.gauth.OAuth2Token(client_id,client_secret,scope,user_agent)
After getting the authorization token i generate an authorized url to get an access code with auth2token.generate_authorize_url(redirect_uri=URL,approval_prompt="force").
once you get this url, you manually get the code and generate a refresh token, with which you generate an access token:
token = auth2token.get_access_token(code). Easy enough. For any other information as to how to save the token to a blob string in a file here's the reference:
gdata-python-api + Analytics with simple auth