The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.

Title: Utilities for Working with Google APIs
Version: 1.5.2
Description: Provides utilities for working with Google APIs https://developers.google.com/apis-explorer. This includes functions and classes for handling common credential types and for preparing, executing, and processing HTTP requests.
License: MIT + file LICENSE
URL: https://gargle.r-lib.org, https://github.com/r-lib/gargle
BugReports: https://github.com/r-lib/gargle/issues
Depends: R (≥ 3.6)
Imports: cli (≥ 3.0.1), fs (≥ 1.3.1), glue (≥ 1.3.0), httr (≥ 1.4.5), jsonlite, lifecycle, openssl, rappdirs, rlang (≥ 1.1.0), stats, utils, withr
Suggests: aws.ec2metadata, aws.signature, covr, httpuv, knitr, rmarkdown, sodium, spelling, testthat (≥ 3.1.7)
VignetteBuilder: knitr
Config/Needs/website: tidyverse/tidytemplate
Config/testthat/edition: 3
Encoding: UTF-8
Language: en-US
RoxygenNote: 7.2.3
NeedsCompilation: no
Packaged: 2023-07-20 18:17:52 UTC; jenny
Author: Jennifer Bryan ORCID iD [aut, cre], Craig Citro [aut], Hadley Wickham ORCID iD [aut], Google Inc [cph], Posit Software, PBC [cph, fnd]
Maintainer: Jennifer Bryan <jenny@posit.co>
Repository: CRAN
Date/Publication: 2023-07-20 18:50:08 UTC

gargle: Utilities for Working with Google APIs

Description

Provides utilities for working with Google APIs https://developers.google.com/apis-explorer. This includes functions and classes for handling common credential types and for preparing, executing, and processing HTTP requests.

Author(s)

Maintainer: Jennifer Bryan jenny@posit.co (ORCID)

Authors:

Other contributors:

See Also

Useful links:


Authorization state

Description

An AuthState object manages an authorization state, typically on behalf of a wrapper package that makes requests to a Google API.

The ⁠vignette("gargle-auth-in-client-package)⁠ describes a design for wrapper packages that relies on an AuthState object. This state can then be incorporated into the package's requests for tokens and can control the inclusion of tokens in requests to the target API.

An AuthState should be created through the constructor function init_AuthState(), which has more details on the arguments.

Public fields

package

Package name.

client

An OAuth client.

app

[Deprecated] Use client instead.

api_key

An API key.

auth_active

Logical, indicating whether auth is active.

cred

Credentials.

Methods

Public methods


Method new()

Create a new AuthState

Usage
AuthState$new(
  package = NA_character_,
  client = NULL,
  api_key = NULL,
  auth_active = TRUE,
  cred = NULL,
  app = deprecated()
)
Arguments
package

Package name.

client

An OAuth client.

api_key

An API key.

auth_active

Logical, indicating whether auth is active.

cred

Credentials.

app

[Deprecated] Use client instead.

Details

For more details on the parameters, see init_AuthState()


Method format()

Format an AuthState

Usage
AuthState$format(...)
Arguments
...

Not used.


Method set_client()

Set the OAuth client

Usage
AuthState$set_client(client)
Arguments
client

An OAuth client.


Method set_app()

[Deprecated] Deprecated method to set the OAuth client

Usage
AuthState$set_app(app)
Arguments
app

[Deprecated] Use client instead.


Method set_api_key()

Set the API key

Usage
AuthState$set_api_key(value)
Arguments
value

An API key.


Method set_auth_active()

Set whether auth is (in)active

Usage
AuthState$set_auth_active(value)
Arguments
value

Logical, indicating whether to send requests authorized with user credentials.


Method set_cred()

Set credentials

Usage
AuthState$set_cred(cred)
Arguments
cred

User credentials.


Method clear_cred()

Clear credentials

Usage
AuthState$clear_cred()

Method get_cred()

Get credentials

Usage
AuthState$get_cred()

Method has_cred()

Report if we have credentials

Usage
AuthState$has_cred()

Method clone()

The objects of this class are cloneable with this method.

Usage
AuthState$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.


OAuth2 token objects specific to Google APIs

Description

Gargle2.0 is based on the Token2.0 class provided in httr. The preferred way to create a Gargle2.0 token is through the constructor function gargle2.0_token(). Key differences with Token2.0:

Super classes

httr::Token -> httr::Token2.0 -> Gargle2.0

Public fields

email

Email associated with the token.

package

Name of the package requesting a token. Used in messages.

client

An OAuth client.

Methods

Public methods

Inherited methods

Method new()

Create a Gargle2.0 token

Usage
Gargle2.0$new(
  email = gargle_oauth_email(),
  client = gargle_client(),
  package = "gargle",
  credentials = NULL,
  params = list(),
  cache_path = gargle_oauth_cache(),
  app = deprecated()
)
Arguments
email

Optional email address. See gargle2.0_token() for full details.

client

An OAuth consumer application.

package

Name of the package requesting a token. Used in messages.

credentials

Exists largely for testing purposes.

params

A list of parameters for the internal function init_oauth2.0(), which is a modified version of httr::init_oauth2.0(). gargle actively uses scope and use_oob, but does not use user_params, type, as_header (hard-wired to TRUE), use_basic_auth (accept default of use_basic_auth = FALSE), config_init, or client_credentials.

cache_path

Specifies the OAuth token cache. Read more in gargle_oauth_cache().

app

[Deprecated] Use client instead.

Returns

A Gargle2.0 token.


Method format()

Format a Gargle2.0 token

Usage
Gargle2.0$format(...)
Arguments
...

Not used.


Method print()

Print a Gargle2.0 token

Usage
Gargle2.0$print(...)
Arguments
...

Not used.


Method hash()

Generate the email-augmented hash of a Gargle2.0 token

Usage
Gargle2.0$hash()

Method cache()

Put a Gargle2.0 token into the cache

Usage
Gargle2.0$cache()

Method load_from_cache()

(Attempt to) get a Gargle2.0 token from the cache

Usage
Gargle2.0$load_from_cache()

Method refresh()

(Attempt to) refresh a Gargle2.0 token

Usage
Gargle2.0$refresh()

Method init_credentials()

Initiate a new Gargle2.0 token

Usage
Gargle2.0$init_credentials()

Method clone()

The objects of this class are cloneable with this method.

Usage
Gargle2.0$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.


Token for use on Google Compute Engine instances

Description

Token for use on Google Compute Engine instances

Token for use on Google Compute Engine instances

Details

This class uses the metadata service available on GCE VMs to fetch access tokens. Not intended for direct use. See credentials_gce() instead.

Super classes

httr::Token -> httr::Token2.0 -> GceToken

Methods

Public methods

Inherited methods

Method new()

Get an access for a GCE service account.

Usage
GceToken$new(params)
Arguments
params

A list of parameters for fetch_gce_access_token().

Returns

A GceToken.


Method init_credentials()

Request an access token.

Usage
GceToken$init_credentials()

Method refresh()

Refreshes the token. In this case, that just means "ask again for an access token".

Usage
GceToken$refresh()

Method can_refresh()

Placeholder implementation of required method. Returns TRUE.

Usage
GceToken$can_refresh()

Method format()

Format a GceToken().

Usage
GceToken$format(...)
Arguments
...

Not used.


Method print()

Print a GceToken().

Usage
GceToken$print(...)
Arguments
...

Not used.


Method cache()

Placeholder implementation of required method.

Usage
GceToken$cache()

Method load_from_cache()

Placeholder implementation of required method.

Usage
GceToken$load_from_cache()

Method revoke()

Placeholder implementation of required method.

Usage
GceToken$revoke()

Method validate()

Placeholder implementation of required method

Usage
GceToken$validate()

Method clone()

The objects of this class are cloneable with this method.

Usage
GceToken$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.


Token for use with workload identity federation

Description

Token for use with workload identity federation

Token for use with workload identity federation

Details

Not intended for direct use. See credentials_external_account() instead.

Super classes

httr::Token -> httr::Token2.0 -> WifToken

Methods

Public methods

Inherited methods

Method new()

Get a token via workload identity federation

Usage
WifToken$new(params = list())
Arguments
params

A list of parameters for init_oauth_external_account().

Returns

A WifToken.


Method init_credentials()

Enact the actual token exchange for workload identity federation.

Usage
WifToken$init_credentials()

Method refresh()

Refreshes the token, which means re-doing the entire token flow in this case.

Usage
WifToken$refresh()

Method format()

Format a WifToken().

Usage
WifToken$format(...)
Arguments
...

Not used.


Method print()

Print a WifToken().

Usage
WifToken$print(...)
Arguments
...

Not used.


Method can_refresh()

Placeholder implementation of required method. Returns TRUE.

Usage
WifToken$can_refresh()

Method cache()

Placeholder implementation of required method. Returns self.

Usage
WifToken$cache()

Method load_from_cache()

Placeholder implementation of required method. Returns self.

Usage
WifToken$load_from_cache()

Method validate()

Placeholder implementation of required method.

Usage
WifToken$validate()

Method revoke()

Placeholder implementation of required method.

Usage
WifToken$revoke()

Method clone()

The objects of this class are cloneable with this method.

Usage
WifToken$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.


Abbreviate a bullet list neatly

Description

For internal use in gargle, googledrive, and googlesheets4 (for now).

Usage

bulletize(x, bullet = "*", n_show = 5, n_fudge = 2)

Check for a service account

Description

This pre-checks information provided to a high-level, user-facing auth function, such as googledrive::drive_auth(), before passing the user's input along to token_fetch(), which is designed to silently swallow errors. Some users are confused about the difference between an OAuth client and a service account and they provide the (path to the) JSON for one, when the other is what's actually expected.

Usage

check_is_service_account(path, hint, call = caller_env())

Arguments

path

JSON identifying the service account, in one of the forms supported for the txt argument of jsonlite::fromJSON() (typically, a file path or JSON string).

hint

The relevant function to call for configuring an OAuth client.

call

The execution environment of a currently running function, e.g. call = caller_env(). The corresponding function call is retrieved and mentioned in error messages as the source of the error.

You only need to supply call when throwing a condition from a helper function which wouldn't be relevant to mention in the message.

Can also be NULL or a defused function call to respectively not display any call or hard-code a code to display.

For more information about error calls, see Including function calls in error messages.

Value

Nothing. Exists purely to throw an error.


Credential function registry

Description

Functions to query or manipulate the registry of credential functions consulted by token_fetch().

Usage

cred_funs_list()

cred_funs_add(...)

cred_funs_set(funs, ls = deprecated())

cred_funs_clear()

cred_funs_list_default()

cred_funs_set_default()

local_cred_funs(
  funs = cred_funs_list_default(),
  action = c("replace", "modify"),
  .local_envir = caller_env()
)

with_cred_funs(
  funs = cred_funs_list_default(),
  code,
  action = c("replace", "modify")
)

Arguments

...

<dynamic-dots> One or more credential functions, in name = value form. Each credential function is subject to a superficial check that it at least "smells like" a credential function: its first argument must be named scopes, and its signature must include .... To remove a credential function, you can use a specification like name = NULL.

funs

A named list of credential functions.

ls

[Deprecated] This argument has been renamed to funs.

action

Whether to use funs to replace or modify the registry with funs:

  • "replace" does cred_funs_set(funs)

  • "modify" does cred_funs_add(!!!funs)

.local_envir

The environment to use for scoping. Defaults to current execution environment.

code

Code to run with temporary credential function registry.

Value

A list of credential functions or NULL.

Functions

See Also

token_fetch(), which is where the registry is actually used.

Examples

names(cred_funs_list())

creds_one <- function(scopes, ...) {}

cred_funs_add(one = creds_one)
cred_funs_add(two = creds_one, three = creds_one)
names(cred_funs_list())

cred_funs_add(two = NULL)
names(cred_funs_list())

# restore the default list
cred_funs_set_default()

# remove one specific credential fetcher
cred_funs_add(credentials_gce = NULL)
names(cred_funs_list())

# force the use of one specific credential fetcher
cred_funs_set(list(credentials_user_oauth2 = credentials_user_oauth2))
names(cred_funs_list())

# restore the default list
cred_funs_set_default()

# run some code with a temporary change to the registry
# creds_one ONLY
with_cred_funs(
  list(one = creds_one),
  names(cred_funs_list())
)
# add creds_one to the list
with_cred_funs(
  list(one = creds_one),
  names(cred_funs_list()),
  action = "modify"
)
# remove credentials_gce
with_cred_funs(
  list(credentials_gce = NULL),
  names(cred_funs_list()),
  action = "modify"
)

Load Application Default Credentials

Description

Loads credentials from a file identified via a search strategy known as Application Default Credentials (ADC). The hope is to make auth "just work" for someone working on Google-provided infrastructure or who has used Google tooling to get started, such as the gcloud command line tool.

A sequence of paths is consulted, which we describe here, with some abuse of notation. ALL_CAPS represents the value of an environment variable and ⁠%||%⁠ is used in the spirit of a null coalescing operator.

GOOGLE_APPLICATION_CREDENTIALS
CLOUDSDK_CONFIG/application_default_credentials.json
# on Windows:
(APPDATA %||% SystemDrive %||% C:)\gcloud\application_default_credentials.json
# on not-Windows:
~/.config/gcloud/application_default_credentials.json

If the above search successfully identifies a JSON file, it is parsed and ingested as a service account, an external account ("workload identity federation"), or a user account. Literally, if the JSON describes a service account, we call credentials_service_account() and if it describes an external account, we call credentials_external_account().

Usage

credentials_app_default(scopes = NULL, ..., subject = NULL)

Arguments

scopes

A character vector of scopes to request. Pick from those listed at https://developers.google.com/identity/protocols/oauth2/scopes.

For certain token flows, the "https://www.googleapis.com/auth/userinfo.email" scope is unconditionally included. This grants permission to retrieve the email address associated with a token; gargle uses this to index cached OAuth tokens. This grants no permission to view or send email and is generally considered a low-value scope.

...

Additional arguments passed to all credential functions.

subject

An optional subject claim. Specify this if you wish to use the service account represented by path to impersonate the subject, who is a normal user. Before this can work, an administrator must grant the service account domain-wide authority. Identify the user to impersonate via their email, e.g. subject = "user@example.com". Note that gargle automatically adds the non-sensitive "https://www.googleapis.com/auth/userinfo.email" scope, so this scope must be enabled for the service account, along with any other scopes being requested.

Value

An httr::TokenServiceAccount, a WifToken, an httr::Token2.0 or NULL.

See Also

Other credential functions: credentials_byo_oauth2(), credentials_external_account(), credentials_gce(), credentials_service_account(), credentials_user_oauth2(), token_fetch()

Examples

## Not run: 
credentials_app_default()

## End(Not run)

Load a user-provided token

Description

This function is designed to pass its token input through, after doing a few checks and some light processing:

There is no point in providing scopes. They are ignored because the scopes associated with the token have already been baked in to the token itself and gargle does not support incremental authorization. The main point of credentials_byo_oauth2() is to allow token_fetch() (and packages that wrap it) to accommodate a "bring your own token" workflow.

This also makes it possible to obtain a token with one package and then register it for use with another package. For example, the default scope requested by googledrive is also sufficient for operations available in googlesheets4. You could use a shared token like so:

library(googledrive)
library(googlesheets4)
drive_auth(email = "jane_doe@example.com")
gs4_auth(token = drive_token())
# work with both packages freely now, with the same identity

Usage

credentials_byo_oauth2(scopes = NULL, token, ...)

Arguments

scopes

A character vector of scopes to request. Pick from those listed at https://developers.google.com/identity/protocols/oauth2/scopes.

For certain token flows, the "https://www.googleapis.com/auth/userinfo.email" scope is unconditionally included. This grants permission to retrieve the email address associated with a token; gargle uses this to index cached OAuth tokens. This grants no permission to view or send email and is generally considered a low-value scope.

token

A token with class Token2.0 or an object of httr's class request, i.e. a token that has been prepared with httr::config() and has a Token2.0 in the auth_token component.

...

Additional arguments passed to all credential functions.

Value

An Token2.0.

See Also

Other credential functions: credentials_app_default(), credentials_external_account(), credentials_gce(), credentials_service_account(), credentials_user_oauth2(), token_fetch()

Examples

## Not run: 
# assume `my_token` is a Token2.0 object returned by a function such as
# credentials_user_oauth2()
credentials_byo_oauth2(token = my_token)

## End(Not run)

Get a token for an external account

Description

[Experimental] Workload identity federation is a new (as of April 2021) keyless authentication mechanism that allows applications running on a non-Google Cloud platform, such as AWS, to access Google Cloud resources without using a conventional service account token. This eliminates the dilemma of how to safely manage service account credential files.

Unlike service accounts, the configuration file for workload identity federation contains no secrets. Instead, it holds non-sensitive metadata. The external application obtains the needed sensitive data "on-the-fly" from the running instance. The combined data is then used to obtain a so-called subject token from the external identity provider, such as AWS. This is then sent to Google's Security Token Service API, in exchange for a very short-lived federated access token. Finally, the federated access token is sent to Google's Service Account Credentials API, in exchange for a short-lived GCP access token. This access token allows the external application to impersonate a service account and inherit the permissions of the service account to access GCP resources.

This feature is still experimental in gargle and currently only supports AWS. It also requires installation of the suggested packages aws.signature and aws.ec2metadata. Workload identity federation can be used with other platforms, such as Microsoft Azure or any identity provider that supports OpenID Connect. If you would like gargle to support this token flow for additional platforms, please open an issue on GitHub and describe your use case.

Usage

credentials_external_account(
  scopes = "https://www.googleapis.com/auth/cloud-platform",
  path = "",
  ...
)

Arguments

scopes

A character vector of scopes to request. Pick from those listed at https://developers.google.com/identity/protocols/oauth2/scopes.

For certain token flows, the "https://www.googleapis.com/auth/userinfo.email" scope is unconditionally included. This grants permission to retrieve the email address associated with a token; gargle uses this to index cached OAuth tokens. This grants no permission to view or send email and is generally considered a low-value scope.

path

JSON containing the workload identity configuration for the external account, in one of the forms supported for the txt argument of jsonlite::fromJSON() (probably, a file path, although it could be a JSON string). The instructions for generating this configuration are given at Configuring workload identity federation.

Note that external account tokens are a natural fit for use as Application Default Credentials, so consider storing the configuration file in one of the standard locations consulted for ADC, instead of providing path explicitly. See credentials_app_default() for more.

...

Additional arguments passed to all credential functions.

Value

A WifToken() or NULL.

See Also

There is substantial setup necessary, both on the GCP and AWS side, to use this authentication method. These two links provide, respectively, a high-level overview and step-by-step instructions.

Other credential functions: credentials_app_default(), credentials_byo_oauth2(), credentials_gce(), credentials_service_account(), credentials_user_oauth2(), token_fetch()

Examples

## Not run: 
credentials_external_account()

## End(Not run)

Get a token from the Google metadata server

Description

If your code is running on Google Cloud, we can often obtain a token for an attached service account directly from a metadata server. This is more secure than working with an explicit a service account key, as credentials_service_account() does, and is the preferred method of auth for workloads running on Google Cloud.

The most straightforward scenario is when you are working in a VM on Google Compute Engine and it's OK to use the default service account. This should "just work" automatically.

credentials_gce() supports other use cases (such as GKE Workload Identity), but may require some explicit setup, such as:

options(gargle.gce.timeout = 3)

For details on specific use cases, such as Google Kubernetes Engine (GKE), see vignette("non-interactive-auth").

Usage

credentials_gce(
  scopes = "https://www.googleapis.com/auth/cloud-platform",
  service_account = "default",
  ...
)

Arguments

scopes

A character vector of scopes to request. Pick from those listed at https://developers.google.com/identity/protocols/oauth2/scopes.

For certain token flows, the "https://www.googleapis.com/auth/userinfo.email" scope is unconditionally included. This grants permission to retrieve the email address associated with a token; gargle uses this to index cached OAuth tokens. This grants no permission to view or send email and is generally considered a low-value scope.

service_account

Name of the GCE service account to use.

...

Additional arguments passed to all credential functions.

Value

A GceToken() or NULL.

See Also

A related auth flow that can be used on certain non-Google cloud providers is workload identity federation, which is implemented in credentials_external_account().

https://cloud.google.com/compute/docs/access/service-accounts

https://cloud.google.com/iam/docs/best-practices-service-accounts

How to attach a service account to a resource: https://cloud.google.com/iam/docs/impersonating-service-accounts#attaching-to-resources

https://cloud.google.com/kubernetes-engine/docs/concepts/workload-identity

https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity

https://cloud.google.com/compute/docs/metadata/overview

Other credential functions: credentials_app_default(), credentials_byo_oauth2(), credentials_external_account(), credentials_service_account(), credentials_user_oauth2(), token_fetch()

Examples

## Not run: 
credentials_gce()

## End(Not run)

Load a service account token

Description

Load a service account token

Usage

credentials_service_account(scopes = NULL, path = "", ..., subject = NULL)

Arguments

scopes

A character vector of scopes to request. Pick from those listed at https://developers.google.com/identity/protocols/oauth2/scopes.

For certain token flows, the "https://www.googleapis.com/auth/userinfo.email" scope is unconditionally included. This grants permission to retrieve the email address associated with a token; gargle uses this to index cached OAuth tokens. This grants no permission to view or send email and is generally considered a low-value scope.

path

JSON identifying the service account, in one of the forms supported for the txt argument of jsonlite::fromJSON() (typically, a file path or JSON string).

...

Additional arguments passed to all credential functions.

subject

An optional subject claim. Specify this if you wish to use the service account represented by path to impersonate the subject, who is a normal user. Before this can work, an administrator must grant the service account domain-wide authority. Identify the user to impersonate via their email, e.g. subject = "user@example.com". Note that gargle automatically adds the non-sensitive "https://www.googleapis.com/auth/userinfo.email" scope, so this scope must be enabled for the service account, along with any other scopes being requested.

Details

Note that fetching a token for a service account requires a reasonably accurate system clock. For more information, see the vignette("how-gargle-gets-tokens").

Value

An httr::TokenServiceAccount or NULL.

See Also

Additional reading on delegation of domain-wide authority:

Other credential functions: credentials_app_default(), credentials_byo_oauth2(), credentials_external_account(), credentials_gce(), credentials_user_oauth2(), token_fetch()

Examples

## Not run: 
token <- credentials_service_account(
  scopes = "https://www.googleapis.com/auth/userinfo.email",
  path = "/path/to/your/service-account.json"
)

## End(Not run)

Get an OAuth token for a user

Description

Consults the token cache for a suitable OAuth token and, if unsuccessful, gets a token via the browser flow. A cached token is suitable if it's compatible with the user's request in this sense:

gargle is very conservative about using OAuth tokens discovered in the user's cache and will generally seek interactive confirmation. Therefore, in a non-interactive setting, it's important to explicitly specify the "email" of the target account or to explicitly authorize automatic discovery. See gargle2.0_token(), which this function wraps, for more. Non-interactive use also suggests it might be time to use a service account token or workload identity federation.

Usage

credentials_user_oauth2(
  scopes = NULL,
  client = gargle_client(),
  package = "gargle",
  ...,
  app = deprecated()
)

Arguments

scopes

A character vector of scopes to request. Pick from those listed at https://developers.google.com/identity/protocols/oauth2/scopes.

For certain token flows, the "https://www.googleapis.com/auth/userinfo.email" scope is unconditionally included. This grants permission to retrieve the email address associated with a token; gargle uses this to index cached OAuth tokens. This grants no permission to view or send email and is generally considered a low-value scope.

client

A Google OAuth client, preferably constructed via gargle_oauth_client_from_json(), which returns an instance of gargle_oauth_client. For backwards compatibility, for a limited time, gargle will still accept an "OAuth app" created with httr::oauth_app().

package

Name of the package requesting a token. Used in messages.

...

Arguments passed on to gargle2.0_token

email

Optional. If specified, email can take several different forms:

  • "jane@gmail.com", i.e. an actual email address. This allows the user to target a specific Google identity. If specified, this is used for token lookup, i.e. to determine if a suitable token is already available in the cache. If no such token is found, email is used to pre-select the targeted Google identity in the OAuth chooser. (Note, however, that the email associated with a token when it's cached is always determined from the token itself, never from this argument).

  • "*@example.com", i.e. a domain-only glob pattern. This can be helpful if you need code that "just works" for both alice@example.com and bob@example.com.

  • TRUE means that you are approving email auto-discovery. If exactly one matching token is found in the cache, it will be used.

  • FALSE or NA mean that you want to ignore the token cache and force a new OAuth dance in the browser.

Defaults to the option named "gargle_oauth_email", retrieved by gargle_oauth_email() (unless a wrapper package implements different default behavior).

use_oob

Whether to use out-of-band authentication (or, perhaps, a variant implemented by gargle and known as "pseudo-OOB") when first acquiring the token. Defaults to the value returned by gargle_oob_default(). Note that (pseudo-)OOB auth only affects the initial OAuth dance. If we retrieve (and possibly refresh) a cached token, use_oob has no effect.

If the OAuth client is provided implicitly by a wrapper package, its type probably defaults to the value returned by gargle_oauth_client_type(). You can take control of the client type by setting options(gargle_oauth_client_type = "web") or options(gargle_oauth_client_type = "installed").

cache

Specifies the OAuth token cache. Defaults to the option named "gargle_oauth_cache", retrieved via gargle_oauth_cache().

credentials

Advanced use only: allows you to completely customise token generation.

app

[Deprecated] Replaced by the client argument.

Value

A Gargle2.0 token.

See Also

Other credential functions: credentials_app_default(), credentials_byo_oauth2(), credentials_external_account(), credentials_gce(), credentials_service_account(), token_fetch()

Examples

## Not run: 
# Drive scope, built-in gargle demo client
scopes <- "https://www.googleapis.com/auth/drive"
credentials_user_oauth2(scopes, client = gargle_client())

# bring your own client
client <- gargle_oauth_client_from_json(
  path = "/path/to/the/JSON/you/downloaded/from/gcp/console.json",
  name = "my-nifty-oauth-client"
)
credentials_user_oauth2(scopes, client)

## End(Not run)

Generate a field mask

Description

Many Google API requests take a field mask, via a fields parameter, in the URL and/or in the body. field_mask() generates such a field mask from an R list, typically a list that is destined to be part of the body of a request that writes or updates a resource. field_mask() is designed to help in the common case where the attributes you wish to modify are exactly the ones represented in the object. It is possible to use a "larger" field mask, that is either less specific or that explicitly includes other attributes, in which case the attributes covered by the mask but absent from the object are reset to default values. This is not exactly the use case field_mask() is designed for, but its output could still be useful as a first step in constructing such a mask.

Usage

field_mask(x)

Arguments

x

A named R list, where the requirement for names applies at all levels, i.e. recursively.

Value

A Google API field mask, as a string.

See Also

The documentation for the JSON encoding of a Protocol Buffers FieldMask.

Examples

x <- list(sheetId = 1234, title = "my_favorite_worksheet")
field_mask(x)

x <- list(
  userEnteredFormat = list(
    backgroundColor = list(
      red = 159 / 255, green = 183 / 255, blue = 196 / 255
    )
  )
)
field_mask(x)

x <- list(
  sheetId = 1234,
  gridProperties = list(rowCount = 5, columnCount = 3)
)
field_mask(x)

Generate a gargle token

Description

Constructor function for objects of class Gargle2.0.

Usage

gargle2.0_token(
  email = gargle_oauth_email(),
  client = gargle_client(),
  package = "gargle",
  scope = NULL,
  use_oob = gargle_oob_default(),
  credentials = NULL,
  cache = if (is.null(credentials)) gargle_oauth_cache() else FALSE,
  ...,
  app = deprecated()
)

Arguments

email

Optional. If specified, email can take several different forms:

  • "jane@gmail.com", i.e. an actual email address. This allows the user to target a specific Google identity. If specified, this is used for token lookup, i.e. to determine if a suitable token is already available in the cache. If no such token is found, email is used to pre-select the targeted Google identity in the OAuth chooser. (Note, however, that the email associated with a token when it's cached is always determined from the token itself, never from this argument).

  • "*@example.com", i.e. a domain-only glob pattern. This can be helpful if you need code that "just works" for both alice@example.com and bob@example.com.

  • TRUE means that you are approving email auto-discovery. If exactly one matching token is found in the cache, it will be used.

  • FALSE or NA mean that you want to ignore the token cache and force a new OAuth dance in the browser.

Defaults to the option named "gargle_oauth_email", retrieved by gargle_oauth_email() (unless a wrapper package implements different default behavior).

client

A Google OAuth client, preferably constructed via gargle_oauth_client_from_json(), which returns an instance of gargle_oauth_client. For backwards compatibility, for a limited time, gargle will still accept an "OAuth app" created with httr::oauth_app().

package

Name of the package requesting a token. Used in messages.

scope

A character vector of scopes to request.

use_oob

Whether to use out-of-band authentication (or, perhaps, a variant implemented by gargle and known as "pseudo-OOB") when first acquiring the token. Defaults to the value returned by gargle_oob_default(). Note that (pseudo-)OOB auth only affects the initial OAuth dance. If we retrieve (and possibly refresh) a cached token, use_oob has no effect.

If the OAuth client is provided implicitly by a wrapper package, its type probably defaults to the value returned by gargle_oauth_client_type(). You can take control of the client type by setting options(gargle_oauth_client_type = "web") or options(gargle_oauth_client_type = "installed").

credentials

Advanced use only: allows you to completely customise token generation.

cache

Specifies the OAuth token cache. Defaults to the option named "gargle_oauth_cache", retrieved via gargle_oauth_cache().

...

Absorbs arguments intended for use by other credential functions. Not used.

app

[Deprecated] Replaced by the client argument.

Value

An object of class Gargle2.0, either new or loaded from the cache.

Examples

## Not run: 
gargle2.0_token()

## End(Not run)

API key for demonstration purposes

Description

Some APIs accept requests for public resources, in which case the request must be sent with an API key in lieu of a token. This function provides an API key for limited use in prototyping and for testing and documentation of gargle itself. This key may be deleted or rotated at any time. There are no guarantees about which APIs are enabled. DO NOT USE THIS IN A PACKAGE or for anything other than interactive, small-scale experimentation.

You can get your own API key, without these limitations. See the How to get your own API credentials vignette for more details.

Usage

gargle_api_key()

Examples

gargle_api_key()

OAuth client for demonstration purposes

Description

Invisibly returns an instance of gargle_oauth_client that can be used to test drive gargle before obtaining your own client ID and secret. This OAuth client may be deleted or rotated at any time. There are no guarantees about which APIs are enabled. DO NOT USE THIS IN A PACKAGE or for anything other than interactive, small-scale experimentation.

You can get your own OAuth client ID and secret, without these limitations. See the vignette("get-api-credentials") for more details.

Usage

gargle_client(type = NULL)

Arguments

type

Specifies the type of OAuth client. The valid values are a subset of possible Google client types and reflect the key used to describe the client in its JSON representation:

  • "installed" is associated with a "Desktop app"

  • "web" is associated with a "Web application"

Value

An OAuth client, produced by gargle_oauth_client(), invisibly.

Examples

## Not run: 
gargle_client()

## End(Not run)

Map a cli-styled template over an object

Description

For internal use in gargle, googledrive, and googlesheets4 (for now).

Usage

gargle_map_cli(x, ...)

Create an OAuth client for Google

Description

A gargle_oauth_client consists of:

A gargle_oauth_client is an adaptation of httr's oauth_app() (currently) and httr2's oauth_client() (which gargle will migrate to in the future).

Usage

gargle_oauth_client_from_json(path, name = NULL)

gargle_oauth_client(
  id,
  secret,
  redirect_uris = NULL,
  type = c("installed", "web"),
  name = hash(id)
)

Arguments

path

JSON downloaded from Google Cloud Console, containing a client id and secret, in one of the forms supported for the txt argument of jsonlite::fromJSON() (typically, a file path or JSON string).

name

A label for this specific client, presumably the same name used to label it in Google Cloud Console. Unfortunately there is no way to make that true programmatically, i.e. the JSON representation does not contain this information.

id

Client ID

secret

Client secret

redirect_uris

Where your application listens for the response from Google's authorization server. If you didn't configure this specifically when creating the client (which is only possible for clients of the "web" type), you can leave this unspecified.

type

Specifies the type of OAuth client. The valid values are a subset of possible Google client types and reflect the key used to describe the client in its JSON representation:

  • "installed" is associated with a "Desktop app"

  • "web" is associated with a "Web application"

Value

An OAuth client: An S3 list with class gargle_oauth_client. For backwards compatibility reasons, this currently also inherits from the httr S3 class oauth_app, but that is a temporary measure. An instance of gargle_oauth_client stores more information than httr's oauth_app, such as the OAuth client's type ("web" or "installed").

There are some redundant fields in this object during the httr-to-httr2 transition period. The legacy fields appname and key repeat the information in the future-facing fields name and (client) id. Prefer name and id to appname and key in downstream code. Prefer the constructors gargle_oauth_client_from_json() and gargle_oauth_client() to httr::oauth_app() and oauth_app_from_json().

Examples

## Not run: 
gargle_oauth_client_from_json(
  path = "/path/to/the/JSON/you/downloaded/from/gcp/console.json",
  name = "my-nifty-oauth-client"
)

## End(Not run)

gargle_oauth_client(
  id = "some_long_id",
  secret = "ssshhhhh_its_a_secret",
  name = "my-nifty-oauth-client"
)

OAuth token situation report

Description

Get a human-oriented overview of the existing gargle OAuth tokens:

Usage

gargle_oauth_sitrep(cache = NULL)

Arguments

cache

Specifies the OAuth token cache. Defaults to the option named "gargle_oauth_cache", retrieved via gargle_oauth_cache().

Value

A data frame with one row per cached token, invisibly. Note this data frame may contain more columns than it seems, e.g. the filepath column isn't printed by default.

Examples

gargle_oauth_sitrep()

Options consulted by gargle

Description

Wrapper functions around options consulted by gargle, which provide:

If the built-in defaults don't suit you, set one or more of these options. Typically, this is done in the .Rprofile startup file, with code along these lines:

options(
  gargle_oauth_email = "jane@example.com",
  gargle_oauth_cache = "/path/to/folder/that/does/not/sync/to/cloud"
)

Usage

gargle_oauth_email()

gargle_oob_default()

gargle_oauth_cache()

gargle_oauth_client_type()

gargle_verbosity()

local_gargle_verbosity(level, env = caller_env())

with_gargle_verbosity(level, code)

Arguments

level

Verbosity level: "debug" > "info" > "silent"

env

The environment to use for scoping

code

Code to execute with specified verbosity level

gargle_oauth_email

gargle_oauth_email() returns the option named "gargle_oauth_email", which is undefined by default. If set, this option should be one of:

gargle_oob_default

gargle_oob_default() returns TRUE unconditionally on RStudio Server, Posit Workbench, Posit Cloud, or Google Colaboratory, since it is not possible to launch a local web server in these contexts. In this case, for the final step of the OAuth dance, the user is redirected to a specific URL where they must copy a code and paste it back into the R session.

In all other contexts, gargle_oob_default() consults the option named "gargle_oob_default", then the option named "httr_oob_default", and eventually defaults to FALSE.

"oob" stands for out-of-band. Read more about out-of-band authentication in the vignette vignette("auth-from-web").

gargle_oauth_cache

gargle_oauth_cache() returns the option named "gargle_oauth_cache", defaulting to NA. If defined, the option must be set to a logical value or a string. TRUE means to cache using the default user-level cache file, ⁠~/.R/gargle/gargle-oauth⁠, FALSE means don't cache, and NA means to guess using some sensible heuristics.

gargle_oauth_client_type

gargle_oauth_client_type() returns the option named "gargle_oauth_client_type", if defined. If defined, the option must be either "installed" or "web". If the option is not defined, the function returns:

Primarily intended to help infer the most suitable OAuth client type when a user is relying on a built-in client, such as the tidyverse client used by packages like bigrquery, googledrive, and googlesheets4.

gargle_verbosity

gargle_verbosity() returns the option named "gargle_verbosity", which determines gargle's verbosity. There are three possible values, inspired by the logging levels of log4j:

Examples

gargle_oauth_email()
gargle_oob_default()
gargle_oauth_cache()
gargle_oauth_client_type()
gargle_verbosity()

Encrypt/decrypt JSON or an R object

Description

These functions help to encrypt and decrypt confidential information that you might need when deploying gargle-using projects or in CI/CD. They basically rely on inlined copies of the secret functions in the httr2 package. The awkwardness of inlining code from httr2 can be removed if/when gargle starts to depend on httr2.

Usage

secret_encrypt_json(json, path = NULL, key)

secret_decrypt_json(path, key)

secret_make_key()

secret_write_rds(x, path, key)

secret_read_rds(path, key)

secret_has_key(key)

Arguments

json

A JSON file (or string).

path

The path to write to (secret_encrypt_json(), secret_write_rds()) or to read from (secret_decrypt_json(), secret_read_rds()).

key

Encryption key, as implemented by httr2's secret functions. This should almost always be the name of an environment variable whose value was generated with secret_make_key() (which is an inlined copy of httr2::secret_make_key()).

x

An R object.

Value

Examples


# gargle ships with JSON for a fake service account
# here we put the encrypted JSON into a new file
tmp <- tempfile()
secret_encrypt_json(
  fs::path_package("gargle", "extdata", "fake_service_account.json"),
  tmp,
  key = "GARGLE_KEY"
)

# complete the round trip by providing the decrypted JSON to a credential
# function
credentials_service_account(
 scopes = "https://www.googleapis.com/auth/userinfo.email",
 path = secret_decrypt_json(
   fs::path_package("gargle", "secret", "gargle-testing.json"),
   key = "GARGLE_KEY"
 )
)

file.remove(tmp)

# make an artificial Gargle2.0 token
fauxen <- gargle2.0_token(
  email = "jane@example.org",
  client = gargle_oauth_client(
    id = "CLIENT_ID", secret = "SECRET", name = "CLIENT"
  ),
  credentials = list(token = "fauxen"),
  cache = FALSE
)
fauxen

# store the fake token in an encrypted file
tmp2 <- tempfile()
secret_write_rds(fauxen, path = tmp2, key = "GARGLE_KEY")

# complete the round trip by providing the decrypted token to the "BYO token"
# credential function
rt_fauxen <- credentials_byo_oauth2(
  token  = secret_read_rds(tmp2, key = "GARGLE_KEY")
)
rt_fauxen

file.remove(tmp2)


Fetch access token for a service account on GCE

Description

Fetch access token for a service account on GCE

Usage

gce_access_token(
  scopes = "https://www.googleapis.com/auth/cloud-platform",
  service_account = "default"
)

Arguments

scopes

A character vector of scopes to request. Pick from those listed at https://developers.google.com/identity/protocols/oauth2/scopes.

For certain token flows, the "https://www.googleapis.com/auth/userinfo.email" scope is unconditionally included. This grants permission to retrieve the email address associated with a token; gargle uses this to index cached OAuth tokens. This grants no permission to view or send email and is generally considered a low-value scope.

service_account

Name of the GCE service account to use.


List all service accounts available on this GCE instance

Description

List all service accounts available on this GCE instance

Usage

gce_instance_service_accounts()

Value

A data frame, where each row is a service account. Due to aliasing, there is no guarantee that each row represents a distinct service account.

See Also

The return value is built from a recursive query of the so-called "directory" of the instance's service accounts as documented in https://cloud.google.com/compute/docs/metadata/default-metadata-values#vm_instance_metadata.

Examples


credentials_gce()


Create an AuthState

Description

Constructor function for objects of class AuthState.

Usage

init_AuthState(
  package = NA_character_,
  client = NULL,
  api_key = NULL,
  auth_active = TRUE,
  cred = NULL,
  app = deprecated()
)

Arguments

package

Package name, an optional string. It is recommended to record the name of the package whose auth state is being managed. Ultimately, this may be used in some downstream messaging.

client

A Google OAuth client, preferably constructed via gargle_oauth_client_from_json(), which returns an instance of gargle_oauth_client. For backwards compatibility, for a limited time, gargle will still accept an "OAuth app" created with httr::oauth_app().

api_key

Optional. API key (a string). Some APIs accept unauthorized, "token-free" requests for public resources, but only if the request includes an API key.

auth_active

Logical. TRUE means requests should include a token (and probably not an API key). FALSE means requests should include an API key (and probably not a token).

cred

Credentials. Typically populated indirectly via token_fetch().

app

[Deprecated] Replaced by the client argument.

Value

An object of class AuthState.

Examples

my_client <- gargle_oauth_client(
  id = "some_long_client_id",
  secret = "ssshhhhh_its_a_secret",
  name = "my-nifty-oauth-client"
)

init_AuthState(
  package = "my_package",
  client = my_client,
  api_key = "api_key_api_key_api_key",
)

Assets for internal use

Description

Assets for use inside specific packages maintained by the tidyverse team.

Usage

tidyverse_api_key()

tidyverse_client(type = NULL)

tidyverse_app()

Create an OAuth app from JSON

Description

[Deprecated]

oauth_app_from_json() is being replaced with gargle_oauth_client_from_json(), in light of the new gargle_oauth_client class. Now oauth_app_from_json() potentially warns about this deprecation and immediately passes its inputs through to gargle_oauth_client_from_json().

gargle_app() is being replaced with gargle_client().

Usage

oauth_app_from_json(path, appname = NULL)

gargle_app()

Arguments

path

JSON downloaded from Google Cloud Console, containing a client id and secret, in one of the forms supported for the txt argument of jsonlite::fromJSON() (typically, a file path or JSON string).

appname

name of the application. This is not used for OAuth, but is used to make it easier to identify different applications.


Generate OAuth token for an external account

Description

Generate OAuth token for an external account

Usage

oauth_external_token(
  path = "",
  scopes = "https://www.googleapis.com/auth/cloud-platform"
)

Arguments

path

JSON containing the workload identity configuration for the external account, in one of the forms supported for the txt argument of jsonlite::fromJSON() (probably, a file path, although it could be a JSON string). The instructions for generating this configuration are given at Configuring workload identity federation.

Note that external account tokens are a natural fit for use as Application Default Credentials, so consider storing the configuration file in one of the standard locations consulted for ADC, instead of providing path explicitly. See credentials_app_default() for more.

scopes

A character vector of scopes to request. Pick from those listed at https://developers.google.com/identity/protocols/oauth2/scopes.

For certain token flows, the "https://www.googleapis.com/auth/userinfo.email" scope is unconditionally included. This grants permission to retrieve the email address associated with a token; gargle uses this to index cached OAuth tokens. This grants no permission to view or send email and is generally considered a low-value scope.


Build a Google API request

Description

Intended primarily for internal use in client packages that provide high-level wrappers for users. The vignette("request-helper-functions") describes how one might use these functions inside a wrapper package.

Usage

request_develop(
  endpoint,
  params = list(),
  base_url = "https://www.googleapis.com"
)

request_build(
  method = "GET",
  path = "",
  params = list(),
  body = list(),
  token = NULL,
  key = NULL,
  base_url = "https://www.googleapis.com"
)

Arguments

endpoint

List of information about the target endpoint or, in Google's vocabulary, the target "method". Presumably prepared from the Discovery Document for the target API.

params

Named list. Values destined for URL substitution, the query, or, for request_develop() only, the body. For request_build(), body parameters must be passed via the body argument.

base_url

Character.

method

Character. An HTTP verb, such as GET or POST.

path

Character. Path to the resource, not including the API's base_url. Examples: drive/v3/about or drive/v3/files/{fileId}. The path can be a template, i.e. it can include variables inside curly brackets, such as {fileId} in the example. Such variables are substituted by request_build(), using named parameters found in params.

body

List. Values to send in the API request body.

token

Token, ready for inclusion in a request, i.e. prepared with httr::config().

key

API key. Needed for requests that don't contain a token. For more, see Google's document Credentials, access, security, and identity (⁠https://support.google.com/googleapi/answer/6158857?hl=en&ref_topic=7013279⁠). A key can be passed as a named component of params, but note that the formal argument key will clobber it, if non-NULL.

Value

request_develop(): list() with components method, path, params, body, and base_url.

request_build(): list() with components method, path (post-substitution), query (the input params not used in URL substitution), body, token, url (the full URL, post-substitution, including the query).

request_develop()

Combines user input (params) with information about an API endpoint. endpoint should contain these components:

The return value is typically used as input to request_build().

request_build()

Builds a request, in a purely mechanical sense. This function does nothing specific to any particular Google API or endpoint.

See googledrive::generate_request() for an example of usage in a client package. googledrive has an internal list of selected endpoints, derived from the Drive API Discovery Document (⁠https://www.googleapis.com/discovery/v1/apis/drive/v3/rest⁠), exposed via googledrive::drive_endpoints(). An element from such a list is the expected input for endpoint. googledrive::generate_request() is a wrapper around request_develop() and request_build() that inserts a googledrive-managed API key and some logic about Team Drives. All user-facing functions use googledrive::generate_request() under the hood.

See Also

Other requests and responses: request_make(), response_process()

Examples

## Not run: 
## Example with a prepared endpoint
ept <- googledrive::drive_endpoints("drive.files.update")[[1]]
req <- request_develop(
  ept,
  params = list(
    fileId = "abc",
    addParents = "123",
    description = "Exciting File"
  )
)
req

req <- request_build(
  method = req$method,
  path = req$path,
  params = req$params,
  body = req$body,
  token = "PRETEND_I_AM_A_TOKEN"
)
req

## Example with no previous knowledge of the endpoint
## List a file's comments
## https://developers.google.com/drive/v3/reference/comments/list
req <- request_build(
  method = "GET",
  path = "drive/v3/files/{fileId}/comments",
  params = list(
    fileId = "your-file-id-goes-here",
    fields = "*"
  ),
  token = "PRETEND_I_AM_A_TOKEN"
)
req

# Example with no previous knowledge of the endpoint and no token
# use an API key for which the Places API is enabled!
API_KEY <- "1234567890"

# get restaurants close to a location in Vancouver, BC
req <- request_build(
  method = "GET",
  path = "maps/api/place/nearbysearch/json",
  params = list(
    location = "49.268682,-123.167117",
    radius = 100,
    type = "restaurant"
  ),
  key = API_KEY,
  base_url = "https://maps.googleapis.com"
)
resp <- request_make(req)
out <- response_process(resp)
vapply(out$results, function(x) x$name, character(1))

## End(Not run)

Make a Google API request

Description

Intended primarily for internal use in client packages that provide high-level wrappers for users. request_make() does relatively little:

Typically the input is created with request_build() and the output is processed with response_process().

Usage

request_make(x, ..., encode = "json", user_agent = gargle_user_agent())

Arguments

x

List. Holds the components for an HTTP request, presumably created with request_develop() or request_build(). Must contain a method and url. If present, body and token are used.

...

Optional arguments passed through to the HTTP method. Currently neither gargle nor httr checks that all are used, so be aware that unused arguments may be silently ignored.

encode

If the body is a named list, how should it be encoded? Can be one of form (application/x-www-form-urlencoded), multipart, (multipart/form-data), or json (application/json).

For "multipart", list elements can be strings or objects created by upload_file(). For "form", elements are coerced to strings and escaped, use I() to prevent double-escaping. For "json", parameters are automatically "unboxed" (i.e. length 1 vectors are converted to scalars). To preserve a length 1 vector as a vector, wrap in I(). For "raw", either a character or raw vector. You'll need to make sure to set the content_type() yourself.

user_agent

A user agent string, prepared by httr::user_agent(). When in doubt, a client package should have an internal function that extends gargle_user_agent() by prepending its return value with the client package's name and version.

Value

Object of class response from httr.

See Also

Other requests and responses: request_develop(), response_process()

Examples

## Not run: 
req <- gargle::request_build(
  method = "GET",
  path = "path/to/the/resource",
  token = "PRETEND_I_AM_TOKEN"
)
gargle::request_make(req)

## End(Not run)

Make a Google API request, repeatedly

Description

Intended primarily for internal use in client packages that provide high-level wrappers for users. It is a drop-in substitute for request_make() that also has the ability to retry the request. Codes that are considered retryable: 408, 429, 500, 502, 503.

Usage

request_retry(..., max_tries_total = 5, max_total_wait_time_in_seconds = 100)

Arguments

...

Passed along to request_make().

max_tries_total

Maximum number of tries.

max_total_wait_time_in_seconds

Total seconds we are willing to dedicate to waiting, summed across all tries. This is a technical upper bound and actual cumulative waiting will be less.

Details

Consider an example where we are willing to make a request up to 5 times.

try  1  2    3        4                5
     |--|----|--------|----------------|
wait  1   2      3           4

There will be up to 5 - 1 = 4 waits and we generally want the waiting period to get longer, in an exponential way. Such schemes are called exponential backoff. request_retry() implements exponential backoff with "full jitter", where each waiting time is generated from a uniform distribution, where the interval of support grows exponentially. A common alternative is "equal jitter", which adds some noise to fixed, exponentially increasing waiting times.

Either way our waiting times are based on a geometric series, which, by convention, is usually written in terms of powers of 2:

b, 2b, 4b, 8b, ...
  = b * 2^0, b * 2^1, b * 2^2, b * 2^3, ...

The terms in this series require knowledge of b, the so-called exponential base, and many retry functions and libraries require the user to specify this. But most users find it easier to declare the total amount of waiting time they can tolerate for one request. Therefore request_retry() asks for that instead and solves for b internally. This is inspired by the Opnieuw Python library for retries. Opnieuw's interface is designed to eliminate uncertainty around:

Let n be the total number of tries we're willing to make (the argument max_tries_total) and let W be the total amount of seconds we're willing to dedicate to making and retrying this request (the argument max_total_wait_time_in_seconds). Here's how we determine b:

sum_{i=0}^(n - 1) b * 2^i = W
b * sum_{i=0}^(n - 1) 2^i = W
       b * ( (2 ^ n) - 1) = W
                        b = W / ( (2 ^ n) - 1)

Value

Object of class response from httr.

Special cases

request_retry() departs from exponential backoff in three special cases:

See Also

Examples

## Not run: 
req <- gargle::request_build(
  method = "GET",
  path = "path/to/the/resource",
  token = "PRETEND_I_AM_TOKEN"
)
gargle::request_retry(req)

## End(Not run)

Process a Google API response

Description

response_process() is intended primarily for internal use in client packages that provide high-level wrappers for users. Typically applied as the final step in this sequence of calls:

All that's needed for a successful request is to parse the JSON extracted via httr::content(). Therefore, the main point of response_process() is to handle less happy outcomes:

If process_response() results in an error, a redacted version of the resp input is returned in the condition (auth tokens are removed).

Usage

response_process(
  resp,
  error_message = gargle_error_message,
  remember = TRUE,
  call = caller_env()
)

response_as_json(resp, call = caller_env())

gargle_error_message(resp, call = caller_env())

Arguments

resp

Object of class response from httr.

error_message

Function that produces an informative error message from the primary input, resp. It must return a character vector.

remember

Whether to remember the most recently processed response.

call

The execution environment of a currently running function, e.g. call = caller_env(). The corresponding function call is retrieved and mentioned in error messages as the source of the error.

You only need to supply call when throwing a condition from a helper function which wouldn't be relevant to mention in the message.

Can also be NULL or a defused function call to respectively not display any call or hard-code a code to display.

For more information about error calls, see Including function calls in error messages.

Details

When remember = TRUE (the default), gargle stores the most recently seen response internally, for post hoc examination. The stored response is literally just the most recent resp input, but with auth tokens redacted. It can be accessed via the unexported function gargle:::gargle_last_response(). A companion function gargle:::gargle_last_content() returns the content of the last response, which is probably the most useful form for post mortem analysis.

The response_as_json() helper is exported only as an aid to maintainers who wish to use their own error_message function, instead of gargle's built-in gargle_error_message(). When implementing a custom error_message function, call response_as_json() immediately on the input in order to inherit gargle's handling of non-JSON input.

Value

The content of the request, as a list. An HTTP status code of 204 (No content) is a special case returning TRUE.

See Also

Other requests and responses: request_develop(), request_make()

Examples

## Not run: 
# get an OAuth2 token with 'userinfo.email' scope
token <- token_fetch(scopes = "https://www.googleapis.com/auth/userinfo.email")

# see the email associated with this token
req <- gargle::request_build(
  method = "GET",
  path = "v1/userinfo",
  token = token,
  base_url = "https://openidconnect.googleapis.com"
)
resp <- gargle::request_make(req)
response_process(resp)

# make a bad request (this token has incorrect scope)
req <- gargle::request_build(
  method = "GET",
  path = "fitness/v1/users/{userId}/dataSources",
  token = token,
  params = list(userId = 12345)
)
resp <- gargle::request_make(req)
response_process(resp)

## End(Not run)

Get info from a token

Description

These functions send the token to Google endpoints that return info about a token or a user.

Usage

token_userinfo(token)

token_email(token)

token_tokeninfo(token)

Arguments

token

A token with class Token2.0 or an object of httr's class request, i.e. a token that has been prepared with httr::config() and has a Token2.0 in the auth_token component.

Details

It's hard to say exactly what info will be returned by the "userinfo" endpoint targetted by token_userinfo(). It depends on the token's scopes. Where possible, OAuth2 tokens obtained via the gargle package include the ⁠https://www.googleapis.com/auth/userinfo.email⁠ scope, which guarantees we can learn the email associated with the token. If the token has the ⁠https://www.googleapis.com/auth/userinfo.profile⁠ scope, there will be even more information available. But for a token with unknown or arbitrary scopes, we can't make any promises about what information will be returned.

Value

A list containing:

Examples

## Not run: 
# with service account token
t <- token_fetch(
  scopes = "https://www.googleapis.com/auth/drive",
  path   = "path/to/service/account/token/blah-blah-blah.json"
)
# or with an OAuth token
t <- token_fetch(
  scopes = "https://www.googleapis.com/auth/drive",
  email  = "janedoe@example.com"
)
token_userinfo(t)
token_email(t)
tokens_tokeninfo(t)

## End(Not run)

Fetch a token for the given scopes

Description

This is a rather magical function that calls a series of concrete credential-fetching functions, each wrapped in a tryCatch(). token_fetch() keeps trying until it succeeds or there are no more functions to try. See the vignette("how-gargle-gets-tokens") for a full description of token_fetch().

Usage

token_fetch(scopes = NULL, ...)

Arguments

scopes

A character vector of scopes to request. Pick from those listed at https://developers.google.com/identity/protocols/oauth2/scopes.

For certain token flows, the "https://www.googleapis.com/auth/userinfo.email" scope is unconditionally included. This grants permission to retrieve the email address associated with a token; gargle uses this to index cached OAuth tokens. This grants no permission to view or send email and is generally considered a low-value scope.

...

Additional arguments passed to all credential functions.

Value

An httr::Token (often an instance of something that inherits from httr::Token) or NULL.

See Also

cred_funs_list() reveals the current registry of credential-fetching functions, in order.

Other credential functions: credentials_app_default(), credentials_byo_oauth2(), credentials_external_account(), credentials_gce(), credentials_service_account(), credentials_user_oauth2()

Examples

## Not run: 
token_fetch(scopes = "https://www.googleapis.com/auth/userinfo.email")

## End(Not run)

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.