Skip to content
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

Models nested inside response fields aren't registered #613

Open
panda-byte opened this issue Aug 12, 2024 · 0 comments · May be fixed by #614
Open

Models nested inside response fields aren't registered #613

panda-byte opened this issue Aug 12, 2024 · 0 comments · May be fixed by #614
Labels
bug Something isn't working

Comments

@panda-byte
Copy link

panda-byte commented Aug 12, 2024

Code

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.

@panda-byte panda-byte added the bug Something isn't working label Aug 12, 2024
panda-byte pushed a commit to panda-byte/flask-restx that referenced this issue Aug 12, 2024
Fix python-restx#613. When using e.g. `fields.List` for response structures, any models nested inside are now correctly registered.
panda-byte pushed a commit to panda-byte/flask-restx that referenced this issue Aug 12, 2024
@panda-byte panda-byte linked a pull request Aug 12, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant