예제 #1
0
    def __init__(
        self,
        refresh_token=None,
        client_id=None,
        client_secret=None,
        token_uri="https://www.googleapis.com/oauth2/v3/token",
        credentials=None,
        service=None,
    ):
        if service:
            self.service = service
        else:
            if not credentials:
                credentials = GoogleCredentials(
                    refresh_token=refresh_token,
                    token_uri=token_uri,
                    client_id=client_id,
                    client_secret=client_secret,
                    user_agent="Python client library",
                    access_token=None,
                    token_expiry=None,
                    revoke_uri=None,
                )

            self.service = build("analytics",
                                 "v3",
                                 credentials=credentials,
                                 cache_discovery=False)
예제 #2
0
파일: auth.py 프로젝트: SSSakuraa/gcp
    def post_service(self, request):
        data = json.loads(request.get_data())
        (client_id, client_secret,
         refresh_token) = self.aes_decrypt(data['client_id'],
                                           data['client_secret'],
                                           data['refresh_token'])
        if 'project_id' in data.keys():
            self.project = data['project_id']
        if 'region_id' in data.keys():
            self.region = data['region_id']
        elif 'region_name' in data.keys():
            self.region = Region().get_region_id(data['region_name'])
#        if data.has_key('zone') and self.region != '':
#            self.zone=self.region+'-'+data['zone']

        credentials = GoogleCredentials(
            access_token=None,
            client_id=client_id,
            client_secret=client_secret,
            refresh_token=refresh_token,
            token_expiry=None,
            token_uri='https://www.googleapis.com/oauth2/v4/token',
            user_agent='Python client library')

        service = discovery.build('compute', 'beta', credentials=credentials)
        return service
예제 #3
0
def _get_application_default_credential_from_dict(client_credentials):
    """Build the Application Default Credentials from file."""
    credentials_type = client_credentials.get('type')
    if credentials_type == AUTHORIZED_USER:
        required_fields = set(['client_id', 'client_secret', 'refresh_token'])
    elif credentials_type == SERVICE_ACCOUNT:
        required_fields = set(
            ['client_id', 'client_email', 'private_key_id', 'private_key'])
    else:
        raise ApplicationDefaultCredentialsError(
            "'type' field should be defined (and have one of the '" +
            AUTHORIZED_USER + "' or '" + SERVICE_ACCOUNT + "' values)")

    missing_fields = required_fields.difference(client_credentials.keys())

    if missing_fields:
        _raise_exception_for_missing_fields(missing_fields)

    if client_credentials['type'] == AUTHORIZED_USER:
        return GoogleCredentials(
            access_token=None,
            client_id=client_credentials['client_id'],
            client_secret=client_credentials['client_secret'],
            refresh_token=client_credentials['refresh_token'],
            token_expiry=None,
            token_uri=GOOGLE_TOKEN_URI,
            user_agent='Python client library')
    else:  # client_credentials['type'] == SERVICE_ACCOUNT
        from oauth2client.service_account import _JWTAccessCredentials
        return _JWTAccessCredentials.from_json_keyfile_dict(client_credentials)
예제 #4
0
파일: gdoc.py 프로젝트: gxf1986/hub
def pull_gdoc(source: dict, project: str, path: str) -> List[str]:
    """
    Pull google doc using given user token
    """
    assert "doc_id" in source, "source must have a doc_id"
    assert "token" in source, "source must include a token"

    credentials = GoogleCredentials(
        source["token"],
        None,
        None,
        None,
        None,
        None,
        "Stencila Hub Client",
    )
    docs_service = build("docs",
                         "v1",
                         credentials=credentials,
                         cache_discovery=False)
    document = docs_service.documents().get(
        documentId=source["doc_id"]).execute()

    with open(os.path.join(project, path), "wb") as file:
        file.write(json.dumps(document).encode("utf-8"))

    return [path]
예제 #5
0
파일: gdrive.py 프로젝트: gxf1986/hub
def pull_gdrive(source: dict, project: str, path: str) -> List[str]:
    """
    Pull a google drive folder
    """
    assert "folder_id" in source, "source must have a folder_id"
    assert ("token" in source
            and source["token"] is not None), "source must include a token"

    credentials = GoogleCredentials(
        source["token"],
        None,
        None,
        None,
        None,
        None,
        "Stencila Hub Client",
    )
    drive_service = build("drive",
                          "v3",
                          credentials=credentials,
                          cache_discovery=False)
    files_resource = drive_service.files()
    local_path = utf8_normpath(utf8_path_join(project, path))
    utf8_makedirs(local_path, exist_ok=True)

    return pull_directory(
        files_resource,
        source["folder_id"],
        local_path,
    )
예제 #6
0
def createauth():
    creds = GoogleCredentials(None, credentials.googleusername,
                              credentials.googlesecret,
                              credentials.googlerefresh, None,
                              'https://accounts.google.com/o/oauth2/token',
                              'sms-proxy')
    return creds
예제 #7
0
def refresh(client_id, client_secret, refresh_token):
    cred = GoogleCredentials(None, client_id, client_secret, refresh_token,
                             None,
                             "https://accounts.google.com/o/oauth2/token",
                             None)
    http = cred.authorize(httplib2.Http())
    cred.refresh(http)
    return cred.access_token
예제 #8
0
def pull_google_contacts(user, book):
    app = SocialApp.objects.filter(provider='google')[0]
    token = SocialToken.objects.get(account__user=user, app=app)
    creds = GoogleCredentials(
        access_token=token.token,
        token_expiry=None,
        token_uri=GOOGLE_TOKEN_URI,
        client_id=app.client_id,
        client_secret=app.secret,
        refresh_token=None,
        user_agent='Python',
        revoke_uri=None,
    )

    http = httplib2.Http()
    http = creds.authorize(http)
    people_service = build(serviceName='people', version='v1', http=http)

    try:
        connections = people_service.people().connections().list(
            resourceName='people/me', pageSize=50).execute()
    except HttpError:
        time.sleep(60)
        connections = people_service.people().connections().list(
            resourceName='people/me', pageSize=50).execute()
    except HttpAccessTokenRefreshError:
        sentry.error("Bad google token for user",
                     exc_info=True,
                     extra={"user": user})
        return

    next_page = connections.get('nextPageToken')
    sync_token = connections.get('nextSyncToken')

    get_expanded_response_and_create_contacts(connections, people_service,
                                              sync_token, book)
    try:
        success = True
        while next_page:
            try:
                connections = people_service.people().connections().list(
                    resourceName='people/me', pageSize=50,
                    pageToken=next_page).execute()
            except HttpError:
                time.sleep(60)
                connections = people_service.people().connections().list(
                    resourceName='people/me', pageSize=50,
                    pageToken=next_page).execute()
            get_expanded_response_and_create_contacts(
                connections, people_service, connections.get('nextSyncToken'),
                book)
            next_page = connections.get('nextPageToken')
        return success
    except:
        sentry.error("Google Import Error",
                     exc_info=True,
                     extra={"book": book})
        return False
예제 #9
0
    def __init__(self,
                 clientid=None,
                 secret=None,
                 token=None,
                 projectid=None,
                 imageid=None,
                 instancetype=None,
                 user=None,
                 localpath=None,
                 zone=None):
        """
        Init GCE connector to create and configure instance VMs.
        :param clientid: client id from GCE API manager (create credentials API manager)
            https://developers.google.com/identity/protocols/application-default-credentials
        :param secret: client secret obtained from the GCE API manager
        :param token: refresh token obtained from gcloud sdk authentication
        :param imageid: GCE stores images based on predefined family keys; this should be provided
                        as stored in GCE should be provided: e.g. ubuntu-1604-lts
        :param instancetype: GCE hardware profile or vm size e.g. 'n1-highmem-16'
        :param user: remote ssh user for the VM
        :param localpath: localpath where the logs should be downloaded, and the
                            default path for other necessary tools
        :param zone: GCE global zone to connect to
        """
        self.credentials = GoogleCredentials(
            access_token=None,
            client_id=clientid,
            client_secret=secret,
            refresh_token=token,
            token_expiry=None,
            token_uri=GOOGLE_TOKEN_URI,
            user_agent='Python client library')

        self.compute = None
        self.storage = None

        self.instancetype = instancetype
        self.localpath = localpath
        self.host_key_file = os.path.join(self.localpath, 'known_hosts')
        if not zone:
            self.zone = 'us-west1-a'
        else:
            self.zone = zone
        self.region = re.match('([a-zA-Z]+-[a-zA-Z0-9]+)', self.zone).group(1)

        self.imageid = imageid
        self.projectid = projectid
        self.user = user

        self.key_name = 'test_ssh_key'
        self.bucket_name = 'middleware_bench' + str(time.time()).replace(
            '.', '')
        self.net_name = 'middleware-bench-net' + str(time.time()).replace(
            '.', '')
        self.subnet_name = 'middleware-bench-subnet' + str(
            time.time()).replace('.', '')

        self.vms = []
예제 #10
0
def get_user_google_token(
    user: User,
) -> Tuple[Optional[SocialToken], Optional[SocialApp]]:
    """
    Get a Google `SocialToken` for the user.

    If necessary will refresh the OAuth2 access token and
    update it in the database so that the refresh does not
    need to be done again within the next hour (at time of writing
    the expiry time for tokens).

    In most contexts that this function is used the Google `SocialApp`
    is also needed (e.g. for it's client_id etc) so we return that too.
    To avoid exceptions during development where there might not be a
    Google `SocialApp` we return None.
    """
    token = get_user_social_token(user, Provider.google)

    try:
        app = SocialApp.objects.get(provider=Provider.google.name)
    except SocialApp.DoesNotExist:
        app = None

    if token is None:
        return None, app

    # If the token has not expired just return it
    if token.expires_at is None or token.expires_at > timezone.now() - timezone.timedelta(
        seconds=90
    ):
        return token, app

    # The folowing are all required for a token refresh so if any
    # are missing, and the token has expired, return no token.
    if not (token.token and token.token_secret and token.expires_at):
        return None, app

    # Refresh the token
    credentials = GoogleCredentials(
        access_token=token.token,
        client_id=app.client_id,
        client_secret=app.secret,
        refresh_token=token.token_secret,
        token_expiry=token.expires_at,
        token_uri="https://accounts.google.com/o/oauth2/token",
        user_agent="Stencila Hub Client",
    )
    credentials.refresh(http=transport.get_http_object())
    info = credentials.get_access_token()

    # Save the new access token and expiry time
    token.token = info.access_token
    token.expires_at = timezone.now() + timezone.timedelta(seconds=info.expires_in)
    token.save()

    return token, app
예제 #11
0
 def initialize_credentials(self, config):
     return GoogleCredentials(
         access_token=config['access_token'],
         refresh_token=config['refresh_token'],
         client_id=config['client_id'],
         client_secret=config['client_secret'],
         # let the library refresh the token if it is expired
         token_expiry=None,
         token_uri="https://accounts.google.com/o/oauth2/token",
         user_agent="tap-google-analytics (via singer.io)")
예제 #12
0
    def _get_driver_service(self=None):
        if self.driver_service_singleton is None:
            if self.context_env is not None:
                Config = self.context_env.env['ir.config_parameter'].sudo()
                google_drive_refresh_token = Config.get_param(
                    'google_drive_refresh_token')
            else:
                Config = request.env['ir.config_parameter'].sudo()
                google_drive_refresh_token = Config.get_param(
                    'google_drive_refresh_token')
                user_is_admin = request.env['res.users'].browse(
                    request.env.user.id)._is_admin()
                if not google_drive_refresh_token:
                    if user_is_admin:
                        dummy, action_id = request.env[
                            'ir.model.data'].get_object_reference(
                                'base_setup', 'action_general_configuration')
                        msg = _(
                            "You haven't configured 'Authorization Code' generated from google, Please generate and configure it ."
                        )
                        raise RedirectWarning(
                            msg, action_id, _('Go to the configuration panel'))
                    else:
                        raise UserError(
                            _("Google Drive is not yet configured. Please contact your administrator."
                              ))
            google_drive_client_id = Config.get_param('google_drive_client_id')
            google_drive_client_secret = Config.get_param(
                'google_drive_client_secret')
            access_token = None
            token_expiry = None
            token_uri = 'https://www.googleapis.com/auth/drive.metadata.readonly'

            # GOOGLE_TOKEN_URI = 'https://oauth2.googleapis.com/token'
            token_uri = oauth2client.GOOGLE_TOKEN_URI
            user_agent = 'Python client library'
            revoke_uri = None
            credentials = GoogleCredentials(access_token,
                                            google_drive_client_id,
                                            google_drive_client_secret,
                                            google_drive_refresh_token,
                                            token_expiry,
                                            token_uri,
                                            user_agent,
                                            revoke_uri=revoke_uri)
            credentials.scopes = [
                'https://www.googleapis.com/auth/drive.metadata',
                'https://www.googleapis.com/auth/drive.readonly',
                'https://www.googleapis.com/auth/drive'
            ]
            self.driver_service_singleton = build('drive',
                                                  'v3',
                                                  credentials=credentials)
        return self.driver_service_singleton
예제 #13
0
 def get_google_credentials(self):
     social_user = self.user.social_auth.filter(provider='google-oauth2').first()
     if social_user is None:
         return None
     access_token = social_user.extra_data["access_token"]
     refresh_token = social_user.extra_data.get("refresh_token")
     expires_at = social_user.extra_data["expires"]
     return GoogleCredentials(access_token, get_secret('SOCIAL_AUTH_GOOGLE_OAUTH2_KEY'),
                              get_secret('SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET'), refresh_token,
                              expires_at,
                              "https://accounts.google.com/o/oauth2/token", 'my-user-agent/1.0')
예제 #14
0
    def __init__(self, config):
        self.credentials = GoogleCredentials(
            None,
            client_id=config.get('client_id'),
            client_secret=config.get('client_secret'),
            refresh_token=config.get('refresh_token'),
            token_expiry=None,
            token_uri="https://accounts.google.com/o/oauth2/token",
            user_agent=config.get('user_agent'))

        self.refresh_credentials()
예제 #15
0
def get_credentials(source):
  gCreds = GoogleCredentials(
    source['access_token'],
    client['web']['client_id'],
    client['web']['client_secret'],
    source['refresh_token'],
    source['token_expiry'],
    GOOGLE_TOKEN_URI,
    source['user_agent'],
    revoke_uri=source['revoke_uri']
  )
  return gCreds
예제 #16
0
def getDriveService(user_agent):

    with open(TOKEN) as f:
        creds = json.load(f)

    credentials = GoogleCredentials(None,creds["client_id"],creds["client_secret"],
                                          creds["refresh_token"],None,"https://accounts.google.com/o/oauth2/token",user_agent)
    http = credentials.authorize(Http())
    credentials.refresh(http)
    drive_service = build('drive', 'v3', http)

    return drive_service
예제 #17
0
파일: sources.py 프로젝트: jlbrewe/hub
 def create_credentials(self, secrets: dict) -> GoogleCredentials:
     """
     Create a Google credentials object to use with Google APIs.
     """
     return GoogleCredentials(
         access_token=secrets.get("access_token"),
         client_id=secrets.get("client_id"),
         client_secret=secrets.get("client_secret"),
         refresh_token=secrets.get("refresh_token"),
         token_expiry=None,
         token_uri="https://accounts.google.com/o/oauth2/token",
         user_agent="Stencila Hub Client",
     )
예제 #18
0
 def get_credentials(self, scope):
     # check
     # run: gcloud beta auth application-default login
     # look to ~/.config/gcloud/application_default_credentials.json
     credentials = GoogleCredentials(
         access_token=None,
         client_id=self.auth['client_id'],
         client_secret=self.auth['client_secret'],
         refresh_token=self.auth['refresh_token'],
         token_expiry=None,
         token_uri=GOOGLE_TOKEN_URI,
         user_agent='Python client library')
     return credentials
 def initialize_credentials(self, config):
     if 'oauth_credentials' in config:
         return GoogleCredentials(
             access_token=config['oauth_credentials']['access_token'],
             refresh_token=config['oauth_credentials']['refresh_token'],
             client_id=config['oauth_credentials']['client_id'],
             client_secret=config['oauth_credentials']['client_secret'],
             token_expiry=None,  # let the library refresh the token if it is expired
             token_uri="https://accounts.google.com/o/oauth2/token",
             user_agent="tap-google-analytics (via singer.io)"
         )
     else:
         return ServiceAccountCredentials.from_json_keyfile_dict(config['client_secrets'], SCOPES)
예제 #20
0
 def dispatch(self, request, *args, **kwargs):
     if not gargoyle.is_active('import_from_google', request):
         return HttpResponseRedirect('/')
     app = SocialApp.objects.filter(provider='google')[0]
     url = "{}?process=connect&next={}".format(
         reverse("google_login"),
         reverse("import-google-contacts",
                 kwargs={'book': self.request.current_book.id}),
     )
     try:
         token = SocialToken.objects.get(account__user=self.request.user,
                                         app=app)
     except SocialToken.DoesNotExist:
         sentry.error("Social token missing in google import",
                      extra={
                          "user": self.request.user,
                      })
         return HttpResponseRedirect(url)
     try:
         creds = GoogleCredentials(
             access_token=token.token,
             token_expiry=None,
             token_uri=GOOGLE_TOKEN_URI,
             client_id=app.client_id,
             client_secret=app.secret,
             refresh_token=None,
             user_agent='Python',
             revoke_uri=None,
         )
         http = httplib2.Http()
         http = creds.authorize(http)
         people_service = build(serviceName='people',
                                version='v1',
                                http=http)
         connections = people_service.people().connections().list(
             resourceName='people/me', pageSize=50).execute()
     except HttpAccessTokenRefreshError:
         return HttpResponseRedirect(url)
     cache.set("{}::google-import".format(request.user.username),
               "processing", 86400)
     Channel('import-google-contacts').send({
         'user_id':
         self.request.user.id,
         'book_id':
         self.request.current_book.id
     })
     messages.success(
         request,
         "We're importing your Google contacts now! You'll receive an email when we're done."
     )
     return HttpResponseRedirect('/')
예제 #21
0
def connect_to_gdrive(access_token, refresh_token):
    credentials = GoogleCredentials(
        access_token,
        os.environ['GDRIVE_API_CLIENT_ID'],
        os.environ['GDRIVE_API_CLIENT_SECRET'],
        refresh_token,
        None,
        "https://www.googleapis.com/oauth2/v4/token",
        "cuely/1.0"
    )
    http = httplib2.Http()
    http = credentials.authorize(http)
    service = discovery.build('drive', 'v3', http=http)
    return service
예제 #22
0
 def get_service(self):
     if self.access_code == '' or self.access_token == '' or self.refresh_token == '':
         self._start_connection()
     else:
         credentials = GoogleCredentials(self.access_token, self.client_id,
                                         self.client_secret,
                                         self.refresh_token, 3920,
                                         google_drive_info['url'], 'test')
         http = httplib2.Http()
         http = credentials.authorize(http)
         service = build(google_drive_info['name'],
                         google_drive_info['version'],
                         http=http)
         return service
예제 #23
0
    def _get_credentials(self) -> dict:
        """ Authenticates with google fit and returns a dictionary with
        the most recent valid credentials """
        online_credentials = self.parameter_manager.get_multiple('/google_fit/')
        credentials = GoogleCredentials(**online_credentials, token_expiry=None, user_agent=None)

        http = credentials.authorize(httplib2.Http())
        credentials.refresh(http)

        credentials_dict = json.loads(credentials.to_json())
        self.access_token = credentials_dict.get("access_token")
        self._store_credentials_online(credentials_dict)

        return credentials_dict        
예제 #24
0
    def init_credentials(self):
        """Build a `GoogleCredentials` object from the `SocialToken`/client IDs we have."""
        if self._credentials is not None:
            return

        self._credentials = GoogleCredentials(
            self.social_auth_token.token,
            self.google_app.client_id,
            self.google_app.secret,
            self.social_auth_token.token_secret,
            self.social_auth_token.expires_at,
            GOOGLE_TOKEN_URI,
            "Stencila Hub Client",
        )
예제 #25
0
class GmailManger:

    news = input("You want a new boi ?\n")
    credencialos = get_stored_credentials(1)
    if credencialos == 0:
        email = input("Please input your email\n")
        url = get_authorization_url(email, "")
        webbrowser.open(url)
        authorization = input("Please input the authorization code given\n")
        credentials = get_credentials(authorization, "holis")
        #storage.put(Credentials)
        #credentials = storage.get()

        print("Credentials : \n" + credentials.to_json())
        userinfo = get_user_info(credentials)
        print("Printing info...")
        for infotas in userinfo:
            print(str(infotas) + ' - ' + str(userinfo[infotas]))

        webbrowser.open(userinfo['link'])
    else:
        #client stuff
        clientstuff = json.load(open('./client_credentials.json'))

        dicto = json.loads(credencialos)
        print(dicto['id_token']['email'])
        credentialos = GoogleCredentials(
            dicto['access_token'], dicto['client_id'], dicto['client_secret'],
            dicto['refresh_token'], dicto['token_expiry'], dicto['token_uri'],
            dicto['user_agent'], dicto['revoke_uri'])
        #credentialos = AccessTokenCredentials(dicto['access_token'],'my-user-agent/1.0')
        #http_auth = credentialos.authorize(Http())
        http = httplib2.Http()
        http = credentialos.authorize(http)
        service = build('gmail', 'v1', http=http)
        mails = GmailMessages.ListMessages(
            service, dicto['id_token']['email'],
            'in:inbox is:unread -category:(promotions OR social)')
        for item in mails:
            indmessage = GmailMessages.getIndividualMessage(
                service, dicto['id_token']['email'], item['id'])
            #print(json.dumps(indmessage, sort_keys=True, indent=4, separators=(',', ': ')))
            headerswanted = ('From', 'Subject', 'Date')
            headersdicto = indmessage['payload']['headers']
            for ito in headersdicto:
                for want in headerswanted:
                    if ito['name'] == want:
                        print(want + ':' + ito['value'])
            print('\n')
예제 #26
0
def configure_youtube():
    cred = GoogleCredentials(None, os.environ.get('GOOGLE_CLIENT_ID'),
                             os.environ.get('GOOGLE_CLIENT_SECRET'),
                             os.environ.get('GOOGLE_REFRESH_TOKEN'), None,
                             "https://accounts.google.com/o/oauth2/token", '')
    http = cred.authorize(httplib2.Http())
    cred.refresh(http)

    api_service_name = "youtube"
    api_version = "v3"

    return googleapiclient.discovery.build(api_service_name,
                                           api_version,
                                           credentials=cred,
                                           cache_discovery=False)
예제 #27
0
def fit_client():
    """ build google fit service
    """
    credentials = GoogleCredentials(
        access_token=None,
        client_id=app.config['GOOGLE_CLIENT_ID'],
        client_secret=app.config['GOOGLE_CLIENT_SECRET'],
        refresh_token=app.config['GOOGLE_REFRESH_TOKEN'],
        token_expiry=None,
        token_uri=GOOGLE_TOKEN_URI,
        user_agent="My Dashboard",
    )
    http = httplib2.Http()
    http = credentials.authorize(http)

    return build('fitness', 'v1', http=http)
예제 #28
0
def get_credentials(credential_file=None, credentials=None):
    if credential_file:
        return GoogleCredentials.from_stream(credential_file)

    if credentials and credentials["type"] == "service_account":
        return ServiceAccountCredentials_from_dict(credentials)

    if credentials and credentials["type"] == "authorized_user":
        return GoogleCredentials(access_token=None,
                                 client_id=credentials["client_id"],
                                 client_secret=credentials["client_secret"],
                                 refresh_token=credentials["refresh_token"],
                                 token_expiry=None,
                                 token_uri=GOOGLE_TOKEN_URI,
                                 user_agent="pghoard")

    return GoogleCredentials.get_application_default()
예제 #29
0
 def __init__(self, user, *args, **kwargs):
     self.user = user
     self.social_token = SocialToken.objects.filter(app__provider='google',
                                                    account__provider='google',
                                                    account__user=user)
     token = self.social_token.get()
     credentials = GoogleCredentials(
         access_token=token.token,
         client_id=token.app.client_id,
         client_secret=token.app.secret,
         refresh_token=token.token_secret,
         token_expiry=token.expires_at,
         token_uri=GOOGLE_TOKEN_URI,
         user_agent=None
     )
     self.youtube = discovery.build('youtube', 'v3', credentials=credentials)
     self.social_app = SocialApp.objects.filter(id=token.app.id)
예제 #30
0
파일: gapis.py 프로젝트: jlbrewe/hub
def google_credentials(secrets: Dict) -> GoogleCredentials:
    """
    Create a Google credentials object to use with Google APIs.
    """
    assert secrets.get(
        "access_token"
    ), """A Google access token is required. Please connect a Google account to your Stencila
 account at https://hub.stenci.la/me/social/connections/."""

    return GoogleCredentials(
        access_token=secrets.get("access_token"),
        client_id=secrets.get("client_id"),
        client_secret=secrets.get("client_secret"),
        refresh_token=secrets.get("refresh_token"),
        token_expiry=None,
        token_uri="https://accounts.google.com/o/oauth2/token",
        user_agent="Stencila Hub Client",
    )