1
0
mirror of https://github.com/kevin1024/vcrpy.git synced 2025-12-09 01:03:24 +00:00

Make changes from b1cdd50e9b compatible with requests1.x; Update Readme.md with description of before_record_response

This commit is contained in:
Ivan Malison
2014-09-20 10:55:03 -07:00
parent dc249b0965
commit 83211a1887
2 changed files with 61 additions and 19 deletions

View File

@@ -176,13 +176,13 @@ with vcr.use_cassette('fixtures/vcr_cassettes/synopsis.yaml') as cass:
The `Cassette` object exposes the following properties which I consider part of The `Cassette` object exposes the following properties which I consider part of
the API. The fields are as follows: the API. The fields are as follows:
* `requests`: A list of vcr.Request objects containing the requests made while * `requests`: A list of vcr.Request objects corresponding to the http requests
this cassette was being used, ordered by the order that the request was made. that were made during the recording of the cassette. The requests appear in the
order that they were originally processed.
* `responses`: A list of the responses made. * `responses`: A list of the responses made.
* `play_count`: The number of times this cassette has had a response played * `play_count`: The number of times this cassette has played back a response.
back * `all_played`: A boolean indicating whether all the responses have been
* `all_played`: A boolean indicates whether all the responses have been played back.
played back
* `responses_of(request)`: Access the responses that match a given request * `responses_of(request)`: Access the responses that match a given request
The `Request` object has the following properties: The `Request` object has the following properties:
@@ -215,7 +215,7 @@ Finally, register your class with VCR to use your new serializer.
```python ```python
import vcr import vcr
BogoSerializer(object): class BogoSerializer(object):
""" """
Must implement serialize() and deserialize() methods Must implement serialize() and deserialize() methods
""" """
@@ -293,12 +293,12 @@ with my_vcr.use_cassette('test.yml', filter_query_parameters=['api_key']):
requests.get('http://api.com/getdata?api_key=secretstring') requests.get('http://api.com/getdata?api_key=secretstring')
``` ```
### Custom request filtering ### Custom Request filtering
If neither of these covers your use case, you can register a callback that will If neither of these covers your request filtering needs, you can register a callback
manipulate the HTTP request before adding it to the cassette. Use the that will manipulate the HTTP request before adding it to the cassette. Use the
`before_record` configuration option to so this. Here is an `before_record` configuration option to so this. Here is an example that will
example that will never record requests to the /login endpoint. never record requests to the /login endpoint.
```python ```python
def before_record_cb(request): def before_record_cb(request):
@@ -312,6 +312,40 @@ with my_vcr.use_cassette('test.yml'):
# your http code here # your http code here
``` ```
You can also mutate the response using this callback. For example, you could
remove all query parameters from any requests to the `'/login'` path.
```python
def scrub_login_request(request):
if request.path == '/login':
request.uri, _ = urllib.splitquery(response.uri)
return request
my_vcr = vcr.VCR(
before_record=scrub_login_request,
)
with my_vcr.use_cassette('test.yml'):
# your http code here
```
### Custom Response Filtering
VCR.py also suports response filtering with the `before_record_response` keyword
argument. It's usage is similar to that of `before_record`:
```python
def scrub_string(string, replacement=''):
def before_record_reponse(response):
return response['body']['string] = response['body']['string].replace(string, replacement)
return scrub_string
my_vcr = vcr.VCR(
before_record=scrub_string(settings.USERNAME, 'username'),
)
with my_vcr.use_cassette('test.yml'):
# your http code here
```
## Ignore requests ## Ignore requests
If you would like to completely ignore certain requests, you can do it in a If you would like to completely ignore certain requests, you can do it in a
@@ -335,7 +369,7 @@ to `brew install libyaml` [[Homebrew](http://mxcl.github.com/homebrew/)])
## Ruby VCR compatibility ## Ruby VCR compatibility
I'm not trying to match the format of the Ruby VCR YAML files. Cassettes VCR.py does not aim to match the format of the Ruby VCR YAML files. Cassettes
generated by Ruby's VCR are not compatible with VCR.py. generated by Ruby's VCR are not compatible with VCR.py.
## Running VCR's test suite ## Running VCR's test suite
@@ -356,7 +390,7 @@ installed.
Also, in order for the boto tests to run, you will need an AWS key. Refer to Also, in order for the boto tests to run, you will need an AWS key. Refer to
the [boto the [boto
documentation](http://boto.readthedocs.org/en/latest/getting_started.html) for documentation](http://boto.readthedocs.org/en/latest/getting_started.html) for
how to set this up. I have marked the boto tests as optional in Travis so you how to set this up. I have marked the boto tests as optional in Travis so you
don't have to worry about them failing if you submit a pull request. don't have to worry about them failing if you submit a pull request.
@@ -423,6 +457,8 @@ API in version 1.0.x
## Changelog ## Changelog
* 1.1.0 Add `before_record_response`. Fix several bugs related to the context
management of cassettes.
* 1.0.3: Fix an issue with requests 2.4 and make sure case sensitivity is * 1.0.3: Fix an issue with requests 2.4 and make sure case sensitivity is
consistent across python versions consistent across python versions
* 1.0.2: Fix an issue with requests 2.3 * 1.0.2: Fix an issue with requests 2.3

View File

@@ -127,22 +127,28 @@ class CassettePatcherBuilder(object):
(cpool, 'VerifiedHTTPSConnection', VCRRequestsHTTPSConnection), (cpool, 'VerifiedHTTPSConnection', VCRRequestsHTTPSConnection),
(cpool, 'VerifiedHTTPSConnection', VCRRequestsHTTPSConnection), (cpool, 'VerifiedHTTPSConnection', VCRRequestsHTTPSConnection),
(cpool, 'HTTPConnection', VCRRequestsHTTPConnection), (cpool, 'HTTPConnection', VCRRequestsHTTPConnection),
(cpool, 'HTTPConnection', VCRHTTPConnection), (cpool, 'HTTPSConnection', VCRRequestsHTTPSConnection),
(cpool.HTTPConnectionPool, 'ConnectionCls', VCRRequestsHTTPConnection), (cpool.HTTPConnectionPool, 'ConnectionCls', VCRRequestsHTTPConnection),
(cpool.HTTPSConnectionPool, 'ConnectionCls', VCRRequestsHTTPSConnection), (cpool.HTTPSConnectionPool, 'ConnectionCls', VCRRequestsHTTPSConnection),
# These handle making sure that sessions only use the # These handle making sure that sessions only use the
# connections of the appropriate type. # connections of the appropriate type.
(cpool.HTTPConnectionPool, '_get_conn', self._patched_get_conn(cpool.HTTPConnectionPool)),
(cpool.HTTPSConnectionPool, '_get_conn', self._patched_get_conn(cpool.HTTPSConnectionPool)),
) )
mock_triples += ((cpool.HTTPConnectionPool, '_get_conn',
self._patched_get_conn(cpool.HTTPConnectionPool,
lambda : cpool.HTTPConnection)),
(cpool.HTTPSConnectionPool, '_get_conn',
self._patched_get_conn(cpool.HTTPSConnectionPool,
lambda : cpool.HTTPSConnection)))
return self._build_patchers_from_mock_triples(mock_triples) return self._build_patchers_from_mock_triples(mock_triples)
def _patched_get_conn(self, connection_pool_class): def _patched_get_conn(self, connection_pool_class, connection_class_getter):
get_conn = connection_pool_class._get_conn get_conn = connection_pool_class._get_conn
@functools.wraps(get_conn) @functools.wraps(get_conn)
def patched_get_conn(pool, timeout=None): def patched_get_conn(pool, timeout=None):
connection = get_conn(pool, timeout) connection = get_conn(pool, timeout)
while not isinstance(connection, pool.ConnectionCls): connection_class = pool.ConnectionCls if hasattr(pool, 'ConnectionCls') \
else connection_class_getter()
while not isinstance(connection, connection_class):
connection = get_conn(pool, timeout) connection = get_conn(pool, timeout)
return connection return connection
return patched_get_conn return patched_get_conn