Skip to content

Commit

Permalink
V3.4.0 dev (#452)
Browse files Browse the repository at this point in the history
Python v3.6 is supported again.
Namespaces are iterable again.
Few bug fixes.
  • Loading branch information
urbanmatthias authored Aug 4, 2020
1 parent ba39d30 commit 0da7b0c
Show file tree
Hide file tree
Showing 25 changed files with 176 additions and 70 deletions.
12 changes: 11 additions & 1 deletion osp/core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import sys
import logging
import osp.core.namespaces
from osp.core.namespaces import _namespace_registry

logging.getLogger("rdflib").setLevel(logging.WARNING)

Expand Down Expand Up @@ -29,8 +31,16 @@


def __getattr__(name):
import osp.core.namespaces
if name != "load_tests":
logger.warning(f"osp.core.{name} is deprecated. "
f"Use osp.core.namespaces.{name} instead.")
return getattr(osp.core.namespaces, name)


if (sys.version_info.major, sys.version_info.minor) <= (3, 6):
logger.info("We recommend using a python version of at least 3.7")
logger.info(f"osp.core.<namespace> is deprecated. "
f"Use osp.core.namespaces.<namespace> instead.")
_namespace_registry.update_namespaces(modules=[
sys.modules[__name__], namespaces
])
21 changes: 14 additions & 7 deletions osp/core/ontology/namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def _get(self, name, _case_sensitive=False, _force_by_iri=False):
try:
return self._do_get(name, _case_sensitive, _force_by_iri)
except KeyError as e:
if name.startswith("INVERSE_OF_"):
if name and name.startswith("INVERSE_OF_"):
return self._do_get(name[11:], _case_sensitive,
_force_by_iri).inverse
raise e
Expand Down Expand Up @@ -196,13 +196,20 @@ def _get_case_insensitive(self, name):
f"looked for {alternative} and failed."
) from e

# def __iter__(self): TODO
# """Iterate over the ontology entities in the namespace.
def __iter__(self):
"""Iterate over the ontology entities in the namespace.
# :return: An iterator over the entities.
# :rtype: Iterator[OntologyEntity]
# """
# return iter(self._entities.values())
:return: An iterator over the entities.
:rtype: Iterator[OntologyEntity]
"""
types = [rdflib.OWL.DatatypeProperty,
rdflib.OWL.ObjectProperty,
rdflib.OWL.Class]
for t in types:
for s, _, _ in self._graph.triples((None, rdflib.RDF.type, t)):
if str(s).startswith(str(self._iri)):
iri_suffix = str(s)[len(str(self._iri)):]
yield self._get(name=None, _force_by_iri=iri_suffix)

def __contains__(self, name):
return bool(self._get(name))
44 changes: 31 additions & 13 deletions osp/core/ontology/namespace_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

class NamespaceRegistry():
def __init__(self):
# Do not instantiate you own namespace registry.
# Instead you can use osp.core.namespaces._namespace_registry.
self._graph = rdflib.Graph()
self._namespaces = dict()

Expand All @@ -25,7 +27,8 @@ def __iter__(self):
:rtype: Iterator[OntologyNamespace]
"""
for namespace_name in self._namespaces:
yield self._get(namespace_name)
if namespace_name:
yield self._get(namespace_name)

def __getattr__(self, name):
try:
Expand Down Expand Up @@ -73,12 +76,16 @@ def _get(self, name):
iri=self._namespaces[name])
raise KeyError("Namespace %s not installed." % name)

def update_namespaces(self):
def update_namespaces(self, modules=[]):
"""Update the namespaces of the namespace registry from the
namespaces of the graph."""
self._namespaces = dict()
for name, iri in self._graph.namespace_manager.namespaces():
self._namespaces[name.lower()] = iri
for module in modules:
for namespace in self:
setattr(module, namespace.get_name().upper(), namespace)
setattr(module, namespace.get_name().lower(), namespace)

def from_iri(self, iri):
"""Get an entity from IRI.
Expand All @@ -89,17 +96,28 @@ def from_iri(self, iri):
Returns:
OntologyEntity: The OntologyEntity.
"""
for name, ns_iri in self._graph.namespace_manager.namespaces():
if str(iri).startswith(str(ns_iri)):
ns = OntologyNamespace(
name=name,
namespace_registry=self,
iri=ns_iri
)
if ns._reference_by_label:
return ns._get(None, _force_by_iri=iri[len(ns_iri):])
else:
return ns._get(iri[len(ns_iri):])
for _name, _ns_iri in self._graph.namespace_manager.namespaces():
if str(iri).startswith(str(_ns_iri)) and _name:
name = _name
ns_iri = _ns_iri
break
else:
if "#" in str(iri):
ns_iri = str(iri).split("#")[0] + "#"
else:
ns_iri = "/".join(str(iri).split("/")[:-1]) + "/"
name = str(ns_iri)
ns_iri = rdflib.URIRef(ns_iri)

ns = OntologyNamespace(
name=name,
namespace_registry=self,
iri=ns_iri
)
if ns._reference_by_label:
return ns._get(None, _force_by_iri=iri[len(ns_iri):])
else:
return ns._get(iri[len(ns_iri):])

def clear(self):
"""Clear the loaded Graph and load cuba only.
Expand Down
26 changes: 25 additions & 1 deletion osp/core/ontology/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ def _parse_rdf(self, **kwargs):
default_rels[iri] = default_rel
reference_styles[iri] = reference_style

self._check_namespaces()
self._add_cuba_triples(active_rels)
self._add_default_rel_triples(default_rels)
self._add_reference_style_triples(reference_styles)
Expand Down Expand Up @@ -252,8 +253,14 @@ def _add_cuba_triples(self, active_rels):
active_rels (List[str]): The URIs of the active relationships.
"""
for rel in active_rels:
iri = rdflib.URIRef(rel)
if (iri, rdflib.RDF.type, rdflib.OWL.ObjectProperty) \
not in self.graph:
raise ValueError(f"Specified relationship {rel} as "
f"active relationship, which is not "
f"a valid object property in the ontology.")
self.graph.add(
(rdflib.URIRef(rel), rdflib.RDFS.subPropertyOf,
(iri, rdflib.RDFS.subPropertyOf,
rdflib_cuba.activeRelationship)
)

Expand All @@ -271,3 +278,20 @@ def _add_reference_style_triples(self, reference_styles):
rdflib_cuba._reference_by_label,
rdflib.Literal(True)
))

def _check_namespaces(self):
namespaces = set(x for _, x in self.graph.namespaces()
if not x.startswith("http://www.w3.org/"))
for s, p, o in self.graph:
pop = None
for ns in namespaces:
if s.startswith(ns):
pop = ns
logger.debug(f"There exists an entity for namespace {ns}:"
f"\n\t{s, p, o}")
if pop:
namespaces.remove(pop)
if not namespaces:
break
for namespace in namespaces:
logger.warning(f"There exists no entity for namespace {namespace}")
31 changes: 19 additions & 12 deletions osp/wrappers/simdummy/simdummy_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@
from osp.core.session.sim_wrapper_session import SimWrapperSession
from osp.core.utils import change_oclass

try:
from osp.core.namespaces import city
except ImportError:
from osp.core.ontology import Parser
from osp.core.namespaces import _namespace_registry
Parser(_namespace_registry._graph).parse("city")
_namespace_registry.update_namespaces()
city = _namespace_registry.city


class SimDummySession(SimWrapperSession):
def __init__(self, **kwargs):
super().__init__(engine=DummySyntacticLayer(), **kwargs)
from osp.core.namespaces import city
self.onto = city
self._person_map = dict()

def __str__(self):
Expand All @@ -24,7 +31,7 @@ def _load_from_backend(self, uids, expired=None):
# update the age of each person and delete persons that became citizens
for uid in uids:
root_cuds_object = self._registry.get(self.root)
cities = root_cuds_object.get(oclass=self.onto.City)
cities = root_cuds_object.get(oclass=city.City)
if uid == self.root:
yield self._load_wrapper(uid)
elif cities and uid == cities[0].uid:
Expand All @@ -41,15 +48,15 @@ def _load_person(self, uid):
person = self._registry.get(uid)
idx = self._person_map[uid]
person.age = self._engine.get_person(idx)[1].age
if person.is_a(self.onto.Citizen):
if person.is_a(city.Citizen):
return person
self._check_convert_to_inhabitant(uid)
return person

def _load_city(self, uid):
c = self._registry.get(uid)
inhabitant_uids = set(
[x.uid for x in c.get(rel=self.onto.hasInhabitant)]
[x.uid for x in c.get(rel=city.hasInhabitant)]
)
person_uids = self._person_map.keys() - inhabitant_uids
for person_uid in person_uids:
Expand All @@ -58,22 +65,22 @@ def _load_city(self, uid):

def _load_wrapper(self, uid):
wrapper = self._registry.get(uid)
for person in wrapper.get(oclass=self.onto.Person):
for person in wrapper.get(oclass=city.Person):
self.refresh(person.uid)
return wrapper

def _check_convert_to_inhabitant(self, uid):
wrapper = self._registry.get(self.root)
c = wrapper.get(oclass=self.onto.City)[0]
c = wrapper.get(oclass=city.City)[0]
idx = self._person_map[uid]
is_inhabitant, dummy_person = self._engine.get_person(idx)
if is_inhabitant:
person = self._registry.get(uid)
change_oclass(person, self.onto.Citizen,
change_oclass(person, city.Citizen,
{"name": dummy_person.name,
"age": dummy_person.age})
wrapper.remove(person, rel=self.onto.hasPart)
c.add(person, rel=self.onto.hasInhabitant)
wrapper.remove(person, rel=city.hasPart)
c.add(person, rel=city.hasInhabitant)

# OVERRIDE
def _apply_added(self, root_obj, buffer):
Expand All @@ -85,9 +92,9 @@ def _apply_added(self, root_obj, buffer):
key=lambda x: x.name if hasattr(x, "name") else "0")
for added in sorted_added:
if (
added.is_a(self.onto.Person)
added.is_a(city.Person)
and self.root in map(lambda x: x.uid,
added.get(rel=self.onto.isPartOf))
added.get(rel=city.isPartOf))
):
idx = self._engine.add_person(DummyPerson(added.name,
added.age))
Expand Down
2 changes: 1 addition & 1 deletion packageinfo.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
NAME = "osp-core"
VERSION = "3.3.9"
VERSION = "3.4.0"
2 changes: 1 addition & 1 deletion tests/parser_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ ontology_file: parser_test.ttl
format: "ttl"
default_relationship: http://www.osp-core.com/parser_test#relationshipA
active_relationships:
- http://www.osp-core.com/parser_test#relationshipA,
- http://www.osp-core.com/parser_test#relationshipA
- http://www.osp-core.com/parser_test#relationshipB
2 changes: 1 addition & 1 deletion tests/performance_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from osp.core.namespaces import _namespace_registry
Parser(_namespace_registry._graph).parse("city")
_namespace_registry.update_namespaces()
from osp.core.namespaces import city
city = _namespace_registry.city

RUN_PERFORMANCE_TEST = False

Expand Down
2 changes: 1 addition & 1 deletion tests/sqlite_performance_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from osp.core.namespaces import _namespace_registry
Parser(_namespace_registry._graph).parse("city")
_namespace_registry.update_namespaces()
from osp.core.namespaces import city
city = _namespace_registry.city

RUN_PERFORMANCE_TEST = False
DB = "performance_test.db"
Expand Down
2 changes: 1 addition & 1 deletion tests/test_api_city.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from osp.core.namespaces import _namespace_registry
Parser(_namespace_registry._graph).parse("city")
_namespace_registry.update_namespaces()
from osp.core.namespaces import city
city = _namespace_registry.city


class TestAPICity(unittest.TestCase):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_dataspace_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from osp.core.namespaces import _namespace_registry
Parser(_namespace_registry._graph).parse("city")
_namespace_registry.update_namespaces()
from osp.core.namespaces import city
city = _namespace_registry.city

HOST = "127.0.0.1"
PORT = 8681
Expand Down
2 changes: 1 addition & 1 deletion tests/test_filetransfer.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def async_test(x):
from osp.core.namespaces import _namespace_registry
Parser(_namespace_registry._graph).parse("city")
_namespace_registry.update_namespaces()
from osp.core.namespaces import city
city = _namespace_registry.city

HOST = "127.0.0.1"
PORT = 8645
Expand Down
Loading

0 comments on commit 0da7b0c

Please sign in to comment.