1from .cassette import Cassette
2
3
4class Configuration(object):
5
6    """This object acts as a proxy to configure different parts of Betamax.
7
8    You should only ever encounter this object when configuring the library as
9    a whole. For example:
10
11    .. code::
12
13        with Betamax.configure() as config:
14            config.cassette_library_dir = 'tests/cassettes/'
15            config.default_cassette_options['record_mode'] = 'once'
16            config.default_cassette_options['match_requests_on'] = ['uri']
17            config.define_cassette_placeholder('<URI>', 'http://httpbin.org')
18            config.preserve_exact_body_bytes = True
19
20    """
21
22    CASSETTE_LIBRARY_DIR = 'vcr/cassettes'
23
24    def __enter__(self):
25        return self
26
27    def __exit__(self, *args):
28        pass
29
30    def __setattr__(self, prop, value):
31        if prop == 'preserve_exact_body_bytes':
32            self.default_cassette_options[prop] = True
33        else:
34            super(Configuration, self).__setattr__(prop, value)
35
36    def before_playback(self, tag=None, callback=None):
37        """Register a function to call before playing back an interaction.
38
39        Example usage:
40
41        .. code-block:: python
42
43            def before_playback(interaction, cassette):
44                pass
45
46            with Betamax.configure() as config:
47                config.before_playback(callback=before_playback)
48
49        :param str tag:
50            Limits the interactions passed to the function based on the
51            interaction's tag (currently unsupported).
52        :param callable callback:
53            The function which either accepts just an interaction or an
54            interaction and a cassette and mutates the interaction before
55            returning.
56        """
57        Cassette.hooks['before_playback'].append(callback)
58
59    def before_record(self, tag=None, callback=None):
60        """Register a function to call before recording an interaction.
61
62        Example usage:
63
64        .. code-block:: python
65
66            def before_record(interaction, cassette):
67                pass
68
69            with Betamax.configure() as config:
70                config.before_record(callback=before_record)
71
72        :param str tag:
73            Limits the interactions passed to the function based on the
74            interaction's tag (currently unsupported).
75        :param callable callback:
76            The function which either accepts just an interaction or an
77            interaction and a cassette and mutates the interaction before
78            returning.
79        """
80        Cassette.hooks['before_record'].append(callback)
81
82    @property
83    def cassette_library_dir(self):
84        """Retrieve and set the directory to store the cassettes in."""
85        return Configuration.CASSETTE_LIBRARY_DIR
86
87    @cassette_library_dir.setter
88    def cassette_library_dir(self, value):
89        Configuration.CASSETTE_LIBRARY_DIR = value
90
91    @property
92    def default_cassette_options(self):
93        """Retrieve and set the default cassette options.
94
95        The options include:
96
97        - ``match_requests_on``
98        - ``placeholders``
99        - ``re_record_interval``
100        - ``record_mode``
101        - ``preserve_exact_body_bytes``
102
103        Other options will be ignored.
104        """
105        return Cassette.default_cassette_options
106
107    @default_cassette_options.setter
108    def default_cassette_options(self, value):
109        Cassette.default_cassette_options = value
110
111    def define_cassette_placeholder(self, placeholder, replace):
112        """Define a placeholder value for some text.
113
114        This also will replace the placeholder text with the text you wish it
115        to use when replaying interactions from cassettes.
116
117        :param str placeholder: (required), text to be used as a placeholder
118        :param str replace: (required), text to be replaced or replacing the
119            placeholder
120        """
121        self.default_cassette_options['placeholders'].append({
122            'placeholder': placeholder,
123            'replace': replace,
124        })
125