fuhrysteve / marshmallow-jsonschema

JSON Schema Draft v7 (http://json-schema.org/) formatting with marshmallow
MIT License
208 stars 73 forks source link

Cannot generate top level array schemas #92

Open yeralin opened 5 years ago

yeralin commented 5 years ago

Consider following schema:

from marshmallow import Schema, fields

class UserSchema(Schema):
    username = fields.String()
    age = fields.Integer()

Now, say my payload is of this form:

[{"username": "test-1", "age": 1}, {"username": "test-2", "age": 2}]

The JSON Schema that could describe this payload could be:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "array", <- important part
  "definitions": {
      "UserSchema": {
        "items": {
            "properties": {
              "username": {
                "type": "string",
                "title": "username"
              },
              "age": {
                "type": "number",
                "format": "integer"
                "title": "age"
              }
            }
          }
      }
  }
}

So, in theory to generate this schema using marshmallow-jsonschema we could do the following:

user_schema = UserSchema(many=True)
JSONSchema().dump(user_schema).data

However, that's not the case. The resulting schema would be:

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$ref": "#/definitions/UserSchema",
    "definitions": {
        "UserSchema": {
            "properties": {
                "age": {
                    "title": "age",
                    "type": "number",
                    "format": "integer"
                },
                "username": {
                    "title": "username",
                    "type": "string"
                }
            },
            "type": "object", <- notice, type is always "object"
            "additionalProperties": false
        }
    }
}

Setting many=True during schema instantiation does not affect the resulting JSON schema. According to https://github.com/fuhrysteve/marshmallow-jsonschema/blob/307a911c38a4d827d06794a04f29794fee788c4a/marshmallow_jsonschema/base.py#L81 It will always be set to "type": "object" irregardless of many option.

lindycoder commented 3 years ago

This quick fix seems to work for me:

    schema = JSONSchema().dump(MySchema(many=True))  # Note that the many=true is ignored
    schema.update(
        type='array',
        items={
            'type': 'object',
            '$ref': schema.pop('$ref'),
        },
    )