Skip to content

Bugfix 311 falcon get media error #316

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions openapi_core/contrib/falcon/compat.py
Original file line number Diff line number Diff line change
@@ -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)
5 changes: 4 additions & 1 deletion openapi_core/contrib/falcon/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
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,
Expand Down Expand Up @@ -36,11 +38,12 @@ def handle(cls, req, resp, errors):
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
Expand Down
8 changes: 5 additions & 3 deletions openapi_core/contrib/falcon/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from werkzeug.datastructures import ImmutableMultiDict

from openapi_core.contrib.falcon.compat import get_request_media
from openapi_core.validation.request.datatypes import (
OpenAPIRequest, RequestParameters,
)
Expand All @@ -11,19 +12,20 @@
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:
Expand Down
5 changes: 4 additions & 1 deletion openapi_core/contrib/falcon/responses.py
Original file line number Diff line number Diff line change
@@ -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


Expand All @@ -13,8 +14,10 @@ def create(cls, response):
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,
)
3 changes: 2 additions & 1 deletion requirements_dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion tests/integration/contrib/falcon/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ def create_request(
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

Expand Down
4 changes: 2 additions & 2 deletions tests/integration/contrib/falcon/test_falcon_middlewares.py
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -24,7 +24,7 @@ def middleware(self, spec):

@pytest.fixture
def app(self, middleware):
return API(middleware=[middleware])
return App(middleware=[middleware])

@pytest.yield_fixture
def client(self, app):
Expand Down