Skip to content

Commit 8085b52

Browse files
feat: add error handling for missing nodes and edges, introduce new API endpoints, and update ZepGraphiti class (camel-ai#104)
* feat: Expose crud operations to service + add graphiti errors * fix: linter
1 parent c0a740f commit 8085b52

File tree

6 files changed

+69
-5
lines changed

6 files changed

+69
-5
lines changed

graphiti_core/edges.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from neo4j import AsyncDriver
2525
from pydantic import BaseModel, Field
2626

27+
from graphiti_core.errors import EdgeNotFoundError
2728
from graphiti_core.helpers import parse_db_date
2829
from graphiti_core.llm_client.config import EMBEDDING_DIM
2930
from graphiti_core.nodes import Node
@@ -104,7 +105,8 @@ async def get_by_uuid(cls, driver: AsyncDriver, uuid: str):
104105
edges = [get_episodic_edge_from_record(record) for record in records]
105106

106107
logger.info(f'Found Edge: {uuid}')
107-
108+
if len(edges) == 0:
109+
raise EdgeNotFoundError(uuid)
108110
return edges[0]
109111

110112

@@ -191,7 +193,8 @@ async def get_by_uuid(cls, driver: AsyncDriver, uuid: str):
191193
edges = [get_entity_edge_from_record(record) for record in records]
192194

193195
logger.info(f'Found Edge: {uuid}')
194-
196+
if len(edges) == 0:
197+
raise EdgeNotFoundError(uuid)
195198
return edges[0]
196199

197200

graphiti_core/errors.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class GraphitiError(Exception):
2+
"""Base exception class for Graphiti Core."""
3+
4+
5+
class EdgeNotFoundError(GraphitiError):
6+
"""Raised when an edge is not found."""
7+
8+
def __init__(self, uuid: str):
9+
self.message = f'edge {uuid} not found'
10+
super().__init__(self.message)
11+
12+
13+
class NodeNotFoundError(GraphitiError):
14+
"""Raised when a node is not found."""
15+
16+
def __init__(self, uuid: str):
17+
self.message = f'node {uuid} not found'
18+
super().__init__(self.message)

graphiti_core/nodes.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from neo4j import AsyncDriver
2626
from pydantic import BaseModel, Field
2727

28+
from graphiti_core.errors import NodeNotFoundError
2829
from graphiti_core.llm_client.config import EMBEDDING_DIM
2930

3031
logger = logging.getLogger(__name__)
@@ -148,7 +149,7 @@ async def get_by_uuid(cls, driver: AsyncDriver, uuid: str):
148149
e.valid_at AS valid_at,
149150
e.uuid AS uuid,
150151
e.name AS name,
151-
e.group_id AS group_id
152+
e.group_id AS group_id,
152153
e.source_description AS source_description,
153154
e.source AS source
154155
""",
@@ -159,6 +160,9 @@ async def get_by_uuid(cls, driver: AsyncDriver, uuid: str):
159160

160161
logger.info(f'Found Node: {uuid}')
161162

163+
if len(episodes) == 0:
164+
raise NodeNotFoundError(uuid)
165+
162166
return episodes[0]
163167

164168
@classmethod

server/graph_service/routers/ingest.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,18 @@ async def add_entity_node(
8383
return node
8484

8585

86+
@router.delete('/entity-edge/{uuid}', status_code=status.HTTP_200_OK)
87+
async def delete_entity_edge(uuid: str, graphiti: ZepGraphitiDep):
88+
await graphiti.delete_entity_edge(uuid)
89+
return Result(message='Entity Edge deleted', success=True)
90+
91+
92+
@router.delete('/episode/{uuid}', status_code=status.HTTP_200_OK)
93+
async def delete_episode(uuid: str, graphiti: ZepGraphitiDep):
94+
await graphiti.delete_episodic_node(uuid)
95+
return Result(message='Episode deleted', success=True)
96+
97+
8698
@router.post('/clear', status_code=status.HTTP_200_OK)
8799
async def clear(
88100
graphiti: ZepGraphitiDep,

server/graph_service/routers/retrieve.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ async def search(query: SearchQuery, graphiti: ZepGraphitiDep):
2727
)
2828

2929

30+
@router.get('/entity-edge/{uuid}', status_code=status.HTTP_200_OK)
31+
async def get_entity_edge(uuid: str, graphiti: ZepGraphitiDep):
32+
return await graphiti.get_entity_edge(uuid)
33+
34+
3035
@router.get('/episodes/{group_id}', status_code=status.HTTP_200_OK)
3136
async def get_episodes(group_id: str, last_n: int, graphiti: ZepGraphitiDep):
3237
episodes = await graphiti.retrieve_episodes(

server/graph_service/zep_graphiti.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from typing import Annotated
22

3-
from fastapi import Depends
3+
from fastapi import Depends, HTTPException
44
from graphiti_core import Graphiti # type: ignore
55
from graphiti_core.edges import EntityEdge # type: ignore
6+
from graphiti_core.errors import EdgeNotFoundError, NodeNotFoundError # type: ignore
67
from graphiti_core.llm_client import LLMClient # type: ignore
7-
from graphiti_core.nodes import EntityNode # type: ignore
8+
from graphiti_core.nodes import EntityNode, EpisodicNode # type: ignore
89

910
from graph_service.config import ZepEnvDep
1011
from graph_service.dto import FactResult
@@ -25,6 +26,27 @@ async def save_entity_node(self, name: str, uuid: str, group_id: str, summary: s
2526
await new_node.save(self.driver)
2627
return new_node
2728

29+
async def get_entity_edge(self, uuid: str):
30+
try:
31+
edge = await EntityEdge.get_by_uuid(self.driver, uuid)
32+
return edge
33+
except EdgeNotFoundError as e:
34+
raise HTTPException(status_code=404, detail=e.message) from e
35+
36+
async def delete_entity_edge(self, uuid: str):
37+
try:
38+
edge = await EntityEdge.get_by_uuid(self.driver, uuid)
39+
await edge.delete(self.driver)
40+
except EdgeNotFoundError as e:
41+
raise HTTPException(status_code=404, detail=e.message) from e
42+
43+
async def delete_episodic_node(self, uuid: str):
44+
try:
45+
episode = await EpisodicNode.get_by_uuid(self.driver, uuid)
46+
await episode.delete(self.driver)
47+
except NodeNotFoundError as e:
48+
raise HTTPException(status_code=404, detail=e.message) from e
49+
2850

2951
async def get_graphiti(settings: ZepEnvDep):
3052
client = ZepGraphiti(

0 commit comments

Comments
 (0)