'How can I use Python Google API without getting a fresh auth code via browser each time?
I am playing with the Google API. I am using this as a starting point, here is the actual Python code.
I have created a OAuth 2.0 client ID at https://console.developers.google.com/apis/credentials and downloaded it as client_secret.json
which is used in the code as follows:
CLIENT_SECRETS_FILE = "client_secret.json"
def get_authenticated_service():
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
credentials = flow.run_console()
return build(API_SERVICE_NAME, API_VERSION, credentials = credentials)
The contents of client_secret.json
looks like this:
{
"installed": {
"client_id": "**REDACTED**",
"project_id": "api-project-1014650230452",
"auth_uri": "https:\/\/accounts.google.com\/o\/oauth2\/auth",
"token_uri": "https:\/\/accounts.google.com\/o\/oauth2\/token",
"auth_provider_x509_cert_url": "https:\/\/www.googleapis.com\/oauth2\/v1\/certs",
"client_secret": "**REDACTED**",
"redirect_uris": [
"urn:ietf:wg:oauth:2.0:oob",
"http:\/\/localhost"
]
}
}
The whole program works and successfully returns a meaningful data set, however, each time I run the program I am prompted as follows:
Please visit this URL to authorize this application: https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=... Enter the authorization code:
I enter the code and the program works, but I have to visit this URL and get a fresh code each time the program runs. I was under the impression that client_secret.json
existed precisely to prevent this from being necessary.
What do I have to do to make my CLI Python program use the API without having to get a fresh token each time?
Solution 1:[1]
You want to run the script without retrieving the code every time. If my understanding is correct, how about this modification? In this modification, when the script is run for the first time, the refresh token is saved to a file of "credential_sample.json". By this, from the next run, you can use the API using the access token retrieved by the refresh token. So you are not required to retrieve the code every time.
Modified script :
Please modify as follows.
From :def get_authenticated_service():
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
credentials = flow.run_console()
return build(API_SERVICE_NAME, API_VERSION, credentials = credentials)
To :
from oauth2client import client # Added
from oauth2client import tools # Added
from oauth2client.file import Storage # Added
def get_authenticated_service(): # Modified
credential_path = os.path.join('./', 'credential_sample.json')
store = Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRETS_FILE, SCOPES)
credentials = tools.run_flow(flow, store)
return build(API_SERVICE_NAME, API_VERSION, credentials=credentials)
Note :
- When you run this for the first time, the browser is automatically opened. When you authorize the scopes, the script automatically retrieves the code and create the tokens to "credential_sample.json".
- This modification supposes that your current script works except for being required to retrieve the code every time.
References :
- Python Quickstart
- About this modification, you can also refer this script.
If this was not what you want, I'm sorry.
Solution 2:[2]
After playing with a bunch of solutions, including the accepted answer, here's mine:
def get_authenticated_service():
try:
credentials = google.oauth2.credentials.Credentials.from_authorized_user_file(CLIENT_SECRETS_FILE)
except ValueError as e: # first run with new secret.json (no refresh_token yet)
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
credentials = flow.run_console()
with open(CLIENT_SECRETS_FILE, 'w') as file:
file.write(credentials.to_json())
return build(API_SERVICE_NAME, API_VERSION, credentials=credentials)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Tanaike |
Solution 2 |