iolanta 2.1.4__tar.gz → 2.1.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {iolanta-2.1.4 → iolanta-2.1.7}/PKG-INFO +6 -3
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/cli/main.py +44 -24
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/data/context.yaml +1 -1
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/data/iolanta.yaml +1 -1
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/data/textual-browser.yaml +1 -7
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/declension/data/declension.yamlld +1 -1
- iolanta-2.1.7/iolanta/facets/locator/sparql/get-query-to-facet.sparql +5 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/locator.py +4 -7
- iolanta-2.1.7/iolanta/facets/mkdocs_material_insiders_markdown/__init__.py +4 -0
- iolanta-2.1.7/iolanta/facets/mkdocs_material_insiders_markdown/data/mkdocs_material_insiders_markdown.yamlld +20 -0
- iolanta-2.1.7/iolanta/facets/mkdocs_material_insiders_markdown/facet.py +86 -0
- iolanta-2.1.7/iolanta/facets/mkdocs_material_insiders_markdown/templates/datatype.jinja2.md +24 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_browser/page_switcher.py +1 -1
- iolanta-2.1.7/iolanta/facets/textual_graphs/__init__.py +6 -0
- iolanta-2.1.7/iolanta/facets/textual_graphs/data/textual_graphs.yamlld +23 -0
- iolanta-2.1.7/iolanta/facets/textual_graphs/facets.py +138 -0
- iolanta-2.1.7/iolanta/facets/textual_graphs/sparql/graphs.sparql +5 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/iolanta.py +4 -3
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/labeled_triple_set/data/labeled_triple_set.yamlld +1 -1
- iolanta-2.1.7/iolanta/mcp/cli.py +39 -0
- iolanta-2.1.7/iolanta/mcp/prompts/nanopublication_assertion_authoring_rules.md +63 -0
- iolanta-2.1.7/iolanta/mcp/prompts/rules.md +83 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/mermaid/facet.py +0 -3
- iolanta-2.1.7/iolanta/mermaid/mermaid.yamlld +25 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/mermaid/models.py +4 -2
- iolanta-2.1.7/iolanta/mermaid/sparql/ask-has-triples.sparql +3 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/models.py +0 -3
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/namespaces.py +2 -2
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/parse_quads.py +2 -2
- iolanta-2.1.7/iolanta/sparqlspace/inference/wikidata-prop-label.sparql +10 -0
- iolanta-2.1.7/iolanta/sparqlspace/inference/wikidata-statement-label.sparql +27 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/sparqlspace/processor.py +80 -78
- iolanta-2.1.7/iolanta/widgets/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/pyproject.toml +8 -4
- iolanta-2.1.4/iolanta/mermaid/mermaid.yamlld +0 -42
- iolanta-2.1.4/iolanta/sparqlspace/inference/wikibase-claim.sparql +0 -9
- iolanta-2.1.4/iolanta/sparqlspace/inference/wikibase-statement-property.sparql +0 -9
- {iolanta-2.1.4 → iolanta-2.1.7}/README.md +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/base_plugin.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/cli/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/cli/formatters/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/cli/formatters/choose.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/cli/formatters/csv.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/cli/formatters/json.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/cli/formatters/pretty.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/cli/models.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/cli/pretty_print.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/context.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/conversions.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/data/graph-triples.yamlld +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/declension/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/declension/facet.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/declension/sparql/declension.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/ensure_is_context.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/entry_points.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/errors.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/cli/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/cli/base.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/cli/default.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/cli/record.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/cli/sparql/link.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/cli/sparql/record.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/errors.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/facet.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/foaf_person_title/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/foaf_person_title/facet.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/foaf_person_title/sparql/names.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/generic/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/generic/bool_literal.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/generic/date_literal.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/generic/default.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/generic/sparql/default.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/html/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/html/base.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/html/code_literal.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/html/default.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/icon.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/page_title.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/qname.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_browser/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_browser/app.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_browser/facet.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_browser/history.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_browser/home.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_browser/location.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_browser/models.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_browser/page.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_class/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_class/facets.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_class/sparql/instances.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_default/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_default/facets.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_default/sparql/inverse-properties.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_default/sparql/label.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_default/sparql/nodes-for-property.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_default/sparql/properties.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_default/tcss/default.tcss +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_default/templates/default.md +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_default/triple_uri_ref.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_default/widgets.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_graph/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_graph/facets.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_graph/sparql/triples.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_graph_triples.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_link/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_link/facet.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_nanopublication/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_nanopublication/facet.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_nanopublication/models.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_nanopublication/nanopublication_widget.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_nanopublication/term_list_widget.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_nanopublication/term_widget.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_no_facet_found.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_ontology/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_ontology/facets.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_ontology/sparql/terms.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_ontology/sparql/visualization-vocab.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_property_pairs_table.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_provenance/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_provenance/facets.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_provenance/sparql/graphs.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/textual_provenance/sparql/triples.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/title/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/title/facets.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/title/sparql/title.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/wikibase_statement_title/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/wikibase_statement_title/facets.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/facets/wikibase_statement_title/sparql/statement-title.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/labeled_triple_set/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/labeled_triple_set/labeled_triple_set.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/labeled_triple_set/sparql/triples.sparql +0 -0
- {iolanta-2.1.4/iolanta/mermaid → iolanta-2.1.7/iolanta/mcp}/__init__.py +0 -0
- {iolanta-2.1.4/iolanta/resolvers → iolanta-2.1.7/iolanta/mermaid}/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/mermaid/sparql/graph.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/mermaid/sparql/subgraphs.sparql +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/node_to_qname.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/plugin.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/query_result.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/reformat_blank_nodes.py +0 -0
- {iolanta-2.1.4/iolanta/sparqlspace → iolanta-2.1.7/iolanta/resolvers}/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/resolvers/base.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/resolvers/dispatch.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/resolvers/pypi.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/resolvers/python_import.py +0 -0
- {iolanta-2.1.4/iolanta/widgets → iolanta-2.1.7/iolanta/sparqlspace}/__init__.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/sparqlspace/cli.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/sparqlspace/sparqlspace.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/widgets/description.py +0 -0
- {iolanta-2.1.4 → iolanta-2.1.7}/iolanta/widgets/mixin.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: iolanta
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.7
|
|
4
4
|
Summary: Semantic Web browser
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Anatoly Scherbakov
|
|
@@ -10,6 +10,7 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
14
|
Provides-Extra: all
|
|
14
15
|
Requires-Dist: boltons (>=24.0.0)
|
|
15
16
|
Requires-Dist: classes (>=0.4.0)
|
|
@@ -17,9 +18,11 @@ Requires-Dist: deepmerge (>=0.1.1)
|
|
|
17
18
|
Requires-Dist: diskcache (>=5.6.3)
|
|
18
19
|
Requires-Dist: documented (>=0.1.1)
|
|
19
20
|
Requires-Dist: dominate (>=2.6.0)
|
|
21
|
+
Requires-Dist: fastmcp (>=2.12.4,<3.0.0)
|
|
20
22
|
Requires-Dist: funcy (>=2.0)
|
|
21
23
|
Requires-Dist: loguru (>=0.7.3)
|
|
22
24
|
Requires-Dist: more-itertools (>=9.0.0)
|
|
25
|
+
Requires-Dist: nanopub (>=2.1.0,<3.0.0)
|
|
23
26
|
Requires-Dist: owlrl (>=6.0.2)
|
|
24
27
|
Requires-Dist: oxrdflib (>=0.4.0)
|
|
25
28
|
Requires-Dist: packageurl-python (>=0.17.5)
|
|
@@ -31,7 +34,7 @@ Requires-Dist: rich (>=13.3.1)
|
|
|
31
34
|
Requires-Dist: textual (>=0.83.0)
|
|
32
35
|
Requires-Dist: typer (>=0.9.0)
|
|
33
36
|
Requires-Dist: watchfiles (>=1.0.4)
|
|
34
|
-
Requires-Dist: yaml-ld (>=1.1.
|
|
37
|
+
Requires-Dist: yaml-ld (>=1.1.15)
|
|
35
38
|
Requires-Dist: yarl (>=1.9.4)
|
|
36
39
|
Description-Content-Type: text/markdown
|
|
37
40
|
|
|
@@ -11,7 +11,7 @@ from rdflib import Literal, URIRef
|
|
|
11
11
|
from rich.console import Console
|
|
12
12
|
from rich.markdown import Markdown
|
|
13
13
|
from rich.table import Table
|
|
14
|
-
from typer import Argument, Exit, Option, Typer
|
|
14
|
+
from typer import Argument, Exit, Option, Typer, Context
|
|
15
15
|
from yarl import URL
|
|
16
16
|
|
|
17
17
|
from iolanta.cli.models import LogLevel
|
|
@@ -24,9 +24,7 @@ DEFAULT_LANGUAGE = locale.getlocale()[0].split('_')[0]
|
|
|
24
24
|
console = Console()
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
app = Typer(
|
|
28
|
-
no_args_is_help=True,
|
|
29
|
-
)
|
|
27
|
+
app = Typer(no_args_is_help=True)
|
|
30
28
|
|
|
31
29
|
|
|
32
30
|
def string_to_node(name: str) -> NotLiteralNode:
|
|
@@ -52,19 +50,10 @@ def decode_datatype(datatype: str) -> URIRef:
|
|
|
52
50
|
return URIRef(f'https://iolanta.tech/datatypes/{datatype}')
|
|
53
51
|
|
|
54
52
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
str, Option(
|
|
60
|
-
'--as',
|
|
61
|
-
),
|
|
62
|
-
] = 'https://iolanta.tech/cli/interactive',
|
|
63
|
-
language: Annotated[
|
|
64
|
-
str, Option(
|
|
65
|
-
help='Data language to prefer.',
|
|
66
|
-
),
|
|
67
|
-
] = DEFAULT_LANGUAGE,
|
|
53
|
+
def render_and_return(
|
|
54
|
+
url: str,
|
|
55
|
+
as_datatype: str,
|
|
56
|
+
language: str = DEFAULT_LANGUAGE,
|
|
68
57
|
log_level: LogLevel = LogLevel.ERROR,
|
|
69
58
|
):
|
|
70
59
|
"""Render a given URL."""
|
|
@@ -124,13 +113,38 @@ def render_command( # noqa: WPS231, WPS238, WPS210, C901
|
|
|
124
113
|
project_root=path,
|
|
125
114
|
)
|
|
126
115
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
116
|
+
return iolanta.render(
|
|
117
|
+
node=URIRef(node),
|
|
118
|
+
as_datatype=decode_datatype(as_datatype),
|
|
119
|
+
)
|
|
120
|
+
|
|
132
121
|
|
|
122
|
+
@app.command(name='render')
|
|
123
|
+
def render_command( # noqa: WPS231, WPS238, WPS210, C901
|
|
124
|
+
url: Annotated[str, Argument()],
|
|
125
|
+
as_datatype: Annotated[
|
|
126
|
+
str, Option(
|
|
127
|
+
'--as',
|
|
128
|
+
),
|
|
129
|
+
] = 'https://iolanta.tech/cli/interactive',
|
|
130
|
+
language: Annotated[
|
|
131
|
+
str, Option(
|
|
132
|
+
help='Data language to prefer.',
|
|
133
|
+
),
|
|
134
|
+
] = DEFAULT_LANGUAGE,
|
|
135
|
+
log_level: LogLevel = LogLevel.ERROR,
|
|
136
|
+
):
|
|
137
|
+
"""Render a given URL."""
|
|
138
|
+
try:
|
|
139
|
+
renderable = render_and_return(url, as_datatype, language, log_level)
|
|
133
140
|
except DocumentedError as documented_error:
|
|
141
|
+
level = {
|
|
142
|
+
LogLevel.DEBUG: logging.DEBUG,
|
|
143
|
+
LogLevel.INFO: logging.INFO,
|
|
144
|
+
LogLevel.WARNING: logging.WARNING,
|
|
145
|
+
LogLevel.ERROR: logging.ERROR,
|
|
146
|
+
}[log_level]
|
|
147
|
+
|
|
134
148
|
if level in {logging.DEBUG, logging.INFO}:
|
|
135
149
|
raise
|
|
136
150
|
|
|
@@ -143,12 +157,18 @@ def render_command( # noqa: WPS231, WPS238, WPS210, C901
|
|
|
143
157
|
raise Exit(1)
|
|
144
158
|
|
|
145
159
|
except Exception as err:
|
|
146
|
-
|
|
160
|
+
level = {
|
|
161
|
+
LogLevel.DEBUG: logging.DEBUG,
|
|
162
|
+
LogLevel.INFO: logging.INFO,
|
|
163
|
+
LogLevel.WARNING: logging.WARNING,
|
|
164
|
+
LogLevel.ERROR: logging.ERROR,
|
|
165
|
+
}[log_level]
|
|
166
|
+
|
|
167
|
+
if level in {logging.DEBUG, logging.INFO}:
|
|
147
168
|
raise
|
|
148
169
|
|
|
149
170
|
console.print(str(err))
|
|
150
171
|
raise Exit(1)
|
|
151
|
-
|
|
152
172
|
else:
|
|
153
173
|
# FIXME: An intermediary Literal can be used to dispatch rendering.
|
|
154
174
|
match renderable:
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
foaf: https://xmlns.com/foaf/0.1/
|
|
5
5
|
owl: https://www.w3.org/2002/07/owl#
|
|
6
6
|
iolanta: https://iolanta.tech/
|
|
7
|
-
rdfs: "
|
|
7
|
+
rdfs: "http://www.w3.org/2000/01/rdf-schema#"
|
|
8
8
|
rdf: https://www.w3.org/1999/02/22-rdf-syntax-ns#
|
|
9
9
|
|
|
10
10
|
$included:
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
foaf: https://xmlns.com/foaf/0.1/
|
|
5
5
|
owl: https://www.w3.org/2002/07/owl#
|
|
6
6
|
iolanta: https://iolanta.tech/
|
|
7
|
-
rdfs: "
|
|
7
|
+
rdfs: "http://www.w3.org/2000/01/rdf-schema#"
|
|
8
8
|
rdf: https://www.w3.org/1999/02/22-rdf-syntax-ns#
|
|
9
9
|
np: https://www.nanopub.org/nschema#
|
|
10
10
|
dcterms: https://purl.org/dc/terms/
|
|
@@ -88,12 +88,6 @@
|
|
|
88
88
|
iolanta:hasDefaultFacet:
|
|
89
89
|
$id: pkg:pypi/iolanta#textual-link
|
|
90
90
|
|
|
91
|
-
- $id: https://wikiba.se/ontology#Statement
|
|
92
|
-
iolanta:hasInstanceFacet:
|
|
93
|
-
$id: pkg:pypi/iolanta#wikibase-statement-title
|
|
94
|
-
$: Title
|
|
95
|
-
→: https://iolanta.tech/datatypes/title
|
|
96
|
-
|
|
97
91
|
- $id: rdfs:Class
|
|
98
92
|
iolanta:hasInstanceFacet:
|
|
99
93
|
$id: pkg:pypi/iolanta#textual-class
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
foaf: https://xmlns.com/foaf/0.1/
|
|
5
5
|
owl: https://www.w3.org/2002/07/owl#
|
|
6
6
|
iolanta: https://iolanta.tech/
|
|
7
|
-
rdfs: "
|
|
7
|
+
rdfs: "http://www.w3.org/2000/01/rdf-schema#"
|
|
8
8
|
rdf: https://www.w3.org/1999/02/22-rdf-syntax-ns#
|
|
9
9
|
dcterms: https://purl.org/dc/terms/
|
|
10
10
|
dcam: https://purl.org/dc/dcam/
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from functools import cached_property
|
|
3
3
|
from graphlib import TopologicalSorter
|
|
4
|
+
from pathlib import Path
|
|
4
5
|
from typing import Iterable, List, TypedDict
|
|
5
6
|
|
|
6
7
|
import funcy
|
|
@@ -18,13 +19,9 @@ class FoundRow(TypedDict):
|
|
|
18
19
|
output_datatype: NotLiteralNode
|
|
19
20
|
|
|
20
21
|
|
|
21
|
-
GET_QUERY_TO_FACET =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
iolanta:matches ?match ;
|
|
25
|
-
iolanta:outputs $as_datatype .
|
|
26
|
-
}
|
|
27
|
-
"""
|
|
22
|
+
GET_QUERY_TO_FACET = (
|
|
23
|
+
Path(__file__).parent / 'locator' / 'sparql' / 'get-query-to-facet.sparql'
|
|
24
|
+
).read_text()
|
|
28
25
|
|
|
29
26
|
|
|
30
27
|
def reorder_rows_by_facet_preferences( # noqa: WPS214, WPS210
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"@context":
|
|
2
|
+
"@import": https://json-ld.org/contexts/dollar-convenience.jsonld
|
|
3
|
+
rdfs: "http://www.w3.org/2000/01/rdf-schema#"
|
|
4
|
+
rdf: https://www.w3.org/1999/02/22-rdf-syntax-ns#
|
|
5
|
+
iolanta: https://iolanta.tech/
|
|
6
|
+
|
|
7
|
+
$: rdfs:label
|
|
8
|
+
|
|
9
|
+
→:
|
|
10
|
+
"@type": "@id"
|
|
11
|
+
"@id": iolanta:outputs
|
|
12
|
+
|
|
13
|
+
↦: iolanta:matches
|
|
14
|
+
|
|
15
|
+
$id: pkg:pypi/iolanta#mkdocs-material-insiders-markdown-datatype
|
|
16
|
+
$: OutputDatatype (mkdocs-material-insiders-markdown)
|
|
17
|
+
|
|
18
|
+
→: https://iolanta.tech/datatypes/mkdocs-material-insiders-markdown
|
|
19
|
+
|
|
20
|
+
↦: ASK WHERE { $this a iolanta:OutputDatatype }
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from jinja2 import Environment, FileSystemLoader
|
|
4
|
+
from rdflib import URIRef
|
|
5
|
+
|
|
6
|
+
from iolanta.facets.facet import Facet
|
|
7
|
+
from iolanta.namespaces import DATATYPES, IOLANTA, RDF, RDFS
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MkDocsMaterialInsidersMarkdownFacet(Facet[str]):
|
|
11
|
+
"""Render rdfs:Datatype nodes as mkdocs-material-insiders-markdown."""
|
|
12
|
+
|
|
13
|
+
META = Path(__file__).parent / 'data' / 'mkdocs_material_insiders_markdown.yamlld'
|
|
14
|
+
"""Render rdfs:Datatype nodes as mkdocs-material-insiders-markdown."""
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def _template_env(self) -> Environment:
|
|
18
|
+
"""Jinja2 template environment."""
|
|
19
|
+
template_path = Path(__file__).parent / 'templates'
|
|
20
|
+
return Environment(
|
|
21
|
+
loader=FileSystemLoader(str(template_path)),
|
|
22
|
+
autoescape=False,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
def show(self) -> str:
|
|
26
|
+
"""Render the datatype as markdown."""
|
|
27
|
+
# Get the label using title facet
|
|
28
|
+
label = self.render(
|
|
29
|
+
self.this,
|
|
30
|
+
as_datatype=DATATYPES.title,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# Get the comment/description
|
|
34
|
+
comment_rows = self.query(
|
|
35
|
+
"""
|
|
36
|
+
SELECT ?comment WHERE {
|
|
37
|
+
$this rdfs:comment ?comment .
|
|
38
|
+
}
|
|
39
|
+
LIMIT 1
|
|
40
|
+
""",
|
|
41
|
+
this=self.this,
|
|
42
|
+
)
|
|
43
|
+
comment = str(comment_rows[0]['comment']) if comment_rows else None
|
|
44
|
+
|
|
45
|
+
# Get all types (rdf:type)
|
|
46
|
+
type_rows = self.query(
|
|
47
|
+
"""
|
|
48
|
+
SELECT ?type WHERE {
|
|
49
|
+
$this rdf:type ?type .
|
|
50
|
+
}
|
|
51
|
+
""",
|
|
52
|
+
this=self.this,
|
|
53
|
+
)
|
|
54
|
+
types = [
|
|
55
|
+
{
|
|
56
|
+
'uri': row['type'],
|
|
57
|
+
'title': self.render(row['type'], as_datatype=DATATYPES.title),
|
|
58
|
+
}
|
|
59
|
+
for row in type_rows
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
# Get all superclasses (rdfs:subClassOf)
|
|
63
|
+
superclass_rows = self.query(
|
|
64
|
+
"""
|
|
65
|
+
SELECT ?superclass WHERE {
|
|
66
|
+
$this rdfs:subClassOf ?superclass .
|
|
67
|
+
}
|
|
68
|
+
""",
|
|
69
|
+
this=self.this,
|
|
70
|
+
)
|
|
71
|
+
superclasses = [
|
|
72
|
+
{
|
|
73
|
+
'uri': row['superclass'],
|
|
74
|
+
'title': self.render(row['superclass'], as_datatype=DATATYPES.title),
|
|
75
|
+
}
|
|
76
|
+
for row in superclass_rows
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
template = self._template_env.get_template('datatype.jinja2.md')
|
|
80
|
+
return template.render(
|
|
81
|
+
label=label,
|
|
82
|
+
comment=comment,
|
|
83
|
+
types=types,
|
|
84
|
+
superclasses=superclasses,
|
|
85
|
+
)
|
|
86
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# {{ label }}
|
|
2
|
+
|
|
3
|
+
<table>
|
|
4
|
+
<thead>
|
|
5
|
+
</thead>
|
|
6
|
+
<tbody>
|
|
7
|
+
{% if types %}
|
|
8
|
+
<tr>
|
|
9
|
+
<td>∈ Instance Of</td>
|
|
10
|
+
<td>{% for type in types %}<code><a href="{{ type.uri }}">{{ type.title }}</a></code>{% if not loop.last %}, {% endif %}{% endfor %}</td>
|
|
11
|
+
</tr>
|
|
12
|
+
{% endif %}
|
|
13
|
+
{% if superclasses %}
|
|
14
|
+
<tr>
|
|
15
|
+
<td>⊊ Subclass Of</td>
|
|
16
|
+
<td>{% for superclass in superclasses %}<code><a href="{{ superclass.uri }}">{{ superclass.title }}</a></code>{% if not loop.last %}, {% endif %}{% endfor %}</td>
|
|
17
|
+
</tr>
|
|
18
|
+
{% endif %}
|
|
19
|
+
</tbody>
|
|
20
|
+
</table>
|
|
21
|
+
|
|
22
|
+
{% if comment %}
|
|
23
|
+
{{ comment | safe }}
|
|
24
|
+
{% endif %}
|
|
@@ -323,7 +323,7 @@ class DevConsole(RichLog):
|
|
|
323
323
|
|
|
324
324
|
def __init__(self):
|
|
325
325
|
"""Set default props for console."""
|
|
326
|
-
super().__init__(highlight=
|
|
326
|
+
super().__init__(highlight=False, markup=False, id='console')
|
|
327
327
|
|
|
328
328
|
def action_close(self):
|
|
329
329
|
"""Close the dev console."""
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"@context":
|
|
2
|
+
"@import": https://json-ld.org/contexts/dollar-convenience.jsonld
|
|
3
|
+
iolanta: https://iolanta.tech/
|
|
4
|
+
rdfs: http://www.w3.org/2000/01/rdf-schema#
|
|
5
|
+
rdfg: http://www.w3.org/2009/rdfg#
|
|
6
|
+
|
|
7
|
+
$: rdfs:label
|
|
8
|
+
iolanta:is-preferred-over:
|
|
9
|
+
"@type": "@id"
|
|
10
|
+
|
|
11
|
+
iolanta:outputs:
|
|
12
|
+
"@type": "@id"
|
|
13
|
+
|
|
14
|
+
$id: rdfg:Graph
|
|
15
|
+
iolanta:facet:
|
|
16
|
+
$id: pkg:pypi/iolanta#textual-graphs
|
|
17
|
+
$: Named Graphs
|
|
18
|
+
|
|
19
|
+
iolanta:outputs: https://iolanta.tech/cli/textual
|
|
20
|
+
|
|
21
|
+
iolanta:is-preferred-over:
|
|
22
|
+
- pkg:pypi/iolanta#textual-properties
|
|
23
|
+
- pkg:pypi/iolanta#textual-graph-triples
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
from collections import defaultdict
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Iterable, NamedTuple
|
|
4
|
+
|
|
5
|
+
import funcy
|
|
6
|
+
from rdflib import Literal, Node
|
|
7
|
+
from textual.containers import Vertical
|
|
8
|
+
from textual.coordinate import Coordinate
|
|
9
|
+
from textual.widgets import DataTable
|
|
10
|
+
|
|
11
|
+
from iolanta.facets.facet import Facet
|
|
12
|
+
from iolanta.facets.page_title import PageTitle
|
|
13
|
+
from iolanta.models import NotLiteralNode
|
|
14
|
+
from iolanta.namespaces import DATATYPES
|
|
15
|
+
from iolanta.widgets.mixin import IolantaWidgetMixin
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class GraphRow(NamedTuple):
|
|
19
|
+
"""A row in the graphs table."""
|
|
20
|
+
|
|
21
|
+
graph: NotLiteralNode
|
|
22
|
+
count: int
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class GraphsTable(IolantaWidgetMixin, DataTable):
|
|
26
|
+
"""Render graphs as a table with graph URI and triple count."""
|
|
27
|
+
|
|
28
|
+
BINDINGS = [
|
|
29
|
+
('enter', 'goto', 'Goto'),
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
def __init__(self, rows: Iterable[GraphRow]):
|
|
33
|
+
"""Construct."""
|
|
34
|
+
super().__init__(show_header=True, cell_padding=1)
|
|
35
|
+
self.graph_rows = list(rows)
|
|
36
|
+
|
|
37
|
+
def render_human_readable_cells(self):
|
|
38
|
+
"""Replace the cells with their human readable titles."""
|
|
39
|
+
terms_and_coordinates = sorted(
|
|
40
|
+
self.node_to_coordinates.items(),
|
|
41
|
+
key=lambda node_and_coordinates_pair: len(
|
|
42
|
+
node_and_coordinates_pair[1],
|
|
43
|
+
),
|
|
44
|
+
reverse=True,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
for term, coordinates in terms_and_coordinates:
|
|
48
|
+
title = str(self.iolanta.render(term, as_datatype=DATATYPES.title))
|
|
49
|
+
for coordinate in coordinates:
|
|
50
|
+
self.app.call_from_thread(
|
|
51
|
+
self.update_cell_at,
|
|
52
|
+
coordinate,
|
|
53
|
+
value=title,
|
|
54
|
+
update_width=False,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
@funcy.cached_property
|
|
58
|
+
@funcy.post_processing(dict)
|
|
59
|
+
def coordinate_to_node(self):
|
|
60
|
+
"""Return a mapping of coordinates to their corresponding nodes."""
|
|
61
|
+
for row_number, (graph, _count) in enumerate(self.graph_rows):
|
|
62
|
+
yield Coordinate(row_number, 0), graph
|
|
63
|
+
|
|
64
|
+
@funcy.cached_property
|
|
65
|
+
def node_to_coordinates(self) -> defaultdict[Node, list[Coordinate]]:
|
|
66
|
+
"""Map node to coordinates where it appears."""
|
|
67
|
+
node_to_coordinate = [
|
|
68
|
+
(node, coordinate)
|
|
69
|
+
for coordinate, node in self.coordinate_to_node.items()
|
|
70
|
+
]
|
|
71
|
+
return funcy.group_values(node_to_coordinate)
|
|
72
|
+
|
|
73
|
+
def format_as_loading(self, node: Node) -> str:
|
|
74
|
+
"""Intermediate version of a value while it is loading."""
|
|
75
|
+
if isinstance(node, Literal):
|
|
76
|
+
node_text = f'⌛ {node}'
|
|
77
|
+
else:
|
|
78
|
+
node_text = self.iolanta.node_as_qname(node)
|
|
79
|
+
node_text = f'⌛ {node_text}'
|
|
80
|
+
|
|
81
|
+
return node_text
|
|
82
|
+
|
|
83
|
+
def on_mount(self):
|
|
84
|
+
"""Fill the table and start rendering."""
|
|
85
|
+
self.add_columns('Graph', 'Triples Count')
|
|
86
|
+
self.cell_padding = 1
|
|
87
|
+
|
|
88
|
+
for graph, count in self.graph_rows:
|
|
89
|
+
self.add_row(
|
|
90
|
+
self.format_as_loading(graph),
|
|
91
|
+
str(count),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
self.run_worker(
|
|
95
|
+
self.render_human_readable_cells,
|
|
96
|
+
thread=True,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
def action_goto(self):
|
|
100
|
+
"""Navigate to the selected graph."""
|
|
101
|
+
if self.cursor_coordinate:
|
|
102
|
+
node = self.coordinate_to_node.get(self.cursor_coordinate)
|
|
103
|
+
if node is not None:
|
|
104
|
+
self.app.action_goto(node)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class GraphsBody(Vertical):
|
|
108
|
+
"""Container for graphs table."""
|
|
109
|
+
|
|
110
|
+
DEFAULT_CSS = """
|
|
111
|
+
GraphsBody {
|
|
112
|
+
height: auto;
|
|
113
|
+
max-height: 100%;
|
|
114
|
+
}
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class Graphs(Facet):
|
|
119
|
+
"""Render named graphs as a table."""
|
|
120
|
+
|
|
121
|
+
META = Path(__file__).parent / 'data' / 'textual_graphs.yamlld'
|
|
122
|
+
|
|
123
|
+
def show(self):
|
|
124
|
+
"""Construct the table."""
|
|
125
|
+
rows = self.stored_query('graphs.sparql')
|
|
126
|
+
|
|
127
|
+
return GraphsBody(
|
|
128
|
+
PageTitle(self.this),
|
|
129
|
+
GraphsTable(
|
|
130
|
+
[
|
|
131
|
+
GraphRow(
|
|
132
|
+
graph=row['graph'],
|
|
133
|
+
count=int(row['count'].value),
|
|
134
|
+
)
|
|
135
|
+
for row in rows
|
|
136
|
+
],
|
|
137
|
+
),
|
|
138
|
+
)
|
|
@@ -119,7 +119,7 @@ class Iolanta: # noqa: WPS214
|
|
|
119
119
|
processor='sparqlspace',
|
|
120
120
|
initBindings=kwargs,
|
|
121
121
|
)
|
|
122
|
-
except
|
|
122
|
+
except SyntaxError as err:
|
|
123
123
|
raise SPARQLParseException(
|
|
124
124
|
error=err,
|
|
125
125
|
query=query_text,
|
|
@@ -171,8 +171,9 @@ class Iolanta: # noqa: WPS214
|
|
|
171
171
|
self.logger.error(f'{source} | {parser_not_found}')
|
|
172
172
|
continue
|
|
173
173
|
except YAMLLDError as yaml_ld_error:
|
|
174
|
-
|
|
175
|
-
|
|
174
|
+
# .add() only processes local files, so errors should be raised
|
|
175
|
+
self.logger.error(f'{source_file} | {yaml_ld_error}')
|
|
176
|
+
raise
|
|
176
177
|
except ValueError as value_error:
|
|
177
178
|
self.logger.error(f'{source} | {value_error}')
|
|
178
179
|
continue
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
foaf: https://xmlns.com/foaf/0.1/
|
|
5
5
|
owl: https://www.w3.org/2002/07/owl#
|
|
6
6
|
iolanta: https://iolanta.tech/
|
|
7
|
-
rdfs: "
|
|
7
|
+
rdfs: "http://www.w3.org/2000/01/rdf-schema#"
|
|
8
8
|
rdf: https://www.w3.org/1999/02/22-rdf-syntax-ns#
|
|
9
9
|
dcterms: https://purl.org/dc/terms/
|
|
10
10
|
dcam: https://purl.org/dc/dcam/
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from typing import Annotated
|
|
2
|
+
from fastmcp import FastMCP
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from iolanta.cli.main import render_and_return
|
|
6
|
+
|
|
7
|
+
mcp = FastMCP("Iolanta MCP Server")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@mcp.tool()
|
|
11
|
+
def render_uri(
|
|
12
|
+
uri: Annotated[str, 'URL, or file system path, to render'],
|
|
13
|
+
as_format: Annotated[str, 'Format to render as. Examples: `labeled-triple-set`, `mermaid`']
|
|
14
|
+
) -> str:
|
|
15
|
+
"""Render a URI."""
|
|
16
|
+
result = render_and_return(uri, as_format)
|
|
17
|
+
return str(result)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@mcp.prompt(description="How to author Linked Data with Iolanta")
|
|
21
|
+
def ld_authoring_rules() -> str:
|
|
22
|
+
"""How to author Linked Data with Iolanta."""
|
|
23
|
+
rules_path = Path(__file__).parent / 'prompts' / 'rules.md'
|
|
24
|
+
return rules_path.read_text()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@mcp.prompt(description="How to author nanopublication assertions with Iolanta")
|
|
28
|
+
def nanopublication_assertion_authoring_rules() -> str:
|
|
29
|
+
"""How to author nanopublication assertions with Iolanta."""
|
|
30
|
+
rules_path = Path(__file__).parent / 'prompts' / 'nanopublication_assertion_authoring_rules.md'
|
|
31
|
+
return rules_path.read_text()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def app():
|
|
35
|
+
mcp.run()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if __name__ == "__main__":
|
|
39
|
+
app()
|