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.
Related
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)
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 would like to create a group using the API Cloud Identity and the command groups().create().
To do so, I'v used the example provided by Google:
def create_google_group(service, customer_id, group_id, group_display_name, group_description):
group_key = {"id": group_id}
group = {
"parent": "customers/" + customer_id,
"description": group_description,
"displayName": group_display_name,
"groupKey": group_key,
# Set the label to specify creation of a Google Group.
"labels": {
"cloudidentity.googleapis.com/groups.discussion_forum": ""
}
}
try:
request = service.groups().create(body=group)
request.uri += "&initialGroupConfig=WITH_INITIAL_OWNER"
response = request.execute()
print(response)
except Exception as e:
print(e)
But I got an issue:
<HttpError 400 when requesting https://cloudidentity.googleapis.com/v1/groups?alt=json&initialGroupConfig=WITH_INITIAL_OWNER returned "Invalid resource.parent". Details: "[{'#type': 'type.googleapis.com/google.rpc.BadRequest', 'fieldViolations': [{'field': 'resource.parent', 'description': 'Invalid resource.parent'}]}]">
For the field customer_id, I tried without any success:
data from https://console.developers.google.com/
ID clients OAuth 2.0, ID_client: "XXXXXXXXXXXXXXXXX.apps.googleusercontent.com"
idem but only: "XXXXXXXXXXXXXXXXX"
project identifier: 'yyyy-yyyy-123456'
'me'
'my_email#example.com'
'my_customer'
Thank you in advance for your support to understand what is expected for the field customer_id!
You can find your customer ID through the Admin console.
https://support.google.com/a/answer/10070793?hl=en
There are several other ways to find it as well.
User Resource from AdminSDK (customerId field - docs)
Organization API for GCP customers (directoryCustomerId field - docs)
I have an access token for Facebook Audiences but I am not able to get create a custom audience using Python-SDK
First I get information about USER id using the following link:
https://developers.facebook.com/tools/debug/accesstoken
Than I use the following URL to list Ad ID's from my account:
https://graph.facebook.com/v3.2/MY_USER_ID/adaccounts
It returns a json with a list of act's like this:
{
"data": [
{
"account_id": "xxxx",
"id": "act_xxxx"
}
] }
With this ID I try to create a new audience:
from facebook_business.adobjects.adaccount import AdAccount
from facebook_business.adobjects.customaudience import CustomAudience
from facebook_business.api import FacebookAdsApi
id = 'act_xxxx'
FacebookAdsApi.init(access_token='MY TOKEN')
fields = [
]
params = {
'name': 'My new Custom Audience',
'subtype': 'CUSTOM',
'description': 'People who purchased on my website',
'customer_file_source': 'USER_PROVIDED_ONLY',
}
print(AdAccount(id).create_custom_audience(
fields=fields,
params=params,
))
Then the code produces the following error:
Unsupported post request. Object with ID 'act_xxxx' does not exist,
cannot be loaded due to missing permissions, or does not support this
operation.
I know that this ID exists because it was returned by the previous call. Debugging the access token I can see it has the following access:
read_insights, read_audience_network_insights, publish_video,
manage_pages, pages_manage_cta, pages_manage_instant_articles,
pages_show_list, publish_pages, read_page_mailboxes, ads_management,
ads_read, business_management, pages_messaging,
pages_messaging_phone_number, pages_messaging_subscriptions,
instagram_basic, instagram_manage_comments, instagram_manage_insights,
leads_retrieval
Can anyone help me to discover the reason of this error?
Thanks!
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.