use prepared request to format payload before converting

This commit is contained in:
Elisha Yadgaran 2020-11-17 00:12:56 -08:00 committed by p1c2u
parent 6a222b93df
commit 5a91425c68

View file

@ -1,5 +1,8 @@
"""OpenAPI core contrib requests requests module"""
from typing import Union
from werkzeug.datastructures import ImmutableMultiDict
from requests import Request, PreparedRequest
from urllib.parse import urlparse, parse_qs
from openapi_core.validation.request.datatypes import (
RequestParameters, OpenAPIRequest,
@ -9,26 +12,57 @@ from openapi_core.validation.request.datatypes import (
class RequestsOpenAPIRequestFactory(object):
@classmethod
def create(cls, request):
def create(cls, request: Union[Request, PreparedRequest]) -> OpenAPIRequest:
"""
Converts a requests request to an OpenAPI one
Internally converts to a `PreparedRequest` first to parse the exact
payload being sent
"""
if isinstance(request, Request):
request = request.prepare()
# Method
method = request.method.lower()
cookie = request.cookies or {}
# Cookies
if request._cookies is not None:
# cookies are stored in a cookiejar object
cookie = request._cookies.get_dict()
else:
cookie = {}
# Preparing a request formats the URL with params, strip them out again
o = urlparse(request.url)
params = parse_qs(o.query)
# extract the URL without query parameters
url = o._replace(query=None).geturl()
# gets deduced by path finder against spec
path = {}
mimetype = request.headers.get('Accept') or \
request.headers.get('Content-Type')
# Order matters because all python requests issued from a session include
# Accept */* which does not necessarily match the content type
mimetype = request.headers.get('Content-Type') or \
request.headers.get('Accept')
# Headers - request.headers is not an instance of dict, which is expected
header = dict(request.headers)
# Body
# TODO: figure out if request._body_position is relevant
body = request.body
parameters = RequestParameters(
query=ImmutableMultiDict(request.params),
header=request.headers,
query=ImmutableMultiDict(params),
header=header,
cookie=cookie,
path=path,
)
return OpenAPIRequest(
full_url_pattern=request.url,
full_url_pattern=url,
method=method,
parameters=parameters,
body=request.data,
body=body,
mimetype=mimetype,
)