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. |
Version: | 1.7.0 |
URL: | https://github.com/ropensci/vcr/, https://books.ropensci.org/http-testing/, https://docs.ropensci.org/vcr/ |
BugReports: | https://github.com/ropensci/vcr/issues |
License: | MIT + file LICENSE |
Encoding: | UTF-8 |
Language: | en-US |
LazyData: | true |
VignetteBuilder: | knitr |
Imports: | crul (≥ 0.8.4), httr, httr2, webmockr (≥ 0.8.0), urltools, yaml, R6, base64enc, rprojroot |
Suggests: | roxygen2 (≥ 7.2.1), jsonlite, testthat, knitr, rmarkdown, desc, crayon, cli, curl, withr, webfakes |
X-schema.org-applicationCategory: | Web |
X-schema.org-keywords: | http, https, API, web-services, curl, mock, mocking, http-mocking, testing, testing-tools, tdd |
X-schema.org-isPartOf: | https://ropensci.org |
RoxygenNote: | 7.3.2 |
NeedsCompilation: | no |
Packaged: | 2025-03-07 18:32:27 UTC; sckott |
Author: | Scott Chamberlain |
Maintainer: | Scott Chamberlain <myrmecocystus@gmail.com> |
Repository: | CRAN |
Date/Publication: | 2025-03-10 10:10:02 UTC |
vcr: 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.
Backstory
A Ruby gem of the same name (VCR
, https://github.com/vcr/vcr) was
created many years ago and is the original. Ports in many languages
have been done. Check out that GitHub repo for all the details on
how the canonical version works.
Main functions
The use_cassette function is most likely what you'll want to use. It sets the cassette you want to record to, inserts the cassette, and then ejects the cassette, recording the interactions to the cassette.
Instead, you can use insert_cassette, but then you have to make sure to use eject_cassette.
vcr configuration
vcr_configure is the function to use to set R session wide settings. See it's manual file for help.
Record modes
See recording for help on record modes.
Request matching
See request-matching for help on the many request matching options.
Async
As of crul v1.5, vcr
will work for async http requests with
crul. httr does not do async requests, and httr2
async plumbing does not have any hooks for mocking via webmockr
or recording real requests via this package
Author(s)
Maintainer: Scott Chamberlain myrmecocystus@gmail.com (ORCID)
Authors:
Other contributors:
rOpenSci (019jywm96) [funder]
See Also
Useful links:
Report bugs at https://github.com/ropensci/vcr/issues
Coerce names, etc. to cassettes
Description
Coerce names, etc. to cassettes
Coerce to a cassette path
Usage
as.cassette(x, ...)
as.cassettepath(x)
Arguments
x |
Input, a cassette name (character), or something that can be coerced to a cassette |
... |
further arguments passed on to |
Value
a cassette of class Cassette
Examples
## Not run:
vcr_configure(dir = tempfile())
insert_cassette("foobar")
cassettes(on_disk = FALSE)
cassettes(on_disk = TRUE)
as.cassette("foobar", on_disk = FALSE)
eject_cassette() # eject the current cassette
# cleanup
unlink(file.path(tempfile(), "foobar.yml"))
## End(Not run)
Cassette handler
Description
Main R6 class that is called from the main user facing
function use_cassette()
Value
an object of class Cassette
Points of webmockr integration
-
initialize()
: webmockr is used in theinitialize()
method to create webmockr stubs. stubs are created on call toCassette$new()
withininsert_cassette()
, but then on exitinguse_cassette()
, or callingeject()
onCassette
class frominsert_cassette()
, stubs are cleaned up. -
eject()
method:webmockr::disable()
is called before exiting eject to disable webmock so that webmockr does not affect any HTTP requests that happen afterwards -
call_block()
method: call_block is used in theuse_cassette()
function to evaluate whatever code is passed to it; within call_blockwebmockr::webmockr_allow_net_connect()
is run before we evaluate the code block to allow real HTTP requests, thenwebmockr::webmockr_disable_net_connect()
is called after evalulating the code block to disallow real HTTP requests -
make_http_interaction()
method:webmockr::pluck_body()
utility function is used to pull the request body out of the HTTP request -
serialize_to_crul()
method: method: webmockr::RequestSignature and webmockr::Response are used to build a request and response, respectively, then passed towebmockr::build_crul_response()
to make a completecrul
HTTP response object
Public fields
name
(character) cassette name
record
(character) record mode
manfile
(character) cassette file path
recorded_at
(character) date/time recorded at
serialize_with
(character) serializer to use (yaml|json)
serializer
(character) serializer to use (yaml|json)
persist_with
(character) persister to use (FileSystem only)
persister
(character) persister to use (FileSystem only)
match_requests_on
(character) matchers to use default: method & uri
re_record_interval
(numeric) the re-record interval
tag
ignored, not used right now
tags
ignored, not used right now
root_dir
root dir, gathered from
vcr_configuration()
update_content_length_header
(logical) Whether to overwrite the
Content-Length
headerallow_playback_repeats
(logical) Whether to allow a single HTTP interaction to be played back multiple times
allow_unused_http_interactions
(logical) ignored, not used right now
exclusive
(logical) ignored, not used right now
preserve_exact_body_bytes
(logical) Whether to base64 encode the bytes of the requests and responses
args
(list) internal use
http_interactions_
(list) internal use
new_recorded_interactions
(list) internal use
clean_outdated_http_interactions
(logical) Should outdated interactions be recorded back to file
to_return
(logical) internal use
cassette_opts
(list) various cassette options
Methods
Public methods
Method new()
Create a new Cassette
object
Usage
Cassette$new( name, record, serialize_with, persist_with, match_requests_on, re_record_interval, tag, tags, update_content_length_header, allow_playback_repeats, allow_unused_http_interactions, exclusive, preserve_exact_body_bytes, clean_outdated_http_interactions )
Arguments
name
The name of the cassette. vcr will sanitize this to ensure it is a valid file name.
record
The record mode. Default: "once". In the future we'll support "once", "all", "none", "new_episodes". See recording for more information
serialize_with
(character) Which serializer to use. Valid values are "yaml" (default), the only one supported for now.
persist_with
(character) Which cassette persister to use. Default: "file_system". You can also register and use a custom persister.
match_requests_on
List of request matchers to use to determine what recorded HTTP interaction to replay. Defaults to
["method", "uri"]
. The built-in matchers are "method", "uri", "headers" and "body" ("host" and "path" not supported yet, but should be in a future version)re_record_interval
(numeric) When given, the cassette will be re-recorded at the given interval, in seconds.
tag, tags
tags ignored, not used right now
update_content_length_header
(logical) Whether or not to overwrite the
Content-Length
header of the responses to match the length of the response body. Default:FALSE
allow_playback_repeats
(logical) Whether or not to allow a single HTTP interaction to be played back multiple times. Default:
FALSE
.allow_unused_http_interactions
(logical) ignored, not used right now
exclusive
(logical) ignored, not used right now
preserve_exact_body_bytes
(logical) Whether or not to base64 encode the bytes of the requests and responses for this cassette when serializing it. See also
preserve_exact_body_bytes
invcr_configure()
. Default:FALSE
clean_outdated_http_interactions
(logical) Should outdated interactions be recorded back to file. Default:
FALSE
Returns
A new Cassette
object
Method print()
print method for Cassette
objects
Usage
Cassette$print(x, ...)
Arguments
x
self
...
ignored
Method call_block()
run code
Usage
Cassette$call_block(...)
Arguments
...
pass in things to be evaluated
Returns
various
Method eject()
ejects the current cassette
Usage
Cassette$eject()
Returns
self
Method file()
get the file path for the cassette
Usage
Cassette$file()
Returns
character
Method recording()
is the cassette in recording mode?
Usage
Cassette$recording()
Returns
logical
Method is_empty()
is the cassette on disk empty
Usage
Cassette$is_empty()
Returns
logical
Method originally_recorded_at()
timestamp the cassette was originally recorded at
Usage
Cassette$originally_recorded_at()
Returns
POSIXct date
Method serializable_hash()
Get a list of the http interactions to record + recorded_with
Usage
Cassette$serializable_hash()
Returns
list
Method interactions_to_record()
Get the list of http interactions to record
Usage
Cassette$interactions_to_record()
Returns
list
Method merged_interactions()
Get interactions to record
Usage
Cassette$merged_interactions()
Returns
list
Method up_to_date_interactions()
Cleans out any old interactions based on the re_record_interval and clean_outdated_http_interactions settings
Usage
Cassette$up_to_date_interactions(interactions)
Arguments
interactions
list of http interactions, of class HTTPInteraction
Returns
list of interactions to record
Method should_re_record()
Should re-record interactions?
Usage
Cassette$should_re_record()
Returns
logical
Method should_stub_requests()
Is record mode NOT "all"?
Usage
Cassette$should_stub_requests()
Returns
logical
Method should_remove_matching_existing_interactions()
Is record mode "all"?
Usage
Cassette$should_remove_matching_existing_interactions()
Returns
logical
Method storage_key()
Get the serializer path
Usage
Cassette$storage_key()
Returns
character
Method raw_cassette_bytes()
Get character string of entire cassette; bytes is a misnomer
Usage
Cassette$raw_cassette_bytes()
Returns
character
Method make_dir()
Create the directory that holds the cassettes, if not present
Usage
Cassette$make_dir()
Returns
no return; creates a directory recursively, if missing
Method deserialized_hash()
get http interactions from the cassette via the serializer
Usage
Cassette$deserialized_hash()
Returns
list
Method previously_recorded_interactions()
get all previously recorded interactions
Usage
Cassette$previously_recorded_interactions()
Returns
list
Method write_recorded_interactions_to_disk()
write recorded interactions to disk
Usage
Cassette$write_recorded_interactions_to_disk()
Returns
nothing returned
Method record_http_interaction()
record an http interaction (doesn't write to disk)
Usage
Cassette$record_http_interaction(x)
Arguments
x
a crul, httr, or httr2 response object, with the request at
$request
Returns
nothing returned
Method any_new_recorded_interactions()
Are there any new recorded interactions?
Usage
Cassette$any_new_recorded_interactions()
Returns
logical
Method make_args()
make list of all options
Usage
Cassette$make_args()
Returns
nothing returned
Method write_metadata()
write metadata to the cassette
Usage
Cassette$write_metadata()
Returns
nothing returned
Method http_interactions()
make HTTPInteractionList object, assign to http_interactions_ var
Usage
Cassette$http_interactions()
Returns
nothing returned
Method make_http_interaction()
Make an HTTPInteraction
object
Usage
Cassette$make_http_interaction(x)
Arguments
x
A crul, httr, or httr2 response object, with the request at
$request
Returns
an object of class HTTPInteraction
Method serialize_to_crul()
Make a crul response object
Usage
Cassette$serialize_to_crul()
Returns
a crul response
Method clone()
The objects of this class are cloneable with this method.
Usage
Cassette$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
See Also
vcr_configure()
, use_cassette()
, insert_cassette()
Examples
## Not run:
library(vcr)
vcr_configure(dir = tempdir())
res <- Cassette$new(name = "bob")
res$file()
res$originally_recorded_at()
res$recording()
res$serializable_hash()
res$eject()
res$should_remove_matching_existing_interactions()
res$storage_key()
res$match_requests_on
# record all requests
res <- Cassette$new("foobar", record = "all")
res$eject()
# cleanup
unlink(file.path(tempdir(), c("bob.yml", "foobar.yml")))
library(vcr)
vcr_configure(dir = tempdir())
res <- Cassette$new(name = "jane")
library(crul)
# HttpClient$new("https://hb.opencpu.org")$get("get")
## End(Not run)
List cassettes, get current cassette, etc.
Description
List cassettes, get current cassette, etc.
Usage
cassettes(on_disk = TRUE, verb = FALSE)
current_cassette()
cassette_path()
Arguments
on_disk |
(logical) Check for cassettes on disk + cassettes in session
( |
verb |
(logical) verbose messages |
Details
-
cassettes()
: returns cassettes found in your R session, you can toggle whether we pull from those on disk or not -
current_cassette()
: returns an empty list when no cassettes are in use, while it returns the current cassette (aCassette
object) when one is in use -
cassette_path()
: just gives you the current directory path where cassettes will be stored
Examples
vcr_configure(dir = tempdir())
# list all cassettes
cassettes()
cassettes(on_disk = FALSE)
# list the currently active cassette
insert_cassette("stuffthings")
current_cassette()
eject_cassette()
cassettes()
cassettes(on_disk = FALSE)
# list the path to cassettes
cassette_path()
vcr_configure(dir = file.path(tempdir(), "foo"))
cassette_path()
vcr_configure_reset()
Check cassette names
Description
Check cassette names
Usage
check_cassette_names(
pattern = "test-",
behavior = "stop",
allowed_duplicates = NULL
)
Arguments
pattern |
(character) regex pattern for file paths to check.
this is done inside of |
behavior |
(character) "stop" (default) or "warning". if "warning",
we use |
allowed_duplicates |
(character) cassette names that can be duplicated |
Details
Cassette names:
Should be meaningful so that it is obvious to you what test/function they relate to. Meaningful names are important so that you can quickly determine to what test file or test block a cassette belongs. Note that vcr cannot check that your cassette names are meaningful.
Should not be duplicated. Duplicated cassette names would lead to a test using the wrong cassette.
Should not have spaces. Spaces can lead to problems in using file paths.
Should not include a file extension. vcr handles file extensions for the user.
Should not have illegal characters that can lead to problems in using file paths:
/
,?
,<
,>
,\
,:
,*
,|
, and\"
Should not have control characters, e.g.,
\n
Should not have just dots, e.g.,
.
or..
Should not have Windows reserved words, e.g.,
com1
Should not have trailing dots
Should not be longer than 255 characters
vcr::check_cassette_names()
is meant to be run during your tests, from
a helper-*.R
file
inside the tests/testthat
directory. It only checks that cassette
names are not duplicated. Note that if you do need to have duplicated
cassette names you can do so by using the allowed_duplicates
parameter
in check_cassette_names()
. A helper function check_cassette_names()
runs inside insert_cassette()
that checks that
cassettes do not have: spaces, file extensions, unaccepted characters
(slashes).
An HTTP request as prepared by the crul package
Description
The object is a list, and is the object that is passed on to webmockr and vcr instead of routing through crul as normal. Used in examples/tests.
Format
A list
Eject a cassette
Description
Eject a cassette
Usage
eject_cassette(
cassette = NULL,
options = list(),
skip_no_unused_interactions_assertion = NULL
)
Arguments
cassette |
(character) a single cassette names to eject; see |
options |
(list) a list of options to apply to the eject process |
skip_no_unused_interactions_assertion |
(logical) If |
Value
The ejected cassette if there was one
See Also
use_cassette()
, insert_cassette()
Examples
vcr_configure(dir = tempdir())
insert_cassette("hello")
(x <- current_cassette())
# by default does current cassette
x <- eject_cassette()
x
# can also select by cassette name
# eject_cassette(cassette = "hello")
File system persister
Description
The only built-in cassette persister. Persists cassettes to the file system.
Details
Private Methods
storage_location()
-
Get storage location
absolute_path_to_file()
-
Get absolute path to the
storage_location
Public fields
file_name
(character) the file name, not whole path
write_fxn
(character) fxn to use for writing to disk
content
(character) content to record to a cassette
path
(character) storage directory for cassettes
write2disk
(character) write to disk or make a new FileSystem
Methods
Public methods
Method new()
Create a new FileSystem
object
Usage
FileSystem$new( file_name = NULL, write_fxn = NULL, content = NULL, path = NULL, write2disk = FALSE )
Arguments
file_name
(character) the file name, not whole path
write_fxn
(character) fxn to use for writing to disk
content
(character) content to record to a cassette
path
(character) storage directory for cassettes
write2disk
(logical) write to disk or just make a new FileSystem object. Default:
FALSE
Returns
A new FileSystem
object
Method get_cassette()
Gets the cassette for the given storage key (file name)
Usage
FileSystem$get_cassette(file_name = NULL)
Arguments
file_name
(character) the file name, not whole path
Returns
named list, from yaml::yaml.load_file
Method is_empty()
Checks if a cassette is empty or not
Usage
FileSystem$is_empty()
Returns
logical
Method set_cassette()
Sets the cassette for the given storage key (file name)
Usage
FileSystem$set_cassette(file_name = NULL, content)
Arguments
file_name
(character) the file name, not whole path
content
(character) content to record to a cassette
Returns
no return; writes to disk
Method clone()
The objects of this class are cloneable with this method.
Usage
FileSystem$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Hooks class
Description
Helps define new hooks, hold hooks, and accessors to get and use hooks.
Details
Private Methods
make_hook(x, plac, fun)
-
Make a hook. - x (character) Hook name - plac Placement, one of "start" or "end" - fun a function/callback
Public fields
hooks
intenal use
Methods
Public methods
Method invoke_hook()
invoke a hook
Usage
Hooks$invoke_hook(hook_type, args)
Arguments
hook_type
(character) Hook name
args
(named list) Args passed when invoking a hook
Returns
executes hook
Method clear_hooks()
clear all hooks
Usage
Hooks$clear_hooks()
Returns
no return
Method define_hook()
define a hook
Usage
Hooks$define_hook(hook_type, fun, prepend = FALSE)
Arguments
hook_type
(character) Hook name
fun
A function
prepend
(logical) Whether to prepend or add to the end of the string. Default:
FALSE
Returns
no return; defines hook internally
Method clone()
The objects of this class are cloneable with this method.
Usage
Hooks$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Get the http interactions of the current cassette
Description
Get the http interactions of the current cassette
Usage
http_interactions()
Value
object of class HTTPInteractionList
if there is a current
cassette in use, or NullList
if no cassette in use
Examples
## Not run:
vcr_configure(dir = tempdir())
insert_cassette("foo_bar")
webmockr::webmockr_allow_net_connect()
library(crul)
cli <- crul::HttpClient$new("https://hb.opencpu.org/get")
one <- cli$get(query = list(a = 5))
z <- http_interactions()
z
z$interactions
z$used_interactions
# on eject, request written to the cassette
eject_cassette("foo_bar")
# insert cassette again
insert_cassette("foo_bar")
# now interactions will be present
z <- http_interactions()
z$interactions
z$used_interactions
invisible(cli$get(query = list(a = 5)))
z$used_interactions
# cleanup
unlink(file.path(tempdir(), "foo_bar.yml"))
## End(Not run)
HTTPInteraction class
Description
object holds request and response objects
Details
Methods
to_hash()
-
Create a hash from the HTTPInteraction object
from_hash(hash)
-
Create a HTTPInteraction object from a hash
Public fields
request
A
Request
class objectresponse
A
VcrResponse
class objectrecorded_at
(character) Time http interaction recorded at
Methods
Public methods
Method new()
Create a new HTTPInteraction
object
Usage
HTTPInteraction$new(request, response, recorded_at)
Arguments
request
A
Request
class objectresponse
A
VcrResponse
class objectrecorded_at
(character) Time http interaction recorded at
Returns
A new HTTPInteraction
object
Method to_hash()
Create a hash from the HTTPInteraction object
Usage
HTTPInteraction$to_hash()
Returns
a named list
Method from_hash()
Create a HTTPInteraction object from a hash
Usage
HTTPInteraction$from_hash(hash)
Arguments
hash
a named list
Returns
a new HttpInteraction
object
Method clone()
The objects of this class are cloneable with this method.
Usage
HTTPInteraction$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Examples
## Not run:
# make the request
library(vcr)
url <- "https://hb.opencpu.org/post"
body <- list(foo = "bar")
cli <- crul::HttpClient$new(url = url)
res <- cli$post(body = body)
# build a Request object
(request <- Request$new("POST", uri = url,
body = body, headers = res$response_headers))
# build a VcrResponse object
(response <- VcrResponse$new(
res$status_http(),
res$response_headers,
res$parse("UTF-8"),
res$response_headers$status))
# make HTTPInteraction object
(x <- HTTPInteraction$new(request = request, response = response))
x$recorded_at
x$to_hash()
# make an HTTPInteraction from a hash with the object already made
x$from_hash(x$to_hash())
# Make an HTTPInteraction from a hash alone
my_hash <- x$to_hash()
HTTPInteraction$new()$from_hash(my_hash)
## End(Not run)
HTTPInteractionList class
Description
keeps track of all HTTPInteraction objects
Details
Private Methods
has_unused_interactions()
-
Are there any unused interactions? returns boolean
matching_interaction_index_for()
-
asdfadf
matching_used_interaction_for(request)
-
asdfadfs
interaction_matches_request(request, interaction)
-
Check if a request matches an interaction (logical)
from_hash()
-
Get a hash back.
request_summary(z)
-
Get a request summary (character)
response_summary(z)
-
Get a response summary (character)
Public fields
interactions
(list) list of interaction class objects
request_matchers
(character) vector of request matchers
allow_playback_repeats
whether to allow playback repeats
parent_list
A list for empty objects, see
NullList
used_interactions
(list) Interactions that have been used
Methods
Public methods
Method new()
Create a new HTTPInteractionList
object
Usage
HTTPInteractionList$new( interactions, request_matchers, allow_playback_repeats = FALSE, parent_list = NullList$new(), used_interactions = list() )
Arguments
interactions
(list) list of interaction class objects
request_matchers
(character) vector of request matchers
allow_playback_repeats
whether to allow playback repeats or not
parent_list
A list for empty objects, see
NullList
used_interactions
(list) Interactions that have been used. That is, interactions that are on disk in the current cassette, and a request has been made that matches that interaction
Returns
A new HTTPInteractionList
object
Method response_for()
Check if there's a matching interaction, returns a response object
Usage
HTTPInteractionList$response_for(request)
Arguments
request
The request from an object of class
HTTPInteraction
Method has_interaction_matching()
Check if has a matching interaction
Usage
HTTPInteractionList$has_interaction_matching(request)
Arguments
request
The request from an object of class
HTTPInteraction
Returns
logical
Method has_used_interaction_matching()
check if has used interactions matching a given request
Usage
HTTPInteractionList$has_used_interaction_matching(request)
Arguments
request
The request from an object of class
HTTPInteraction
Returns
logical
Method remaining_unused_interaction_count()
Number of unused interactions
Usage
HTTPInteractionList$remaining_unused_interaction_count()
Returns
integer
Method assert_no_unused_interactions()
Checks if there are no unused interactions left.
Usage
HTTPInteractionList$assert_no_unused_interactions()
Returns
various
Method clone()
The objects of this class are cloneable with this method.
Usage
HTTPInteractionList$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Examples
## Not run:
vcr_configure(
dir = tempdir(),
record = "once"
)
# make interactions
## make the request
### turn off mocking
crul::mock(FALSE)
url <- "https://hb.opencpu.org/post"
cli <- crul::HttpClient$new(url = url)
res <- cli$post(body = list(a = 5))
## request
(request <- Request$new("POST", url, list(a = 5), res$headers))
## response
(response <- VcrResponse$new(
res$status_http(),
res$response_headers,
res$parse("UTF-8"),
res$response_headers$status))
## make an interaction
(inter <- HTTPInteraction$new(request = request, response = response))
# make an interactionlist
(x <- HTTPInteractionList$new(
interactions = list(inter),
request_matchers = vcr_configuration()$match_requests_on
))
x$interactions
x$request_matchers
x$parent_list
x$parent_list$response_for()
x$parent_list$has_interaction_matching()
x$parent_list$has_used_interaction_matching()
x$parent_list$remaining_unused_interaction_count()
x$used_interactions
x$allow_playback_repeats
x$interactions
x$response_for(request)
## End(Not run)
Insert a cassette to record HTTP requests
Description
Insert a cassette to record HTTP requests
Usage
insert_cassette(
name,
record = NULL,
match_requests_on = NULL,
update_content_length_header = FALSE,
allow_playback_repeats = FALSE,
serialize_with = NULL,
persist_with = NULL,
preserve_exact_body_bytes = NULL,
re_record_interval = NULL,
clean_outdated_http_interactions = NULL
)
Arguments
name |
The name of the cassette. vcr will check this to ensure it
is a valid file name. Not allowed: spaces, file extensions, control
characters (e.g., |
record |
The record mode (default: |
match_requests_on |
List of request matchers
to use to determine what recorded HTTP interaction to replay. Defaults to
|
update_content_length_header |
(logical) Whether or
not to overwrite the |
allow_playback_repeats |
(logical) Whether or not to
allow a single HTTP interaction to be played back multiple times.
Default: |
serialize_with |
(character) Which serializer to use. Valid values are "yaml" (default) and "json". Note that you can have multiple cassettes with the same name as long as they use different serializers; so if you only want one cassette for a given cassette name, make sure to not switch serializers, or clean up files you no longer need. |
persist_with |
(character) Which cassette persister to use. Default: "file_system". You can also register and use a custom persister. |
preserve_exact_body_bytes |
(logical) Whether or not
to base64 encode the bytes of the requests and responses for
this cassette when serializing it. See also |
re_record_interval |
(integer) How frequently (in seconds) the
cassette should be re-recorded. default: |
clean_outdated_http_interactions |
(logical) Should outdated
interactions be recorded back to file? default: |
Details
Cassette names:
Should be meaningful so that it is obvious to you what test/function they relate to. Meaningful names are important so that you can quickly determine to what test file or test block a cassette belongs. Note that vcr cannot check that your cassette names are meaningful.
Should not be duplicated. Duplicated cassette names would lead to a test using the wrong cassette.
Should not have spaces. Spaces can lead to problems in using file paths.
Should not include a file extension. vcr handles file extensions for the user.
Should not have illegal characters that can lead to problems in using file paths:
/
,?
,<
,>
,\
,:
,*
,|
, and\"
Should not have control characters, e.g.,
\n
Should not have just dots, e.g.,
.
or..
Should not have Windows reserved words, e.g.,
com1
Should not have trailing dots
Should not be longer than 255 characters
vcr::check_cassette_names()
is meant to be run during your tests, from
a helper-*.R
file
inside the tests/testthat
directory. It only checks that cassette
names are not duplicated. Note that if you do need to have duplicated
cassette names you can do so by using the allowed_duplicates
parameter
in check_cassette_names()
. A helper function check_cassette_names()
runs inside insert_cassette()
that checks that
cassettes do not have: spaces, file extensions, unaccepted characters
(slashes).
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()
.
See Also
use_cassette()
, eject_cassette()
Examples
## Not run:
library(vcr)
library(crul)
vcr_configure(dir = tempdir())
webmockr::webmockr_allow_net_connect()
(x <- insert_cassette(name = "leo5"))
current_cassette()
x$new_recorded_interactions
x$previously_recorded_interactions()
cli <- crul::HttpClient$new(url = "https://hb.opencpu.org")
cli$get("get")
x$new_recorded_interactions # 1 interaction
x$previously_recorded_interactions() # empty
webmockr::stub_registry() # not empty
# very important when using inject_cassette: eject when done
x$eject() # same as eject_cassette("leo5")
x$new_recorded_interactions # same, 1 interaction
x$previously_recorded_interactions() # now not empty
## stub_registry now empty, eject() calls webmockr::disable(), which
## calls the disable method for each of crul and httr adadapters,
## which calls webmockr's remove_stubs() method for each adapter
webmockr::stub_registry()
# cleanup
unlink(file.path(tempdir(), "leo5.yml"))
## End(Not run)
The JSON serializer
Description
class with methods for serializing via jsonlite
Super class
vcr::Serializer
-> JSON
Methods
Public methods
Method new()
Create a new JSON
object
Usage
JSON$new(path = NULL)
Arguments
path
(character) full path to the yaml file
Returns
A new JSON
object
Method serialize()
Serializes the given hash using internal fxn write_json
Usage
JSON$serialize(x, path, bytes)
Arguments
x
(list) the object to serialize
path
(character) the file path
bytes
(logical) whether to preserve exact body bytes or not
Returns
(character) the json string to write to disk
Method deserialize()
Deserializes the content at the file path using jsonlite::fromJSON
Usage
JSON$deserialize(cassette)
Arguments
cassette
the current cassette object so it's properties can be retrieved
Returns
(list) the deserialized object, an R list
Method clone()
The objects of this class are cloneable with this method.
Usage
JSON$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Turn vcr on and off, check on/off status, and turn off for a given http call
Description
Turn vcr on and off, check on/off status, and turn off for a given http call
Usage
turned_off(..., ignore_cassettes = FALSE)
turn_on()
turned_on()
turn_off(ignore_cassettes = FALSE)
Arguments
... |
Any block of code to run, presumably an http request |
ignore_cassettes |
(logical) Controls what happens when a cassette is
inserted while vcr is turned off. If |
Details
Sometimes you may need to turn off vcr
, either for individual function
calls, individual test blocks, whole test files, or for the entire
package. The following attempts to break down all the options.
vcr
has the following four exported functions:
-
turned_off()
- Turns vcr off for the duration of a code block -
turn_off()
- Turns vcr off completely, so that it no longer handles every HTTP request -
turn_on()
- turns vcr on; the opposite ofturn_off()
-
turned_on()
- Asks if vcr is turned on, returns a boolean
Instead of using the above four functions, you could use environment
variables to achieve the same thing. This way you could enable/disable
vcr
in non-interactive environments such as continuous integration,
Docker containers, or running R non-interactively from the command line.
The full set of environment variables vcr
uses, all of which accept
only TRUE
or FALSE
:
-
VCR_TURN_OFF
: turn off vcr altogether; set toTRUE
to skip any vcr usage; default:FALSE
-
VCR_TURNED_OFF
: set theturned_off
internal package setting; this does not turn off vcr completely as doesVCR_TURN_OFF
does, but rather is looked at together withVCR_IGNORE_CASSETTES
-
VCR_IGNORE_CASSETTES
: set theignore_cassettes
internal package setting; this is looked at together withVCR_TURNED_OFF
turned_off
turned_off()
lets you temporarily make a real HTTP request without
completely turning vcr
off, unloading it, etc.
What happens internally is we turn off vcr
, run your code block, then
on exit turn vcr
back on - such that vcr
is only turned off for the
duration of your code block. Even if your code block errors, vcr
will
be turned back on due to use of on.exit(turn_on())
library(vcr) library(crul) turned_off({ con <- HttpClient$new(url = "https://httpbin.org/get") con$get() })
#> <crul response> #> url: https://httpbin.org/get #> request_headers: #> User-Agent: libcurl/7.54.0 r-curl/4.3 crul/0.9.0 #> Accept-Encoding: gzip, deflate #> Accept: application/json, text/xml, application/xml, */* #> response_headers: #> status: HTTP/1.1 200 OK #> date: Fri, 14 Feb 2020 19:44:46 GMT #> content-type: application/json #> content-length: 365 #> connection: keep-alive #> server: gunicorn/19.9.0 #> access-control-allow-origin: * #> access-control-allow-credentials: true #> status: 200
turn_off/turn_on
turn_off()
is different from turned_off()
in that turn_off()
is
not aimed at a single call block, but rather it turns vcr
off for the
entire package. turn_off()
does check first before turning vcr
off
that there is not currently a cassette in use. turn_off()
is meant to
make R ignore vcr::insert_cassette()
and vcr::use_cassette()
blocks
in your test suite - letting the code in the block run as if they were
not wrapped in vcr
code - so that all you have to do to run your tests
with cached requests/responses AND with real HTTP requests is toggle a
single R function or environment variable.
library(vcr) vcr_configure(dir = tempdir()) # real HTTP request works - vcr is not engaged here crul::HttpClient$new(url = "https://eu.httpbin.org/get")$get() # wrap HTTP request in use_cassette() - vcr is engaged here use_cassette("foo_bar", { crul::HttpClient$new(url = "https://eu.httpbin.org/get")$get() }) # turn off & ignore cassettes - use_cassette is ignored, real HTTP request made turn_off(ignore_cassettes = TRUE) use_cassette("foo_bar", { crul::HttpClient$new(url = "https://eu.httpbin.org/get")$get() }) # if you turn off and don't ignore cassettes, error thrown turn_off(ignore_cassettes = FALSE) use_cassette("foo_bar", { res2=crul::HttpClient$new(url = "https://eu.httpbin.org/get")$get() }) # vcr back on - now use_cassette behaves as before turn_on() use_cassette("foo_bar3", { res2=crul::HttpClient$new(url = "https://eu.httpbin.org/get")$get() })
turned_on
turned_on()
does what it says on the tin - it tells you if vcr
is
turned on or not.
library(vcr) turn_on() turned_on()
## [1] TRUE
turn_off()
## vcr turned off; see ?turn_on to turn vcr back on
turned_on()
## [1] FALSE
Environment variables
The VCR_TURN_OFF
environment variable can be used within R or on the
command line to turn off vcr
. For example, you can run tests for a
package that uses vcr
, but ignore any use_cassette
/insert_cassette
usage, by running this on the command line in the root of your package:
VCR_TURN_OFF=true Rscript -e "devtools::test()"
Or, similarly within R:
Sys.setenv(VCR_TURN_OFF = TRUE) devtools::test()
The VCR_TURNED_OFF
and VCR_IGNORE_CASSETTES
environment variables
can be used in combination to achieve the same thing as VCR_TURN_OFF
:
VCR_TURNED_OFF=true VCR_IGNORE_CASSETTES=true Rscript -e "devtools::test()"
Examples
## Not run:
vcr_configure(dir = tempdir())
turn_on()
turned_on()
turn_off()
# turn off for duration of a block
library(crul)
turned_off({
res <- HttpClient$new(url = "https://hb.opencpu.org/get")$get()
})
res
# turn completely off
turn_off()
library(webmockr)
crul::mock()
# HttpClient$new(url = "https://hb.opencpu.org/get")$get(verbose = TRUE)
turn_on()
## End(Not run)
Cassette persisters
Description
Keeps track of the cassette persisters in a hash-like object
Usage
persister_fetch(x = "FileSystem", file_name)
Details
There's only one option: FileSystem
Private Methods
persister_get()
-
Gets and sets a named persister
Public fields
persisters
(list) internal use, holds persister object
name
(character)
Methods
Public methods
Method new()
Create a new Persisters
object
Usage
Persisters$new(persisters = list(), name = "FileSystem")
Arguments
persisters
(list) a list
name
(character) Persister name, only option right now is "FileSystem"
Returns
A new Persisters
object
Method clone()
The objects of this class are cloneable with this method.
Usage
Persisters$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Examples
(aa <- Persisters$new())
aa$name
aa$persisters
yaml_serializer <- aa$persisters$new()
yaml_serializer
Are real http connections allowed?
Description
Are real http connections allowed?
Usage
real_http_connections_allowed()
Value
boolean, TRUE
if real HTTP requests allowed; FALSE
if not
Examples
real_http_connections_allowed()
vcr recording options
Description
vcr recording options
Details
Record modes dictate under what circumstances http requests/responses
are recorded to cassettes (disk). Set the recording mode with the
parameter record
in the use_cassette()
and insert_cassette()
functions.
once
The once
record mode will:
Replay previously recorded interactions.
Record new interactions if there is no cassette file.
Cause an error to be raised for new requests if there is a cassette file.
It is similar to the new_episodes
record mode, but will prevent new,
unexpected requests from being made (i.e. because the request URI
changed or whatever).
once
is the default record mode, used when you do not set one.
none
The none
record mode will:
Replay previously recorded interactions.
Cause an error to be raised for any new requests.
This is useful when your code makes potentially dangerous HTTP requests.
The none
record mode guarantees that no new HTTP requests will be
made.
new_episodes
The new_episodes
record mode will:
Record new interactions.
Replay previously recorded interactions.
It is similar to the once
record mode, but will always record new
interactions, even if you have an existing recorded one that is similar
(but not identical, based on the match_request_on
option).
all
The all
record mode will:
Record new interactions.
Never replay previously recorded interactions.
This can be temporarily used to force vcr to re-record a cassette (i.e. to ensure the responses are not out of date) or can be used when you simply want to log all HTTP requests.
The request of an HTTPInteraction
Description
object that handled all aspects of a request
Public fields
method
(character) http method
uri
(character) a uri
scheme
(character) scheme (http or https)
host
(character) host (e.g., stuff.org)
path
(character) path (e.g., foo/bar)
query
(character) query params, named list
body
(character) named list
headers
(character) named list
skip_port_stripping
(logical) whether to strip the port
hash
(character) a named list - internal use
opts
(character) options - internal use
disk
(logical) xx
fields
(various) request body details
output
(various) request output details, disk, memory, etc
policies
(various) http policies, used in httr2 only
Methods
Public methods
Method new()
Create a new Request
object
Usage
Request$new( method, uri, body, headers, opts, disk, fields, output, policies, skip_port_stripping = FALSE )
Arguments
method
(character) the HTTP method (i.e. head, options, get, post, put, patch or delete)
uri
(character) request URI
body
(character) request body
headers
(named list) request headers
opts
(named list) options internal use
disk
(boolean), is body a file on disk
fields
(various) post fields
output
(various) output details
policies
(various) http policies, used in httr2 only
skip_port_stripping
(logical) whether to strip the port. default:
FALSE
Returns
A new Request
object
Method to_hash()
Convert the request to a list
Usage
Request$to_hash()
Returns
list
Method from_hash()
Convert the request to a list
Usage
Request$from_hash(hash)
Arguments
hash
a list
Returns
a new Request
object
Method clone()
The objects of this class are cloneable with this method.
Usage
Request$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Examples
url <- "https://hb.opencpu.org/post"
body <- list(foo = "bar")
headers <- list(
`User-Agent` = "libcurl/7.54.0 r-curl/3.2 crul/0.5.2",
`Accept-Encoding` = "gzip, deflate",
Accept = "application/json, text/xml, application/xml, */*"
)
(x <- Request$new("POST", url, body, headers))
x$body
x$method
x$uri
x$host
x$path
x$headers
h <- x$to_hash()
x$from_hash(h)
request and response summary methods
Description
request and response summary methods
Usage
request_summary(request, request_matchers = "")
response_summary(response)
Arguments
request |
a Request object |
request_matchers |
(character) a vector of matchers.
Default: |
response |
a VcrResponse object |
Details
By default, method and uri are included
in the request summary - if body and/or headers are
specified in request_matchers
, then they are also
included
HTTP status code and response body are included in the response summary. The response body is truncated to a max of 80 characters
In response_summary()
we use gsub with useBytes=TRUE
to avoid
problems sometimes seen with multibyte strings - this shouldn't affect
your data/etc. as this is only for printing a summary of the response
Value
character string, of either request or response
Examples
# request
url <- "https://hb.opencpu.org"
body <- list(foo = "bar")
headers <- list(
`User-Agent` = "r-curl/3.2",
`Accept-Encoding` = "gzip, deflate",
Accept = "application/json"
)
(x <- Request$new("POST", url, body, headers))
request_summary(request = x)
request_summary(request = x, c('method', 'uri'))
request_summary(request = x, c('method', 'uri', 'body'))
request_summary(request = x, c('method', 'uri', 'headers'))
request_summary(request = x, c('method', 'uri', 'body', 'headers'))
# response
status <- list(status_code = 200, message = "OK",
explanation = "Request fulfilled, document follows")
headers <- list(
status = "HTTP/1.1 200 OK",
connection = "keep-alive",
date = "Tue, 24 Apr 2018 04:46:56 GMT"
)
response_body <-
"{\"args\": {\"q\": \"stuff\"}, \"headers\": {\"Accept\": \"text/html\"}}\n"
(x <- VcrResponse$new(status, headers,
response_body, "HTTP/1.1 200 OK"))
response_summary(x)
## with binary body
# path <- "tests/testthat/png_eg.rda"
# load(path)
# (x <- VcrResponse$new(status, headers, png_eg, "HTTP/1.1 200 OK"))
# response_summary(x)
vcr request matching
Description
There are a number of options, some of which are on by default, some of which can be used together, and some alone.
Details
To match previously recorded requests, vcr
has to try to match new
HTTP requests to a previously recorded one. By default, we match on HTTP
method (e.g., GET
) and URI (e.g., http://foo.com
), following Ruby’s
VCR gem.
You can customize how we match requests with one or more of the following options, some of which are on by default, some of which can be used together, and some alone.
-
method
: Use the method request matcher to match requests on the HTTP method (i.e. GET, POST, PUT, DELETE, etc). You will generally want to use this matcher. The method matcher is used (along with the uri matcher) by default if you do not specify how requests should match. -
uri
: Use the uri request matcher to match requests on the request URI. The uri matcher is used (along with the method matcher) by default if you do not specify how requests should match. -
host
: Use the host request matcher to match requests on the request host. You can use this (alone, or in combination with path) as an alternative to uri so that non-deterministic portions of the URI are not considered as part of the request matching. -
path
: Use the path request matcher to match requests on the path portion of the request URI. You can use this (alone, or in combination with host) as an alternative to uri so that non-deterministic portions of the URI -
query
: Use the query request matcher to match requests on the query string portion of the request URI. You can use this (alone, or in combination with others) as an alternative to uri so that non-deterministic portions of the URI are not considered as part of the request matching. -
body
: Use the body request matcher to match requests on the request body. -
headers
: Use the headers request matcher to match requests on the request headers.
You can set your own options by tweaking the match_requests_on
parameter in use_cassette()
:
library(vcr)
use_cassette(name = "foo_bar", { cli$post("post", body = list(a = 5)) }, match_requests_on = c('method', 'headers', 'body') )
Matching
headers
library(crul) library(vcr) cli <- crul::HttpClient$new("https://httpbin.org/get", headers = list(foo = "bar")) use_cassette(name = "nothing_new", { one <- cli$get() }, match_requests_on = 'headers' ) cli$headers$foo <- "stuff" use_cassette(name = "nothing_new", { two <- cli$get() }, match_requests_on = 'headers' ) one$request_headers two$request_headers
RequestHandler
Description
Base handler for http requests, deciding whether a request is stubbed, to be ignored, recordable, or unhandled
Details
Private Methods
request_type(request)
-
Get the request type
externally_stubbed()
-
just returns FALSE
should_ignore()
-
should we ignore the request, depends on request ignorer infrastructure that's not working yet
has_response_stub()
-
Check if there is a matching response stub in the http interaction list
get_stubbed_response()
-
Check for a response and get it
request_summary(request)
-
get a request summary
on_externally_stubbed_request(request)
-
on externally stubbed request do nothing
on_ignored_request(request)
-
on ignored request, do something
on_recordable_request(request)
-
on recordable request, record the request
on_unhandled_request(request)
-
on unhandled request, run UnhandledHTTPRequestError
Public fields
request_original
original, before any modification
request
the request, after any modification
vcr_response
holds VcrResponse object
stubbed_response
the stubbed response
cassette
the cassette holder
Methods
Public methods
Method new()
Create a new RequestHandler
object
Usage
RequestHandler$new(request)
Arguments
request
The request from an object of class
HttpInteraction
Returns
A new RequestHandler
object
Method handle()
Handle the request (request
given in $initialize()
)
Usage
RequestHandler$handle()
Returns
handles a request, outcomes vary
Method clone()
The objects of this class are cloneable with this method.
Usage
RequestHandler$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Examples
## Not run:
# record mode: once
vcr_configure(
dir = tempdir(),
record = "once"
)
data(crul_request)
crul_request$url$handle <- curl::new_handle()
crul_request
x <- RequestHandler$new(crul_request)
# x$handle()
# record mode: none
vcr_configure(
dir = tempdir(),
record = "none"
)
data(crul_request)
crul_request$url$handle <- curl::new_handle()
crul_request
insert_cassette("testing_record_mode_none", record = "none")
#file.path(vcr_c$dir, "testing_record_mode_none.yml")
x <- RequestHandlerCrul$new(crul_request)
# x$handle()
crul_request$url$url <- "https://api.crossref.org/works/10.1039/c8sm90002g/"
crul_request$url$handle <- curl::new_handle()
z <- RequestHandlerCrul$new(crul_request)
# z$handle()
eject_cassette("testing_record_mode_none")
## End(Not run)
RequestHandlerCrul
Description
Methods for the crul package, building on RequestHandler
Super class
vcr::RequestHandler
-> RequestHandlerCrul
Methods
Public methods
Inherited methods
Method clone()
The objects of this class are cloneable with this method.
Usage
RequestHandlerCrul$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Examples
## Not run:
vcr_configure(
dir = tempdir(),
record = "once"
)
data(crul_request)
crul_request$url$handle <- curl::new_handle()
crul_request
x <- RequestHandlerCrul$new(crul_request)
# x$handle()
# body matching
library(vcr)
library(crul)
vcr_configure(dir = tempdir(), log = TRUE,
log_opts = list(file = file.path(tempdir(), "vcr.log")))
cli <- HttpClient$new(url = "https://hb.opencpu.org")
## testing, same uri and method, changed body in 2nd block
use_cassette(name = "apple7", {
resp <- cli$post("post", body = list(foo = "bar"))
}, match_requests_on = c("method", "uri", "body"))
## should error, b/c record="once"
if (interactive()) {
use_cassette(name = "apple7", {
resp <- cli$post("post", body = list(foo = "bar"))
resp2 <- cli$post("post", body = list(hello = "world"))
}, match_requests_on = c("method", "uri", "body"))
}
cas <- insert_cassette(name = "apple7",
match_requests_on = c("method", "uri", "body"))
resp2 <- cli$post("post", body = list(foo = "bar"))
eject_cassette("apple7")
## testing, same body, changed method in 2nd block
if (interactive()) {
use_cassette(name = "apple8", {
x <- cli$post("post", body = list(hello = "world"))
}, match_requests_on = c("method", "body"))
use_cassette(name = "apple8", {
x <- cli$get("post", body = list(hello = "world"))
}, match_requests_on = c("method", "body"))
}
## testing, same body, changed uri in 2nd block
# use_cassette(name = "apple9", {
# x <- cli$post("post", body = list(hello = "world"))
# w <- cli$post("get", body = list(hello = "world"))
# }, match_requests_on = c("method", "body"))
# use_cassette(name = "apple9", {
# NOTHING HERE
# }, match_requests_on = c("method", "body"))
# unlink(file.path(vcr_configuration()$dir, "apple9.yml"))
## End(Not run)
RequestHandlerHttr
Description
Methods for the httr package, building on RequestHandler
Super class
vcr::RequestHandler
-> RequestHandlerHttr
Methods
Public methods
Inherited methods
Method new()
Create a new RequestHandlerHttr
object
Usage
RequestHandlerHttr$new(request)
Arguments
request
The request from an object of class
HttpInteraction
Returns
A new RequestHandlerHttr
object
Method clone()
The objects of this class are cloneable with this method.
Usage
RequestHandlerHttr$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Examples
## Not run:
vcr_configure(
dir = tempdir(),
record = "once"
)
# GET request
library(httr)
load("~/httr_req.rda")
req
x <- RequestHandlerHttr$new(req)
# x$handle()
# POST request
library(httr)
webmockr::httr_mock()
mydir <- file.path(tempdir(), "testing_httr")
invisible(vcr_configure(dir = mydir))
use_cassette(name = "testing2", {
res <- POST("https://hb.opencpu.org/post", body = list(foo = "bar"))
}, match_requests_on = c("method", "uri", "body"))
load("~/httr_req_post.rda")
insert_cassette("testing3")
httr_req_post
x <- RequestHandlerHttr$new(httr_req_post)
x
# x$handle()
self=x
## End(Not run)
RequestHandlerHttr2
Description
Methods for the httr2 package, building on RequestHandler
Super class
vcr::RequestHandler
-> RequestHandlerHttr2
Methods
Public methods
Inherited methods
Method new()
Create a new RequestHandlerHttr2
object
Usage
RequestHandlerHttr2$new(request)
Arguments
request
The request from an object of class
HttpInteraction
Returns
A new RequestHandlerHttr2
object
Method clone()
The objects of this class are cloneable with this method.
Usage
RequestHandlerHttr2$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Examples
## Not run:
# GET request
library(httr2)
req <- request("https://hb.opencpu.org/post") %>%
req_body_json(list(foo = "bar"))
x <- RequestHandlerHttr2$new(req)
# x$handle()
# POST request
library(httr2)
mydir <- file.path(tempdir(), "testing_httr2")
invisible(vcr_configure(dir = mydir))
req <- request("https://hb.opencpu.org/post") %>%
req_body_json(list(foo = "bar"))
use_cassette(name = "testing3", {
response <- req_perform(req)
}, match_requests_on = c("method", "uri", "body"))
use_cassette(name = "testing3", {
response2 <- req_perform(req)
}, match_requests_on = c("method", "uri", "body"))
## End(Not run)
Request ignorer
Description
request ignorer methods
Public fields
LOCALHOST_ALIASES
A constant with values: 'localhost', '127.0.0.1', and '0.0.0.0'
ignored_hosts
vector of ignored host URI's
Methods
Public methods
Method new()
Create a new RequestIgnorer
object
Usage
RequestIgnorer$new()
Returns
A new RequestIgnorer
object
Method ignore_request()
Will ignore any request for which the given function
returns TRUE
Usage
RequestIgnorer$ignore_request()
Returns
no return; defines request ignorer hook
Method ignore_localhost()
ignore all localhost values (localhost, 127.0.0.1, 0.0.0.0)
Usage
RequestIgnorer$ignore_localhost()
Returns
no return; sets to ignore all localhost aliases
Method ignore_localhost_value()
ignore a specific named localhost
Usage
RequestIgnorer$ignore_localhost_value(value)
Arguments
value
(character) A localhost value to ignore, e.g., 'localhost'
Returns
no return; defines request ignorer hook
Method ignore_hosts()
ignore any named host
Usage
RequestIgnorer$ignore_hosts(hosts)
Arguments
hosts
(character) vector of hosts to ignore
Returns
no return; adds host to ignore
Method should_be_ignored()
method to determine whether to ignore a request
Usage
RequestIgnorer$should_be_ignored(request)
Arguments
request
request to ignore
Returns
no return; defines request ignorer hook
Method clone()
The objects of this class are cloneable with this method.
Usage
RequestIgnorer$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
RequestMatcherRegistry
Description
handles request matchers
Public fields
registry
initialze registry list with a request, or leave empty
default_matchers
request matchers to use. default: method, uri
Methods
Public methods
Method new()
Create a new RequestMatcherRegistry object
Usage
RequestMatcherRegistry$new( registry = list(), default_matchers = list("method", "uri") )
Arguments
registry
initialze registry list with a request, or leave empty
default_matchers
request matchers to use. default: method, uri
Returns
A new RequestMatcherRegistry
object
Method register()
Register a custom matcher
Usage
RequestMatcherRegistry$register(name, func)
Arguments
name
matcher name
func
function that describes a matcher, should return a single boolean
Returns
no return; registers the matcher
Method register_built_ins()
Register all built in matchers
Usage
RequestMatcherRegistry$register_built_ins()
Returns
no return; registers all built in matchers
Method try_to_register_body_as_json()
Try to register body as JSON
Usage
RequestMatcherRegistry$try_to_register_body_as_json(r1, r2)
Arguments
r1, r2
Request class objects
Returns
no return; registers the matcher
Method clone()
The objects of this class are cloneable with this method.
Usage
RequestMatcherRegistry$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Note
r1=from new request; r2=from recorded interaction
Examples
## Not run:
(x <- RequestMatcherRegistry$new())
x$default_matchers
x$registry
## End(Not run)
Serializer class - base class for JSON/YAML serializers
Description
Serializer class - base class for JSON/YAML serializers
Serializer class - base class for JSON/YAML serializers
Public fields
file_extension
(character) A file extension
path
(character) full path to the yaml file
Methods
Public methods
Method new()
Create a new YAML object
Usage
Serializer$new(file_extension = NULL, path = NULL)
Arguments
file_extension
(character) A file extension
path
(character) path to the cassette, excluding the cassette directory and the file extension
Returns
A new YAML
object
Method serialize()
Serializes a hash - REPLACED BY YAML/JSON METHODS
Usage
Serializer$serialize(x, path, bytes)
Arguments
x
(list) the object to serialize
path
(character) the file path
bytes
(logical) whether to preserve exact body bytes or not
Returns
(character) the YAML or JSON string to write to disk
Method deserialize()
Serializes a file - REPLACED BY YAML/JSON METHODS
Usage
Serializer$deserialize()
Method clone()
The objects of this class are cloneable with this method.
Usage
Serializer$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Cassette serializers
Description
Keeps track of the cassette serializers in a hash-like object
Usage
serializer_fetch(x = "yaml", name)
Details
Private Methods
serialize_get()
-
Gets a named serializer. This is also run on
Serializers$new()
Public fields
serializers
(list) list of serializer names
name
(character) Name of a serializer. "yaml" (default) or "json"
Methods
Public methods
Method new()
Create a new Serializers object
Usage
Serializers$new(serializers = list(), name = "yaml")
Arguments
serializers
(list) list of serializer names
name
(character) Name of a serializer. "yaml" (default) or "json"
Returns
A new Serializers
object
Method clone()
The objects of this class are cloneable with this method.
Usage
Serializers$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Examples
## Not run:
(aa <- Serializers$new())
aa$name
aa$serializers
yaml_serializer <- aa$serializers$new()
yaml_serializer
x <- Serializers$new(name = "json")
x$serializers$new()
json_serializer <- x$serializers$new()
json_serializer
## End(Not run)
Skip tests if vcr is off
Description
Custom testthat skipper to skip tests if vcr is turned off via the
environment variable VCR_TURN_OFF
.
Usage
skip_if_vcr_off()
Details
This might be useful if your test will fail with real requests: when the cassette was e.g. edited (a real request produced a 200 status code but you made it a 502 status code for testing the behavior of your code when the API errors) or if the tests are very specific (e.g. testing a date was correctly parsed, but making a real request would produce a different date).
Value
Nothing, skip test.
See Also
split string every N characters
Description
split string every N characters
Usage
str_splitter(str, length)
Arguments
str |
(character) a string |
length |
(integer) number of characters to split by |
Examples
## Not run:
str = "XOVEWVJIEWNIGOIWENVOIWEWVWEW"
str_splitter(str, 5)
str_splitter(str, 5L)
## End(Not run)
UnhandledHTTPRequestError
Description
Handle http request errors
Usage
vcr_last_error()
Details
How this error class is used:
If record="once"
we trigger this.
Users can use vcr in the context of both use_cassette()
and insert_cassette()
For the former, all requests go through the call_block But for the latter, requests go through webmockr.
Where is one place where we can put UnhandledHTTPRequestError that will handle both use_cassette and insert_cassette?
Error situations where this is invoked
-
record=once
AND there's a new request that doesn't match the one in the cassette on diskin webmockr: if no stub found and there are recorded interactions on the cassette, and record = once, then error with UnhandledHTTPRequestError
but if record != once, then allow it, unless record == none
others?
Public fields
request
a Request object
cassette
a cassette name
Methods
Public methods
Method new()
Create a new UnhandledHTTPRequestError
object
Usage
UnhandledHTTPRequestError$new(request)
Arguments
request
(Request) a Request object
Returns
A new UnhandledHTTPRequestError
object
Method run()
Run unhandled request handling
Usage
UnhandledHTTPRequestError$run()
Returns
various
Method construct_message()
Construct and execute stop message for why request failed
Usage
UnhandledHTTPRequestError$construct_message()
Returns
a stop message
Method request_description()
construct request description
Usage
UnhandledHTTPRequestError$request_description()
Returns
character
Method current_matchers()
get current request matchers
Usage
UnhandledHTTPRequestError$current_matchers()
Returns
character
Method match_request_on_headers()
are headers included in current matchers?
Usage
UnhandledHTTPRequestError$match_request_on_headers()
Returns
logical
Method match_request_on_body()
is body includled in current matchers?
Usage
UnhandledHTTPRequestError$match_request_on_body()
Returns
logical
Method formatted_headers()
get request headers
Usage
UnhandledHTTPRequestError$formatted_headers()
Returns
character
Method cassettes_description()
construct description of current or lack thereof cassettes
Usage
UnhandledHTTPRequestError$cassettes_description()
Returns
character
Method cassettes_list()
cassette details
Usage
UnhandledHTTPRequestError$cassettes_list()
Returns
character
Method get_help()
get help message for non-verbose error
Usage
UnhandledHTTPRequestError$get_help()
Returns
character
Method formatted_suggestions()
make suggestions for what to do
Usage
UnhandledHTTPRequestError$formatted_suggestions()
Returns
character
Method format_bullet_point()
add bullet point to beginning of a line
Usage
UnhandledHTTPRequestError$format_bullet_point(lines, index)
Arguments
lines
(character) vector of strings
index
(integer) a number
Returns
character
Method format_foot_note()
make a foot note
Usage
UnhandledHTTPRequestError$format_foot_note(url, index)
Arguments
url
(character) a url
index
(integer) a number
Returns
character
Method suggestion_for()
get a suggestion by key
Usage
UnhandledHTTPRequestError$suggestion_for(key)
Arguments
key
(character) a character string
Returns
character
Method suggestions()
get all suggestions
Usage
UnhandledHTTPRequestError$suggestions()
Returns
list
Method no_cassette_suggestions()
get all no cassette suggestions
Usage
UnhandledHTTPRequestError$no_cassette_suggestions()
Returns
list
Method record_mode_suggestion()
get the appropriate record mode suggestion
Usage
UnhandledHTTPRequestError$record_mode_suggestion()
Returns
character
Method has_used_interaction_matching()
are there any used interactions
Usage
UnhandledHTTPRequestError$has_used_interaction_matching()
Returns
logical
Method match_requests_on_suggestion()
match requests on suggestion
Usage
UnhandledHTTPRequestError$match_requests_on_suggestion()
Returns
list
Method clone()
The objects of this class are cloneable with this method.
Usage
UnhandledHTTPRequestError$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Examples
## Not run:
vcr_configure(dir = tempdir())
cassettes()
insert_cassette("turtle")
request <- Request$new("post", 'https://hb.opencpu.org/post?a=5',
"", list(foo = "bar"))
err <- UnhandledHTTPRequestError$new(request)
err$request_description()
err$current_matchers()
err$match_request_on_headers()
err$match_request_on_body()
err$formatted_headers()
cat(err$formatted_headers(), "\n")
cat(err$cassettes_description(), "\n")
cat(err$cassettes_list(), "\n")
err$formatted_suggestions()
cat(err$format_bullet_point('foo bar', 1), "\n")
err$suggestion_for("use_new_episodes")
err$suggestions()
err$no_cassette_suggestions()
err$record_mode_suggestion()
err$has_used_interaction_matching()
err$match_requests_on_suggestion()
# err$construct_message()
# cleanup
eject_cassette("turtle")
unlink(tempdir())
## End(Not run)
## Not run:
# vcr_last_error()
## End(Not run)
Use a cassette to record HTTP requests
Description
Use a cassette to record HTTP requests
Usage
use_cassette(
name,
...,
record = NULL,
match_requests_on = NULL,
update_content_length_header = FALSE,
allow_playback_repeats = FALSE,
serialize_with = NULL,
persist_with = NULL,
preserve_exact_body_bytes = NULL,
re_record_interval = NULL,
clean_outdated_http_interactions = NULL
)
Arguments
name |
The name of the cassette. vcr will check this to ensure it
is a valid file name. Not allowed: spaces, file extensions, control
characters (e.g., |
... |
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 |
record |
The record mode (default: |
match_requests_on |
List of request matchers
to use to determine what recorded HTTP interaction to replay. Defaults to
|
update_content_length_header |
(logical) Whether or
not to overwrite the |
allow_playback_repeats |
(logical) Whether or not to
allow a single HTTP interaction to be played back multiple times.
Default: |
serialize_with |
(character) Which serializer to use. Valid values are "yaml" (default) and "json". Note that you can have multiple cassettes with the same name as long as they use different serializers; so if you only want one cassette for a given cassette name, make sure to not switch serializers, or clean up files you no longer need. |
persist_with |
(character) Which cassette persister to use. Default: "file_system". You can also register and use a custom persister. |
preserve_exact_body_bytes |
(logical) Whether or not
to base64 encode the bytes of the requests and responses for
this cassette when serializing it. See also |
re_record_interval |
(integer) How frequently (in seconds) the
cassette should be re-recorded. default: |
clean_outdated_http_interactions |
(logical) Should outdated
interactions be recorded back to file? default: |
Details
A run down of the family of top level vcr functions
-
use_cassette
Initializes a cassette. Returns the inserted cassette. -
insert_cassette
Internally used withinuse_cassette
-
eject_cassette
ejects the current cassette. The cassette will no longer be used. In addition, any newly recorded HTTP interactions will be written to disk.
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 ejectedwhen 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 backwhenever 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 ofon.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()
, eject_cassette()
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 it's behavior
two <- use_cassette("none_eg", (res2 <- conn$get("get")), record = "none")
two; res2
## End(Not run)
Setup vcr for a package
Description
Setup vcr for a package
Usage
use_vcr(dir = ".", verbose = TRUE)
Arguments
dir |
(character) path to package root. default's to current directory |
verbose |
(logical) print progress messages. default: |
Details
Sets a mimimum vcr version, which is usually the latest (stable) version on CRAN. You can of course easily remove or change the version requirement yourself after running this function.
Value
only messages about progress, returns invisible()
Global Configuration Options
Description
Configurable options that define vcr's default behavior.
Usage
vcr_configure(...)
vcr_configure_reset()
vcr_configuration()
vcr_config_defaults()
Arguments
... |
configuration settings used to override defaults. See below for a complete list of valid arguments. |
Configurable settings
vcr options
File locations
-
dir
Cassette directory -
write_disk_path
(character) path to write files to for any requests that write responses to disk. by default this parameter isNULL
. For testing a package, you'll probably want this path to be in yourtests/
directory, perhaps next to your cassettes directory, e.g., where your cassettes are intests/fixtures
, your files from requests that write to disk are intests/files
. If you want to ignore these files in your installed package, add them to.Rinstignore
. If you want these files ignored on build then add them to.Rbuildignore
(though if you do, tests that depend on these files probably will not work because they won't be found; so you'll likely have to skip the associated tests as well).
Contexts
-
turned_off
(logical) VCR is turned on by default. Default:FALSE
-
allow_unused_http_interactions
(logical) Default:TRUE
-
allow_http_connections_when_no_cassette
(logical) Determines how vcr treats HTTP requests that are made when no vcr cassette is in use. WhenTRUE
, requests made when there is no vcr cassette in use will be allowed. WhenFALSE
(default), an UnhandledHTTPRequestError error will be raised for any HTTP request made when there is no cassette in use
Filtering
-
ignore_hosts
(character) Vector of hosts to ignore. e.g., localhost, or google.com. These hosts are ignored and real HTTP requests allowed to go through -
ignore_localhost
(logical) Default:FALSE
-
ignore_request
List of requests to ignore. NOT USED RIGHT NOW, sorry -
filter_sensitive_data
named list of values to replace. Format is:list(thing_to_replace_it_with = thing_to_replace)
We replace all instances of
thing_to_replace
withthing_to_replace_it_with
. Usesgsub()
internally, withfixed=TRUE
; so does exact matches. Before recording (writing to a cassette) we do the replacement and then when reading from the cassette we do the reverse replacement to get back to the real data. Before record replacement happens in internal functionwrite_interactions()
, while before playback replacement happens in internal functionYAML$deserialize()
-
filter_sensitive_data_regex
named list of values to replace. Followsfilter_sensitive_data
format, except usesfixed=FALSE
in thegsub()
function call; this means that the value inthing_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 tofilter_sensitive_data
instructing vcr with what value to replace the real value of the request header. -
filter_response_headers
(named 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 tofilter_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 tofilter_sensitive_data
instructing vcr with what value to replace the real value of the query parameter.
Errors
-
verbose_errors
Do you want more verbose errors or less verbose errors when cassette recording/usage fails? Default isFALSE
, that is, less verbose errors. IfTRUE
, error messages will include more details about what went wrong and suggest possible solutions. For testing in an interactive R session, ifverbose_errors=FALSE
, you can runvcr_last_error()
to get the full error. If in non-interactive mode, which most users will be in when running the entire test suite for a package, you can set an environment variable (VCR_VERBOSE_ERRORS
) to toggle this setting (e.g.,Sys.setenv(VCR_VERBOSE_ERRORS=TRUE); devtools::test()
)
Internals
-
cassettes
(list) don't use -
linked_context
(logical) linked context -
uri_parser
the uri parser, default:crul::url_parse()
Logging
-
log
(logical) should we log important vcr things? Default:FALSE
-
log_opts
(list) Additional logging options:'file' either
"console"
or a file path to log to'log_prefix' default: "Cassette". We insert the cassette name after that prefix, then the rest of the message.
More to come...
Cassette Options
These settings can be configured globally, using vcr_configure()
, or
locally, using either use_cassette()
or insert_cassette()
. Global
settings are applied to all cassettes but are overridden by settings
defined locally for individual cassettes.
-
record
(character) One of 'all', 'none', 'new_episodes', or 'once'. See recording -
match_requests_on
vector of matchers. Default: (method
,uri
) See request-matching for details. -
serialize_with
: (character) "yaml" or "json". Note that you can have multiple cassettes with the same name as long as they use different serializers; so if you only want one cassette for a given cassette name, make sure to not switch serializers, or clean up files you no longer need. -
json_pretty
: (logical) want JSON to be newline separated to be easier to read? Or remove newlines to save disk space? default: FALSE -
persist_with
(character) only option is "FileSystem" -
preserve_exact_body_bytes
(logical) preserve exact body bytes for -
re_record_interval
(numeric) When given, the cassette will be re-recorded at the given interval, in seconds. -
clean_outdated_http_interactions
(logical) Should outdated interactions be recorded back to file. Default:FALSE
-
quiet
(logical) Suppress any messages from both vcr and webmockr. Default:TRUE
-
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
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)
# logging
vcr_configure(dir = tempdir(), log = TRUE,
log_opts = list(file = file.path(tempdir(), "vcr.log")))
vcr_configure(dir = tempdir(), log = TRUE, log_opts = list(file = "console"))
vcr_configure(dir = tempdir(), log = TRUE,
log_opts = list(
file = file.path(tempdir(), "vcr.log"),
log_prefix = "foobar"
))
vcr_configure(dir = tempdir(), log = FALSE)
# 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>")
)
vcr log file setup
Description
vcr log file setup
Usage
vcr_log_file(file, overwrite = TRUE)
vcr_log_info(message, include_date = TRUE)
Arguments
file |
(character) a file path, required |
overwrite |
(logical) whether or not to overwrite the file at
'file' if it already exists. Default: |
message |
(character) a message to log |
include_date |
(logical) include date and time in each log entry.
Default: |
Examples
# user workflow
vcr_configuration()
logfile <- file.path(tempdir(), "vcr.log")
vcr_configure(dir = tempdir(), log = TRUE, log_opts = list(file = logfile))
readLines(logfile) # empty
# log messages
vcr_log_info("hello world!")
readLines(logfile)
vcr_log_info("foo bar")
readLines(logfile)
## many messages
vcr_log_info(c("brown cow", "blue horse"))
readLines(logfile)
vcr_log_info(c("brown cow", "blue horse", "green goat"))
readLines(logfile)
# standalone workflow
# set a file to log to
vcr_log_file((f <- tempfile()))
readLines(f) # empty
# log messages
vcr_log_info("hello world!")
readLines(logfile)
vcr_log_info("foo bar")
readLines(logfile)
# cleanup
unlink(f)
unlink(logfile)
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 component. each character string
gets added on to the path, e.g., |
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")
}
The response of an HTTPInteraction
Description
Custom vcr http response object
Public fields
status
the status of the response
headers
the response headers
body
the response body
http_version
the HTTP version
opts
a list
adapter_metadata
Additional metadata used by a specific VCR adapter
hash
a list
disk
a boolean
Methods
Public methods
Method new()
Create a new VcrResponse object
Usage
VcrResponse$new( status, headers, body, http_version, opts, adapter_metadata = NULL, disk )
Arguments
status
the status of the response
headers
the response headers
body
the response body
http_version
the HTTP version
opts
a list
adapter_metadata
Additional metadata used by a specific VCR adapter
disk
boolean, is body a file on disk
Returns
A new VcrResponse
object
Method print()
print method for the VcrResponse
class
Usage
VcrResponse$print(x, ...)
Arguments
x
self
...
ignored
Method to_hash()
Create a hash
Usage
VcrResponse$to_hash()
Returns
a list
Method from_hash()
Get a hash back to an R list
Usage
VcrResponse$from_hash(hash)
Arguments
hash
a list
Returns
an VcrResponse
object
Method update_content_length_header()
Updates the Content-Length response header so that it is accurate for the response body
Usage
VcrResponse$update_content_length_header()
Returns
no return; modifies the content length header
Method get_header()
Get a header by name
Usage
VcrResponse$get_header(key)
Arguments
key
(character) header name to get
Returns
the header value (if it exists)
Method edit_header()
Edit a header
Usage
VcrResponse$edit_header(key, value = NULL)
Arguments
key
(character) header name to edit
value
(character) new value to assign
Returns
no return; modifies the header in place
Method delete_header()
Delete a header
Usage
VcrResponse$delete_header(key)
Arguments
key
(character) header name to delete
Returns
no return; the header is deleted if it exists
Method content_encoding()
Get the content-encoding header value
Usage
VcrResponse$content_encoding()
Returns
(character) the content-encoding value
Method is_compressed()
Checks if the encoding is one of "gzip" or "deflate"
Usage
VcrResponse$is_compressed()
Returns
logical
Method clone()
The objects of this class are cloneable with this method.
Usage
VcrResponse$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Examples
## Not run:
vcr_configure(dir = tempdir())
# basic example of VcrResponse use
url <- "https://google.com"
(cli <- crul::HttpClient$new(url = url))
(res <- cli$get("get", query = list(q = "stuff")))
(x <- VcrResponse$new(res$status_http(), res$response_headers,
res$parse("UTF-8"), res$response_headers$status))
x$body
x$status
x$headers
x$http_version
x$to_hash()
x$from_hash(x$to_hash())
# update content length header
## example 1
### content-length header present, but no change
url <- "https://fishbase.ropensci.org"
cli <- crul::HttpClient$new(url = url, headers = list(`Accept-Encoding` = '*'))
res <- cli$get("species/34")
x <- VcrResponse$new(res$status_http(), res$response_headers,
res$parse("UTF-8"), res$response_headers$status)
x$headers$`content-length`
x$update_content_length_header()
x$headers$`content-length`
## example 2
### no content-length header b/c a transfer-encoding header is included
### and no content-length header allowed if transfer-encoding header
### used (via rfc7230)
url <- "https://google.com"
cli <- crul::HttpClient$new(url = url)
res <- cli$get()
x <- VcrResponse$new(res$status_http(), res$response_headers,
rawToChar(res$content), res$response_headers$status)
x$headers$`content-length` # = NULL
x$update_content_length_header() # no change, b/c header doesn't exist
x$headers$`content-length` # = NULL
## example 3
### content-length header present, and does change
body <- " Hello World "
x <- VcrResponse$new(200, list('content-length'=nchar(body)),
body, "HTTP/2")
x$headers$`content-length` # = 13
x$body <- gsub("^\\s|\\s$", "", x$body)
x$headers$`content-length` # = 13
x$update_content_length_header()
x$headers$`content-length` # = 11
# check if body is compressed
url <- "https://fishbase.ropensci.org"
(cli <- crul::HttpClient$new(url = url))
(res <- cli$get("species/3"))
res$response_headers
(x <- VcrResponse$new(res$status_http(), res$response_headers,
res$parse("UTF-8"), res$response_headers$status))
x$content_encoding()
x$is_compressed()
# with disk
url <- "https://google.com"
(cli <- crul::HttpClient$new(url = url))
f <- tempfile()
(res <- cli$get("get", query = list(q = "stuff"), disk = f))
(x <- VcrResponse$new(res$status_http(), res$response_headers,
f, res$response_headers$status, disk = TRUE))
## End(Not run)
The YAML serializer
Description
class with methods for serializing via the yaml package
Super class
vcr::Serializer
-> YAML
Methods
Public methods
Method new()
Create a new YAML object
Usage
YAML$new(path = NULL)
Arguments
path
(character) path to the cassette, excluding the cassette directory and the file extension
Returns
A new YAML
object
Method serialize()
Serializes the given hash using internal fxn write_yaml
Usage
YAML$serialize(x, path, bytes)
Arguments
x
(list) the object to serialize
path
(character) the file path
bytes
(logical) whether to preserve exact body bytes or not
Returns
(character) the YAML string to write to disk
Method deserialize()
Deserializes the content at the path using yaml::yaml.load_file
Usage
YAML$deserialize(cassette)
Arguments
cassette
the current cassette object so it's properties can be retrieved
Returns
(list) the deserialized object, an R list
Method clone()
The objects of this class are cloneable with this method.
Usage
YAML$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.