Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON Schema generation #98

Closed
Fatal1ty opened this issue Feb 23, 2023 · 1 comment
Closed

JSON Schema generation #98

Fatal1ty opened this issue Feb 23, 2023 · 1 comment
Labels
enhancement New feature or request

Comments

@Fatal1ty
Copy link
Owner

Fatal1ty commented Feb 23, 2023

Is your feature request related to a problem? Please describe.

Many users, including me, want to generate JSON Schema for their dataclasses. This can be useful for further integration into web frameworks. Thanks to the rich and tested data type support in mashumaro, it is pretty straightforward to add such functionality. The main difficulty will be to support various specifications, some of which are as follows:

  • JSON Schema 2020-12
  • OpenAPI Specification

Examples of who needs this feature:

Describe the solution you'd like

Linked PR:

I see it this way:

from enum import Enum
from uuid import UUID
from dataclasses import dataclass
from typing import Annotated
from mashumaro.jsonschema import JSONSchemaBuilder
from mashumaro.jsonschema.annotations import Minimum


class ModelType(Enum):
    ANDROID = "android"
    IPHONE = "iphone"


@dataclass
class Device:
    id: UUID
    type: ModelType = ModelType.IPHONE


@dataclass
class User:
    name: str
    age: Annotated[int, Minimum(1)]
    devices: list[Device]


builder = JSONSchemaBuilder()
print(builder.build(User).to_json())
print(builder.get_definitions().to_json())

Here builder.build(User) will generate the following schema:

{"$ref":"#/defs/User"}

A separated get_definitions method can be used to get all subschema definitions that can be referenced to:

Here builder.get_definitions() will produce the following schema:

{
    "Device": {
        "type": "object",
        "title": "Device",
        "properties": {
            "id": {
                "type": "string",
                "format": "uuid"
            },
            "type": {
                "enum": [
                    "android",
                    "iphone"
                ],
                "default": "iphone"
            }
        },
        "additionalProperties": false,
        "required": [
            "id"
        ]
    },
    "User": {
        "type": "object",
        "title": "User",
        "properties": {
            "name": {
                "type": "string"
            },
            "age": {
                "type": "integer",
                "minimum": 1
            },
            "devices": {
                "type": "array",
                "items": {
                    "$ref": "#/defs/Device"
                }
            }
        },
        "additionalProperties": false,
        "required": [
            "name",
            "age",
            "devices"
        ]
    }
}

Open questions to discuss

The following questions come to mind

  • What keywords must be added to the final scheme?
  • What dialects should be supported out of the box?
    • Which versions of JSON Schema Drafts?
    • Which versions of OpenAPI Specification?
  • How to add custom keywords to the final scheme?
@Fatal1ty Fatal1ty added enhancement New feature or request and removed feature labels Mar 21, 2023
@Fatal1ty
Copy link
Owner Author

Fatal1ty commented Apr 6, 2023

From now on, mashumaro can build JSON Schema 🎉

@Fatal1ty Fatal1ty closed this as completed Apr 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant