from flask import Flask
from flask_restx import Resource, Api, fields
app = Flask(__name__)
api = Api(app)
model = api.model('Model', {'foo': fields.String})
# @api.route('/get-one')
# @api.doc(model=model)
# class One(Resource):
# def get(self):
# return {'foo': "bar"}
@api.route('/get-many')
@api.doc(model=fields.List(fields.Nested(model)))
class Many(Resource):
def get(self):
return [{'foo': "bar"}]
if __name__ == '__main__':
app.run(debug=True)
Expected Behavior
The Swagger doc page should show the get-many endpoint with Model used for the response documentation. Model should appear in the list of models at the end.
Actual Behavior
Model is not included in the list of models, and when the endpoint is expanded, an error is displayed:
Resolver error at paths./get-many.get.responses.200.schema.items.$ref
Could not resolve reference: Could not resolve pointer: /definitions/Model does not exist in document
Environment
Python version: 3.10
Flask version: 2.3.2
Flask-RESTX version: 1.3.0
Additional Context
If the get-one endpoint is uncommented, the behavior is as expected. The cause of the error is in serialize_schema in swagger.py, which gets called to serialize the documentation for the model argument. When a model is passed, it is correctly registered, as well as any nested models. However, if a fields.List(fields.Nested(model)) is passed like in the example, the nested model isn't included. The easiest fix is to include a call to register_field(model) for fields, which
is also called to detect models nested inside other models. I will open a pull request with the proposed solution.
A similar problem goes for the body parameter of api.doc, which documents the expected data (corresponding to api.expect). However, the arguments allowed for model aren't all covered by body. For example, model allows to specify models via their name as a string, while body doesn't. This problem of inconsistent handling is touched upon in #56.
A workaround is to use RESTX_INCLUDE_ALL_MODELS, which includes all defined models in the Swagger doc, regardless of actual usage.
Code
Expected Behavior
The Swagger doc page should show the
get-many
endpoint withModel
used for the response documentation.Model
should appear in the list of models at the end.Actual Behavior
Model
is not included in the list of models, and when the endpoint is expanded, an error is displayed:Environment
Additional Context
If the
get-one
endpoint is uncommented, the behavior is as expected. The cause of the error is inserialize_schema
inswagger.py
, which gets called to serialize the documentation for themodel
argument. When a model is passed, it is correctly registered, as well as any nested models. However, if afields.List(fields.Nested(model))
is passed like in the example, the nested model isn't included. The easiest fix is to include a call toregister_field(model)
for fields, which is also called to detect models nested inside other models. I will open a pull request with the proposed solution.A similar problem goes for the
body
parameter ofapi.doc
, which documents the expected data (corresponding toapi.expect
). However, the arguments allowed formodel
aren't all covered bybody
. For example,model
allows to specify models via their name as a string, whilebody
doesn't. This problem of inconsistent handling is touched upon in #56.A workaround is to use
RESTX_INCLUDE_ALL_MODELS
, which includes all defined models in the Swagger doc, regardless of actual usage.