openapi-core
openapi-core copied to clipboard
Falcon request factory not working
With the latest openapi-core
version (i.e. 0.14.2
) Falcon request factory (i.e. FalconOpenAPIRequestFactory
) not working at all. It's the same behavior with embedded middleware and custom one.
Code for reproducing:
import logging
import json
import falcon
from wsgiref import simple_server
from openapi_core import create_spec
from openapi_spec_validator.schemas import read_yaml_file
from openapi_core.validation.request.validators import RequestValidator
from openapi_core.contrib.falcon import FalconOpenAPIRequestFactory
# from openapi_core.contrib.falcon.middlewares import FalconOpenAPIMiddleware
logging.basicConfig()
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
class Resource:
def on_get(self, req, resp):
logger.info('Calling GET...')
resp.body = json.dumps({'foo': 'bar'})
resp.status = falcon.HTTP_200
class OpenAPI3Middleware:
def __init__(self, spec_dict):
try:
self.spec = create_spec(spec_dict)
self.spec.security = []
except Exception:
logger.exception('Failed to create OpenAPI 3 spec from input dict.')
raise
def process_resource(self, req, resp, resource, params):
logger.info('Processing request...')
openapi_request = FalconOpenAPIRequestFactory().create(req)
logger.info('Validating request...')
validator = RequestValidator(self.spec)
result = validator.validate(openapi_request)
result.raise_for_errors()
if __name__ == '__main__':
spec_dict = read_yaml_file('swagger.yml')
openapi_middleware = OpenAPI3Middleware(spec_dict)
# openapi_middleware = FalconOpenAPIMiddleware.from_spec(spec_dict)
falcon_app = falcon.App(middleware=[openapi_middleware])
test_resource = Resource()
falcon_app.add_route('/v1/test', test_resource)
httpd = simple_server.make_server('127.0.0.1', 8000, falcon_app)
logger.info('Now serving on port 8000')
httpd.serve_forever()
Swagger spec for above example:
openapi: 3.0.1
info:
version: 1.0.0
title: Test
description: Test description.
servers:
- url: http://localhost:8000
description: Local server instance
tags:
- name: Test
description: Test description.
paths:
/v1/test:
get:
tags:
- Test
summary: Test resource
description: Test resource
responses:
200:
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/job_response'
components:
securitySchemes:
jwt_token:
type: http
scheme: bearer
schemas:
job_response:
type: object
security:
- jwt_token: []
GET
to http://localhost:8000/v1/test
gives error:
{
"title": "415 Unsupported Media Type",
"description": "text/plain is an unsupported media type."
}
Maybe I'm missing something here!? This is pretty critical issue for me, I'm not able to upgrade openapi-core
to the latest version, which brings pretty much other bugfixes. :(
Falcon version is the latest one, i.e. 3.0.1
.
Btw, from which openapi-core
version is dropped off support for Falcon <3.0.0
? Not sure what is reason for this?!
This behavior is reproducing from version 0.13.4
, i.e. last working version is 0.13.3
.
Does it work for master branch?
Falcon <3.0 was dropped on master.
@p1c2u Will check as soon as I get chance and respond here. Thanks!
@p1c2u @stojan-jovic This is still happening on 0.14.2 with Falcon 3.0.1. Furthermore, if I try with:
curl --request GET \
--url http://localhost:8000/v1/test \
--header 'content-type: application/json'
I get the following:
2022-01-18 14:07:23 [FALCON] [ERROR] GET /v1/test => Traceback (most recent call last):
File "/Users/alex/dev/recipe-book/backend/api/venv/lib/python3.10/site-packages/falcon/app.py", line 323, in __call__
process_request(req, resp)
File "/Users/alex/dev/recipe-book/backend/api/venv/lib/python3.10/site-packages/openapi_core/contrib/falcon/middlewares.py", line 29, in process_request
req_result = super(FalconOpenAPIMiddleware, self).process_request(
File "/Users/alex/dev/recipe-book/backend/api/venv/lib/python3.10/site-packages/openapi_core/validation/processors.py", line 11, in process_request
return self.request_validator.validate(request)
File "/Users/alex/dev/recipe-book/backend/api/venv/lib/python3.10/site-packages/openapi_core/validation/request/validators.py", line 30, in validate
path, operation, _, path_result, _ = self._find_path(request)
File "/Users/alex/dev/recipe-book/backend/api/venv/lib/python3.10/site-packages/openapi_core/validation/validators.py", line 24, in _find_path
return finder.find(request)
File "/Users/alex/dev/recipe-book/backend/api/venv/lib/python3.10/site-packages/openapi_core/templating/paths/finders.py", line 25, in find
if not paths_iter_peek:
File "/Users/alex/dev/recipe-book/backend/api/venv/lib/python3.10/site-packages/more_itertools/more.py", line 316, in __bool__
self.peek()
File "/Users/alex/dev/recipe-book/backend/api/venv/lib/python3.10/site-packages/more_itertools/more.py", line 330, in peek
self._cache.append(next(self._it))
File "/Users/alex/dev/recipe-book/backend/api/venv/lib/python3.10/site-packages/openapi_core/templating/paths/finders.py", line 45, in _get_paths_iter
paths = self.spec / 'paths'
TypeError: unsupported operand type(s) for /: 'dict' and 'str'
Interestingly, I have a large app I am working on where it's working fine (I was trying to repo a different issue), but there's too much code to provide a snippet as it is. I'll try to figure out what's different between them.