mirror of
https://github.com/kevin1024/vcrpy.git
synced 2025-12-10 01:25:34 +00:00
bring back the files module, but do serialization in cassette
This commit is contained in:
@@ -1,27 +1,23 @@
|
|||||||
'''The container for recorded requests and responses'''
|
'''The container for recorded requests and responses'''
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import yaml
|
|
||||||
import tempfile
|
import tempfile
|
||||||
try:
|
|
||||||
# Use the libYAML versions if possible. They're much faster than the pure
|
|
||||||
# python implemenations
|
|
||||||
from yaml import CLoader as Loader, CDumper as Dumper
|
|
||||||
except ImportError: # pragma: no cover
|
|
||||||
from yaml import Loader, Dumper
|
|
||||||
|
|
||||||
# Internal imports
|
# Internal imports
|
||||||
from .patch import install, reset
|
from .patch import install, reset
|
||||||
|
from .files import load_cassette, save_cassette
|
||||||
|
|
||||||
|
|
||||||
class Cassette(object):
|
class Cassette(object):
|
||||||
'''A container for recorded requests and responses'''
|
'''A container for recorded requests and responses'''
|
||||||
|
# TODO: clean up the constructor and
|
||||||
|
# classmethods
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load(cls, path):
|
def load(cls, path):
|
||||||
'''Load in the cassette stored at the provided path'''
|
'''Load in the cassette stored at the provided path'''
|
||||||
try:
|
try:
|
||||||
with open(path) as fin:
|
return cls(path, load_cassette(path))
|
||||||
return cls(path, yaml.load(fin, Loader=Loader))
|
|
||||||
except IOError:
|
except IOError:
|
||||||
return cls(path)
|
return cls(path)
|
||||||
|
|
||||||
@@ -35,15 +31,7 @@ class Cassette(object):
|
|||||||
|
|
||||||
def save(self, path):
|
def save(self, path):
|
||||||
'''Save this cassette to a path'''
|
'''Save this cassette to a path'''
|
||||||
dirname, filename = os.path.split(path)
|
save_cassette(path, self.serialize())
|
||||||
if not os.path.exists(dirname):
|
|
||||||
os.makedirs(dirname)
|
|
||||||
# We'll overwrite the old version securely by writing out a temporary
|
|
||||||
# version and then moving it to replace the old version
|
|
||||||
fd, name = tempfile.mkstemp(dir=dirname, prefix=filename)
|
|
||||||
with os.fdopen(fd, 'w') as fout:
|
|
||||||
fout.write(yaml.dump(self.serialize(), Dumper=Dumper))
|
|
||||||
os.rename(name, path)
|
|
||||||
|
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
'''Return a serializable version of the cassette'''
|
'''Return a serializable version of the cassette'''
|
||||||
@@ -58,8 +46,13 @@ class Cassette(object):
|
|||||||
[r['request'] for r in source], [r['response'] for r in source])
|
[r['request'] for r in source], [r['response'] for r in source])
|
||||||
|
|
||||||
def cached(self, request=None):
|
def cached(self, request=None):
|
||||||
'''Alert the cassete of a request that's been cached, or get the
|
'''
|
||||||
requests that we've cached'''
|
Alert the cassette of a request that's been cached, or get the
|
||||||
|
requests that we've cached. This is used mainly for
|
||||||
|
debugging purposes.
|
||||||
|
'''
|
||||||
|
# TODO: maybe dependency injection for this method since
|
||||||
|
# it's only used in tests?
|
||||||
if request:
|
if request:
|
||||||
self._cached.append(request)
|
self._cached.append(request)
|
||||||
else:
|
else:
|
||||||
@@ -87,10 +80,12 @@ class Cassette(object):
|
|||||||
try:
|
try:
|
||||||
return self._responses[self._requests.index(request)]
|
return self._responses[self._requests.index(request)]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
#todo: keyerror if not in cassette
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
'''Patch the fetching libraries we know about'''
|
'''Patch the fetching libraries we know about'''
|
||||||
|
#TODO: how is this context manager used?
|
||||||
install(self)
|
install(self)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|||||||
19
vcr/files.py
Normal file
19
vcr/files.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import os
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
# Use the libYAML versions if possible
|
||||||
|
try:
|
||||||
|
from yaml import CLoader as Loader, CDumper as Dumper
|
||||||
|
except ImportError:
|
||||||
|
from yaml import Loader, Dumper
|
||||||
|
|
||||||
|
def load_cassette(cassette_path):
|
||||||
|
return yaml.load(open(cassette_path), Loader=Loader)
|
||||||
|
|
||||||
|
def save_cassette(cassette_path, data):
|
||||||
|
#TODO: safe overwrite using tmpfile
|
||||||
|
dirname, filename = os.path.split(cassette_path)
|
||||||
|
if not os.path.exists(dirname):
|
||||||
|
os.makedirs(dirname)
|
||||||
|
with open(cassette_path, 'a') as cassette_file:
|
||||||
|
cassette_file.write(yaml.dump(data, Dumper=Dumper))
|
||||||
Reference in New Issue
Block a user