Skip to content

Commit 5a91425

Browse files
eyadgaranp1c2u
authored andcommitted
use prepared request to format payload before converting
1 parent 6a222b9 commit 5a91425

File tree

1 file changed

+42
-8
lines changed

1 file changed

+42
-8
lines changed
Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
"""OpenAPI core contrib requests requests module"""
2+
from typing import Union
23
from werkzeug.datastructures import ImmutableMultiDict
4+
from requests import Request, PreparedRequest
5+
from urllib.parse import urlparse, parse_qs
36

47
from openapi_core.validation.request.datatypes import (
58
RequestParameters, OpenAPIRequest,
@@ -9,26 +12,57 @@
912
class RequestsOpenAPIRequestFactory(object):
1013

1114
@classmethod
12-
def create(cls, request):
15+
def create(cls, request: Union[Request, PreparedRequest]) -> OpenAPIRequest:
16+
"""
17+
Converts a requests request to an OpenAPI one
18+
19+
Internally converts to a `PreparedRequest` first to parse the exact
20+
payload being sent
21+
"""
22+
if isinstance(request, Request):
23+
request = request.prepare()
24+
25+
# Method
1326
method = request.method.lower()
1427

15-
cookie = request.cookies or {}
28+
# Cookies
29+
if request._cookies is not None:
30+
# cookies are stored in a cookiejar object
31+
cookie = request._cookies.get_dict()
32+
else:
33+
cookie = {}
34+
35+
# Preparing a request formats the URL with params, strip them out again
36+
o = urlparse(request.url)
37+
params = parse_qs(o.query)
38+
# extract the URL without query parameters
39+
url = o._replace(query=None).geturl()
1640

1741
# gets deduced by path finder against spec
1842
path = {}
1943

20-
mimetype = request.headers.get('Accept') or \
21-
request.headers.get('Content-Type')
44+
# Order matters because all python requests issued from a session include
45+
# Accept */* which does not necessarily match the content type
46+
mimetype = request.headers.get('Content-Type') or \
47+
request.headers.get('Accept')
48+
49+
# Headers - request.headers is not an instance of dict, which is expected
50+
header = dict(request.headers)
51+
52+
# Body
53+
# TODO: figure out if request._body_position is relevant
54+
body = request.body
55+
2256
parameters = RequestParameters(
23-
query=ImmutableMultiDict(request.params),
24-
header=request.headers,
57+
query=ImmutableMultiDict(params),
58+
header=header,
2559
cookie=cookie,
2660
path=path,
2761
)
2862
return OpenAPIRequest(
29-
full_url_pattern=request.url,
63+
full_url_pattern=url,
3064
method=method,
3165
parameters=parameters,
32-
body=request.data,
66+
body=body,
3367
mimetype=mimetype,
3468
)

0 commit comments

Comments
 (0)