diff --git a/README.md b/README.md index 72ddcae..82d8109 100644 --- a/README.md +++ b/README.md @@ -310,6 +310,21 @@ with my_vcr.use_cassette('test.yml'): # your http code here ``` +## Ignore requests + +If you would like to completely ignore certain requests, you can do it in a +few ways: + + * Set the `ignore_localhost` option equal to True. This will not record any + requests sent to (or responses from) localhost, 127.0.0.1, or 0.0.0.0. + * Set the `ignore_hosts` configuration option to a list of hosts to ignore + * Add a `before_record` callback that returns None for requests you want to + ignore + +Requests that are ignored by VCR will not be saved in a cassette, nor played +back from a cassette. VCR will completely ignore those requests as if it +didn't notice them at all, and they will continue to hit the server as if VCR +were not there. ## Installation @@ -398,10 +413,10 @@ The migration *should* only modify cassettes using the old 0.x format. ## Changelog * 1.0.0 (in development) - _BACKWARDS INCOMPATIBLE_: Please see the 'upgrade' section in the README. Add support for filtering sensitive data from - requests (thanks to @mshytikov), bump supported Python3 version to 3.4, fix - some bugs with Boto support (thanks @marusich), fix error with URL field - capitalization in README (thanks @simon-weber), added some log messages to - help with debugging. + requests (thanks to @mshytikov), support for ignoring requests to certain + hosts, bump supported Python3 version to 3.4, fix some bugs with Boto support + (thanks @marusich), fix error with URL field capitalization in README (thanks + @simon-weber), added some log messages to help with debugging. * 0.7.0: VCR.py now supports Python 3! (thanks @asundg) Also I refactored the stub connections quite a bit to add support for the putrequest and putheader calls. This version also adds support for httplib2 (thanks diff --git a/setup.py b/setup.py index 6fef312..8fb8995 100644 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ setup( }, install_requires=['PyYAML', 'contextdecorator', 'six'], license='MIT', - tests_require=['pytest', 'mock'], + tests_require=['pytest', 'mock', 'pytest-localserver'], cmdclass={'test': PyTest}, classifiers=[ 'Development Status :: 4 - Beta', diff --git a/tox.ini b/tox.ini index 905a258..e3a1e2a 100644 --- a/tox.ini +++ b/tox.ini @@ -31,6 +31,7 @@ commands = deps = mock pytest + pytest-localserver PyYAML [testenv:py26oldrequests] @@ -38,6 +39,7 @@ basepython = python2.6 deps = mock pytest + pytest-localserver PyYAML requests==1.2.3 @@ -46,6 +48,7 @@ basepython = python2.7 deps = mock pytest + pytest-localserver PyYAML requests==1.2.3 @@ -54,6 +57,7 @@ basepython = python3.3 deps = mock pytest + pytest-localserver PyYAML requests==1.2.3 @@ -62,6 +66,7 @@ basepython = python3.4 deps = mock pytest + pytest-localserver PyYAML requests==1.2.3 @@ -70,6 +75,7 @@ basepython = pypy deps = mock pytest + pytest-localserver PyYAML requests==1.2.3 @@ -78,6 +84,7 @@ basepython = python2.6 deps = mock pytest + pytest-localserver PyYAML requests @@ -86,6 +93,7 @@ basepython = python2.7 deps = mock pytest + pytest-localserver PyYAML requests @@ -94,6 +102,7 @@ basepython = python3.4 deps = mock pytest + pytest-localserver PyYAML requests @@ -102,6 +111,7 @@ basepython = python3.4 deps = mock pytest + pytest-localserver PyYAML requests @@ -110,6 +120,7 @@ basepython = pypy deps = mock pytest + pytest-localserver PyYAML requests @@ -118,6 +129,7 @@ basepython = python2.6 deps = mock pytest + pytest-localserver PyYAML httplib2 @@ -126,6 +138,7 @@ basepython = python2.7 deps = mock pytest + pytest-localserver PyYAML httplib2 @@ -134,6 +147,7 @@ basepython = python3.4 deps = mock pytest + pytest-localserver PyYAML httplib2 @@ -142,6 +156,7 @@ basepython = python3.4 deps = mock pytest + pytest-localserver PyYAML httplib2 @@ -150,5 +165,6 @@ basepython = pypy deps = mock pytest + pytest-localserver PyYAML httplib2 diff --git a/vcr/cassette.py b/vcr/cassette.py index 4053c25..aa9f5a9 100644 --- a/vcr/cassette.py +++ b/vcr/cassette.py @@ -34,6 +34,8 @@ class Cassette(ContextDecorator): filter_headers=[], filter_query_parameters=[], before_record=None, + ignore_hosts=[], + ignore_localhost=[], ): self._path = path self._serializer = serializer @@ -41,6 +43,11 @@ class Cassette(ContextDecorator): self._filter_headers = filter_headers self._filter_query_parameters = filter_query_parameters self._before_record = before_record + self._ignore_hosts = ignore_hosts + if ignore_localhost: + self._ignore_hosts = list(set( + self._ignore_hosts + ['localhost', '0.0.0.0', '127.0.0.1'] + )) # self.data is the list of (req, resp) tuples self.data = [] @@ -72,7 +79,8 @@ class Cassette(ContextDecorator): request=request, filter_headers=self._filter_headers, filter_query_parameters=self._filter_query_parameters, - before_record=self._before_record + before_record=self._before_record, + ignore_hosts=self._ignore_hosts ) if not request: return @@ -88,7 +96,8 @@ class Cassette(ContextDecorator): request=request, filter_headers=self._filter_headers, filter_query_parameters=self._filter_query_parameters, - before_record=self._before_record + before_record=self._before_record, + ignore_hosts=self._ignore_hosts ) if not request: return diff --git a/vcr/config.py b/vcr/config.py index 9789583..0a1615a 100644 --- a/vcr/config.py +++ b/vcr/config.py @@ -20,6 +20,8 @@ class VCR(object): 'path', 'query', ], + ignore_hosts=[], + ignore_localhost=False, ): self.serializer = serializer self.match_on = match_on @@ -44,6 +46,8 @@ class VCR(object): self.filter_headers = filter_headers self.filter_query_parameters = filter_query_parameters self.before_record = before_record + self.ignore_hosts = ignore_hosts + self.ignore_localhost = ignore_localhost def _get_serializer(self, serializer_name): try: @@ -82,9 +86,21 @@ class VCR(object): "serializer": self._get_serializer(serializer_name), "match_on": self._get_matchers(matcher_names), "record_mode": kwargs.get('record_mode', self.record_mode), - "filter_headers": kwargs.get('filter_headers', self.filter_headers), - "filter_query_parameters": kwargs.get('filter_query_parameters', self.filter_query_parameters), - "before_record": kwargs.get("before_record", self.before_record), + "filter_headers": kwargs.get( + 'filter_headers', self.filter_headers + ), + "filter_query_parameters": kwargs.get( + 'filter_query_parameters', self.filter_query_parameters + ), + "before_record": kwargs.get( + "before_record", self.before_record + ), + "ignore_hosts": kwargs.get( + 'ignore_hosts', self.ignore_hosts + ), + "ignore_localhost": kwargs.get( + 'ignore_localhost', self.ignore_localhost + ), } return Cassette.load(path, **merged_config) diff --git a/vcr/filters.py b/vcr/filters.py index 318d651..562f840 100644 --- a/vcr/filters.py +++ b/vcr/filters.py @@ -28,11 +28,14 @@ def filter_request( request, filter_headers, filter_query_parameters, - before_record + before_record, + ignore_hosts ): request = copy.copy(request) # don't mutate request object if hasattr(request, 'headers') and filter_headers: request = _remove_headers(request, filter_headers) + if hasattr(request, 'host') and request.host in ignore_hosts: + return None if filter_query_parameters: request = _remove_query_parameters(request, filter_query_parameters) if before_record: