linkml.generators.csvgen — linkml documentation

# Source code for linkml.generators.csvgen

    """
    Generate CSVs
    """
    import os
    import sys
    from csv import DictWriter
    from typing import List, Union, TextIO, Set, Optional

    import click

    from linkml_runtime.linkml_model.meta import ClassDefinition, ClassDefinitionName, SchemaDefinition
    from linkml_runtime.utils.formatutils import underscore, be
    from linkml.utils.generator import Generator, shared_arguments

    class CsvGenerator(Generator):
        generatorname = os.path.basename(__file__)
        generatorversion = "0.1.1"
        valid_formats = ['csv', 'tsv']

        def __init__(self, schema: Union[str, TextIO, SchemaDefinition], **kwargs) -> None:
            super().__init__(schema, **kwargs)
            self.sep: Optional[str] = None
            self.closure: Optional[Set[ClassDefinitionName]] = None       # List of classes to include in output
            self.writer: Optional[DictWriter] = None

        def visit_schema(self, classes: List[ClassDefinitionName] = None, **_) -> None:
            # Note: classes comes from the "root" argument
            self.closure = set()

            if classes is None:
                classes = []

            # Validate the supplied list of classes
            for clsname in classes:
                if clsname not in self.schema.classes:
                    raise ValueError(f"Unrecognized class: {clsname}")
                else:
                    self.closure.update(self.ancestors(self.schema.classes[clsname]))

            dialect: str = "excel" if self.format == 'csv' else "excel-tab"
            self.writer = DictWriter(sys.stdout, ['id', 'mappings', 'description'], dialect=dialect)
            self.writer.writeheader()

        def visit_class(self, cls: ClassDefinition) -> bool:
            # TODO: find out what to do with mappings
            if not self.closure or cls.name in self.closure:
                self.writer.writerow({'id': underscore(cls.name),
                                      # 'mappings': "|".join(cls.mappings),
                                      'mappings': '',
                                      'description': be(cls.description)})
                return True
            return False

    @shared_arguments(CsvGenerator)
    @click.command()
    @click.option("--root", "-r", default=None, multiple=True, help="Class(es) to transform")
    def cli(yamlfile, root=None, **args):
        """ Generate CSV/TSV file from LinkML model """
        print(CsvGenerator(yamlfile, **args).serialize(classes=root, **args))

    if __name__ == '__main__':
        cli()