I want to use a python script to retrieve the policies I have created into BigQuery. The issue is regarding themissing required authentication credential. It is said the script is Expecting OAuth 2 access token, login cookie or other valid authentication credential. But I am not sure where to find it and where to position it in my script. Someone can help me please.
My code:
import requests
response = requests.get("https://bigquery.googleapis.com/bigquery/v2/projects/project123/datasets/Dataset123/tables/Test/rowAccessPolicies")
response.json()
Desired output:
{
"rowAccessPolicies": [
{
"rowAccessPolicyReference": {
"projectId": "project123",
"datasetId": "Dataset123",
"tableId": "Test",
"policyId": "test_2"
},
"filterPredicate": "gender = \"M\"",
"creationTime": "2021-11-09T09:45:35.181602Z",
"lastModifiedTime": "2021-11-09T09:45:35.181602Z"
}
]
}
Actual ouptut:
{'error': {'code': 401,
'message': 'Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.',
'status': 'UNAUTHENTICATED',
'details': [{'#type': 'type.googleapis.com/google.rpc.ErrorInfo',
'reason': 'CREDENTIALS_MISSING',
'domain': 'googleapis.com',
'metadata': {'method': 'google.cloud.bigquery.v2.RowAccessPolicyService.ListRowAccessPolicies',
'service': 'bigquery.googleapis.com'}}]}}
As said in your message: "Request is missing required authentication credential". You should provide the credentials in your request. You have several ways to do so:
add the credentials in the headers (depending on the type of authentication you have)
use Google Api Core (https://googleapis.dev/python/google-api-core/latest/auth.html)
or use the Google Cloud Python lib which has this procedure include (https://github.com/googleapis/google-cloud-python)
Related
I have been trying to login to Superset (including registering new user) using Google OAuth API, following this instruction: https://aungmt.medium.com/superset-with-google-oauth-3ba7a1c1f459
All my search results shows me this config supposed to work. However, as soon as I click login button, I'm getting a Error 400: invalid_request Missing required parameter: scope. I quadruple checked my superset_config.py and it has 'scope': 'openid email profile' in it.
Anyone could shine a light on this?
I received some feed backs from Superset Slack channel. #Daniel Gaspar
I guess the tutorial I found online were all for older version of Superset. Some of the key names in the config did not match current documentation. Below is my working config as of Superset v0.38.0
OAUTH_PROVIDERS = [
{
'name': 'google',
'icon': 'fa-google',
'token_key': 'access_token',
'remote_app': {
'api_base_url': 'https://www.googleapis.com/oauth2/v2/',
'client_kwargs': {
'scope': 'openid email profile'
},
'request_token_url': None,
'access_token_url': 'https://accounts.google.com/o/oauth2/token',
'authorize_url': 'https://accounts.google.com/o/oauth2/auth',
'client_id': '###GOOGLE_KEY###',
'client_secret': '###GOOGLE_SECRET###'
}
}
]
I was trying to use API to make some changes on my google calendar.
I have created a project on google cloud console, enable calendar API, and got the credential ready. The OAuth scope I set is:
scopes = ['https://www.googleapis.com/auth/calendar']
flow = InstalledAppFlow.from_client_secrets_file("client_secret.json", scopes=scopes)
And I got both credentials for my account.
credentials = flow.run_console()
I wanted to use ACL to gain access to the calendar, so I tried "get" and "insert" these two functions. Codes are as follows:
rule = service.acl().get(calendarId='primary', ruleId='ruleId').execute()
print('%s: %s' % (rule['id'], rule['role']))
rule = {
'scope': {
'type': 'group',
'value': 'default',
},
'role': 'owner'
}
created_rule = service.acl().insert(calendarId='primary', body=rule).execute()
print(created_rule)
However, the results show that I have some problems with the access part.
<HttpError 400 when requesting https://www.googleapis.com/calendar/v3/calendars/primary/acl/ruleId?alt=json
returned "Invalid resource id value.">
and
<HttpError 400 when requesting https://www.googleapis.com/calendar/v3/calendars/primary/acl?alt=json
returned "Invalid scope value.">
what step have I miss or do wrong?
The first error shows up in Acl.get whenever you specify an invalid ruleId. So make sure you are providing a valid ruleId in here:
rule = service.acl().get(calendarId='primary', ruleId='valid-rule-id').execute()
If you don't know the ruleId, you can look for it by calling Acl.list.
About the second error, the problem is that you are providing a wrong request body for Acl.insert. If you want to share this calendar with a group, you should provide a valid email address of the group in scope.value. default is not a valid value. Your request body should be something like this:
rule = {
'scope': {
'type': 'group',
'value': 'group-email-address',
},
'role': 'owner'
}
You will find the group email address if you click About in the corresponding group.
I hope this is of any help.
I need to get the Instance List of my Google cloud project. So i tried this:
requests.get('https://compute.googleapis.com/compute/v1/projects/clouddeployment-265711/zones/europe-west3-a/instances)
How do i get authorization in python?.
{
"error": {
"code": 401,
"message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"errors": [
{
"message": "Login Required.",
"domain": "global",
"reason": "required",
"location": "Authorization",
"locationType": "header"
}
],
"status": "UNAUTHENTICATED"
}
}
How do i get my "OAuth 2 access token" for my Google Cloud Project
Here is the full documentation on Server to Server authentication which also includes sample codes for every method supported.
In this GCP Github code, you can see multiple ways of authentication that you might choose from depending on your use-case.
For example with this code sample you can use a service account JSON key for authentication:
# [START auth_api_explicit]
def explicit(project):
from google.oauth2 import service_account
import googleapiclient.discovery
# Construct service account credentials using the service account key
# file.
credentials = service_account.Credentials.from_service_account_file(
'service_account.json')
# Explicitly pass the credentials to the client library.
storage_client = googleapiclient.discovery.build(
'storage', 'v1', credentials=credentials)
# Make an authenticated API request
buckets = storage_client.buckets().list(project=project).execute()
print(buckets)
# [END auth_api_explicit]
UPDATE:
If what you want is simply getting the Bearer token and storing it in a python variable to make a simple GET request:
import os
your_key = os.system('gcloud auth print-access-token')
so your_key will now have the Bearer token that you need to include in your request header
Otherwise, please read through this documentation which explains how to authenticate as an end-user.
When the flask-jwt-extended token has expired, a HTTP request will result in this JSON response
{
"msg": "Token has expired"
}
My application has a fixed error response format:
{
"message": "Project name 'Test 8' already exist.",
"error": {
"resource": "Project",
"field": "project_name",
"code": "already_exists",
"stack_trace": "(psycopg2.IntegrityError) duplicate key value violates unique constraint \"project_name_idx\"\nDETAIL: Key (project_name)=(Test 8) already exists.\n [SQL: 'INSERT INTO project (project_name, project_root, deadline_id) VALUES (%(project_name)s, %(project_root)s, %(deadline_id)s) RETURNING project.project_id'] [parameters: {'project_name': 'Test 8', 'project_root': 'P:\\\\Test8', 'deadline_id': 2}]"
}
}
How do I customize flask-jwt-extended error response?
Examples of this are documented here: http://flask-jwt-extended.readthedocs.io/en/latest/changing_default_behavior.html
The API docs are here: http://flask-jwt-extended.readthedocs.io/en/latest/api.html#module-flask_jwt_extended
If you want to provide being able to change the standard JSON error response that is returned by Flask JWT so that you can send back your own standard error message format you would have to use JWTManager loader functions. Specifically the expired_token_loader
# Using the expired_token_loader decorator, we will now call
# this function whenever an expired but otherwise valid access
# token attempts to access an endpoint
#jwt.expired_token_loader
def my_expired_token_callback():
return jsonify({
'status': 401,
'sub_status': 42,
'msg': 'The token has expired'
}), 401
Doing this may end up being tedious having to use all the loader functions for all the different ways in validating a token though.
You could considered writing your own generic utility function that returns the value portion of any response object text attribute and then put that into your fixed error message format that needs to be returned.
Example:
def extract_response_text(the_response):
return the_response.json().get('msg')
Also I forgot to mention you could take the above example and use the #app.after_request decorator. This would allow you to configure all your apps endpoints to use this method before returning the response. In which you could alter or create your specific JSON response payload.
I need some help completing the Mirror Credentials API insertion from my Python server code. We are using the Python Google API library to insert a special auth token into the Mirror API, but I'm getting a blank result from mirror.accounts().insert().execute() where I should be getting at least an error or confirmation that the API token credential we are passing to Google's Mirror API.
Here is our Python server code with some redaction of our secret info, the secret info private keys and client_id's are in a secret .json file we store securely on our server.
with open(os.path.join(os.path.dirname(__file__), 'mirror-credentials.json')) as f:
credentials_json = json.load(f)
credentials = SignedJwtAssertionCredentials(
service_account_name=credentials_json['client_email'],
private_key=credentials_json['private_key'],
scope='https://www.googleapis.com/auth/glass.thirdpartyauth',
)
http = credentials.authorize(httplib2.Http())
mirror = apiclient.discovery.build('mirror', 'v1', http=http)
glass_request = mirror.accounts().insert(
userToken=$glassware_gallery_user_token,
accountType='com.mycompany',
accountName="testAccountName",
body={
'features': ["a", "b", "c"],
'password': $myapp_glass_auth_token,
'userData': [{"key": "realName", "value": "Rusty Shackleford"}],
'authTokens': [
{"type": "drchrono_glass_token", "authToken": $myapp_glass_auth_token}
],
},
)
retValue = glass_request.execute()
Note: $glassware_gallery_user_token is the token we get passed in from the Google App Gallery when we turn our Glassware on (we've already setup our glassware app).
Executing the above code, we get a blank value for retValue, it's an empty dictionary: {} when printed. From the documentation it looks like this should be either an error message or a confirmation.
In response to comment:
Here is a printout of what the request we are sending looks like (got this by inserting print statements into httplib2 source code):
body='{"userData": [{"value": "Rusty Shackleford", "key": "realName"}], "authTokens": [{"authToken": "$omitted_auth_token", "type": "$myapp_glass_token"}], "password": "$omitted_auth_token", "features": ["a", "b", "c"]}',
headers='{'content-length': '305', 'accept-encoding': 'gzip, deflate', 'accept': 'application/json', 'user-agent': 'google-api-python-client/1.2 (gzip)', 'content-type': 'application/json', 'authorization': 'Bearer ya29.hACi3eQf2L2awk3rrLgf1uZQHen2ZANgT_ObBqTNpqrwC6wa_DwjuO9q'}',
request_uri='/mirror/v1/accounts/$my_google_serviceid/$com.myappname/rustyshack?alt=json'
I get a blank dictionary as a response: {}
I can see that this is actually talking to Googles services for 2 reasons:
If I change the user_token to be invalid the code throws an exception.
I can see our API call count in the Google Developer Console counting these attempts as calls against our API quota.
The actual data in the response from Google's servers (printed out in httplib2 has a status code of 204:
'' / '{'fp': , 'status': 204, 'will_close': False, 'chunk_left': 'UNKNOWN', 'length': 0, 'strict': 0, 'reason': 'No Content', 'version': 11, 'debuglevel': 0, 'msg': , 'chunked': 0, '_method': 'POST'}'
#TonyAllevato I'm trying to fetch all accounts on the device with accountManager.getAccounts(); and I'm only getting one account of type "com.google". getAccountsByType("com.xxxxxx") with my app identified supplied during the review process is returning an empty array.
The Insert Mirror API documentation is a little bit incorrect. It returns an empty response with a status header code of 204 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) "No Content" when it is successful. Some parts of the documentation led me to believe it would echo back the credentials in the response, but that was not the case.
On a separate note, I was able to debug why I couldn't get the credentials loading on my Glass by first making sure that I could install my provisional Glassware from the https://google.com/myglass store on my Glass device which makes sure there is connectivity.