ValueError: Client secrets must be for a web or installed app

25,561

Solution 1

The problem was that I was using the json generated under Service account keys Manage service accounts and not the one under OAuth 2.0 client IDs.

Solution 2

For anyone coming here because they would like to actually connect to the GCP calendar API via a service-account and not this Oauth2 client id, create the creds object in the original example as follows:

from google.oauth2 import service_account

SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
SERVICE_ACCOUNT_FILE = '/path/to/service.json'

credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

Assuming the service-account is configured with the correct access, this will access the calendar without prompting user for confirmation.

Share:
25,561
PaoloAgVa
Author by

PaoloAgVa

Automation engineer, software developer, muppet enthusiast.

Updated on October 20, 2021

Comments

  • PaoloAgVa
    PaoloAgVa over 2 years

    I am running the quickstart.py example code under Python Quickstart and I am getting the following error:

    ValueError: Client secrets must be for a web or installed app.

    I created a credentials.json file with project owner rights.

    The error occurs in the following piece of code:

    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()
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)
    

    I notice also that the token.pickle file is not being created. This is the error output:

      File "updateSlidev01.py", line 51, in <module>
        main()
      File "updateSlidev01.py", line 31, in main
        flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
      File "/Library/Python/2.7/site-packages/google_auth_oauthlib/flow.py", line 174, in from_client_secrets_file
        return cls.from_client_config(client_config, scopes=scopes, **kwargs)
      File "/Library/Python/2.7/site-packages/google_auth_oauthlib/flow.py", line 147, in from_client_config
        'Client secrets must be for a web or installed app.')
    ValueError: Client secrets must be for a web or installed app.
    
  • Kajsa
    Kajsa over 4 years
    What can you use instead if the json was created as a service account?
  • Kajsa
    Kajsa over 4 years
    Found the solution for it here developers.google.com/identity/protocols/…
  • ricekab
    ricekab over 4 years
    @Kajsa Thanks for that, always appreciate it when someone comes back to answer their question.
  • Adam Hughes
    Adam Hughes over 3 years
    Hi - so can I ask does this mean a normal serivce account cannot be used for such an app?
  • ivanibash
    ivanibash almost 3 years
    god bless you 🙏
  • macetw
    macetw over 2 years
    Why would we use a scope of "sqlservice.admin" if we're trying to connect to the GCP calendar API? I think you meant "calendar.readonly." Please correct if I'm right.
  • Adam Hughes
    Adam Hughes over 2 years
    Probably - I think this was just the scope I happened to be using at the time. But yes, obviously use the appropriate scope for the task at hand.