-
-
Notifications
You must be signed in to change notification settings - Fork 133
/
Copy pathrequests.py
96 lines (78 loc) · 3.13 KB
/
requests.py
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
"""OpenAPI core contrib requests requests module"""
from typing import Optional
from typing import Union
from urllib.parse import parse_qs
from urllib.parse import urlparse
from requests import PreparedRequest
from requests import Request
from requests.cookies import RequestsCookieJar
from werkzeug.datastructures import Headers
from werkzeug.datastructures import ImmutableMultiDict
from openapi_core.contrib.requests.protocols import SupportsCookieJar
from openapi_core.datatypes import RequestParameters
class RequestsOpenAPIRequest:
"""
Converts a requests request to an OpenAPI request
Internally converts to a `PreparedRequest` first to parse the exact
payload being sent
"""
def __init__(self, request: Union[Request, PreparedRequest]):
if not isinstance(request, (Request, PreparedRequest)):
raise TypeError(
"'request' argument is not type of "
f"{Request} or {PreparedRequest}"
)
if isinstance(request, Request):
request = request.prepare()
self.request = request
if request.url is None:
raise RuntimeError("Request URL is missing")
self._url_parsed = urlparse(request.url, allow_fragments=False)
cookie = {}
if isinstance(self.request, SupportsCookieJar) and isinstance(
self.request._cookies, RequestsCookieJar
):
# cookies are stored in a cookiejar object
cookie = self.request._cookies.get_dict()
self.parameters = RequestParameters(
query=ImmutableMultiDict(parse_qs(self._url_parsed.query)),
header=Headers(dict(self.request.headers)),
cookie=ImmutableMultiDict(cookie),
)
@property
def host_url(self) -> str:
return f"{self._url_parsed.scheme}://{self._url_parsed.netloc}"
@property
def path(self) -> str:
assert isinstance(self._url_parsed.path, str)
return self._url_parsed.path
@property
def method(self) -> str:
method = self.request.method
return method and method.lower() or ""
@property
def body(self) -> Optional[bytes]:
if self.request.body is None:
return None
if isinstance(self.request.body, bytes):
return self.request.body
assert isinstance(self.request.body, str)
# TODO: figure out if request._body_position is relevant
return self.request.body.encode("utf-8")
@property
def content_type(self) -> str:
# Order matters because all python requests issued from a session
# include Accept */* which does not necessarily match the content type
return str(
self.request.headers.get("Content-Type")
or self.request.headers.get("Accept")
)
class RequestsOpenAPIWebhookRequest(RequestsOpenAPIRequest):
"""
Converts a requests request to an OpenAPI Webhook request
Internally converts to a `PreparedRequest` first to parse the exact
payload being sent
"""
def __init__(self, request: Union[Request, PreparedRequest], name: str):
super().__init__(request)
self.name = name