Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use Python Google API without getting a fresh auth code via browser each time?

Tags:

google-api

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?

like image 667
spraff Avatar asked Jul 23 '18 21:07

spraff


1 Answers

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.

like image 132
Tanaike Avatar answered Oct 16 '22 22:10

Tanaike