From 1a2f13154b69646bd2ec5d9acc2784deacde0cce Mon Sep 17 00:00:00 2001 From: imbajin Date: Tue, 20 Aug 2024 15:59:47 +0800 Subject: [PATCH] feat(llm): support graphspace & unify the port to str --- .../src/hugegraph_llm/api/rag_api.py | 4 +-- .../src/hugegraph_llm/config/config.py | 4 +-- .../src/hugegraph_llm/demo/rag_web_demo.py | 32 +++++++++---------- .../src/hugegraph_llm/indices/graph_index.py | 5 +-- .../hugegraph_op/commit_to_hugegraph.py | 1 + .../operators/hugegraph_op/graph_rag_query.py | 11 +++++-- .../operators/hugegraph_op/schema_manager.py | 3 +- .../hugegraph_llm/utils/hugegraph_utils.py | 5 ++- .../src/pyhugegraph/client.py | 2 +- .../pyhugegraph/example/hugegraph_example.py | 2 +- .../src/pyhugegraph/example/hugegraph_test.py | 4 +-- .../src/tests/client_utils.py | 5 +-- 12 files changed, 43 insertions(+), 35 deletions(-) diff --git a/hugegraph-llm/src/hugegraph_llm/api/rag_api.py b/hugegraph-llm/src/hugegraph_llm/api/rag_api.py index b6d80680..e5836192 100644 --- a/hugegraph-llm/src/hugegraph_llm/api/rag_api.py +++ b/hugegraph-llm/src/hugegraph_llm/api/rag_api.py @@ -17,10 +17,10 @@ from fastapi import status, APIRouter +from hugegraph_llm.api.exceptions.rag_exceptions import generate_response +from hugegraph_llm.api.models.rag_requests import RAGRequest, GraphConfigRequest, LLMConfigRequest from hugegraph_llm.api.models.rag_response import RAGResponse from hugegraph_llm.config import settings -from hugegraph_llm.api.models.rag_requests import RAGRequest, GraphConfigRequest, LLMConfigRequest -from hugegraph_llm.api.exceptions.rag_exceptions import generate_response def rag_http_api(router: APIRouter, rag_answer_func, apply_graph_conf, apply_llm_conf, apply_embedding_conf): diff --git a/hugegraph-llm/src/hugegraph_llm/config/config.py b/hugegraph-llm/src/hugegraph_llm/config/config.py index 3659cc1d..2fd8262b 100644 --- a/hugegraph-llm/src/hugegraph_llm/config/config.py +++ b/hugegraph-llm/src/hugegraph_llm/config/config.py @@ -66,11 +66,11 @@ class Config: """HugeGraph settings""" graph_ip: Optional[str] = "127.0.0.1" - graph_port: Optional[int] = 8080 - graph_space: Optional[str] = None + graph_port: Optional[str] = "8080" graph_name: Optional[str] = "hugegraph" graph_user: Optional[str] = "admin" graph_pwd: Optional[str] = "xxx" + graph_space: Optional[str] = None def from_env(self): if os.path.exists(env_path): diff --git a/hugegraph-llm/src/hugegraph_llm/demo/rag_web_demo.py b/hugegraph-llm/src/hugegraph_llm/demo/rag_web_demo.py index bafa6341..efc167f0 100644 --- a/hugegraph-llm/src/hugegraph_llm/demo/rag_web_demo.py +++ b/hugegraph-llm/src/hugegraph_llm/demo/rag_web_demo.py @@ -16,21 +16,23 @@ # under the License. -import os -import json import argparse +import json +import os from typing import List, Union -import requests -import uvicorn import docx import gradio as gr -from gradio.utils import NamedString +import requests +import uvicorn from fastapi import FastAPI, Depends, APIRouter from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials +from gradio.utils import NamedString from requests.auth import HTTPBasicAuth +from hugegraph_llm.api.rag_api import rag_http_api from hugegraph_llm.config import settings, resource_path +from hugegraph_llm.enums.build_mode import BuildMode from hugegraph_llm.models.embeddings.init_embedding import Embeddings from hugegraph_llm.models.llms.init_llm import LLMs from hugegraph_llm.operators.graph_rag_task import GraphRAG @@ -40,8 +42,6 @@ from hugegraph_llm.utils.hugegraph_utils import init_hg_test_data, run_gremlin_query, clean_hg_data from hugegraph_llm.utils.log import log from hugegraph_llm.utils.vector_index_utils import clean_vector_index -from hugegraph_llm.api.rag_api import rag_http_api -from hugegraph_llm.enums.build_mode import BuildMode sec = HTTPBearer() @@ -89,7 +89,7 @@ def rag_answer( except ValueError as e: log.error(e) raise gr.Error(str(e)) - except Exception as e: # pylint: disable=broad-exception-caught + except Exception as e: log.error(e) raise gr.Error(f"An unexpected error occurred: {str(e)}") @@ -220,7 +220,6 @@ def apply_embedding_config(arg1, arg2, arg3, origin_call=None) -> int: settings.ollama_host = arg1 settings.ollama_port = int(arg2) settings.ollama_embedding_model = arg3 - # TODO: right way to test ollama conn? status_code = test_api_connection(f"http://{arg1}:{arg2}", origin_call=origin_call) settings.update_env() gr.Info("Configured!") @@ -229,7 +228,7 @@ def apply_embedding_config(arg1, arg2, arg3, origin_call=None) -> int: def apply_graph_config(ip, port, name, user, pwd, gs, origin_call=None) -> int: settings.graph_ip = ip - settings.graph_port = int(port) + settings.graph_port = port settings.graph_name = name settings.graph_user = user settings.graph_pwd = pwd @@ -265,15 +264,16 @@ def apply_llm_config(arg1, arg2, arg3, arg4, origin_call=None) -> int: settings.ollama_host = arg1 settings.ollama_port = int(arg2) settings.ollama_language_model = arg3 - # TODO: right way to test ollama conn? - status_code = test_api_connection(f"http://{arg1}:{arg2}/status", origin_call=origin_call) + status_code = test_api_connection(f"http://{arg1}:{arg2}", origin_call=origin_call) gr.Info("Configured!") settings.update_env() return status_code def init_rag_ui() -> gr.Interface: - with gr.Blocks(title="HugeGraph LLM") as hugegraph_llm_ui: + with gr.Blocks(theme='default', + title="HugeGraph RAG Platform", + css="footer {visibility: hidden}") as hugegraph_llm_ui: gr.Markdown( """# HugeGraph LLM RAG Demo 1. Set up the HugeGraph server.""" @@ -281,13 +281,11 @@ def init_rag_ui() -> gr.Interface: with gr.Row(): graph_config_input = [ gr.Textbox(value=settings.graph_ip, label="ip"), - gr.Textbox(value=str(settings.graph_port), label="port"), + gr.Textbox(value=settings.graph_port, label="port"), gr.Textbox(value=settings.graph_name, label="graph"), gr.Textbox(value=settings.graph_user, label="user"), gr.Textbox(value=settings.graph_pwd, label="pwd", type="password"), - # gr.Textbox(value=settings.graph_space, label="graphspace (None)"), - # wip: graph_space issue pending - gr.Textbox(value="", label="graphspace (None)"), + gr.Textbox(value=settings.graph_space, label="graphspace(Optional)"), ] graph_config_button = gr.Button("apply configuration") diff --git a/hugegraph-llm/src/hugegraph_llm/indices/graph_index.py b/hugegraph-llm/src/hugegraph_llm/indices/graph_index.py index 74269fcb..996c25c2 100644 --- a/hugegraph-llm/src/hugegraph_llm/indices/graph_index.py +++ b/hugegraph-llm/src/hugegraph_llm/indices/graph_index.py @@ -26,12 +26,13 @@ class GraphIndex: def __init__( self, graph_ip: Optional[str] = settings.graph_ip, - graph_port: Optional[int] = settings.graph_port, + graph_port: Optional[str] = settings.graph_port, graph_name: Optional[str] = settings.graph_name, graph_user: Optional[str] = settings.graph_user, graph_pwd: Optional[str] = settings.graph_pwd, + graph_space: Optional[str] = settings.graph_space, ): - self.client = PyHugeClient(graph_ip, graph_port, graph_name, graph_user, graph_pwd) + self.client = PyHugeClient(graph_ip, graph_port, graph_name, graph_user, graph_pwd, graph_space) def clear_graph(self): self.client.gremlin().exec("g.V().drop()") diff --git a/hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/commit_to_hugegraph.py b/hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/commit_to_hugegraph.py index b4ad640d..cf252e25 100644 --- a/hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/commit_to_hugegraph.py +++ b/hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/commit_to_hugegraph.py @@ -32,6 +32,7 @@ def __init__(self): settings.graph_name, settings.graph_user, settings.graph_pwd, + settings.graph_space, ) self.schema = self.client.schema() diff --git a/hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/graph_rag_query.py b/hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/graph_rag_query.py index 63193876..5f18d3cc 100644 --- a/hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/graph_rag_query.py +++ b/hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/graph_rag_query.py @@ -27,6 +27,11 @@ class GraphRAGQuery: VERTEX_GREMLIN_QUERY_TEMPL = ( "g.V().hasId({keywords}).as('subj').toList()" ) + # ID_RAG_GREMLIN_QUERY_TEMPL = "g.V().hasId({keywords}).as('subj').repeat(bothE({edge_labels}).as('rel').otherV( + # ).as('obj')).times({max_deep}).path().by(project('label', 'id', 'props').by(label()).by(id()).by(valueMap().by( + # unfold()))).by(project('label', 'inV', 'outV', 'props').by(label()).by(inV().id()).by(outV().id()).by(valueMap( + # ).by(unfold()))).limit({max_items}).toList()" + # TODO: we could use a simpler query (like kneighbor-api to get the edges) ID_RAG_GREMLIN_QUERY_TEMPL = """ g.V().hasId({keywords}).as('subj') @@ -81,6 +86,7 @@ def __init__( settings.graph_name, settings.graph_user, settings.graph_pwd, + settings.graph_space, ) self._max_deep = max_deep self._max_items = max_items @@ -93,11 +99,12 @@ def run(self, context: Dict[str, Any]) -> Dict[str, Any]: self._client = context["graph_client"] else: ip = context.get("ip") or "localhost" - port = context.get("port") or 8080 + port = context.get("port") or "8080" graph = context.get("graph") or "hugegraph" user = context.get("user") or "admin" pwd = context.get("pwd") or "admin" - self._client = PyHugeClient(ip=ip, port=port, graph=graph, user=user, pwd=pwd) + gs = context.get("graphspace") or None + self._client = PyHugeClient(ip, port, graph, user, pwd, gs) assert self._client is not None, "No valid graph to search." keywords = context.get("keywords") diff --git a/hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/schema_manager.py b/hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/schema_manager.py index 78c06a5c..5c002ae2 100644 --- a/hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/schema_manager.py +++ b/hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/schema_manager.py @@ -29,10 +29,11 @@ def __init__(self, graph_name: str): self.graph_name, settings.graph_user, settings.graph_pwd, + settings.graph_space, ) self.schema = self.client.schema() - def run(self, data: dict): + def run(self): schema = self.schema.getSchema() vertices = [] for vl in schema["vertexlabels"]: diff --git a/hugegraph-llm/src/hugegraph_llm/utils/hugegraph_utils.py b/hugegraph-llm/src/hugegraph_llm/utils/hugegraph_utils.py index d942bf93..3320efa6 100644 --- a/hugegraph-llm/src/hugegraph_llm/utils/hugegraph_utils.py +++ b/hugegraph-llm/src/hugegraph_llm/utils/hugegraph_utils.py @@ -32,6 +32,7 @@ def get_hg_client(): settings.graph_name, settings.graph_user, settings.graph_pwd, + settings.graph_space, ) @@ -41,9 +42,7 @@ def init_hg_test_data(): schema = client.schema() schema.propertyKey("name").asText().ifNotExist().create() schema.propertyKey("birthDate").asText().ifNotExist().create() - schema.vertexLabel("Person").properties( - "name", "birthDate" - ).useCustomizeStringId().ifNotExist().create() + schema.vertexLabel("Person").properties("name", "birthDate").useCustomizeStringId().ifNotExist().create() schema.vertexLabel("Movie").properties("name").useCustomizeStringId().ifNotExist().create() schema.edgeLabel("ActedIn").sourceLabel("Person").targetLabel("Movie").ifNotExist().create() diff --git a/hugegraph-python-client/src/pyhugegraph/client.py b/hugegraph-python-client/src/pyhugegraph/client.py index c8547149..241fe8e8 100644 --- a/hugegraph-python-client/src/pyhugegraph/client.py +++ b/hugegraph-python-client/src/pyhugegraph/client.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -from typing import Any, Callable, Optional, TypeVar +from typing import Any, Callable, Optional, TypeVar, Type from pyhugegraph.api.auth import AuthManager from pyhugegraph.api.graph import GraphManager diff --git a/hugegraph-python-client/src/pyhugegraph/example/hugegraph_example.py b/hugegraph-python-client/src/pyhugegraph/example/hugegraph_example.py index d58190e2..15ce868d 100644 --- a/hugegraph-python-client/src/pyhugegraph/example/hugegraph_example.py +++ b/hugegraph-python-client/src/pyhugegraph/example/hugegraph_example.py @@ -19,7 +19,7 @@ if __name__ == "__main__": client = PyHugeClient( - "127.0.0.1", "8080", user="admin", pwd="admin", graph="hugegraph" + "127.0.0.1", "8080", user="admin", pwd="admin", graph="hugegraph", graphspace=None ) """schema""" diff --git a/hugegraph-python-client/src/pyhugegraph/example/hugegraph_test.py b/hugegraph-python-client/src/pyhugegraph/example/hugegraph_test.py index 739862da..e58a98d6 100644 --- a/hugegraph-python-client/src/pyhugegraph/example/hugegraph_test.py +++ b/hugegraph-python-client/src/pyhugegraph/example/hugegraph_test.py @@ -24,7 +24,7 @@ def __init__( username: str = "default", password: str = "default", address: str = "127.0.0.1", - port: int = 8081, + port: str = "8081", graph: str = "hugegraph", ) -> None: """Create a new HugeGraph wrapper instance.""" @@ -42,7 +42,7 @@ def __init__( self.port = port self.graph = graph self.client = PyHugeClient( - address, port, user=username, pwd=password, graph=graph + address, port, user=username, pwd=password, graph=graph, graphspace=None ) self.schema = "" diff --git a/hugegraph-python-client/src/tests/client_utils.py b/hugegraph-python-client/src/tests/client_utils.py index 12b35db1..6a75ab1c 100644 --- a/hugegraph-python-client/src/tests/client_utils.py +++ b/hugegraph-python-client/src/tests/client_utils.py @@ -20,15 +20,16 @@ class ClientUtils: IP = "127.0.0.1" - PORT = 8080 + PORT = "8080" GRAPH = "hugegraph" USERNAME = "admin" PASSWORD = "admin" + GRAPHSPACE = None TIMEOUT = 10 def __init__(self): self.client = PyHugeClient( - self.IP, self.PORT, user=self.USERNAME, pwd=self.PASSWORD, graph=self.GRAPH + self.IP, self.PORT, user=self.USERNAME, pwd=self.PASSWORD, graph=self.GRAPH, graphspace=self.GRAPHSPACE ) assert self.client is not None