GithubHelp home page GithubHelp logo

Comments (11)

sloria avatar sloria commented on May 25, 2024 1

@zedrdave thanks for volunteering!

i believe the relevant method is field2type_and_format, which takes a marshmallow field and returns the corresponding OAI type and format as a dict.

relevant test is here:

def test_enum_value_field(spec_fixture, by_value):

from apispec.

Bangertm avatar Bangertm commented on May 25, 2024 1

A couple more details on how the type is decided:

For enum fields there is enum2properties. This is indirectly calling field2type_and_format with the enum field's field.field property. In the case where by_value is True, field.field is a marshmallow.fields.Field instance. This class is set to have no type property in the field mapping:

marshmallow.fields.Field: (None, None),

That's typically because apispec can't infer the type of a generic field.

Not sure what the proper behavior would be in this case because I don't have any experience working with enum fields.

from apispec.

zedrdave avatar zedrdave commented on May 25, 2024

@sloria if you are able to point me in the direction of the code that defines how that type is decided, I would be happy to dig further and hopefully submit a PR

from apispec.

zedrdave avatar zedrdave commented on May 25, 2024

@Bangertm thanks for diving into this further. I must admit I'll need a bit of time to potentially wrap my head around that field.field thing… I don't quite understand why it would be Field in the by_value = True case, and not when False

But basically the behaviour we want to achieve is: type = "string" no matter what, if the Field is enum
It seems like adding a simple ret["type"] = "string" on line 515 would fix it, but I suspect this is not the cleanest way to do it…

from apispec.

zedrdave avatar zedrdave commented on May 25, 2024

@Bangertm OK, I think I understand better, and as best as I can tell, this is an upstream issue with Marshmallow setting field to Field() in the by_value case instead of string otherwise (not sure I understand the reasoning): https://marshmallow.readthedocs.io/en/stable/_modules/marshmallow/fields.html#Enum

Short of this being changed upstream, it seems like the only option would be to correct it inside enum2properties as I suggested above, maybe around line 518…?

from apispec.

zedrdave avatar zedrdave commented on May 25, 2024

FWIW: passing by_value=fields.String instead of by_value=True does fix the problem…
But I am not sure it makes sense ever omitting the string type for Enums in OpenAPI, so maybe checking for by_value is True and setting it if missing, would be a good way to solve this?

from apispec.

lafrech avatar lafrech commented on May 25, 2024

I don't remember the whole story, there may be retro-compatibility involved, but I think the rationale in marshmallow is that when using by_value=True, without any more information about the value type, marshmallow can only use Field and hope the value doesn't need any serialization specifics. Any non-trivial type must pass a field class. In fact, even strings "should" probably pass a field type. Should marshmallow set String by default? Not sure.

In any case, my advice would be to set by_value=ma.fields.String when needed.

I wouldn't expect apispec to set a string type if nothing is specified. If values are integers, for instance, documenting them as string would be wrong.

from apispec.

zedrdave avatar zedrdave commented on May 25, 2024

Indeed, by_value=ma.fields.String does fix it.
It seems a little weird to me that this is needed, when Marshmallow could, at the very least, infer the enum type and use that (or just assume str unless a Field is specified), but that is indeed more of a Marshmallow usability issue than apispec.

I'm not sure I see how adding a default type (if no Field is specified) would hurt:

  • in the vast majority of cases (regular string enum), it would prevent people bumping into the same weird issue.
  • in cases where people explicitly want a numeric enum, they can specify Field

from apispec.

lafrech avatar lafrech commented on May 25, 2024

I understand. But I still think explicit is better than implicit. Also, I'm afraid using String rather than Field if nothing is specified would be a breaking change.

More history here if you're interested (I'm the author of the PRs adding Enum to marshmallow):
marshmallow-code/marshmallow#2017
marshmallow-code/marshmallow#2044

We use Field by default no deserialization is needed since Enum validates the content anyway so we don't really care. And we figured people wouldn't bother setting a field for this reason, but it appears this doesn't work well for the apispec case (hence this issue).

from apispec.

zedrdave avatar zedrdave commented on May 25, 2024

I would argue there is already a strong implicit behaviour (people setting by_value to True and assuming everything will work), but you definitely have a better view on the overall problem, so I'll defer to you.

I would still recommend finding a way to warn users of that behaviour (if only by putting a note in marshmallow's Enum doc recommending to set by_value to an explicit type if possible).

Happy to close this in any case.

from apispec.

sloria avatar sloria commented on May 25, 2024

Upon reading this thread more closely, I agree that explicitly passing a field to by_value is the best approach. I've added a specific note about this in the docs in #876 .

Closing for now. Thanks for the discussion all!

from apispec.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.