betamaxpy / betamax

A VCR imitation designed only for python-requests.
https://betamax.readthedocs.io/en/latest/
Other
562 stars 61 forks source link

How to retry request and store response of that retried request in cassette #165

Closed GunjanSkry closed 5 years ago

GunjanSkry commented 5 years ago

How to retry request in below example:


from betamax.fixtures.unittest import BetamaxTestCase

with Betamax.configure() as config:
    config.cassette_library_dir = 'cassettes'
    config.preserve_exact_body_bytes = True

class TestExample(BetamaxTestCase): 

    def test_parse(self):
        example = Example()

        # How to retry below request 4 time
        response = self.session.get(example.url)```
sigmavirus24 commented 5 years ago

I don't understand what you're trying to achieve

GunjanSkry commented 5 years ago

I want to retry the request if it fails and for that, I've done like below

from betamax.fixtures.unittest import BetamaxTestCase
import requests

with Betamax.configure() as config:
    config.cassette_library_dir = 'cassettes'
    config.preserve_exact_body_bytes = True

class TestExample(BetamaxTestCase): 

    def test_parse(self):
        example = Example()

        adapter = requests.adapters.HTTPAdapter(max_retries = 5)

        self.session.mount('http://', adapter)
        self.session.mount('https://', adapter)

        response = self.session.get(example.url)

But it doesn't store the response of the get request in cassette, The json file generated by this looks like below,

{"http_interactions": [], "recorded_with": "betamax/0.8.1"}

I've also tried "BetamaxAdapter" like below,

from betamax.fixtures.unittest import BetamaxTestCase
from betamax.adapter import BetamaxAdapter

with Betamax.configure() as config:
    config.cassette_library_dir = 'cassettes'
    config.preserve_exact_body_bytes = True

class TestExample(BetamaxTestCase): 

    def test_parse(self):
        example = Example()

        adapter = BetamaxAdapter(max_retries=5)

        self.session.mount('http://', adapter)
        self.session.mount('https://', adapter)

        response = self.session.get(example.url)

But it gave me this error

    return self.request('GET', url, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/betamax/adapter.py", line 120, in send
    raise BetamaxError('No cassette was specified or found.')
betamax.exceptions.BetamaxError: No cassette was specified or found.
sigmavirus24 commented 5 years ago

So based on our documentation, what you could do is:

import requests

class RetryingSession(requests.Session):
    def __init__(self):
        super().__init__()
        self.mount('http://', requests.adapters.HTTPAdapter(max_retries=5))
        self.mount('https://', requests.adapters.HTTPAdapter(max_retries=5))

class TestExample(BetamaxTestCase):
    SESSION_CLASS = RetryingSession

That will configure the adapter that Betamax will use under-the-covers to retry 5 times.

In general, though, Betamax expects you to be configuring your session elsewhere and passing that in to the test case to be used.