linkml-map 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. linkml_map/__init__.py +6 -0
  2. linkml_map/cli/__init__.py +0 -0
  3. linkml_map/cli/cli.py +205 -0
  4. linkml_map/compiler/__init__.py +1 -0
  5. linkml_map/compiler/awk_compiler.py +13 -0
  6. linkml_map/compiler/compiler.py +88 -0
  7. linkml_map/compiler/graphviz_compiler.py +109 -0
  8. linkml_map/compiler/j2_based_compiler.py +36 -0
  9. linkml_map/compiler/markdown_compiler.py +12 -0
  10. linkml_map/compiler/python_compiler.py +113 -0
  11. linkml_map/compiler/r2rml_compiler.py +12 -0
  12. linkml_map/compiler/sparql_compiler.py +12 -0
  13. linkml_map/compiler/sql_compiler.py +138 -0
  14. linkml_map/compiler/sssom_compiler.py +13 -0
  15. linkml_map/compiler/templates/__init__.py +3 -0
  16. linkml_map/compiler/templates/markdown.j2 +24 -0
  17. linkml_map/compiler/tr/__init__.py +4 -0
  18. linkml_map/compiler/tr/transformer_to_mapping_tables.tr.yaml +29 -0
  19. linkml_map/datamodel/__init__.py +4 -0
  20. linkml_map/datamodel/sssom.map.yaml +8 -0
  21. linkml_map/datamodel/transformer_model.py +425 -0
  22. linkml_map/datamodel/transformer_model.yaml +369 -0
  23. linkml_map/functions/__init__.py +0 -0
  24. linkml_map/functions/unit_conversion.py +157 -0
  25. linkml_map/importer/__init__.py +0 -0
  26. linkml_map/importer/importer.py +35 -0
  27. linkml_map/inference/__init__.py +0 -0
  28. linkml_map/inference/inference.py +38 -0
  29. linkml_map/inference/inverter.py +181 -0
  30. linkml_map/inference/schema_mapper.py +249 -0
  31. linkml_map/session.py +167 -0
  32. linkml_map/transformer/__init__.py +0 -0
  33. linkml_map/transformer/duckdb_transformer.py +70 -0
  34. linkml_map/transformer/object_transformer.py +368 -0
  35. linkml_map/transformer/transformer.py +269 -0
  36. linkml_map/utils/__init__.py +0 -0
  37. linkml_map/utils/dynamic_object.py +49 -0
  38. linkml_map/utils/eval_utils.py +207 -0
  39. linkml_map/utils/loaders.py +22 -0
  40. linkml_map/utils/multi_file_transformer.py +212 -0
  41. linkml_map-0.1.0.dist-info/METADATA +56 -0
  42. linkml_map-0.1.0.dist-info/RECORD +44 -0
  43. linkml_map-0.1.0.dist-info/WHEEL +4 -0
  44. linkml_map-0.1.0.dist-info/entry_points.txt +3 -0
linkml_map/__init__.py ADDED
@@ -0,0 +1,6 @@
1
+ from linkml_map.transformer.object_transformer import ObjectTransformer
2
+
3
+ __all__ = [
4
+ "Session",
5
+ "ObjectTransformer",
6
+ ]
File without changes
linkml_map/cli/cli.py ADDED
@@ -0,0 +1,205 @@
1
+ """Command line interface for linkml-transformer."""
2
+
3
+ import logging
4
+ import sys
5
+
6
+ import click
7
+
8
+ __all__ = [
9
+ "main",
10
+ ]
11
+
12
+ import yaml
13
+ from linkml_runtime import SchemaView
14
+ from linkml_runtime.dumpers import yaml_dumper
15
+
16
+ from linkml_map.compiler.markdown_compiler import MarkdownCompiler
17
+ from linkml_map.compiler.python_compiler import PythonCompiler
18
+ from linkml_map.inference.inverter import TransformationSpecificationInverter
19
+ from linkml_map.inference.schema_mapper import SchemaMapper
20
+ from linkml_map.transformer.object_transformer import ObjectTransformer
21
+
22
+ schema_option = click.option("-s", "--schema", help="Path to source schema.")
23
+ transformer_specification_option = click.option(
24
+ "-T", "--transformer-specification", help="Path to transformer specification."
25
+ )
26
+ output_option_wb = click.option(
27
+ "-o",
28
+ "--output",
29
+ type=click.File(mode="wb"),
30
+ default=sys.stdout,
31
+ help="Output file.",
32
+ )
33
+ output_option = click.option("-o", "--output", help="Output file.")
34
+ output_format_options = click.option(
35
+ "-O",
36
+ "--output-format",
37
+ type=click.Choice(["json", "yaml", "pickle", "md"]),
38
+ default="yaml",
39
+ help="Output format.",
40
+ )
41
+
42
+
43
+ @click.group()
44
+ @click.option("-v", "--verbose", count=True)
45
+ @click.option("-q", "--quiet")
46
+ # @click.version_option(__version__)
47
+ def main(verbose: int, quiet: bool):
48
+ """CLI for linkml-transformer."""
49
+ logger = logging.getLogger()
50
+ if verbose >= 2:
51
+ logger.setLevel(level=logging.DEBUG)
52
+ elif verbose == 1:
53
+ logger.setLevel(level=logging.INFO)
54
+ else:
55
+ logger.setLevel(level=logging.WARNING)
56
+ if quiet:
57
+ logger.setLevel(level=logging.ERROR)
58
+ logger.info(f"Logger {logger.name} set to level {logger.level}")
59
+
60
+
61
+ @main.command()
62
+ @output_option
63
+ @transformer_specification_option
64
+ @schema_option
65
+ @output_format_options
66
+ @click.option("--source-type")
67
+ @click.option(
68
+ "--unrestricted-eval/--no-unrestricted-eval",
69
+ default=False,
70
+ show_default=True,
71
+ help="Allow unrestricted eval of python expressions.",
72
+ )
73
+ @click.argument("input")
74
+ def map_data(
75
+ input,
76
+ schema,
77
+ source_type,
78
+ transformer_specification,
79
+ output,
80
+ output_format,
81
+ **kwargs,
82
+ ):
83
+ """
84
+ Map data from a source schema to a target schema using a transformation specification.
85
+
86
+ Example:
87
+
88
+ linkml-tr map-data -T X-to-Y-tr.yaml -s X.yaml X-data.yaml
89
+ """
90
+ logging.info(f"Transforming {input} conforming to {schema} using {transformer_specification}")
91
+ tr = ObjectTransformer(**kwargs)
92
+ tr.source_schemaview = SchemaView(schema)
93
+ tr.load_transformer_specification(transformer_specification)
94
+ with open(input) as file:
95
+ input_obj = yaml.safe_load(file)
96
+ tr.index(input_obj, source_type)
97
+ tr_obj = tr.map_object(input_obj, source_type)
98
+ if output:
99
+ outfile = open(output, "w", encoding="utf-8")
100
+ else:
101
+ outfile = sys.stdout
102
+ outfile.write(yaml_dumper.dumps(tr_obj))
103
+
104
+
105
+ @main.command()
106
+ @output_option
107
+ @transformer_specification_option
108
+ @schema_option
109
+ @click.option("--source-type")
110
+ @click.option("--target", default="python", show_default=True, help="Target representation.")
111
+ def compile(
112
+ schema,
113
+ source_type,
114
+ transformer_specification,
115
+ target,
116
+ output,
117
+ **kwargs,
118
+ ):
119
+ """
120
+ Compiles a schema to another representation.
121
+
122
+ Example:
123
+
124
+ linkml-tr compile -T X-to-Y-tr.yaml -s X.yaml
125
+ """
126
+ logging.info(f"Compiling {transformer_specification} with {schema}")
127
+ compiler_args = {}
128
+ if schema:
129
+ compiler_args["source_schemaview"] = SchemaView(schema)
130
+ if target == "python":
131
+ compiler = PythonCompiler(**compiler_args)
132
+ elif target == "markdown":
133
+ compiler = MarkdownCompiler(**compiler_args)
134
+ else:
135
+ raise NotImplementedError(f"Compiler {target} not implemented")
136
+ tr = ObjectTransformer()
137
+ tr.source_schemaview = SchemaView(schema)
138
+ tr.load_transformer_specification(transformer_specification)
139
+ result = compiler.compile(tr.specification)
140
+ print(result.serialization)
141
+
142
+
143
+ @main.command()
144
+ @output_option
145
+ @transformer_specification_option
146
+ @output_format_options
147
+ @click.argument("schema")
148
+ def derive_schema(schema, transformer_specification, output, output_format, **kwargs):
149
+ """Derive a schema from a source schema and a transformation specification.
150
+
151
+ This can be thought of as "copying" the source to a target, using the transformation
152
+ specification as a "patch"
153
+
154
+ Notes:
155
+
156
+ the implementation is currently incomplete; the derived schema may not be valid
157
+ linkml, e.g. there may be "dangling" references.
158
+
159
+ Example:
160
+
161
+ linkml-tr derive-schema -T transform/personinfo-to-agent.transform.yaml source/personinfo.yaml
162
+ """
163
+ logging.info(f"Transforming {schema} using {transformer_specification}")
164
+ tr = ObjectTransformer()
165
+ tr.load_transformer_specification(transformer_specification)
166
+ mapper = SchemaMapper(transformer=tr)
167
+ mapper.source_schemaview = SchemaView(schema)
168
+ target_schema = mapper.derive_schema()
169
+ if output:
170
+ outfile = open(output, "w", encoding="utf-8")
171
+ else:
172
+ outfile = sys.stdout
173
+ outfile.write(yaml_dumper.dumps(target_schema))
174
+
175
+
176
+ @main.command()
177
+ @output_option
178
+ @transformer_specification_option
179
+ @output_format_options
180
+ @click.option("--strict/--no-strict", default=True, show_default=True, help="Strict mode.")
181
+ @click.argument("schema")
182
+ def invert(schema, transformer_specification, output, output_format, **kwargs):
183
+ """Invert a transformation specification.
184
+
185
+ Example:
186
+
187
+ linkml-tr invert -T transform/personinfo-to-agent.transform.yaml source/personinfo.yaml
188
+ """
189
+ logging.info(f"Inverting {transformer_specification} using {schema} as source")
190
+ tr = ObjectTransformer()
191
+ tr.load_transformer_specification(transformer_specification)
192
+ inverter = TransformationSpecificationInverter(
193
+ source_schemaview=SchemaView(schema),
194
+ **kwargs,
195
+ )
196
+ inverted_spec = inverter.invert(tr.specification)
197
+ if output:
198
+ outfile = open(output, "w", encoding="utf-8")
199
+ else:
200
+ outfile = sys.stdout
201
+ outfile.write(yaml_dumper.dumps(inverted_spec))
202
+
203
+
204
+ if __name__ == "__main__":
205
+ main()
@@ -0,0 +1 @@
1
+ """Compiles schemas into other transformation frameworks."""
@@ -0,0 +1,13 @@
1
+ from linkml_map.compiler.compiler import CompiledSpecification, Compiler
2
+ from linkml_map.datamodel.transformer_model import TransformationSpecification
3
+
4
+
5
+ class AWKCompiler(Compiler):
6
+ """
7
+ Compiles a Transformation Specification to an Awk script.
8
+
9
+ Note: this is only expected to work for flat schemas.
10
+ """
11
+
12
+ def compile(self, specification: TransformationSpecification) -> CompiledSpecification:
13
+ raise NotImplementedError
@@ -0,0 +1,88 @@
1
+ """
2
+ Compilers are responsible for compiling a transformation specification into an alternative representation.
3
+
4
+ This is the opposite of an importer.
5
+
6
+ For example:
7
+
8
+ - LinkML-Transformer Specifications to R2RML
9
+ - LinkML-Transformer Specifications to awk scripts
10
+ - LinkML-Transformer Specifications to SQL
11
+ - LinkML-Transformer Specifications to Python (OO)
12
+ - LinkML-Transformer Specifications to Pandas
13
+ - LinkML-Transformer Specifications to Hamilton
14
+ """
15
+
16
+ from abc import ABC
17
+ from dataclasses import dataclass, field
18
+ from types import ModuleType
19
+ from typing import Iterator, Optional
20
+
21
+ from linkml_runtime import SchemaView
22
+ from linkml_runtime.dumpers import yaml_dumper
23
+ from linkml_runtime.utils.compile_python import compile_python
24
+
25
+ from linkml_map.datamodel.transformer_model import TransformationSpecification
26
+ from linkml_map.inference.schema_mapper import SchemaMapper
27
+
28
+
29
+ @dataclass
30
+ class CompiledSpecification:
31
+ serialization: str = field(default="")
32
+
33
+ _module: Optional[ModuleType] = None
34
+
35
+ @property
36
+ def module(self) -> ModuleType:
37
+ if not self._module:
38
+ self._module = compile_python(self.serialization)
39
+ return self._module
40
+
41
+
42
+ @dataclass
43
+ class Compiler(ABC):
44
+ """
45
+ Base class for all compilers.
46
+
47
+ A compiler will compile a transformation specification into
48
+ an alternative representation.
49
+
50
+ An example compiler would be a R2RML compiler.
51
+
52
+ Note: Compilers and Importers will in general be implemented by providing
53
+ mapping specifications
54
+ """
55
+
56
+ source_schemaview: SchemaView = None
57
+ """A view over the schema describing the source."""
58
+
59
+ source_python_module: str = None
60
+ """The python module containing the source classes."""
61
+
62
+ target_python_module: str = None
63
+ """The python module containing the target classes."""
64
+
65
+ def compile(self, specification: TransformationSpecification) -> CompiledSpecification:
66
+ """
67
+ Transform source object into an instance of the target class.
68
+
69
+ :param specification:
70
+ :return:
71
+ """
72
+ s = self._compile_header(specification)
73
+ for chunk in self._compile_iterator(specification):
74
+ s += chunk
75
+ return CompiledSpecification(serialization=s)
76
+
77
+ def _compile_header(self, specification: TransformationSpecification) -> str:
78
+ return ""
79
+
80
+ def _compile_iterator(self, specification: TransformationSpecification) -> Iterator[str]:
81
+ raise NotImplementedError
82
+
83
+ def derived_target_schemaview(self, specification: TransformationSpecification):
84
+ """
85
+ Returns a view over the target schema, including any derived classes.
86
+ """
87
+ mapper = SchemaMapper(source_schemaview=self.source_schemaview)
88
+ return SchemaView(yaml_dumper.dumps(mapper.derive_schema(specification)))
@@ -0,0 +1,109 @@
1
+ import re
2
+ from dataclasses import dataclass
3
+ from typing import List, Optional, Tuple
4
+
5
+ from graphviz import Digraph
6
+ from linkml_runtime import SchemaView
7
+ from pydantic import BaseModel
8
+
9
+ from linkml_map.compiler.compiler import CompiledSpecification, Compiler
10
+ from linkml_map.datamodel.transformer_model import TransformationSpecification
11
+
12
+
13
+ class Record(BaseModel):
14
+ """
15
+ A simplified representation of a class, UML-style.
16
+ """
17
+
18
+ name: str
19
+ source: str
20
+ fields: List[Tuple[str, str]] = []
21
+
22
+ @property
23
+ def id(self):
24
+ return f"{self.source}{self.name}"
25
+
26
+ def __str__(self):
27
+ return (
28
+ f"""<
29
+ <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
30
+ <TR><TD><B>{self.name}</B></TD></TR>
31
+ """
32
+ + "".join(
33
+ [
34
+ f'<TR><TD SIDES="LRB" PORT="{f[0]}">{f[0]} : {f[1]}</TD></TR>'
35
+ for f in self.fields
36
+ ]
37
+ )
38
+ + """
39
+ </TABLE>>"""
40
+ )
41
+
42
+
43
+ @dataclass
44
+ class GraphvizObject(CompiledSpecification):
45
+ digraph: Digraph = None
46
+
47
+ def render(self, file_path: str, format="png", view=False) -> None:
48
+ """
49
+ Renders a graphviz graph to a file.
50
+ :param file_path:
51
+ :return:
52
+ """
53
+ self.digraph.render(file_path, format=format, view=view)
54
+
55
+
56
+ class GraphvizCompiler(Compiler):
57
+ """
58
+ Compiles a Transformation Specification to GraphViz.
59
+ """
60
+
61
+ def compile(
62
+ self, specification: TransformationSpecification, elements: Optional[List[str]] = None
63
+ ) -> GraphvizObject:
64
+ dg = Digraph(comment="UML Class Diagram", format="png")
65
+ dg.attr(rankdir="LR") # Set graph direction from left to right
66
+ target_schemaview = self.derived_target_schemaview(specification)
67
+ source_schemaview = self.source_schemaview
68
+
69
+ records = []
70
+ records += self.add_records(source_schemaview, "source")
71
+ records += self.add_records(target_schemaview, "target")
72
+
73
+ for record in records:
74
+ dg.node(record.id, str(record), shape="plaintext")
75
+
76
+ # Define the class nodes with fields in UML format using HTML-like labels
77
+ # for precise control over the stacking of the fields
78
+ for target_cn, cd in specification.class_derivations.items():
79
+ source_cn = cd.populated_from
80
+ if source_cn is None:
81
+ source_cn = cd.name
82
+ if elements is not None and target_cn not in elements:
83
+ continue
84
+ source_record = Record(name=source_cn, source="source")
85
+ target_record = Record(name=target_cn, source="target")
86
+ for sd in cd.slot_derivations.values():
87
+ target_slot = sd.name
88
+ target_id = f"{target_record.id}:{target_slot}"
89
+ source_slot = sd.populated_from
90
+ if source_slot:
91
+ source_id = f"{source_record.id}:{source_slot}"
92
+ dg.edge(source_id, target_id)
93
+ elif sd.expr:
94
+ # TODO: do this in a less hacky way
95
+ tokens = re.findall(r"\w+", sd.expr)
96
+ for token in tokens:
97
+ if token not in source_schemaview.all_slots():
98
+ continue
99
+ dg.edge(f"{source_record.id}:{token}", target_id, style="dashed")
100
+ return GraphvizObject(digraph=dg, serialization=dg.source)
101
+
102
+ def add_records(self, schemaview: SchemaView, source: str) -> List[Record]:
103
+ records = []
104
+ for cn in schemaview.all_classes():
105
+ record = Record(name=cn, source=source)
106
+ for induced_slot in schemaview.class_induced_slots(cn):
107
+ record.fields.append((induced_slot.name, induced_slot.range))
108
+ records.append(record)
109
+ return records
@@ -0,0 +1,36 @@
1
+ from dataclasses import dataclass
2
+
3
+ from jinja2 import Environment, FileSystemLoader
4
+
5
+ from linkml_map.compiler.compiler import CompiledSpecification, Compiler
6
+ from linkml_map.compiler.templates import TEMPLATE_DIR
7
+ from linkml_map.datamodel.transformer_model import TransformationSpecification
8
+
9
+
10
+ @dataclass
11
+ class J2BasedCompiler(Compiler):
12
+ """
13
+ Compiles a Transformation Specification using a Jinja2 template.
14
+ """
15
+
16
+ template_dir: str = None
17
+ """The directory containing the Jinja2 template."""
18
+
19
+ template_name: str = None
20
+ """The name of the Jinja2 template."""
21
+
22
+ def compile(self, specification: TransformationSpecification) -> CompiledSpecification:
23
+ template_dir = self.template_dir
24
+ if not template_dir:
25
+ template_dir = TEMPLATE_DIR
26
+ if not template_dir:
27
+ raise ValueError("template_dir must be set")
28
+ loader = FileSystemLoader(template_dir)
29
+ env = Environment(loader=loader, autoescape=True)
30
+ if not self.template_name:
31
+ raise ValueError("template_name must be set")
32
+ template = env.get_template(self.template_name)
33
+ rendered = template.render(
34
+ spec=specification,
35
+ )
36
+ return CompiledSpecification(serialization=rendered)
@@ -0,0 +1,12 @@
1
+ from dataclasses import dataclass
2
+
3
+ from linkml_map.compiler.j2_based_compiler import J2BasedCompiler
4
+
5
+
6
+ @dataclass
7
+ class MarkdownCompiler(J2BasedCompiler):
8
+ """
9
+ Compiles a Transformation Specification to Markdown.
10
+ """
11
+
12
+ template_name: str = "markdown.j2"
@@ -0,0 +1,113 @@
1
+ from copy import deepcopy
2
+ from dataclasses import dataclass
3
+ from typing import Iterator
4
+
5
+ from jinja2 import Template
6
+
7
+ from linkml_map.compiler.compiler import Compiler
8
+ from linkml_map.datamodel.transformer_model import (
9
+ ClassDerivation,
10
+ TransformationSpecification,
11
+ )
12
+ from linkml_map.inference.inference import induce_missing_values
13
+
14
+ CD_TEMPLATE = """
15
+ {% macro gen_slot_derivation_value(sd, var) -%}
16
+ {%- if sd.range -%}
17
+ derive_{{ sd.range }}({{ var }})
18
+ {%- else -%}
19
+ {%- if var is not none -%}
20
+ {{ var }}
21
+ {%- else -%}
22
+ None
23
+ {%- endif -%}
24
+ {%- endif -%}
25
+ {%- endmacro %}
26
+ {% macro gen_slot_derivation(sd, force_singlevalued=False) -%}
27
+ {%- if not force_singlevalued and sd.populated_from and induced_slots[sd.populated_from].multivalued -%}
28
+ [ {{ gen_slot_derivation_value(sd, "x") }} for x in {{ gen_slot_derivation(sd, force_singlevalued=True) }} ]
29
+ {%- else -%}
30
+ {%- if sd.populated_from -%}
31
+ source_object.{{ sd.populated_from }}
32
+ {%- elif sd.expr -%}
33
+ {%- if '\n' in sd.expr -%}
34
+ gen_{{ sd.name }}(source_object)
35
+ {%- elif '{' in sd.expr and '}' in sd.expr -%}
36
+ {{ sd.expr|replace('{', '')|replace('}', '') }}
37
+ {%- else -%}
38
+ {{ sd.expr }}
39
+ {%- endif -%}
40
+ {%- else -%}
41
+ None
42
+ {%- endif -%}
43
+ {%- endif -%}
44
+ {%- endmacro %}
45
+ {% macro gen_slot_derivation_defs(sd) -%}
46
+ {% if sd.expr and '\n' in sd.expr %}
47
+
48
+ def gen_{{ sd.name }}(src):
49
+ target = None
50
+ {%- for line in sd.expr.split('\n') %}
51
+ {{ line }}
52
+ {%- endfor -%}
53
+ return target
54
+ {% endif %}
55
+ {%- endmacro %}
56
+ def derive_{{ cd.name }}(
57
+ source_object: {{ source_module }}.{{ cd.populated_from }}
58
+ ) -> {{ target_module }}.{{ cd.name }}:
59
+ # assign slots
60
+ {%- for slot in source_slots %}
61
+ {{ slot.name }} = source_object.{{ slot.name }}
62
+ {%- endfor %}
63
+ {%- for sd in cd.slot_derivations.values() -%}
64
+ {{ gen_slot_derivation_defs(sd) }}
65
+ {%- endfor %}
66
+
67
+ return tgt.{{ cd.name }}(
68
+ {%- for sd in cd.slot_derivations.values() %}
69
+ {{ sd.name }}={{ gen_slot_derivation(sd) }},
70
+ {%- endfor %}
71
+ )
72
+ """
73
+
74
+
75
+ @dataclass
76
+ class PythonCompiler(Compiler):
77
+ """
78
+ Compiles a Transformation Specification to Python code.
79
+ """
80
+
81
+ def _compile_header(self, specification: TransformationSpecification) -> str:
82
+ s = ""
83
+ if self.source_python_module:
84
+ s += f"import {self.source_python_module} as src\n"
85
+ if self.target_python_module:
86
+ s += f"import {self.target_python_module} as tgt\n"
87
+ s += "\nNULL = None\n\n"
88
+ return s
89
+
90
+ def _compile_iterator(self, specification: TransformationSpecification) -> Iterator[str]:
91
+ specification = deepcopy(specification)
92
+ induce_missing_values(specification, self.source_schemaview)
93
+ for cd in specification.class_derivations.values():
94
+ yield from self._compiled_class_derivations_iter(cd)
95
+
96
+ def _compiled_class_derivations_iter(self, cd: ClassDerivation) -> Iterator[str]:
97
+ sv = self.source_schemaview
98
+ if cd.populated_from:
99
+ populated_from = cd.populated_from
100
+ else:
101
+ populated_from = cd.name
102
+ if populated_from not in sv.all_classes():
103
+ return
104
+ induced_slots = {s.name: s for s in sv.class_induced_slots(populated_from)}
105
+ t = Template(CD_TEMPLATE)
106
+ yield t.render(
107
+ cd=cd,
108
+ source_module="src",
109
+ target_module="tgt",
110
+ induced_slots=induced_slots,
111
+ schemaview=sv,
112
+ source_slots=sv.class_induced_slots(populated_from),
113
+ )
@@ -0,0 +1,12 @@
1
+ from linkml_map.compiler.compiler import CompiledSpecification, Compiler
2
+ from linkml_map.datamodel.transformer_model import TransformationSpecification
3
+
4
+
5
+ class R2RMLCompiler(Compiler):
6
+ """
7
+ Compiles a Transformation Specification to R2RML.
8
+
9
+ """
10
+
11
+ def compile(self, specification: TransformationSpecification) -> CompiledSpecification:
12
+ raise NotImplementedError
@@ -0,0 +1,12 @@
1
+ from linkml_map.compiler.compiler import CompiledSpecification, Compiler
2
+ from linkml_map.datamodel.transformer_model import TransformationSpecification
3
+
4
+
5
+ class SPARQLCompiler(Compiler):
6
+ """
7
+ Compiles a Transformation Specification to SPARQL Construct.
8
+
9
+ """
10
+
11
+ def compile(self, specification: TransformationSpecification) -> CompiledSpecification:
12
+ raise NotImplementedError