koxudaxi / datamodel-code-generator

Pydantic model and dataclasses.dataclass generator for easy conversion of JSON, OpenAPI, JSON Schema, and YAML data sources.
https://koxudaxi.github.io/datamodel-code-generator/
MIT License
2.66k stars 296 forks source link

Code not generated for patternProperties in JSON Schemas #1851

Open lfvjimisola opened 7 months ago

lfvjimisola commented 7 months ago

Describe the bug

In our open source project reqstool we have several JSON Schemas. We would like to use datamode-code-generator to generate pydantic v2 code, but the code does not get generated correctly.

Our schemas have been validated with: check-jsonschema --verbose --schemafile "https://json-schema.org/draft/2020-12/schema" <schema_folder>/*

However, it seems as if patternProperties in JSON Schemas are not handled properly.

To Reproduce

Example schema:

All schemas are available here: https://github.com/Luftfartsverket/reqstool-client/tree/main/src/reqstool/resources/schemas/v1

The requirements.schema.json is the most advanced but it does not use pattternProperties.

An example to use is: annotations.schema.json where there is:

note: This particular case does not need to use patternProperties since the two properties implementations and tests and known before runtime.

  "$defs": {
        "requirement_annotations": {
            "type": "object",
            "additionalProperties": false,
            "patternProperties": {
                "^implementations": {
                    "type": "object",
                    "$ref": "#/$defs/annotation",
                    "description": "requirement annotation used in implementation"
                },
                "^tests": {
                    "type": "object",
                    "$ref": "#/$defs/annotation",
                    "description": "requirement annotation used in test"
                }
            }
        }

Used commandline:

$ DIR=. find $DIR -type f -name '*.schema.json' -exec sh -c 'base_name=$(basename "{}" .schema.json); datamodel-codegen --input "{}" --input-file-type jsonschema --output "$DIR/$base_name.py"   --output-model-type pydantic_v2.BaseModel --use-annotated   --use-standard-collections --capitalize-enum-members --target-python-version 3.10 --use-schema-description --wrap-string-literal --use-double-quotes --use-field-description --snake-case-field ' \;

Expected behavior A clear and concise description of what you expected to happen.

Version:

Additional context Add any other context about the problem here.

lfvjimisola commented 7 months ago

There might be other issues than the patternProperties.

lfvjimisola commented 7 months ago

The generator also fails to generate datamodels for the OpenAPI 3.1 JSON Schema.

Steps to reproduce:

1 clone to get official JSON Schemas for OpenAPI Specification

git clone https://github.com/OAI/OpenAPI-Specification

2 check that the JSON Schema is valid

check-jsonschema --verbose --schemafile "https://json-schema.org/draft/2020-12/schema" OpenAPI-Specification/schemas/v3.1/schema.json

 ok -- validation done
The following files were checked:
  OpenAPI-Specification/schemas/v3.1/schema.json

3 run datamodel-codegen (fails)

datamodel-codegen --input-file-type jsonschema --input OpenAPI-Specification/schemas/v3.1/schema.json --output model.py

Error:

  File "/home/u30576/.local/lib/python3.10/site-packages/pydantic/main.py", line 509, in model_validate
    return cls.__pydantic_validator__.validate_python(
pydantic_core._pydantic_core.ValidationError: 1 validation error for JsonSchemaObject
patternProperties.^x-
  Input should be a valid dictionary or instance of JsonSchemaObject [type=model_type, input_value=True, input_type=bool]
    For further information visit https://errors.pydantic.dev/2.6/v/model_type
lfvjimisola commented 7 months ago

@koxudaxi With the risk of disturbing you, is there any other information needed?

If not, would you be able to confirm that this is a known issue or am I doing something wrong? If it is a known issue, is this likely to be featured? How much work is it? Is it a good first issue?

lfvjimisola commented 6 months ago

@koxudaxi This is a blocker for us. Is there anything we can do make this move forward?

koxudaxi commented 6 months ago

Sorry for the late reply. I ran it with the repositories and commands you presented and generated the code. I don't think pydantic is currently capable of handling multiple patternProperties. Specifically, I think it is limited to determining if it matches a single regex, as in this example. What is the model of Pydantic you are envisioning? https://github.com/koxudaxi/datamodel-code-generator/blob/b3fbbcade9814d4080098ae61ba69e6f8dd018f5/tests/data/expected/main/main_ jsonschema_pattern_properties_by_reference/output.py#L20

lfvjimisola commented 6 months ago

I'm not sure. Will have to get back to you on that. Preferably, something that works and makes sense :)

Is this issue related to: https://github.com/koxudaxi/datamodel-code-generator/issues/715

lfvjimisola commented 6 months ago

@koxudaxi It could be that I'm not answering your actual question below (please advise if so).

Just so that we understand this the same. There are two challenges here:

  1. the actual regexp (pydantic seems to be a lot more restrictive)
  2. multiple patternProperties as seen in the schema for reqstool

1 Actual regexp

It seems as the regexp "^[a-z]{1}[0-9]{1}$" in your link to TextResponse is quite restrictive which is understandable if it is to be easy to create a valid python class name from the regexp. However, the patternProperty can look quite different as we've seen in our schema for reqstool, but more importantly, for well-adopted standards such as OpenAPI.

For OpenAPI 3.1 there seems to be a bit of a various with the patternProperties, e.g.:

2 multiple patternProperties

I think that given the initial example with requirement_annotations and patternProperties keys"^implementations" and "^tests" pydantic should create a class requirement_annotations with two objects as instance variables. I'm not sure how pydantic normally goes about naming of those two classes, but it seems as the keys for the two patternProperties can be be used as is (with disregard of the ^).

lfvjimisola commented 5 months ago

@koxudaxi Is the information above enough to be able to move forward?

lfvjimisola commented 5 months ago

@koxudaxi Anything we can do to help move this forward?

danielxpander commented 3 months ago

Is there any update on this? :')

lfvjimisola commented 2 months ago

@danielxpander Sadly, no. I was afraid that something had happened to @koxudaxi but there seem to be activity in the repository by him, @bpsoos and @natikgadzhi.