diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9ada6ba7..ccd89d03 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,29 +1,24 @@ -#name: Python package -# -#on: [push,pull_request] -# -#jobs: -# build: -# runs-on: ubuntu-latest -# strategy: -# matrix: -# python-version: ["3.9"] -# max-parallel: 5 -# steps: -# - uses: actions/checkout@v3 -# - name: Set up Python ${{ matrix.python-version }} -# uses: actions/setup-python@v4 -# with: -# python-version: ${{ matrix.python-version }} -# -# - name: Install dependencies -# run: | -# python -m pip install --upgrade pip -# pip install -r requirements.txt -# -# - name: Test with pytest -# run: | -# pip install pytest -# wget https://files.dice-research.org/projects/Ontolearn/KGs.zip -# unzip KGs.zip -# pytest -p no:warnings -x \ No newline at end of file +name: Python package + +on: [push,pull_request] +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10.13"] + + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -e . + + - name: Test with pytest + run: | + python -m pytest -p no:warnings -x diff --git a/README.md b/README.md index b13711f9..4512ebd2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -# OWLpy: OWL in Python - +# OWLAPY ## Installation
Click me! @@ -15,9 +14,8 @@ pip3 install owlapy ```
- - ## Usage +
Click me! In this example we start with a simple atomic class expression and move to some more complex ones and finally render and print the last of them in description logics syntax. @@ -26,6 +24,7 @@ ones and finally render and print the last of them in description logics syntax. from owlapy.render import DLSyntaxObjectRenderer from owlapy.model import IRI, OWLClass, OWLObjectProperty, OWLObjectSomeValuesFrom, \ OWLObjectIntersectionOf +from owlapy.owl2sparql.converter import owl_expression_to_sparql # Create an IRI object using the iri as a string for 'male' class. male_iri = IRI.create('http://example.com/society#male') @@ -46,7 +45,7 @@ male_teachers_with_children = OWLObjectIntersectionOf([males_with_children, teac # You can render and print owl class expressions in description logics syntax print(DLSyntaxObjectRenderer().render(male_teachers_with_children)) # (∃ hasChild.male) ⊓ teacher -print(Owl2SparqlConverter().as_query("?x", male_teachers_with_children)) +print(owl_expression_to_sparql("?x", male_teachers_with_children)) # SELECT DISTINCT ?x WHERE { ?x ?s_1 . ?s_1 a . ?x a . } } ``` For more, you can check the [API documentation](https://ontolearn-docs-dice-group.netlify.app/autoapi/owlapy/#module-owlapy). @@ -61,14 +60,7 @@ class. In the above examples we have introduced 3 types of class expressions: Like we showed in this example, you can create all kinds of class expressions using the OWL objects in [owlapy model](https://ontolearn-docs-dice-group.netlify.app/autoapi/owlapy/model/#module-owlapy.model). +
- -### Are you looking for more? - -The java _owlapi_ library also offers classes for OWL ontology, manager and reasoner. -We have also implemented those classes in python, but for the time being we are -not including them in owlapy. You can find all of those classes in -[Ontolearn](https://github.com/dice-group/Ontolearn/tree/develop), which is a -python library that offers more than just that. - -In case you have any question or request please don't hesitate to open an issue. \ No newline at end of file +## How to cite +Currently, we are working on our manuscript describing our framework. diff --git a/owlapy/model/__init__.py b/owlapy/model/__init__.py index e8ea7b72..707d6247 100644 --- a/owlapy/model/__init__.py +++ b/owlapy/model/__init__.py @@ -1,12 +1,4 @@ -"""The OWL-APy Model classes and methods. - -Their names should match those of OWL API [1]. - -If OWL API has streaming and getter API, it is enough to provide the streaming API only. - -Many help texts copied from OWL API. - -[1] https://github.com/owlcs/owlapi""" +"""@TODO: CD: This is not a python code. We should refactor this model module.""" from abc import ABCMeta, abstractmethod from functools import total_ordering @@ -245,6 +237,14 @@ def get_nnf(self) -> 'OWLClass': # documented in parent return self + @property + def str(self): + return self.get_iri().as_str() + + @property + def reminder(self)->str: + """The reminder of the IRI """ + return self.get_iri().get_remainder() class OWLPropertyExpression(OWLObject, metaclass=ABCMeta): """Represents a property or possibly the inverse of a property.""" @@ -408,6 +408,10 @@ def is_owl_top_object_property(self) -> bool: # documented in parent return self.get_iri() == OWLRDFVocabulary.OWL_TOP_OBJECT_PROPERTY.get_iri() + @property + def str(self)->str: + return self.get_iri().as_str() + class OWLObjectInverseOf(OWLObjectPropertyExpression): """Represents the inverse of a property expression (ObjectInverseOf). This can be used to refer to the inverse of diff --git a/owlapy/model/_iri.py b/owlapy/model/_iri.py index 5e348443..9fe98744 100644 --- a/owlapy/model/_iri.py +++ b/owlapy/model/_iri.py @@ -147,11 +147,30 @@ def as_iri(self) -> 'IRI': def as_str(self) -> str: """ + CD: Should be deprecated. Returns: The string that specifies the IRI. """ return self._namespace + self._remainder + @property + def str(self) -> str: + """ + + Returns: + The string that specifies the IRI. + """ + return self.as_str() + + @property + def reminder(self) -> str: + """ + + Returns: + The string corresponding to the reminder of the IRI. + """ + return self.reminder() + def get_short_form(self) -> str: """Gets the short form. diff --git a/owlapy/owl2sparql/converter.py b/owlapy/owl2sparql/converter.py index c7074570..9b6ef4cc 100644 --- a/owlapy/owl2sparql/converter.py +++ b/owlapy/owl2sparql/converter.py @@ -495,7 +495,7 @@ def _(self, ce: OWLObjectOneOf): self.append(",") assert isinstance(ind, OWLNamedIndividual) self.append(f"<{ind.to_string_id()}>") - self.append(f" )") + self.append(f" ) )") @process.register def _(self, ce: OWLDataSomeValuesFrom): @@ -626,3 +626,14 @@ def as_query(self, query = "\n".join(qs) parseQuery(query) return query + + +converter = Owl2SparqlConverter() + + +def owl_expression_to_sparql(root_variable: str, + ce: OWLClassExpression, + count: bool = False, + values: Optional[Iterable[OWLNamedIndividual]] = None, + named_individuals: bool = False): + return converter.as_query(root_variable, ce, count, values, named_individuals) diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index e8c98187..00000000 --- a/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -pandas>=1.5.0 -rdflib>=6.0.2 -parsimonious>=0.8.1 \ No newline at end of file diff --git a/setup.py b/setup.py index 690a4b7d..5f508633 100644 --- a/setup.py +++ b/setup.py @@ -11,15 +11,16 @@ install_requires=[ "pandas>=1.5.0", "rdflib>=6.0.2", - "parsimonious>=0.8.1"], - author='Ontolearn Team', + "parsimonious>=0.8.1", + "pytest>=8.1.1"], + author='Caglar Demir', author_email='caglardemir8@gmail.com', url='https://github.com/dice-group/owlapy', classifiers=[ - "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.10", "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)", "Topic :: Scientific/Engineering"], - python_requires='>=3.8', + python_requires='>=3.10', long_description=long_description, long_description_content_type="text/markdown", )