marshmallow-code / marshmallow-code/apispec

Issue with nested self-referencing schemas

Open
#813 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

question
Dominant language
Python
Stars
1.2k
Forks
202
Avg merge
3h 38m
Merged PRs (30d)
3

Description

I have an issue with nested self-referencing schema,

```python
class GroupSchema(HasPermissionMixin, ModelSchema):
content = fields.Nested(GroupParamSchema, required=True)

class GroupParamSchema(Schema):
filters = fields.Nested(FilterSchema, required=True, many=True)

class FilterSchema(Schema):
next_filter = fields.Nested("FilterSchema", required=False, allow_none=True)
```

The issue is with `FilterSchema`

I have a helper method that converts Marshmallow Schema to an OpenApiJson object:

```python
def get_openapi_schema(
serializer,
):
spec = APISpec(
title="",
version="",
openapi_version="3.0.2",
plugins=[MarshmallowPlugin(schema_name_resolver=schema_name_resolver)],
)

openapi_schema = OpenAPIConverter(openapi_version="3.0.2",schema_name_resolver=schema_name_resolver,spec=spec)
return {200: openapi_schema.schema2jsonschema(serializer)}
```

The `schema_name_resolver` as described in the docs should not return `None` for Circular schemas

```python
def schema_name_resolver(schema):

schema_name = resolve_schema_cls(schema).__name__
circular = False
values = list(schema.fields.values())

for value in values:
if value.__class__.__name__ == "Nested":
if value.nested == schema_name:
circular = True
break

if circular:
return schema_name

return None
```

But it still complains:

```bash
File "/usr/local/lib/python3.9/site-packages/apispec/ext/marshmallow/openapi.py", line 297, in get_ref_dict
ref_schema = self.spec.components.get_ref("schema", self.refs[schema_key])
KeyError: (, None, frozenset(), frozenset(), frozenset(), False)
```

And I'm sure that the `schema_name_resolver` is returning a `string` when the schema is circular

Using a resolver as `lambda schema_class: None` will raise the error below which is understandable!
```bash
apispec.exceptions.APISpecError: Name resolver returned None for schema which is part of a chain of circular referencing schemas. Please ensure that the schema_name_resolver passed to MarshmallowPlugin returns a string for all circular referencing schemas.
```

I'm using:
```
Django==4.0.8
apispec==6.0.2
marshmallow==3.19.0
Debian GNU/Linux 11 (bullseye)
```

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure with the nested GroupSchema, GroupParamSchema, and self-referencing FilterSchema shown in the issue. Start at apispec/ext/marshmallow/openapi.py:get_ref_dict and trace how the resolver result becomes the circular schema reference key. Done means the schema conversion completes without the KeyError and produces a valid reference for FilterSchema.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.