Merge pull request #316 from BontaVlad/bugfix-311-falcon-get-media-error

Bugfix 311 falcon get media error
This commit is contained in:
A 2021-05-01 01:01:32 +01:00 committed by GitHub
commit c23f9fe12b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 41 additions and 9 deletions

View file

@ -0,0 +1,24 @@
"""OpenAPI core contrib falcon compat module"""
try:
from falcon import App # noqa: F401
HAS_FALCON3 = True
except ImportError:
HAS_FALCON3 = False
def get_request_media(req, default=None):
# in falcon 3 media is deprecated
return req.get_media(default_when_empty=default) if HAS_FALCON3 else \
(req.media if req.media else default)
def get_response_text(resp):
# in falcon 3 body is deprecated
return getattr(resp, 'text') if HAS_FALCON3 else \
getattr(resp, 'body')
def set_response_text(resp, text):
# in falcon 3 body is deprecated
setattr(resp, 'text', text) if HAS_FALCON3 else \
setattr(resp, 'body', text)

View file

@ -5,6 +5,8 @@ from falcon.constants import MEDIA_JSON
from falcon.status_codes import (
HTTP_400, HTTP_404, HTTP_405, HTTP_415,
)
from openapi_core.contrib.falcon.compat import set_response_text
from openapi_core.templating.media_types.exceptions import MediaTypeNotFound
from openapi_core.templating.paths.exceptions import (
ServerNotFound, OperationNotFound, PathNotFound,
@ -36,11 +38,12 @@ class FalconOpenAPIErrorsHandler(object):
data = {
'errors': data_errors,
}
data_str = dumps(data)
data_error_max = max(data_errors, key=lambda x: x['status'])
resp.content_type = MEDIA_JSON
resp.status = cls.FALCON_STATUS_CODES.get(
data_error_max['status'], HTTP_400)
resp.body = dumps(data)
set_response_text(resp, data_str)
resp.complete = True
@classmethod

View file

@ -3,6 +3,7 @@ from json import dumps
from werkzeug.datastructures import ImmutableMultiDict
from openapi_core.contrib.falcon.compat import get_request_media
from openapi_core.validation.request.datatypes import (
OpenAPIRequest, RequestParameters,
)
@ -11,19 +12,20 @@ from openapi_core.validation.request.datatypes import (
class FalconOpenAPIRequestFactory:
@classmethod
def create(cls, request):
def create(cls, request, default_when_empty={}):
"""
Create OpenAPIRequest from falcon Request and route params.
"""
default = default_when_empty
method = request.method.lower()
# gets deduced by path finder against spec
path = {}
media = get_request_media(request, default=default)
# Support falcon-jsonify.
body = (
dumps(request.json) if getattr(request, "json", None)
else dumps(request.media)
dumps(getattr(request, "json", media))
)
mimetype = request.options.default_media_type
if request.content_type:

View file

@ -1,4 +1,5 @@
"""OpenAPI core contrib falcon responses module"""
from openapi_core.contrib.falcon.compat import get_response_text
from openapi_core.validation.response.datatypes import OpenAPIResponse
@ -13,8 +14,10 @@ class FalconOpenAPIResponseFactory(object):
else:
mimetype = response.options.default_media_type
data = get_response_text(response)
return OpenAPIResponse(
data=response.body,
data=data,
status_code=status_code,
mimetype=mimetype,
)

View file

@ -2,7 +2,8 @@ mock==2.0.0
pytest==3.5.0
pytest-flake8
pytest-cov==2.5.1
falcon==2.0.0
falcon==2.0.0; python_version<"3.0"
falcon==3.0.0; python_version>="3.0"
flask
django==2.2.18; python_version>="3.0"
requests==2.22.0

View file

@ -33,7 +33,6 @@ def request_factory(environ_factory, router):
options = RequestOptions()
# return create_req(options=options, **environ)
req = Request(environ, options)
resource, method_map, params, req.uri_template = router.find(path, req)
return req
return create_request

View file

@ -1,6 +1,6 @@
from json import dumps
from falcon import API
from falcon import API as App
from falcon.testing import TestClient
import pytest
@ -24,7 +24,7 @@ class TestFalconOpenAPIMiddleware(object):
@pytest.fixture
def app(self, middleware):
return API(middleware=[middleware])
return App(middleware=[middleware])
@pytest.yield_fixture
def client(self, app):