I'm a google blooger.
I upload 10 posts everyday by using python.
After uploaded 25 posts, I have to make a new credential.
This is code
CLIENT_SECRET = 'client_secret.json'
SCOPE = 'https://www.googleapis.com/auth/blogger'
STORAGE = Storage('credentials.storage')
# Start the OAuth flow to retrieve credentials
def authorize_credentials():
# Fetch credentials from storage
credentials = STORAGE.get()
# If the credentials doesn't exist in the storage location then run the flow
if credentials is None or credentials.invalid:
flow = flow_from_clientsecrets(CLIENT_SECRET, scope=SCOPE)
http = httplib2.Http()
credentials = run_flow(flow, STORAGE, http=http)
return credentials
credentials = authorize_credentials()
Do you have an idea there is any method without refreshing credential by mannual?
My python isnt the best but i think you might have an indentation issue. Have a look at this.
def initialize_blogger():
"""Initializes the blogger service object.
Returns:
analytics an authorized blogger service object.
"""
# Parse command-line arguments.
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
parents=[tools.argparser])
flags = parser.parse_args([])
# Set up a Flow object to be used if we need to authenticate.
flow = client.flow_from_clientsecrets(
CLIENT_SECRETS_PATH, scope=SCOPES,
message=tools.message_if_missing(CLIENT_SECRETS_PATH))
# Prepare credentials, and authorize HTTP object with them.
# If the credentials don't exist or are invalid run through the native client
# flow. The Storage object will ensure that if successful the good
# credentials will get written back to a file.
storage = file.Storage('blogger.dat')
credentials = storage.get()
if credentials is None or credentials.invalid:
credentials = tools.run_flow(flow, storage, flags)
http = credentials.authorize(http=httplib2.Http())
# Build the service object.
service= build('blogger', 'v3', http=http)
return service
Related
When trying to query the Google Search Console for certain metrics (not pictured) using the Google search Console API, specifically OAuth 2.0, I am getting a HTTPError 403: "returned "User does not have sufficient permission for site 'XXXXXXXX.com'. See also: https://support.google.com/webmasters/answer/2451999.". Details: "[{'message': "User does not have sufficient permission for site 'https://www.xxxxxx.com'. See also: https://support.google.com/webmasters/answer/2451999.", 'domain': 'global', 'reason': 'forbidden'}]">" (replaced site URL with x's)
I have also gotten a 403 error that says I do not have a Google Analytics account on some other attempts.
Below is the code to authorize the access:
def get_domain_name(start_url):
domain_name = '{uri.netloc}'.format(uri=urlparse(start_url)) # Get Domain Name To Name Project
domain_name = domain_name.replace('.','_')
return domain_name
def create_project(directory):
if not os.path.exists(directory):
print('Create project: '+ directory)
os.makedirs(directory)
def authorize_creds(creds):
# Variable parameter that controls the set of resources that the access token permits.
SCOPES = ['https://www.googleapis.com/auth/webmasters.readonly']
# Path to client_secrets.json file
CLIENT_SECRETS_PATH = creds
# Create a parser to be able to open browser for Authorization
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
parents=[tools.argparser])
flags = parser.parse_args([])
flow = client.flow_from_clientsecrets(
CLIENT_SECRETS_PATH, scope = SCOPES,
message = tools.message_if_missing(CLIENT_SECRETS_PATH))
# Prepare credentials and authorize HTTP
# If they exist, get them from the storage object
# credentials will get written back to a file.
storage = file.Storage('authorizedcreds.dat')
credentials = storage.get()
# If authenticated credentials don't exist, open Browser to authenticate
if credentials is None or credentials.invalid:
credentials = tools.run_flow(flow, storage, flags)
http = credentials.authorize(http=httplib2.Http())
webmasters_service = build('webmasters', 'v3', http=http)
return webmasters_service
I followed the Google Sheet Python API Quickstart guide (https://developers.google.com/sheets/api/quickstart/python) and was able to get it working using their supplied code:
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.
"""
# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/sheets.googleapis.com-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/spreadsheets'
CLIENT_SECRET_FILE = 'my/path/client_secret.json'
APPLICATION_NAME = 'Google Sheets API Python Quickstart'
credential_path = 'my/path/sheets.googleapis.com-python-quickstart.json'
store = Storage(credential_path)
credentials = store.get()
## !!!!! Is this needed?
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
In the default setup I downloaded two JSON files:
client_secret.JSON
downloaded to project directory.
sheets.googleapis.com-python-quickstart.JSON
downloaded to ~/.credentials directory
The sheets.googleapis.com JSON file starts with:
"_module": "oauth2client.client".
Question 1: What is the purpose for each of these JSON files?
Question 2: Are both of these JSON files needed to successfully use the Google Sheets API?
I am thinking no, as I am able to get the API working without the client_secret.JSON file.
How about this answer? I think when you know the OAuth2 process for retrieving access token and refresh token, you can understand the meaning of both files. The flow for retrieving access token and refresh token using OAuth2 is as follows.
Flow :
Download client_secret.JSON from the API Console.
client_secret.JSON includes client_id, client_secret and redirect_uris.
Retrieve an authorization code using scopes and client_id from client_secret.JSON.
Retrieve access token and refresh token using the authorization code, client_id, client_secret and redirect_uris.
Retrieved access token, refresh token and other parameters are saved to the file of sheets.googleapis.com-python-quickstart.JSON.
Note :
When you run the Quickstart for the first time, the authorization process using your browser is launched. At that time, the script of Quickstart retrieves the authorization code using client_id and scopes, and then the access token and refresh token are retrieved using the authorization code, client_id, client_secret and redirect_uris.
After the first run of the Quickstart, the access token is retrieved by the refresh token from sheets.googleapis.com-python-quickstart.JSON. By this, retrieving the authorization code using browser is not required to do. So when there is sheets.googleapis.com-python-quickstart.JSON, client_secret.JSON is not required.
I think that this leads to an answer for your Question 2.
But, if you want to change scopes and/or credentials of client_secret.JSON, the authorization process using browser and retrieving the authorization code are required to do. For this, you have to remove sheets.googleapis.com-python-quickstart.JSON and authorize again. At that time, at Quickstart, client_secret.JSON is used again.
References :
Using OAuth 2.0 to Access Google APIs
Authorization for Google Services
If this is not useful for you, I'm sorry.
I'm using google service account for access all mail from gmail account without UI interface but When I execute my code it giving me error
googleapiclient.errors.HttpError: https://www.googleapis.com/gmail/v1/users/me/labels?alt=json returned
"Bad Request">
But when i check Quotas from https://console.developers.google.com/apis/api/gmail.googleapis.com/quotas
there is showing all request that I did using my python code but it always return Bad request when I execute below code.
import httplib2
from apiclient import discovery
from oauth2client.service_account import ServiceAccountCredentials
def get_credentials():
scopes = ['https://mail.google.com/',
'https://www.googleapis.com/auth/gmail.compose',
'https://www.googleapis.com/auth/gmail.metadata',
'https://www.googleapis.com/auth/gmail.readonly',
'https://www.googleapis.com/auth/gmail.labels',
'https://www.googleapis.com/auth/gmail.modify',
'https://www.googleapis.com/auth/gmail.metadata',
'https://www.googleapis.com/auth/gmail.settings.basic']
credentials = ServiceAccountCredentials.from_json_keyfile_name(
'client_secret.json', scopes=scopes)
return credentials
def main():
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
results = service.users().labels().list(userId='me').execute()
labels = results.get('labels', [])
if not labels:
print('No labels found.')
else:
print('Labels:')
for label in labels:
print(label['name'])
if __name__ == '__main__':
main()
Much has changed since this post was first written,
If anyone else is still looking for an answer. This is my initialization process for the Gmail API today.
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools
SCOPES = 'https://www.googleapis.com/auth/gmail.readonly'
def main():
# Setup for the Gmail API
store = file.Storage('token.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
creds = tools.run_flow(flow, store)
service = build('gmail', 'v1', http=creds.authorize(Http()))
# Call the Gmail API to fetch INBOX
results = service.users().labels().list().execute()
A major difference is the use of access tokens along with credentials in my code.
I am playing with a Python script that is based on https://developers.google.com/drive/v3/web/quickstart/python and it works fine. I can upload simple text files to my Drive account.
The code on that page is as follows:
# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/drive-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Drive 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,
'drive-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
Suppose that the script is executed once, resulting in 'drive-python-quickstart.json' file being saved with something like this (X's replacing sensitive information of course):
{"_module": "oauth2client.client",
"scopes": ["https://www.googleapis.com/auth/drive.file"],
"token_expiry": "2016-11-13T07:15:15Z",
"id_token": null,
"access_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"invalid": false,
"token_response": {"access_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"},
"client_id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.apps.googleusercontent.com",
"token_info_uri": "https://www.googleapis.com/oauth2/v3/tokeninfo",
"client_secret": "XXXXXXXXXXXXXXXXXXXXXXXX",
"revoke_uri": "https://accounts.google.com/o/oauth2/revoke",
"_class": "OAuth2Credentials",
"refresh_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"user_agent": null}
Let's suppose that the 'drive-python-quickstart.json' file is always existing and both readable and writable. Suppose some time passes, and the script executes again at some time after the time given by the "token_expiry" key in that JSON value. Is it expected that something detects that the time has expired on the Credentials object, forcing the credentials object to switch into an invalid state, which means that credentials.invalid then becomes True? Or is it the case that the existence of the "refresh_token" field implies that the something in the API will automatically update the 'drive-python-quickstart.json' file automatically such that credentials.invalid always returns True?
The Google python client library will refresh the access token as needed as long as your refresh token is good. To be clear, the client library is used to access the API. The API has no control over your authentication. It expects you, or rather the client library, to send it the information it requires in order for it to work.
Top Tip: Refresh tokens that aren't used for six months will also expire, so I recommend you run your script at least once every six months.
Is there any way to use a refresh token with Google directory service API?
I couldn't find any examples how to do that (I'm using Python).
I'm looking for something similar to the following code (this works for Google Adwords API), with previosly set credentials:
oauth2_client = oauth2.GoogleRefreshTokenClient(
CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN)
adwords_client = adwords.AdWordsClient(
DEVELOPER_TOKEN, oauth2_client, USER_AGENT, CLIENT_CUSTOMER_ID)
self.managed_customer_service = adwords_client.GetService(
'ManagedCustomerService', version='v201402')
For Directory API I found just the following code snippet, but I have no idea how I could use a refresh token with it:
flow = OAuth2WebServerFlow(CLIENT_ID, CLIENT_SECRET, OAUTH_SCOPE, REDIRECT_URI)
authorize_url = flow.step1_get_authorize_url()
print 'Go to the following link in your browser: ' + authorize_url
code = raw_input('Enter verification code: ').strip()
credentials = flow.step2_exchange(code)
# Create an httplib2.Http object and authorize it with our credentials
http = httplib2.Http()
http = credentials.authorize(http)
self.directory_service = build('admin', 'directory_v1', http=http)
My final goal is to authorize my application using just the refresh token and without having to open the browser, login and get a new token each time.
The Python client library can automatically store, load, and refresh credentials if you use a Storage object. The Gmail API Python Quickstart sample shows how to use a file storage, which saves the credentials to disk. Here are the relevant lines of code:
from oauth2client.file import Storage
from oauth2client.tools import run
...
# Location of the credentials storage file
STORAGE = Storage('gmail.storage')
...
# Try to retrieve credentials from storage or run the flow to generate them
credentials = STORAGE.get()
if credentials is None or credentials.invalid:
credentials = run(flow, STORAGE, http=http)
There are additional storage classes built into the client library, or you can extend the Storage base class to implement you own.