Authorize google api requests to list users - python

I want to get list of users google api but face an issue
My steps are:
Created Service account with domain wide delegation and listed scopes (same as in the script)
Downloaded json file with private key
On execution of the next script
import google.auth
import google.auth.transport.requests
from google.oauth2 import service_account
import requests
credentials = service_account.Credentials.from_service_account_file('key.json', scopes=[
'https://www.googleapis.com/auth/admin.directory.user',
'https://www.googleapis.com/auth/admin.directory.group',
'https://www.googleapis.com/auth/admin.directory.group.member',
'https://www.googleapis.com/auth/admin.directory.user.security',
'https://www.googleapis.com/auth/admin.directory.user.readonly'
])
auth_req = google.auth.transport.requests.Request()
refresh = credentials.refresh(auth_req)
response = requests.get('https://www.googleapis.com/admin/directory/v1/users?domain=domain.com',
headers={'Authorization': f'Bearer {credentials.token}'})
Response is:
{
"error": {
"code": 403,
"message": "Not Authorized to access this resource/api",
"errors": [
{
"message": "Not Authorized to access this resource/api",
"domain": "global",
"reason": "forbidden"
}
]
}
}

I ended up with the next solution
console.cloud.google.com => APIs & Services > Credentials
Create Credentials > OAuth Client ID > Desktop APp
Saved key as 'credentials.json'
The rest id described here
from __future__ import print_function
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/admin.directory.user']
#
def main():
"""Shows basic usage of the Admin SDK Directory API.
Prints the emails and names of the first 10 users in the domain.
"""
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
print('Refreshing token')
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'python_admin.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())
service = build('admin', 'directory_v1', credentials=creds)
# Call the Admin SDK Directory API
print('Getting the first 10 users in the domain')
service_users = service.users()
results = service_users.list(customer='my_customer', maxResults=10, orderBy='email').execute()
users = results.get('users', [])
service_users.insert()
if not users:
print('No users in the domain.')
else:
print('Users:')
for user in users:
print(u'{0} ({1})'.format(user['primaryEmail'],
user['name']['fullName']))
if __name__ == '__main__':
main()
For the first time I had to authorize request in the browser, after that access and refresh token could be used for next requests. Except manual authorization for the first time - works fine

Related

How to get Access Token for uploading files on google drive

headers = {"Authorization": "Bearer " + ACCESS_TOKEN}
folder=Folder_id // google drive folder Id
para = {"title": assignment_file_name,
"parents": [{"id": "root"}, {'id': folder}]}
files = {
"data": ("metadata", json.dumps(para), "application/json; charset=UTF-8"),
"file": assignment_file.stream.read()
}
response = requests.get("https://drive.google.com/drive/folders/"+Folder_id,
headers= headers, files=files)
I want to upload file fetched from requests to google drive folder.
But From where to get this ACCESS_TOKEN in the headers variable?
The access token is the result of the Oauth2 request. When you want to access private user data you must first ask for the users consent to your application accessing their data. To do this we use Oauth2. If you are interested in knowing how it works i have a video on it Understanding Oauth2 with curl..
Rather then coding all this manually you should consider using the Google Api python client library. As shown in the official Python quickstart for Drive api will walk you though how to create credentials (be sure to enable drive api) for your application and then how to request access of the user.
from __future__ import print_function
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']
def main():
"""Shows basic usage of the Drive v3 API.
Prints the names and ids of the first 10 files the user has access to.
"""
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())
try:
service = build('drive', 'v3', credentials=creds)
# Call the Drive v3 API
results = service.files().list(
pageSize=10, fields="nextPageToken, files(id, name)").execute()
items = results.get('files', [])
if not items:
print('No files found.')
return
print('Files:')
for item in items:
print(u'{0} ({1})'.format(item['name'], item['id']))
except HttpError as error:
# TODO(developer) - Handle errors from drive API.
print(f'An error occurred: {error}')
if __name__ == '__main__':
main()

problems with my Python code connecting with google docs api

I'm coding a Python app to automatize invoices via a google docs API but I'm having errors with the code and I don't know how to solve it
# [START docs_quickstart]
from __future__ import print_function
import os.path
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/documents.readonly','https://www.googleapis.com/auth/documents','https://www.googleapis.com/auth/drive.file','https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/drive.readonly']
def main():
"""Shows basic usage of the Docs API.
Prints the title of a sample document.
"""
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())
try:
service = build('docs', 'v1', credentials=creds)
title = 'My Document'
body = {
'title': title
}
document = service.documents().create(body=body).execute()
print('Created document with title: {0}'.format(
document.get('title')))
except HttpError as err:
print(err)
if __name__ == '__main__':
main()
# [END docs_quickstart]
and this is the error code that I'm having
PS D:\Universidad\Proyectos de Programacion Propia\python\googledocsinvoice.restapi> python quickstart.py
<HttpError 403 when requesting https://docs.googleapis.com/v1/documents?alt=json returned "Request had insufficient authentication scopes.". Details: "[{'#type': 'type.googleapis.com/google.rpc.ErrorInfo', 'reason': 'ACCESS_TOKEN_SCOPE_INSUFFICIENT', 'domain': 'googleapis.com', 'metadata': {'service': 'docs.googleapis.com', 'method': 'google.apps.docs.v1.DocumentsService.CreateDocument'}}]">
if you know some guide or complete tutorial to Automate Document Creation with the Google Docs API like invoices and replace encapsulation values like {{productID}} I will be very grateful
I saw the Automate document creation of google channel but it wasn't very helpful https://youtu.be/-dX-fWb3ogE
Best Regards
Make sure you also enable the Docs API in your Developers Console.
Delete the credential file ~/.credentials.json and token.json (if you ran the code before
Change the scope variable used for reading docs
var SCOPES = ['https://www.googleapis.com/auth/documents.readonly'];
to
var SCOPES = ['https://www.googleapis.com/auth/documents'];
Check more info on https://developers.google.com/docs/api/reference/rest/v1/documents/create#authorization-scopes and https://developers.google.com/docs/api/how-tos/authorizing
After the execution of code, API will authenticate again and then the issue should be resolved.

Request had insufficient authentication scopes for classroom announcements

I am using python api for fetching announcements from classroom.
My code:
from __future__ import print_function
import pickle
import os.path
from os import getcwd
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
class ClassRoom:
# If modifying these scopes, delete the file token.pickle.
def announcements_list(self):
self.SCOPES = ['https://www.googleapis.com/auth/classroom.courses.readonly',
'https://www.googleapis.com/auth/classroom.announcements.readonly']
"""Shows basic usage of the Classroom API.
Prints the names of the first 10 courses the user has access to.
"""
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', self.SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('classroom', 'v1', credentials=creds)
# Call the Classroom API
results = service.courses().list(pageSize=10).execute()
courses = results.get('courses', [])
announcements = []
for course in course:
announcements += service.courses().announcements().list(courseId=course["id"],
pageSize=1).execute().get("annoucements")
return announcements
cs = ClassRoom()
print(cs.announcements_list())
But the script is generating HttpError 403 error something like
"Request had insufficient authentication scopes.". Details: "Request had insufficient authentication scopes."
How to resolve this issue?
I had the same issue, delete token.pickle from your folder and execute again. it should work

how to create new contacts with people API

I am trying to create multiple contacts in my company using python and the people API.
I've researched it and found that I need to use people API to edit contacts via API but I'm not finding good examples of how this could be done.
I am using the following command to make a simple listing of my contacts:
from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import urllib3
# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/contacts']
def main():
"""Shows basic usage of the People API.
Prints the name of the first 10 connections.
"""
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('people', 'v1', credentials=creds)
# Call the People API
print('List 10 connection names')
results = service.people().connections().list(
resourceName='people/me',
pageSize=10,
personFields='names,phoneNumbers').execute()
connections = results.get('connections', [])
for person in connections:
names = person.get('names', [])
phones = person.get('phoneNumbers', [])
if names and phones:
name = names[0].get('displayName')
phones = phones[0].get('canonicalForm')
print(name, phones)
if __name__ == '__main__':
main()
Output:
List 10 connection names
Eeverton None
Evetton None
Paulinha None
Wayne +5521992*****
Joao Pedro +55219643*****
Mae +552199*****
Maae +552199*****
Advogado Gb +5521964*****
working perfection.
But what I need is to create new contacts.
I changed the scopes
I authenticated oauth2
I have all files and keys properly stored (token.picke and credentials.json)
how should i go about creating new contacts? functions or POST?
Could you provide a simple code example for creating contacts?
https://developers.google.com/people/api/rest/v1/people/createContact
works with:
from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
SCOPES = ['https://www.googleapis.com/auth/contacts']
def main():
"""Shows basic usage of the People API.
Prints the name of the first 10 connections.
"""
creds = None
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('people', 'v1', credentials=creds)
# CREATING CONTACTSSSSSSSS
service.people().createContact( body={
"names": [
{
"givenName": "Samkit"
}
],
"phoneNumbers": [
{
'value': "8600086024"
}
],
"emailAddresses": [
{
'value': 'samkit5495#gmail.com'
}
]
}).execute()
if __name__ == '__main__':
main()
I recommend you to try this piece of code:
from __future__ import print_function
import httplib2
import os
from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None
# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/people.googleapis.com-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/contacts'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'People API Python Quickstart'
def get_credentials():
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
the OAuth2 flow is completed to obtain the new credentials.
Returns:
Credentials, the obtained credential.
"""
home_dir = os.path.expanduser('./')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'people.googleapis.com-python-quickstart.json')
store = Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatibility with Python 2.6
credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('people', 'v1', http=http,
discoveryServiceUrl='https://people.googleapis.com/$discovery/rest')
service.people().createContact(parent='people/me', body={
"names": [
{
"givenName": "Samkit"
}
],
"phoneNumbers": [
{
'value': "8600086024"
}
],
"emailAddresses": [
{
'value': 'samkit5495#gmail.com'
}
]
}).execute()
I hope this helps.

Can't change the SCOPES in Google Sheets API without getting a 404 error : Requested entity was not found

I get this error whenever I try running that code : HttpError 404 when requesting https://sheets.googleapis.com/v4/spreadsheets/1KpJw640oNNwVfEasGoSffrfoyC7i1ryHakdWZmr-AX4/values:batchUpdate?alt=json returned "Requested entity was not found.">
I am trying to update a Google Sheet file with the help of this API but the only scope that I manage using is "readonly". I tried deleting the token.pickle file : I get identified so the request isn't requiring authentification credentials. But I don't know why I would still get an error. So basically all I can do is extracting data from a sheet but not overwrite cells.
from __future__ import print_function
from pprint import pprint
from googleapiclient import discovery
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
SCOPES = ['https:// www.googleapis.com/auth/spreadsheets'] #what I have changed from the Python Quickstart code from the Google Sheets API website
creds = None
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server()
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = discovery.build('sheets', 'v4', credentials=creds)
spreadsheet_id = '1KpJw640oNNwVfEasGoSffrfoyC7i1ryHakdWZmr-AX4' #this id is correct and still I get an error
batch_update_values_request_body = {
'value_input_option': 'USER_ENTERED',
'data': [
{
"range": "Control Panel!A:B",
"majorDimension": "ROWS",
"values": [[1,2]]
}
],
}
request = service.spreadsheets().values().batchUpdate(spreadsheetId=spreadsheet_id,
body=batch_update_values_request_body)
response = request.execute()
pprint(response)

Categories