validation traceback when having cascading $ref in definitions
- Dominant language
- Python
- Stars
- 3.7k
- Forks
- 525
- PR merge metrics
- No merged PRs in 30d
Description
I have a single yaml file for all the paths and definitins I need (see test_ref.yaml)
validation for the test endpoint works great but I get a traceback when trying to validate test2.
The only difference is that one parameter if defined as a $ref...
```
127.0.0.1 - - [18/Feb/2020 19:27:53] "POST /test2 HTTP/1.1" 500 -
Traceback (most recent call last):
File "/home/dev/venv/lib/python3.6/site-packages/flask/app.py", line 2463, in __call__
return self.wsgi_app(environ, start_response)
File "/home/dev/venv/lib/python3.6/site-packages/flask/app.py", line 2449, in wsgi_app
response = self.handle_exception(e)
File "/home/dev/venv/lib/python3.6/site-packages/flask/app.py", line 1866, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/dev/venv/lib/python3.6/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/home/dev/venv/lib/python3.6/site-packages/flask/app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "/home/dev/venv/lib/python3.6/site-packages/flask/app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/dev/venv/lib/python3.6/site-packages/flask/app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/dev/venv/lib/python3.6/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/home/dev/venv/lib/python3.6/site-packages/flask/app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "/home/dev/venv/lib/python3.6/site-packages/flask/app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/dev/venv/lib/python3.6/site-packages/flasgger/utils.py", line 253, in wrapper
**validate_args
File "/home/dev/venv/lib/python3.6/site-packages/flasgger/utils.py", line 412, in validate
main_def = __replace_ref(main_def, relative_path, all_definitions)
File "/home/dev/venv/lib/python3.6/site-packages/flasgger/utils.py", line 272, in __replace_ref
new_value[key] = __replace_ref(value, relative_path, all_definitions)
File "/home/dev/venv/lib/python3.6/site-packages/flasgger/utils.py", line 272, in __replace_ref
new_value[key] = __replace_ref(value, relative_path, all_definitions)
File "/home/dev/venv/lib/python3.6/site-packages/flasgger/utils.py", line 279, in __replace_ref
with open(file_ref_path) as file:
FileNotFoundError: [Errno 2] No such file or directory: '/home/jolin/dev/#/definitions/SubType'
```
test_ref.yaml :
```
swagger: '2.0'
################################################################################
# API Information #
################################################################################
info:
version: '1.0'
title: test
description: |
test "recursive" $ref definitions for input parameters
################################################################################
# Host, Base Path, Schemes and Content Types #
################################################################################
# The host (name or ip) serving the API
host: localhost:5000
# The base path on which the API is served, relative to the host. Will be prefixed to all paths. Used to control versioning
basePath: /
# The transfer protocol of the API
schemes:
- http
# Format of bodies a client can send (Content-Type)
consumes:
- application/json
# Format of the responses to the client (Accepts)
produces:
- application/json
################################################################################
# Paths #
################################################################################
paths:
/test:
post:
tags:
- test-test
operationId: testPOST
consumes:
- application/json
produces:
- application/json
parameters:
- in: body
name: request
description: request
required: true
schema:
$ref: '#/definitions/TestRequest'
responses:
'200':
description: OK
schema:
type: array
items:
$ref: '#/definitions/Test'
'201':
description: Created
'401':
description: Unauthorized
'403':
description: Forbidden
'404':
description: Not Found
deprecated: false
/test2:
post:
tags:
- test2
operationId: test2UsingPOST
consumes:
- application/json
produces:
- application/json
parameters:
- in: body
name: request
description: request
required: true
schema:
$ref: '#/definitions/Test2Request'
responses:
'200':
description: OK
schema:
type: array
items:
$ref: '#/definitions/Test'
'201':
description: Created
'401':
description: Unauthorized
'403':
description: Forbidden
'404':
description: Not Found
deprecated: false
definitions:
Test:
type: object
properties:
capacity:
type: integer
format: int32
description: the capacity
contactName:
type: string
description: Contact name
title: Test
TestRequest:
type: object
properties:
a:
description: a string parameter
type: string
p:
type: integer
description: an integer parameter
s:
type: object
properties:
p1:
type: string
p2:
type: integer
p3:
type: string
format: 'date-time'
title: TestRequest
Test2Request:
type: object
properties:
a:
description: a string parameter
type: string
p:
type: integer
description: an integer parameter
s:
$ref: '#/definitions/SubType'
title: Test2Request
SubType:
type: object
properties:
p1:
type: string
p2:
type: integer
p3:
type: string
format: 'date-time'
title: SubType
```
test_ref.py :
```
from flask import Flask, jsonify, request as flask_request
from flasgger import swag_from, Swagger
swagger_description_file = 'test_ref.yaml'
if __name__ == '__main__':
app = Flask(__name__)
swagger = Swagger(app, template_file=swagger_description_file)
@app.route('/test', methods=['POST'])
@swag_from(swagger.template, definition='TestRequest', validation=True)
def test():
req = flask_request.json
print('req:', req)
# validate(req, None, swagger_description)
return 'ok'
@app.route('/test2', methods=['POST'])
@swag_from(swagger.template, definition='Test2Request', validation=True)
def test2():
req = flask_request.json
print('req:', req)
# validate(req, None, swagger_description)
return 'ok'
app.run(debug=True)
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by running test_ref.py with test_ref.yaml and reproducing the POST to /test2, then compare it with /test. Trace the validation path shown in flasgger/utils.py, especially __replace_ref; done means the cascading #/definitions/SubType reference validates without FileNotFoundError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- flask, openapi, python
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100