marshmallow_enum
marshmallow_enum copied to clipboard
Add support for Apispec / OpenApi
OpenApi spec allows defining enumerations, following the JSON Schema validation. Apispec allows generating such OpenApi spec from Marshmallow schemas.
Currently Apispec does not get enumeration information from MarshmallowEnum. It is easy to add support by doing something like the following in the __init__ of the EnumField class:
self.metadata['enum'] = [e.name for e in enum]
metadata is a property of Field that apispec uses to retrieve OpenApi-related fields.
Currently I am achieving the same by doing:
class ApispecEnumField(EnumField):
def __init__(self, enum, by_value=False, load_by=None, dump_by=None, error='', *args,
**kwargs):
super().__init__(enum, by_value, load_by, dump_by, error, *args, **kwargs)
self.metadata['enum'] = [e.name for e in enum]
Finally I would like to thank you for your package :-)
I'm +1 on this, I'd accept that PR too. One thing it'd need to keep in mind is that the field might expect the enum values to be either their names OR their values and it could change depending on if things are being dumped or loaded.
I've not looked at Apispec so I'm not sure if it supports that particular situation.
I think fix should looks like this:
class ApispecEnumField(ma_enum.EnumField):
def __init__(self, enum_value, by_value=False, load_by=None, dump_by=None, error='', *args, **kwargs):
super().__init__(enum_value, by_value, load_by, dump_by, error, *args, **kwargs)
if self.load_by == ma_enum.LoadDumpOptions.name:
enum_meta = [e.name for e in enum_value]
elif self.load_by == ma_enum.LoadDumpOptions.value:
enum_meta = [e.value for e in enum_value]
else:
raise NotImplementedError
self.metadata['enum'] = enum_meta
to show correct Enum values in Openapi/Swagger cause we depends on how data will be dumped or loaded
PS: i rename enum -> enum_value cause it shadows builtin package name
I've run into this exact issue as well, is there any word on merging either #25 or #27 to resolve it? Or anything we can do to help it along? Thanks for a great project!
I added a fork (based on #25) that fixes this issue (while removing the load_by/dump_by ambiguity) at https://github.com/h/marshmallow_enum
This issue hasn't been fixed/merged since 2018, so if anyone else needs support for APISpec with marshmallow, simply run:
$ pip install -e git+https://github.com/h/marshmallow_enum#egg=marshmallow-enum
Just an FYI - as of version 3.0 of APISpec there is support for adding custom extensions for converting fields to OpenAPI properties. See the documentation for an example and the api.
Instead of changing the internal structure of the EnumField to match what builtin function in APISpec it may be simpler to provide a function that translates EnumField to an OpenAPI enum. It may be convenient to include that function in this library as a convenience for users and so that it is always easy to change the internal structure of EnumField without impacting documentation.
Hi I also need this feature. Is there any plan to add this feature?
@h would you consider adding your fork with new name to pip?
Thanks @Bangertm, here is what your suggestion gives
from marshmallow_enum import EnumField
ma_plugin = MarshmallowPlugin()
def enumfield_custom_field2properties(self, field, **kwargs):
ret = {}
if isinstance(field, EnumField):
ret["type"] = "string"
if field.by_value:
values = [e.value for e in field.enum]
else:
values = [e.name for e in field.enum]
ret["enum"] = values
return ret
ma_plugin.converter.add_attribute_function(enumfield_custom_field2properties)
@jitka consider this workaround.