From f1457613e8eb4a86649cbe052d061359c71c9a7a Mon Sep 17 00:00:00 2001 From: Paco Nathan Date: Sun, 27 Mar 2022 13:26:02 -0700 Subject: [PATCH 1/8] WIP refactor KG class #237 --- kglab/kglab.py | 4 + kglab/query/__init__.py | 0 kglab/query/base.py | 26 +++++ kglab/query/sparql.py | 220 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 250 insertions(+) create mode 100644 kglab/query/__init__.py create mode 100644 kglab/query/base.py create mode 100644 kglab/query/sparql.py diff --git a/kglab/kglab.py b/kglab/kglab.py index 671817d..ba404e4 100644 --- a/kglab/kglab.py +++ b/kglab/kglab.py @@ -38,6 +38,7 @@ from kglab.gpviz import GPViz from kglab.util import get_gpu_count from kglab.version import _check_version +import kglab.query.sparql ## pre-constructor set-up @@ -138,6 +139,9 @@ def __init__ ( for prefix, iri in namespaces.items(): self.add_ns(prefix, iri) + # backwards compatibility for class refactoring + self.sparql = kglab.query.sparql.SparqlQueryable(self) + def build_blank_graph ( self, diff --git a/kglab/query/__init__.py b/kglab/query/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kglab/query/base.py b/kglab/query/base.py new file mode 100644 index 0000000..f0448a9 --- /dev/null +++ b/kglab/query/base.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# see license https://github.com/DerwenAI/kglab#license-and-copyright + +""" +Queryable abstraction layer. +""" + +from abc import ABC, abstractmethod +import typing + + +class Queryable (ABC): + """ +Abstract class for query support. + """ + + @abstractmethod + def query ( + self, + query: str, + ) -> typing.Iterable: + """ +Abstract method for querying. + """ + pass # pylint: disable=W0107 diff --git a/kglab/query/sparql.py b/kglab/query/sparql.py new file mode 100644 index 0000000..211e569 --- /dev/null +++ b/kglab/query/sparql.py @@ -0,0 +1,220 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# see license https://github.com/DerwenAI/kglab#license-and-copyright + +""" +SPARQL query abstractions. +""" +import re +import typing + +import pandas as pd # type: ignore # pylint: disable=E0401 +import pyvis # type: ignore # pylint: disable=E0401 +import rdflib # type: ignore # pylint: disable=E0401 + +from kglab.gpviz import GPViz +from kglab.pkg_types import RDF_Node +from kglab.util import get_gpu_count + +from .base import Queryable + + +## pre-constructor set-up +if get_gpu_count() > 0: + import cudf # type: ignore # pylint: disable=E0401 + + +class SparqlQueryable (Queryable): + """ +SPARQL implementation for Queryable abstract class. + """ + + def __init__ ( + self, + kg: typing.Any, + ) -> None: + """ +Constructor. + """ + self.kg = kg + + + ###################################################################### + ## SPARQL queries + + def query ( # pylint: disable=W0221 + self, + query: str, + *, + bindings: dict = None, + ) -> typing.Iterable: + """ +Wrapper for [`rdflib.Graph.query()`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=query#rdflib.Graph.query) to perform a SPARQL query on the RDF graph. + + query: +text for the SPARQL query + + bindings: +initial variable bindings + + yields: +[`rdflib.query.ResultRow`](https://rdflib.readthedocs.io/en/stable/_modules/rdflib/query.html?highlight=ResultRow#) named tuples, to iterate through the query result set + """ + if not bindings: + bindings = {} + + for row in self.kg._g.query( # pylint: disable=W0212 + query, + initBindings=bindings, + ): + yield row + + + def query_as_df ( + self, + query: str, + *, + bindings: dict = None, + simplify: bool = True, + pythonify: bool = True, + ) -> pd.DataFrame: + """ +Wrapper for [`rdflib.Graph.query()`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=query#rdflib.Graph.query) to perform a SPARQL query on the RDF graph. + + query: +text for the SPARQL query + + bindings: +initial variable bindings + + simplify: +convert terms in each row of the result set into a readable representation for each term, using N3 format + + pythonify: +convert instances of [`rdflib.term.Literal`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=Literal#rdflib.term.Identifier) to their Python literal representation + + returns: +the query result set represented as a [`pandas.DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html); uses the [RAPIDS `cuDF` library](https://docs.rapids.ai/api/cudf/stable/) if GPUs are enabled + """ + if not bindings: + bindings = {} + + row_iter = self.kg._g.query(query, initBindings=bindings) # pylint: disable=W0212 + + if simplify: + rows_list = [ self.n3fy_row(r.asdict(), pythonify=pythonify) for r in row_iter ] + else: + rows_list = [ r.asdict() for r in row_iter ] + + if self.kg.use_gpus: + df = cudf.DataFrame(rows_list) + else: + df = pd.DataFrame(rows_list) + + return df + + + def n3fy ( + self, + node: RDF_Node, + *, + pythonify: bool = True, + ) -> typing.Any: + """ +Wrapper for RDFlib [`n3()`](https://rdflib.readthedocs.io/en/stable/utilities.html?highlight=n3#serializing-a-single-term-to-n3) and [`toPython()`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=toPython#rdflib.Variable.toPython) to serialize a node into a human-readable representation using N3 format. + + node: +must be a [`rdflib.term.Node`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=Node#rdflib.term.Node) + + pythonify: +flag to force instances of [`rdflib.term.Literal`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=Literal#rdflib.term.Identifier) to their Python literal representation + + returns: +text (or Python objects) for the serialized node + """ + if pythonify and isinstance(node, rdflib.term.Literal): + serialized = node.toPython() + else: + serialized = node.n3(self.kg._g.namespace_manager) # type: ignore # pylint: disable=W0212 + + return serialized + + + def n3fy_row ( + self, + row_dict: dict, + *, + pythonify: bool = True, + ) -> dict: + """ +Wrapper for RDFlib [`n3()`](https://rdflib.readthedocs.io/en/stable/utilities.html?highlight=n3#serializing-a-single-term-to-n3) and [`toPython()`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=toPython#rdflib.Variable.toPython) to serialize one row of a result set from a SPARQL query into a human-readable representation for each term using N3 format. + + row_dict: +one row of a SPARQL query results, as a `dict` + + pythonify: +flag to force instances of [`rdflib.term.Literal`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=Literal#rdflib.term.Identifier) to their Python literal representation + + returns: +a dictionary of serialized row bindings + """ + bindings = { + k: self.n3fy(v, pythonify=pythonify) + for k, v in row_dict.items() + } + + return bindings + + + @classmethod + def unbind_sparql ( + cls, + query: str, + bindings: dict, + *, + preamble: str = "", + ) -> str: + """ +Substitute the _binding variables_ into the text of a SPARQL query, +to obviate the need for binding variables specified separately. +This can be helpful for debugging, or for some query engines that +may not have full SPARQL support yet. + + query: +text for the SPARQL query + + bindings: +variable bindings + + returns: +a string of the expanded SPARQL query + """ + sparql_meta, sparql_body = re.split(r"\s*WHERE\s*\{", query, maxsplit=1) + + for var in sorted(bindings.keys(), key=lambda x: len(x), reverse=True): # pylint: disable=W0108 + pattern = re.compile("(\?" + var + ")(\W)") # pylint: disable=W1401 + bind_val = "<" + str(bindings[var]) + ">\\2" + sparql_body = re.sub(pattern, bind_val, sparql_body) + + return "".join([preamble, sparql_meta, " WHERE {", sparql_body]).strip() + + + def visualize_query ( + self, + query: str, + *, + notebook: bool = False, + ) -> pyvis.network.Network: + """ +Visualize the given SPARQL query as a [`pyvis.network.Network`](https://pyvis.readthedocs.io/en/latest/documentation.html#pyvis.network.Network) + + query: +input SPARQL query to be visualized + + notebook: +optional boolean flag, whether to initialize the PyVis graph to render within a notebook; defaults to `False` + + returns: +PyVis network object, to be rendered + """ + return GPViz(query, self.kg._ns).visualize_query(notebook=notebook) # pylint: disable=W0212 From 1f83702a6f369352a3c85e720a512a0913ee550a Mon Sep 17 00:00:00 2001 From: Paco Nathan Date: Sun, 27 Mar 2022 19:31:42 -0700 Subject: [PATCH 2/8] WIP refactor KG class #237 --- kglab/query/base.py | 13 +++++++++++++ kglab/query/sparql.py | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/kglab/query/base.py b/kglab/query/base.py index f0448a9..f1db052 100644 --- a/kglab/query/base.py +++ b/kglab/query/base.py @@ -9,6 +9,8 @@ from abc import ABC, abstractmethod import typing +import pandas as pd # type: ignore # pylint: disable=E0401 + class Queryable (ABC): """ @@ -24,3 +26,14 @@ def query ( Abstract method for querying. """ pass # pylint: disable=W0107 + + + @abstractmethod + def query_as_df ( + self, + query: str, + ) -> pd.DataFrame: + """ +Abstract method for querying, which returns a pandas DataFrame. + """ + pass # pylint: disable=W0107 diff --git a/kglab/query/sparql.py b/kglab/query/sparql.py index 211e569..32675e2 100644 --- a/kglab/query/sparql.py +++ b/kglab/query/sparql.py @@ -70,7 +70,7 @@ def query ( # pylint: disable=W0221 yield row - def query_as_df ( + def query_as_df ( # pylint: disable=W0221 self, query: str, *, @@ -199,7 +199,7 @@ def unbind_sparql ( return "".join([preamble, sparql_meta, " WHERE {", sparql_body]).strip() - def visualize_query ( + def visualize ( self, query: str, *, From 6a1df9a47c5899e000c704a0d475d896e88dd2e4 Mon Sep 17 00:00:00 2001 From: Paco Nathan Date: Sun, 3 Apr 2022 08:40:54 -0700 Subject: [PATCH 3/8] update docs --- README.md | 43 +++++++++++++++++++++++++------------------ changelog.txt | 6 +++--- docs/ack.md | 1 + kglab/version.py | 2 +- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 4e7fdc7..1b08dac 100644 --- a/README.md +++ b/README.md @@ -158,24 +158,8 @@ For detailed instructions please see: -illustration of a knowledge graph, plus laboratory glassware - - -## License and Copyright - -Source code for **kglab** plus its logo, documentation, and examples -have an [MIT license](https://spdx.org/licenses/MIT.html) which is -succinct and simplifies use in commercial applications. - -All materials herein are Copyright © 2020-2022 Derwen, Inc. - - -## Attribution - +
+ Attribution Please use the following BibTeX entry for citing **kglab** if you use it in your research or software. Citations are helpful for the continued development and maintenance of @@ -191,6 +175,22 @@ this library. url = {https://github.com/DerwenAI/kglab} } ``` +
+ +illustration of a knowledge graph, plus laboratory glassware + + +## License and Copyright + +Source code for **kglab** plus its logo, documentation, and examples +have an [MIT license](https://spdx.org/licenses/MIT.html) which is +succinct and simplifies use in commercial applications. + +All materials herein are Copyright © 2020-2022 Derwen, Inc. ## Kudos @@ -205,6 +205,7 @@ and to our contributors: [@Mec-iS](https://github.com/Mec-iS), [@cutterkom](https://github.com/cutterkom), [@RishiKumarRay](https://github.com/RishiKumarRay), +[@Tpt](https://github.com/Tpt), [@ArenasGuerreroJulian](https://github.com/ArenasGuerreroJulian), [@fils](https://github.com/fils), [@gauravjaglan](https://github.com/gauravjaglan), @@ -222,3 +223,9 @@ the [RAPIDS team @ NVIDIA](https://rapids.ai/), [Gradient Flow](https://gradientflow.com/), and [Manning Publications](https://www.manning.com/). + +kglab contributors + diff --git a/changelog.txt b/changelog.txt index 3abfd4a..eef753f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,10 +1,10 @@ # `kglab` changelog -## 0.6.? +## 0.6.1 -2022-??-?? +2022-04-?? - * ??? + * automated RDF tests, coordinated with `Oxigraph`; kudos @Mec-iS, @Tpt ## 0.6.0 diff --git a/docs/ack.md b/docs/ack.md index e81c904..9f4ee7a 100644 --- a/docs/ack.md +++ b/docs/ack.md @@ -13,6 +13,7 @@ and to our contributors: [@Mec-iS](https://github.com/Mec-iS), [@cutterkom](https://github.com/cutterkom), [@RishiKumarRay](https://github.com/RishiKumarRay), +[@Tpt](https://github.com/Tpt), [@ArenasGuerreroJulian](https://github.com/ArenasGuerreroJulian), [@fils](https://github.com/fils), [@gauravjaglan](https://github.com/gauravjaglan), diff --git a/kglab/version.py b/kglab/version.py index b34c580..0c374e5 100644 --- a/kglab/version.py +++ b/kglab/version.py @@ -11,7 +11,7 @@ MIN_PY_VERSION: typing.Tuple = (3, 7,) -__version__: str = "0.6.0" +__version__: str = "0.6.1" def _versify ( From 225c9f15e6c3d37b10fab4d157df3cc8b43404ab Mon Sep 17 00:00:00 2001 From: Paco Nathan Date: Sun, 27 Mar 2022 13:26:02 -0700 Subject: [PATCH 4/8] WIP refactor KG class #237 --- kglab/kglab.py | 4 + kglab/query/__init__.py | 0 kglab/query/base.py | 26 +++++ kglab/query/sparql.py | 220 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 250 insertions(+) create mode 100644 kglab/query/__init__.py create mode 100644 kglab/query/base.py create mode 100644 kglab/query/sparql.py diff --git a/kglab/kglab.py b/kglab/kglab.py index 671817d..ba404e4 100644 --- a/kglab/kglab.py +++ b/kglab/kglab.py @@ -38,6 +38,7 @@ from kglab.gpviz import GPViz from kglab.util import get_gpu_count from kglab.version import _check_version +import kglab.query.sparql ## pre-constructor set-up @@ -138,6 +139,9 @@ def __init__ ( for prefix, iri in namespaces.items(): self.add_ns(prefix, iri) + # backwards compatibility for class refactoring + self.sparql = kglab.query.sparql.SparqlQueryable(self) + def build_blank_graph ( self, diff --git a/kglab/query/__init__.py b/kglab/query/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kglab/query/base.py b/kglab/query/base.py new file mode 100644 index 0000000..f0448a9 --- /dev/null +++ b/kglab/query/base.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# see license https://github.com/DerwenAI/kglab#license-and-copyright + +""" +Queryable abstraction layer. +""" + +from abc import ABC, abstractmethod +import typing + + +class Queryable (ABC): + """ +Abstract class for query support. + """ + + @abstractmethod + def query ( + self, + query: str, + ) -> typing.Iterable: + """ +Abstract method for querying. + """ + pass # pylint: disable=W0107 diff --git a/kglab/query/sparql.py b/kglab/query/sparql.py new file mode 100644 index 0000000..211e569 --- /dev/null +++ b/kglab/query/sparql.py @@ -0,0 +1,220 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# see license https://github.com/DerwenAI/kglab#license-and-copyright + +""" +SPARQL query abstractions. +""" +import re +import typing + +import pandas as pd # type: ignore # pylint: disable=E0401 +import pyvis # type: ignore # pylint: disable=E0401 +import rdflib # type: ignore # pylint: disable=E0401 + +from kglab.gpviz import GPViz +from kglab.pkg_types import RDF_Node +from kglab.util import get_gpu_count + +from .base import Queryable + + +## pre-constructor set-up +if get_gpu_count() > 0: + import cudf # type: ignore # pylint: disable=E0401 + + +class SparqlQueryable (Queryable): + """ +SPARQL implementation for Queryable abstract class. + """ + + def __init__ ( + self, + kg: typing.Any, + ) -> None: + """ +Constructor. + """ + self.kg = kg + + + ###################################################################### + ## SPARQL queries + + def query ( # pylint: disable=W0221 + self, + query: str, + *, + bindings: dict = None, + ) -> typing.Iterable: + """ +Wrapper for [`rdflib.Graph.query()`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=query#rdflib.Graph.query) to perform a SPARQL query on the RDF graph. + + query: +text for the SPARQL query + + bindings: +initial variable bindings + + yields: +[`rdflib.query.ResultRow`](https://rdflib.readthedocs.io/en/stable/_modules/rdflib/query.html?highlight=ResultRow#) named tuples, to iterate through the query result set + """ + if not bindings: + bindings = {} + + for row in self.kg._g.query( # pylint: disable=W0212 + query, + initBindings=bindings, + ): + yield row + + + def query_as_df ( + self, + query: str, + *, + bindings: dict = None, + simplify: bool = True, + pythonify: bool = True, + ) -> pd.DataFrame: + """ +Wrapper for [`rdflib.Graph.query()`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=query#rdflib.Graph.query) to perform a SPARQL query on the RDF graph. + + query: +text for the SPARQL query + + bindings: +initial variable bindings + + simplify: +convert terms in each row of the result set into a readable representation for each term, using N3 format + + pythonify: +convert instances of [`rdflib.term.Literal`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=Literal#rdflib.term.Identifier) to their Python literal representation + + returns: +the query result set represented as a [`pandas.DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html); uses the [RAPIDS `cuDF` library](https://docs.rapids.ai/api/cudf/stable/) if GPUs are enabled + """ + if not bindings: + bindings = {} + + row_iter = self.kg._g.query(query, initBindings=bindings) # pylint: disable=W0212 + + if simplify: + rows_list = [ self.n3fy_row(r.asdict(), pythonify=pythonify) for r in row_iter ] + else: + rows_list = [ r.asdict() for r in row_iter ] + + if self.kg.use_gpus: + df = cudf.DataFrame(rows_list) + else: + df = pd.DataFrame(rows_list) + + return df + + + def n3fy ( + self, + node: RDF_Node, + *, + pythonify: bool = True, + ) -> typing.Any: + """ +Wrapper for RDFlib [`n3()`](https://rdflib.readthedocs.io/en/stable/utilities.html?highlight=n3#serializing-a-single-term-to-n3) and [`toPython()`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=toPython#rdflib.Variable.toPython) to serialize a node into a human-readable representation using N3 format. + + node: +must be a [`rdflib.term.Node`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=Node#rdflib.term.Node) + + pythonify: +flag to force instances of [`rdflib.term.Literal`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=Literal#rdflib.term.Identifier) to their Python literal representation + + returns: +text (or Python objects) for the serialized node + """ + if pythonify and isinstance(node, rdflib.term.Literal): + serialized = node.toPython() + else: + serialized = node.n3(self.kg._g.namespace_manager) # type: ignore # pylint: disable=W0212 + + return serialized + + + def n3fy_row ( + self, + row_dict: dict, + *, + pythonify: bool = True, + ) -> dict: + """ +Wrapper for RDFlib [`n3()`](https://rdflib.readthedocs.io/en/stable/utilities.html?highlight=n3#serializing-a-single-term-to-n3) and [`toPython()`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=toPython#rdflib.Variable.toPython) to serialize one row of a result set from a SPARQL query into a human-readable representation for each term using N3 format. + + row_dict: +one row of a SPARQL query results, as a `dict` + + pythonify: +flag to force instances of [`rdflib.term.Literal`](https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html?highlight=Literal#rdflib.term.Identifier) to their Python literal representation + + returns: +a dictionary of serialized row bindings + """ + bindings = { + k: self.n3fy(v, pythonify=pythonify) + for k, v in row_dict.items() + } + + return bindings + + + @classmethod + def unbind_sparql ( + cls, + query: str, + bindings: dict, + *, + preamble: str = "", + ) -> str: + """ +Substitute the _binding variables_ into the text of a SPARQL query, +to obviate the need for binding variables specified separately. +This can be helpful for debugging, or for some query engines that +may not have full SPARQL support yet. + + query: +text for the SPARQL query + + bindings: +variable bindings + + returns: +a string of the expanded SPARQL query + """ + sparql_meta, sparql_body = re.split(r"\s*WHERE\s*\{", query, maxsplit=1) + + for var in sorted(bindings.keys(), key=lambda x: len(x), reverse=True): # pylint: disable=W0108 + pattern = re.compile("(\?" + var + ")(\W)") # pylint: disable=W1401 + bind_val = "<" + str(bindings[var]) + ">\\2" + sparql_body = re.sub(pattern, bind_val, sparql_body) + + return "".join([preamble, sparql_meta, " WHERE {", sparql_body]).strip() + + + def visualize_query ( + self, + query: str, + *, + notebook: bool = False, + ) -> pyvis.network.Network: + """ +Visualize the given SPARQL query as a [`pyvis.network.Network`](https://pyvis.readthedocs.io/en/latest/documentation.html#pyvis.network.Network) + + query: +input SPARQL query to be visualized + + notebook: +optional boolean flag, whether to initialize the PyVis graph to render within a notebook; defaults to `False` + + returns: +PyVis network object, to be rendered + """ + return GPViz(query, self.kg._ns).visualize_query(notebook=notebook) # pylint: disable=W0212 From 4ea00b1d54cb98af27073e83e3cd76faa11de03e Mon Sep 17 00:00:00 2001 From: Paco Nathan Date: Sun, 27 Mar 2022 19:31:42 -0700 Subject: [PATCH 5/8] WIP refactor KG class #237 --- kglab/query/base.py | 13 +++++++++++++ kglab/query/sparql.py | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/kglab/query/base.py b/kglab/query/base.py index f0448a9..f1db052 100644 --- a/kglab/query/base.py +++ b/kglab/query/base.py @@ -9,6 +9,8 @@ from abc import ABC, abstractmethod import typing +import pandas as pd # type: ignore # pylint: disable=E0401 + class Queryable (ABC): """ @@ -24,3 +26,14 @@ def query ( Abstract method for querying. """ pass # pylint: disable=W0107 + + + @abstractmethod + def query_as_df ( + self, + query: str, + ) -> pd.DataFrame: + """ +Abstract method for querying, which returns a pandas DataFrame. + """ + pass # pylint: disable=W0107 diff --git a/kglab/query/sparql.py b/kglab/query/sparql.py index 211e569..32675e2 100644 --- a/kglab/query/sparql.py +++ b/kglab/query/sparql.py @@ -70,7 +70,7 @@ def query ( # pylint: disable=W0221 yield row - def query_as_df ( + def query_as_df ( # pylint: disable=W0221 self, query: str, *, @@ -199,7 +199,7 @@ def unbind_sparql ( return "".join([preamble, sparql_meta, " WHERE {", sparql_body]).strip() - def visualize_query ( + def visualize ( self, query: str, *, From c5cbf5ce52f9d22507102f2e177a943f75f8c62e Mon Sep 17 00:00:00 2001 From: Paco Nathan Date: Sun, 3 Apr 2022 08:40:54 -0700 Subject: [PATCH 6/8] update docs --- README.md | 43 +++++++++++++++++++++++++------------------ changelog.txt | 6 +++--- docs/ack.md | 1 + kglab/version.py | 2 +- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 4e7fdc7..1b08dac 100644 --- a/README.md +++ b/README.md @@ -158,24 +158,8 @@ For detailed instructions please see: -illustration of a knowledge graph, plus laboratory glassware - - -## License and Copyright - -Source code for **kglab** plus its logo, documentation, and examples -have an [MIT license](https://spdx.org/licenses/MIT.html) which is -succinct and simplifies use in commercial applications. - -All materials herein are Copyright © 2020-2022 Derwen, Inc. - - -## Attribution - +
+ Attribution Please use the following BibTeX entry for citing **kglab** if you use it in your research or software. Citations are helpful for the continued development and maintenance of @@ -191,6 +175,22 @@ this library. url = {https://github.com/DerwenAI/kglab} } ``` +
+ +illustration of a knowledge graph, plus laboratory glassware + + +## License and Copyright + +Source code for **kglab** plus its logo, documentation, and examples +have an [MIT license](https://spdx.org/licenses/MIT.html) which is +succinct and simplifies use in commercial applications. + +All materials herein are Copyright © 2020-2022 Derwen, Inc. ## Kudos @@ -205,6 +205,7 @@ and to our contributors: [@Mec-iS](https://github.com/Mec-iS), [@cutterkom](https://github.com/cutterkom), [@RishiKumarRay](https://github.com/RishiKumarRay), +[@Tpt](https://github.com/Tpt), [@ArenasGuerreroJulian](https://github.com/ArenasGuerreroJulian), [@fils](https://github.com/fils), [@gauravjaglan](https://github.com/gauravjaglan), @@ -222,3 +223,9 @@ the [RAPIDS team @ NVIDIA](https://rapids.ai/), [Gradient Flow](https://gradientflow.com/), and [Manning Publications](https://www.manning.com/). + +kglab contributors + diff --git a/changelog.txt b/changelog.txt index 3abfd4a..eef753f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,10 +1,10 @@ # `kglab` changelog -## 0.6.? +## 0.6.1 -2022-??-?? +2022-04-?? - * ??? + * automated RDF tests, coordinated with `Oxigraph`; kudos @Mec-iS, @Tpt ## 0.6.0 diff --git a/docs/ack.md b/docs/ack.md index e81c904..9f4ee7a 100644 --- a/docs/ack.md +++ b/docs/ack.md @@ -13,6 +13,7 @@ and to our contributors: [@Mec-iS](https://github.com/Mec-iS), [@cutterkom](https://github.com/cutterkom), [@RishiKumarRay](https://github.com/RishiKumarRay), +[@Tpt](https://github.com/Tpt), [@ArenasGuerreroJulian](https://github.com/ArenasGuerreroJulian), [@fils](https://github.com/fils), [@gauravjaglan](https://github.com/gauravjaglan), diff --git a/kglab/version.py b/kglab/version.py index b34c580..0c374e5 100644 --- a/kglab/version.py +++ b/kglab/version.py @@ -11,7 +11,7 @@ MIN_PY_VERSION: typing.Tuple = (3, 7,) -__version__: str = "0.6.0" +__version__: str = "0.6.1" def _versify ( From f5916d1b40cb2cfd595d3a7a3b292cfdb6cefa13 Mon Sep 17 00:00:00 2001 From: Paco Nathan Date: Sun, 3 Apr 2022 08:46:37 -0700 Subject: [PATCH 7/8] update docs --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index eef753f..55a3f96 100644 --- a/changelog.txt +++ b/changelog.txt @@ -5,6 +5,7 @@ 2022-04-?? * automated RDF tests, coordinated with `Oxigraph`; kudos @Mec-iS, @Tpt + * begin refactoring `KnowledgeGraph` as abstract classes, per #237 ## 0.6.0 From 1155a8929b95c8689ec676a09aa7e77f4b9b017b Mon Sep 17 00:00:00 2001 From: Paco Nathan Date: Sun, 3 Apr 2022 08:52:29 -0700 Subject: [PATCH 8/8] update Oxrdflib for namespace support --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a92b2eb..087b06a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ morph-kgc >= 1.6 networkx >= 2.7 numpy >= 1.21 owlrl >= 6.0.2 -oxrdflib >= 0.3 +oxrdflib >= 0.3.1 pandas >= 1.4 pslpython >= 2.2.2 pyarrow >= 7.0