trustgraph-cli 2.1.10__tar.gz → 2.1.12__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.
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/PKG-INFO +1 -1
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/pyproject.toml +1 -0
- trustgraph_cli-2.1.12/trustgraph/cli/query_graph.py +595 -0
- trustgraph_cli-2.1.12/trustgraph/cli_version.py +1 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph_cli.egg-info/PKG-INFO +1 -1
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph_cli.egg-info/SOURCES.txt +1 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph_cli.egg-info/entry_points.txt +1 -0
- trustgraph_cli-2.1.10/trustgraph/cli_version.py +0 -1
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/README.md +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/setup.cfg +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/__init__.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/add_library_document.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/delete_collection.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/delete_config_item.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/delete_flow_blueprint.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/delete_kg_core.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/delete_mcp_tool.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/delete_tool.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/dump_msgpack.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/dump_queues.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/get_config_item.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/get_document_content.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/get_flow_blueprint.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/get_kg_core.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/graph_to_turtle.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/init_pulsar_manager.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/init_trustgraph.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/invoke_agent.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/invoke_document_embeddings.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/invoke_document_rag.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/invoke_embeddings.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/invoke_graph_embeddings.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/invoke_graph_rag.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/invoke_llm.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/invoke_mcp_tool.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/invoke_nlp_query.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/invoke_prompt.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/invoke_row_embeddings.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/invoke_rows_query.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/invoke_structured_query.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/list_collections.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/list_config_items.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/load_doc_embeds.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/load_kg_core.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/load_knowledge.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/load_sample_documents.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/load_structured_data.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/load_turtle.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/put_config_item.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/put_flow_blueprint.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/put_kg_core.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/remove_library_document.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/save_doc_embeds.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/set_collection.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/set_mcp_tool.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/set_prompt.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/set_token_costs.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/set_tool.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/show_config.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/show_flow_blueprints.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/show_flow_state.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/show_flows.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/show_graph.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/show_kg_cores.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/show_library_documents.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/show_library_processing.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/show_mcp_tools.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/show_parameter_types.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/show_processor_state.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/show_prompts.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/show_token_costs.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/show_token_rate.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/show_tools.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/start_flow.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/start_library_processing.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/stop_flow.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/stop_library_processing.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/unload_kg_core.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/verify_system_status.py +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph_cli.egg-info/dependency_links.txt +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph_cli.egg-info/requires.txt +0 -0
- {trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: trustgraph-cli
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.12
|
|
4
4
|
Summary: TrustGraph provides a means to run a pipeline of flexible AI processing components in a flexible means to achieve a processing pipeline.
|
|
5
5
|
Author-email: "trustgraph.ai" <security@trustgraph.ai>
|
|
6
6
|
Project-URL: Homepage, https://github.com/trustgraph-ai/trustgraph
|
|
@@ -71,6 +71,7 @@ tg-show-config = "trustgraph.cli.show_config:main"
|
|
|
71
71
|
tg-show-flow-blueprints = "trustgraph.cli.show_flow_blueprints:main"
|
|
72
72
|
tg-show-flow-state = "trustgraph.cli.show_flow_state:main"
|
|
73
73
|
tg-show-flows = "trustgraph.cli.show_flows:main"
|
|
74
|
+
tg-query-graph = "trustgraph.cli.query_graph:main"
|
|
74
75
|
tg-show-graph = "trustgraph.cli.show_graph:main"
|
|
75
76
|
tg-show-kg-cores = "trustgraph.cli.show_kg_cores:main"
|
|
76
77
|
tg-show-library-documents = "trustgraph.cli.show_library_documents:main"
|
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Query the triple store with pattern matching and configurable output formats.
|
|
3
|
+
|
|
4
|
+
Unlike tg-show-graph which dumps the entire graph, this tool enables selective
|
|
5
|
+
queries by specifying any combination of subject, predicate, object, and graph.
|
|
6
|
+
|
|
7
|
+
Auto-detection rules for values:
|
|
8
|
+
- Starts with http://, https://, urn:, or wrapped in <> -> IRI
|
|
9
|
+
- Starts with << -> quoted triple (Turtle-style)
|
|
10
|
+
- Anything else -> literal
|
|
11
|
+
|
|
12
|
+
Examples:
|
|
13
|
+
tg-query-graph -s "http://example.org/entity"
|
|
14
|
+
tg-query-graph -p "http://www.w3.org/2000/01/rdf-schema#label"
|
|
15
|
+
tg-query-graph -o "Marie Curie" --object-language en
|
|
16
|
+
tg-query-graph -o "<<http://ex.org/s http://ex.org/p http://ex.org/o>>"
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import argparse
|
|
20
|
+
import json
|
|
21
|
+
import os
|
|
22
|
+
import sys
|
|
23
|
+
from trustgraph.api import Api
|
|
24
|
+
|
|
25
|
+
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
|
26
|
+
default_user = 'trustgraph'
|
|
27
|
+
default_collection = 'default'
|
|
28
|
+
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def parse_inline_quoted_triple(value):
|
|
32
|
+
"""Parse inline Turtle-style quoted triple: <<s p o>>
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
value: String in format "<<subject predicate object>>"
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
dict: Wire-format quoted triple term, or None if parsing fails
|
|
39
|
+
"""
|
|
40
|
+
# Strip << and >> markers
|
|
41
|
+
inner = value[2:-2].strip()
|
|
42
|
+
|
|
43
|
+
# Split on whitespace, but respect quoted strings
|
|
44
|
+
# Simple approach: split and handle common cases
|
|
45
|
+
parts = []
|
|
46
|
+
current = ""
|
|
47
|
+
in_quotes = False
|
|
48
|
+
quote_char = None
|
|
49
|
+
|
|
50
|
+
for char in inner:
|
|
51
|
+
if char in ('"', "'") and not in_quotes:
|
|
52
|
+
in_quotes = True
|
|
53
|
+
quote_char = char
|
|
54
|
+
current += char
|
|
55
|
+
elif char == quote_char and in_quotes:
|
|
56
|
+
in_quotes = False
|
|
57
|
+
quote_char = None
|
|
58
|
+
current += char
|
|
59
|
+
elif char.isspace() and not in_quotes:
|
|
60
|
+
if current:
|
|
61
|
+
parts.append(current)
|
|
62
|
+
current = ""
|
|
63
|
+
else:
|
|
64
|
+
current += char
|
|
65
|
+
|
|
66
|
+
if current:
|
|
67
|
+
parts.append(current)
|
|
68
|
+
|
|
69
|
+
if len(parts) != 3:
|
|
70
|
+
raise ValueError(
|
|
71
|
+
f"Quoted triple must have exactly 3 parts (s p o), got {len(parts)}: {parts}"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
s_val, p_val, o_val = parts
|
|
75
|
+
|
|
76
|
+
# Build the inner triple terms
|
|
77
|
+
s_term = build_term(s_val)
|
|
78
|
+
p_term = build_term(p_val)
|
|
79
|
+
o_term = build_term(o_val)
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
"t": "t",
|
|
83
|
+
"tr": {
|
|
84
|
+
"s": s_term,
|
|
85
|
+
"p": p_term,
|
|
86
|
+
"o": o_term
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def build_term(value, term_type=None, datatype=None, language=None):
|
|
92
|
+
"""Build wire-format Term dict from CLI input.
|
|
93
|
+
|
|
94
|
+
Auto-detection rules (when term_type is None):
|
|
95
|
+
- Starts with http://, https://, urn: -> IRI
|
|
96
|
+
- Wrapped in <> (e.g., <http://...>) -> IRI (angle brackets stripped)
|
|
97
|
+
- Starts with << and ends with >> -> quoted triple
|
|
98
|
+
- Anything else -> literal
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
value: The term value
|
|
102
|
+
term_type: One of 'iri', 'literal', 'triple', or None for auto-detect
|
|
103
|
+
datatype: Datatype for literal objects (e.g., xsd:integer)
|
|
104
|
+
language: Language tag for literal objects (e.g., en)
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
dict: Wire-format Term dict, or None if value is None
|
|
108
|
+
"""
|
|
109
|
+
if value is None:
|
|
110
|
+
return None
|
|
111
|
+
|
|
112
|
+
# Auto-detect type if not specified
|
|
113
|
+
if term_type is None:
|
|
114
|
+
if value.startswith("<<") and value.endswith(">>"):
|
|
115
|
+
term_type = "triple"
|
|
116
|
+
elif value.startswith("<") and value.endswith(">") and not value.startswith("<<"):
|
|
117
|
+
# Angle-bracket wrapped IRI: <http://...>
|
|
118
|
+
value = value[1:-1] # Strip < and >
|
|
119
|
+
term_type = "iri"
|
|
120
|
+
elif value.startswith(("http://", "https://", "urn:")):
|
|
121
|
+
term_type = "iri"
|
|
122
|
+
else:
|
|
123
|
+
term_type = "literal"
|
|
124
|
+
|
|
125
|
+
if term_type == "iri":
|
|
126
|
+
# Strip angle brackets if present
|
|
127
|
+
if value.startswith("<") and value.endswith(">"):
|
|
128
|
+
value = value[1:-1]
|
|
129
|
+
return {"t": "i", "i": value}
|
|
130
|
+
elif term_type == "literal":
|
|
131
|
+
result = {"t": "l", "v": value}
|
|
132
|
+
if datatype:
|
|
133
|
+
result["dt"] = datatype
|
|
134
|
+
if language:
|
|
135
|
+
result["ln"] = language
|
|
136
|
+
return result
|
|
137
|
+
elif term_type == "triple":
|
|
138
|
+
# Check if it's inline Turtle-style
|
|
139
|
+
if value.startswith("<<") and value.endswith(">>"):
|
|
140
|
+
return parse_inline_quoted_triple(value)
|
|
141
|
+
else:
|
|
142
|
+
# Assume it's raw JSON (legacy support)
|
|
143
|
+
triple_data = json.loads(value)
|
|
144
|
+
return {"t": "t", "tr": triple_data}
|
|
145
|
+
else:
|
|
146
|
+
raise ValueError(f"Unknown term type: {term_type}")
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def build_quoted_triple_term(qt_subject, qt_subject_type,
|
|
150
|
+
qt_predicate,
|
|
151
|
+
qt_object, qt_object_type,
|
|
152
|
+
qt_object_datatype, qt_object_language):
|
|
153
|
+
"""Build a quoted triple term from --qt-* arguments.
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
dict: Wire-format quoted triple term, or None if no qt args provided
|
|
157
|
+
"""
|
|
158
|
+
# Check if any qt args were provided
|
|
159
|
+
if not any([qt_subject, qt_predicate, qt_object]):
|
|
160
|
+
return None
|
|
161
|
+
|
|
162
|
+
# Subject (IRI or nested triple)
|
|
163
|
+
s_term = build_term(qt_subject, term_type=qt_subject_type)
|
|
164
|
+
|
|
165
|
+
# Predicate (always IRI)
|
|
166
|
+
p_term = build_term(qt_predicate, term_type='iri')
|
|
167
|
+
|
|
168
|
+
# Object (IRI, literal, or nested triple)
|
|
169
|
+
o_term = build_term(
|
|
170
|
+
qt_object,
|
|
171
|
+
term_type=qt_object_type,
|
|
172
|
+
datatype=qt_object_datatype,
|
|
173
|
+
language=qt_object_language
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
return {
|
|
177
|
+
"t": "t",
|
|
178
|
+
"tr": {
|
|
179
|
+
"s": s_term,
|
|
180
|
+
"p": p_term,
|
|
181
|
+
"o": o_term
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def format_term(term_dict):
|
|
187
|
+
"""Format a term dict for display in space/pipe output formats.
|
|
188
|
+
|
|
189
|
+
Handles multiple wire format styles:
|
|
190
|
+
- Short form (send): {"t": "i", "i": "..."}, {"t": "l", "v": "..."}
|
|
191
|
+
- Long form (receive): {"type": "i", "iri": "..."}, {"type": "l", "value": "..."}
|
|
192
|
+
- Raw quoted triple: {"s": {...}, "p": {...}, "o": {...}} (no type wrapper)
|
|
193
|
+
- Stringified quoted triple in IRI: {"t": "i", "i": "{\"s\":...}"} (backend quirk)
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
term_dict: Wire-format term dict
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
str: Formatted string representation
|
|
200
|
+
"""
|
|
201
|
+
if not term_dict:
|
|
202
|
+
return ""
|
|
203
|
+
|
|
204
|
+
# Get type - handle both short and long form
|
|
205
|
+
t = term_dict.get("t") or term_dict.get("type")
|
|
206
|
+
|
|
207
|
+
if t == "i":
|
|
208
|
+
# IRI - handle both "i" and "iri" keys
|
|
209
|
+
iri_value = term_dict.get("i") or term_dict.get("iri", "")
|
|
210
|
+
# Check if IRI value is actually a stringified quoted triple (backend quirk)
|
|
211
|
+
if iri_value.startswith('{"s":') or iri_value.startswith("{\"s\":"):
|
|
212
|
+
try:
|
|
213
|
+
parsed = json.loads(iri_value)
|
|
214
|
+
if "s" in parsed and "p" in parsed and "o" in parsed:
|
|
215
|
+
# It's a stringified quoted triple - format it properly
|
|
216
|
+
s = format_term(parsed.get("s", {}))
|
|
217
|
+
p = format_term(parsed.get("p", {}))
|
|
218
|
+
o = format_term(parsed.get("o", {}))
|
|
219
|
+
return f"<<{s} {p} {o}>>"
|
|
220
|
+
except json.JSONDecodeError:
|
|
221
|
+
pass # Not valid JSON, treat as regular IRI
|
|
222
|
+
return iri_value
|
|
223
|
+
elif t == "l":
|
|
224
|
+
# Literal - handle both short and long form keys
|
|
225
|
+
value = term_dict.get("v") or term_dict.get("value", "")
|
|
226
|
+
result = f'"{value}"'
|
|
227
|
+
# Language tag
|
|
228
|
+
lang = term_dict.get("ln") or term_dict.get("language")
|
|
229
|
+
if lang:
|
|
230
|
+
result += f'@{lang}'
|
|
231
|
+
else:
|
|
232
|
+
# Datatype
|
|
233
|
+
dt = term_dict.get("dt") or term_dict.get("datatype")
|
|
234
|
+
if dt:
|
|
235
|
+
result += f'^^{dt}'
|
|
236
|
+
return result
|
|
237
|
+
elif t == "t":
|
|
238
|
+
# Quoted triple - handle both "tr" and "triple" keys
|
|
239
|
+
tr = term_dict.get("tr") or term_dict.get("triple", {})
|
|
240
|
+
s = format_term(tr.get("s", {}))
|
|
241
|
+
p = format_term(tr.get("p", {}))
|
|
242
|
+
o = format_term(tr.get("o", {}))
|
|
243
|
+
return f"<<{s} {p} {o}>>"
|
|
244
|
+
elif t is None and "s" in term_dict and "p" in term_dict and "o" in term_dict:
|
|
245
|
+
# Raw quoted triple without type wrapper (has s, p, o keys directly)
|
|
246
|
+
s = format_term(term_dict.get("s", {}))
|
|
247
|
+
p = format_term(term_dict.get("p", {}))
|
|
248
|
+
o = format_term(term_dict.get("o", {}))
|
|
249
|
+
return f"<<{s} {p} {o}>>"
|
|
250
|
+
|
|
251
|
+
return str(term_dict)
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def output_space(triples, headers=False):
|
|
255
|
+
"""Output triples in space-separated format."""
|
|
256
|
+
if headers:
|
|
257
|
+
print("subject predicate object")
|
|
258
|
+
for triple in triples:
|
|
259
|
+
s = format_term(triple.get("s", {}))
|
|
260
|
+
p = format_term(triple.get("p", {}))
|
|
261
|
+
o = format_term(triple.get("o", {}))
|
|
262
|
+
print(s, p, o)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def output_pipe(triples, headers=False):
|
|
266
|
+
"""Output triples in pipe-separated format."""
|
|
267
|
+
if headers:
|
|
268
|
+
print("subject|predicate|object")
|
|
269
|
+
for triple in triples:
|
|
270
|
+
s = format_term(triple.get("s", {}))
|
|
271
|
+
p = format_term(triple.get("p", {}))
|
|
272
|
+
o = format_term(triple.get("o", {}))
|
|
273
|
+
print(f"{s}|{p}|{o}")
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def output_json(triples):
|
|
277
|
+
"""Output triples as a JSON array."""
|
|
278
|
+
print(json.dumps(triples, indent=2))
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def output_jsonl(triples):
|
|
282
|
+
"""Output triples as JSON Lines (one object per line)."""
|
|
283
|
+
for triple in triples:
|
|
284
|
+
print(json.dumps(triple))
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def query_graph(
|
|
288
|
+
url, flow_id, user, collection, limit, batch_size,
|
|
289
|
+
subject=None, predicate=None, obj=None, graph=None,
|
|
290
|
+
output_format="space", headers=False, token=None
|
|
291
|
+
):
|
|
292
|
+
"""Query the triple store with pattern matching.
|
|
293
|
+
|
|
294
|
+
Uses the WebSocket API's raw streaming mode for efficient delivery of results.
|
|
295
|
+
"""
|
|
296
|
+
socket = Api(url, token=token).socket()
|
|
297
|
+
|
|
298
|
+
# Build request dict directly (bypassing triples_query_stream's string conversion)
|
|
299
|
+
request = {
|
|
300
|
+
"user": user,
|
|
301
|
+
"collection": collection,
|
|
302
|
+
"limit": limit,
|
|
303
|
+
"streaming": True,
|
|
304
|
+
"batch-size": batch_size,
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
# Add term dicts for s/p/o (None means wildcard)
|
|
308
|
+
if subject is not None:
|
|
309
|
+
request["s"] = subject
|
|
310
|
+
if predicate is not None:
|
|
311
|
+
request["p"] = predicate
|
|
312
|
+
if obj is not None:
|
|
313
|
+
request["o"] = obj
|
|
314
|
+
if graph is not None:
|
|
315
|
+
request["g"] = graph
|
|
316
|
+
|
|
317
|
+
all_triples = []
|
|
318
|
+
|
|
319
|
+
try:
|
|
320
|
+
# Use raw streaming mode - yields response dicts directly
|
|
321
|
+
for response in socket._send_request_sync(
|
|
322
|
+
"triples", flow_id, request, streaming_raw=True
|
|
323
|
+
):
|
|
324
|
+
# Response may have triples in different locations depending on format
|
|
325
|
+
if isinstance(response, dict):
|
|
326
|
+
triples = response.get("response", response.get("triples", []))
|
|
327
|
+
else:
|
|
328
|
+
triples = response
|
|
329
|
+
|
|
330
|
+
if not isinstance(triples, list):
|
|
331
|
+
triples = [triples] if triples else []
|
|
332
|
+
|
|
333
|
+
if output_format in ("json",):
|
|
334
|
+
# Collect all triples for JSON array output
|
|
335
|
+
all_triples.extend(triples)
|
|
336
|
+
else:
|
|
337
|
+
# Stream output for other formats
|
|
338
|
+
if output_format == "space":
|
|
339
|
+
output_space(triples, headers=headers and not all_triples)
|
|
340
|
+
elif output_format == "pipe":
|
|
341
|
+
output_pipe(triples, headers=headers and not all_triples)
|
|
342
|
+
elif output_format == "jsonl":
|
|
343
|
+
output_jsonl(triples)
|
|
344
|
+
# Track that we've output something (for headers logic)
|
|
345
|
+
all_triples.extend([None] * len(triples))
|
|
346
|
+
|
|
347
|
+
# Output collected JSON array
|
|
348
|
+
if output_format == "json":
|
|
349
|
+
output_json(all_triples)
|
|
350
|
+
|
|
351
|
+
finally:
|
|
352
|
+
socket.close()
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
def main():
|
|
356
|
+
parser = argparse.ArgumentParser(
|
|
357
|
+
prog='tg-query-graph',
|
|
358
|
+
description=__doc__,
|
|
359
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
# Outer triple filters
|
|
363
|
+
outer_group = parser.add_argument_group('Outer triple filters')
|
|
364
|
+
|
|
365
|
+
outer_group.add_argument(
|
|
366
|
+
'-s', '--subject',
|
|
367
|
+
metavar='VALUE',
|
|
368
|
+
help='Subject filter (auto-detected as IRI or literal)',
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
outer_group.add_argument(
|
|
372
|
+
'-p', '--predicate',
|
|
373
|
+
metavar='VALUE',
|
|
374
|
+
help='Predicate filter (auto-detected as IRI)',
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
outer_group.add_argument(
|
|
378
|
+
'-o', '--object',
|
|
379
|
+
dest='obj',
|
|
380
|
+
metavar='VALUE',
|
|
381
|
+
help='Object filter (IRI, literal, or <<quoted triple>>)',
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
outer_group.add_argument(
|
|
385
|
+
'--object-type',
|
|
386
|
+
choices=['iri', 'literal', 'triple'],
|
|
387
|
+
metavar='TYPE',
|
|
388
|
+
help='Override object type detection: iri, literal, triple',
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
outer_group.add_argument(
|
|
392
|
+
'--object-datatype',
|
|
393
|
+
metavar='DATATYPE',
|
|
394
|
+
help='Datatype for literal object (e.g., xsd:integer)',
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
outer_group.add_argument(
|
|
398
|
+
'--object-language',
|
|
399
|
+
metavar='LANG',
|
|
400
|
+
help='Language tag for literal object (e.g., en)',
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
outer_group.add_argument(
|
|
404
|
+
'-g', '--graph',
|
|
405
|
+
metavar='VALUE',
|
|
406
|
+
help='Named graph filter',
|
|
407
|
+
)
|
|
408
|
+
|
|
409
|
+
# Quoted triple filters (alternative to inline <<s p o>> syntax)
|
|
410
|
+
qt_group = parser.add_argument_group(
|
|
411
|
+
'Quoted triple filters',
|
|
412
|
+
'Build object as quoted triple using explicit fields (alternative to -o "<<s p o>>")'
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
qt_group.add_argument(
|
|
416
|
+
'--qt-subject',
|
|
417
|
+
metavar='VALUE',
|
|
418
|
+
help='Quoted triple subject',
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
qt_group.add_argument(
|
|
422
|
+
'--qt-subject-type',
|
|
423
|
+
choices=['iri', 'triple'],
|
|
424
|
+
metavar='TYPE',
|
|
425
|
+
help='Override qt-subject type: iri, triple',
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
qt_group.add_argument(
|
|
429
|
+
'--qt-predicate',
|
|
430
|
+
metavar='VALUE',
|
|
431
|
+
help='Quoted triple predicate (always IRI)',
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
qt_group.add_argument(
|
|
435
|
+
'--qt-object',
|
|
436
|
+
metavar='VALUE',
|
|
437
|
+
help='Quoted triple object',
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
qt_group.add_argument(
|
|
441
|
+
'--qt-object-type',
|
|
442
|
+
choices=['iri', 'literal', 'triple'],
|
|
443
|
+
metavar='TYPE',
|
|
444
|
+
help='Override qt-object type: iri, literal, triple',
|
|
445
|
+
)
|
|
446
|
+
|
|
447
|
+
qt_group.add_argument(
|
|
448
|
+
'--qt-object-datatype',
|
|
449
|
+
metavar='DATATYPE',
|
|
450
|
+
help='Datatype for qt-object literal',
|
|
451
|
+
)
|
|
452
|
+
|
|
453
|
+
qt_group.add_argument(
|
|
454
|
+
'--qt-object-language',
|
|
455
|
+
metavar='LANG',
|
|
456
|
+
help='Language tag for qt-object literal',
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
# Standard parameters
|
|
460
|
+
std_group = parser.add_argument_group('Standard parameters')
|
|
461
|
+
|
|
462
|
+
std_group.add_argument(
|
|
463
|
+
'-u', '--api-url',
|
|
464
|
+
default=default_url,
|
|
465
|
+
metavar='URL',
|
|
466
|
+
help=f'API URL (default: {default_url})',
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
std_group.add_argument(
|
|
470
|
+
'-f', '--flow-id',
|
|
471
|
+
default="default",
|
|
472
|
+
metavar='ID',
|
|
473
|
+
help='Flow ID (default: default)'
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
std_group.add_argument(
|
|
477
|
+
'-U', '--user',
|
|
478
|
+
default=default_user,
|
|
479
|
+
metavar='USER',
|
|
480
|
+
help=f'User/keyspace (default: {default_user})'
|
|
481
|
+
)
|
|
482
|
+
|
|
483
|
+
std_group.add_argument(
|
|
484
|
+
'-C', '--collection',
|
|
485
|
+
default=default_collection,
|
|
486
|
+
metavar='COLL',
|
|
487
|
+
help=f'Collection (default: {default_collection})'
|
|
488
|
+
)
|
|
489
|
+
|
|
490
|
+
std_group.add_argument(
|
|
491
|
+
'-t', '--token',
|
|
492
|
+
default=default_token,
|
|
493
|
+
metavar='TOKEN',
|
|
494
|
+
help='Auth token (default: $TRUSTGRAPH_TOKEN)',
|
|
495
|
+
)
|
|
496
|
+
|
|
497
|
+
std_group.add_argument(
|
|
498
|
+
'-l', '--limit',
|
|
499
|
+
type=int,
|
|
500
|
+
default=1000,
|
|
501
|
+
metavar='N',
|
|
502
|
+
help='Max results (default: 1000)',
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
std_group.add_argument(
|
|
506
|
+
'-b', '--batch-size',
|
|
507
|
+
type=int,
|
|
508
|
+
default=20,
|
|
509
|
+
metavar='N',
|
|
510
|
+
help='Streaming batch size (default: 20)',
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
# Output options
|
|
514
|
+
out_group = parser.add_argument_group('Output options')
|
|
515
|
+
|
|
516
|
+
out_group.add_argument(
|
|
517
|
+
'--format',
|
|
518
|
+
choices=['space', 'pipe', 'json', 'jsonl'],
|
|
519
|
+
default='space',
|
|
520
|
+
metavar='FORMAT',
|
|
521
|
+
help='Output format: space, pipe, json, jsonl (default: space)',
|
|
522
|
+
)
|
|
523
|
+
|
|
524
|
+
out_group.add_argument(
|
|
525
|
+
'-H', '--headers',
|
|
526
|
+
action='store_true',
|
|
527
|
+
help='Show column headers (for space/pipe formats)',
|
|
528
|
+
)
|
|
529
|
+
|
|
530
|
+
args = parser.parse_args()
|
|
531
|
+
|
|
532
|
+
try:
|
|
533
|
+
# Build term dicts from CLI arguments
|
|
534
|
+
subject_term = build_term(args.subject) if args.subject else None
|
|
535
|
+
predicate_term = build_term(args.predicate) if args.predicate else None
|
|
536
|
+
|
|
537
|
+
# Check for --qt-* args to build quoted triple as object
|
|
538
|
+
qt_term = build_quoted_triple_term(
|
|
539
|
+
qt_subject=args.qt_subject,
|
|
540
|
+
qt_subject_type=args.qt_subject_type,
|
|
541
|
+
qt_predicate=args.qt_predicate,
|
|
542
|
+
qt_object=args.qt_object,
|
|
543
|
+
qt_object_type=args.qt_object_type,
|
|
544
|
+
qt_object_datatype=args.qt_object_datatype,
|
|
545
|
+
qt_object_language=args.qt_object_language,
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
# Object: use --qt-* args if provided, otherwise use -o
|
|
549
|
+
if qt_term is not None:
|
|
550
|
+
if args.obj:
|
|
551
|
+
parser.error("Cannot use both -o/--object and --qt-* arguments")
|
|
552
|
+
obj_term = qt_term
|
|
553
|
+
elif args.obj:
|
|
554
|
+
obj_term = build_term(
|
|
555
|
+
args.obj,
|
|
556
|
+
term_type=args.object_type,
|
|
557
|
+
datatype=args.object_datatype,
|
|
558
|
+
language=args.object_language
|
|
559
|
+
)
|
|
560
|
+
else:
|
|
561
|
+
obj_term = None
|
|
562
|
+
|
|
563
|
+
# Graph is a plain IRI string, not a Term
|
|
564
|
+
# None = all graphs, "" = default graph only, "uri" = specific graph
|
|
565
|
+
graph_value = args.graph
|
|
566
|
+
|
|
567
|
+
query_graph(
|
|
568
|
+
url=args.api_url,
|
|
569
|
+
flow_id=args.flow_id,
|
|
570
|
+
user=args.user,
|
|
571
|
+
collection=args.collection,
|
|
572
|
+
limit=args.limit,
|
|
573
|
+
batch_size=args.batch_size,
|
|
574
|
+
subject=subject_term,
|
|
575
|
+
predicate=predicate_term,
|
|
576
|
+
obj=obj_term,
|
|
577
|
+
graph=graph_value,
|
|
578
|
+
output_format=args.format,
|
|
579
|
+
headers=args.headers,
|
|
580
|
+
token=args.token,
|
|
581
|
+
)
|
|
582
|
+
|
|
583
|
+
except json.JSONDecodeError as e:
|
|
584
|
+
print(f"Error parsing JSON: {e}", file=sys.stderr)
|
|
585
|
+
sys.exit(1)
|
|
586
|
+
except ValueError as e:
|
|
587
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
588
|
+
sys.exit(1)
|
|
589
|
+
except Exception as e:
|
|
590
|
+
print(f"Exception: {e}", file=sys.stderr)
|
|
591
|
+
sys.exit(1)
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
if __name__ == "__main__":
|
|
595
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.1.12"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: trustgraph-cli
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.12
|
|
4
4
|
Summary: TrustGraph provides a means to run a pipeline of flexible AI processing components in a flexible means to achieve a processing pipeline.
|
|
5
5
|
Author-email: "trustgraph.ai" <security@trustgraph.ai>
|
|
6
6
|
Project-URL: Homepage, https://github.com/trustgraph-ai/trustgraph
|
|
@@ -42,6 +42,7 @@ trustgraph/cli/load_turtle.py
|
|
|
42
42
|
trustgraph/cli/put_config_item.py
|
|
43
43
|
trustgraph/cli/put_flow_blueprint.py
|
|
44
44
|
trustgraph/cli/put_kg_core.py
|
|
45
|
+
trustgraph/cli/query_graph.py
|
|
45
46
|
trustgraph/cli/remove_library_document.py
|
|
46
47
|
trustgraph/cli/save_doc_embeds.py
|
|
47
48
|
trustgraph/cli/set_collection.py
|
|
@@ -38,6 +38,7 @@ tg-load-turtle = trustgraph.cli.load_turtle:main
|
|
|
38
38
|
tg-put-config-item = trustgraph.cli.put_config_item:main
|
|
39
39
|
tg-put-flow-blueprint = trustgraph.cli.put_flow_blueprint:main
|
|
40
40
|
tg-put-kg-core = trustgraph.cli.put_kg_core:main
|
|
41
|
+
tg-query-graph = trustgraph.cli.query_graph:main
|
|
41
42
|
tg-remove-library-document = trustgraph.cli.remove_library_document:main
|
|
42
43
|
tg-save-doc-embeds = trustgraph.cli.save_doc_embeds:main
|
|
43
44
|
tg-set-collection = trustgraph.cli.set_collection:main
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.1.10"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph/cli/invoke_document_embeddings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{trustgraph_cli-2.1.10 → trustgraph_cli-2.1.12}/trustgraph_cli.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|