apispec-oneofschema

raw JSON →
3.0.2 verified Thu Apr 16 auth: no python

apispec-oneofschema is a plugin for apispec that extends its functionality to provide support for Marshmallow-OneOfSchema schemas. It enables the generation of OpenAPI documentation for polymorphic schemas defined using marshmallow-oneofschema. The current version is 3.0.2, and it is actively maintained.

pip install apispec-oneofschema
error DuplicateComponentNameError: Another schema with name "SchemaA" is already registered.
cause Attempting to register multiple `OneOfSchema` instances that include the same underlying schema (e.g., `SchemaA` is part of both `SchemaAorB` and `SchemaAorC`). `apispec` attempts to register `SchemaA` multiple times during the processing of `OneOfSchema`s.
fix
Explicitly register shared sub-schemas (like SchemaA) once with spec.components.schema('SchemaA', schema=SchemaA) *before* registering the OneOfSchemas that depend on it. This ensures it's only defined once.
error OpenAPI documentation does not show 'oneOf' schemas or discriminator properties for `Marshmallow-OneOfSchema`.
cause The `apispec` library, specifically in combination with `apispec-oneofschema`, may not correctly process and render `oneOf` definitions due to an outstanding bug/issue (e.g., `apispec` Issue #1012). Also, ensure `openapi_version` is 3.0.0 or higher.
fix
Verify that openapi_version in APISpec initialization is '3.0.0' or greater. If the issue persists, consult the GitHub issues for both apispec and apispec-oneofschema for potential workarounds or updates. Ensure marshmallow-oneofschema is correctly configured with type_schemas and type_field (if customizing).
breaking This plugin only supports OpenAPI Specification version 3.0.0 or greater. It relies on features like the `discriminator` which were introduced in OpenAPI 3.0.0.
fix Ensure `openapi_version` is set to '3.0.0' or higher when initializing `APISpec`.
gotcha When registering multiple `OneOfSchema` instances that share common sub-schemas (e.g., `SchemaA` in both `SchemaAorB` and `SchemaAorC`), `apispec` may raise a `DuplicateComponentNameError` if the shared schema is registered implicitly more than once.
fix Manually register common sub-schemas only once via `spec.components.schema()` before registering the `OneOfSchema` instances. Alternatively, catch and handle `DuplicateComponentNameError` if the duplicate component is guaranteed to be identical.
gotcha There is an open issue in `apispec` (Issue #1012) where `apispec` might ignore `oneOf` definitions coming from `marshmallow-oneofschema`, leading to incomplete or incorrect OpenAPI documentation for polymorphic schemas.
fix There is no direct user fix. Check the `apispec` and `apispec-oneofschema` GitHub repositories for updates on Issue #1012, or potential workarounds/newer versions that address this.

This quickstart demonstrates how to define a polymorphic schema using `marshmallow-oneofschema.OneOfSchema` and then integrate it with `apispec` using `apispec-oneofschema.MarshmallowPlugin` to generate an OpenAPI specification. Ensure `openapi_version` is set to '3.0.0' or greater.

from apispec import APISpec
from marshmallow import Schema, fields
from marshmallow_oneofschema import OneOfSchema
from apispec_oneofschema import MarshmallowPlugin

class TreeSchema(Schema):
    leaves = fields.Int(required=True)

class FlowerSchema(Schema):
    blooming = fields.Bool(required=True)

class PlantSchema(OneOfSchema):
    type_schemas = {
        'tree': TreeSchema,
        'flower': FlowerSchema
    }

spec = APISpec(
    title='Botany',
    version='1.0.0',
    openapi_version='3.0.0', # Must be 3.0.0 or greater
    plugins=[
        MarshmallowPlugin(),
    ]
)

spec.components.schema('Plant', schema=PlantSchema)
spec.components.schema('Tree', schema=TreeSchema)
spec.components.schema('Flower', schema=FlowerSchema)

# Optional: Add schemas that are part of OneOfSchema directly to components
# spec.components.schema('Tree', schema=TreeSchema)
# spec.components.schema('Flower', schema=FlowerSchema)

print(spec.to_yaml())