Python API implements streaming interfaces (#577)

* Tech spec

* Python CLI utilities updated to use the API including streaming features

* Added type safety to Python API

* Completed missing auth token support in CLI
This commit is contained in:
cybermaggedon 2025-12-04 17:38:57 +00:00 committed by GitHub
parent b957004db9
commit 01aeede78b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
53 changed files with 4489 additions and 715 deletions

View file

@ -8,10 +8,11 @@ from trustgraph.api import Api
from trustgraph.api.types import ConfigKey
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def delete_config_item(url, config_type, key):
def delete_config_item(url, config_type, key, token=None):
api = Api(url).config()
api = Api(url, token=token).config()
config_key = ConfigKey(type=config_type, key=key)
api.delete([config_key])
@ -43,6 +44,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
@ -51,6 +58,7 @@ def main():
url=args.api_url,
config_type=args.type,
key=args.key,
token=args.token,
)
except Exception as e:

View file

@ -9,10 +9,11 @@ from trustgraph.api import Api
from trustgraph.api.types import ConfigKey
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def get_config_item(url, config_type, key, format_type):
def get_config_item(url, config_type, key, format_type, token=None):
api = Api(url).config()
api = Api(url, token=token).config()
config_key = ConfigKey(type=config_type, key=key)
values = api.get([config_key])
@ -59,6 +60,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
@ -68,6 +75,7 @@ def main():
config_type=args.type,
key=args.key,
format_type=args.format,
token=args.token,
)
except Exception as e:

View file

@ -14,6 +14,7 @@ import msgpack
default_url = os.getenv("TRUSTGRAPH_URL", 'ws://localhost:8088/')
default_user = 'trustgraph'
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def write_triple(f, data):
msg = (
@ -51,13 +52,16 @@ def write_ge(f, data):
)
f.write(msgpack.packb(msg, use_bin_type=True))
async def fetch(url, user, id, output):
async def fetch(url, user, id, output, token=None):
if not url.endswith("/"):
url += "/"
url = url + "api/v1/socket"
if token:
url = f"{url}?token={token}"
mid = str(uuid.uuid4())
async with connect(url) as ws:
@ -138,6 +142,12 @@ def main():
help=f'Output file'
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
@ -148,6 +158,7 @@ def main():
user = args.user,
id = args.id,
output = args.output,
token = args.token,
)
)

View file

@ -5,12 +5,10 @@ Uses the agent service to answer a question
import argparse
import os
import textwrap
import uuid
import asyncio
import json
from websockets.asyncio.client import connect
from trustgraph.api import Api
default_url = os.getenv("TRUSTGRAPH_URL", 'ws://localhost:8088/')
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
default_user = 'trustgraph'
default_collection = 'default'
@ -99,79 +97,47 @@ def output(text, prefix="> ", width=78):
)
print(out)
async def question(
def question(
url, question, flow_id, user, collection,
plan=None, state=None, group=None, verbose=False, streaming=True
plan=None, state=None, group=None, verbose=False, streaming=True,
token=None
):
if not url.endswith("/"):
url += "/"
url = url + "api/v1/socket"
if verbose:
output(wrap(question), "\U00002753 ")
print()
# Track last chunk type and current outputter for streaming
last_chunk_type = None
current_outputter = None
# Create API client
api = Api(url=url, token=token)
socket = api.socket()
flow = socket.flow(flow_id)
def think(x):
if verbose:
output(wrap(x), "\U0001f914 ")
print()
# Prepare request parameters
request_params = {
"question": question,
"user": user,
"streaming": streaming,
}
def observe(x):
if verbose:
output(wrap(x), "\U0001f4a1 ")
print()
# Only add optional fields if they have values
if state is not None:
request_params["state"] = state
if group is not None:
request_params["group"] = group
mid = str(uuid.uuid4())
try:
# Call agent
response = flow.agent(**request_params)
async with connect(url) as ws:
# Handle streaming response
if streaming:
# Track last chunk type and current outputter for streaming
last_chunk_type = None
current_outputter = None
req = {
"id": mid,
"service": "agent",
"flow": flow_id,
"request": {
"question": question,
"user": user,
"history": [],
"streaming": streaming
}
}
# Only add optional fields if they have values
if state is not None:
req["request"]["state"] = state
if group is not None:
req["request"]["group"] = group
req = json.dumps(req)
await ws.send(req)
while True:
msg = await ws.recv()
obj = json.loads(msg)
if "error" in obj:
raise RuntimeError(obj["error"])
if obj["id"] != mid:
print("Ignore message")
continue
response = obj["response"]
# Handle streaming format (new format with chunk_type)
if "chunk_type" in response:
chunk_type = response["chunk_type"]
content = response.get("content", "")
for chunk in response:
chunk_type = chunk.chunk_type
content = chunk.content
# Check if we're switching to a new message type
if last_chunk_type != chunk_type:
@ -195,33 +161,27 @@ async def question(
# Output the chunk
if current_outputter:
current_outputter.output(content)
elif chunk_type == "answer":
elif chunk_type == "final-answer":
print(content, end="", flush=True)
else:
# Handle legacy format (backward compatibility)
if "thought" in response:
think(response["thought"])
if "observation" in response:
observe(response["observation"])
# Close any remaining outputter
if current_outputter:
current_outputter.__exit__(None, None, None)
current_outputter = None
# Add final newline if we were outputting answer
elif last_chunk_type == "final-answer":
print()
if "answer" in response:
print(response["answer"])
else:
# Non-streaming response
if "answer" in response:
print(response["answer"])
if "error" in response:
raise RuntimeError(response["error"])
if "error" in response:
raise RuntimeError(response["error"])
if obj["complete"]:
# Close any remaining outputter
if current_outputter:
current_outputter.__exit__(None, None, None)
current_outputter = None
# Add final newline if we were outputting answer
elif last_chunk_type == "answer":
print()
break
await ws.close()
finally:
# Clean up socket connection
socket.close()
def main():
@ -236,6 +196,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-f', '--flow-id',
default="default",
@ -292,19 +258,18 @@ def main():
try:
asyncio.run(
question(
url = args.url,
flow_id = args.flow_id,
question = args.question,
user = args.user,
collection = args.collection,
plan = args.plan,
state = args.state,
group = args.group,
verbose = args.verbose,
streaming = not args.no_streaming,
)
question(
url = args.url,
flow_id = args.flow_id,
question = args.question,
user = args.user,
collection = args.collection,
plan = args.plan,
state = args.state,
group = args.group,
verbose = args.verbose,
streaming = not args.no_streaming,
token = args.token,
)
except Exception as e:

View file

@ -4,89 +4,50 @@ Uses the DocumentRAG service to answer a question
import argparse
import os
import asyncio
import json
import uuid
from websockets.asyncio.client import connect
from trustgraph.api import Api
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
default_user = 'trustgraph'
default_collection = 'default'
default_doc_limit = 10
async def question_streaming(url, flow_id, question, user, collection, doc_limit):
"""Streaming version using websockets"""
def question(url, flow_id, question, user, collection, doc_limit, streaming=True, token=None):
# Convert http:// to ws://
if url.startswith('http://'):
url = 'ws://' + url[7:]
elif url.startswith('https://'):
url = 'wss://' + url[8:]
# Create API client
api = Api(url=url, token=token)
if not url.endswith("/"):
url += "/"
if streaming:
# Use socket client for streaming
socket = api.socket()
flow = socket.flow(flow_id)
url = url + "api/v1/socket"
try:
response = flow.document_rag(
question=question,
user=user,
collection=collection,
doc_limit=doc_limit,
streaming=True
)
mid = str(uuid.uuid4())
# Stream output
for chunk in response:
print(chunk.content, end="", flush=True)
print() # Final newline
async with connect(url) as ws:
req = {
"id": mid,
"service": "document-rag",
"flow": flow_id,
"request": {
"query": question,
"user": user,
"collection": collection,
"doc-limit": doc_limit,
"streaming": True
}
}
req = json.dumps(req)
await ws.send(req)
while True:
msg = await ws.recv()
obj = json.loads(msg)
if "error" in obj:
raise RuntimeError(obj["error"])
if obj["id"] != mid:
print("Ignore message")
continue
response = obj["response"]
# Handle streaming format (chunk)
if "chunk" in response:
chunk = response["chunk"]
print(chunk, end="", flush=True)
elif "response" in response:
# Final response with complete text
# Already printed via chunks, just add newline
pass
if obj["complete"]:
print() # Final newline
break
await ws.close()
def question_non_streaming(url, flow_id, question, user, collection, doc_limit):
"""Non-streaming version using HTTP API"""
api = Api(url).flow().id(flow_id)
resp = api.document_rag(
question=question, user=user, collection=collection,
doc_limit=doc_limit,
)
print(resp)
finally:
socket.close()
else:
# Use REST API for non-streaming
flow = api.flow().id(flow_id)
resp = flow.document_rag(
question=question,
user=user,
collection=collection,
doc_limit=doc_limit,
)
print(resp)
def main():
@ -101,6 +62,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-f', '--flow-id',
default="default",
@ -127,6 +94,7 @@ def main():
parser.add_argument(
'-d', '--doc-limit',
type=int,
default=default_doc_limit,
help=f'Document limit (default: {default_doc_limit})'
)
@ -141,30 +109,20 @@ def main():
try:
if not args.no_streaming:
asyncio.run(
question_streaming(
url=args.url,
flow_id=args.flow_id,
question=args.question,
user=args.user,
collection=args.collection,
doc_limit=args.doc_limit,
)
)
else:
question_non_streaming(
url=args.url,
flow_id=args.flow_id,
question=args.question,
user=args.user,
collection=args.collection,
doc_limit=args.doc_limit,
)
question(
url=args.url,
flow_id=args.flow_id,
question=args.question,
user=args.user,
collection=args.collection,
doc_limit=args.doc_limit,
streaming=not args.no_streaming,
token=args.token,
)
except Exception as e:
print("Exception:", e, flush=True)
if __name__ == "__main__":
main()
main()

View file

@ -4,13 +4,10 @@ Uses the GraphRAG service to answer a question
import argparse
import os
import asyncio
import json
import uuid
from websockets.asyncio.client import connect
from trustgraph.api import Api
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
default_user = 'trustgraph'
default_collection = 'default'
default_entity_limit = 50
@ -18,89 +15,51 @@ default_triple_limit = 30
default_max_subgraph_size = 150
default_max_path_length = 2
async def question_streaming(
def question(
url, flow_id, question, user, collection, entity_limit, triple_limit,
max_subgraph_size, max_path_length
max_subgraph_size, max_path_length, streaming=True, token=None
):
"""Streaming version using websockets"""
# Convert http:// to ws://
if url.startswith('http://'):
url = 'ws://' + url[7:]
elif url.startswith('https://'):
url = 'wss://' + url[8:]
# Create API client
api = Api(url=url, token=token)
if not url.endswith("/"):
url += "/"
if streaming:
# Use socket client for streaming
socket = api.socket()
flow = socket.flow(flow_id)
url = url + "api/v1/socket"
try:
response = flow.graph_rag(
question=question,
user=user,
collection=collection,
entity_limit=entity_limit,
triple_limit=triple_limit,
max_subgraph_size=max_subgraph_size,
max_path_length=max_path_length,
streaming=True
)
mid = str(uuid.uuid4())
# Stream output
for chunk in response:
print(chunk.content, end="", flush=True)
print() # Final newline
async with connect(url) as ws:
req = {
"id": mid,
"service": "graph-rag",
"flow": flow_id,
"request": {
"query": question,
"user": user,
"collection": collection,
"entity-limit": entity_limit,
"triple-limit": triple_limit,
"max-subgraph-size": max_subgraph_size,
"max-path-length": max_path_length,
"streaming": True
}
}
req = json.dumps(req)
await ws.send(req)
while True:
msg = await ws.recv()
obj = json.loads(msg)
if "error" in obj:
raise RuntimeError(obj["error"])
if obj["id"] != mid:
print("Ignore message")
continue
response = obj["response"]
# Handle streaming format (chunk)
if "chunk" in response:
chunk = response["chunk"]
print(chunk, end="", flush=True)
elif "response" in response:
# Final response with complete text
# Already printed via chunks, just add newline
pass
if obj["complete"]:
print() # Final newline
break
await ws.close()
def question_non_streaming(
url, flow_id, question, user, collection, entity_limit, triple_limit,
max_subgraph_size, max_path_length
):
"""Non-streaming version using HTTP API"""
api = Api(url).flow().id(flow_id)
resp = api.graph_rag(
question=question, user=user, collection=collection,
entity_limit=entity_limit, triple_limit=triple_limit,
max_subgraph_size=max_subgraph_size,
max_path_length=max_path_length
)
print(resp)
finally:
socket.close()
else:
# Use REST API for non-streaming
flow = api.flow().id(flow_id)
resp = flow.graph_rag(
question=question,
user=user,
collection=collection,
entity_limit=entity_limit,
triple_limit=triple_limit,
max_subgraph_size=max_subgraph_size,
max_path_length=max_path_length
)
print(resp)
def main():
@ -115,6 +74,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-f', '--flow-id',
default="default",
@ -141,24 +106,28 @@ def main():
parser.add_argument(
'-e', '--entity-limit',
type=int,
default=default_entity_limit,
help=f'Entity limit (default: {default_entity_limit})'
)
parser.add_argument(
'-t', '--triple-limit',
'--triple-limit',
type=int,
default=default_triple_limit,
help=f'Triple limit (default: {default_triple_limit})'
)
parser.add_argument(
'-s', '--max-subgraph-size',
type=int,
default=default_max_subgraph_size,
help=f'Max subgraph size (default: {default_max_subgraph_size})'
)
parser.add_argument(
'-p', '--max-path-length',
type=int,
default=default_max_path_length,
help=f'Max path length (default: {default_max_path_length})'
)
@ -173,36 +142,23 @@ def main():
try:
if not args.no_streaming:
asyncio.run(
question_streaming(
url=args.url,
flow_id=args.flow_id,
question=args.question,
user=args.user,
collection=args.collection,
entity_limit=args.entity_limit,
triple_limit=args.triple_limit,
max_subgraph_size=args.max_subgraph_size,
max_path_length=args.max_path_length,
)
)
else:
question_non_streaming(
url=args.url,
flow_id=args.flow_id,
question=args.question,
user=args.user,
collection=args.collection,
entity_limit=args.entity_limit,
triple_limit=args.triple_limit,
max_subgraph_size=args.max_subgraph_size,
max_path_length=args.max_path_length,
)
question(
url=args.url,
flow_id=args.flow_id,
question=args.question,
user=args.user,
collection=args.collection,
entity_limit=args.entity_limit,
triple_limit=args.triple_limit,
max_subgraph_size=args.max_subgraph_size,
max_path_length=args.max_path_length,
streaming=not args.no_streaming,
token=args.token,
)
except Exception as e:
print("Exception:", e, flush=True)
if __name__ == "__main__":
main()
main()

View file

@ -5,64 +5,39 @@ and user prompt. Both arguments are required.
import argparse
import os
import json
import uuid
import asyncio
from websockets.asyncio.client import connect
from trustgraph.api import Api
default_url = os.getenv("TRUSTGRAPH_URL", 'ws://localhost:8088/')
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
async def query(url, flow_id, system, prompt, streaming=True):
def query(url, flow_id, system, prompt, streaming=True, token=None):
if not url.endswith("/"):
url += "/"
# Create API client
api = Api(url=url, token=token)
socket = api.socket()
flow = socket.flow(flow_id)
url = url + "api/v1/socket"
try:
# Call text completion
response = flow.text_completion(
system=system,
prompt=prompt,
streaming=streaming
)
mid = str(uuid.uuid4())
if streaming:
# Stream output to stdout without newline
for chunk in response:
print(chunk.content, end="", flush=True)
# Add final newline after streaming
print()
else:
# Non-streaming: print complete response
print(response)
async with connect(url) as ws:
req = {
"id": mid,
"service": "text-completion",
"flow": flow_id,
"request": {
"system": system,
"prompt": prompt,
"streaming": streaming
}
}
await ws.send(json.dumps(req))
while True:
msg = await ws.recv()
obj = json.loads(msg)
if "error" in obj:
raise RuntimeError(obj["error"])
if obj["id"] != mid:
continue
if "response" in obj["response"]:
if streaming:
# Stream output to stdout without newline
print(obj["response"]["response"], end="", flush=True)
else:
# Non-streaming: print complete response
print(obj["response"]["response"])
if obj["complete"]:
if streaming:
# Add final newline after streaming
print()
break
await ws.close()
finally:
# Clean up socket connection
socket.close()
def main():
@ -77,6 +52,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'system',
nargs=1,
@ -105,17 +86,18 @@ def main():
try:
asyncio.run(query(
query(
url=args.url,
flow_id=args.flow_id,
system=args.system[0],
prompt=args.prompt[0],
streaming=not args.no_streaming
))
streaming=not args.no_streaming,
token=args.token,
)
except Exception as e:
print("Exception:", e, flush=True)
if __name__ == "__main__":
main()
main()

View file

@ -10,76 +10,61 @@ using key=value arguments on the command line, and these replace
import argparse
import os
import json
import uuid
import asyncio
from websockets.asyncio.client import connect
from trustgraph.api import Api
default_url = os.getenv("TRUSTGRAPH_URL", 'ws://localhost:8088/')
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
async def query(url, flow_id, template_id, variables, streaming=True):
def query(url, flow_id, template_id, variables, streaming=True, token=None):
if not url.endswith("/"):
url += "/"
# Create API client
api = Api(url=url, token=token)
socket = api.socket()
flow = socket.flow(flow_id)
url = url + "api/v1/socket"
try:
# Call prompt
response = flow.prompt(
id=template_id,
variables=variables,
streaming=streaming
)
mid = str(uuid.uuid4())
if streaming:
full_response = {"text": "", "object": ""}
async with connect(url) as ws:
# Stream output
for chunk in response:
content = chunk.content
if content:
print(content, end="", flush=True)
full_response["text"] += content
req = {
"id": mid,
"service": "prompt",
"flow": flow_id,
"request": {
"id": template_id,
"variables": variables,
"streaming": streaming
}
}
# Check if this is an object response (JSON)
if hasattr(chunk, 'object') and chunk.object:
full_response["object"] = chunk.object
await ws.send(json.dumps(req))
# Handle final output
if full_response["text"]:
# Add final newline after streaming text
print()
elif full_response["object"]:
# Print JSON object (pretty-printed)
print(json.dumps(json.loads(full_response["object"]), indent=4))
full_response = {"text": "", "object": ""}
while True:
msg = await ws.recv()
obj = json.loads(msg)
if "error" in obj:
raise RuntimeError(obj["error"])
if obj["id"] != mid:
continue
response = obj["response"]
# Handle text responses (streaming)
if "text" in response and response["text"]:
if streaming:
# Stream output to stdout without newline
print(response["text"], end="", flush=True)
full_response["text"] += response["text"]
else:
# Non-streaming: print complete response
else:
# Non-streaming: handle response
if isinstance(response, str):
print(response)
elif isinstance(response, dict):
if "text" in response:
print(response["text"])
elif "object" in response:
print(json.dumps(json.loads(response["object"]), indent=4))
# Handle object responses (JSON, never streamed)
if "object" in response and response["object"]:
full_response["object"] = response["object"]
if obj["complete"]:
if streaming and full_response["text"]:
# Add final newline after streaming text
print()
elif full_response["object"]:
# Print JSON object (pretty-printed)
print(json.dumps(json.loads(full_response["object"]), indent=4))
break
await ws.close()
finally:
# Clean up socket connection
socket.close()
def main():
@ -94,6 +79,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-f', '--flow-id',
default="default",
@ -135,17 +126,18 @@ specified multiple times''',
try:
asyncio.run(query(
query(
url=args.url,
flow_id=args.flow_id,
template_id=args.id[0],
variables=variables,
streaming=not args.no_streaming
))
streaming=not args.no_streaming,
token=args.token,
)
except Exception as e:
print("Exception:", e, flush=True)
if __name__ == "__main__":
main()
main()

View file

@ -8,10 +8,11 @@ import json
from trustgraph.api import Api
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def list_config_items(url, config_type, format_type):
def list_config_items(url, config_type, format_type, token=None):
api = Api(url).config()
api = Api(url, token=token).config()
keys = api.list(config_type)
@ -47,6 +48,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
@ -55,6 +62,7 @@ def main():
url=args.api_url,
config_type=args.type,
format_type=args.format,
token=args.token,
)
except Exception as e:

View file

@ -2,18 +2,17 @@
Loads triples and entity contexts into the knowledge graph.
"""
import asyncio
import argparse
import os
import time
import rdflib
import json
from websockets.asyncio.client import connect
from typing import List, Dict, Any
from typing import Iterator, Tuple
from trustgraph.api import Api, Triple
from trustgraph.log_level import LogLevel
default_url = os.getenv("TRUSTGRAPH_URL", 'ws://localhost:8088/')
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
default_user = 'trustgraph'
default_collection = 'default'
@ -26,108 +25,114 @@ class KnowledgeLoader:
user,
collection,
document_id,
url = default_url,
url=default_url,
token=None,
):
if not url.endswith("/"):
url += "/"
self.triples_url = url + f"api/v1/flow/{flow}/import/triples"
self.entity_contexts_url = url + f"api/v1/flow/{flow}/import/entity-contexts"
self.files = files
self.flow = flow
self.user = user
self.collection = collection
self.document_id = document_id
self.url = url
self.token = token
async def run(self):
try:
# Load triples first
async with connect(self.triples_url) as ws:
for file in self.files:
await self.load_triples(file, ws)
# Then load entity contexts
async with connect(self.entity_contexts_url) as ws:
for file in self.files:
await self.load_entity_contexts(file, ws)
except Exception as e:
print(e, flush=True)
async def load_triples(self, file, ws):
def load_triples_from_file(self, file) -> Iterator[Triple]:
"""Generator that yields Triple objects from a Turtle file"""
g = rdflib.Graph()
g.parse(file, format="turtle")
def Value(value, is_uri):
return { "v": value, "e": is_uri }
for e in g:
s = Value(value=str(e[0]), is_uri=True)
p = Value(value=str(e[1]), is_uri=True)
if type(e[2]) == rdflib.term.URIRef:
o = Value(value=str(e[2]), is_uri=True)
# Extract subject, predicate, object
s_value = str(e[0])
p_value = str(e[1])
# Check if object is a URI or literal
if isinstance(e[2], rdflib.term.URIRef):
o_value = str(e[2])
o_is_uri = True
else:
o = Value(value=str(e[2]), is_uri=False)
o_value = str(e[2])
o_is_uri = False
req = {
"metadata": {
"id": self.document_id,
"metadata": [],
"user": self.user,
"collection": self.collection
},
"triples": [
{
"s": s,
"p": p,
"o": o,
}
]
}
# Create Triple object
# Note: The Triple dataclass has 's', 'p', 'o' fields as strings
# The API will handle the metadata wrapping
yield Triple(s=s_value, p=p_value, o=o_value)
await ws.send(json.dumps(req))
async def load_entity_contexts(self, file, ws):
"""
Load entity contexts by extracting entities from the RDF graph
and generating contextual descriptions based on their relationships.
"""
def load_entity_contexts_from_file(self, file) -> Iterator[Tuple[str, str]]:
"""Generator that yields (entity, context) tuples from a Turtle file"""
g = rdflib.Graph()
g.parse(file, format="turtle")
for s, p, o in g:
# If object is a URI, do nothing
# If object is a URI, skip (we only want literal contexts)
if isinstance(o, rdflib.term.URIRef):
continue
# If object is a literal, create entity context for subject with literal as context
# If object is a literal, create entity context for subject
s_str = str(s)
o_str = str(o)
req = {
"metadata": {
"id": self.document_id,
"metadata": [],
"user": self.user,
"collection": self.collection
},
"entities": [
{
"entity": {
"v": s_str,
"e": True
},
"context": o_str
yield (s_str, o_str)
def run(self):
"""Load triples and entity contexts using Python API"""
try:
# Create API client
api = Api(url=self.url, token=self.token)
bulk = api.bulk()
# Load triples from all files
print("Loading triples...")
for file in self.files:
print(f" Processing {file}...")
triples = self.load_triples_from_file(file)
bulk.import_triples(
flow=self.flow,
triples=triples,
metadata={
"id": self.document_id,
"metadata": [],
"user": self.user,
"collection": self.collection
}
]
}
)
await ws.send(json.dumps(req))
print("Triples loaded.")
# Load entity contexts from all files
print("Loading entity contexts...")
for file in self.files:
print(f" Processing {file}...")
# Convert tuples to the format expected by import_entity_contexts
def entity_context_generator():
for entity, context in self.load_entity_contexts_from_file(file):
yield {
"entity": {"v": entity, "e": True},
"context": context
}
bulk.import_entity_contexts(
flow=self.flow,
entities=entity_context_generator(),
metadata={
"id": self.document_id,
"metadata": [],
"user": self.user,
"collection": self.collection
}
)
print("Entity contexts loaded.")
except Exception as e:
print(f"Error: {e}", flush=True)
raise
def main():
@ -142,6 +147,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-i', '--document-id',
required=True,
@ -166,7 +177,6 @@ def main():
help=f'Collection ID (default: {default_collection})'
)
parser.add_argument(
'files', nargs='+',
help=f'Turtle files to load'
@ -178,15 +188,16 @@ def main():
try:
loader = KnowledgeLoader(
document_id = args.document_id,
url = args.api_url,
flow = args.flow_id,
files = args.files,
user = args.user,
collection = args.collection,
document_id=args.document_id,
url=args.api_url,
token=args.token,
flow=args.flow_id,
files=args.files,
user=args.user,
collection=args.collection,
)
asyncio.run(loader.run())
loader.run()
print("Triples and entity contexts loaded.")
break
@ -199,4 +210,4 @@ def main():
time.sleep(10)
if __name__ == "__main__":
main()
main()

View file

@ -13,6 +13,7 @@ from trustgraph.api.types import hash, Uri, Literal, Triple
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_user = 'trustgraph'
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
from requests.adapters import HTTPAdapter
@ -655,10 +656,10 @@ documents = [
class Loader:
def __init__(
self, url, user
self, url, user, token=None
):
self.api = Api(url).library()
self.api = Api(url, token=token).library()
self.user = user
def load(self, documents):
@ -719,6 +720,12 @@ def main():
help=f'User ID (default: {default_user})'
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
@ -726,6 +733,7 @@ def main():
p = Loader(
url=args.url,
user=args.user,
token=args.token,
)
p.load(documents)

View file

@ -22,6 +22,7 @@ import logging
logger = logging.getLogger(__name__)
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def load_structured_data(
@ -41,7 +42,8 @@ def load_structured_data(
user: str = 'trustgraph',
collection: str = 'default',
dry_run: bool = False,
verbose: bool = False
verbose: bool = False,
token: str = None
):
"""
Load structured data using a descriptor configuration.
@ -133,9 +135,9 @@ def load_structured_data(
# Get batch size from descriptor
batch_size = descriptor.get('output', {}).get('options', {}).get('batch_size', 1000)
# Send to TrustGraph using shared function
imported_count = _send_to_trustgraph(output_objects, api_url, flow, batch_size)
imported_count = _send_to_trustgraph(output_objects, api_url, flow, batch_size, token=token)
# Summary
format_info = descriptor.get('format', {})
@ -288,10 +290,10 @@ def load_structured_data(
# Get batch size from descriptor or use default
batch_size = descriptor.get('output', {}).get('options', {}).get('batch_size', 1000)
# Send to TrustGraph
print(f"🚀 Importing {len(output_records)} records to TrustGraph...")
imported_count = _send_to_trustgraph(output_records, api_url, flow, batch_size)
imported_count = _send_to_trustgraph(output_records, api_url, flow, batch_size, token=token)
# Get summary info from descriptor
format_info = descriptor.get('format', {})
@ -571,66 +573,30 @@ def _process_data_pipeline(input_file, descriptor_file, user, collection, sample
return output_records, descriptor
def _send_to_trustgraph(objects, api_url, flow, batch_size=1000):
"""Send ExtractedObject records to TrustGraph using WebSocket"""
import json
import asyncio
from websockets.asyncio.client import connect
def _send_to_trustgraph(objects, api_url, flow, batch_size=1000, token=None):
"""Send ExtractedObject records to TrustGraph using Python API"""
from trustgraph.api import Api
try:
# Construct objects import URL similar to load_knowledge pattern
if not api_url.endswith("/"):
api_url += "/"
# Convert HTTP URL to WebSocket URL if needed
ws_url = api_url.replace("http://", "ws://").replace("https://", "wss://")
objects_url = ws_url + f"api/v1/flow/{flow}/import/objects"
logger.info(f"Connecting to objects import endpoint: {objects_url}")
async def import_objects():
async with connect(objects_url) as ws:
imported_count = 0
for record in objects:
try:
# Send individual ExtractedObject records
await ws.send(json.dumps(record))
imported_count += 1
if imported_count % 100 == 0:
logger.debug(f"Imported {imported_count}/{len(objects)} records...")
except Exception as e:
logger.error(f"Failed to send record {imported_count + 1}: {e}")
print(f"❌ Failed to send record {imported_count + 1}: {e}")
logger.info(f"Successfully imported {imported_count} records to TrustGraph")
return imported_count
# Run the async import
imported_count = asyncio.run(import_objects())
# Summary
total_records = len(objects)
failed_count = total_records - imported_count
logger.info(f"Importing {total_records} records to TrustGraph...")
# Use Python API bulk import
api = Api(api_url, token=token)
bulk = api.bulk()
bulk.import_objects(flow=flow, objects=iter(objects))
logger.info(f"Successfully imported {total_records} records to TrustGraph")
# Summary
print(f"\n📊 Import Summary:")
print(f"- Total records: {total_records}")
print(f"- Successfully imported: {imported_count}")
print(f"- Failed: {failed_count}")
if failed_count > 0:
print(f"⚠️ {failed_count} records failed to import. Check logs for details.")
else:
print("✅ All records imported successfully!")
return imported_count
except ImportError as e:
logger.error(f"Failed to import required modules: {e}")
print(f"Error: Required modules not available - {e}")
raise
print(f"- Successfully imported: {total_records}")
print("✅ All records imported successfully!")
return total_records
except Exception as e:
logger.error(f"Failed to import data to TrustGraph: {e}")
print(f"Import failed: {e}")
@ -1024,7 +990,13 @@ For more information on the descriptor format, see:
'--error-file',
help='Path to write error records (optional)'
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
# Input validation
@ -1077,7 +1049,8 @@ For more information on the descriptor format, see:
user=args.user,
collection=args.collection,
dry_run=args.dry_run,
verbose=args.verbose
verbose=args.verbose,
token=args.token
)
except FileNotFoundError as e:
print(f"Error: File not found - {e}", file=sys.stderr)

View file

@ -1,18 +1,18 @@
"""
Loads triples into the knowledge graph.
Loads triples into the knowledge graph from Turtle files.
"""
import asyncio
import argparse
import os
import time
import rdflib
import json
from websockets.asyncio.client import connect
from typing import Iterator
from trustgraph.api import Api, Triple
from trustgraph.log_level import LogLevel
default_url = os.getenv("TRUSTGRAPH_URL", 'ws://localhost:8088/')
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
default_user = 'trustgraph'
default_collection = 'default'
@ -25,67 +25,67 @@ class Loader:
user,
collection,
document_id,
url = default_url,
url=default_url,
token=None,
):
if not url.endswith("/"):
url += "/"
url = url + f"api/v1/flow/{flow}/import/triples"
self.url = url
self.files = files
self.flow = flow
self.user = user
self.collection = collection
self.document_id = document_id
self.url = url
self.token = token
async def run(self):
try:
async with connect(self.url) as ws:
for file in self.files:
await self.load_file(file, ws)
except Exception as e:
print(e, flush=True)
async def load_file(self, file, ws):
def load_triples_from_file(self, file) -> Iterator[Triple]:
"""Generator that yields Triple objects from a Turtle file"""
g = rdflib.Graph()
g.parse(file, format="turtle")
def Value(value, is_uri):
return { "v": value, "e": is_uri }
triples = []
for e in g:
s = Value(value=str(e[0]), is_uri=True)
p = Value(value=str(e[1]), is_uri=True)
if type(e[2]) == rdflib.term.URIRef:
o = Value(value=str(e[2]), is_uri=True)
# Extract subject, predicate, object
s_value = str(e[0])
p_value = str(e[1])
# Check if object is a URI or literal
if isinstance(e[2], rdflib.term.URIRef):
o_value = str(e[2])
else:
o = Value(value=str(e[2]), is_uri=False)
o_value = str(e[2])
req = {
"metadata": {
"id": self.document_id,
"metadata": [],
"user": self.user,
"collection": self.collection
},
"triples": [
{
"s": s,
"p": p,
"o": o,
# Create Triple object
yield Triple(s=s_value, p=p_value, o=o_value)
def run(self):
"""Load triples using Python API"""
try:
# Create API client
api = Api(url=self.url, token=self.token)
bulk = api.bulk()
# Load triples from all files
print("Loading triples...")
for file in self.files:
print(f" Processing {file}...")
triples = self.load_triples_from_file(file)
bulk.import_triples(
flow=self.flow,
triples=triples,
metadata={
"id": self.document_id,
"metadata": [],
"user": self.user,
"collection": self.collection
}
]
}
)
await ws.send(json.dumps(req))
print("Triples loaded.")
except Exception as e:
print(f"Error: {e}", flush=True)
raise
def main():
@ -100,6 +100,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-i', '--document-id',
required=True,
@ -134,16 +140,17 @@ def main():
while True:
try:
p = Loader(
document_id = args.document_id,
url = args.api_url,
flow = args.flow_id,
files = args.files,
user = args.user,
collection = args.collection,
loader = Loader(
document_id=args.document_id,
url=args.api_url,
token=args.token,
flow=args.flow_id,
files=args.files,
user=args.user,
collection=args.collection,
)
asyncio.run(p.run())
loader.run()
print("File loaded.")
break
@ -156,4 +163,4 @@ def main():
time.sleep(10)
if __name__ == "__main__":
main()
main()

View file

@ -9,10 +9,11 @@ from trustgraph.api import Api
from trustgraph.api.types import ConfigValue
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def put_config_item(url, config_type, key, value):
def put_config_item(url, config_type, key, value, token=None):
api = Api(url).config()
api = Api(url, token=token).config()
config_value = ConfigValue(type=config_type, key=key, value=value)
api.put([config_value])
@ -56,6 +57,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
@ -70,6 +77,7 @@ def main():
config_type=args.type,
key=args.key,
value=value,
token=args.token,
)
except Exception as e:

View file

@ -9,10 +9,11 @@ from trustgraph.api import Api
import json
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def put_flow_class(url, class_name, config):
def put_flow_class(url, class_name, config, token=None):
api = Api(url)
api = Api(url, token=token)
class_names = api.flow().put_class(class_name, config)
@ -29,6 +30,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-n', '--class-name',
help=f'Flow class name',
@ -47,6 +54,7 @@ def main():
url=args.api_url,
class_name=args.class_name,
config=json.loads(args.config),
token=args.token,
)
except Exception as e:

View file

@ -13,6 +13,7 @@ import msgpack
default_url = os.getenv("TRUSTGRAPH_URL", 'ws://localhost:8088/')
default_user = 'trustgraph'
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def read_message(unpacked, id, user):
@ -47,13 +48,16 @@ def read_message(unpacked, id, user):
else:
raise RuntimeError("Unpacked unexpected messsage type", unpacked[0])
async def put(url, user, id, input):
async def put(url, user, id, input, token=None):
if not url.endswith("/"):
url += "/"
url = url + "api/v1/socket"
if token:
url = f"{url}?token={token}"
async with connect(url) as ws:
@ -160,6 +164,12 @@ def main():
help=f'Input file'
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
@ -170,6 +180,7 @@ def main():
user = args.user,
id = args.id,
input = args.input,
token = args.token,
)
)

View file

@ -10,11 +10,12 @@ from trustgraph.api import Api
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_user = 'trustgraph'
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def remove_doc(url, user, id):
def remove_doc(url, user, id, token=None):
api = Api(url).library()
api = Api(url, token=token).library()
api.remove_document(user=user, id=id)
@ -43,11 +44,17 @@ def main():
help=f'Document ID'
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
remove_doc(args.url, args.user, args.identifier)
remove_doc(args.url, args.user, args.identifier, token=args.token)
except Exception as e:

View file

@ -9,10 +9,11 @@ from trustgraph.api import Api
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_user = "trustgraph"
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def set_collection(url, user, collection, name, description, tags):
def set_collection(url, user, collection, name, description, tags, token=None):
api = Api(url).collection()
api = Api(url, token=token).collection()
result = api.update_collection(
user=user,
@ -82,6 +83,12 @@ def main():
help='Collection tags (can be specified multiple times)'
)
parser.add_argument(
'--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
@ -92,7 +99,8 @@ def main():
collection = args.collection,
name = args.name,
description = args.description,
tags = args.tags
tags = args.tags,
token = args.token
)
except Exception as e:

View file

@ -20,6 +20,7 @@ import textwrap
import json
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def set_mcp_tool(
url : str,
@ -27,9 +28,10 @@ def set_mcp_tool(
remote_name : str,
tool_url : str,
auth_token : str = None,
token : str = None,
):
api = Api(url).config()
api = Api(url, token=token).config()
# Build the MCP tool configuration
config = {
@ -72,6 +74,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-i', '--id',
required=True,
@ -116,7 +124,8 @@ def main():
id=args.id,
remote_name=remote_name,
tool_url=args.tool_url,
auth_token=args.auth_token
auth_token=args.auth_token,
token=args.token,
)
except Exception as e:

View file

@ -10,10 +10,11 @@ import tabulate
import textwrap
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def set_system(url, system):
def set_system(url, system, token=None):
api = Api(url).config()
api = Api(url, token=token).config()
api.put([
ConfigValue(type="prompt", key="system", value=json.dumps(system))
@ -21,9 +22,9 @@ def set_system(url, system):
print("System prompt set.")
def set_prompt(url, id, prompt, response, schema):
def set_prompt(url, id, prompt, response, schema, token=None):
api = Api(url).config()
api = Api(url, token=token).config()
values = api.get([
ConfigKey(type="prompt", key="template-index")
@ -71,6 +72,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'--id',
help=f'Prompt ID',
@ -103,9 +110,9 @@ def main():
if args.system:
if args.id or args.prompt or args.schema or args.response:
raise RuntimeError("Can't use --system with other args")
set_system(
url=args.api_url, system=args.system
url=args.api_url, system=args.system, token=args.token
)
else:
@ -130,7 +137,7 @@ def main():
set_prompt(
url=args.api_url, id=args.id, prompt=args.prompt,
response=args.response, schema=schobj
response=args.response, schema=schobj, token=args.token
)
except Exception as e:

View file

@ -10,10 +10,11 @@ import tabulate
import textwrap
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def set_costs(api_url, model, input_costs, output_costs):
def set_costs(api_url, model, input_costs, output_costs, token=None):
api = Api(api_url).config()
api = Api(api_url, token=token).config()
api.put([
ConfigValue(
@ -95,6 +96,12 @@ def main():
help=f'Input costs in $ per 1M tokens',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:

View file

@ -26,6 +26,7 @@ import textwrap
import dataclasses
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
@dataclasses.dataclass
class Argument:
@ -67,9 +68,10 @@ def set_tool(
group : List[str],
state : str,
applicable_states : List[str],
token : str = None,
):
api = Api(url).config()
api = Api(url, token=token).config()
values = api.get([
ConfigKey(type="agent", key="tool-index")
@ -156,6 +158,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'--id',
help=f'Unique tool identifier',
@ -257,6 +265,7 @@ def main():
group=args.group,
state=args.state,
applicable_states=args.applicable_states,
token=args.token,
)
except Exception as e:

View file

@ -8,10 +8,11 @@ from trustgraph.api import Api
import json
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def show_config(url):
def show_config(url, token=None):
api = Api(url).config()
api = Api(url, token=token).config()
config, version = api.all()
@ -31,12 +32,19 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
show_config(
url=args.api_url,
token=args.token,
)
except Exception as e:

View file

@ -9,6 +9,7 @@ from trustgraph.api import Api, ConfigKey
import json
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def format_parameters(params_metadata, config_api):
"""
@ -57,9 +58,9 @@ def format_parameters(params_metadata, config_api):
return "\n".join(param_list)
def show_flow_classes(url):
def show_flow_classes(url, token=None):
api = Api(url)
api = Api(url, token=token)
flow_api = api.flow()
config_api = api.config()
@ -106,12 +107,19 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
show_flow_classes(
url=args.api_url,
token=args.token,
)
except Exception as e:

View file

@ -9,10 +9,11 @@ import os
default_metrics_url = "http://localhost:8088/api/metrics"
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def dump_status(metrics_url, api_url, flow_id):
def dump_status(metrics_url, api_url, flow_id, token=None):
api = Api(api_url).flow()
api = Api(api_url, token=token).flow()
flow = api.get(flow_id)
class_name = flow["class-name"]
@ -77,11 +78,17 @@ def main():
help=f'Metrics URL (default: {default_metrics_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
dump_status(args.metrics_url, args.api_url, args.flow_id)
dump_status(args.metrics_url, args.api_url, args.flow_id, token=args.token)
except Exception as e:

View file

@ -9,6 +9,7 @@ from trustgraph.api import Api, ConfigKey
import json
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def get_interface(config_api, i):
@ -128,9 +129,9 @@ def format_parameters(flow_params, class_params_metadata, config_api):
return "\n".join(param_list) if param_list else "None"
def show_flows(url):
def show_flows(url, token=None):
api = Api(url)
api = Api(url, token=token)
config_api = api.config()
flow_api = api.flow()
@ -199,12 +200,19 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
show_flows(
url=args.api_url,
token=args.token,
)
except Exception as e:

View file

@ -9,10 +9,11 @@ from trustgraph.api import Api
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_user = 'trustgraph'
default_collection = 'default'
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def show_graph(url, flow_id, user, collection):
def show_graph(url, flow_id, user, collection, token=None):
api = Api(url).flow().id(flow_id)
api = Api(url, token=token).flow().id(flow_id)
rows = api.triples_query(
user=user, collection=collection,
@ -53,6 +54,12 @@ def main():
help=f'Collection ID (default: {default_collection})'
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
@ -62,6 +69,7 @@ def main():
flow_id = args.flow_id,
user = args.user,
collection = args.collection,
token = args.token,
)
except Exception as e:

View file

@ -9,10 +9,11 @@ from trustgraph.api import Api, ConfigKey
import json
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def show_cores(url, user):
def show_cores(url, user, token=None):
api = Api(url).knowledge()
api = Api(url, token=token).knowledge()
ids = api.list_kg_cores()
@ -35,6 +36,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-U', '--user',
default="trustgraph",
@ -46,7 +53,9 @@ def main():
try:
show_cores(
url=args.api_url, user=args.user
url=args.api_url,
user=args.user,
token=args.token,
)
except Exception as e:

View file

@ -9,11 +9,12 @@ from trustgraph.api import Api, ConfigKey
import json
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
default_user = "trustgraph"
def show_docs(url, user):
def show_docs(url, user, token=None):
api = Api(url).library()
api = Api(url, token=token).library()
docs = api.get_documents(user=user)
@ -52,6 +53,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-U', '--user',
default=default_user,
@ -63,7 +70,9 @@ def main():
try:
show_docs(
url = args.api_url, user = args.user
url = args.api_url,
user = args.user,
token = args.token,
)
except Exception as e:

View file

@ -9,10 +9,11 @@ import json
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_user = "trustgraph"
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def show_procs(url, user):
def show_procs(url, user, token=None):
api = Api(url).library()
api = Api(url, token=token).library()
procs = api.get_processings(user = user)
@ -57,12 +58,18 @@ def main():
help=f'User ID (default: {default_user})'
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
show_procs(
url = args.api_url, user = args.user
url = args.api_url, user = args.user, token = args.token
)
except Exception as e:

View file

@ -10,10 +10,11 @@ import tabulate
import textwrap
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def show_config(url):
def show_config(url, token=None):
api = Api(url).config()
api = Api(url, token=token).config()
values = api.get_values(type="mcp")
@ -57,12 +58,19 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
show_config(
url=args.api_url,
token=args.token,
)
except Exception as e:

View file

@ -13,6 +13,7 @@ from trustgraph.api import Api, ConfigKey
import json
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def format_enum_values(enum_list):
"""
@ -75,11 +76,11 @@ def format_constraints(param_type_def):
return ", ".join(constraints) if constraints else "None"
def show_parameter_types(url):
def show_parameter_types(url, token=None):
"""
Show all parameter type definitions
"""
api = Api(url)
api = Api(url, token=token)
config_api = api.config()
# Get list of all parameter types
@ -145,6 +146,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-t', '--type',
help='Show only the specified parameter type',
@ -155,19 +162,19 @@ def main():
try:
if args.type:
# Show specific parameter type
show_specific_parameter_type(args.api_url, args.type)
show_specific_parameter_type(args.api_url, args.type, args.token)
else:
# Show all parameter types
show_parameter_types(args.api_url)
show_parameter_types(args.api_url, args.token)
except Exception as e:
print("Exception:", e, flush=True)
def show_specific_parameter_type(url, param_type_name):
def show_specific_parameter_type(url, param_type_name, token=None):
"""
Show a specific parameter type definition
"""
api = Api(url)
api = Api(url, token=token)
config_api = api.config()
try:

View file

@ -10,10 +10,11 @@ import tabulate
import textwrap
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def show_config(url):
def show_config(url, token=None):
api = Api(url).config()
api = Api(url, token=token).config()
values = api.get([
ConfigKey(type="prompt", key="system"),
@ -78,12 +79,19 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
show_config(
url=args.api_url,
token=args.token,
)
except Exception as e:

View file

@ -12,10 +12,11 @@ import textwrap
tabulate.PRESERVE_WHITESPACE = True
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def show_config(url):
def show_config(url, token=None):
api = Api(url).config()
api = Api(url, token=token).config()
models = api.list("token-costs")
@ -61,12 +62,19 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
show_config(
url=args.api_url,
token=args.token,
)
except Exception as e:

View file

@ -17,10 +17,11 @@ import tabulate
import textwrap
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def show_config(url):
def show_config(url, token=None):
api = Api(url).config()
api = Api(url, token=token).config()
values = api.get_values(type="tool")
@ -100,12 +101,19 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
args = parser.parse_args()
try:
show_config(
url=args.api_url,
token=args.token,
)
except Exception as e:

View file

@ -17,10 +17,11 @@ from trustgraph.api import Api
import json
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def start_flow(url, class_name, flow_id, description, parameters=None):
def start_flow(url, class_name, flow_id, description, parameters=None, token=None):
api = Api(url).flow()
api = Api(url, token=token).flow()
api.start(
class_name = class_name,
@ -42,6 +43,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-n', '--class-name',
required=True,
@ -112,6 +119,7 @@ def main():
flow_id = args.flow_id,
description = args.description,
parameters = parameters,
token = args.token,
)
except Exception as e:

View file

@ -9,13 +9,14 @@ from trustgraph.api import Api, ConfigKey
import json
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
default_user = "trustgraph"
def start_processing(
url, user, document_id, id, flow, collection, tags
url, user, document_id, id, flow, collection, tags, token=None
):
api = Api(url).library()
api = Api(url, token=token).library()
if tags:
tags = tags.split(",")
@ -44,6 +45,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-U', '--user',
default=default_user,
@ -90,7 +97,8 @@ def main():
id = args.id,
flow = args.flow_id,
collection = args.collection,
tags = args.tags
tags = args.tags,
token = args.token,
)
except Exception as e:

View file

@ -9,10 +9,11 @@ from trustgraph.api import Api
import json
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
def stop_flow(url, flow_id):
def stop_flow(url, flow_id, token=None):
api = Api(url).flow()
api = Api(url, token=token).flow()
api.stop(id = flow_id)
@ -29,6 +30,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-i', '--flow-id',
required=True,
@ -42,6 +49,7 @@ def main():
stop_flow(
url=args.api_url,
flow_id=args.flow_id,
token=args.token,
)
except Exception as e:

View file

@ -10,13 +10,14 @@ from trustgraph.api import Api, ConfigKey
import json
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
default_user = "trustgraph"
def stop_processing(
url, user, id
url, user, id, token=None
):
api = Api(url).library()
api = Api(url, token=token).library()
api.stop_processing(user = user, id = id)
@ -33,6 +34,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-U', '--user',
default=default_user,
@ -53,6 +60,7 @@ def main():
url = args.api_url,
user = args.user,
id = args.id,
token = args.token,
)
except Exception as e:

View file

@ -11,12 +11,13 @@ from trustgraph.api import Api
import json
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
default_flow = "default"
default_collection = "default"
def unload_kg_core(url, user, id, flow):
def unload_kg_core(url, user, id, flow, token=None):
api = Api(url).knowledge()
api = Api(url, token=token).knowledge()
class_names = api.unload_kg_core(user = user, id = id, flow=flow)
@ -33,6 +34,12 @@ def main():
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-t', '--token',
default=default_token,
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
)
parser.add_argument(
'-U', '--user',
default="trustgraph",
@ -60,6 +67,7 @@ def main():
user=args.user,
id=args.id,
flow=args.flow_id,
token=args.token,
)
except Exception as e: