Comments (11)
@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:
apispec/tests/test_ext_marshmallow_field.py
Line 294 in fb58570
from apispec.
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:
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.
@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.
@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.
@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.
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.
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.
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.
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.
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.
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)
- Marshmallow OpenApiConverter does not support str openapi_version HOT 4
- Incorrect handling of nullable enums in marshmallow converter HOT 2
- Issue with nested self-referencing schemas HOT 2
- Marshmallow plugin doesn't document the format of fields.DateTime() correctly HOT 3
- marshmallow plugin does not support `marshmallow.fields.Tuple` HOT 1
- What is the correct way to use add_attribute_function in the Marshmallow plugin? HOT 2
- additionalProperties=false is not set when using default Marshmallow schema options HOT 2
- callbacks in operation are not resolved to refs HOT 5
- wrong default value for 'name' in schema2parameters HOT 3
- parameters not being resolved for OAS3 'content' type parameters HOT 2
- Incorrect handling of marshmallow nested schema with allow_none=True in OpenAPI 3.1 HOT 4
- Incorrect handling of Union types HOT 2
- Deprecated flag is not configured correctly on query parameter objects
- sdist is missing `tox.ini` HOT 1
- Interest in taking Schema description from Schema.__doc__ docstring
- Incorrectly serialized format when using a range validator on a Decimal Marshmallow field HOT 10
- Document form data and images
- Deprecate __version__ attribute
- Add requestBody component HOT 14
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from apispec.