├── DISCLAIMER ├── LICENSE ├── NOTICE ├── README.md ├── hugegraph-llm ├── MANIFEST.in ├── README.md ├── pyproject.toml ├── quick_start.md ├── requirements.txt └── src │ ├── hugegraph_llm │ ├── __init__.py │ ├── api │ │ ├── __init__.py │ │ ├── admin_api.py │ │ ├── exceptions │ │ │ ├── __init__.py │ │ │ └── rag_exceptions.py │ │ ├── models │ │ │ ├── __init__.py │ │ │ ├── rag_requests.py │ │ │ └── rag_response.py │ │ └── rag_api.py │ ├── config │ │ ├── __init__.py │ │ ├── admin_config.py │ │ ├── generate.py │ │ ├── hugegraph_config.py │ │ ├── llm_config.py │ │ ├── models │ │ │ ├── __init__.py │ │ │ ├── base_config.py │ │ │ └── base_prompt_config.py │ │ └── prompt_config.py │ ├── demo │ │ ├── __init__.py │ │ └── rag_demo │ │ │ ├── __init__.py │ │ │ ├── admin_block.py │ │ │ ├── app.py │ │ │ ├── configs_block.py │ │ │ ├── other_block.py │ │ │ ├── rag_block.py │ │ │ ├── text2gremlin_block.py │ │ │ └── vector_graph_block.py │ ├── document │ │ ├── __init__.py │ │ └── chunk_split.py │ ├── enums │ │ ├── __init__.py │ │ ├── id_strategy.py │ │ ├── property_cardinality.py │ │ └── property_data_type.py │ ├── indices │ │ ├── __init__.py │ │ ├── graph_index.py │ │ ├── keyword_index.py │ │ └── vector_index.py │ ├── middleware │ │ ├── __init__.py │ │ └── middleware.py │ ├── models │ │ ├── __init__.py │ │ ├── embeddings │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── init_embedding.py │ │ │ ├── litellm.py │ │ │ ├── ollama.py │ │ │ ├── openai.py │ │ │ └── qianfan.py │ │ ├── llms │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── init_llm.py │ │ │ ├── litellm.py │ │ │ ├── ollama.py │ │ │ ├── openai.py │ │ │ └── qianfan.py │ │ └── rerankers │ │ │ ├── __init__.py │ │ │ ├── cohere.py │ │ │ ├── init_reranker.py │ │ │ └── siliconflow.py │ ├── operators │ │ ├── __init__.py │ │ ├── common_op │ │ │ ├── __init__.py │ │ │ ├── check_schema.py │ │ │ ├── merge_dedup_rerank.py │ │ │ ├── nltk_helper.py │ │ │ └── print_result.py │ │ ├── document_op │ │ │ ├── __init__.py │ │ │ ├── chunk_split.py │ │ │ └── word_extract.py │ │ ├── graph_rag_task.py │ │ ├── gremlin_generate_task.py │ │ ├── hugegraph_op │ │ │ ├── __init__.py │ │ │ ├── commit_to_hugegraph.py │ │ │ ├── fetch_graph_data.py │ │ │ ├── graph_rag_query.py │ │ │ └── schema_manager.py │ │ ├── index_op │ │ │ ├── __init__.py │ │ │ ├── build_gremlin_example_index.py │ │ │ ├── build_semantic_index.py │ │ │ ├── build_vector_index.py │ │ │ ├── gremlin_example_index_query.py │ │ │ ├── semantic_id_query.py │ │ │ └── vector_index_query.py │ │ ├── kg_construction_task.py │ │ └── llm_op │ │ │ ├── __init__.py │ │ │ ├── answer_synthesize.py │ │ │ ├── disambiguate_data.py │ │ │ ├── gremlin_generate.py │ │ │ ├── info_extract.py │ │ │ ├── keyword_extract.py │ │ │ ├── prompt_generate.py │ │ │ ├── property_graph_extract.py │ │ │ ├── schema_build.py │ │ │ └── unstructured_data_utils.py │ ├── resources │ │ ├── demo │ │ │ ├── css.py │ │ │ ├── test.txt │ │ │ └── text2gremlin.csv │ │ ├── nltk_data │ │ │ └── corpora │ │ │ │ └── stopwords │ │ │ │ ├── chinese │ │ │ │ └── english │ │ └── prompt_examples │ │ │ ├── prompt_examples.json │ │ │ ├── query_examples.json │ │ │ └── schema_examples.json │ └── utils │ │ ├── __init__.py │ │ ├── anchor.py │ │ ├── decorators.py │ │ ├── graph_index_utils.py │ │ ├── hugegraph_utils.py │ │ ├── log.py │ │ └── vector_index_utils.py │ └── tests │ ├── config │ └── test_config.py │ ├── indices │ └── test_vector_index.py │ ├── models │ ├── embeddings │ │ ├── test_ollama_embedding.py │ │ └── test_openai_embedding.py │ └── llms │ │ └── test_ollama_client.py │ └── operators │ ├── common_op │ ├── test_check_schema.py │ └── test_nltk_helper.py │ └── llm_op │ ├── test_disambiguate_data.py │ └── test_info_extract.py ├── hugegraph-python-client ├── README.md ├── pyproject.toml └── src │ ├── pyhugegraph │ ├── __init__.py │ ├── api │ │ ├── __init__.py │ │ ├── auth.py │ │ ├── common.py │ │ ├── graph.py │ │ ├── graphs.py │ │ ├── gremlin.py │ │ ├── metric.py │ │ ├── rank.py │ │ ├── rebuild.py │ │ ├── schema.py │ │ ├── schema_manage │ │ │ ├── __init__.py │ │ │ ├── edge_label.py │ │ │ ├── index_label.py │ │ │ ├── property_key.py │ │ │ └── vertex_label.py │ │ ├── services.py │ │ ├── task.py │ │ ├── traverser.py │ │ ├── variable.py │ │ └── version.py │ ├── client.py │ ├── example │ │ ├── __init__.py │ │ ├── hugegraph_example.py │ │ └── hugegraph_test.py │ ├── structure │ │ ├── __init__.py │ │ ├── edge_data.py │ │ ├── edge_label_data.py │ │ ├── gremlin_data.py │ │ ├── index_label_data.py │ │ ├── property_key_data.py │ │ ├── rank_data.py │ │ ├── response_data.py │ │ ├── services_data.py │ │ ├── vertex_data.py │ │ └── vertex_label_data.py │ └── utils │ │ ├── __init__.py │ │ ├── constants.py │ │ ├── exceptions.py │ │ ├── huge_config.py │ │ ├── huge_decorator.py │ │ ├── huge_requests.py │ │ ├── huge_router.py │ │ ├── log.py │ │ └── util.py │ └── tests │ ├── __init__.py │ ├── api │ ├── __init__.py │ ├── test_auth.py │ ├── test_graph.py │ ├── test_graphs.py │ ├── test_gremlin.py │ ├── test_metric.py │ ├── test_schema.py │ ├── test_task.py │ ├── test_traverser.py │ ├── test_variable.py │ └── test_version.py │ └── client_utils.py └── vermeer-python-client ├── README.md ├── pyproject.toml └── src └── pyvermeer ├── __init__.py ├── api ├── base.py ├── graph.py ├── master.py ├── task.py └── worker.py ├── client ├── __init__.py └── client.py ├── demo └── task_demo.py ├── structure ├── __init__.py ├── base_data.py ├── graph_data.py ├── master_data.py ├── task_data.py └── worker_data.py └── utils ├── __init__.py ├── exception.py ├── log.py ├── vermeer_config.py ├── vermeer_datetime.py └── vermeer_requests.py /DISCLAIMER: -------------------------------------------------------------------------------- 1 | Apache HugeGraph (incubating) is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator PMC. 2 | 3 | Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, 4 | and decision making process have stabilized in a manner consistent with other successful ASF projects. 5 | 6 | While incubation status is not necessarily a reflection of the completeness or stability of the code, 7 | it does indicate that the project has yet to be fully endorsed by the ASF. 8 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Apache HugeGraph(incubating) 2 | Copyright 2022-2025 The Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | -------------------------------------------------------------------------------- /hugegraph-llm/MANIFEST.in: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | # Note: 19 | # This MANIFEST.in file ensures that all necessary non-code resource files are included when building the 20 | # hugegraph-llm Python package distribution. It recursively includes all files under src/hugegraph_llm/resources. 21 | # Maintenance: When adding or removing resource files, update this file to keep the package contents accurate. 22 | 23 | recursive-include src/hugegraph_llm/resources * 24 | -------------------------------------------------------------------------------- /hugegraph-llm/pyproject.toml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | [project] 19 | name = "hugegraph-llm" 20 | version = "1.5.0" 21 | description = "A tool for the implementation and research related to large language models." 22 | authors = [ 23 | { name = "Apache HugeGraph Contributors", email = "dev@hugegraph.apache.org" }, 24 | ] 25 | readme = "README.md" 26 | license = "Apache-2.0" 27 | requires-python = ">=3.10,<3.12" 28 | maintainers = [ 29 | { name = "Apache HugeGraph Contributors", email = "dev@hugegraph.apache.org" }, 30 | ] 31 | 32 | 33 | dependencies = [ 34 | "openai~=1.61.0", 35 | "ollama~=0.4.8", 36 | "qianfan~=0.3.18", 37 | "retry~=0.9.2", 38 | "tiktoken~=0.7.0", 39 | "nltk~=3.9.1", 40 | "gradio~=5.20.0", 41 | "jieba~=0.42.1", 42 | "numpy~=1.24.4", 43 | "python-docx~=1.1.2", 44 | "langchain-text-splitters~=0.2.2", 45 | "faiss-cpu~=1.8.0", 46 | "python-dotenv~=1.0.1", 47 | "pyarrow~=17.0.0", 48 | "pandas<2.2.2", 49 | "openpyxl~=3.1.5", 50 | "pydantic~=2.10.6", 51 | "pydantic-settings~=2.6.1", 52 | "decorator~=5.1.1", 53 | "requests~=2.32.0", 54 | "setuptools~=70.0.0", 55 | "urllib3~=2.2.2", 56 | "rich~=13.9.4", 57 | "apscheduler~=3.10.4", 58 | "litellm~=1.61.13", 59 | "hugegraph-python-client", 60 | ] 61 | [project.urls] 62 | homepage = "https://hugegraph.apache.org/" 63 | repository = "https://github.com/apache/incubator-hugegraph-ai" 64 | documentation = "https://hugegraph.apache.org/docs/quickstart/hugegraph-ai/" 65 | "Bug Tracker" = "https://github.com/apache/incubator-hugegraph-ai/issues" 66 | 67 | [build-system] 68 | requires = ["hatchling"] 69 | build-backend = "hatchling.build" 70 | 71 | #If you want to modify the network configuration file of the project, then you can modify this part 72 | [[tool.uv.index]] 73 | url = "https://pypi.tuna.tsinghua.edu.cn/simple" 74 | default = true 75 | 76 | [tool.hatch.build.targets.wheel] 77 | packages = ["src/hugegraph_llm"] 78 | 79 | [tool.hatch.build.targets.sdist] 80 | include = [ 81 | "src/hugegraph_llm", 82 | "README.md", 83 | "LICENSE", 84 | "NOTICE", 85 | "MANIFEST.in" 86 | ] 87 | 88 | [tool.hatch.metadata] 89 | allow-direct-references = true 90 | 91 | [tool.uv.sources] 92 | hugegraph-python-client = { path = "../hugegraph-python-client/", editable = true } 93 | -------------------------------------------------------------------------------- /hugegraph-llm/requirements.txt: -------------------------------------------------------------------------------- 1 | # TODO: remove this file after uv run stable, don't update it 2 | openai~=1.61.0 3 | ollama~=0.4.8 4 | qianfan~=0.3.18 5 | retry~=0.9.2 6 | tiktoken>=0.7.0 7 | nltk~=3.8.1 8 | gradio~=5.29.1 9 | jieba>=0.42.1 10 | numpy~=1.24.4 11 | python-docx~=1.1.2 12 | langchain-text-splitters~=0.2.2 13 | faiss-cpu~=1.8.0 14 | python-dotenv>=1.0.1 15 | pyarrow~=17.0.0 # TODO: a temporary dependency for pandas, figure out why ImportError 16 | pandas~=2.2.2 17 | openpyxl~=3.1.5 18 | pydantic-settings~=2.6.1 19 | apscheduler~=3.10.4 20 | litellm~=1.61.13 21 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/api/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/api/admin_api.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import os 19 | 20 | from fastapi import status, APIRouter 21 | from fastapi.responses import StreamingResponse 22 | 23 | from hugegraph_llm.api.exceptions.rag_exceptions import generate_response 24 | from hugegraph_llm.api.models.rag_requests import LogStreamRequest 25 | from hugegraph_llm.api.models.rag_response import RAGResponse 26 | from hugegraph_llm.config import admin_settings 27 | 28 | 29 | # FIXME: line 31: E0702: Raising dict while only classes or instances are allowed (raising-bad-type) 30 | def admin_http_api(router: APIRouter, log_stream): 31 | @router.post("/logs", status_code=status.HTTP_200_OK) 32 | async def log_stream_api(req: LogStreamRequest): 33 | if admin_settings.admin_token != req.admin_token: 34 | raise generate_response(RAGResponse(status_code=status.HTTP_403_FORBIDDEN, #pylint: disable=E0702 35 | message="Invalid admin_token")) 36 | log_path = os.path.join("logs", req.log_file) 37 | 38 | # Create a StreamingResponse that reads from the log stream generator 39 | return StreamingResponse(log_stream(log_path), media_type="text/plain") 40 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/api/exceptions/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/api/exceptions/rag_exceptions.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from fastapi import HTTPException 19 | from hugegraph_llm.api.models.rag_response import RAGResponse 20 | 21 | 22 | class ExternalException(HTTPException): 23 | def __init__(self): 24 | super().__init__(status_code=400, detail="Connect failed with error code -1, please check the input.") 25 | 26 | 27 | class ConnectionFailedException(HTTPException): 28 | def __init__(self, status_code: int, message: str): 29 | super().__init__(status_code=status_code, detail=message) 30 | 31 | 32 | def generate_response(response: RAGResponse) -> dict: 33 | if response.status_code == -1: 34 | raise ExternalException() 35 | if not 200 <= response.status_code < 300: 36 | raise ConnectionFailedException(response.status_code, response.message) 37 | return {"message": "Connection successful. Configured finished."} 38 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/api/models/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/api/models/rag_response.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from pydantic import BaseModel 19 | 20 | 21 | class RAGResponse(BaseModel): 22 | status_code: int = -1 23 | message: str = "" 24 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/config/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | __all__ = ["huge_settings", "admin_settings", "llm_settings", "resource_path"] 20 | 21 | import os 22 | 23 | from .prompt_config import PromptConfig 24 | from .hugegraph_config import HugeGraphConfig 25 | from .admin_config import AdminConfig 26 | from .llm_config import LLMConfig 27 | 28 | prompt = PromptConfig() 29 | prompt.ensure_yaml_file_exists() 30 | 31 | huge_settings = HugeGraphConfig() 32 | admin_settings = AdminConfig() 33 | llm_settings = LLMConfig() 34 | 35 | package_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 36 | resource_path = os.path.join(package_path, "resources") 37 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/config/admin_config.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from typing import Optional 19 | from .models import BaseConfig 20 | 21 | class AdminConfig(BaseConfig): 22 | """Admin settings""" 23 | enable_login: Optional[str] = "False" 24 | user_token: Optional[str] = "4321" 25 | admin_token: Optional[str] = "xxxx" 26 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/config/generate.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | import argparse 20 | 21 | from hugegraph_llm.config import huge_settings, admin_settings, llm_settings, PromptConfig 22 | 23 | if __name__ == "__main__": 24 | parser = argparse.ArgumentParser(description="Generate hugegraph-llm config file") 25 | parser.add_argument("-U", "--update", default=True, action="store_true", help="Update the config file") 26 | args = parser.parse_args() 27 | if args.update: 28 | huge_settings.generate_env() 29 | admin_settings.generate_env() 30 | llm_settings.generate_env() 31 | PromptConfig().generate_yaml_file() 32 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/config/hugegraph_config.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from typing import Optional 19 | from .models import BaseConfig 20 | 21 | 22 | class HugeGraphConfig(BaseConfig): 23 | """HugeGraph settings""" 24 | # graph server config 25 | graph_url: Optional[str] = "127.0.0.1:8080" 26 | graph_name: Optional[str] = "hugegraph" 27 | graph_user: Optional[str] = "admin" 28 | graph_pwd: Optional[str] = "xxx" 29 | graph_space: Optional[str] = None 30 | 31 | # graph query config 32 | limit_property: Optional[str] = "False" 33 | max_graph_path: Optional[int] = 10 34 | max_graph_items: Optional[int] = 30 35 | edge_limit_pre_label: Optional[int] = 8 36 | 37 | # vector config 38 | vector_dis_threshold: Optional[float] = 0.9 39 | topk_per_keyword: Optional[int] = 1 40 | 41 | # rerank config 42 | topk_return_results: Optional[int] = 20 43 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/config/models/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from .base_config import BaseConfig 19 | from .base_prompt_config import BasePromptConfig 20 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/demo/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/demo/rag_demo/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/document/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/document/chunk_split.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from typing import Literal, Union, List 20 | from langchain_text_splitters import RecursiveCharacterTextSplitter 21 | 22 | 23 | class ChunkSplitter: 24 | def __init__( 25 | self, 26 | split_type: Literal["paragraph", "sentence"] = "paragraph", 27 | language: Literal["zh", "en"] = "zh" 28 | ): 29 | if language == "zh": 30 | separators = ["\n\n", "\n", "。", ",", ""] 31 | elif language == "en": 32 | separators = ["\n\n", "\n", ".", ",", " ", ""] 33 | else: 34 | raise ValueError("Argument `language` must be zh or en!") 35 | if split_type == "paragraph": 36 | self.text_splitter = RecursiveCharacterTextSplitter( 37 | chunk_size=500, 38 | chunk_overlap=30, 39 | separators=separators 40 | ) 41 | elif split_type == "sentence": 42 | self.text_splitter = RecursiveCharacterTextSplitter( 43 | chunk_size=50, 44 | chunk_overlap=0, 45 | separators=separators 46 | ) 47 | else: 48 | raise ValueError("Arg `type` must be paragraph, sentence!") 49 | 50 | def split(self, documents: Union[str, List[str]]) -> List[str]: 51 | chunks = [] 52 | if isinstance(documents, str): 53 | documents = [documents] 54 | for document in documents: 55 | chunks.extend(self.text_splitter.split_text(document)) 56 | return chunks 57 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/enums/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/enums/id_strategy.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from enum import Enum 20 | 21 | 22 | class IdStrategy(Enum): 23 | AUTOMATIC = "automatic" 24 | PRIMARY_KEY = "primary_key" 25 | CUSTOMIZE_STRING = "customize_string" 26 | CUSTOMIZE_NUMBER = "customize_number" 27 | CUSTOMIZE_UUID = "customize_uuid" 28 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/enums/property_cardinality.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from enum import Enum 20 | 21 | 22 | class PropertyCardinality(Enum): 23 | SINGLE = "SINGLE" 24 | LIST = "LIST" 25 | SET = "SET" 26 | DEFAULT = SINGLE 27 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/enums/property_data_type.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from enum import Enum 20 | 21 | 22 | class PropertyDataType(Enum): 23 | BOOLEAN = "BOOLEAN" 24 | BYTE = "BYTE" 25 | INT = "INT" 26 | LONG = "LONG" 27 | FLOAT = "FLOAT" 28 | DOUBLE = "DOUBLE" 29 | TEXT = "TEXT" 30 | BLOB = "BLOB" 31 | DATE = "DATE" 32 | UUID = "UUID" 33 | DEFAULT = TEXT 34 | 35 | 36 | def default_value_map(data_type: str): 37 | return { 38 | "BOOLEAN": False, 39 | "BYTE": 0, 40 | "INT": 0, 41 | "LONG": 0, 42 | "FLOAT": 0.0, 43 | "DOUBLE": 0.0, 44 | "TEXT": "", 45 | "BLOB": "", 46 | "DATE": "2000-01-01", 47 | "UUID": "", 48 | }[data_type] 49 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/indices/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/indices/graph_index.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from typing import Optional 20 | from pyhugegraph.client import PyHugeClient 21 | 22 | from hugegraph_llm.config import huge_settings 23 | 24 | 25 | class GraphIndex: 26 | def __init__( 27 | self, 28 | graph_url: Optional[str] = huge_settings.graph_url, 29 | graph_name: Optional[str] = huge_settings.graph_name, 30 | graph_user: Optional[str] = huge_settings.graph_user, 31 | graph_pwd: Optional[str] = huge_settings.graph_pwd, 32 | graph_space: Optional[str] = huge_settings.graph_space, 33 | ): 34 | self.client = PyHugeClient(url=graph_url, graph=graph_name, user=graph_user, pwd=graph_pwd, 35 | graphspace=graph_space) 36 | 37 | def clear_graph(self): 38 | self.client.gremlin().exec("g.V().drop()") 39 | 40 | # TODO: replace triples with a more specific graph element type & implement it 41 | def add_triples(self, triples: list): 42 | pass 43 | 44 | # TODO: replace triples with a more specific graph element type & implement it 45 | def search_triples(self, max_deep: int = 2): 46 | pass 47 | 48 | def execute_gremlin_query(self, query: str): 49 | return self.client.gremlin().exec(query) 50 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/indices/keyword_index.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | """TODO: implement keyword index""" 20 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/middleware/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/middleware/middleware.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import time 19 | 20 | from fastapi import Request 21 | from starlette.middleware.base import BaseHTTPMiddleware 22 | 23 | from hugegraph_llm.utils.log import log 24 | 25 | 26 | # TODO: we could use middleware(AOP) in the future (dig out the lifecycle of gradio & fastapi) 27 | class UseTimeMiddleware(BaseHTTPMiddleware): 28 | """Middleware to add process time to response headers""" 29 | def __init__(self, app): 30 | super().__init__(app) 31 | 32 | async def dispatch(self, request: Request, call_next): 33 | # TODO: handle time record for async task pool in gradio 34 | start_time = time.perf_counter() 35 | response = await call_next(request) 36 | process_time = (time.perf_counter() - start_time) * 1000 # ms 37 | unit = "ms" 38 | if process_time > 1000: 39 | process_time /= 1000 40 | unit = "s" 41 | 42 | response.headers["X-Process-Time"] = f"{process_time:.2f} {unit}" 43 | log.info("Request process time: %.2f ms, code=%d", process_time, response.status_code) 44 | log.info( 45 | "%s - Args: %s, IP: %s, URL: %s", 46 | request.method, 47 | request.query_params, 48 | request.client.host, 49 | request.url 50 | ) 51 | return response 52 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/models/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/models/embeddings/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/models/embeddings/init_embedding.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from hugegraph_llm.models.embeddings.openai import OpenAIEmbedding 20 | from hugegraph_llm.models.embeddings.ollama import OllamaEmbedding 21 | from hugegraph_llm.models.embeddings.qianfan import QianFanEmbedding 22 | from hugegraph_llm.models.embeddings.litellm import LiteLLMEmbedding 23 | from hugegraph_llm.config import llm_settings 24 | 25 | 26 | class Embeddings: 27 | def __init__(self): 28 | self.embedding_type = llm_settings.embedding_type 29 | 30 | def get_embedding(self): 31 | if self.embedding_type == "openai": 32 | return OpenAIEmbedding( 33 | model_name=llm_settings.openai_embedding_model, 34 | api_key=llm_settings.openai_embedding_api_key, 35 | api_base=llm_settings.openai_embedding_api_base 36 | ) 37 | if self.embedding_type == "ollama/local": 38 | return OllamaEmbedding( 39 | model=llm_settings.ollama_embedding_model, 40 | host=llm_settings.ollama_embedding_host, 41 | port=llm_settings.ollama_embedding_port 42 | ) 43 | if self.embedding_type == "qianfan_wenxin": 44 | return QianFanEmbedding( 45 | model_name=llm_settings.qianfan_embedding_model, 46 | api_key=llm_settings.qianfan_embedding_api_key, 47 | secret_key=llm_settings.qianfan_embedding_secret_key 48 | ) 49 | if self.embedding_type == "litellm": 50 | return LiteLLMEmbedding( 51 | model_name=llm_settings.litellm_embedding_model, 52 | api_key=llm_settings.litellm_embedding_api_key, 53 | api_base=llm_settings.litellm_embedding_api_base 54 | ) 55 | 56 | raise Exception("embedding type is not supported !") 57 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/models/embeddings/ollama.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from typing import List 20 | 21 | import ollama 22 | 23 | from .base import BaseEmbedding 24 | 25 | 26 | class OllamaEmbedding(BaseEmbedding): 27 | def __init__(self, model: str, host: str = "127.0.0.1", port: int = 11434, **kwargs): 28 | self.model = model 29 | self.client = ollama.Client(host=f"http://{host}:{port}", **kwargs) 30 | self.async_client = ollama.AsyncClient(host=f"http://{host}:{port}", **kwargs) 31 | self.embedding_dimension = None 32 | 33 | def get_text_embedding(self, text: str) -> List[float]: 34 | """Get embedding for a single text.""" 35 | return self.get_texts_embeddings([text])[0] 36 | 37 | def get_texts_embeddings(self, texts: List[str]) -> List[List[float]]: 38 | """Get embeddings for multiple texts in a single batch. 39 | 40 | Returns 41 | ------- 42 | List[List[float]] 43 | A list of embedding vectors, where each vector is a list of floats. 44 | The order of embeddings matches the order of input texts. 45 | """ 46 | if not hasattr(self.client, "embed"): 47 | error_message = ( 48 | "The required 'embed' method was not found on the Ollama client. " 49 | "Please ensure your ollama library is up-to-date and supports batch embedding. " 50 | ) 51 | raise AttributeError(error_message) 52 | 53 | response = self.client.embed(model=self.model, input=texts)["embeddings"] 54 | return [list(inner_sequence) for inner_sequence in response] 55 | 56 | # TODO: Add & implement batch processing for async_get_texts_embeddings (refactor here) 57 | async def async_get_text_embedding(self, text: str) -> List[float]: 58 | response = await self.async_client.embeddings(model=self.model, prompt=text) 59 | return list(response["embedding"]) 60 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/models/embeddings/openai.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from typing import Optional, List 20 | 21 | from openai import OpenAI, AsyncOpenAI 22 | 23 | 24 | class OpenAIEmbedding: 25 | def __init__( 26 | self, 27 | model_name: str = "text-embedding-3-small", 28 | api_key: Optional[str] = None, 29 | api_base: Optional[str] = None 30 | ): 31 | api_key = api_key or '' 32 | self.client = OpenAI(api_key=api_key, base_url=api_base) 33 | self.aclient = AsyncOpenAI(api_key=api_key, base_url=api_base) 34 | self.embedding_model_name = model_name 35 | 36 | def get_text_embedding(self, text: str) -> List[float]: 37 | """Comment""" 38 | response = self.client.embeddings.create(input=text, model=self.embedding_model_name) 39 | return response.data[0].embedding 40 | 41 | def get_texts_embeddings( 42 | self, 43 | texts: List[str] 44 | ) -> List[List[float]]: 45 | """Get embeddings for multiple texts in a single batch. 46 | 47 | This method efficiently processes multiple texts at once by leveraging 48 | OpenAI's batching capabilities, which is more efficient than processing 49 | texts individually. 50 | 51 | Parameters 52 | ---------- 53 | texts : List[str] 54 | A list of text strings to be embedded. 55 | 56 | Returns 57 | ------- 58 | List[List[float]] 59 | A list of embedding vectors, where each vector is a list of floats. 60 | The order of embeddings matches the order of input texts. 61 | """ 62 | response = self.client.embeddings.create(input=texts, model=self.embedding_model_name) 63 | return [data.embedding for data in response.data] 64 | 65 | async def async_get_text_embedding(self, text: str) -> List[float]: 66 | """Comment""" 67 | response = await self.aclient.embeddings.create(input=text, model=self.embedding_model_name) 68 | return response.data[0].embedding 69 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/models/embeddings/qianfan.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from typing import Optional, List 20 | 21 | import qianfan 22 | 23 | from hugegraph_llm.config import llm_settings 24 | 25 | """ 26 | "QianFan" platform can be understood as a unified LLM platform that encompasses the 27 | WenXin large model along with other 28 | common open-source models. 29 | 30 | It enables the invocation and switching between WenXin and these open-source models. 31 | """ 32 | 33 | 34 | class QianFanEmbedding: 35 | def __init__( 36 | self, 37 | model_name: str = "embedding-v1", 38 | api_key: Optional[str] = None, 39 | secret_key: Optional[str] = None 40 | ): 41 | qianfan.get_config().AK = api_key or llm_settings.qianfan_embedding_api_key 42 | qianfan.get_config().SK = secret_key or llm_settings.qianfan_embedding_secret_key 43 | self.embedding_model_name = model_name 44 | self.client = qianfan.Embedding() 45 | 46 | def get_text_embedding(self, text: str) -> List[float]: 47 | """ Usage refer: https://cloud.baidu.com/doc/WENXINWORKSHOP/s/hlmokk9qn""" 48 | response = self.client.do( 49 | model=self.embedding_model_name, 50 | texts=[text] 51 | ) 52 | return response["body"]["data"][0]["embedding"] 53 | 54 | def get_texts_embeddings(self, texts: List[str]) -> List[List[float]]: 55 | """ Usage refer: https://cloud.baidu.com/doc/WENXINWORKSHOP/s/hlmokk9qn""" 56 | response = self.client.do( 57 | model=self.embedding_model_name, 58 | texts=texts 59 | ) 60 | return [data["embedding"] for data in response["body"]["data"]] 61 | 62 | async def async_get_text_embedding(self, text: str) -> List[float]: 63 | """ Usage refer: https://cloud.baidu.com/doc/WENXINWORKSHOP/s/hlmokk9qn""" 64 | response = await self.client.ado( 65 | model=self.embedding_model_name, 66 | texts=[text] 67 | ) 68 | return response["body"]["data"][0]["embedding"] 69 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/models/llms/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/models/llms/base.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from abc import ABC, abstractmethod 19 | from typing import Any, AsyncGenerator, Generator, List, Optional, Callable, Dict 20 | 21 | 22 | class BaseLLM(ABC): 23 | """LLM wrapper should take in a prompt and return a string.""" 24 | 25 | @abstractmethod 26 | def generate( 27 | self, 28 | messages: Optional[List[Dict[str, Any]]] = None, 29 | prompt: Optional[str] = None, 30 | ) -> str: 31 | """Comment""" 32 | 33 | @abstractmethod 34 | async def agenerate( 35 | self, 36 | messages: Optional[List[Dict[str, Any]]] = None, 37 | prompt: Optional[str] = None, 38 | ) -> str: 39 | """Comment""" 40 | 41 | @abstractmethod 42 | def generate_streaming( 43 | self, 44 | messages: Optional[List[Dict[str, Any]]] = None, 45 | prompt: Optional[str] = None, 46 | on_token_callback: Optional[Callable] = None, 47 | ) -> Generator[str, None, None]: 48 | """Comment""" 49 | 50 | @abstractmethod 51 | async def agenerate_streaming( 52 | self, 53 | messages: Optional[List[Dict[str, Any]]] = None, 54 | prompt: Optional[str] = None, 55 | on_token_callback: Optional[Callable] = None, 56 | ) -> AsyncGenerator[str, None]: 57 | """Comment""" 58 | 59 | @abstractmethod 60 | def num_tokens_from_string( 61 | self, 62 | string: str, 63 | ) -> str: 64 | """Given a string returns the number of tokens the given string consists of""" 65 | 66 | @abstractmethod 67 | def max_allowed_token_length( 68 | self, 69 | ) -> int: 70 | """Returns the maximum number of tokens the LLM can handle""" 71 | 72 | @abstractmethod 73 | def get_llm_type(self) -> str: 74 | """Returns the type of the LLM""" 75 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/models/rerankers/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/models/rerankers/cohere.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from typing import Optional, List 19 | 20 | import requests 21 | 22 | 23 | class CohereReranker: 24 | def __init__( 25 | self, 26 | api_key: Optional[str] = None, 27 | base_url: Optional[str] = None, 28 | model: Optional[str] = None, 29 | ): 30 | self.api_key = api_key 31 | self.base_url = base_url 32 | self.model = model 33 | 34 | def get_rerank_lists(self, query: str, documents: List[str], top_n: Optional[int] = None) -> List[str]: 35 | if not top_n: 36 | top_n = len(documents) 37 | assert top_n <= len(documents), "'top_n' should be less than or equal to the number of documents" 38 | 39 | if top_n == 0: 40 | return [] 41 | 42 | url = self.base_url 43 | from pyhugegraph.utils.constants import Constants 44 | headers = { 45 | "accept": Constants.HEADER_CONTENT_TYPE, 46 | "content-type": Constants.HEADER_CONTENT_TYPE, 47 | "Authorization": f"Bearer {self.api_key}", 48 | } 49 | payload = { 50 | "model": self.model, 51 | "query": query, 52 | "top_n": top_n, 53 | "documents": documents, 54 | } 55 | response = requests.post(url, headers=headers, json=payload, timeout=(1.0, 10.0)) 56 | response.raise_for_status() # Raise an error for bad status codes 57 | results = response.json()["results"] 58 | sorted_docs = [documents[item["index"]] for item in results] 59 | return sorted_docs 60 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/models/rerankers/init_reranker.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from hugegraph_llm.config import llm_settings 19 | from hugegraph_llm.models.rerankers.cohere import CohereReranker 20 | from hugegraph_llm.models.rerankers.siliconflow import SiliconReranker 21 | 22 | 23 | class Rerankers: 24 | def __init__(self): 25 | self.reranker_type = llm_settings.reranker_type 26 | 27 | def get_reranker(self): 28 | if self.reranker_type == "cohere": 29 | return CohereReranker( 30 | api_key=llm_settings.reranker_api_key, 31 | base_url=llm_settings.cohere_base_url, 32 | model=llm_settings.reranker_model, 33 | ) 34 | if self.reranker_type == "siliconflow": 35 | return SiliconReranker(api_key=llm_settings.reranker_api_key, model=llm_settings.reranker_model) 36 | raise Exception("Reranker type is not supported!") 37 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/models/rerankers/siliconflow.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from typing import Optional, List 19 | 20 | import requests 21 | 22 | 23 | class SiliconReranker: 24 | def __init__( 25 | self, 26 | api_key: Optional[str] = None, 27 | model: Optional[str] = None, 28 | ): 29 | self.api_key = api_key 30 | self.model = model 31 | 32 | def get_rerank_lists(self, query: str, documents: List[str], top_n: Optional[int] = None) -> List[str]: 33 | if not top_n: 34 | top_n = len(documents) 35 | assert top_n <= len(documents), "'top_n' should be less than or equal to the number of documents" 36 | 37 | if top_n == 0: 38 | return [] 39 | 40 | url = "https://api.siliconflow.cn/v1/rerank" 41 | payload = { 42 | "model": self.model, 43 | "query": query, 44 | "documents": documents, 45 | "return_documents": False, 46 | "max_chunks_per_doc": 1024, 47 | "overlap_tokens": 80, 48 | "top_n": top_n, 49 | } 50 | from pyhugegraph.utils.constants import Constants 51 | headers = { 52 | "accept": Constants.HEADER_CONTENT_TYPE, 53 | "content-type": Constants.HEADER_CONTENT_TYPE, 54 | "authorization": f"Bearer {self.api_key}", 55 | } 56 | response = requests.post(url, json=payload, headers=headers, timeout=(1.0, 10.0)) 57 | response.raise_for_status() # Raise an error for bad status codes 58 | results = response.json()["results"] 59 | sorted_docs = [documents[item["index"]] for item in results] 60 | return sorted_docs 61 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/common_op/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/common_op/nltk_helper.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | import os 20 | import sys 21 | from pathlib import Path 22 | from typing import List, Optional, Dict 23 | 24 | import nltk 25 | from nltk.corpus import stopwords 26 | 27 | from hugegraph_llm.config import resource_path 28 | 29 | 30 | class NLTKHelper: 31 | _stopwords: Dict[str, Optional[List[str]]] = { 32 | "english": None, 33 | "chinese": None, 34 | } 35 | 36 | def stopwords(self, lang: str = "chinese") -> List[str]: 37 | """Get stopwords.""" 38 | nltk.data.path.append(os.path.join(resource_path, "nltk_data")) 39 | if self._stopwords.get(lang) is None: 40 | cache_dir = self.get_cache_dir() 41 | nltk_data_dir = os.environ.get("NLTK_DATA", cache_dir) 42 | 43 | # update nltk path for nltk so that it finds the data 44 | if nltk_data_dir not in nltk.data.path: 45 | nltk.data.path.append(nltk_data_dir) 46 | 47 | try: 48 | nltk.data.find("corpora/stopwords") 49 | except LookupError: 50 | nltk.download("stopwords", download_dir=nltk_data_dir) 51 | self._stopwords[lang] = stopwords.words(lang) 52 | 53 | return self._stopwords[lang] 54 | 55 | @staticmethod 56 | def get_cache_dir() -> str: 57 | """Locate a platform-appropriate cache directory for hugegraph-llm, 58 | and create it if it doesn't yet exist 59 | """ 60 | # User override 61 | if "HG_AI_CACHE_DIR" in os.environ: 62 | path = Path(os.environ["HG_AI_CACHE_DIR"]) 63 | 64 | # Linux, Unix, AIX, etc. 65 | elif os.name == "posix" and sys.platform != "darwin": 66 | path = Path("/tmp/hugegraph_llm") 67 | 68 | # Mac OS 69 | elif sys.platform == "darwin": 70 | path = Path(os.path.expanduser("~"), "Library/Caches/hugegraph_llm") 71 | 72 | # Windows (hopefully) 73 | else: 74 | local = os.environ.get("LOCALAPPDATA", None) or os.path.expanduser("~\\AppData\\Local") 75 | path = Path(local, "hugegraph_llm") 76 | 77 | if not os.path.exists(path): 78 | os.makedirs(path, exist_ok=True) 79 | 80 | return str(path) 81 | 82 | 83 | if __name__ == "__main__": 84 | NLTKHelper().stopwords() 85 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/common_op/print_result.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from typing import Any 20 | 21 | 22 | class PrintResult: 23 | def __init__(self): 24 | self.result = None 25 | 26 | def run(self, data: Any) -> Any: 27 | self.result = data 28 | print(self.result) 29 | return self.result 30 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/document_op/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/document_op/chunk_split.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from typing import Literal, Dict, Any, Optional, Union, List 20 | 21 | from langchain_text_splitters import RecursiveCharacterTextSplitter 22 | 23 | # Constants 24 | LANGUAGE_ZH = "zh" 25 | LANGUAGE_EN = "en" 26 | SPLIT_TYPE_DOCUMENT = "document" 27 | SPLIT_TYPE_PARAGRAPH = "paragraph" 28 | SPLIT_TYPE_SENTENCE = "sentence" 29 | 30 | class ChunkSplit: 31 | def __init__( 32 | self, 33 | texts: Union[str, List[str]], 34 | split_type: Literal["document", "paragraph", "sentence"] = SPLIT_TYPE_DOCUMENT, 35 | language: Literal["zh", "en"] = LANGUAGE_ZH, 36 | ): 37 | if isinstance(texts, str): 38 | texts = [texts] 39 | self.texts = texts 40 | self.separators = self._get_separators(language) 41 | self.text_splitter = self._get_text_splitter(split_type) 42 | 43 | def _get_separators(self, language: str) -> List[str]: 44 | if language == LANGUAGE_ZH: 45 | return ["\n\n", "\n", "。", ",", ""] 46 | if language == LANGUAGE_EN: 47 | return ["\n\n", "\n", ".", ",", " ", ""] 48 | raise ValueError("language must be zh or en") 49 | 50 | def _get_text_splitter(self, split_type: str): 51 | if split_type == SPLIT_TYPE_DOCUMENT: 52 | return lambda text: [text] 53 | if split_type == SPLIT_TYPE_PARAGRAPH: 54 | return RecursiveCharacterTextSplitter( 55 | chunk_size=500, chunk_overlap=30, separators=self.separators 56 | ).split_text 57 | if split_type == SPLIT_TYPE_SENTENCE: 58 | return RecursiveCharacterTextSplitter( 59 | chunk_size=50, chunk_overlap=0, separators=self.separators 60 | ).split_text 61 | raise ValueError("Type must be paragraph, sentence, html or markdown") 62 | 63 | def run(self, context: Optional[Dict[str, Any]]) -> Dict[str, Any]: 64 | all_chunks = [] 65 | for text in self.texts: 66 | chunks = self.text_splitter(text) 67 | all_chunks.extend(chunks) 68 | 69 | if context is None: 70 | return {"chunks": all_chunks} 71 | context["chunks"] = all_chunks 72 | return context 73 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/fetch_graph_data.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from typing import Optional, Dict, Any 20 | 21 | from pyhugegraph.client import PyHugeClient 22 | 23 | 24 | class FetchGraphData: 25 | 26 | def __init__(self, graph: PyHugeClient): 27 | self.graph = graph 28 | 29 | def run(self, graph_summary: Optional[Dict[str, Any]]) -> Dict[str, Any]: 30 | if graph_summary is None: 31 | graph_summary = {} 32 | 33 | # TODO: v_limit will influence the vid embedding logic in build_semantic_index.py 34 | v_limit = 10000 35 | e_limit = 200 36 | keys = ["vertex_num", "edge_num", "vertices", "edges", "note"] 37 | 38 | groovy_code = f""" 39 | def res = [:]; 40 | res.{keys[0]} = g.V().count().next(); 41 | res.{keys[1]} = g.E().count().next(); 42 | res.{keys[2]} = g.V().id().limit({v_limit}).toList(); 43 | res.{keys[3]} = g.E().id().limit({e_limit}).toList(); 44 | res.{keys[4]} = "Only ≤{v_limit} VIDs and ≤ {e_limit} EIDs for brief overview ."; 45 | return res; 46 | """ 47 | 48 | result = self.graph.gremlin().exec(groovy_code)["data"] 49 | 50 | if isinstance(result, list) and len(result) > 0: 51 | graph_summary.update({key: result[i].get(key) for i, key in enumerate(keys)}) 52 | return graph_summary 53 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/schema_manager.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | from typing import Dict, Any, Optional 18 | 19 | from hugegraph_llm.config import huge_settings 20 | from pyhugegraph.client import PyHugeClient 21 | 22 | 23 | class SchemaManager: 24 | def __init__(self, graph_name: str): 25 | self.graph_name = graph_name 26 | self.client = PyHugeClient( 27 | url=huge_settings.graph_url, 28 | graph=self.graph_name, 29 | user=huge_settings.graph_user, 30 | pwd=huge_settings.graph_pwd, 31 | graphspace=huge_settings.graph_space, 32 | ) 33 | self.schema = self.client.schema() 34 | 35 | def simple_schema(self, schema: Dict[str, Any]) -> Dict[str, Any]: 36 | mini_schema = {} 37 | 38 | # Add necessary vertexlabels items (3) 39 | if "vertexlabels" in schema: 40 | mini_schema["vertexlabels"] = [] 41 | for vertex in schema["vertexlabels"]: 42 | new_vertex = {key: vertex[key] for key in ["id", "name", "properties"] if key in vertex} 43 | mini_schema["vertexlabels"].append(new_vertex) 44 | 45 | # Add necessary edgelabels items (4) 46 | if "edgelabels" in schema: 47 | mini_schema["edgelabels"] = [] 48 | for edge in schema["edgelabels"]: 49 | new_edge = {key: edge[key] for key in 50 | ["name", "source_label", "target_label", "properties"] if key in edge} 51 | mini_schema["edgelabels"].append(new_edge) 52 | 53 | return mini_schema 54 | 55 | def run(self, context: Optional[Dict[str, Any]]) -> Dict[str, Any]: 56 | if context is None: 57 | context = {} 58 | schema = self.schema.getSchema() 59 | if not schema["vertexlabels"] and not schema["edgelabels"]: 60 | raise Exception(f"Can not get {self.graph_name}'s schema from HugeGraph!") 61 | 62 | context.update({"schema": schema}) 63 | # TODO: enhance the logic here 64 | context["simple_schema"] = self.simple_schema(schema) 65 | return context 66 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/index_op/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/index_op/build_gremlin_example_index.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | import os 20 | from typing import Dict, Any, List 21 | 22 | from hugegraph_llm.config import resource_path 23 | from hugegraph_llm.indices.vector_index import VectorIndex 24 | from hugegraph_llm.models.embeddings.base import BaseEmbedding 25 | 26 | 27 | # FIXME: we need keep the logic same with build_semantic_index.py 28 | class BuildGremlinExampleIndex: 29 | def __init__(self, embedding: BaseEmbedding, examples: List[Dict[str, str]]): 30 | self.index_dir = os.path.join(resource_path, "gremlin_examples") 31 | self.examples = examples 32 | self.embedding = embedding 33 | 34 | def run(self, context: Dict[str, Any]) -> Dict[str, Any]: 35 | examples_embedding = [] 36 | for example in self.examples: 37 | examples_embedding.append(self.embedding.get_text_embedding(example["query"])) 38 | embed_dim = len(examples_embedding[0]) 39 | if len(self.examples) > 0: 40 | vector_index = VectorIndex(embed_dim) 41 | vector_index.add(examples_embedding, self.examples) 42 | vector_index.to_index_file(self.index_dir) 43 | context["embed_dim"] = embed_dim 44 | return context 45 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/index_op/build_vector_index.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | import os 20 | from typing import Dict, Any 21 | 22 | from tqdm import tqdm 23 | 24 | from hugegraph_llm.config import huge_settings, resource_path 25 | from hugegraph_llm.indices.vector_index import VectorIndex 26 | from hugegraph_llm.models.embeddings.base import BaseEmbedding 27 | from hugegraph_llm.utils.log import log 28 | 29 | 30 | class BuildVectorIndex: 31 | def __init__(self, embedding: BaseEmbedding): 32 | self.embedding = embedding 33 | self.index_dir = str(os.path.join(resource_path, huge_settings.graph_name, "chunks")) 34 | self.vector_index = VectorIndex.from_index_file(self.index_dir) 35 | 36 | def run(self, context: Dict[str, Any]) -> Dict[str, Any]: 37 | if "chunks" not in context: 38 | raise ValueError("chunks not found in context.") 39 | chunks = context["chunks"] 40 | chunks_embedding = [] 41 | log.debug("Building vector index for %s chunks...", len(context["chunks"])) 42 | # TODO: use async_get_texts_embedding instead of single sync method 43 | for chunk in tqdm(chunks): 44 | chunks_embedding.append(self.embedding.get_text_embedding(chunk)) 45 | if len(chunks_embedding) > 0: 46 | self.vector_index.add(chunks_embedding, chunks) 47 | self.vector_index.to_index_file(self.index_dir) 48 | return context 49 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/index_op/vector_index_query.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | import os 20 | from typing import Dict, Any 21 | 22 | from hugegraph_llm.config import resource_path, huge_settings 23 | from hugegraph_llm.indices.vector_index import VectorIndex 24 | from hugegraph_llm.models.embeddings.base import BaseEmbedding 25 | from hugegraph_llm.utils.log import log 26 | 27 | 28 | class VectorIndexQuery: 29 | def __init__(self, embedding: BaseEmbedding, topk: int = 3): 30 | self.embedding = embedding 31 | self.topk = topk 32 | self.index_dir = str(os.path.join(resource_path, huge_settings.graph_name, "chunks")) 33 | self.vector_index = VectorIndex.from_index_file(self.index_dir) 34 | 35 | def run(self, context: Dict[str, Any]) -> Dict[str, Any]: 36 | query = context.get("query") 37 | query_embedding = self.embedding.get_text_embedding(query) 38 | # TODO: why set dis_threshold=2? 39 | results = self.vector_index.search(query_embedding, self.topk, dis_threshold=2) 40 | # TODO: check format results 41 | context["vector_result"] = results 42 | log.debug("KNOWLEDGE FROM VECTOR:\n%s", "\n".join(rel for rel in context["vector_result"])) 43 | return context 44 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/llm_op/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/llm_op/disambiguate_data.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from typing import Dict, List, Any 20 | 21 | from hugegraph_llm.models.llms.base import BaseLLM 22 | from hugegraph_llm.operators.llm_op.info_extract import extract_triples_by_regex 23 | 24 | 25 | def generate_disambiguate_prompt(triples): 26 | return f""" 27 | Your task is to disambiguate the following triples: 28 | {triples} 29 | If the second element of the triples expresses the same meaning but in different ways, 30 | unify them and keep the most concise expression. 31 | 32 | For example, if the input is: 33 | [("Alice", "friend", "Bob"), ("Simon", "is friends with", "Bob")] 34 | 35 | The output should be: 36 | [("Alice", "friend", "Bob"), ("Simon", "friend", "Bob")] 37 | """ 38 | 39 | 40 | class DisambiguateData: 41 | def __init__(self, llm: BaseLLM) -> None: 42 | self.llm = llm 43 | 44 | def run(self, data: Dict) -> Dict[str, List[Any]]: 45 | # only disambiguate triples 46 | if "triples" in data: 47 | # TODO: ensure the logic here 48 | # log.debug(data) 49 | triples = data["triples"] 50 | prompt = generate_disambiguate_prompt(triples) 51 | llm_output = self.llm.generate(prompt=prompt) 52 | data["triples"] = [] 53 | extract_triples_by_regex(llm_output, data) 54 | print( 55 | f"LLM {self.__class__.__name__} input:{prompt} \n" 56 | f" output: {llm_output} \n data: {data}") 57 | data["call_count"] = data.get("call_count", 0) + 1 58 | 59 | return data 60 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/operators/llm_op/prompt_generate.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | import json 20 | import os 21 | from typing import Dict, Any 22 | 23 | from hugegraph_llm.config import resource_path, prompt as prompt_tpl 24 | from hugegraph_llm.models.llms.base import BaseLLM 25 | from hugegraph_llm.utils.log import log 26 | 27 | 28 | class PromptGenerate: 29 | def __init__(self, llm: BaseLLM): 30 | self.llm = llm 31 | 32 | def _load_few_shot_example(self, example_name: str) -> Dict[str, Any]: 33 | """Loads and finds the specified few-shot example from the unified JSON file.""" 34 | examples_path = os.path.join(resource_path, "prompt_examples", "prompt_examples.json") 35 | if not os.path.exists(examples_path): 36 | raise FileNotFoundError(f"Examples file not found: {examples_path}") 37 | with open(examples_path, "r", encoding="utf-8") as f: 38 | all_examples = json.load(f) 39 | for example in all_examples: 40 | if example.get("name") == example_name: 41 | return example 42 | raise ValueError(f"Example with name '{example_name}' not found in prompt_examples.json") 43 | 44 | def run(self, context: Dict[str, Any]) -> Dict[str, Any]: 45 | """Executes the core logic of prompt generation.""" 46 | source_text = context.get("source_text") 47 | scenario = context.get("scenario") 48 | example_name = context.get("example_name") 49 | 50 | if not all([source_text, scenario, example_name]): 51 | raise ValueError("Missing required context: source_text, scenario, or example_name.") 52 | few_shot_example = self._load_few_shot_example(example_name) 53 | 54 | meta_prompt = prompt_tpl.generate_extract_prompt_template.format( 55 | few_shot_text=few_shot_example.get('text', ''), 56 | few_shot_prompt=few_shot_example.get('prompt', ''), 57 | user_text=source_text, 58 | user_scenario=scenario 59 | ) 60 | log.debug("Meta-prompt sent to LLM: %s", meta_prompt) 61 | generated_prompt = self.llm.generate(prompt=meta_prompt) 62 | log.debug("Generated prompt from LLM: %s", generated_prompt) 63 | 64 | context["generated_extract_prompt"] = generated_prompt 65 | return context 66 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/resources/demo/css.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | CSS = """ 19 | footer { 20 | visibility: hidden 21 | } 22 | 23 | .code-container-edit { 24 | max-height: 520px; 25 | overflow-y: auto; /* enable scroll */ 26 | } 27 | 28 | .code-container-show { 29 | max-height: 250px; 30 | overflow-y: auto; /* enable scroll */ 31 | } 32 | 33 | /* FIXME: wrap code is not work as expected now */ 34 | .wrap-code { 35 | white-space: pre-wrap; /* CSS3 */ 36 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 37 | white-space: -pre-wrap; /* Opera 4-6 */ 38 | white-space: -o-pre-wrap; /* Opera 7 */ 39 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 40 | } 41 | 42 | .output-box { 43 | border: 1px solid #ccc; 44 | border-radius: 5px; 45 | padding: 8px; 46 | box-sizing: border-box; 47 | min-height: 50px; 48 | font-family: Arial, sans-serif; 49 | line-height: 1.5; 50 | margin-top: -5px; 51 | width: 99.5%; 52 | max-height: 300px; 53 | overflow-y: auto; 54 | } 55 | 56 | .output-box-label { 57 | font-size: 14px; 58 | font-weight: bold; 59 | margin-bottom: -5px; 60 | } 61 | """ 62 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/resources/demo/test.txt: -------------------------------------------------------------------------------- 1 | Meet Sarah, a 30-year-old attorney, and her roommate, James, whom she's shared a home with since 2010. James, in his professional life, works as a journalist. Additionally, Sarah is the proud owner of the website www.sarahsplace.com, while James manages his own webpage, though the specific URL is not mentioned here. These two individuals, Sarah and James, have not only forged a strong personal bond as roommates but have also carved out their distinctive digital presence through their respective webpages, showcasing their varied interests and experiences. 2 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/resources/nltk_data/corpora/stopwords/english: -------------------------------------------------------------------------------- 1 | i 2 | me 3 | my 4 | myself 5 | we 6 | our 7 | ours 8 | ourselves 9 | you 10 | you're 11 | you've 12 | you'll 13 | you'd 14 | your 15 | yours 16 | yourself 17 | yourselves 18 | he 19 | him 20 | his 21 | himself 22 | she 23 | she's 24 | her 25 | hers 26 | herself 27 | it 28 | it's 29 | its 30 | itself 31 | they 32 | them 33 | their 34 | theirs 35 | themselves 36 | what 37 | which 38 | who 39 | whom 40 | this 41 | that 42 | that'll 43 | these 44 | those 45 | am 46 | is 47 | are 48 | was 49 | were 50 | be 51 | been 52 | being 53 | have 54 | has 55 | had 56 | having 57 | do 58 | does 59 | did 60 | doing 61 | a 62 | an 63 | the 64 | and 65 | but 66 | if 67 | or 68 | because 69 | as 70 | until 71 | while 72 | of 73 | at 74 | by 75 | for 76 | with 77 | about 78 | against 79 | between 80 | into 81 | through 82 | during 83 | before 84 | after 85 | above 86 | below 87 | to 88 | from 89 | up 90 | down 91 | in 92 | out 93 | on 94 | off 95 | over 96 | under 97 | again 98 | further 99 | then 100 | once 101 | here 102 | there 103 | when 104 | where 105 | why 106 | how 107 | all 108 | any 109 | both 110 | each 111 | few 112 | more 113 | most 114 | other 115 | some 116 | such 117 | no 118 | nor 119 | not 120 | only 121 | own 122 | same 123 | so 124 | than 125 | too 126 | very 127 | s 128 | t 129 | can 130 | will 131 | just 132 | don 133 | don't 134 | should 135 | should've 136 | now 137 | d 138 | ll 139 | m 140 | o 141 | re 142 | ve 143 | y 144 | ain 145 | aren 146 | aren't 147 | couldn 148 | couldn't 149 | didn 150 | didn't 151 | doesn 152 | doesn't 153 | hadn 154 | hadn't 155 | hasn 156 | hasn't 157 | haven 158 | haven't 159 | isn 160 | isn't 161 | ma 162 | mightn 163 | mightn't 164 | mustn 165 | mustn't 166 | needn 167 | needn't 168 | shan 169 | shan't 170 | shouldn 171 | shouldn't 172 | wasn 173 | wasn't 174 | weren 175 | weren't 176 | won 177 | won't 178 | wouldn 179 | wouldn't 180 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/resources/prompt_examples/query_examples.json: -------------------------------------------------------------------------------- 1 | [ 2 | "Property filter: Find all 'person' nodes with age > 30 and return their name and occupation", 3 | "Relationship traversal: Find all roommates of the person named Alice, and return their name and age", 4 | "Shortest path: Find the shortest path between Bob and Charlie and show the edge labels along the way", 5 | "Subgraph match: Find all friend pairs who both follow the same webpage, and return the names and URL", 6 | "Aggregation: Count the number of people for each occupation and compute their average age", 7 | "Time-based filter: Find all nodes created after 2025-01-01 and return their name and created_at", 8 | "Top-N query: List top 10 most visited webpages with their URL and visit_count" 9 | ] 10 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/resources/prompt_examples/schema_examples.json: -------------------------------------------------------------------------------- 1 | { 2 | "vertexlabels": [ 3 | { 4 | "id": 1, 5 | "name": "person", 6 | "id_strategy": "PRIMARY_KEY", 7 | "primary_keys": [ 8 | "name" 9 | ], 10 | "properties": [ 11 | "name", 12 | "age", 13 | "occupation" 14 | ] 15 | }, 16 | { 17 | "id": 2, 18 | "name": "webpage", 19 | "id_strategy": "PRIMARY_KEY", 20 | "primary_keys": [ 21 | "name" 22 | ], 23 | "properties": [ 24 | "name", 25 | "url" 26 | ] 27 | } 28 | ], 29 | "edgelabels": [ 30 | { 31 | "id": 1, 32 | "name": "roommate", 33 | "source_label": "person", 34 | "target_label": "person", 35 | "properties": [ 36 | "date" 37 | ] 38 | }, 39 | { 40 | "id": 2, 41 | "name": "link", 42 | "source_label": "webpage", 43 | "target_label": "person", 44 | "properties": [] 45 | } 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/utils/anchor.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from pathlib import Path 17 | 18 | def get_project_root() -> Path: 19 | """ 20 | Returns the Path object of the project root directory. 21 | 22 | The function searches for common project root indicators like pyproject.toml 23 | or .git directory by traversing up the directory tree from the current file location. 24 | 25 | Returns: 26 | Path: The absolute path to the project root directory 27 | 28 | Raises: 29 | RuntimeError: If no project root indicators could be found 30 | """ 31 | current_path = Path(__file__).resolve() 32 | for parent in current_path.parents: 33 | if (parent / "pyproject.toml").exists() or (parent / ".git").exists(): 34 | return parent 35 | # Raise an error if no project root is found 36 | raise RuntimeError( 37 | "Project root could not be determined. " 38 | "Ensure that 'pyproject.toml' or '.git' exists in the project directory." 39 | ) 40 | -------------------------------------------------------------------------------- /hugegraph-llm/src/hugegraph_llm/utils/log.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | import logging 17 | import os 18 | 19 | from pyhugegraph.utils.log import init_logger 20 | 21 | # Configure common settings 22 | LOG_DIR = "logs" 23 | os.makedirs(LOG_DIR, exist_ok=True) 24 | LOG_FILE = os.path.join(LOG_DIR, "llm-server.log") 25 | INFO = logging.INFO 26 | 27 | # Initialize the root logger first with Rich handler 28 | root_logger = init_logger( 29 | log_output=LOG_FILE, 30 | log_level=INFO, 31 | logger_name="root", 32 | propagate_logs=True, 33 | stdout_logging=True 34 | ) 35 | 36 | # Initialize custom logger 37 | log = init_logger( 38 | log_output=LOG_FILE, 39 | log_level=logging.DEBUG, # Adjust level if needed 40 | logger_name="llm", 41 | ) 42 | 43 | # Configure Uvicorn (FastAPI) logging 44 | uvicorn_logger = logging.getLogger("uvicorn") 45 | uvicorn_logger.handlers.clear() 46 | uvicorn_logger.handlers.extend(root_logger.handlers) 47 | uvicorn_logger.setLevel(INFO) 48 | 49 | # Configure Gradio logging 50 | gradio_logger = logging.getLogger("gradio") 51 | gradio_logger.handlers.clear() # remove default handlers 52 | gradio_logger.handlers.extend(root_logger.handlers) 53 | gradio_logger.setLevel(INFO) 54 | 55 | # Suppress `watchfiles` logging 56 | watchfiles_logger = logging.getLogger("watchfiles") 57 | watchfiles_logger.handlers.clear() 58 | watchfiles_logger.handlers.extend(root_logger.handlers) 59 | watchfiles_logger.setLevel(logging.ERROR) 60 | -------------------------------------------------------------------------------- /hugegraph-llm/src/tests/config/test_config.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | import unittest 20 | 21 | 22 | class TestConfig(unittest.TestCase): 23 | def test_config(self): 24 | import nltk 25 | from hugegraph_llm.config import resource_path 26 | nltk.data.path.append(resource_path) 27 | nltk.data.find("corpora/stopwords") 28 | -------------------------------------------------------------------------------- /hugegraph-llm/src/tests/indices/test_vector_index.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | import unittest 20 | from pprint import pprint 21 | 22 | from hugegraph_llm.indices.vector_index import VectorIndex 23 | from hugegraph_llm.models.embeddings.ollama import OllamaEmbedding 24 | 25 | 26 | class TestVectorIndex(unittest.TestCase): 27 | def test_vector_index(self): 28 | embedder = OllamaEmbedding("quentinz/bge-large-zh-v1.5") 29 | data = ["腾讯的合伙人有字节跳动", "谷歌和微软是竞争关系", "美团的合伙人有字节跳动"] 30 | data_embedding = [embedder.get_text_embedding(d) for d in data] 31 | index = VectorIndex(1024) 32 | index.add(data_embedding, data) 33 | query = "腾讯的合伙人有哪些?" 34 | query_vector = embedder.get_text_embedding(query) 35 | results = index.search(query_vector, 2) 36 | pprint(results) 37 | -------------------------------------------------------------------------------- /hugegraph-llm/src/tests/models/embeddings/test_ollama_embedding.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | import unittest 20 | 21 | from hugegraph_llm.models.embeddings.base import SimilarityMode 22 | from hugegraph_llm.models.embeddings.ollama import OllamaEmbedding 23 | 24 | 25 | class TestOllamaEmbedding(unittest.TestCase): 26 | def test_get_text_embedding(self): 27 | ollama_embedding = OllamaEmbedding(model="quentinz/bge-large-zh-v1.5") 28 | embedding = ollama_embedding.get_text_embedding("hello world") 29 | print(embedding) 30 | 31 | def test_get_cosine_similarity(self): 32 | ollama_embedding = OllamaEmbedding(model="quentinz/bge-large-zh-v1.5") 33 | embedding1 = ollama_embedding.get_text_embedding("hello world") 34 | embedding2 = ollama_embedding.get_text_embedding("bye world") 35 | similarity = OllamaEmbedding.similarity(embedding1, embedding2, SimilarityMode.DEFAULT) 36 | print(similarity) 37 | -------------------------------------------------------------------------------- /hugegraph-llm/src/tests/models/embeddings/test_openai_embedding.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | import unittest 20 | 21 | 22 | class TestOpenAIEmbedding(unittest.TestCase): 23 | def test_embedding_dimension(self): 24 | from hugegraph_llm.models.embeddings.openai import OpenAIEmbedding 25 | embedding = OpenAIEmbedding(api_key="") 26 | result = embedding.get_text_embedding("hello world!") 27 | print(result) 28 | -------------------------------------------------------------------------------- /hugegraph-llm/src/tests/models/llms/test_ollama_client.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import unittest 19 | 20 | from hugegraph_llm.models.llms.ollama import OllamaClient 21 | 22 | 23 | class TestOllamaClient(unittest.TestCase): 24 | def test_generate(self): 25 | ollama_client = OllamaClient(model="llama3:8b-instruct-fp16") 26 | response = ollama_client.generate(prompt="What is the capital of France?") 27 | print(response) 28 | 29 | def test_stream_generate(self): 30 | ollama_client = OllamaClient(model="llama3:8b-instruct-fp16") 31 | def on_token_callback(chunk): 32 | print(chunk, end="", flush=True) 33 | ollama_client.generate_streaming(prompt="What is the capital of France?", 34 | on_token_callback=on_token_callback) 35 | -------------------------------------------------------------------------------- /hugegraph-llm/src/tests/operators/common_op/test_nltk_helper.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | import unittest 20 | 21 | 22 | class TestNLTKHelper(unittest.TestCase): 23 | def test_stopwords(self): 24 | from hugegraph_llm.operators.common_op.nltk_helper import NLTKHelper 25 | nltk_helper = NLTKHelper() 26 | stopwords = nltk_helper.stopwords() 27 | print(stopwords) 28 | -------------------------------------------------------------------------------- /hugegraph-python-client/pyproject.toml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | [project] 19 | name = "hugegraph-python-client" 20 | version = "1.5.0" 21 | description = "A Python SDK for Apache HugeGraph Database." 22 | authors = [ 23 | { name = "Apache HugeGraph Contributors", email = "dev@hugegraph.apache.org" }, 24 | ] 25 | readme = "README.md" 26 | license = "Apache-2.0" 27 | requires-python = ">=3.9" 28 | 29 | dependencies = [ 30 | "decorator~=5.1.1", 31 | "requests~=2.32.0", 32 | "setuptools~=70.0.0", 33 | "urllib3~=2.2.2", 34 | "rich~=13.9.4", 35 | ] 36 | 37 | [project.urls] 38 | "Homepage" = "https://github.com/apache/incubator-hugegraph-ai" 39 | "Repository" = "https://github.com/apache/incubator-hugegraph-ai" 40 | "Bug Tracker" = "https://github.com/apache/incubator-hugegraph-ai/issues" 41 | 42 | [build-system] 43 | requires = ["setuptools>=61.0"] 44 | build-backend = "setuptools.build_meta" 45 | 46 | [tool.setuptools.packages.find] 47 | where = ["src"] 48 | exclude = ["tests"] 49 | 50 | [tool.setuptools] 51 | package-dir = {"" = "src"} 52 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/api/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/api/graphs.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import json 19 | 20 | from pyhugegraph.api.common import HugeParamsBase 21 | from pyhugegraph.utils import huge_router as router 22 | from pyhugegraph.utils.util import ResponseValidation 23 | 24 | 25 | class GraphsManager(HugeParamsBase): 26 | 27 | @router.http("GET", "/graphs") 28 | def get_all_graphs(self) -> dict: 29 | return self._invoke_request(validator=ResponseValidation("text")) 30 | 31 | @router.http("GET", "/versions") 32 | def get_version(self) -> dict: 33 | return self._invoke_request(validator=ResponseValidation("text")) 34 | 35 | @router.http("GET", "") 36 | def get_graph_info(self) -> dict: 37 | return self._invoke_request(validator=ResponseValidation("text")) 38 | 39 | def clear_graph_all_data(self) -> dict: 40 | if self._sess.cfg.gs_supported: 41 | response = self._sess.request( 42 | "", 43 | "PUT", 44 | validator=ResponseValidation("text"), 45 | data=json.dumps({"action": "clear", "clear_schema": True}), 46 | ) 47 | else: 48 | response = self._sess.request( 49 | "clear?confirm_message=I%27m+sure+to+delete+all+data", 50 | "DELETE", 51 | validator=ResponseValidation("text"), 52 | ) 53 | return response 54 | 55 | @router.http("GET", "conf") 56 | def get_graph_config(self) -> dict: 57 | return self._invoke_request(validator=ResponseValidation("text")) 58 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/api/gremlin.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from pyhugegraph.api.common import HugeParamsBase 20 | from pyhugegraph.utils.exceptions import NotFoundError 21 | from pyhugegraph.structure.gremlin_data import GremlinData 22 | from pyhugegraph.structure.response_data import ResponseData 23 | from pyhugegraph.utils import huge_router as router 24 | from pyhugegraph.utils.log import log 25 | 26 | 27 | class GremlinManager(HugeParamsBase): 28 | 29 | @router.http("POST", "/gremlin") 30 | def exec(self, gremlin): 31 | gremlin_data = GremlinData(gremlin) 32 | if self._sess.cfg.gs_supported: 33 | gremlin_data.aliases = { 34 | "graph": f"{self._sess.cfg.graphspace}-{self._sess.cfg.graph_name}", 35 | "g": f"__g_{self._sess.cfg.graphspace}-{self._sess.cfg.graph_name}", 36 | } 37 | else: 38 | gremlin_data.aliases = { 39 | "graph": f"{self._sess.cfg.graph_name}", 40 | "g": f"__g_{self._sess.cfg.graph_name}", 41 | } 42 | 43 | try: 44 | if response := self._invoke_request(data=gremlin_data.to_json()): 45 | return ResponseData(response).result 46 | log.error( # pylint: disable=logging-fstring-interpolation 47 | f"Gremlin can't get results: {str(response)}" 48 | ) 49 | return None 50 | except Exception as e: 51 | raise NotFoundError(f"Gremlin can't get results: {e}") from e 52 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/api/metric.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from pyhugegraph.api.common import HugeParamsBase 19 | from pyhugegraph.utils import huge_router as router 20 | 21 | 22 | class MetricsManager(HugeParamsBase): 23 | 24 | @router.http("GET", "/metrics/?type=json") 25 | def get_all_basic_metrics(self) -> dict: 26 | return self._invoke_request() 27 | 28 | @router.http("GET", "/metrics/gauges") 29 | def get_gauges_metrics(self) -> dict: 30 | return self._invoke_request() 31 | 32 | @router.http("GET", "/metrics/counters") 33 | def get_counters_metrics(self) -> dict: 34 | return self._invoke_request() 35 | 36 | @router.http("GET", "/metrics/gauges") 37 | def get_histograms_metrics(self) -> dict: 38 | return self._invoke_request() 39 | 40 | @router.http("GET", "/metrics/meters") 41 | def get_meters_metrics(self) -> dict: 42 | return self._invoke_request() 43 | 44 | @router.http("GET", "/metrics/timers") 45 | def get_timers_metrics(self) -> dict: 46 | return self._invoke_request() 47 | 48 | @router.http("GET", "/metrics/statistics/?type=json") 49 | def get_statistics_metrics(self) -> dict: 50 | return self._invoke_request() 51 | 52 | @router.http("GET", "/metrics/system") 53 | def get_system_metrics(self) -> dict: 54 | return self._invoke_request() 55 | 56 | @router.http("GET", "/metrics/backend") 57 | def get_backend_metrics(self) -> dict: 58 | return self._invoke_request() 59 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/api/rank.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from pyhugegraph.utils import huge_router as router 20 | from pyhugegraph.structure.rank_data import ( 21 | PersonalRankParameters, 22 | NeighborRankParameters, 23 | ) 24 | from pyhugegraph.api.common import HugeParamsBase 25 | 26 | 27 | class RankManager(HugeParamsBase): 28 | """ 29 | This class provides methods to interact with the rank APIs in HugeGraphServer. 30 | It allows for personalized recommendations based on graph traversal and ranking algorithms. 31 | 32 | Methods: 33 | personal_rank(source, label, alpha=0.85, max_degree=10000, max_depth=5, 34 | limit=100, sorted=True, with_label="BOTH_LABEL"): 35 | Computes the Personal Rank for a given source vertex and edge label. 36 | 37 | neighbor_rank(source, steps, alpha=0.85, capacity=10000000): 38 | Computes the Neighbor Rank for a given source vertex and defined steps. 39 | """ 40 | 41 | @router.http("POST", "traversers/personalrank") 42 | def personal_rank(self, body_params: PersonalRankParameters): 43 | """ 44 | Computes the Personal Rank for a given source vertex and edge label. 45 | 46 | Args: 47 | body_params (PersonalRankParameters): BodyParams defines the body parameters for the rank API requests. 48 | 49 | Returns: 50 | dict: A dictionary containing the ranked list of vertices and their corresponding rank values. 51 | """ 52 | return self._invoke_request(data=body_params.dumps()) 53 | 54 | @router.http("POST", "traversers/neighborrank") 55 | def neighbor_rank(self, body_params: NeighborRankParameters): 56 | """ 57 | Computes the Neighbor Rank for a given source vertex and defined steps. 58 | 59 | Args: 60 | body_params (NeighborRankParameters): BodyParams defines the body parameters for the rank API requests. 61 | 62 | Returns: 63 | dict: A dictionary containing the probability of reaching other vertices from the source vertex. 64 | """ 65 | return self._invoke_request(data=body_params.dumps()) 66 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/api/schema_manage/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/api/task.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from pyhugegraph.api.common import HugeParamsBase 19 | from pyhugegraph.utils import huge_router as router 20 | 21 | 22 | class TaskManager(HugeParamsBase): 23 | 24 | @router.http("GET", "tasks") 25 | def list_tasks(self, status=None, limit=None): 26 | params = {} 27 | if status is not None: 28 | params["status"] = status 29 | if limit is not None: 30 | params["limit"] = limit 31 | return self._invoke_request(params=params) 32 | 33 | @router.http("GET", "tasks/{task_id}") 34 | def get_task(self, task_id): # pylint: disable=unused-argument 35 | return self._invoke_request() 36 | 37 | @router.http("DELETE", "tasks/{task_id}") 38 | def delete_task(self, task_id): # pylint: disable=unused-argument 39 | return self._invoke_request() 40 | 41 | @router.http("PUT", "tasks/{task_id}?action=cancel") 42 | def cancel_task(self, task_id): # pylint: disable=unused-argument 43 | return self._invoke_request() 44 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/api/variable.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import json 19 | 20 | from pyhugegraph.api.common import HugeParamsBase 21 | from pyhugegraph.utils import huge_router as router 22 | 23 | 24 | class VariableManager(HugeParamsBase): 25 | 26 | @router.http("PUT", "variables/{key}") 27 | def set(self, key, value): # pylint: disable=unused-argument 28 | return self._invoke_request(data=json.dumps({"data": value})) 29 | 30 | @router.http("GET", "variables/{key}") 31 | def get(self, key): # pylint: disable=unused-argument 32 | return self._invoke_request() 33 | 34 | @router.http("GET", "variables") 35 | def all(self): 36 | return self._invoke_request() 37 | 38 | @router.http("DELETE", "variables/{key}") 39 | def remove(self, key): # pylint: disable=unused-argument 40 | return self._invoke_request() 41 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/api/version.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from pyhugegraph.api.common import HugeParamsBase 19 | from pyhugegraph.utils import huge_router as router 20 | 21 | 22 | class VersionManager(HugeParamsBase): 23 | 24 | @router.http("GET", "/versions") 25 | def version(self): 26 | return self._invoke_request() 27 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/example/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/example/hugegraph_example.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from pyhugegraph.client import PyHugeClient 19 | 20 | if __name__ == "__main__": 21 | client = PyHugeClient( 22 | url="http://127.0.0.1:8080", user="admin", pwd="admin", graph="hugegraph", graphspace=None 23 | ) 24 | 25 | """schema""" 26 | schema = client.schema() 27 | schema.propertyKey("name").asText().ifNotExist().create() 28 | schema.propertyKey("birthDate").asText().ifNotExist().create() 29 | schema.vertexLabel("Person").properties( 30 | "name", "birthDate" 31 | ).usePrimaryKeyId().primaryKeys("name").ifNotExist().create() 32 | schema.vertexLabel("Movie").properties("name").usePrimaryKeyId().primaryKeys( 33 | "name" 34 | ).ifNotExist().create() 35 | schema.edgeLabel("ActedIn").sourceLabel("Person").targetLabel( 36 | "Movie" 37 | ).ifNotExist().create() 38 | 39 | print(schema.getVertexLabels()) 40 | print(schema.getEdgeLabels()) 41 | print(schema.getRelations()) 42 | 43 | """graph""" 44 | g = client.graph() 45 | # add Vertex 46 | p1 = g.addVertex("Person", {"name": "Al Pacino", "birthDate": "1940-04-25"}) 47 | p2 = g.addVertex("Person", {"name": "Robert De Niro", "birthDate": "1943-08-17"}) 48 | m1 = g.addVertex("Movie", {"name": "The Godfather"}) 49 | m2 = g.addVertex("Movie", {"name": "The Godfather Part II"}) 50 | m3 = g.addVertex( 51 | "Movie", {"name": "The Godfather Coda The Death of Michael Corleone"} 52 | ) 53 | 54 | # add Edge 55 | g.addEdge("ActedIn", p1.id, m1.id, {}) 56 | g.addEdge("ActedIn", p1.id, m2.id, {}) 57 | g.addEdge("ActedIn", p1.id, m3.id, {}) 58 | g.addEdge("ActedIn", p2.id, m2.id, {}) 59 | 60 | # update property 61 | # g.eliminateVertex("vertex_id", {"property_key": "property_value"}) 62 | 63 | print(g.getVertexById(p1.id).label) 64 | # g.removeVertexById("12:Al Pacino") 65 | g.close() 66 | 67 | """gremlin""" 68 | g = client.gremlin() 69 | print("gremlin.exec: ", g.exec("g.V().limit(10)")) 70 | 71 | """graphs""" 72 | g = client.graphs() 73 | print("get_graph_info: ", g.get_graph_info()) 74 | print("get_all_graphs: ", g.get_all_graphs()) 75 | print("get_version: ", g.get_version()) 76 | print("get_graph_config: ", g.get_graph_config()) 77 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/example/hugegraph_test.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | class HugeGraph: 20 | """HugeGraph wrapper for graph operations""" 21 | 22 | def __init__( 23 | self, 24 | username: str = "default", 25 | password: str = "default", 26 | url: str = "http://127.0.0.1:8081", 27 | graph: str = "hugegraph", 28 | ) -> None: 29 | """Create a new HugeGraph wrapper instance.""" 30 | try: 31 | from pyhugegraph.client import PyHugeClient 32 | except ImportError: 33 | raise ValueError( 34 | "Please install HugeGraph Python client first: " 35 | "`pip3 install hugegraph-python-client`" 36 | ) from ImportError 37 | 38 | self.username = username 39 | self.password = password 40 | self.url = url 41 | self.graph = graph 42 | self.client = PyHugeClient( 43 | url=url, user=username, pwd=password, graph=graph, graphspace=None 44 | ) 45 | self.schema = "" 46 | 47 | def exec(self, query) -> str: 48 | """Returns the schema of the HugeGraph database""" 49 | return self.client.gremlin().exec(query) 50 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/structure/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/structure/edge_data.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | class EdgeData: 20 | def __init__(self, dic): 21 | self.__id = dic["id"] 22 | self.__label = dic["label"] if "label" in dic else None 23 | self.__type = dic["type"] if "type" in dic else None 24 | self.__outV = dic["outV"] if "outV" in dic else None 25 | self.__outVLabel = dic["outVLabel"] if "outVLabel" in dic else None 26 | self.__inV = dic["inV"] if "inV" in dic else None 27 | self.__inVLabel = dic["inVLabel"] if "inVLabel" in dic else None 28 | self.__properties = dic["properties"] if "properties" in dic else None 29 | 30 | @property 31 | def id(self): 32 | return self.__id 33 | 34 | @property 35 | def label(self): 36 | return self.__label 37 | 38 | @property 39 | def type(self): 40 | return self.__type 41 | 42 | @property 43 | def outV(self): 44 | return self.__outV 45 | 46 | @property 47 | def outVLabel(self): 48 | return self.__outVLabel 49 | 50 | @property 51 | def inV(self): 52 | return self.__inV 53 | 54 | @property 55 | def inVLabel(self): 56 | return self.__inVLabel 57 | 58 | @property 59 | def properties(self): 60 | return self.__properties 61 | 62 | def __repr__(self): 63 | res = f"{self.__outV}--{self.__label}-->{self.__inV}" 64 | return res 65 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/structure/edge_label_data.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | class EdgeLabelData: 20 | def __init__(self, dic): 21 | self.__id = dic["id"] 22 | self.__name = dic["name"] 23 | self.__source_label = dic["source_label"] 24 | self.__target_label = dic["target_label"] 25 | self.__frequency = dic["frequency"] 26 | self.__sort_keys = dic["sort_keys"] 27 | self.__nullable_keys = dic["nullable_keys"] 28 | self.__index_labels = dic["index_labels"] 29 | self.__properties = dic["properties"] 30 | self.__enable_label_index = dic["enable_label_index"] 31 | self.__user_data = dic["user_data"] 32 | 33 | @property 34 | def id(self): 35 | return self.__id 36 | 37 | @property 38 | def name(self): 39 | return self.__name 40 | 41 | @property 42 | def sourceLabel(self): 43 | return self.__source_label 44 | 45 | @property 46 | def targetLabel(self): 47 | return self.__target_label 48 | 49 | @property 50 | def frequency(self): 51 | return self.__frequency 52 | 53 | @property 54 | def sortKeys(self): 55 | return self.__sort_keys 56 | 57 | @property 58 | def properties(self): 59 | return self.__properties 60 | 61 | @property 62 | def nullableKeys(self): 63 | return self.__nullable_keys 64 | 65 | @property 66 | def userdata(self): 67 | return self.__user_data 68 | 69 | def relations(self): 70 | res = f"{self.__source_label}--{self.__name}-->{self.__target_label}" 71 | return res 72 | 73 | @property 74 | def indexLabels(self): 75 | return self.__index_labels 76 | 77 | @property 78 | def enableLabelIndex(self): 79 | return self.__enable_label_index 80 | 81 | def __repr__(self): 82 | res = f"name: {self.__name}, properties: {self.__properties}" 83 | return res 84 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/structure/gremlin_data.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import json 19 | 20 | 21 | class GremlinData: 22 | def __init__(self, gremlin): 23 | self.__gremlin = gremlin 24 | self.__bindings = {} 25 | self.__language = "gremlin-groovy" 26 | self.__aliases = {} 27 | 28 | @property 29 | def gremlin(self): 30 | return self.__gremlin 31 | 32 | @gremlin.setter 33 | def gremlin(self, _gremlin): 34 | self.__gremlin = _gremlin 35 | 36 | @property 37 | def bindings(self): 38 | return self.__bindings 39 | 40 | @bindings.setter 41 | def bindings(self, _bindings): 42 | self.__bindings = _bindings 43 | 44 | @property 45 | def language(self): 46 | return self.__language 47 | 48 | @language.setter 49 | def language(self, _language): 50 | self.__language = _language 51 | 52 | @property 53 | def aliases(self): 54 | return self.__aliases 55 | 56 | @aliases.setter 57 | def aliases(self, _aliases): 58 | self.__aliases = _aliases 59 | 60 | def __repr__(self): 61 | res = ( 62 | f"gremlin: {self.__gremlin}, bindings: {self.__bindings}," 63 | f"language: {self.__language}, aliases: {self.__aliases}" 64 | ) 65 | return res 66 | 67 | def to_json(self): 68 | return json.dumps(self, cls=GremlinDataEncoder) 69 | 70 | 71 | class GremlinDataEncoder(json.JSONEncoder): 72 | def default(self, o): 73 | return {k.split("__")[1]: v for k, v in vars(o).items()} 74 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/structure/index_label_data.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | class IndexLabelData: 20 | def __init__(self, dic): 21 | self.__id = dic["id"] if "id" in dic else None 22 | self.__base_type = dic["base_type"] if "base_type" in dic else None 23 | self.__base_value = dic["base_value"] if "base_value" in dic else None 24 | self.__name = dic["name"] if "name" in dic else None 25 | self.__fields = dic["fields"] if "fields" in dic else None 26 | self.__index_type = dic["index_type"] if "index_type" in dic else None 27 | 28 | @property 29 | def id(self): 30 | return self.__id 31 | 32 | @property 33 | def baseType(self): 34 | return self.__base_type 35 | 36 | @property 37 | def baseValue(self): 38 | return self.__base_value 39 | 40 | @property 41 | def name(self): 42 | return self.__name 43 | 44 | @property 45 | def fields(self): 46 | return self.__fields 47 | 48 | @property 49 | def indexType(self): 50 | return self.__index_type 51 | 52 | def __repr__(self): 53 | res = ( 54 | f"index_name: {self.__name}, base_value: {self.__base_value}, base_type:" 55 | f" {self.__base_type}, fields: {self.__fields}, index_type: {self.__index_type}" 56 | ) 57 | return res 58 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/structure/property_key_data.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | # from dataclasses import dataclass, field 19 | 20 | 21 | # @dataclass 22 | # class PropertyKeyData: 23 | # id: int 24 | # name: str 25 | # cardinality: str 26 | # data_type: str 27 | # properties: list = field(default_factory=list) 28 | # user_data: dict = field(default_factory=dict) 29 | 30 | # @classmethod 31 | # def from_dict(cls, data: dict): 32 | # filtered_data = {k: v for k, v in data.items() if k in cls.__annotations__} 33 | # return cls(**filtered_data) 34 | 35 | 36 | class PropertyKeyData: 37 | def __init__(self, dic): 38 | self.__id = dic["id"] 39 | self.__name = dic["name"] 40 | self.__cardinality = dic["cardinality"] 41 | self.__data_type = dic["data_type"] 42 | self.__user_data = dic["user_data"] 43 | 44 | @property 45 | def id(self): 46 | return self.__id 47 | 48 | @property 49 | def cardinality(self): 50 | return self.__cardinality 51 | 52 | @property 53 | def name(self): 54 | return self.__name 55 | 56 | @property 57 | def dataType(self): 58 | return self.__data_type 59 | 60 | @property 61 | def userdata(self): 62 | return self.__user_data 63 | 64 | def __repr__(self): 65 | res = f"name: {self.__name}, cardinality: {self.__cardinality}, data_type: {self.__data_type}" 66 | return res 67 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/structure/response_data.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | class ResponseData: 20 | def __init__(self, dic): 21 | self.__id = dic["requestId"] 22 | self.__status = dic["status"] 23 | self.__result = dic["result"] 24 | 25 | @property 26 | def id(self): 27 | return self.__id 28 | 29 | @property 30 | def status(self): 31 | return self.__status 32 | 33 | @property 34 | def result(self): 35 | return self.__result 36 | 37 | def __repr__(self): 38 | res = f"id: {self.__id}, status: {self.__status}, result: {self.__result}" 39 | return res 40 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/structure/services_data.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import json 19 | 20 | from typing import List, Optional 21 | from dataclasses import asdict, dataclass, field 22 | 23 | 24 | @dataclass 25 | class ServiceCreateParameters: 26 | """ 27 | Data class representing the request body for HugeGraph services. 28 | 29 | Attributes: 30 | - name (str): The name of the service. It must consist of lowercase letters, numbers, and underscores. 31 | The first character must be a lowercase letter and the length must not exceed 48. 32 | - description (str): A description of the service. 33 | - type (str): The type of service. Currently, only 'OLTP' is allowed. Default is 'OLTP'. 34 | - count (int): The number of HugeGraphServer instances. Must be greater than 0. Default is 1. 35 | - cpu_limit (int): The number of CPU cores per HugeGraphServer instance. Must be greater than 0. Default is 1. 36 | - memory_limit (int): The memory size per HugeGraphServer instance in GB. Must be greater than 0. Default is 4. 37 | - storage_limit (int): The disk size for HStore in GB. Must be greater than 0. Default is 100. 38 | - route_type (str): Required when deployment_type is 'K8S'. 39 | Accepted values are 'ClusterIP', 'LoadBalancer', 'NodePort'. 40 | - port (int): Required when deployment_type is 'K8S'. Must be greater than 0. 41 | Default is None and invalid for other deployment types. 42 | - urls (List[str]): Required when deployment_type is 'MANUAL'. 43 | Should not be provided for other deployment types. 44 | - deployment_type (str): The deployment type of the service. 45 | 'K8S' indicates service deployment through a Kubernetes cluster, 46 | 'MANUAL' indicates manual service deployment. Default is an empty string. 47 | """ 48 | 49 | name: str 50 | description: str 51 | type: str = "OLTP" 52 | count: int = 1 53 | cpu_limit: int = 1 54 | memory_limit: int = 4 55 | storage_limit: int = 100 56 | route_type: Optional[str] = None 57 | port: Optional[int] = None 58 | urls: List[str] = field(default_factory=list) 59 | deployment_type: Optional[str] = None 60 | 61 | def dumps(self): 62 | return json.dumps(asdict(self)) 63 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/structure/vertex_data.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | class VertexData: 20 | def __init__(self, dic): 21 | self.__id = dic["id"] 22 | self.__label = dic["label"] if "label" in dic else None 23 | self.__type = dic["type"] if "type" in dic else None 24 | self.__properties = dic["properties"] if "properties" in dic else None 25 | 26 | @property 27 | def id(self): 28 | return self.__id 29 | 30 | @property 31 | def label(self): 32 | return self.__label 33 | 34 | @property 35 | def type(self): 36 | return self.__type 37 | 38 | @property 39 | def properties(self): 40 | return self.__properties 41 | 42 | def __repr__(self): 43 | res = f"id: {self.__id}, label: {self.__label}, type: {self.__type}" 44 | return res 45 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/structure/vertex_label_data.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | class VertexLabelData: 20 | def __init__(self, dic): 21 | self.__id = dic["id"] 22 | self.__name = dic["name"] 23 | self.__id_strategy = dic["id_strategy"] 24 | self.__primary_keys = dic["primary_keys"] 25 | self.__nullable_keys = dic["nullable_keys"] 26 | self.__index_labels = dic["index_labels"] 27 | self.__properties = dic["properties"] 28 | self.__enable_label_index = dic["enable_label_index"] 29 | self.__user_data = dic["user_data"] 30 | 31 | @property 32 | def id(self): 33 | return self.__id 34 | 35 | @property 36 | def name(self): 37 | return self.__name 38 | 39 | @property 40 | def primaryKeys(self): 41 | return self.__primary_keys 42 | 43 | @property 44 | def idStrategy(self): 45 | return self.__id_strategy 46 | 47 | @property 48 | def properties(self): 49 | return self.__properties 50 | 51 | @property 52 | def nullableKeys(self): 53 | return self.__nullable_keys 54 | 55 | @property 56 | def userdata(self): 57 | return self.__user_data 58 | 59 | @property 60 | def indexLabels(self): 61 | return self.__index_labels 62 | 63 | @property 64 | def enableLabelIndex(self): 65 | return self.__enable_label_index 66 | 67 | def __repr__(self): 68 | res = ( 69 | f"name: {self.__name}, primary_keys: {self.__primary_keys}, " 70 | f"properties: {self.__properties}" 71 | ) 72 | return res 73 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/utils/constants.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | class Constants(str): 20 | CONFORM_MESSAGE = "I%27m+sure+to+delete+all+data" 21 | HEADER_CONTENT_TYPE = "application/json" 22 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/utils/exceptions.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | class NotAuthorizedError(Exception): 20 | """ 21 | Not Authorized 22 | """ 23 | 24 | 25 | class InvalidParameter(Exception): 26 | """ 27 | Parameter setting error 28 | """ 29 | 30 | 31 | class NotFoundError(Exception): 32 | """ 33 | no content found 34 | """ 35 | 36 | 37 | class CreateError(Exception): 38 | """ 39 | Failed to create vertex or edge 40 | """ 41 | 42 | 43 | class RemoveError(Exception): 44 | """ 45 | Failed to delete vertex or edge 46 | """ 47 | 48 | 49 | class UpdateError(Exception): 50 | """ 51 | Failed to modify node 52 | """ 53 | 54 | 55 | class DataFormatError(Exception): 56 | """ 57 | Input data format error 58 | """ 59 | 60 | 61 | class ServiceUnavailableException(Exception): 62 | """ 63 | The server is too busy to be available 64 | """ 65 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/utils/huge_config.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import re 19 | import sys 20 | import traceback 21 | from dataclasses import dataclass, field 22 | from typing import List, Optional 23 | 24 | import requests 25 | 26 | from pyhugegraph.utils.log import log 27 | 28 | 29 | @dataclass 30 | class HGraphConfig: 31 | url: str 32 | username: str 33 | password: str 34 | graph_name: str 35 | graphspace: Optional[str] = None 36 | timeout: tuple[float, float] = (0.5, 15.0) 37 | gs_supported: bool = field(default=False, init=False) 38 | version: List[int] = field(default_factory=list) 39 | 40 | def __post_init__(self): 41 | # Add URL prefix compatibility check 42 | if self.url and not self.url.startswith('http'): 43 | self.url = f"http://{self.url}" 44 | 45 | if self.graphspace and self.graphspace.strip(): 46 | self.gs_supported = True 47 | 48 | else: 49 | try: 50 | response = requests.get( 51 | f"{self.url}/versions", timeout=0.5 52 | ) 53 | core = response.json()["versions"]["core"] 54 | log.info( # pylint: disable=logging-fstring-interpolation 55 | f"Retrieved API version information from the server: {core}." 56 | ) 57 | 58 | match = re.search(r"(\d+)\.(\d+)(?:\.(\d+))?(?:\.\d+)?", core) 59 | major, minor, patch = map(int, match.groups()) 60 | self.version.extend([major, minor, patch]) 61 | 62 | if major >= 3: 63 | self.graphspace = "DEFAULT" 64 | self.gs_supported = True 65 | log.warning("graph space is not set, default value 'DEFAULT' will be used.") 66 | 67 | except Exception as e: # pylint: disable=broad-exception-caught 68 | try: 69 | traceback.print_exception(e) 70 | self.gs_supported = False 71 | except Exception: # pylint: disable=broad-exception-caught 72 | exc_type, exc_value, tb = sys.exc_info() 73 | traceback.print_exception(exc_type, exc_value, tb) 74 | log.warning("Failed to retrieve API version information from the server, reverting to default v1.") 75 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/pyhugegraph/utils/huge_decorator.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | from decorator import decorator 20 | from pyhugegraph.utils.exceptions import NotAuthorizedError 21 | 22 | 23 | @decorator 24 | def decorator_params(func, *args, **kwargs): 25 | parameter_holder = args[0].get_parameter_holder() 26 | if parameter_holder is None or "name" not in parameter_holder.get_keys(): 27 | print("Parameters required, please set necessary parameters.") 28 | raise Exception("Parameters required, please set necessary parameters.") 29 | return func(*args, **kwargs) 30 | 31 | 32 | @decorator 33 | def decorator_create(func, *args, **kwargs): 34 | parameter_holder = args[0].get_parameter_holder() 35 | if parameter_holder.get_value("not_exist") is False: 36 | return f'Create failed, "{parameter_holder.get_value("name")}" already exists.' 37 | return func(*args, **kwargs) 38 | 39 | 40 | @decorator 41 | def decorator_auth(func, *args, **kwargs): 42 | response = args[0] 43 | if response.status_code == 401: 44 | raise NotAuthorizedError(f"NotAuthorized: {str(response.content)}") 45 | return func(*args, **kwargs) 46 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/tests/api/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/tests/api/test_graphs.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import unittest 19 | 20 | from tests.client_utils import ClientUtils 21 | 22 | 23 | class TestGraphsManager(unittest.TestCase): 24 | client = None 25 | graph = None 26 | 27 | @classmethod 28 | def setUpClass(cls): 29 | cls.client = ClientUtils() 30 | cls.graphs = cls.client.graphs 31 | cls.client.init_property_key() 32 | cls.client.init_vertex_label() 33 | cls.client.init_edge_label() 34 | cls.client.init_index_label() 35 | 36 | @classmethod 37 | def tearDownClass(cls): 38 | cls.client.clear_graph_all_data() 39 | 40 | def setUp(self): 41 | pass 42 | 43 | def tearDown(self): 44 | pass 45 | 46 | def test_get_all_graphs(self): 47 | all_graphs = self.graphs.get_all_graphs() 48 | self.assertTrue("hugegraph" in all_graphs) 49 | 50 | def test_get_version(self): 51 | version = self.graphs.get_version() 52 | self.assertIsNotNone(version) 53 | 54 | def test_get_graph_info(self): 55 | graph_info = self.graphs.get_graph_info() 56 | self.assertTrue("backend" in graph_info) 57 | 58 | def test_get_graph_config(self): 59 | graph_config = self.graphs.get_graph_config() 60 | self.assertIsNotNone(graph_config) 61 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/tests/api/test_metric.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import unittest 19 | 20 | from tests.client_utils import ClientUtils 21 | 22 | 23 | class TestMetricsManager(unittest.TestCase): 24 | client = None 25 | metrics = None 26 | 27 | @classmethod 28 | def setUpClass(cls): 29 | cls.client = ClientUtils() 30 | cls.metrics = cls.client.metrics 31 | cls.client.init_property_key() 32 | cls.client.init_vertex_label() 33 | cls.client.init_edge_label() 34 | cls.client.init_index_label() 35 | 36 | @classmethod 37 | def tearDownClass(cls): 38 | cls.client.clear_graph_all_data() 39 | 40 | def setUp(self): 41 | self.client.init_vertices() 42 | self.client.init_edges() 43 | 44 | def tearDown(self): 45 | pass 46 | 47 | def test_metrics_operations(self): 48 | all_basic_metrics = self.metrics.get_all_basic_metrics() 49 | self.assertEqual(len(all_basic_metrics), 5) 50 | 51 | gauges_metrics = self.metrics.get_gauges_metrics() 52 | self.assertIsInstance(gauges_metrics, dict) 53 | 54 | counters_metrics = self.metrics.get_counters_metrics() 55 | self.assertIsInstance(counters_metrics, dict) 56 | 57 | histograms_metrics = self.metrics.get_histograms_metrics() 58 | self.assertIsInstance(histograms_metrics, dict) 59 | 60 | meters_metrics = self.metrics.get_meters_metrics() 61 | self.assertIsInstance(meters_metrics, dict) 62 | 63 | timers_metrics = self.metrics.get_timers_metrics() 64 | self.assertIsInstance(timers_metrics, dict) 65 | 66 | system_metrics = self.metrics.get_system_metrics() 67 | self.assertIsInstance(system_metrics, dict) 68 | 69 | statistics = self.metrics.get_statistics_metrics() 70 | self.assertIsInstance(statistics, dict) 71 | 72 | backend_metrics = self.metrics.get_backend_metrics() 73 | self.assertGreater(len(backend_metrics["hugegraph"]), 1) 74 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/tests/api/test_schema.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import unittest 19 | 20 | from tests.client_utils import ClientUtils 21 | 22 | 23 | class TestSchemaManager(unittest.TestCase): 24 | client = None 25 | schema = None 26 | 27 | @classmethod 28 | def setUpClass(cls): 29 | cls.client = ClientUtils() 30 | cls.client.clear_graph_all_data() 31 | cls.schema = cls.client.schema 32 | cls.client.init_property_key() 33 | cls.client.init_vertex_label() 34 | cls.client.init_edge_label() 35 | cls.client.init_index_label() 36 | 37 | @classmethod 38 | def tearDownClass(cls): 39 | cls.client.clear_graph_all_data() 40 | 41 | def setUp(self): 42 | pass 43 | 44 | def tearDown(self): 45 | pass 46 | 47 | def test_get_schema(self): 48 | schema = self.schema.getSchema() 49 | self.assertEqual(4, len(schema)) 50 | 51 | def test_get_property_keys(self): 52 | property_keys = self.schema.getPropertyKeys() 53 | self.assertEqual(7, len(property_keys)) 54 | 55 | def test_get_property_key(self): 56 | property_key = self.schema.getPropertyKey("name") 57 | self.assertEqual(property_key.name, "name") 58 | 59 | def test_get_vertex_labels(self): 60 | vertex_labels = self.schema.getVertexLabels() 61 | self.assertEqual(3, len(vertex_labels)) 62 | 63 | def test_get_vertex_label(self): 64 | vertex_label = self.schema.getVertexLabel("person") 65 | self.assertEqual(vertex_label.name, "person") 66 | 67 | def test_get_edge_labels(self): 68 | edge_labels = self.schema.getEdgeLabels() 69 | self.assertEqual(2, len(edge_labels)) 70 | 71 | def test_get_edge_label(self): 72 | edge_label = self.schema.getEdgeLabel("knows") 73 | self.assertEqual(edge_label.name, "knows") 74 | 75 | def test_get_index_labels(self): 76 | index_labels = self.schema.getIndexLabels() 77 | self.assertEqual(6, len(index_labels)) 78 | 79 | def test_get_index_label(self): 80 | index_label = self.schema.getIndexLabel("personByCity") 81 | self.assertEqual(index_label.name, "personByCity") 82 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/tests/api/test_task.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import unittest 19 | 20 | from pyhugegraph.utils.exceptions import NotFoundError 21 | from tests.client_utils import ClientUtils 22 | 23 | 24 | class TestTaskManager(unittest.TestCase): 25 | client = None 26 | task = None 27 | 28 | @classmethod 29 | def setUpClass(cls): 30 | cls.client = ClientUtils() 31 | cls.task = cls.client.task 32 | 33 | @classmethod 34 | def tearDownClass(cls): 35 | cls.client.clear_graph_all_data() 36 | 37 | def setUp(self): 38 | pass 39 | 40 | def tearDown(self): 41 | pass 42 | 43 | def test_list_tasks(self): 44 | tasks = self.task.list_tasks() 45 | self.assertIsInstance(tasks, dict) 46 | self.assertTrue("tasks" in tasks) 47 | 48 | def test_get_task(self): 49 | try: 50 | self.task.get_task(1) 51 | except NotFoundError as e: 52 | self.assertTrue("Can\\'t find task with id \\'1\\'" in str(e)) 53 | 54 | def test_delete_task(self): 55 | try: 56 | self.task.delete_task(2) 57 | except NotFoundError as e: 58 | self.assertTrue("Can\\'t find task with id \\'2\\'" in str(e)) 59 | 60 | def test_cancel_task(self): 61 | try: 62 | self.task.cancel_task(3) 63 | except NotFoundError as e: 64 | self.assertTrue("Can\\'t find task with id \\'3\\'" in str(e)) 65 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/tests/api/test_variable.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import unittest 19 | 20 | import pytest 21 | 22 | from pyhugegraph.utils.exceptions import NotFoundError 23 | from tests.client_utils import ClientUtils 24 | 25 | 26 | class TestVariable(unittest.TestCase): 27 | client = None 28 | variable = None 29 | 30 | @classmethod 31 | def setUpClass(cls): 32 | cls.client = ClientUtils() 33 | cls.variable = cls.client.variable 34 | 35 | @classmethod 36 | def tearDownClass(cls): 37 | cls.client.clear_graph_all_data() 38 | 39 | def setUp(self): 40 | self.client.clear_graph_all_data() 41 | 42 | def tearDown(self): 43 | pass 44 | 45 | def test_all(self): 46 | self.assertEqual(len(self.variable.all()), 0) 47 | self.variable.set("student", "mary") 48 | self.variable.set("price", 20.86) 49 | 50 | dic = self.variable.all() 51 | self.assertEqual(2, len(dic)) 52 | self.assertEqual("mary", dic.get("student", None)) 53 | self.assertEqual(20.86, dic.get("price", None)) 54 | 55 | def test_remove(self): 56 | self.variable.set("lang", "java") 57 | dic = self.variable.all() 58 | self.assertEqual(1, len(dic)) 59 | self.assertEqual("java", dic.get("lang", None)) 60 | 61 | self.variable.remove("lang") 62 | dic = self.variable.all() 63 | self.assertEqual(0, len(dic)) 64 | self.assertEqual(dic.get("lang", None), None) 65 | 66 | def test_set_and_get(self): 67 | self.variable.set("name", "tom") 68 | self.variable.set("age", 18) 69 | 70 | self.assertEqual(2, len(self.variable.all())) 71 | name = self.variable.get("name").get("name", None) 72 | self.assertEqual("tom", name) 73 | age = self.variable.get("age").get("age", None) 74 | self.assertEqual(18, age) 75 | 76 | def test_get_key_not_exist(self): 77 | with pytest.raises(NotFoundError): 78 | self.assertIsNone(self.variable.get("id").get("id")) 79 | 80 | def test_remove_key_not_exist(self): 81 | self.variable.remove("id") 82 | -------------------------------------------------------------------------------- /hugegraph-python-client/src/tests/api/test_version.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import unittest 19 | 20 | from tests.client_utils import ClientUtils 21 | 22 | 23 | class TestVersion(unittest.TestCase): 24 | client = None 25 | version = None 26 | 27 | @classmethod 28 | def setUpClass(cls): 29 | cls.client = ClientUtils() 30 | cls.version = cls.client.version 31 | 32 | @classmethod 33 | def tearDownClass(cls): 34 | cls.client.clear_graph_all_data() 35 | 36 | def setUp(self): 37 | self.client.clear_graph_all_data() 38 | 39 | def tearDown(self): 40 | pass 41 | 42 | def test_version(self): 43 | version = self.version.version() 44 | self.assertIsInstance(version, dict) 45 | self.assertIn("version", version['versions']) 46 | self.assertIn("core", version['versions']) 47 | self.assertIn("gremlin", version['versions']) 48 | self.assertIn("api", version['versions']) 49 | -------------------------------------------------------------------------------- /vermeer-python-client/README.md: -------------------------------------------------------------------------------- 1 | # vermeer-python-client 2 | 3 | The `vermeer-python-client` is a Python client(SDK) for [Vermeer](https://github.com/apache/incubator-hugegraph-computer/tree/master/vermeer#readme) (A high-performance distributed graph computing platform based on memory, supporting more than 15 graph algorithms, custom algorithm extensions, and custom data source access & easy to deploy and use) 4 | 5 | ## Installation 6 | 7 | ### Install the released package (🚧 ing) 8 | 9 | To install the `vermeer-python-client`, you can use uv/pip: 10 | 11 | ```bash 12 | # uv is optional, you can use pip directly 13 | # uv pip install vermeer-python-client (Not published yet 🚧ing) 14 | # Note: This will install the latest released version. For the newest code, please install from source. 15 | ``` 16 | 17 | ### Install from Source (Latest Code) 18 | 19 | To install from the source, clone the repository and install the required dependencies: 20 | 21 | ```bash 22 | git clone https://github.com/apache/incubator-hugegraph-ai.git 23 | cd incubator-hugegraph-ai/vermeer-python-client 24 | 25 | # Normal install 26 | uv pip install . 27 | 28 | # (Optional) install the devel version 29 | uv pip install -e . 30 | ``` 31 | 32 | ## Usage 33 | 34 | This section provides examples of how to use the `vermeer-python-client`. 35 | 36 | **Note:** The following examples are placeholders. Please replace them with actual usage scenarios for the `vermeer-python-client`. 37 | 38 | ### Initialize the Client 39 | 40 | ```python 41 | from pyvermeer.client import VermeerClient 42 | 43 | # Initialize the client 44 | client = VermeerClient(host="127.0.0.1", port="8080") 45 | print("Client initialized successfully.") 46 | ``` 47 | 48 | ### Example: Running a Graph Algorithm 49 | 50 | ```python 51 | # Placeholder for running a graph algorithm example 52 | try: 53 | result = client.run_algorithm(name="pagerank", params={"alpha": 0.85, "max_iter": 10}) 54 | print(f"PageRank results: {result}") 55 | except Exception as e: 56 | print(f"Error running algorithm: {e}") 57 | ``` 58 | 59 | ### Example: Managing Jobs 60 | 61 | ```python 62 | # Placeholder for managing jobs example 63 | try: 64 | job_status = client.get_job_status(job_id="some_job_id") 65 | print(f"Job status: {job_status}") 66 | except Exception as e: 67 | print(f"Error getting job status: {e}") 68 | ``` 69 | 70 | Other info is under 🚧 (Welcome to add more docs for it) 71 | 72 | ## Contributing 73 | 74 | * Welcome to contribute to `vermeer-python-client`. Please see the [Guidelines](https://hugegraph.apache.org/docs/contribution-guidelines/) for more information. 75 | * Code format: Please run `./style/code_format_and_analysis.sh` to format your code before submitting a PR. 76 | 77 | Thank you to all the people who already contributed to `vermeer-python-client`! 78 | 79 | ## Contact Us 80 | 81 | * [GitHub Issues](https://github.com/apache/incubator-hugegraph-ai/issues): Feedback on usage issues and functional requirements (quick response) 82 | * Feedback Email: [dev@hugegraph.apache.org](mailto:dev@hugegraph.apache.org) (subscriber only) 83 | ``` 84 | -------------------------------------------------------------------------------- /vermeer-python-client/pyproject.toml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | [project] 19 | name = "vermeer-python-client" 20 | version = "1.5.0" 21 | description = "A Python SDK for Apache Vermeer." 22 | authors = [ 23 | { name = "Apache HugeGraph Contributors", email = "dev@hugegraph.apache.org" }, 24 | ] 25 | readme = "README.md" 26 | license = "Apache-2.0" 27 | requires-python = ">=3.9" 28 | dependencies = [ 29 | "decorator~=5.1.1", 30 | "requests~=2.32.0", 31 | "urllib3~=2.2.2", 32 | ] 33 | 34 | [project.urls] 35 | "Homepage" = "https://github.com/apache/incubator-hugegraph-ai" 36 | "Repository" = "https://github.com/apache/incubator-hugegraph-ai" 37 | "Bug Tracker" = "https://github.com/apache/incubator-hugegraph-ai/issues" 38 | 39 | [project.optional-dependencies] 40 | dev = [ 41 | "pytest>=7.0.0", 42 | "black>=23.0.0", 43 | "isort>=5.0.0", 44 | "flake8>=6.0.0", 45 | ] 46 | 47 | [build-system] 48 | requires = ["setuptools>=61.0"] 49 | build-backend = "setuptools.build_meta" 50 | 51 | [tool.setuptools.packages.find] 52 | where = ["src"] 53 | exclude = ["tests"] 54 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/api/base.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from pyvermeer.utils.log import log 19 | 20 | 21 | class BaseModule: 22 | """Base class""" 23 | 24 | def __init__(self, client): 25 | self._client = client 26 | self.log = log.getChild(__name__) 27 | 28 | @property 29 | def session(self): 30 | """Return the client's session object""" 31 | return self._client.session 32 | 33 | def _send_request(self, method: str, endpoint: str, params: dict = None): 34 | """Unified request entry point""" 35 | self.log.debug(f"Sending {method} to {endpoint}") 36 | return self._client.send_request( 37 | method=method, 38 | endpoint=endpoint, 39 | params=params 40 | ) 41 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/api/graph.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from pyvermeer.structure.graph_data import GraphsResponse, GraphResponse 19 | from .base import BaseModule 20 | 21 | 22 | class GraphModule(BaseModule): 23 | """Graph""" 24 | 25 | def get_graph(self, graph_name: str) -> GraphResponse: 26 | """Get task list""" 27 | response = self._send_request( 28 | "GET", 29 | f"/graphs/{graph_name}" 30 | ) 31 | return GraphResponse(response) 32 | 33 | def get_graphs(self) -> GraphsResponse: 34 | """Get task list""" 35 | response = self._send_request( 36 | "GET", 37 | "/graphs", 38 | ) 39 | return GraphsResponse(response) 40 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/api/master.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/api/task.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from pyvermeer.api.base import BaseModule 19 | 20 | from pyvermeer.structure.task_data import TasksResponse, TaskCreateRequest, TaskCreateResponse, TaskResponse 21 | 22 | 23 | class TaskModule(BaseModule): 24 | """Task""" 25 | 26 | def get_tasks(self) -> TasksResponse: 27 | """Get task list""" 28 | response = self._send_request( 29 | "GET", 30 | "/tasks" 31 | ) 32 | return TasksResponse(response) 33 | 34 | def get_task(self, task_id: int) -> TaskResponse: 35 | """Get single task information""" 36 | response = self._send_request( 37 | "GET", 38 | f"/task/{task_id}" 39 | ) 40 | return TaskResponse(response) 41 | 42 | def create_task(self, create_task: TaskCreateRequest) -> TaskCreateResponse: 43 | """Create new task""" 44 | response = self._send_request( 45 | method="POST", 46 | endpoint="/tasks/create", 47 | params=create_task.to_dict() 48 | ) 49 | return TaskCreateResponse(response) 50 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/api/worker.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/client/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/client/client.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from typing import Dict 19 | from typing import Optional 20 | 21 | from pyvermeer.api.base import BaseModule 22 | from pyvermeer.api.graph import GraphModule 23 | from pyvermeer.api.task import TaskModule 24 | from pyvermeer.utils.log import log 25 | from pyvermeer.utils.vermeer_config import VermeerConfig 26 | from pyvermeer.utils.vermeer_requests import VermeerSession 27 | 28 | 29 | class PyVermeerClient: 30 | """Vermeer API Client""" 31 | 32 | def __init__( 33 | self, 34 | ip: str, 35 | port: int, 36 | token: str, 37 | timeout: Optional[tuple[float, float]] = None, 38 | log_level: str = "INFO", 39 | ): 40 | """Initialize the client, including configuration and session management 41 | :param ip: 42 | :param port: 43 | :param token: 44 | :param timeout: 45 | :param log_level: 46 | """ 47 | self.cfg = VermeerConfig(ip, port, token, timeout) 48 | self.session = VermeerSession(self.cfg) 49 | self._modules: Dict[str, BaseModule] = { 50 | "graph": GraphModule(self), 51 | "tasks": TaskModule(self) 52 | } 53 | log.setLevel(log_level) 54 | 55 | def __getattr__(self, name): 56 | """Access modules through attributes""" 57 | if name in self._modules: 58 | return self._modules[name] 59 | raise AttributeError(f"Module {name} not found") 60 | 61 | def send_request(self, method: str, endpoint: str, params: dict = None): 62 | """Unified request method""" 63 | return self.session.request(method, endpoint, params) 64 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/demo/task_demo.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from pyvermeer.client.client import PyVermeerClient 19 | from pyvermeer.structure.task_data import TaskCreateRequest 20 | 21 | 22 | def main(): 23 | """main""" 24 | client = PyVermeerClient( 25 | ip="127.0.0.1", 26 | port=8688, 27 | token="", 28 | log_level="DEBUG", 29 | ) 30 | task = client.tasks.get_tasks() 31 | 32 | print(task.to_dict()) 33 | 34 | create_response = client.tasks.create_task( 35 | create_task=TaskCreateRequest( 36 | task_type='load', 37 | graph_name='DEFAULT-example', 38 | params={ 39 | "load.hg_pd_peers": "[\"127.0.0.1:8686\"]", 40 | "load.hugegraph_name": "DEFAULT/example/g", 41 | "load.hugegraph_password": "xxx", 42 | "load.hugegraph_username": "xxx", 43 | "load.parallel": "10", 44 | "load.type": "hugegraph" 45 | }, 46 | ) 47 | ) 48 | 49 | print(create_response.to_dict()) 50 | 51 | 52 | if __name__ == "__main__": 53 | main() 54 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/structure/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/structure/base_data.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | RESPONSE_ERR = 1 19 | RESPONSE_OK = 0 20 | RESPONSE_NONE = -1 21 | 22 | 23 | class BaseResponse(object): 24 | """ 25 | Base response class 26 | """ 27 | 28 | def __init__(self, dic: dict): 29 | """ 30 | init 31 | :param dic: 32 | """ 33 | self.__errcode = dic.get('errcode', RESPONSE_NONE) 34 | self.__message = dic.get('message', "") 35 | 36 | @property 37 | def errcode(self) -> int: 38 | """ 39 | get error code 40 | :return: 41 | """ 42 | return self.__errcode 43 | 44 | @property 45 | def message(self) -> str: 46 | """ 47 | get message 48 | :return: 49 | """ 50 | return self.__message 51 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/structure/master_data.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import datetime 19 | 20 | from pyvermeer.structure.base_data import BaseResponse 21 | from pyvermeer.utils.vermeer_datetime import parse_vermeer_time 22 | 23 | 24 | class MasterInfo: 25 | """Master information""" 26 | 27 | def __init__(self, dic: dict): 28 | """Initialization function""" 29 | self.__grpc_peer = dic.get('grpc_peer', '') 30 | self.__ip_addr = dic.get('ip_addr', '') 31 | self.__debug_mod = dic.get('debug_mod', False) 32 | self.__version = dic.get('version', '') 33 | self.__launch_time = parse_vermeer_time(dic.get('launch_time', '')) 34 | 35 | @property 36 | def grpc_peer(self) -> str: 37 | """gRPC address""" 38 | return self.__grpc_peer 39 | 40 | @property 41 | def ip_addr(self) -> str: 42 | """IP address""" 43 | return self.__ip_addr 44 | 45 | @property 46 | def debug_mod(self) -> bool: 47 | """Whether it is debug mode""" 48 | return self.__debug_mod 49 | 50 | @property 51 | def version(self) -> str: 52 | """Master version number""" 53 | return self.__version 54 | 55 | @property 56 | def launch_time(self) -> datetime: 57 | """Master startup time""" 58 | return self.__launch_time 59 | 60 | def to_dict(self): 61 | """Return data in dictionary format""" 62 | return { 63 | "grpc_peer": self.__grpc_peer, 64 | "ip_addr": self.__ip_addr, 65 | "debug_mod": self.__debug_mod, 66 | "version": self.__version, 67 | "launch_time": self.__launch_time.strftime("%Y-%m-%d %H:%M:%S") if self.__launch_time else '' 68 | } 69 | 70 | 71 | class MasterResponse(BaseResponse): 72 | """Master response""" 73 | 74 | def __init__(self, dic: dict): 75 | """Initialization function""" 76 | super().__init__(dic) 77 | self.__master_info = MasterInfo(dic['master_info']) 78 | 79 | @property 80 | def master_info(self) -> MasterInfo: 81 | """Get master node information""" 82 | return self.__master_info 83 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/utils/exception.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | class ConnectError(Exception): 20 | """Raised when there is an issue connecting to the server.""" 21 | 22 | def __init__(self, message): 23 | super().__init__(f"Connection error: {str(message)}") 24 | 25 | 26 | class TimeOutError(Exception): 27 | """Raised when a request times out.""" 28 | 29 | def __init__(self, message): 30 | super().__init__(f"Request timed out: {str(message)}") 31 | 32 | 33 | class JsonDecodeError(Exception): 34 | """Raised when the response from the server cannot be decoded as JSON.""" 35 | 36 | def __init__(self, message): 37 | super().__init__(f"Failed to decode JSON response: {str(message)}") 38 | 39 | 40 | class UnknownError(Exception): 41 | """Raised for any other unknown errors.""" 42 | 43 | def __init__(self, message): 44 | super().__init__(f"Unknown API error: {str(message)}") 45 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/utils/log.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import logging 19 | import sys 20 | 21 | 22 | class VermeerLogger: 23 | """vermeer API log""" 24 | _instance = None 25 | 26 | def __new__(cls, name: str = "VermeerClient"): 27 | """new api logger""" 28 | if cls._instance is None: 29 | cls._instance = super().__new__(cls) 30 | cls._instance._initialize(name) 31 | return cls._instance 32 | 33 | def _initialize(self, name: str): 34 | """Initialize log configuration""" 35 | self.logger = logging.getLogger(name) 36 | self.logger.setLevel(logging.INFO) # Default level 37 | 38 | if not self.logger.handlers: 39 | # Console output format 40 | console_format = logging.Formatter( 41 | '[%(asctime)s] [%(levelname)s] %(name)s - %(message)s', 42 | datefmt='%Y-%m-%d %H:%M:%S' 43 | ) 44 | 45 | # Console handler 46 | console_handler = logging.StreamHandler(sys.stdout) 47 | console_handler.setLevel(logging.INFO) # Console default level 48 | console_handler.setFormatter(console_format) 49 | 50 | # file_handler = logging.FileHandler('api_client.log') 51 | # file_handler.setLevel(logging.DEBUG) 52 | # file_handler.setFormatter( 53 | # logging.Formatter( 54 | # '[%(asctime)s] [%(levelname)s] [%(threadName)s] %(name)s - %(message)s' 55 | # ) 56 | # ) 57 | 58 | self.logger.addHandler(console_handler) 59 | # self.logger.addHandler(file_handler) 60 | 61 | self.logger.propagate = False 62 | 63 | @classmethod 64 | def get_logger(cls) -> logging.Logger: 65 | """Get configured logger""" 66 | return cls().logger 67 | 68 | 69 | # Global log instance 70 | log = VermeerLogger.get_logger() 71 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/utils/vermeer_config.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | class VermeerConfig: 20 | """The configuration of a Vermeer instance.""" 21 | ip: str 22 | port: int 23 | token: str 24 | factor: str 25 | username: str 26 | graph_space: str 27 | 28 | def __init__(self, 29 | ip: str, 30 | port: int, 31 | token: str, 32 | timeout: tuple[float, float] = (0.5, 15.0)): 33 | """Initialize the configuration for a Vermeer instance.""" 34 | self.ip = ip 35 | self.port = port 36 | self.token = token 37 | self.timeout = timeout 38 | -------------------------------------------------------------------------------- /vermeer-python-client/src/pyvermeer/utils/vermeer_datetime.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import datetime 19 | 20 | from dateutil import parser 21 | 22 | 23 | def parse_vermeer_time(vm_dt: str) -> datetime: 24 | """Parse a vermeer time string into a Python datetime object.""" 25 | if vm_dt is None or len(vm_dt) == 0: 26 | return None 27 | dt = parser.parse(vm_dt) 28 | return dt 29 | 30 | 31 | if __name__ == '__main__': 32 | print(parse_vermeer_time('2025-02-17T15:45:05.396311145+08:00').strftime("%Y%m%d")) 33 | --------------------------------------------------------------------------------