Source code for pygsheets.authorization

# -*- coding: utf-8 -*-.
import os
import json
import warnings

from google.oauth2 import service_account
from google.oauth2.credentials import Credentials
from google.auth.exceptions import RefreshError
from google_auth_oauthlib.flow import Flow, InstalledAppFlow
from google.auth.transport.requests import Request

from pygsheets.client import Client

    input = raw_input
except NameError:

def _get_initial_user_authentication_credentials(client_secret_file, local, scopes):
    if local:
        flow = InstalledAppFlow.from_client_secrets_file(client_secret_file, scopes)
        credentials = flow.run_local_server()
        flow = Flow.from_client_secrets_file(client_secret_file, scopes=scopes,
        auth_url, _ = flow.authorization_url(prompt='consent')

        print('Please go to this URL and finish the authentication flow: {}'.format(auth_url))
        code = input('Enter the authorization code: ')
        credentials = flow.credentials
    return credentials

def _get_user_authentication_credentials(client_secret_file, scopes, credential_directory=None, local=False):
    """Returns user credentials."""
    if credential_directory is None:
        credential_directory = os.getcwd()
    elif credential_directory == 'global':
        home_dir = os.path.expanduser('~')
        credential_directory = os.path.join(home_dir, '.credentials')
        if not os.path.exists(credential_directory):

    credentials_path = os.path.join(credential_directory, '')  # TODO Change hardcoded name?

    credentials = None
    if os.path.exists(credentials_path):
        # expect these to be valid. may expire at some point, but should be refreshed by google api client...
        credentials = Credentials.from_authorized_user_file(credentials_path, scopes=scopes)

    if credentials:
        if credentials.expired and credentials.refresh_token:
            except RefreshError as exc:
                print(f'Refresh token is obsolete {exc}. Executing the initial flow')
                credentials = _get_initial_user_authentication_credentials(client_secret_file, local, scopes)
        credentials = _get_initial_user_authentication_credentials(client_secret_file, local, scopes)

    # Save the credentials for the next run
    credentials_as_dict = {
        'token': credentials.token,
        'refresh_token': credentials.refresh_token,
        'id_token': credentials.id_token,
        'token_uri': credentials.token_uri,
        'client_id': credentials.client_id,
        'client_secret': credentials.client_secret
        with open(credentials_path, 'w') as file:
    except OSError:
        print("Unable to save the credentials to file-system")

    return credentials

_SCOPES = ('', '')

_deprecated_keyword_mapping = {
    'outh_file': 'client_secret',
    'outh_creds_store': 'credentials_directory',
    'service_file': 'service_account_file',
    'credentials': 'custom_credentials'

[docs]def authorize(client_secret='client_secret.json', service_account_file=None, service_account_env_var=None, service_account_json=None, credentials_directory='', scopes=_SCOPES, custom_credentials=None, local=False, **kwargs): """Authenticate this application with a google account. See general authorization documentation for details on how to attain the necessary files. :param client_secret: Location of the oauth2 credentials file. :param service_account_file: Location of a service account file. :param service_account_env_var: Use an environment variable to provide service account credentials. :param service_account_json: pass in json string directly; could use aws secret manager or azure key vault to store value :param credentials_directory: Location of the token file created by the OAuth2 process. Use 'global' to store in global location, which is OS dependent. Default None will store token file in current working directory. Please note that this is override your client secret. :param custom_credentials: A custom or pre-made credentials object. Will ignore all other params. :param scopes: The scopes for which the authentication applies. :param local: If local then a browser will be opened to autheticate :param kwargs: Parameters to be handed into the client constructor. :returns: :class:`Client` .. warning:: The `credentials_directory` overrides `client_secret`. So you might be accidently using a different credential than intended, if you are using global `credentials_directory` in more than one script. """ for key in kwargs: if key in ['outh_file', 'outh_creds_store', 'service_file', 'credentials']: warnings.warn('The argument {} is deprecated. Use {} instead.'.format(key, _deprecated_keyword_mapping[key]) , category=DeprecationWarning) client_secret = kwargs.pop('outh_file', client_secret) service_account_file = kwargs.pop('service_file', service_account_file) credentials_directory = kwargs.pop('outh_creds_store', credentials_directory) custom_credentials = kwargs.pop('credentials', custom_credentials) if custom_credentials is not None: credentials = custom_credentials elif service_account_env_var is not None: service_account_info = json.loads(os.environ[service_account_env_var]) credentials = service_account.Credentials.from_service_account_info( service_account_info, scopes=scopes) elif service_account_json is not None: service_account_info = json.loads(service_account_json) credentials = service_account.Credentials.from_service_account_info( service_account_info, scopes=scopes) elif service_account_file is not None: credentials = service_account.Credentials.from_service_account_file(service_account_file, scopes=scopes) else: credentials = _get_user_authentication_credentials(client_secret, scopes, credentials_directory, local) return Client(credentials, **kwargs)