Session

A wrapper object for a transformer session.

Todo: - rename to Manager? - consolidate configuration - include source and target database

- current spec, src_sv, tgt_sv all live in both this class and transformer
Source code in src/linkml_map/session.py
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
@dataclass
class Session:
    """
    A wrapper object for a transformer session.

    Todo:
    - rename to Manager?
    - consolidate configuration
    - include source and target database

        - current spec, src_sv, tgt_sv all live in both this class and transformer

    """

    transformer_specification: TransformationSpecification | None = None
    source_schemaview: SchemaView | None = None
    transformer: Transformer | None = None
    object_transformer: ObjectTransformer | None = None
    schema_mapper: SchemaMapper | None = None
    _target_schema: SchemaDefinition | None = None
    _target_schemaview: SchemaView | None = None

    def set_transformer_specification(
        self, specification: TransformationSpecification | dict | str | Path | None = None
    ) -> None:
        if isinstance(specification, Path):
            specification = str(specification)
        if isinstance(specification, TransformationSpecification):
            self.transformer_specification = specification
        elif isinstance(specification, dict):
            Transformer._normalize_spec_dict(specification)
            self.transformer_specification = TransformationSpecification(**specification)
        elif isinstance(specification, str):
            if "\n" in specification:
                obj = yaml.safe_load(specification)
            else:
                obj = yaml.safe_load(open(specification))
            self.set_transformer_specification(obj)

    def set_source_schema(self, schema: str | Path | dict | SchemaView | SchemaDefinition) -> None:
        """
        Set the schema from a path or SchemaView object.
        """
        if isinstance(schema, str):
            sv = SchemaView(schema)
        elif isinstance(schema, Path):
            sv = SchemaView(str(schema))
        elif isinstance(schema, dict):
            sv = SchemaView(yaml_dumper.dumps(schema))
        elif isinstance(schema, SchemaView):
            sv = schema
        elif isinstance(schema, SchemaDefinition):
            sv = SchemaView(schema)
        else:
            msg = f"Unsupported schema type: {type(schema)}"
            raise ValueError(msg)
        self.source_schemaview = sv
        self._target_schema = None

    def set_transformer(
        self,
        transformer: Transformer | type[Transformer] | None,
        **kwargs,
    ) -> None:
        if isinstance(transformer, type):
            transformer = transformer()
        transformer.specification = self.transformer_specification
        self.transformer = transformer

    def set_object_transformer(
        self,
        transformer: ObjectTransformer | TransformationSpecification | dict | str | Path | None = None,
    ) -> None:
        if transformer is None:
            if self.object_transformer is not None:
                logger.info("No change")
                return
            logger.warning("No transformer specified")
            return
        if transformer is not None:
            if isinstance(transformer, ObjectTransformer):
                self.object_transformer = transformer
            else:
                self.set_transformer_specification(transformer)
                self.object_transformer = ObjectTransformer()
                self.object_transformer.specification = self.transformer_specification
        self._target_schema = None

    @property
    def target_schema(self) -> SchemaDefinition:
        if self._target_schema is None:
            if not self.schema_mapper:
                self.schema_mapper = SchemaMapper(source_schemaview=self.source_schemaview)
            self._target_schema = self.schema_mapper.derive_schema(self.transformer_specification)
        return self._target_schema

    @property
    def target_schemaview(self) -> SchemaView:
        if self._target_schemaview is None:
            # TODO: simplify
            self._target_schemaview = SchemaView(yaml_dumper.dumps(self.target_schema))
        return self._target_schemaview

    def transform(self, obj: dict, **kwargs) -> dict:
        if self.object_transformer is None:
            msg = "No transformer specified"
            raise ValueError(msg)
        if not self.object_transformer.source_schemaview:
            self.object_transformer.source_schemaview = self.source_schemaview
        return self.object_transformer.map_object(obj, **kwargs)

    def reverse_transform(self, obj: dict, **kwargs) -> dict:
        inv_spec = self.invert()
        reverse_transformer = ObjectTransformer()
        reverse_transformer.specification = inv_spec
        reverse_transformer.source_schemaview = SchemaView(yaml_dumper.dumps(self.target_schema))
        return reverse_transformer.map_object(obj, **kwargs)

    def invert(self, in_place=False) -> TransformationSpecification:
        """
        Invert the transformer specification.
        """
        inverter = TransformationSpecificationInverter(
            source_schemaview=self.source_schemaview,
            target_schemaview=SchemaView(yaml_dumper.dumps(self.target_schema)),
        )
        inv_spec = inverter.invert(self.transformer_specification)
        if in_place:
            raise NotImplementedError
        return inv_spec

    def graphviz(self, **kwargs) -> Any:
        """
        Return a graphviz representation of the schema.
        """
        from linkml_map.compiler.graphviz_compiler import GraphvizCompiler

        gc = GraphvizCompiler(source_schemaview=self.source_schemaview)
        compiled = gc.compile(self.transformer_specification)
        return compiled.digraph

graphviz(**kwargs)

Return a graphviz representation of the schema.

Source code in src/linkml_map/session.py
151
152
153
154
155
156
157
158
159
def graphviz(self, **kwargs) -> Any:
    """
    Return a graphviz representation of the schema.
    """
    from linkml_map.compiler.graphviz_compiler import GraphvizCompiler

    gc = GraphvizCompiler(source_schemaview=self.source_schemaview)
    compiled = gc.compile(self.transformer_specification)
    return compiled.digraph

invert(in_place=False)

Invert the transformer specification.

Source code in src/linkml_map/session.py
138
139
140
141
142
143
144
145
146
147
148
149
def invert(self, in_place=False) -> TransformationSpecification:
    """
    Invert the transformer specification.
    """
    inverter = TransformationSpecificationInverter(
        source_schemaview=self.source_schemaview,
        target_schemaview=SchemaView(yaml_dumper.dumps(self.target_schema)),
    )
    inv_spec = inverter.invert(self.transformer_specification)
    if in_place:
        raise NotImplementedError
    return inv_spec

set_source_schema(schema)

Set the schema from a path or SchemaView object.

Source code in src/linkml_map/session.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
def set_source_schema(self, schema: str | Path | dict | SchemaView | SchemaDefinition) -> None:
    """
    Set the schema from a path or SchemaView object.
    """
    if isinstance(schema, str):
        sv = SchemaView(schema)
    elif isinstance(schema, Path):
        sv = SchemaView(str(schema))
    elif isinstance(schema, dict):
        sv = SchemaView(yaml_dumper.dumps(schema))
    elif isinstance(schema, SchemaView):
        sv = schema
    elif isinstance(schema, SchemaDefinition):
        sv = SchemaView(schema)
    else:
        msg = f"Unsupported schema type: {type(schema)}"
        raise ValueError(msg)
    self.source_schemaview = sv
    self._target_schema = None