mirror of
https://github.com/kevin1024/vcrpy.git
synced 2025-12-09 09:13:23 +00:00
Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53c55b13e7 | ||
|
|
365e7cb112 | ||
|
|
e5d6327de9 | ||
|
|
d86ffe7130 | ||
|
|
d9fd563812 | ||
|
|
9e548718e5 | ||
|
|
83720793fb | ||
|
|
188326b10e | ||
|
|
ff90190660 | ||
|
|
1d9f8b5f7c | ||
|
|
2454aa2eb0 | ||
|
|
df5f6089af | ||
|
|
5738547288 | ||
|
|
8274b660c6 | ||
|
|
a8f1a65d62 | ||
|
|
9c275dd86a | ||
|
|
1fbd65a702 | ||
|
|
31b0e825b5 | ||
|
|
973d8339b3 | ||
|
|
c8db6cb731 | ||
|
|
ecbc192fc4 | ||
|
|
76d365314a | ||
|
|
830a3c2e04 | ||
|
|
9c432c7e50 | ||
|
|
6f7f45d0a8 | ||
|
|
8e352feb6a | ||
|
|
57a934d14b | ||
|
|
f9d7ccd33e | ||
|
|
265a158fe7 | ||
|
|
c65ff0e7b3 | ||
|
|
066752aa0b | ||
|
|
9a5214888b | ||
|
|
609d8e35be | ||
|
|
ce14de8251 | ||
|
|
574b22a62a | ||
|
|
1167b9ea4e | ||
|
|
77ae99bfda | ||
|
|
8851571ba7 | ||
|
|
f71d28d10e | ||
|
|
3355bd01eb | ||
|
|
17afa82bf4 | ||
|
|
f98684e8aa | ||
|
|
5a85e88a39 | ||
|
|
d2368eb2c4 | ||
|
|
37665581e0 |
13
.travis.yml
13
.travis.yml
@@ -22,11 +22,14 @@ env:
|
||||
- TOX_SUFFIX="urllib3110"
|
||||
- TOX_SUFFIX="tornado3"
|
||||
- TOX_SUFFIX="tornado4"
|
||||
- TOX_SUFFIX="aiohttp"
|
||||
matrix:
|
||||
allow_failures:
|
||||
- env: TOX_SUFFIX="boto"
|
||||
- env: TOX_SUFFIX="boto3"
|
||||
exclude:
|
||||
- env: TOX_SUFFIX="flakes"
|
||||
python: 2.6
|
||||
- env: TOX_SUFFIX="boto"
|
||||
python: 3.3
|
||||
- env: TOX_SUFFIX="boto"
|
||||
@@ -35,6 +38,16 @@ matrix:
|
||||
python: 3.4
|
||||
- env: TOX_SUFFIX="requests1"
|
||||
python: 3.5
|
||||
- env: TOX_SUFFIX="aiohttp"
|
||||
python: 2.6
|
||||
- env: TOX_SUFFIX="aiohttp"
|
||||
python: 2.7
|
||||
- env: TOX_SUFFIX="aiohttp"
|
||||
python: 3.3
|
||||
- env: TOX_SUFFIX="aiohttp"
|
||||
python: pypy
|
||||
- env: TOX_SUFFIX="aiohttp"
|
||||
python: pypy3
|
||||
python:
|
||||
- 2.6
|
||||
- 2.7
|
||||
|
||||
16
README.rst
16
README.rst
@@ -13,7 +13,7 @@ Source code
|
||||
https://github.com/kevin1024/vcrpy
|
||||
|
||||
Documentation
|
||||
https://vcrpy.readthedocs.org/
|
||||
https://vcrpy.readthedocs.io/
|
||||
|
||||
Rationale
|
||||
---------
|
||||
@@ -41,6 +41,20 @@ VCR.py will detect the absence of a cassette file and once again record
|
||||
all HTTP interactions, which will update them to correspond to the new
|
||||
API.
|
||||
|
||||
Support
|
||||
-------
|
||||
|
||||
VCR.py works great with the following HTTP clients:
|
||||
|
||||
- requests
|
||||
- aiohttp
|
||||
- urllib3
|
||||
- tornado
|
||||
- urllib2
|
||||
- boto
|
||||
- boto3
|
||||
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
Changelog
|
||||
---------
|
||||
- 1.10.5 Added a fix to httplib2 (thanks @carlosds730), Fix an issue with
|
||||
aiohttp (thanks @madninja), Add missing requirement yarl (thanks @lamenezes),
|
||||
Remove duplicate mock triple (thanks @FooBarQuaxx)
|
||||
- 1.10.4 Fix an issue with asyncio aiohttp (thanks @madninja)
|
||||
- 1.10.3 Fix some issues with asyncio and params (thanks @anovikov1984 and
|
||||
@lamenezes), Fix some issues with cassette serialize / deserialize and empty
|
||||
response bodies (thanks @gRoussac and @dz0ny)
|
||||
- 1.10.2 Fix 1.10.1 release - add aiohttp support back in
|
||||
- 1.10.1 [bad release] Fix build for Fedora package + python2 (thanks @puiterwijk and @lamenezes)
|
||||
- 1.10.0 Add support for aiohttp (thanks @lamenezes)
|
||||
- 1.9.0 Add support for boto3 (thanks @desdm, @foorbarna). Fix deepcopy issue
|
||||
for response headers when `decode_compressed_response` is enabled (thanks
|
||||
@nickdirienzo)
|
||||
|
||||
@@ -110,7 +110,7 @@ todo_include_todos = False
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages.
|
||||
# https://read-the-docs.readthedocs.org/en/latest/theme.html#how-do-i-use-this-locally-and-on-read-the-docs
|
||||
# https://read-the-docs.readthedocs.io/en/latest/theme.html#how-do-i-use-this-locally-and-on-read-the-docs
|
||||
if 'READTHEDOCS' not in os.environ:
|
||||
import sphinx_rtd_theme
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
@@ -19,7 +19,7 @@ that has ``requests`` installed.
|
||||
|
||||
Also, in order for the boto tests to run, you will need an AWS key.
|
||||
Refer to the `boto
|
||||
documentation <http://boto.readthedocs.org/en/latest/getting_started.html>`__
|
||||
documentation <https://boto.readthedocs.io/en/latest/getting_started.html>`__
|
||||
for 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.
|
||||
|
||||
9
setup.py
9
setup.py
@@ -31,6 +31,7 @@ extras_require = {
|
||||
':python_version in "2.4, 2.5, 2.6"':
|
||||
['contextlib2', 'backport_collections', 'mock'],
|
||||
':python_version in "2.7, 3.1, 3.2"': ['contextlib2', 'mock'],
|
||||
':python_version in "3.4, 3.5, 3.6"': ['yarl'],
|
||||
}
|
||||
|
||||
|
||||
@@ -49,9 +50,13 @@ except Exception:
|
||||
install_requires.extend(value)
|
||||
|
||||
|
||||
excluded_packages = ["tests*"]
|
||||
if sys.version_info[0] == 2:
|
||||
excluded_packages.append("vcr.stubs.aiohttp_stubs")
|
||||
|
||||
setup(
|
||||
name='vcrpy',
|
||||
version='1.9.0',
|
||||
version='1.10.5',
|
||||
description=(
|
||||
"Automatically mock your HTTP interactions to simplify and "
|
||||
"speed up testing"
|
||||
@@ -60,7 +65,7 @@ setup(
|
||||
author='Kevin McCarthy',
|
||||
author_email='me@kevinmccarthy.org',
|
||||
url='https://github.com/kevin1024/vcrpy',
|
||||
packages=find_packages(exclude=("tests*",)),
|
||||
packages=find_packages(exclude=excluded_packages),
|
||||
install_requires=install_requires,
|
||||
extras_require=extras_require,
|
||||
license='MIT',
|
||||
|
||||
7
tests/integration/aiohttp_utils.py
Normal file
7
tests/integration/aiohttp_utils.py
Normal file
@@ -0,0 +1,7 @@
|
||||
import asyncio
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def aiohttp_request(session, method, url, as_text, **kwargs):
|
||||
response = yield from session.request(method, url, **kwargs) # NOQA: E999
|
||||
return response, (yield from response.text()) if as_text else (yield from response.json()) # NOQA: E999
|
||||
117
tests/integration/test_aiohttp.py
Normal file
117
tests/integration/test_aiohttp.py
Normal file
@@ -0,0 +1,117 @@
|
||||
import pytest
|
||||
aiohttp = pytest.importorskip("aiohttp")
|
||||
|
||||
import asyncio # NOQA
|
||||
import sys # NOQA
|
||||
|
||||
import aiohttp # NOQA
|
||||
import pytest # NOQA
|
||||
import vcr # NOQA
|
||||
|
||||
from .aiohttp_utils import aiohttp_request # NOQA
|
||||
|
||||
|
||||
def get(url, as_text=True, **kwargs):
|
||||
loop = asyncio.get_event_loop()
|
||||
with aiohttp.ClientSession() as session:
|
||||
task = loop.create_task(aiohttp_request(session, 'GET', url, as_text, **kwargs))
|
||||
return loop.run_until_complete(task)
|
||||
|
||||
|
||||
def post(url, as_text=True, **kwargs):
|
||||
loop = asyncio.get_event_loop()
|
||||
with aiohttp.ClientSession() as session:
|
||||
task = loop.create_task(aiohttp_request(session, 'POST', url, as_text, **kwargs))
|
||||
return loop.run_until_complete(task)
|
||||
|
||||
|
||||
@pytest.fixture(params=["https", "http"])
|
||||
def scheme(request):
|
||||
'''Fixture that returns both http and https.'''
|
||||
return request.param
|
||||
|
||||
|
||||
def test_status(tmpdir, scheme):
|
||||
url = scheme + '://httpbin.org'
|
||||
with vcr.use_cassette(str(tmpdir.join('status.yaml'))):
|
||||
response, _ = get(url)
|
||||
|
||||
with vcr.use_cassette(str(tmpdir.join('status.yaml'))) as cassette:
|
||||
cassette_response, _ = get(url)
|
||||
assert cassette_response.status == response.status
|
||||
assert cassette.play_count == 1
|
||||
|
||||
|
||||
def test_headers(tmpdir, scheme):
|
||||
url = scheme + '://httpbin.org'
|
||||
with vcr.use_cassette(str(tmpdir.join('headers.yaml'))):
|
||||
response, _ = get(url)
|
||||
|
||||
with vcr.use_cassette(str(tmpdir.join('headers.yaml'))) as cassette:
|
||||
cassette_response, _ = get(url)
|
||||
assert cassette_response.headers == response.headers
|
||||
assert cassette.play_count == 1
|
||||
|
||||
|
||||
def test_text(tmpdir, scheme):
|
||||
url = scheme + '://httpbin.org'
|
||||
with vcr.use_cassette(str(tmpdir.join('text.yaml'))):
|
||||
_, response_text = get(url)
|
||||
|
||||
with vcr.use_cassette(str(tmpdir.join('text.yaml'))) as cassette:
|
||||
_, cassette_response_text = get(url)
|
||||
assert cassette_response_text == response_text
|
||||
assert cassette.play_count == 1
|
||||
|
||||
|
||||
def test_json(tmpdir, scheme):
|
||||
url = scheme + '://httpbin.org/get'
|
||||
with vcr.use_cassette(str(tmpdir.join('json.yaml'))):
|
||||
_, response_json = get(url, as_text=False)
|
||||
|
||||
with vcr.use_cassette(str(tmpdir.join('json.yaml'))) as cassette:
|
||||
_, cassette_response_json = get(url, as_text=False)
|
||||
assert cassette_response_json == response_json
|
||||
assert cassette.play_count == 1
|
||||
|
||||
|
||||
def test_post(tmpdir, scheme):
|
||||
data = {'key1': 'value1', 'key2': 'value2'}
|
||||
url = scheme + '://httpbin.org/post'
|
||||
with vcr.use_cassette(str(tmpdir.join('post.yaml'))):
|
||||
_, response_json = post(url, data=data)
|
||||
|
||||
with vcr.use_cassette(str(tmpdir.join('post.yaml'))) as cassette:
|
||||
_, cassette_response_json = post(url, data=data)
|
||||
assert cassette_response_json == response_json
|
||||
assert cassette.play_count == 1
|
||||
|
||||
|
||||
def test_params(tmpdir, scheme):
|
||||
url = scheme + '://httpbin.org/get'
|
||||
params = {'a': 1, 'b': False, 'c': 'c'}
|
||||
with vcr.use_cassette(str(tmpdir.join('get.yaml'))) as cassette:
|
||||
_, response_json = get(url, as_text=False, params=params)
|
||||
|
||||
with vcr.use_cassette(str(tmpdir.join('get.yaml'))) as cassette:
|
||||
_, cassette_response_json = get(url, as_text=False, params=params)
|
||||
assert cassette_response_json == response_json
|
||||
assert cassette.play_count == 1
|
||||
|
||||
|
||||
def test_params_same_url_distinct_params(tmpdir, scheme):
|
||||
url = scheme + '://httpbin.org/get'
|
||||
params = {'a': 1, 'b': False, 'c': 'c'}
|
||||
with vcr.use_cassette(str(tmpdir.join('get.yaml'))) as cassette:
|
||||
_, response_json = get(url, as_text=False, params=params)
|
||||
|
||||
with vcr.use_cassette(str(tmpdir.join('get.yaml'))) as cassette:
|
||||
_, cassette_response_json = get(url, as_text=False, params=params)
|
||||
assert cassette_response_json == response_json
|
||||
assert cassette.play_count == 1
|
||||
|
||||
other_params = {'other': 'params'}
|
||||
with vcr.use_cassette(str(tmpdir.join('get.yaml'))) as cassette:
|
||||
response, cassette_response_text = get(url, as_text=True, params=other_params)
|
||||
assert 'No match for the request' in cassette_response_text
|
||||
assert response.status == 599
|
||||
@@ -38,6 +38,18 @@ def test_body(tmpdir, httpbin_both):
|
||||
assert content == requests.get(url).content
|
||||
|
||||
|
||||
def test_get_empty_content_type_json(tmpdir, httpbin_both):
|
||||
'''Ensure GET with application/json content-type and empty request body doesn't crash'''
|
||||
url = httpbin_both + '/status/200'
|
||||
headers = {'Content-Type': 'application/json'}
|
||||
|
||||
with vcr.use_cassette(str(tmpdir.join('get_empty_json.yaml')), match_on=('body',)):
|
||||
status = requests.get(url, headers=headers).status_code
|
||||
|
||||
with vcr.use_cassette(str(tmpdir.join('get_empty_json.yaml')), match_on=('body',)):
|
||||
assert status == requests.get(url, headers=headers).status_code
|
||||
|
||||
|
||||
def test_effective_url(tmpdir, httpbin_both):
|
||||
'''Ensure that the effective_url is captured'''
|
||||
url = httpbin_both.url + '/redirect-to?url=/html'
|
||||
|
||||
@@ -67,8 +67,8 @@ def test_original_decoded_response_is_not_modified(tmpdir, httpbin):
|
||||
assert 'gzip' == inside.headers['content-encoding']
|
||||
|
||||
# They should effectively be the same response.
|
||||
inside_headers = (h for h in inside.headers.items() if h[0] != 'Date')
|
||||
outside_headers = (h for h in outside.getheaders() if h[0] != 'Date')
|
||||
inside_headers = (h for h in inside.headers.items() if h[0].lower() != 'date')
|
||||
outside_headers = (h for h in outside.getheaders() if h[0].lower() != 'date')
|
||||
assert set(inside_headers) == set(outside_headers)
|
||||
inside = zlib.decompress(inside.read(), 16+zlib.MAX_WBITS)
|
||||
outside = zlib.decompress(outside.read(), 16+zlib.MAX_WBITS)
|
||||
|
||||
@@ -4,7 +4,7 @@ import pytest
|
||||
from vcr.compat import mock
|
||||
from vcr.request import Request
|
||||
from vcr.serialize import deserialize, serialize
|
||||
from vcr.serializers import yamlserializer, jsonserializer
|
||||
from vcr.serializers import yamlserializer, jsonserializer, compat
|
||||
|
||||
|
||||
def test_deserialize_old_yaml_cassette():
|
||||
@@ -131,3 +131,9 @@ def test_serialize_binary_request():
|
||||
)
|
||||
except (UnicodeDecodeError, TypeError) as exc:
|
||||
assert msg in str(exc)
|
||||
|
||||
|
||||
def test_deserialize_no_body_string():
|
||||
data = {'body': {'string': None}}
|
||||
output = compat.convert_to_bytes(data)
|
||||
assert data == output
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
from vcr.stubs import VCRHTTPSConnection
|
||||
from vcr.compat import mock
|
||||
from vcr.cassette import Cassette
|
||||
|
||||
|
||||
class TestVCRConnection(object):
|
||||
@@ -7,3 +9,10 @@ class TestVCRConnection(object):
|
||||
vcr_connection = VCRHTTPSConnection('www.examplehost.com')
|
||||
vcr_connection.ssl_version = 'example_ssl_version'
|
||||
assert vcr_connection.real_connection.ssl_version == 'example_ssl_version'
|
||||
|
||||
@mock.patch('vcr.cassette.Cassette.can_play_response_for', return_value=False)
|
||||
def testing_connect(*args):
|
||||
vcr_connection = VCRHTTPSConnection('www.google.com')
|
||||
vcr_connection.cassette = Cassette('test', record_mode='all')
|
||||
vcr_connection.real_connection.connect()
|
||||
assert vcr_connection.real_connection.sock is not None
|
||||
|
||||
5
tox.ini
5
tox.ini
@@ -1,11 +1,11 @@
|
||||
[tox]
|
||||
envlist = {py26,py27,py33,py34,pypy,pypy3}-{flakes,requests27,requests26,requests25,requests24,requests23,requests22,requests1,httplib2,urllib317,urllib319,urllib3110,tornado3,tornado4,boto,boto3}
|
||||
envlist = {py26,py27,py33,py34,pypy,pypy3}-{flakes,requests27,requests26,requests25,requests24,requests23,requests22,requests1,httplib2,urllib317,urllib319,urllib3110,tornado3,tornado4,boto,boto3,aiohttp}
|
||||
|
||||
[testenv:flakes]
|
||||
skipsdist = True
|
||||
commands =
|
||||
flake8 --version
|
||||
flake8 --exclude="./docs/conf.py"
|
||||
flake8 --exclude=./docs/conf.py,./.tox/
|
||||
pyflakes ./docs/conf.py
|
||||
deps = flake8
|
||||
|
||||
@@ -38,6 +38,7 @@ deps =
|
||||
{py26,py27,py33,py34}-tornado4: pycurl
|
||||
boto: boto
|
||||
boto3: boto3
|
||||
aiohttp: aiohttp
|
||||
|
||||
[flake8]
|
||||
max_line_length = 110
|
||||
|
||||
@@ -49,7 +49,8 @@ def _transform_json(body):
|
||||
# Request body is always a byte string, but json.loads() wants a text
|
||||
# string. RFC 7159 says the default encoding is UTF-8 (although UTF-16
|
||||
# and UTF-32 are also allowed: hmmmmm).
|
||||
return json.loads(body.decode('utf-8'))
|
||||
if body:
|
||||
return json.loads(body.decode('utf-8'))
|
||||
|
||||
|
||||
_xml_header_checker = _header_checker('text/xml')
|
||||
|
||||
@@ -164,5 +164,6 @@ def main():
|
||||
sys.stderr.write("[{0}] {1}\n".format(status, file_path))
|
||||
sys.stderr.write("Done.\n")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
23
vcr/patch.py
23
vcr/patch.py
@@ -80,6 +80,13 @@ else:
|
||||
_CurlAsyncHTTPClient_fetch_impl = \
|
||||
tornado.curl_httpclient.CurlAsyncHTTPClient.fetch_impl
|
||||
|
||||
try:
|
||||
import aiohttp.client
|
||||
except ImportError: # pragma: no cover
|
||||
pass
|
||||
else:
|
||||
_AiohttpClientSessionRequest = aiohttp.client.ClientSession._request
|
||||
|
||||
|
||||
class CassettePatcherBuilder(object):
|
||||
|
||||
@@ -98,7 +105,7 @@ class CassettePatcherBuilder(object):
|
||||
def build(self):
|
||||
return itertools.chain(
|
||||
self._httplib(), self._requests(), self._boto3(), self._urllib3(),
|
||||
self._httplib2(), self._boto(), self._tornado(),
|
||||
self._httplib2(), self._boto(), self._tornado(), self._aiohttp(),
|
||||
self._build_patchers_from_mock_triples(
|
||||
self._cassette.custom_patches
|
||||
),
|
||||
@@ -273,6 +280,19 @@ class CassettePatcherBuilder(object):
|
||||
)
|
||||
yield curl.CurlAsyncHTTPClient, 'fetch_impl', new_fetch_impl
|
||||
|
||||
@_build_patchers_from_mock_triples_decorator
|
||||
def _aiohttp(self):
|
||||
try:
|
||||
import aiohttp.client as client
|
||||
except ImportError: # pragma: no cover
|
||||
pass
|
||||
else:
|
||||
from .stubs.aiohttp_stubs import vcr_request
|
||||
new_request = vcr_request(
|
||||
self._cassette, _AiohttpClientSessionRequest
|
||||
)
|
||||
yield client.ClientSession, '_request', new_request
|
||||
|
||||
def _urllib3_patchers(self, cpool, stubs):
|
||||
http_connection_remover = ConnectionRemover(
|
||||
self._get_cassette_subclass(stubs.VCRRequestsHTTPConnection)
|
||||
@@ -281,7 +301,6 @@ class CassettePatcherBuilder(object):
|
||||
self._get_cassette_subclass(stubs.VCRRequestsHTTPSConnection)
|
||||
)
|
||||
mock_triples = (
|
||||
(cpool, 'VerifiedHTTPSConnection', stubs.VCRRequestsHTTPSConnection),
|
||||
(cpool, 'VerifiedHTTPSConnection', stubs.VCRRequestsHTTPSConnection),
|
||||
(cpool, 'HTTPConnection', stubs.VCRRequestsHTTPConnection),
|
||||
(cpool, 'HTTPSConnection', stubs.VCRRequestsHTTPSConnection),
|
||||
|
||||
@@ -24,7 +24,7 @@ def convert_body_to_bytes(resp):
|
||||
http://pyyaml.org/wiki/PyYAMLDocumentation#Python3support
|
||||
"""
|
||||
try:
|
||||
if not isinstance(resp['body']['string'], six.binary_type):
|
||||
if resp['body']['string'] is not None and not isinstance(resp['body']['string'], six.binary_type):
|
||||
resp['body']['string'] = resp['body']['string'].encode('utf-8')
|
||||
except (KeyError, TypeError, UnicodeEncodeError):
|
||||
# The thing we were converting either wasn't a dictionary or didn't
|
||||
|
||||
@@ -287,7 +287,9 @@ class VCRConnection(object):
|
||||
# Cassette is write-protected, don't actually connect
|
||||
return
|
||||
|
||||
return self.real_connection.connect(*args, **kwargs)
|
||||
from vcr.patch import force_reset
|
||||
with force_reset():
|
||||
return self.real_connection.connect(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def sock(self):
|
||||
|
||||
81
vcr/stubs/aiohttp_stubs/__init__.py
Normal file
81
vcr/stubs/aiohttp_stubs/__init__.py
Normal file
@@ -0,0 +1,81 @@
|
||||
'''Stubs for aiohttp HTTP clients'''
|
||||
from __future__ import absolute_import
|
||||
|
||||
import asyncio
|
||||
import functools
|
||||
import json
|
||||
|
||||
from aiohttp import ClientResponse
|
||||
from yarl import URL
|
||||
|
||||
from vcr.request import Request
|
||||
|
||||
|
||||
class MockClientResponse(ClientResponse):
|
||||
# TODO: get encoding from header
|
||||
@asyncio.coroutine
|
||||
def json(self, *, encoding='utf-8', loads=json.loads): # NOQA: E999
|
||||
return loads(self.content.decode(encoding))
|
||||
|
||||
@asyncio.coroutine
|
||||
def text(self, encoding='utf-8'):
|
||||
return self.content.decode(encoding)
|
||||
|
||||
@asyncio.coroutine
|
||||
def release(self):
|
||||
pass
|
||||
|
||||
|
||||
def vcr_request(cassette, real_request):
|
||||
@functools.wraps(real_request)
|
||||
@asyncio.coroutine
|
||||
def new_request(self, method, url, **kwargs):
|
||||
headers = kwargs.get('headers')
|
||||
headers = self._prepare_headers(headers)
|
||||
data = kwargs.get('data')
|
||||
params = kwargs.get('params')
|
||||
if params:
|
||||
for k, v in params.items():
|
||||
params[k] = str(v)
|
||||
|
||||
request_url = URL(url).with_query(params)
|
||||
vcr_request = Request(method, str(request_url), data, headers)
|
||||
|
||||
if cassette.can_play_response_for(vcr_request):
|
||||
vcr_response = cassette.play_response(vcr_request)
|
||||
|
||||
response = MockClientResponse(method, URL(vcr_response.get('url')))
|
||||
response.status = vcr_response['status']['code']
|
||||
response.content = vcr_response['body']['string']
|
||||
response.reason = vcr_response['status']['message']
|
||||
response.headers = vcr_response['headers']
|
||||
|
||||
response.close()
|
||||
return response
|
||||
|
||||
if cassette.write_protected and cassette.filter_request(vcr_request):
|
||||
response = MockClientResponse(method, URL(url))
|
||||
response.status = 599
|
||||
msg = ("No match for the request {!r} was found. Can't overwrite "
|
||||
"existing cassette {!r} in your current record mode {!r}.")
|
||||
msg = msg.format(vcr_request, cassette._path, cassette.record_mode)
|
||||
response.content = msg.encode()
|
||||
response.close()
|
||||
return response
|
||||
|
||||
response = yield from real_request(self, method, url, **kwargs) # NOQA: E999
|
||||
|
||||
vcr_response = {
|
||||
'status': {
|
||||
'code': response.status,
|
||||
'message': response.reason,
|
||||
},
|
||||
'headers': dict(response.headers),
|
||||
'body': {'string': (yield from response.text())}, # NOQA: E999
|
||||
'url': response.url,
|
||||
}
|
||||
cassette.append(vcr_request, vcr_response)
|
||||
|
||||
return response
|
||||
|
||||
return new_request
|
||||
Reference in New Issue
Block a user