apispec icon indicating copy to clipboard operation
apispec copied to clipboard

What to do about multiple nested schemas warning?

Open revmischa opened this issue 5 years ago • 9 comments

Originally reported here: https://github.com/Nobatek/flask-rest-api/issues/57 - see there for more input

--

I'm using marshmallow v3-rc5 and using two-way nesting Using this technique I get the following error if I attempt to use something like @blp.response(CreatorSchema(many=True, exclude=('follower_count',))):

/Users/cyber/.virtualenvs/luve-pim5aQIP/lib/python3.7/site-packages/apispec/ext/marshmallow/common.py:143: 
UserWarning: Multiple schemas resolved to the name Creator. The name has been modified. Either manually add each of the schemas with a different name or provide a custom schema_name_resolver.

and see multiple versions of the schema in swagger (Creator, Creator1).

If I remove the exclude arg to my schemas and make new schemas then everything works perfectly. Something about exclude causes it to think there are multiple versions of the schema and it all explodes.

revmischa avatar May 03 '19 14:05 revmischa

As I explained in https://github.com/Nobatek/flask-rest-api/issues/57, since a field is excluded, these are indeed different schemas, so apispec is doing the right thing by creating separate schemas in the spec.

We added a warning because we figured the user might not be aware of this (your example proves us right) and he would probably want to set explicit names himself (manually or with a custom name resolver) rather than relying on the default name+increment.

Since you seem to think the default automatic naming is fine, there are two things we could do

  • make this a custom warning to make it easier to filter globally (not sure how I'd do that, but with a custom warning, it should be easier)
  • add an opt-in parameter to prevent emitting the warning

lafrech avatar May 03 '19 14:05 lafrech

I'm fine with the behavior I just want to shut it up.

revmischa avatar May 04 '19 12:05 revmischa

I used https://github.com/Nobatek/flask-rest-api/issues/38#issuecomment-495527421 as a base for the custom schema resolver, but I don't know how to check if partial is passed or not. I assume the same goes for exclude.

mekanix avatar Jul 15 '19 23:07 mekanix

Since you seem to think the default automatic naming is fine, there are two things we could do

  • make this a custom warning to make it easier to filter globally (not sure how I'd do that, but with a custom warning, it should be easier)
  • add an opt-in parameter to prevent emitting the warning

Any decision made about this? In most cases a custom resolver would do exactly the same things as the base resolver except for the warning.. so an option to silent the warning would be appealing

mdantonio avatar Jun 01 '20 05:06 mdantonio

any update about this?

azzamsa avatar Jul 20 '20 08:07 azzamsa

For now I have silenced the warning and I forgot about it. Not a very elegant solution, but it seems to work:

import warnings
warnings.filterwarnings(
    "ignore",
    message="Multiple schemas resolved to the name "
)

Probably an official option to silence the warning would be better, but for the moment this very rough approach is enough for me

mdantonio avatar Jul 20 '20 09:07 mdantonio

@mdantonio I've tried to put it under my flask create_app functions, unfortunately it doesn't work.

def create_app(config_name):
    app = Flask("FOO")
    app.config.from_object(config_by_name[config_name])
    register_extensions(app)
    register_blueprints(app)
    configure_logger(app)

    warnings.filterwarnings(
        "ignore",
        message="Multiple schemas resolved to the name Gateway. The name has been modified. Either manually add each of the schemas with a different name or provide a custom schema_name_resolver.",
    )
    return app

I also tried to use only some part of the warning message "Multiple schemas resolved to the name ", but doesn't work too

warnings.filterwarnings(
    "ignore",
    message="Multiple schemas resolved to the name "
)

azzamsa avatar Jul 20 '20 09:07 azzamsa

Try to move it before the loading of the endpoints, probably after the blueprints registration the app already raised such warnings

mdantonio avatar Jul 20 '20 09:07 mdantonio

Nice idea, worked like a charm. Now I can have clean log. Thank you.

azzamsa avatar Jul 20 '20 09:07 azzamsa