lovasoa / marshmallow_dataclass

Automatic generation of marshmallow schemas from dataclasses.
https://lovasoa.github.io/marshmallow_dataclass/html/marshmallow_dataclass.html
MIT License
456 stars 78 forks source link

apispec is broken with 8.5.4 #195

Open CedricCabessa opened 2 years ago

CedricCabessa commented 2 years ago

Hi, I'm using marshmallow-dataclass with Flask, the documentation is generated via api-spec

Since version 8.5.4 I observed a regression. The object model are not generated in the openapi file.

Here a exemple to reproduce (sorry I tried to minimise it, but it is a bit long)

from flask import Flask
from apispec import APISpec
from marshmallow_dataclass import dataclass
from apispec.ext.marshmallow import MarshmallowPlugin
from apispec_webframeworks.flask import FlaskPlugin

@dataclass
class Foo:
    val: str

# UNCOMMENT THIS LINE MAKE IT WORKS
# Foo.Schema()

spec = APISpec(
    title="title",
    version="0.1",
    openapi_version="3.0.2",
    plugins=[FlaskPlugin(), MarshmallowPlugin()],
)

app = Flask("demo")

@app.route("/")
def hello():
    """Get api users
    ---
    get:
      summary: sum
      responses:
        200:
          content:
            application/json:
              schema: Foo
    """
    return Foo(val="bar")

with app.test_request_context():
    for rule in app.url_map.iter_rules():
        view = app.view_functions.get(rule.endpoint)
        spec.path(view=view)

print(spec.to_dict())

This snippet setup a flask project that return a payload documented by apispec

Running this project print an openapi yaml file

{'paths': {'/': {'get': {'summary': 'sum', 'responses': {'200': {'content': {'application/json': {'schema': {'$ref': '#/components/schemas/Foo'}}}}}}}, '/static/{filename}': {}}, 'info': {'title': 'title', 'version': '0.1'}, 'openapi': '3.0.2'}

However this file is invalid as $ref': '#/components/schemas/Foo' is never defined

What we need to do is instantiate the schema once with Foo.Schema() now we get

{'paths': {'/': {'get': {'summary': 'sum', 'responses': {'200': {'content': {'application/json': {'schema': {'$ref': '#/components/schemas/Foo'}}}}}}}, '/static/{filename}': {}}, 'info': {'title': 'title', 'version': '0.1'}, 'openapi': '3.0.2', 'components': {'schemas': {'Foo': {'type': 'object', 'properties': {'val': {'type': 'string'}}, 'required': ['val']}}}}

I tracked the regression on https://github.com/lovasoa/marshmallow_dataclass/pull/170/files#diff-3d998111751e2042da9789eb7a8181144cb7256d31e243ec09a23f639f10ee21R204

tl;dr: Delaying Schema instantiation break api-spec

Maybe the fix should be in api-spec or MarshmallowPlugin (I haven't dig yet)

Do you have suggestion on how to fix this ? cc @AleksanderPawlak