Skip to content

Commit e9e45a8

Browse files
committed
workflow and last adaptations
1 parent 903c869 commit e9e45a8

File tree

7 files changed

+142
-22
lines changed

7 files changed

+142
-22
lines changed

.github/workflows/pypi-publish.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Publish Python distribution to PyPI
2+
3+
on: push
4+
5+
jobs:
6+
build:
7+
name: Build distribution 📦
8+
runs-on: ubuntu-latest
9+
10+
steps:
11+
- uses: actions/checkout@v4
12+
- name: Set up Python
13+
uses: actions/setup-python@v4
14+
with:
15+
python-version: "3.x"
16+
- name: Install pypa/build
17+
run: |
18+
python -m pip install --upgrade pip
19+
pip install poetry
20+
- name: Build a binary wheel and a source tarball
21+
run: |
22+
poetry build
23+
- name: Store the distribution packages
24+
uses: actions/upload-artifact@v4
25+
with:
26+
name: python-package-distributions
27+
path: dist/
28+
29+
publish-to-pypi:
30+
name: >-
31+
Publish Python distribution to PyPI
32+
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
33+
needs:
34+
- build
35+
runs-on: ubuntu-latest
36+
environment:
37+
name: release
38+
url: https://pypi.org/p/owl2yarrrml # Replace <package-name> with your PyPI project name
39+
permissions:
40+
id-token: write # IMPORTANT: mandatory for trusted publishing
41+
42+
steps:
43+
- name: Download all the dists
44+
uses: actions/download-artifact@v4
45+
with:
46+
name: python-package-distributions
47+
path: dist/
48+
- name: Publish distribution to PyPI
49+
uses: pypa/gh-action-pypi-publish@release/v1

README.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Transforming your ontology to YARRRML mappings
1+
# Transforming your ontology into YARRRML mappings
22
This script generates a YARRRML template from the input ontology. The transformations made are:
33

44
| Ontology | Mapping
@@ -8,9 +8,24 @@ This script generates a YARRRML template from the input ontology. The transforma
88
| Object Property | Join PredicateObjectMap in the TriplesMap corresponding to the class defined in the domain of the property and where the parentTriplesMap is the TriplesMap corresponding to the class defined in the range of the property |
99

1010
## How to execute it
11-
In order to avoid problems, we recommend that the input ontology follows RDF/XML syntax
1211

12+
### Execution from CLI
13+
The input ontology can be serialized in NTRIPLES, RDF/XML or Turtle
14+
```bash
15+
python3 -m pip install owl2ready
16+
python3 owl2yarrrml -i paht/ontology.xml -o ouput_path/mapping.yml
17+
```
18+
19+
### Execution as a library
20+
The ontology has to be provided in RDF/XML.
1321
```python
14-
python3 -m pip install -r requirements.txt
15-
python3 translate.py -i ontology.xml -o mapping.yml
22+
import owl2yarrrml
23+
import owlready2
24+
ontology=owlready2.get_ontology("file://path/to/my/ontology.xml").load()
25+
yarrrml_content = owl2yarrrml.translate(ontology)
26+
1627
```
28+
29+
## Authors
30+
CiTIUS - Universidade de Santiago de Compostela (2023-now) and Ontology Engineering Group - Universidad Politécnica de Madrid (2020-2023):
31+
- [David Chaves-Fraga](mailto:david.chaves@usc.es)

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ repository = "https://github.com/citius/owl2yarrrml"
1010
keywords = ["owl", "yarrrml", "rdf", "mapping", "ontology"]
1111

1212
[tool.poetry.dependencies]
13-
python = ">3.12"
13+
python = ">3.8.1,<4.0.0"
1414
PyYAML = "^6.0"
1515
owlready2 = "^0.39.0"
16+
rdflib="^7.1.4"
1617

1718
[tool.poetry.group.dev.dependencies]
1819
pytest = "^7.0.0"

src/owl2yarrrml/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
from .translate import *
3+
4+
5+
def translate(ontology):
6+
template = init_yarrrml()
7+
construct_mapping(template, ontology)
8+
return template

src/owl2yarrrml/__main__.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,37 @@
1+
from . import translate
12
import argparse
23
import sys
34
import yaml
45
import os
5-
from .translate import translate
6-
import owlready2
6+
import tempfile
7+
from rdflib import Graph
8+
from owlready2 import World
9+
10+
11+
# Inline load_ontology logic
12+
def load_ontology(path_or_url: str):
13+
"""
14+
Load ontology from a local file path or URL.
15+
Supports Turtle by converting via rdflib, otherwise uses Owlready2 directly.
16+
"""
17+
world = World()
18+
ext = path_or_url.split('.')[-1].lower()
19+
20+
if ext in ("ttl", "turtle"):
21+
# Parse Turtle to RDF/XML using rdflib
22+
g = Graph()
23+
g.parse(path_or_url, format="turtle")
24+
with tempfile.NamedTemporaryFile(suffix=".owl", delete=False) as tmp:
25+
tmp_path = tmp.name
26+
g.serialize(destination=tmp_path, format="xml")
27+
onto = world.get_ontology(f"file://{tmp_path}").load()
28+
else:
29+
# Assume RDF/XML, OWL/XML, N-Triples, etc.
30+
# Prepend file:// for local paths if needed
31+
if not path_or_url.startswith(("http://", "https://", "file://")):
32+
path_or_url = "file://" + os.path.abspath(path_or_url)
33+
onto = world.get_ontology(path_or_url).load()
34+
return onto
735

836
def parsing_arguments():
937
parser = argparse.ArgumentParser()
@@ -12,7 +40,7 @@ def parsing_arguments():
1240
args = parser.parse_args()
1341
if len(sys.argv) == 5:
1442
try:
15-
ontology = owlready2.get_ontology("file://" + os.path.abspath(str(args.ontology))).load()
43+
ontology = load_ontology(str(args.ontology))
1644
output_path = str(args.output)
1745
return ontology, output_path
1846
except ValueError:
@@ -30,7 +58,6 @@ def write_results():
3058
output_stream.write(dumped_yaml)
3159

3260
if __name__ == "__main__":
33-
# Allow execution via: python -m owl2yarrrml -i ontology.owl -o mapping.yaml
3461
ontology, output_path = parsing_arguments()
3562
mapping = translate(ontology)
3663
write_results()

src/owl2yarrrml/constants.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,36 @@
11

22

33

4-
URL_TEMPLATE = "https://raw.githubusercontent.com/oeg-upm/owl2yarrrml/refs/heads/main/refs/resources/template.yaml"
4+
YAML_TEMPLATE = """
5+
prefixes:
6+
xsd: http://www.w3.org/2001/XMLSchema#
7+
rr: http://www.w3.org/ns/r2rml#
8+
rml: http://semweb.mmlab.be/ns/rml#
9+
rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns#
10+
ql: http://semweb.mmlab.be/ns/ql#
11+
rdfs: http://www.w3.org/2000/01/rdf-schema#
12+
foaf: http://xmlns.com/foaf/0.1/
13+
schema: http://schema.org/
14+
dc: http://purl.org/dc/elements/1.1/
15+
skos: http://www.w3.org/2004/02/skos/core#
16+
17+
18+
mappings:
19+
triplesmap0:
20+
sources:
21+
- []
22+
s: http://$()
23+
po:
24+
- [a, class]
25+
- p: predicate
26+
o:
27+
- mapping: triplesmap2
28+
condition:
29+
function: equal
30+
parameters:
31+
- [str1, $()]
32+
- [str2, $()]
33+
"""
534

635
##############################################################################
736
############################# YARRRML CONSTANTS ###########################

src/owl2yarrrml/translate.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,11 @@
11
import yaml
22
import copy
3-
from urllib.request import urlopen
43
from owlready2 import *
54
from .constants import *
65

76

8-
def translate(ontology):
9-
template = init_yarrrml()
10-
construct_mapping(template, ontology)
11-
return template
12-
137
def init_yarrrml():
14-
with urlopen(URL_TEMPLATE) as response:
15-
content = response.read().decode('utf-8')
16-
template = yaml.load(content, Loader=yaml.FullLoader)
17-
return template
8+
return yaml.load(YAML_TEMPLATE, Loader=yaml.FullLoader)
189

1910

2011
def construct_mapping(template, onto):
@@ -75,7 +66,7 @@ def generate_prefixes(template, onto):
7566
prefixes[do.namespace.base_iri] = do.namespace.name
7667
return prefixes
7768

78-
def find_triplesmap(mapping, range):
69+
def find_triplesmap(mapping, range, prefixes):
7970
ref_triples_map = ""
8071
for triplesMap in dict.keys(mapping['mappings']):
8172
if mapping['mappings'][triplesMap]['po'][0][1] == range.iri.replace(range.namespace.base_iri, prefixes[range.namespace.base_iri] + ":"):
@@ -108,7 +99,7 @@ def generate_ref_object_maps(triplesmap, join_template, template, c, onto, prefi
10899

109100

110101
def create_join_condition(template, join_template, o, triplesmap, range, prefixes):
111-
triples_map_parent = find_triplesmap(template, range)
102+
triples_map_parent = find_triplesmap(template, range, prefixes)
112103
join = copy.deepcopy(join_template)
113104
join['p'] = o.iri.replace(o.namespace.base_iri, prefixes[o.namespace.base_iri] + ":")
114105
join['o'][0]['mapping'] = triples_map_parent

0 commit comments

Comments
 (0)