def play_responses(cassette, vcr_request): history = [] vcr_response = cassette.play_response(vcr_request) response = build_response(vcr_request, vcr_response, history) # If we're following redirects, continue playing until we reach # our final destination. while 300 <= response.status <= 399: if "Location" not in response.headers: # Not a redirect, an instruction not to call again break next_url = aios.URL(response.url).with_path( response.headers["location"]) # Make a stub VCR request that we can then use to look up the recorded # VCR request saved to the cassette. This feels a little hacky and # may have edge cases based on the headers we're providing (e.g. if # there's a matcher that is used to filter by headers). vcr_request = aios.Request( "GET", str(next_url), None, aios._serialize_headers(response.request_info.headers), ) vcr_request = cassette.find_requests_with_most_matches( vcr_request)[0][0] # Tack on the response we saw from the redirect into the history # list that is added on to the final response. history.append(response) vcr_response = aios.cassette.play_response(vcr_request) response = aios.build_response(vcr_request, vcr_response, history) return response
def build_response(vcr_request, vcr_response, history): request_info = aios.RequestInfo( url=aios.URL(vcr_request.url), method=vcr_request.method, headers=aios.CIMultiDictProxy(aios.CIMultiDict(vcr_request.headers)), real_url=aios.URL(vcr_request.url), ) response = aios.MockClientResponse(vcr_request.method, aios.URL(vcr_request.url), request_info=request_info) response.status = vcr_response["status"]["code"] response._body = vcr_response["body"].get("string", b"") response.reason = vcr_response["status"]["message"] response._headers = aios.CIMultiDictProxy( aios.CIMultiDict(vcr_response["headers"])) response._history = tuple(history) response.close() return response