GenSON icon indicating copy to clipboard operation
GenSON copied to clipboard

Enhancement: Add parameter to add description placeholders

Open zbalkan opened this issue 1 year ago • 1 comments

Summary

Description might be needed for a JSON schema to add comments for developers. It should be an optional parameter as it is not the case for everyone.

Example

I created a POC project, not usable for production, that generates documentation for YML files. I add description property to any JSON property that has a type, so I can ignore arrays, etc. It recursively visits schema, as a dictionary, and adds description property if a value has type.

def generate_json_schema(inputPath: str, outputPath: str, useAnnotations: bool = False, verbose: bool = False) -> None:

    if (verbose):
        print("Loading JSON file from path: " + inputPath)

    jsonObj = json.load(open(inputPath))

    if (verbose):
        print("Generating schema")

    builder: SchemaBuilder = SchemaBuilder()
    builder.add_object(jsonObj)
    schema: dict = builder.to_schema()

    # Here comes the magic
    add_description_property(schema)  # type: ignore

    if (useAnnotations):
        schema["title"] = TITLE
        schema["description"] = DESCRIPTION

    with open(outputPath, 'w') as json_file:
        json.dump(schema, json_file, indent=4)

    if (verbose):
        print("Saved schema to path: " + outputPath)


def add_description_property(d: dict) -> None:
    if ("type" in d):
        d["description"] = "# Description title\n\nDescription placeholder with *bold* and _italic_ text. This is a `code snippet`."
    for key, value in d.items():
        if (type(value) == dict):
            add_description_property(value)

zbalkan avatar Oct 07 '22 14:10 zbalkan

Thanks for the idea!

I'm a bit hesitant to add a specific keyword arg for this, but it may point to a more generic use case that we could support. I think maybe that use case is simply being able to iterate through all the nodes in a SchemaBuilder and modify them.

Naively, SchemaBuilder could have an __iter__() method that yields up each node in turn. However, node is stored as SchemaNode and SchemaStrategy instances, not as a dicts, and those classes aren't intended to touch user code, so they don't have a good API for inspection and manipulation.

Alternately, to_schema() could accept a callable and call it on each node in the schema right after it gets translated to a dict, which I think may be easier to work with. That said, it's a fairly cumbersome thing to add to the interface, and the same functionality can be easily implemented in user code using a recursive function like the one you created.

There is a tradeoff in complexity here, so I'd like to see several +1s on this issue before moving forward. If you have another thought on how your use case might be solved without too much burden on the interface, I'd love to hear it.

wolverdude avatar Oct 11 '22 05:10 wolverdude