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:
64
README.md
64
README.md
@@ -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
|
||||||
|
|||||||
16
vcr/patch.py
16
vcr/patch.py
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user