datamodel-code-generator icon indicating copy to clipboard operation
datamodel-code-generator copied to clipboard

additionalProperties not working when set to a JSON object and not to a boolean

Open giacomomarchioro opened this issue 3 years ago • 2 comments
trafficstars

Thanks for this wonderful tool! Describe the bug From the json schema specification if I understand well, a JSON object can be used in additionalProperties like below:

To Reproduce

Example schema:


{
    "$id": "https://example.com/person.schema.json",
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "my JSON of list of string",
    "type": "object",
    "additionalProperties" : {
            "type": "array",
            "items": { "type": "string"}
        }
}

Used commandline:

datamodel-codegen --input jsonschema.json --input-file-type jsonschema  --output skeleton.py

Expected behavior Now I would expect that only "test":["test"] or "testb":["testb","testc"] are valid while instead it seems that any dict is valid:

import skeleton 
t = skeleton.JSONofListOfString()
t.validate({"asdf":[1,2,3,4]}) 
t.validate({"asdf":1}) 

Version:

  • OS: MacOS 10.15.7
  • Python version: 3.8.3
  • datamodel-code-generator version: 0.11.8

giacomomarchioro avatar Jan 28 '22 16:01 giacomomarchioro

Hi @giacomomarchioro, I'm sorry for my late reply.

I tried your example


from __future__ import annotations

from pydantic import BaseModel, Extra


class MyJsonOfListOfString(BaseModel):
    pass

    class Config:
        extra = Extra.allow

What output do you expect? I don't have the idea that I can realize your request in pydantic.

koxudaxi avatar Apr 16 '22 17:04 koxudaxi

Hi @koxudaxi! it is my turn to apologize I lost your answer. What I would expect is the behaviour explained at the bottom of this paragraph of the JSON schema specification.

You can use additionalProperties with a combination of properties and patternProperties.

So the pydantic file should contain something like this:

from __future__ import annotations

from pydantic import BaseModel
from typing import Dict,List

class MyJsonOfListOfString(BaseModel):
    __root__: Dict[str, List[str]]

Which produces the correct behaviour according to the schema specification:

In [3]: h = MyJsonOfListOfString.validate({"asdf":['a','b','c','d']})        # OK, dict with string as key and list of str  as value         

In [4]: h = MyJsonOfListOfString.validate({"asdf":1})    # Validation error, dict with string as key but int as value                       
---------------------------------------------------------------------------
ValidationError  

giacomomarchioro avatar May 06 '22 12:05 giacomomarchioro

@giacomomarchioro I'm sorry for my too-late reply.
I have released the PR as 0.15.0 Thank you very much!!

koxudaxi avatar Jan 04 '23 16:01 koxudaxi

Thanks a lot @koxudaxi !

giacomomarchioro avatar Jan 04 '23 18:01 giacomomarchioro