Coverage for vcr.request: 62%

# Coverage for vcr.request : 62%

## 50 statements 31 run 19 missing 0 excluded

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | from six import BytesIO, binary_type from six.moves.urllib.parse import urlparse, parse_qsl class Request(object): """ VCR's representation of a request. There is a weird quirk in HTTP. You can send the same header twice. For this reason, headers are represented by a dict, with lists as the values. However, it appears that HTTPlib is completely incapable of sending the same header twice. This puts me in a weird position: I want to be able to accurately represent HTTP headers in cassettes, but I don't want the extra step of always having to do [0] in the general case, i.e. request.headers['key'][0] In addition, some servers sometimes send the same header more than once, and httplib *can* deal with this situation. Futhermore, I wanted to keep the request and response cassette format as similar as possible. For this reason, in cassettes I keep a dict with lists as keys, but once deserialized into VCR, I keep them as plain, naked dicts. """ def __init__(self, method, uri, body, headers): self.method = method self.uri = uri self._was_file = hasattr(body, 'read') if self._was_file: self._body = body.read() if not isinstance(self._body, binary_type): self._body = self._body.encode('utf-8') else: self._body = body self.headers = {} for key in headers: self.add_header(key, headers[key]) @property def body(self): return BytesIO(self._body) if self._was_file else self._body @body.setter def body(self, value): self._body = value def add_header(self, key, value): # see class docstring for an explanation if isinstance(value, (tuple, list)): self.headers[key] = value[0] else: self.headers[key] = value @property def scheme(self): return urlparse(self.uri).scheme @property def host(self): return urlparse(self.uri).hostname @property def port(self): parse_uri = urlparse(self.uri) port = parse_uri.port if port is None: port = {'https': 443, 'http': 80}[parse_uri.scheme] return port @property def path(self): return urlparse(self.uri).path @property def query(self): q = urlparse(self.uri).query return sorted(parse_qsl(q)) # alias for backwards compatibility @property def url(self): return self.uri # alias for backwards compatibility @property def protocol(self): return self.scheme def __str__(self): return "<Request ({0}) {1}>".format(self.method, self.uri) def __repr__(self): return self.__str__() def _to_dict(self): return { 'method': self.method, 'uri': self.uri, 'body': self.body, 'headers': dict(((k, [v]) for k, v in self.headers.items())), } @classmethod def _from_dict(cls, dct): return Request(**dct)