-
Notifications
You must be signed in to change notification settings - Fork 0
property embeddings #5
base: main
Are you sure you want to change the base?
Changes from 63 commits
74cf3c5
e9941ad
d2e4e2e
c5ec3ea
12221c9
8343d3c
0036b2c
173b9b2
c9ef9ed
c933c58
263758b
8a0e6cd
a60887d
43cdcae
b4f1a51
142a44e
9f245a0
87cb1cf
961f582
4cbb47a
36116e6
5db4e0c
bf19a84
026c65c
f2ee374
0e98879
a3b864f
ac7e137
8ace5a8
a9f92c4
18744d2
89b2d47
f14087a
ef37855
c24d210
f1fdbdb
2953dbc
cf279f5
182ecba
b7e7425
52c40cb
10e76cd
923502a
739479a
9acaa96
86e6098
b27d925
765e93f
b5f31ff
50ec338
7d9d67c
c918e73
7b7260a
3754211
7a2cf2b
7b3e5e2
cb31b35
9778c37
cf6d2e4
eb5e9f1
e75f68f
4aa1a4d
7b7c6d2
31bf971
a0e460c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,51 @@ | ||||||
| # Licensed to the Apache Software Foundation (ASF) under one | ||||||
| # or more contributor license agreements. See the NOTICE file | ||||||
| # distributed with this work for additional information | ||||||
| # regarding copyright ownership. The ASF licenses this file | ||||||
| # to you under the Apache License, Version 2.0 (the | ||||||
| # "License"); you may not use this file except in compliance | ||||||
| # with the License. You may obtain a copy of the License at | ||||||
| # | ||||||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||||||
| # | ||||||
| # Unless required by applicable law or agreed to in writing, | ||||||
| # software distributed under the License is distributed on an | ||||||
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||||||
| # KIND, either express or implied. See the License for the | ||||||
| # specific language governing permissions and limitations | ||||||
| # under the License. | ||||||
|
|
||||||
|
|
||||||
| from datetime import date | ||||||
|
|
||||||
| from fastapi import status, APIRouter, HTTPException | ||||||
|
|
||||||
| from hugegraph_llm.utils.log import log | ||||||
|
|
||||||
| API_CALL_TRACKER = {} | ||||||
imbajin marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
|
||||||
|
|
||||||
| # pylint: disable=too-many-statements | ||||||
MrJs133 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| def vector_http_api(router: APIRouter, update_embedding_func): | ||||||
| @router.post("/vector/embedding", status_code=status.HTTP_200_OK) | ||||||
| def update_embedding_api(daily_limit: int = 50): | ||||||
| """ | ||||||
| Updates the vector embedding. | ||||||
| This endpoint is rate-limited. By default, it allows 2 calls per day. (Note: Not Thread-Safe!) | ||||||
| The rate limit is tracked per day and resets at midnight. | ||||||
| """ | ||||||
| today = date.today() | ||||||
| for call_date in list(API_CALL_TRACKER.keys()): | ||||||
| if call_date != today: | ||||||
| del API_CALL_TRACKER[call_date] | ||||||
| call_count = API_CALL_TRACKER.get(today, 0) | ||||||
| if call_count >= daily_limit: | ||||||
| log.error("Rate limit exceeded for update_vid_embedding. Maximum %d calls per day.", daily_limit) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 修正日志消息中的函数名称。 日志消息中的函数名称 应用此修改来修正函数名称: -log.error("Rate limit exceeded for update_vid_embedding. Maximum %d calls per day.", daily_limit)
+log.error("Rate limit exceeded for update_embedding_api. Maximum %d calls per day.", daily_limit)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| raise HTTPException( | ||||||
| status_code=status.HTTP_429_TOO_MANY_REQUESTS, | ||||||
| detail=f"API call limit of {daily_limit} per day exceeded. Please try again tomorrow." | ||||||
| ) | ||||||
| API_CALL_TRACKER[today] = call_count + 1 | ||||||
| result = update_embedding_func() | ||||||
| result = {"detail": result} | ||||||
| return result | ||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -17,7 +17,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| import json | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| import os | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| from typing import Any, Tuple, Dict, Union, Literal | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| from typing import Any, Tuple, Dict, Union, Literal, Optional, List, Set | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| import gradio as gr | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| import pandas as pd | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -214,3 +214,62 @@ def graph_rag_recall( | |||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| context = rag.run(verbose=True, query=query, graph_search=True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return context | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| def gremlin_generate_selective( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| inp: str, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| example_num: int, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| schema_input: str, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| gremlin_prompt_input: str, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| requested_outputs: Optional[List[str]] = None, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Dict[str, Any]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Wraps the original gremlin_generate function and filters its output | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| based on the requested_outputs list of strings. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| output_keys = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "match_result", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "template_gremlin", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "raw_gremlin", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "template_execution_result", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "raw_execution_result", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| original_results = gremlin_generate(inp, example_num, schema_input, gremlin_prompt_input) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| outputs_dict: Dict[str, Any] = {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| requested_outputs_set: Set[str] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not requested_outputs: # None or empty list | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| requested_outputs_set = set(output_keys) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| requested_outputs_set = set(requested_outputs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Handle the case where gremlin_generate might return a 2-tuple error message | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if isinstance(original_results, tuple) and len(original_results) == 2 and isinstance(original_results[0], str): | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| # This indicates an error from gremlin_generate (e.g., "Invalid JSON schema...") | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| # In this case, we can return the error message for relevant fields or a general error | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if "match_result" in requested_outputs_set: # Or any other default error field | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| outputs_dict["match_result"] = original_results[0] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| outputs_dict["error_detail"] = original_results[1] # usually empty string from original | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Or, more simply, return a dictionary indicating the error. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| # For simplicity, if an error tuple is returned, and match_result is requested, we populate it. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| # This part might need refinement based on how errors should be structured in the selective output. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| # For now, if an error tuple is returned, and "match_result" is requested, it gets the error message. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Other requested fields will be absent. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return outputs_dict # Early exit if gremlin_generate returned an error tuple | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+247
to
+259
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 改进错误处理逻辑 当前的错误处理逻辑存在以下问题:
建议改进错误处理逻辑: - # Handle the case where gremlin_generate might return a 2-tuple error message
- if isinstance(original_results, tuple) and len(original_results) == 2 and isinstance(original_results[0], str):
- # This indicates an error from gremlin_generate (e.g., "Invalid JSON schema...")
- # In this case, we can return the error message for relevant fields or a general error
- if "match_result" in requested_outputs_set: # Or any other default error field
- outputs_dict["match_result"] = original_results[0]
- outputs_dict["error_detail"] = original_results[1] # usually empty string from original
- # Or, more simply, return a dictionary indicating the error.
- # For simplicity, if an error tuple is returned, and match_result is requested, we populate it.
- # This part might need refinement based on how errors should be structured in the selective output.
- # For now, if an error tuple is returned, and "match_result" is requested, it gets the error message.
- # Other requested fields will be absent.
- return outputs_dict # Early exit if gremlin_generate returned an error tuple
+ # Handle error case: check if it's specifically an error tuple (str, str) where second element is empty
+ if (isinstance(original_results, tuple) and
+ len(original_results) == 2 and
+ isinstance(original_results[0], str) and
+ isinstance(original_results[1], str) and
+ original_results[1] == ""):
+ # Error case: return error information regardless of requested outputs
+ return {
+ "error": True,
+ "error_message": original_results[0],
+ "requested_outputs": list(requested_outputs_set)
+ }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| match_res_orig, template_gremlin_orig, raw_gremlin_orig, template_exec_res_orig, raw_exec_res_orig = original_results | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 添加参数解包的安全检查 直接对元组进行解包可能在错误情况下失败。建议添加长度检查以确保安全。 + # Ensure we have the expected 5-tuple result
+ if not isinstance(original_results, tuple) or len(original_results) != 5:
+ return {
+ "error": True,
+ "error_message": f"Unexpected result format from gremlin_generate: {type(original_results)}",
+ "requested_outputs": list(requested_outputs_set)
+ }
+
match_res_orig, template_gremlin_orig, raw_gremlin_orig, template_exec_res_orig, raw_exec_res_orig = original_results📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if "match_result" in requested_outputs_set: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| outputs_dict["match_result"] = match_res_orig | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if "template_gremlin" in requested_outputs_set: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| outputs_dict["template_gremlin"] = template_gremlin_orig | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if "raw_gremlin" in requested_outputs_set: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| outputs_dict["raw_gremlin"] = raw_gremlin_orig | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if "template_execution_result" in requested_outputs_set: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| outputs_dict["template_execution_result"] = template_exec_res_orig | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if "raw_execution_result" in requested_outputs_set: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| outputs_dict["raw_execution_result"] = raw_exec_res_orig | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| return outputs_dict | ||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
字段名称拼写错误
字段名
graphspae应该是graphspace。修正字段名称:
📝 Committable suggestion
🤖 Prompt for AI Agents