sensotwin.store_connection

  1from SPARQLWrapper import SPARQLWrapper, JSON, POST, GET
  2from abc import ABC, abstractmethod
  3from owlready2 import *
  4import os.path
  5
  6PREDEFINED_ONTOLOGIES["https://w3id.org/pmd/co/2.0.7/"] = "https://materialdigital.github.io/core-ontology/ontology.rdf"
  7
  8class StoreConnection(ABC):
  9    """Base class for store connections."""
 10    
 11    SPARQL_PREFIXES = [
 12        "xsd: <http://www.w3.org/2001/XMLSchema#>",
 13        "rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>",
 14        "owl: <http://www.w3.org/2002/07/owl#>",
 15        "rdfs: <http://www.w3.org/2000/01/rdf-schema#>",
 16        "senso: <http://w3id.org/sensotwin/applicationontology#>",
 17        "co: <https://w3id.org/pmd/co/>",
 18    ]
 19    
 20    @abstractmethod
 21    def __init__(self):
 22        pass
 23
 24    @abstractmethod
 25    def get_data(self):
 26        pass
 27        
 28    @abstractmethod
 29    def update_data(self):
 30        pass
 31
 32    def _get_prefix_stub(self):
 33        """Generate PREFIX statement for all query from SPARQL_PREFIXES."""
 34        return "\n".join(["PREFIX " + prefix for prefix in self.SPARQL_PREFIXES])
 35
 36
 37class LocalStoreConnection(StoreConnection):
 38    """Connection for storing data on local hard drive."""
 39
 40    _SUBFOLDER_NAME = "owlready_db"
 41    
 42    def __init__(self, world_name: str):
 43        """Establish connection to local sqlite3 file.
 44
 45        Args:
 46            world_name: file name of sqlite3 without file ending
 47        """
 48        self._world_name = world_name
 49        if not os.path.isdir(self._SUBFOLDER_NAME):
 50            os.makedirs(self._SUBFOLDER_NAME)
 51        self._sensotwin_world = World()
 52        world_file = "{}/{}.sqlite3".format(self._SUBFOLDER_NAME, self._world_name)
 53        if os.path.isfile(world_file):
 54            self._sensotwin_world.set_backend(filename = world_file, exclusive = False)
 55            self._onto = self._sensotwin_world.get_ontology("http://w3id.org/sensotwin/applicationontology#").load()
 56        else:
 57            self._sensotwin_world.set_backend(filename = world_file, exclusive = False)
 58            self._onto = self._sensotwin_world.get_ontology("https://upaehler.github.io/SensoTwin/v1.0.1/ontology.rdf").load()
 59        self._sensotwin_world.save()
 60
 61    def get_data(self, query: str) -> list:
 62        """Execute SELECT query against local database file.
 63
 64        Args:
 65            query: full SELECT statement without PREFIX statements
 66        
 67        Returns:
 68            list of retrieved data as specified in SELECT statement
 69        """
 70        result = self._sensotwin_world.sparql(self._get_prefix_stub() + query, error_on_undefined_entities=False)
 71        self._sensotwin_world.save()
 72        parsed_result = []
 73        for row in result:
 74            new_entry = []
 75            for item in row:
 76                if hasattr(item, 'name'):
 77                    new_entry.append(item.name)
 78                else:
 79                    new_entry.append(str(item))
 80            parsed_result.append(new_entry)
 81        return parsed_result
 82
 83    def update_data(self, query: str):
 84        """Execute INSERT query against local database file.
 85
 86        Args:
 87            full INSERT statement without PREFIX statement
 88        """
 89        with self._onto:
 90            # error_on_undefined_entities=False is essential to enable multiple inserts in 1 query, if new objects depend on each other
 91            result = self._sensotwin_world.sparql(self._get_prefix_stub() + query, error_on_undefined_entities=False)
 92            self._sensotwin_world.save()
 93        return result
 94
 95    def __str__(self):
 96        return "Local owlready2 database in '{}.sqlite3'".format(self._world_name)
 97
 98    def __repr__(self):
 99        return "LocalStoreConnection('{}')".format(self._world_name)
100
101
102class FusekiConnection(StoreConnection):
103    """Connection for storing data in remote Apache Jena Fuseki2 triple store."""
104
105    def __init__(self, url: str):
106        """Initialize SPARQLWrapper object."""
107        self._url = url
108        self._wrapper = SPARQLWrapper(url)
109        self._wrapper.setReturnFormat(JSON)
110
111    def get_data(self, query: str):
112        """Execute SELECT query against remote triple store.
113
114        Args:
115            query: full SELECT statement without PREFIX statements
116        
117        Returns:
118            list of retrieved data as specified in SELECT statement
119        """
120        self._wrapper.setMethod(GET)
121        self._wrapper.setQuery(self._get_prefix_stub() + query)
122        raw_result = self._wrapper.queryAndConvert()["results"]["bindings"]
123        parsed_result = []
124        for row in raw_result:
125            new_entry = []
126            for item in row.values():
127                if item['type'] == "uri":
128                    new_entry.append(item["value"].split('#')[-1])
129                else:
130                    new_entry.append(item["value"])
131            parsed_result.append(new_entry)
132        return parsed_result
133
134    def update_data(self, query: str) -> list:
135        """Execute INSERT query against remote triple store.
136
137        Args:
138            full INSERT statement without PREFIX statement
139        """
140        self._wrapper.setMethod(POST)
141        self._wrapper.setQuery(self._get_prefix_stub() + query)
142        return self._wrapper.queryAndConvert()
143
144    def __str__(self):
145        return "Remote Jena Fuseki database at '{}'".format(self._url)
146
147    def __repr__(self):
148        return "FusekiConnection('{}')".format(self._url)
class StoreConnection(abc.ABC):
 9class StoreConnection(ABC):
10    """Base class for store connections."""
11    
12    SPARQL_PREFIXES = [
13        "xsd: <http://www.w3.org/2001/XMLSchema#>",
14        "rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>",
15        "owl: <http://www.w3.org/2002/07/owl#>",
16        "rdfs: <http://www.w3.org/2000/01/rdf-schema#>",
17        "senso: <http://w3id.org/sensotwin/applicationontology#>",
18        "co: <https://w3id.org/pmd/co/>",
19    ]
20    
21    @abstractmethod
22    def __init__(self):
23        pass
24
25    @abstractmethod
26    def get_data(self):
27        pass
28        
29    @abstractmethod
30    def update_data(self):
31        pass
32
33    def _get_prefix_stub(self):
34        """Generate PREFIX statement for all query from SPARQL_PREFIXES."""
35        return "\n".join(["PREFIX " + prefix for prefix in self.SPARQL_PREFIXES])

Base class for store connections.

SPARQL_PREFIXES = ['xsd: <http://www.w3.org/2001/XMLSchema#>', 'rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>', 'owl: <http://www.w3.org/2002/07/owl#>', 'rdfs: <http://www.w3.org/2000/01/rdf-schema#>', 'senso: <http://w3id.org/sensotwin/applicationontology#>', 'co: <https://w3id.org/pmd/co/>']
@abstractmethod
def get_data(self):
25    @abstractmethod
26    def get_data(self):
27        pass
@abstractmethod
def update_data(self):
29    @abstractmethod
30    def update_data(self):
31        pass
class LocalStoreConnection(StoreConnection):
 38class LocalStoreConnection(StoreConnection):
 39    """Connection for storing data on local hard drive."""
 40
 41    _SUBFOLDER_NAME = "owlready_db"
 42    
 43    def __init__(self, world_name: str):
 44        """Establish connection to local sqlite3 file.
 45
 46        Args:
 47            world_name: file name of sqlite3 without file ending
 48        """
 49        self._world_name = world_name
 50        if not os.path.isdir(self._SUBFOLDER_NAME):
 51            os.makedirs(self._SUBFOLDER_NAME)
 52        self._sensotwin_world = World()
 53        world_file = "{}/{}.sqlite3".format(self._SUBFOLDER_NAME, self._world_name)
 54        if os.path.isfile(world_file):
 55            self._sensotwin_world.set_backend(filename = world_file, exclusive = False)
 56            self._onto = self._sensotwin_world.get_ontology("http://w3id.org/sensotwin/applicationontology#").load()
 57        else:
 58            self._sensotwin_world.set_backend(filename = world_file, exclusive = False)
 59            self._onto = self._sensotwin_world.get_ontology("https://upaehler.github.io/SensoTwin/v1.0.1/ontology.rdf").load()
 60        self._sensotwin_world.save()
 61
 62    def get_data(self, query: str) -> list:
 63        """Execute SELECT query against local database file.
 64
 65        Args:
 66            query: full SELECT statement without PREFIX statements
 67        
 68        Returns:
 69            list of retrieved data as specified in SELECT statement
 70        """
 71        result = self._sensotwin_world.sparql(self._get_prefix_stub() + query, error_on_undefined_entities=False)
 72        self._sensotwin_world.save()
 73        parsed_result = []
 74        for row in result:
 75            new_entry = []
 76            for item in row:
 77                if hasattr(item, 'name'):
 78                    new_entry.append(item.name)
 79                else:
 80                    new_entry.append(str(item))
 81            parsed_result.append(new_entry)
 82        return parsed_result
 83
 84    def update_data(self, query: str):
 85        """Execute INSERT query against local database file.
 86
 87        Args:
 88            full INSERT statement without PREFIX statement
 89        """
 90        with self._onto:
 91            # error_on_undefined_entities=False is essential to enable multiple inserts in 1 query, if new objects depend on each other
 92            result = self._sensotwin_world.sparql(self._get_prefix_stub() + query, error_on_undefined_entities=False)
 93            self._sensotwin_world.save()
 94        return result
 95
 96    def __str__(self):
 97        return "Local owlready2 database in '{}.sqlite3'".format(self._world_name)
 98
 99    def __repr__(self):
100        return "LocalStoreConnection('{}')".format(self._world_name)

Connection for storing data on local hard drive.

LocalStoreConnection(world_name: str)
43    def __init__(self, world_name: str):
44        """Establish connection to local sqlite3 file.
45
46        Args:
47            world_name: file name of sqlite3 without file ending
48        """
49        self._world_name = world_name
50        if not os.path.isdir(self._SUBFOLDER_NAME):
51            os.makedirs(self._SUBFOLDER_NAME)
52        self._sensotwin_world = World()
53        world_file = "{}/{}.sqlite3".format(self._SUBFOLDER_NAME, self._world_name)
54        if os.path.isfile(world_file):
55            self._sensotwin_world.set_backend(filename = world_file, exclusive = False)
56            self._onto = self._sensotwin_world.get_ontology("http://w3id.org/sensotwin/applicationontology#").load()
57        else:
58            self._sensotwin_world.set_backend(filename = world_file, exclusive = False)
59            self._onto = self._sensotwin_world.get_ontology("https://upaehler.github.io/SensoTwin/v1.0.1/ontology.rdf").load()
60        self._sensotwin_world.save()

Establish connection to local sqlite3 file.

Args: world_name: file name of sqlite3 without file ending

def get_data(self, query: str) -> list:
62    def get_data(self, query: str) -> list:
63        """Execute SELECT query against local database file.
64
65        Args:
66            query: full SELECT statement without PREFIX statements
67        
68        Returns:
69            list of retrieved data as specified in SELECT statement
70        """
71        result = self._sensotwin_world.sparql(self._get_prefix_stub() + query, error_on_undefined_entities=False)
72        self._sensotwin_world.save()
73        parsed_result = []
74        for row in result:
75            new_entry = []
76            for item in row:
77                if hasattr(item, 'name'):
78                    new_entry.append(item.name)
79                else:
80                    new_entry.append(str(item))
81            parsed_result.append(new_entry)
82        return parsed_result

Execute SELECT query against local database file.

Args: query: full SELECT statement without PREFIX statements

Returns: list of retrieved data as specified in SELECT statement

def update_data(self, query: str):
84    def update_data(self, query: str):
85        """Execute INSERT query against local database file.
86
87        Args:
88            full INSERT statement without PREFIX statement
89        """
90        with self._onto:
91            # error_on_undefined_entities=False is essential to enable multiple inserts in 1 query, if new objects depend on each other
92            result = self._sensotwin_world.sparql(self._get_prefix_stub() + query, error_on_undefined_entities=False)
93            self._sensotwin_world.save()
94        return result

Execute INSERT query against local database file.

Args: full INSERT statement without PREFIX statement

Inherited Members
StoreConnection
SPARQL_PREFIXES
class FusekiConnection(StoreConnection):
103class FusekiConnection(StoreConnection):
104    """Connection for storing data in remote Apache Jena Fuseki2 triple store."""
105
106    def __init__(self, url: str):
107        """Initialize SPARQLWrapper object."""
108        self._url = url
109        self._wrapper = SPARQLWrapper(url)
110        self._wrapper.setReturnFormat(JSON)
111
112    def get_data(self, query: str):
113        """Execute SELECT query against remote triple store.
114
115        Args:
116            query: full SELECT statement without PREFIX statements
117        
118        Returns:
119            list of retrieved data as specified in SELECT statement
120        """
121        self._wrapper.setMethod(GET)
122        self._wrapper.setQuery(self._get_prefix_stub() + query)
123        raw_result = self._wrapper.queryAndConvert()["results"]["bindings"]
124        parsed_result = []
125        for row in raw_result:
126            new_entry = []
127            for item in row.values():
128                if item['type'] == "uri":
129                    new_entry.append(item["value"].split('#')[-1])
130                else:
131                    new_entry.append(item["value"])
132            parsed_result.append(new_entry)
133        return parsed_result
134
135    def update_data(self, query: str) -> list:
136        """Execute INSERT query against remote triple store.
137
138        Args:
139            full INSERT statement without PREFIX statement
140        """
141        self._wrapper.setMethod(POST)
142        self._wrapper.setQuery(self._get_prefix_stub() + query)
143        return self._wrapper.queryAndConvert()
144
145    def __str__(self):
146        return "Remote Jena Fuseki database at '{}'".format(self._url)
147
148    def __repr__(self):
149        return "FusekiConnection('{}')".format(self._url)

Connection for storing data in remote Apache Jena Fuseki2 triple store.

FusekiConnection(url: str)
106    def __init__(self, url: str):
107        """Initialize SPARQLWrapper object."""
108        self._url = url
109        self._wrapper = SPARQLWrapper(url)
110        self._wrapper.setReturnFormat(JSON)

Initialize SPARQLWrapper object.

def get_data(self, query: str):
112    def get_data(self, query: str):
113        """Execute SELECT query against remote triple store.
114
115        Args:
116            query: full SELECT statement without PREFIX statements
117        
118        Returns:
119            list of retrieved data as specified in SELECT statement
120        """
121        self._wrapper.setMethod(GET)
122        self._wrapper.setQuery(self._get_prefix_stub() + query)
123        raw_result = self._wrapper.queryAndConvert()["results"]["bindings"]
124        parsed_result = []
125        for row in raw_result:
126            new_entry = []
127            for item in row.values():
128                if item['type'] == "uri":
129                    new_entry.append(item["value"].split('#')[-1])
130                else:
131                    new_entry.append(item["value"])
132            parsed_result.append(new_entry)
133        return parsed_result

Execute SELECT query against remote triple store.

Args: query: full SELECT statement without PREFIX statements

Returns: list of retrieved data as specified in SELECT statement

def update_data(self, query: str) -> list:
135    def update_data(self, query: str) -> list:
136        """Execute INSERT query against remote triple store.
137
138        Args:
139            full INSERT statement without PREFIX statement
140        """
141        self._wrapper.setMethod(POST)
142        self._wrapper.setQuery(self._get_prefix_stub() + query)
143        return self._wrapper.queryAndConvert()

Execute INSERT query against remote triple store.

Args: full INSERT statement without PREFIX statement

Inherited Members
StoreConnection
SPARQL_PREFIXES