trustgraph-cli 1.2.10__tar.gz → 1.5.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.
Files changed (79) hide show
  1. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/PKG-INFO +2 -2
  2. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/pyproject.toml +14 -1
  3. trustgraph_cli-1.5.7/trustgraph/cli/delete_collection.py +72 -0
  4. trustgraph_cli-1.5.7/trustgraph/cli/delete_config_item.py +61 -0
  5. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/delete_kg_core.py +2 -2
  6. trustgraph_cli-1.5.7/trustgraph/cli/get_config_item.py +78 -0
  7. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/invoke_agent.py +19 -3
  8. trustgraph_cli-1.5.7/trustgraph/cli/invoke_nlp_query.py +111 -0
  9. trustgraph_cli-1.5.7/trustgraph/cli/invoke_objects_query.py +201 -0
  10. trustgraph_cli-1.5.7/trustgraph/cli/invoke_structured_query.py +173 -0
  11. trustgraph_cli-1.5.7/trustgraph/cli/list_collections.py +86 -0
  12. trustgraph_cli-1.5.7/trustgraph/cli/list_config_items.py +65 -0
  13. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/load_kg_core.py +3 -3
  14. trustgraph_cli-1.5.7/trustgraph/cli/load_knowledge.py +202 -0
  15. trustgraph_cli-1.5.7/trustgraph/cli/load_structured_data.py +1097 -0
  16. trustgraph_cli-1.5.7/trustgraph/cli/put_config_item.py +80 -0
  17. trustgraph_cli-1.5.7/trustgraph/cli/set_collection.py +103 -0
  18. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/set_mcp_tool.py +25 -7
  19. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/set_tool.py +59 -16
  20. trustgraph_cli-1.5.7/trustgraph/cli/show_flow_classes.py +122 -0
  21. trustgraph_cli-1.5.7/trustgraph/cli/show_flows.py +215 -0
  22. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/show_mcp_tools.py +6 -0
  23. trustgraph_cli-1.5.7/trustgraph/cli/show_parameter_types.py +210 -0
  24. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/show_tools.py +27 -2
  25. trustgraph_cli-1.5.7/trustgraph/cli/start_flow.py +122 -0
  26. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/unload_kg_core.py +2 -2
  27. trustgraph_cli-1.5.7/trustgraph/cli_version.py +1 -0
  28. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph_cli.egg-info/PKG-INFO +2 -2
  29. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph_cli.egg-info/SOURCES.txt +13 -0
  30. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph_cli.egg-info/entry_points.txt +13 -0
  31. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph_cli.egg-info/requires.txt +1 -1
  32. trustgraph_cli-1.2.10/trustgraph/cli/show_flow_classes.py +0 -67
  33. trustgraph_cli-1.2.10/trustgraph/cli/show_flows.py +0 -112
  34. trustgraph_cli-1.2.10/trustgraph/cli/start_flow.py +0 -70
  35. trustgraph_cli-1.2.10/trustgraph/cli_version.py +0 -1
  36. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/README.md +0 -0
  37. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/setup.cfg +0 -0
  38. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/__init__.py +0 -0
  39. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/add_library_document.py +0 -0
  40. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/delete_flow_class.py +0 -0
  41. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/delete_mcp_tool.py +0 -0
  42. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/delete_tool.py +0 -0
  43. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/dump_msgpack.py +0 -0
  44. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/get_flow_class.py +0 -0
  45. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/get_kg_core.py +0 -0
  46. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/graph_to_turtle.py +0 -0
  47. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/init_pulsar_manager.py +0 -0
  48. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/init_trustgraph.py +0 -0
  49. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/invoke_document_rag.py +0 -0
  50. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/invoke_graph_rag.py +0 -0
  51. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/invoke_llm.py +0 -0
  52. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/invoke_mcp_tool.py +0 -0
  53. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/invoke_prompt.py +0 -0
  54. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/load_doc_embeds.py +0 -0
  55. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/load_pdf.py +0 -0
  56. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/load_sample_documents.py +0 -0
  57. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/load_text.py +0 -0
  58. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/load_turtle.py +0 -0
  59. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/put_flow_class.py +0 -0
  60. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/put_kg_core.py +0 -0
  61. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/remove_library_document.py +0 -0
  62. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/save_doc_embeds.py +0 -0
  63. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/set_prompt.py +0 -0
  64. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/set_token_costs.py +0 -0
  65. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/show_config.py +0 -0
  66. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/show_flow_state.py +0 -0
  67. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/show_graph.py +0 -0
  68. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/show_kg_cores.py +0 -0
  69. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/show_library_documents.py +0 -0
  70. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/show_library_processing.py +0 -0
  71. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/show_processor_state.py +0 -0
  72. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/show_prompts.py +0 -0
  73. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/show_token_costs.py +0 -0
  74. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/show_token_rate.py +0 -0
  75. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/start_library_processing.py +0 -0
  76. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/stop_flow.py +0 -0
  77. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph/cli/stop_library_processing.py +0 -0
  78. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/trustgraph_cli.egg-info/dependency_links.txt +0 -0
  79. {trustgraph_cli-1.2.10 → trustgraph_cli-1.5.7}/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: 1.2.10
3
+ Version: 1.5.7
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
@@ -8,7 +8,7 @@ Classifier: Programming Language :: Python :: 3
8
8
  Classifier: Operating System :: OS Independent
9
9
  Requires-Python: >=3.8
10
10
  Description-Content-Type: text/markdown
11
- Requires-Dist: trustgraph-base<1.3,>=1.2
11
+ Requires-Dist: trustgraph-base<1.6,>=1.5
12
12
  Requires-Dist: requests
13
13
  Requires-Dist: pulsar-client
14
14
  Requires-Dist: aiohttp
@@ -10,7 +10,7 @@ description = "TrustGraph provides a means to run a pipeline of flexible AI proc
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.8"
12
12
  dependencies = [
13
- "trustgraph-base>=1.2,<1.3",
13
+ "trustgraph-base>=1.5,<1.6",
14
14
  "requests",
15
15
  "pulsar-client",
16
16
  "aiohttp",
@@ -43,13 +43,18 @@ tg-invoke-document-rag = "trustgraph.cli.invoke_document_rag:main"
43
43
  tg-invoke-graph-rag = "trustgraph.cli.invoke_graph_rag:main"
44
44
  tg-invoke-llm = "trustgraph.cli.invoke_llm:main"
45
45
  tg-invoke-mcp-tool = "trustgraph.cli.invoke_mcp_tool:main"
46
+ tg-invoke-nlp-query = "trustgraph.cli.invoke_nlp_query:main"
47
+ tg-invoke-objects-query = "trustgraph.cli.invoke_objects_query:main"
46
48
  tg-invoke-prompt = "trustgraph.cli.invoke_prompt:main"
49
+ tg-invoke-structured-query = "trustgraph.cli.invoke_structured_query:main"
47
50
  tg-load-doc-embeds = "trustgraph.cli.load_doc_embeds:main"
48
51
  tg-load-kg-core = "trustgraph.cli.load_kg_core:main"
49
52
  tg-load-pdf = "trustgraph.cli.load_pdf:main"
50
53
  tg-load-sample-documents = "trustgraph.cli.load_sample_documents:main"
51
54
  tg-load-text = "trustgraph.cli.load_text:main"
52
55
  tg-load-turtle = "trustgraph.cli.load_turtle:main"
56
+ tg-load-knowledge = "trustgraph.cli.load_knowledge:main"
57
+ tg-load-structured-data = "trustgraph.cli.load_structured_data:main"
53
58
  tg-put-flow-class = "trustgraph.cli.put_flow_class:main"
54
59
  tg-put-kg-core = "trustgraph.cli.put_kg_core:main"
55
60
  tg-remove-library-document = "trustgraph.cli.remove_library_document:main"
@@ -67,6 +72,7 @@ tg-show-kg-cores = "trustgraph.cli.show_kg_cores:main"
67
72
  tg-show-library-documents = "trustgraph.cli.show_library_documents:main"
68
73
  tg-show-library-processing = "trustgraph.cli.show_library_processing:main"
69
74
  tg-show-mcp-tools = "trustgraph.cli.show_mcp_tools:main"
75
+ tg-show-parameter-types = "trustgraph.cli.show_parameter_types:main"
70
76
  tg-show-processor-state = "trustgraph.cli.show_processor_state:main"
71
77
  tg-show-prompts = "trustgraph.cli.show_prompts:main"
72
78
  tg-show-token-costs = "trustgraph.cli.show_token_costs:main"
@@ -77,6 +83,13 @@ tg-unload-kg-core = "trustgraph.cli.unload_kg_core:main"
77
83
  tg-start-library-processing = "trustgraph.cli.start_library_processing:main"
78
84
  tg-stop-flow = "trustgraph.cli.stop_flow:main"
79
85
  tg-stop-library-processing = "trustgraph.cli.stop_library_processing:main"
86
+ tg-list-config-items = "trustgraph.cli.list_config_items:main"
87
+ tg-get-config-item = "trustgraph.cli.get_config_item:main"
88
+ tg-put-config-item = "trustgraph.cli.put_config_item:main"
89
+ tg-delete-config-item = "trustgraph.cli.delete_config_item:main"
90
+ tg-list-collections = "trustgraph.cli.list_collections:main"
91
+ tg-set-collection = "trustgraph.cli.set_collection:main"
92
+ tg-delete-collection = "trustgraph.cli.delete_collection:main"
80
93
 
81
94
  [tool.setuptools.packages.find]
82
95
  include = ["trustgraph*"]
@@ -0,0 +1,72 @@
1
+ """
2
+ Delete a collection and all its data
3
+ """
4
+
5
+ import argparse
6
+ import os
7
+ from trustgraph.api import Api
8
+
9
+ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
10
+ default_user = "trustgraph"
11
+
12
+ def delete_collection(url, user, collection, confirm):
13
+
14
+ if not confirm:
15
+ response = input(f"Are you sure you want to delete collection '{collection}' and all its data? (y/N): ")
16
+ if response.lower() not in ['y', 'yes']:
17
+ print("Operation cancelled.")
18
+ return
19
+
20
+ api = Api(url).collection()
21
+
22
+ api.delete_collection(user=user, collection=collection)
23
+
24
+ print(f"Collection '{collection}' deleted successfully.")
25
+
26
+ def main():
27
+
28
+ parser = argparse.ArgumentParser(
29
+ prog='tg-delete-collection',
30
+ description=__doc__,
31
+ )
32
+
33
+ parser.add_argument(
34
+ 'collection',
35
+ help='Collection ID to delete'
36
+ )
37
+
38
+ parser.add_argument(
39
+ '-u', '--api-url',
40
+ default=default_url,
41
+ help=f'API URL (default: {default_url})',
42
+ )
43
+
44
+ parser.add_argument(
45
+ '-U', '--user',
46
+ default=default_user,
47
+ help=f'User ID (default: {default_user})'
48
+ )
49
+
50
+ parser.add_argument(
51
+ '-y', '--yes',
52
+ action='store_true',
53
+ help='Skip confirmation prompt'
54
+ )
55
+
56
+ args = parser.parse_args()
57
+
58
+ try:
59
+
60
+ delete_collection(
61
+ url = args.api_url,
62
+ user = args.user,
63
+ collection = args.collection,
64
+ confirm = args.yes
65
+ )
66
+
67
+ except Exception as e:
68
+
69
+ print("Exception:", e, flush=True)
70
+
71
+ if __name__ == "__main__":
72
+ main()
@@ -0,0 +1,61 @@
1
+ """
2
+ Deletes a configuration item
3
+ """
4
+
5
+ import argparse
6
+ import os
7
+ from trustgraph.api import Api
8
+ from trustgraph.api.types import ConfigKey
9
+
10
+ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
11
+
12
+ def delete_config_item(url, config_type, key):
13
+
14
+ api = Api(url).config()
15
+
16
+ config_key = ConfigKey(type=config_type, key=key)
17
+ api.delete([config_key])
18
+
19
+ print(f"Configuration item deleted: {config_type}/{key}")
20
+
21
+ def main():
22
+
23
+ parser = argparse.ArgumentParser(
24
+ prog='tg-delete-config-item',
25
+ description=__doc__,
26
+ )
27
+
28
+ parser.add_argument(
29
+ '--type',
30
+ required=True,
31
+ help='Configuration type',
32
+ )
33
+
34
+ parser.add_argument(
35
+ '--key',
36
+ required=True,
37
+ help='Configuration key',
38
+ )
39
+
40
+ parser.add_argument(
41
+ '-u', '--api-url',
42
+ default=default_url,
43
+ help=f'API URL (default: {default_url})',
44
+ )
45
+
46
+ args = parser.parse_args()
47
+
48
+ try:
49
+
50
+ delete_config_item(
51
+ url=args.api_url,
52
+ config_type=args.type,
53
+ key=args.key,
54
+ )
55
+
56
+ except Exception as e:
57
+
58
+ print("Exception:", e, flush=True)
59
+
60
+ if __name__ == "__main__":
61
+ main()
@@ -19,7 +19,7 @@ def delete_kg_core(url, user, id):
19
19
  def main():
20
20
 
21
21
  parser = argparse.ArgumentParser(
22
- prog='tg-delete-flow-class',
22
+ prog='tg-delete-kg-core',
23
23
  description=__doc__,
24
24
  )
25
25
 
@@ -56,4 +56,4 @@ def main():
56
56
  print("Exception:", e, flush=True)
57
57
 
58
58
  if __name__ == "__main__":
59
- main()
59
+ main()
@@ -0,0 +1,78 @@
1
+ """
2
+ Gets a specific configuration item
3
+ """
4
+
5
+ import argparse
6
+ import os
7
+ import json
8
+ from trustgraph.api import Api
9
+ from trustgraph.api.types import ConfigKey
10
+
11
+ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
12
+
13
+ def get_config_item(url, config_type, key, format_type):
14
+
15
+ api = Api(url).config()
16
+
17
+ config_key = ConfigKey(type=config_type, key=key)
18
+ values = api.get([config_key])
19
+
20
+ if not values:
21
+ raise Exception(f"Configuration item not found: {config_type}/{key}")
22
+
23
+ value = values[0].value
24
+
25
+ if format_type == "json":
26
+ print(json.dumps(value))
27
+ else:
28
+ print(value)
29
+
30
+ def main():
31
+
32
+ parser = argparse.ArgumentParser(
33
+ prog='tg-get-config-item',
34
+ description=__doc__,
35
+ )
36
+
37
+ parser.add_argument(
38
+ '--type',
39
+ required=True,
40
+ help='Configuration type',
41
+ )
42
+
43
+ parser.add_argument(
44
+ '--key',
45
+ required=True,
46
+ help='Configuration key',
47
+ )
48
+
49
+ parser.add_argument(
50
+ '--format',
51
+ choices=['text', 'json'],
52
+ default='text',
53
+ help='Output format (default: text)',
54
+ )
55
+
56
+ parser.add_argument(
57
+ '-u', '--api-url',
58
+ default=default_url,
59
+ help=f'API URL (default: {default_url})',
60
+ )
61
+
62
+ args = parser.parse_args()
63
+
64
+ try:
65
+
66
+ get_config_item(
67
+ url=args.api_url,
68
+ config_type=args.type,
69
+ key=args.key,
70
+ format_type=args.format,
71
+ )
72
+
73
+ except Exception as e:
74
+
75
+ print("Exception:", e, flush=True)
76
+
77
+ if __name__ == "__main__":
78
+ main()
@@ -29,7 +29,7 @@ def output(text, prefix="> ", width=78):
29
29
 
30
30
  async def question(
31
31
  url, question, flow_id, user, collection,
32
- plan=None, state=None, verbose=False
32
+ plan=None, state=None, group=None, verbose=False
33
33
  ):
34
34
 
35
35
  if not url.endswith("/"):
@@ -55,15 +55,24 @@ async def question(
55
55
 
56
56
  async with connect(url) as ws:
57
57
 
58
- req = json.dumps({
58
+ req = {
59
59
  "id": mid,
60
60
  "service": "agent",
61
61
  "flow": flow_id,
62
62
  "request": {
63
63
  "question": question,
64
+ "user": user,
65
+ "history": []
64
66
  }
67
+ }
68
+
69
+ # Only add optional fields if they have values
70
+ if state is not None:
71
+ req["request"]["state"] = state
72
+ if group is not None:
73
+ req["request"]["group"] = group
65
74
 
66
- })
75
+ req = json.dumps(req)
67
76
 
68
77
  await ws.send(req)
69
78
 
@@ -140,6 +149,12 @@ def main():
140
149
  help=f'Agent initial state (default: unspecified)'
141
150
  )
142
151
 
152
+ parser.add_argument(
153
+ '-g', '--group',
154
+ nargs='+',
155
+ help='Agent tool groups (can specify multiple)'
156
+ )
157
+
143
158
  parser.add_argument(
144
159
  '-v', '--verbose',
145
160
  action="store_true",
@@ -159,6 +174,7 @@ def main():
159
174
  collection = args.collection,
160
175
  plan = args.plan,
161
176
  state = args.state,
177
+ group = args.group,
162
178
  verbose = args.verbose,
163
179
  )
164
180
  )
@@ -0,0 +1,111 @@
1
+ """
2
+ Uses the NLP Query service to convert natural language questions to GraphQL queries
3
+ """
4
+
5
+ import argparse
6
+ import os
7
+ import json
8
+ import sys
9
+ from trustgraph.api import Api
10
+
11
+ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
12
+
13
+ def nlp_query(url, flow_id, question, max_results, output_format='json'):
14
+
15
+ api = Api(url).flow().id(flow_id)
16
+
17
+ resp = api.nlp_query(
18
+ question=question,
19
+ max_results=max_results
20
+ )
21
+
22
+ # Check for errors
23
+ if "error" in resp and resp["error"]:
24
+ print("Error:", resp["error"].get("message", "Unknown error"), file=sys.stderr)
25
+ sys.exit(1)
26
+
27
+ # Format output based on requested format
28
+ if output_format == 'json':
29
+ print(json.dumps(resp, indent=2))
30
+ elif output_format == 'graphql':
31
+ # Just print the GraphQL query
32
+ if "graphql_query" in resp:
33
+ print(resp["graphql_query"])
34
+ else:
35
+ print("No GraphQL query generated", file=sys.stderr)
36
+ sys.exit(1)
37
+ elif output_format == 'summary':
38
+ # Print a human-readable summary
39
+ if "graphql_query" in resp:
40
+ print(f"Generated GraphQL Query:")
41
+ print("-" * 40)
42
+ print(resp["graphql_query"])
43
+ print("-" * 40)
44
+ if "detected_schemas" in resp and resp["detected_schemas"]:
45
+ print(f"Detected Schemas: {', '.join(resp['detected_schemas'])}")
46
+ if "confidence" in resp:
47
+ print(f"Confidence: {resp['confidence']:.2%}")
48
+ if "variables" in resp and resp["variables"]:
49
+ print(f"Variables: {json.dumps(resp['variables'], indent=2)}")
50
+ else:
51
+ print("No GraphQL query generated", file=sys.stderr)
52
+ sys.exit(1)
53
+
54
+ def main():
55
+
56
+ parser = argparse.ArgumentParser(
57
+ prog='tg-invoke-nlp-query',
58
+ description=__doc__,
59
+ )
60
+
61
+ parser.add_argument(
62
+ '-u', '--url',
63
+ default=default_url,
64
+ help=f'API URL (default: {default_url})',
65
+ )
66
+
67
+ parser.add_argument(
68
+ '-f', '--flow-id',
69
+ default="default",
70
+ help=f'Flow ID (default: default)'
71
+ )
72
+
73
+ parser.add_argument(
74
+ '-q', '--question',
75
+ required=True,
76
+ help='Natural language question to convert to GraphQL',
77
+ )
78
+
79
+ parser.add_argument(
80
+ '-m', '--max-results',
81
+ type=int,
82
+ default=100,
83
+ help='Maximum number of results (default: 100)'
84
+ )
85
+
86
+ parser.add_argument(
87
+ '--format',
88
+ choices=['json', 'graphql', 'summary'],
89
+ default='summary',
90
+ help='Output format (default: summary)'
91
+ )
92
+
93
+ args = parser.parse_args()
94
+
95
+ try:
96
+
97
+ nlp_query(
98
+ url=args.url,
99
+ flow_id=args.flow_id,
100
+ question=args.question,
101
+ max_results=args.max_results,
102
+ output_format=args.format,
103
+ )
104
+
105
+ except Exception as e:
106
+
107
+ print("Exception:", e, flush=True, file=sys.stderr)
108
+ sys.exit(1)
109
+
110
+ if __name__ == "__main__":
111
+ main()
@@ -0,0 +1,201 @@
1
+ """
2
+ Uses the ObjectsQuery service to execute GraphQL queries against structured data
3
+ """
4
+
5
+ import argparse
6
+ import os
7
+ import json
8
+ import sys
9
+ import csv
10
+ import io
11
+ from trustgraph.api import Api
12
+ from tabulate import tabulate
13
+
14
+ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
15
+ default_user = 'trustgraph'
16
+ default_collection = 'default'
17
+
18
+ def format_output(data, output_format):
19
+ """Format GraphQL response data in the specified format"""
20
+ if not data:
21
+ return "No data returned"
22
+
23
+ # Handle case where data contains multiple query results
24
+ if len(data) == 1:
25
+ # Single query result - extract the list
26
+ query_name, result_list = next(iter(data.items()))
27
+ if isinstance(result_list, list):
28
+ return format_table_data(result_list, query_name, output_format)
29
+
30
+ # Multiple queries or non-list data - use JSON format
31
+ if output_format == 'json':
32
+ return json.dumps(data, indent=2)
33
+ else:
34
+ return json.dumps(data, indent=2) # Fallback to JSON
35
+
36
+ def format_table_data(rows, table_name, output_format):
37
+ """Format a list of rows in the specified format"""
38
+ if not rows:
39
+ return f"No {table_name} found"
40
+
41
+ if output_format == 'json':
42
+ return json.dumps({table_name: rows}, indent=2)
43
+
44
+ elif output_format == 'csv':
45
+ # Get field names in order from first row, then add any missing ones
46
+ fieldnames = list(rows[0].keys()) if rows else []
47
+ # Add any additional fields from other rows that might be missing
48
+ all_fields = set(fieldnames)
49
+ for row in rows:
50
+ for field in row.keys():
51
+ if field not in all_fields:
52
+ fieldnames.append(field)
53
+ all_fields.add(field)
54
+
55
+ # Create CSV string
56
+ output = io.StringIO()
57
+ writer = csv.DictWriter(output, fieldnames=fieldnames)
58
+ writer.writeheader()
59
+ writer.writerows(rows)
60
+ return output.getvalue().rstrip()
61
+
62
+ elif output_format == 'table':
63
+ # Get field names in order from first row, then add any missing ones
64
+ fieldnames = list(rows[0].keys()) if rows else []
65
+ # Add any additional fields from other rows that might be missing
66
+ all_fields = set(fieldnames)
67
+ for row in rows:
68
+ for field in row.keys():
69
+ if field not in all_fields:
70
+ fieldnames.append(field)
71
+ all_fields.add(field)
72
+
73
+ # Create table data
74
+ table_data = []
75
+ for row in rows:
76
+ table_row = [row.get(field, '') for field in fieldnames]
77
+ table_data.append(table_row)
78
+
79
+ return tabulate(table_data, headers=fieldnames, tablefmt='pretty')
80
+
81
+ else:
82
+ return json.dumps({table_name: rows}, indent=2)
83
+
84
+ def objects_query(
85
+ url, flow_id, query, user, collection, variables, operation_name, output_format='table'
86
+ ):
87
+
88
+ api = Api(url).flow().id(flow_id)
89
+
90
+ # Parse variables if provided as JSON string
91
+ parsed_variables = {}
92
+ if variables:
93
+ try:
94
+ parsed_variables = json.loads(variables)
95
+ except json.JSONDecodeError as e:
96
+ print(f"Error parsing variables JSON: {e}", file=sys.stderr)
97
+ sys.exit(1)
98
+
99
+ resp = api.objects_query(
100
+ query=query,
101
+ user=user,
102
+ collection=collection,
103
+ variables=parsed_variables if parsed_variables else None,
104
+ operation_name=operation_name
105
+ )
106
+
107
+ # Check for GraphQL errors
108
+ if "errors" in resp and resp["errors"]:
109
+ print("GraphQL Errors:", file=sys.stderr)
110
+ for error in resp["errors"]:
111
+ print(f" - {error.get('message', 'Unknown error')}", file=sys.stderr)
112
+ if "path" in error and error["path"]:
113
+ print(f" Path: {error['path']}", file=sys.stderr)
114
+ # Still print data if available
115
+ if "data" in resp and resp["data"]:
116
+ print(format_output(resp["data"], output_format))
117
+ sys.exit(1)
118
+
119
+ # Print the data
120
+ if "data" in resp:
121
+ print(format_output(resp["data"], output_format))
122
+ else:
123
+ print("No data returned", file=sys.stderr)
124
+ sys.exit(1)
125
+
126
+ def main():
127
+
128
+ parser = argparse.ArgumentParser(
129
+ prog='tg-invoke-objects-query',
130
+ description=__doc__,
131
+ )
132
+
133
+ parser.add_argument(
134
+ '-u', '--url',
135
+ default=default_url,
136
+ help=f'API URL (default: {default_url})',
137
+ )
138
+
139
+ parser.add_argument(
140
+ '-f', '--flow-id',
141
+ default="default",
142
+ help=f'Flow ID (default: default)'
143
+ )
144
+
145
+ parser.add_argument(
146
+ '-q', '--query',
147
+ required=True,
148
+ help='GraphQL query to execute',
149
+ )
150
+
151
+ parser.add_argument(
152
+ '-U', '--user',
153
+ default=default_user,
154
+ help=f'User ID (default: {default_user})'
155
+ )
156
+
157
+ parser.add_argument(
158
+ '-C', '--collection',
159
+ default=default_collection,
160
+ help=f'Collection ID (default: {default_collection})'
161
+ )
162
+
163
+ parser.add_argument(
164
+ '-v', '--variables',
165
+ help='GraphQL variables as JSON string (e.g., \'{"limit": 5}\')'
166
+ )
167
+
168
+ parser.add_argument(
169
+ '-o', '--operation-name',
170
+ help='Operation name for multi-operation GraphQL documents'
171
+ )
172
+
173
+ parser.add_argument(
174
+ '--format',
175
+ choices=['table', 'json', 'csv'],
176
+ default='table',
177
+ help='Output format (default: table)'
178
+ )
179
+
180
+ args = parser.parse_args()
181
+
182
+ try:
183
+
184
+ objects_query(
185
+ url=args.url,
186
+ flow_id=args.flow_id,
187
+ query=args.query,
188
+ user=args.user,
189
+ collection=args.collection,
190
+ variables=args.variables,
191
+ operation_name=args.operation_name,
192
+ output_format=args.format,
193
+ )
194
+
195
+ except Exception as e:
196
+
197
+ print("Exception:", e, flush=True, file=sys.stderr)
198
+ sys.exit(1)
199
+
200
+ if __name__ == "__main__":
201
+ main()