pythonyamlschemaintellisenseruamel.yaml

Generate YAML schema from dataclass in Python


Suppose I have the following dataclass:

@dataclass
class MyStocksConf:
    File: str = r'buydicnk.cache'
    SrcFile: str = "example_mystock.csv"
    PortofolioName: str = "My Portfolio"
    Use: Union[UseCache, int] = UseCache.USEIFAVALIABLE

I have a class config that is a dataclass and contains it (and other classes).

I register the custom classes using ruamel.yaml. Though I eventually load it unsafe.

I want to have IntelliSense in YAML (using yaml-ls). For this I need to generate a schema. This schema should positively match this:

MyStocks:
 !MyStocksConf
 File: buydicnk.cache
 PortofolioName: My Portfolio
 SrcFile: C:\Users\...\.compare_my_stocks
 Use: !UseCache DONT

The definition of UseCache:

@to_yaml
class UseCache(int,Enum):
    DONT=0
    USEIFAVALIABLE=1
    FORCEUSE=2

How would I generate such a schema from my class definition?

I want to have the types in the schema. If it is an enum, also the members of the enum as it is forcing. Other things are unknown to the schema generator, although arguably the description could be deduced from the description of the fields.

PS:

This is the generated schema. It can still be improved by having the enum accept names.

{'$defs': {'UseCache': {'enum': [0, 1, 2], 'title': 'UseCache', 'type': 'integer'}}, 'proper
ties': {'File': {'default': 'buydicnk.cache', 'title': 'File', 'type': 'string'}, 'SrcFile':
 {'default': 'example_mystock.csv', 'title': 'Srcfile', 'type': 'string'}, 'PortofolioName':
 {'default': 'My Portfolio', 'title': 'Portofolioname', 'type': 'string'}, 'Use': {'anyOf': 
[{'$ref': '#/$defs/UseCache'}, {'type': 'integer'}], 'default': 1, 'title': 'Use'}}, 'title'
: 'MyStocksConf', 'type': 'object'}


Solution

  • Pydantic supports generating schema. You can work with it instead of normal dataclasses.

    So you can do:

    from pydantic.dataclasses import dataclass
    
    @dataclass
    class MyStocksConf:
        ...
    
    from pydantic import TypeAdapter
    
    adapter = TypeAdapter(MyStocksConf)
    print(adapter.json_schema())
    

    See: https://docs.pydantic.dev/latest/usage/json_schema/

    Notice that AFAIK, JSON scheme is used to validate YAML.