Package 'vcr'

Title: Record 'HTTP' Calls to Disk
Description: Record test suite 'HTTP' requests and replays them during future runs. A port of the Ruby gem of the same name (<https://github.com/vcr/vcr/>). Works by hooking into the 'webmockr' R package for matching 'HTTP' requests by various rules ('HTTP' method, 'URL', query parameters, headers, body, etc.), and then caching real 'HTTP' responses on disk in 'cassettes'. Subsequent 'HTTP' requests matching any previous requests in the same 'cassette' use a cached 'HTTP' response.
Authors: Scott Chamberlain [aut, cre] (ORCID: <https://orcid.org/0000-0003-1444-9135>), Aaron Wolen [aut] (ORCID: <https://orcid.org/0000-0003-2542-2202>), Maëlle Salmon [aut] (ORCID: <https://orcid.org/0000-0002-2815-0399>), Daniel Possenriede [aut] (ORCID: <https://orcid.org/0000-0002-6738-9845>), Hadley Wickham [aut], rOpenSci [fnd] (ROR: <https://ror.org/019jywm96>)
Maintainer: Scott Chamberlain <[email protected]>
License: MIT + file LICENSE
Version: 1.7.0.91
Built: 2025-05-29 17:22:02 UTC
Source: https://github.com/ropensci/vcr

Help Index


List cassettes, get current cassette, etc.

Description

List cassettes, get current cassette, etc.

Usage

cassettes()

current_cassette()

current_cassette_recording()

current_cassette_replaying()

cassette_path()

Details

  • cassettes(): returns all active cassettes in the current session.

  • current_cassette(): returns NULL when no cassettes are in use; returns the current cassette (a Cassette object) when one is in use

  • currrent_cassette_recording() and current_cassette_replaying(): tell you if the current cassette is recording and/or replaying. They both return FALSE if there is no cassette in use.

  • cassette_path(): returns the current directory path where cassettes will be stored

Examples

vcr_configure(dir = tempdir())

# list all cassettes
cassettes()

# list the currently active cassette
insert_cassette("stuffthings")
current_cassette()
cassettes()

eject_cassette()
cassettes()


# list the path to cassettes
cassette_path()
vcr_configure(dir = file.path(tempdir(), "foo"))
cassette_path()

vcr_configure_reset()

Use cassettes in examples

Description

insert_example_cassette() is a wrapper around insert_cassette() that stores cassettes in ⁠inst/_vcr/⁠. Call it in the first line of your examples (typically wrapped in ⁠\dontshow{}⁠), and call eject_cassette() on the last line.

Run the example manually once to record the vignettte, then it will be replayed during ⁠R CMD check⁠, ensuring that your example no longer uses the internet.

Usage

insert_example_cassette(
  name,
  package,
  record = NULL,
  match_requests_on = NULL,
  serialize_with = NULL,
  preserve_exact_body_bytes = NULL,
  re_record_interval = NULL
)

Arguments

name

The name of the cassette. This is used to name a file on disk, so it must be valid file name.

package

Package name.

record

Record mode. This will be "all" if package is under development, (i.e. loaded by devtools) and "none" otherwise. These defaults ensure that you can easily re-record the cassette during development and the example will never make HTTP requests while testing.

match_requests_on

Character vector of request matchers used to determine which recorded HTTP interaction to replay. Possible values are:

  • method: the HTTP method.

  • uri: the complete request URI, excluding the port.

  • uri_with_port: the complete request URI, including the port.

  • host: the host component of the URI.

  • path: the path component of the URI.

  • query: the query component of the URI.

  • body: the request body.

  • body_json: the request body, parsed as JSON.

  • header: all request headers.

If more than one is specified, all components must match in order for the request to match. If not supplied, defaults to c("method", "uri").

Note that the request header and body will only be included in the cassette if match_requests_on includes "header" or "body" respectively. This keeps the recorded request as lightweight as possible.

serialize_with

(string) Which serializer to use: "yaml" (the default), "json", or "qs2".

preserve_exact_body_bytes

(logical) Force a binary (base64) representation of the request and response bodies? By default, vcr will look at the Content-Type header to determine if this is necessary, but if it doesn't work you can set preserve_exact_body_bytes = TRUE to force it.

re_record_interval

(integer) How frequently (in seconds) the cassette should be re-recorded. Default: NULL (not re-recorded).

Examples

# In this example I'm showing the insert and eject commands, but you'd
# usually wrap these in \dontshow{} so the user doesn't see them and
# think that they're something they need to copy.

insert_example_cassette("httpbin-get", package = "vcr")

req <- httr2::request("https://hb.cran.dev/get")
resp <- httr2::req_perform(req)

str(httr2::resp_body_json(resp))

eject_cassette()

Turn vcr on and off

Description

  • turn_on() and turn_off() turn on and off for the whole session.

  • turned_off(code) temporarily turns off while code is running, guaranteeing that you make a real HTTP request.

  • turned_on() reports on if vcr is turned on or not.

  • skip_if_vcr_off() skips a test if vcr is turned off. This is occasionally useful if you're using a cassette to simulate a faked request, or if the real request would return different values (e.g. you're testing date parsing and the request returns the current date).

You can also control the default behaviour in a new session by setting the following environment variables before R starts:

  • Use VCR_TURN_OFF=true to suppress all vcr usage, ignoring all cassettes. This is useful for CI/CD workflows where you want to ensure the test suite is run against the live API.

  • Set VCR_TURNED_OFF=true to turn off vcr, but still use cassettes.

Usage

turn_on()

turn_off(ignore_cassettes = FALSE)

turned_off(code, ignore_cassettes = FALSE)

turned_on()

skip_if_vcr_off()

Arguments

ignore_cassettes

(logical) Controls what happens when a cassette is inserted while vcr is turned off. If TRUE is passed, the cassette insertion will be ignored; otherwise an error will be raised. Default: FALSE

code

Any block of code to run, presumably an HTTP request.

Examples

# By default, vcr is turned on
turned_on()

# you can turn off for the rest of the session
turn_off()
turned_on()
# turn on again
turn_on()

# or just turn it on turn off temporarily
turned_off({
  # some HTTP requests here
  turned_on()
})

Use vcr in vignettes

Description

setup_knitr() registers a knitr hook to make it easy to use vcr inside a vignette. First call setup_knitr() in your setup chunk (or other chunk early in the document):

```{r setup}
#| include: false
vcr::setup_knitr()
```

Then, in a chunk where you want to use a cassette, set the cassette chunk option to the name of the cassette:

```{r}
#| cassette: name
req <- httr2::request("http://r-project.org")
resp <- httr2::req_perform(req)
```

Usage

setup_knitr(prefix = NULL, dir = "_vcr", ...)

Arguments

prefix

An prefix for the cassette name to make cassettes unique across vignettes. Defaults to the file name (without extension) of the currently executing vignette.

dir

Directory where to create the cassette file. Default: '"_vcr"“.

...

Other arguments passed on to insert_cassette().


Use a cassette to record HTTP requests

Description

use_cassette(...) uses a cassette for the code in ..., local_cassette() uses a cassette for the current function scope (e.g. for one test).

Usage

use_cassette(
  name,
  ...,
  dir = NULL,
  record = NULL,
  match_requests_on = NULL,
  serialize_with = NULL,
  preserve_exact_body_bytes = NULL,
  re_record_interval = NULL,
  warn_on_empty = NULL
)

local_cassette(
  name,
  dir = NULL,
  record = NULL,
  match_requests_on = NULL,
  serialize_with = NULL,
  preserve_exact_body_bytes = NULL,
  re_record_interval = NULL,
  warn_on_empty = NULL,
  frame = parent.frame()
)

Arguments

name

The name of the cassette. This is used to name a file on disk, so it must be valid file name.

...

a block of code containing one or more requests (required). Use curly braces to encapsulate multi-line code blocks. If you can't pass a code block use insert_cassette() instead.

dir

The directory where the cassette will be stored. If unspecified, (and hasn't been set in vcr_configure()) will use test_path("_vcr").

record

Record mode that dictates how HTTP requests/responses are recorded. Possible values are:

  • once, the default: Replays recorded interactions, records new ones if no cassette exists, and errors on new requests if cassette exists.

  • none: Replays recorded interactions, and errors on any new requests. Guarantees that no HTTP requests occur.

  • new_episodes: Replays recorded interactions and always records new ones, even if similar interactions exist.

  • all: Never replays recorded interactions, always recording new. Useful for re-recording outdated responses or logging all HTTP requests.

match_requests_on

Character vector of request matchers used to determine which recorded HTTP interaction to replay. Possible values are:

  • method: the HTTP method.

  • uri: the complete request URI, excluding the port.

  • uri_with_port: the complete request URI, including the port.

  • host: the host component of the URI.

  • path: the path component of the URI.

  • query: the query component of the URI.

  • body: the request body.

  • body_json: the request body, parsed as JSON.

  • header: all request headers.

If more than one is specified, all components must match in order for the request to match. If not supplied, defaults to c("method", "uri").

Note that the request header and body will only be included in the cassette if match_requests_on includes "header" or "body" respectively. This keeps the recorded request as lightweight as possible.

serialize_with

(string) Which serializer to use: "yaml" (the default), "json", or "qs2".

preserve_exact_body_bytes

(logical) Force a binary (base64) representation of the request and response bodies? By default, vcr will look at the Content-Type header to determine if this is necessary, but if it doesn't work you can set preserve_exact_body_bytes = TRUE to force it.

re_record_interval

(integer) How frequently (in seconds) the cassette should be re-recorded. Default: NULL (not re-recorded).

warn_on_empty

(logical) Warn if the cassette is ejected but no interactions have been recorded. Default: NULL (inherits from global configuration).

frame

Attach exit handlers to this environment. Typically, this should be either the current environment or a parent frame (accessed through parent.frame()). See vignette("withr", package = "withr") for more details.

Value

an object of class Cassette

Cassette options

Default values for arguments controlling cassette behavior are inherited from vcr's global configuration. See vcr_configure() for a complete list of options and their default settings. You can override these options for a specific cassette by changing an argument's value to something other than NULL when calling either insert_cassette() or use_cassette().

Behavior

This function handles a few different scenarios:

  • when everything runs smoothly, and we return a Cassette class object so you can inspect the cassette, and the cassette is ejected

  • when there is an invalid parameter input on cassette creation, we fail with a useful message, we don't return a cassette, and the cassette is ejected

  • when there is an error in calling your passed in code block, we return with a useful message, and since we use on.exit() the cassette is still ejected even though there was an error, but you don't get an object back

  • whenever an empty cassette (a yml/json file) is found, we delete it before returning from the use_cassette() function call. we achieve this via use of on.exit() so an empty cassette is deleted even if there was an error in the code block you passed in

Cassettes on disk

Note that "eject" only means that the R session cassette is no longer in use. If any interactions were recorded to disk, then there is a file on disk with those interactions.

Using with tests (specifically testthat)

There's a few ways to get correct line numbers for failed tests and one way to not get correct line numbers:

Correct: Either wrap your test_that() block inside your use_cassette() block, OR if you put your use_cassette() block inside your test_that() block put your testthat expectations outside of the use_cassette() block.

Incorrect: By wrapping the use_cassette() block inside your test_that() block with your testthat expectations inside the use_cassette() block, you'll only get the line number that the use_cassette() block starts on.

See Also

insert_cassette() and eject_cassette() for the underlying functions.

Examples

## Not run: 
library(vcr)
library(crul)
vcr_configure(dir = tempdir())

use_cassette(name = "apple7", {
  cli <- HttpClient$new(url = "https://hb.opencpu.org")
  resp <- cli$get("get")
})
readLines(file.path(tempdir(), "apple7.yml"))

# preserve exact body bytes - records in base64 encoding
use_cassette("things4", {
  cli <- crul::HttpClient$new(url = "https://hb.opencpu.org")
  bbb <- cli$get("get")
}, preserve_exact_body_bytes = TRUE)
## see the body string value in the output here
readLines(file.path(tempdir(), "things4.yml"))

# cleanup
unlink(file.path(tempdir(), c("things4.yml", "apple7.yml")))


# with httr
library(vcr)
library(httr)
vcr_configure(dir = tempdir(), log = TRUE, log_opts = list(file = file.path(tempdir(), "vcr.log")))

use_cassette(name = "stuff350", {
  res <- GET("https://hb.opencpu.org/get")
})
readLines(file.path(tempdir(), "stuff350.yml"))

use_cassette(name = "catfact456", {
  res <- GET("https://catfact.ninja/fact")
})

# record mode: none
library(crul)
vcr_configure(dir = tempdir())

## make a connection first
conn <- crul::HttpClient$new("https://eu.httpbin.org")
## this errors because 'none' disallows any new requests
# use_cassette("none_eg", (res2 <- conn$get("get")), record = "none")
## first use record mode 'once' to record to a cassette
one <- use_cassette("none_eg", (res <- conn$get("get")), record = "once")
one; res
## then use record mode 'none' to see its behavior
two <- use_cassette("none_eg", (res2 <- conn$get("get")), record = "none")
two; res2

## End(Not run)

Global Configuration Options

Description

Configurable options that define vcr's default behavior.

Usage

vcr_configure(
  dir,
  record,
  match_requests_on,
  serialize_with,
  json_pretty,
  ignore_hosts,
  ignore_localhost,
  ignore_request,
  preserve_exact_body_bytes,
  turned_off,
  re_record_interval,
  log,
  log_opts,
  filter_sensitive_data,
  filter_sensitive_data_regex,
  filter_request_headers,
  filter_response_headers,
  filter_query_parameters,
  write_disk_path,
  warn_on_empty_cassette
)

local_vcr_configure(..., .frame = parent.frame())

vcr_configure_reset()

vcr_configuration()

vcr_config_defaults()

Arguments

dir

Directory where cassettes are stored.

record

Record mode that dictates how HTTP requests/responses are recorded. Possible values are:

  • once, the default: Replays recorded interactions, records new ones if no cassette exists, and errors on new requests if cassette exists.

  • none: Replays recorded interactions, and errors on any new requests. Guarantees that no HTTP requests occur.

  • new_episodes: Replays recorded interactions and always records new ones, even if similar interactions exist.

  • all: Never replays recorded interactions, always recording new. Useful for re-recording outdated responses or logging all HTTP requests.

match_requests_on

Character vector of request matchers used to determine which recorded HTTP interaction to replay. Possible values are:

  • method: the HTTP method.

  • uri: the complete request URI, excluding the port.

  • uri_with_port: the complete request URI, including the port.

  • host: the host component of the URI.

  • path: the path component of the URI.

  • query: the query component of the URI.

  • body: the request body.

  • body_json: the request body, parsed as JSON.

  • header: all request headers.

If more than one is specified, all components must match in order for the request to match. If not supplied, defaults to c("method", "uri").

Note that the request header and body will only be included in the cassette if match_requests_on includes "header" or "body" respectively. This keeps the recorded request as lightweight as possible.

serialize_with

(string) Which serializer to use: "yaml" (the default), "json", or "qs2".

json_pretty

(logical) want JSON to be newline separated to be easier to read? Or remove newlines to save disk space? default: FALSE.'

ignore_hosts

(character) Vector of hosts to ignore. e.g., "localhost", or "google.com". These hosts are ignored and real HTTP requests are allowed to go through.

ignore_localhost

(logical) Default: FALSE

ignore_request

List of requests to ignore. NOT USED RIGHT NOW, sorry

preserve_exact_body_bytes

(logical) Force a binary (base64) representation of the request and response bodies? By default, vcr will look at the Content-Type header to determine if this is necessary, but if it doesn't work you can set preserve_exact_body_bytes = TRUE to force it.

turned_off

(logical) VCR is turned on by default. Default: FALSE.

re_record_interval

(integer) How frequently (in seconds) the cassette should be re-recorded. Default: NULL (not re-recorded).

log, log_opts

See vcr_configure_log().

filter_sensitive_data

instructing vcr with what value to replace the real value of the query parameter.

filter_sensitive_data_regex

named list of values to replace. Follows filter_sensitive_data format, except uses fixed=FALSE in the gsub() function call; this means that the value in thing_to_replace is a regex pattern.

filter_request_headers

(character/list) request headers to filter. A character vector of request headers to remove - the headers will not be recorded to disk. Alternatively, a named list similar to

filter_response_headers

(character/list) response headers to filter. A character vector of response headers to remove - the headers will not be recorded to disk. Alternatively, a named list similar to filter_sensitive_data instructing vcr with what value to replace the real value of the response header.

filter_query_parameters

(named list) query parameters to filter. A character vector of query parameters to remove - the query parameters will not be recorded to disk. Alternatively, a named list similar to

write_disk_path

(character) path to write files to for any requests that write responses to disk. By default this will be ⁠{cassette-name}-files/⁠ inside the cassette directory.

warn_on_empty_cassette

(logical) Should a warning be thrown when an empty cassette is detected? Empty cassettes are cleaned up (deleted) either way. This option only determines whether a warning is thrown or not. Default: FALSE

...

Configuration settings used to override defaults.

.frame

Attach exit handlers to this environment. Typically, this should be either the current environment or a parent frame (accessed through parent.frame()). See vignette("withr", package = "withr") for more details.

Examples

vcr_configure(dir = tempdir())
vcr_configure(dir = tempdir(), record = "all")
vcr_configuration()
vcr_config_defaults()
vcr_configure(dir = tempdir(), ignore_hosts = "google.com")
vcr_configure(dir = tempdir(), ignore_localhost = TRUE)

# filter sensitive data
vcr_configure(dir = tempdir(),
  filter_sensitive_data = list(foo = "<bar>")
)
vcr_configure(dir = tempdir(),
  filter_sensitive_data = list(foo = "<bar>", hello = "<world>")
)

Configure vcr logging

Description

By default, logging is disabled, but you can easily enable for the entire session with vcr_configure_log() or for just one test with local_vcr_configure_log().

Usage

vcr_configure_log(
  log = TRUE,
  file = stderr(),
  include_date = NULL,
  log_prefix = "Cassette"
)

local_vcr_configure_log(
  log = TRUE,
  file = stderr(),
  include_date = NULL,
  log_prefix = "Cassette",
  frame = parent.frame()
)

Arguments

log

Should we log important vcr things?

file

A path or connection to log to

include_date

(boolean) Include date and time in each log entry.

log_prefix

"Cassette". We insert the cassette name after this prefix, followed by the rest of the message.

frame

Attach exit handlers to this environment. Typically, this should be either the current environment or a parent frame (accessed through parent.frame()). See vignette("withr", package = "withr") for more details.

Examples

# The default logs to stderr()
vcr_configure_log()

# But you might want to log to a file
vcr_configure_log(file = file.path(tempdir(), "vcr.log"))

Retrieve last vcr request/response

Description

When debugging, it's often useful to see the last request and response respectively. These functions give you what would have been recorded to disk or replayed from disk. If the last request wasn't recorded, and there was no matching request, vcr_last_response will return NULL.

Usage

vcr_last_request()

vcr_last_response()

Locate file in tests directory

Description

This function, similar to testthat::test_path(), is designed to work both interactively and during tests, locating files in the ⁠tests/⁠ directory.

Usage

vcr_test_path(...)

Arguments

...

Character vectors giving path components. Each character string gets added to the path, e.g., vcr_test_path("a", "b") becomes tests/a/b relative to the root of the package.

Value

A character vector giving the path

Note

vcr_test_path() assumes you are using testthat for your unit tests.

Examples

if (interactive()) {
vcr_test_path("fixtures")
}