graph_router.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. from re import S
  2. from fastapi import FastAPI, HTTPException
  3. from fastapi import APIRouter, Depends, Query
  4. # from networkx import graph
  5. from pydantic import BaseModel
  6. from typing import List, Optional, Dict
  7. from sqlalchemy import create_engine, Column, Integer, String, Boolean, JSON
  8. from sqlalchemy.ext.declarative import declarative_base
  9. from sqlalchemy.orm import properties, sessionmaker
  10. from sqlalchemy.orm import Session
  11. import logging
  12. from agent.libs.graph import GraphBusiness
  13. from agent.libs.user_data_relation import UserDataRelationBusiness
  14. from agent.libs.user import UserBusiness
  15. from agent.db.database import get_db
  16. from agent.models.web.response import StandardResponse,FAILED,SUCCESS
  17. router = APIRouter(prefix="/graph_mg", tags=["knowledge graph management interface"])
  18. logger = logging.getLogger(__name__)
  19. # Pydantic models
  20. class CreateEntity(BaseModel):
  21. user_id: int
  22. graph_id: int
  23. label: str
  24. name: str
  25. properties: Optional[Dict] = None
  26. class DeleteEntity(BaseModel):
  27. user_id: int
  28. graph_id: int
  29. node_id: int
  30. class UpdateEntity(BaseModel):
  31. user_id: int
  32. graph_id: int
  33. node_id: int
  34. name: str
  35. class FindEntity(BaseModel):
  36. user_id: int
  37. graph_id: int
  38. node_id: int
  39. class SearchEntity(BaseModel):
  40. user_id: int
  41. graph_id: int
  42. label: str
  43. name: str
  44. class EntityVO(BaseModel):
  45. user_id: int
  46. graph_id: int
  47. label: str
  48. node_id: int
  49. properties: Dict
  50. class DeleteProperty(BaseModel):
  51. user_id: int
  52. graph_id: int
  53. node_id: int
  54. property_name: str
  55. class UpdateProperty(BaseModel):
  56. user_id: int
  57. graph_id: int
  58. node_id: int
  59. property_name: str
  60. property_value: str
  61. class RelationshipVO(BaseModel):
  62. user_id: int
  63. graph_id: int
  64. start_id: int
  65. end_id: int
  66. start_label: str
  67. end_label: str
  68. relationship_type: str
  69. property: Optional[Dict] = None
  70. class RelationshipNameVO(BaseModel):
  71. user_id: int
  72. graph_id: int
  73. relationship_type: str
  74. class UpdateRelationTypeVO(BaseModel):
  75. user_id: int
  76. graph_id: int
  77. old_relationship_type: str
  78. new_relationship_type: str
  79. # Entity endpoints
  80. @router.post("/entity/create", response_model=StandardResponse)
  81. def create_entity(entities: List[CreateEntity], db: Session = Depends(get_db)):
  82. try:
  83. results = []
  84. graph_business = GraphBusiness(db)
  85. user_data_relation_business = UserDataRelationBusiness(db)
  86. user_business = UserBusiness(db)
  87. user_id = entities[0].user_id
  88. user = user_business.get_user(user_id)
  89. if not user:
  90. raise HTTPException(status_code=404, detail="User not found")
  91. for entity in entities:
  92. node = graph_business.create_node(graph_id=entity.graph_id, name=entity.name, category=entity.label, props=entity.properties if entity.properties else {})
  93. user_data_relation_business.create_relation(user_id=entity.user_id, data_category="DbKgNode", data_id=node.id, user_name=user.username, role_id=user.roles[0].id, role_name=user.roles[0].name)
  94. results.append({"id": node.id, "label": node.category, "name": node.name})
  95. return StandardResponse(records=results, code=SUCCESS, message="Success")
  96. except Exception as e:
  97. logger.error(f"Error creating entity: {str(e)}")
  98. raise HTTPException(status_code=500, detail="Internal Server Error")
  99. @router.post("/entity/delete", response_model=StandardResponse)
  100. def delete_entity(entities: List[DeleteEntity], db: Session = Depends(get_db)):
  101. try:
  102. graph_business = GraphBusiness(db)
  103. for entity in entities:
  104. graph_business.delete_node(entity.graph_id,entity.node_id)
  105. return StandardResponse(records=[], code=SUCCESS, message="Success")
  106. except Exception as e:
  107. logger.error(f"Error deleting entity: {str(e)}")
  108. raise HTTPException(status_code=500, detail="Internal Server Error")
  109. @router.post("/entity/update", response_model=StandardResponse)
  110. def update_entity(entities: List[UpdateEntity], db: Session = Depends(get_db)):
  111. try:
  112. results = []
  113. graph_business = GraphBusiness(db)
  114. for entity in entities:
  115. node = graph_business.update_node(graph_id=entity.graph_id, id=entity.node_id, name=entity.name)
  116. if not node:
  117. continue
  118. results.append({"id": node.id, "label": node.category, "name": node.name})
  119. return StandardResponse(records=results, code=SUCCESS, message="Success")
  120. except Exception as e:
  121. logger.error(f"Error updating entity: {str(e)}")
  122. raise HTTPException(status_code=500, detail="Internal Server Error")
  123. @router.post("/entity/find", response_model=StandardResponse)
  124. def find_entity(entity: FindEntity, db: Session = Depends(get_db)):
  125. try:
  126. graph_business = GraphBusiness(db)
  127. node = graph_business.get_node_by_id(entity.graph_id, entity.node_id)
  128. if not node:
  129. raise HTTPException(status_code=404, detail="Entity not found")
  130. props = []
  131. if node.props:
  132. for prop in node.props:
  133. props.append({
  134. "name": prop.prop_name,
  135. "title": prop.prop_title,
  136. "value": prop.prop_value
  137. })
  138. result = {"id": node.id, "label": node.category, "name": node.name, "properties": props}
  139. return StandardResponse(records=[result], code=SUCCESS, message="Success")
  140. except Exception as e:
  141. logger.error(f"Error finding entity: {str(e)}")
  142. raise HTTPException(status_code=500, detail="Internal Server Error")
  143. @router.post("/entity/search", response_model=StandardResponse)
  144. def search_entity(entity: SearchEntity, db: Session = Depends(get_db)):
  145. try:
  146. graph_business = GraphBusiness(db)
  147. nodes = graph_business.search_like_node_by_name(entity.name, entity.label, entity.graph_id,20)
  148. results = [{"id": node.id, "label": node.category, "name": node.name} for node in nodes]
  149. return StandardResponse(records=results, code=SUCCESS, message="Success")
  150. except Exception as e:
  151. logger.error(f"Error searching entity: {str(e)}")
  152. raise HTTPException(status_code=500, detail="Internal Server Error")
  153. # Property endpoints
  154. @router.post("/property/create", response_model=StandardResponse)
  155. def create_property(entities: List[EntityVO], db: Session = Depends(get_db)):
  156. try:
  157. results = []
  158. graph_business = GraphBusiness(db)
  159. for entity in entities:
  160. node = graph_business.get_node_by_id(entity.graph_id, entity.node_id)
  161. if not node:
  162. continue
  163. property = entity.properties
  164. props = graph_business.create_node_prop(category=entity.label, ref_id=entity.node_id, prop_name=property["name"], prop_value=property["value"],prop_title=property["name"])
  165. properties = []
  166. for prop in props:
  167. properties.append({
  168. "name": prop.prop_name,
  169. "title": prop.prop_title,
  170. "value": prop.prop_value
  171. })
  172. results.append({"id": node.id, "properties": properties})
  173. return StandardResponse(records=results, code=SUCCESS, message="Success")
  174. except Exception as e:
  175. logger.error(f"Error creating property: {str(e)}")
  176. raise HTTPException(status_code=500, detail="Internal Server Error")
  177. # @router.post("/property/delete", response_model=StandardResponse)
  178. # def delete_property(properties: List[DeleteProperty], db: Session = Depends(get_db)):
  179. # try:
  180. # results = []
  181. # graph_business = GraphBusiness(db)
  182. # for property in properties:
  183. # node = graph_business.get_node_by_id(property.graph_id, property.node_id)
  184. # if not node:
  185. # continue
  186. # graph_business.delete_node_prop(property.graph_id, property.node_id, property.property_name)
  187. # except Exception as e:
  188. # logger.error(f"Error deleting property: {str(e)}")
  189. # raise HTTPException(status_code=500, detail="Internal Server Error")
  190. @router.post("/property/update", response_model=StandardResponse)
  191. def update_property(property: UpdateProperty, db: Session = Depends(get_db)):
  192. try:
  193. graph_business = GraphBusiness(db)
  194. node = graph_business.get_node_by_id(property.graph_id, property.node_id)
  195. if not node or not node.props:
  196. raise HTTPException(status_code=404, detail="Entity or property not found")
  197. graph_business.update_node_prop(property.node_id, property.property_name, property.property_value)
  198. return StandardResponse(records=[], code=SUCCESS, message="Success")
  199. except Exception as e:
  200. logger.error(f"Error updating property: {str(e)}")
  201. raise HTTPException(status_code=500, detail="Internal Server Error")
  202. # Relationship endpoints
  203. @router.post("/relationship/create", response_model=StandardResponse)
  204. def create_relationship(relationships: List[RelationshipVO], db: Session = Depends(get_db)):
  205. try:
  206. graph_business = GraphBusiness(db)
  207. for rel in relationships:
  208. graph_business.create_edge(graph_id=rel.graph_id, src_id=rel.start_id, dest_id=rel.end_id, category=rel.relationship_type, name=rel.relationship_type, props=rel.property if rel.property else {})
  209. return StandardResponse(records=[], code=SUCCESS, message="Success")
  210. except Exception as e:
  211. logger.error(f"Error creating relationship: {str(e)}")
  212. raise HTTPException(status_code=500, detail="Internal Server Error")
  213. @router.post("/relationship/delete", response_model=StandardResponse)
  214. def delete_relationship(relationships: List[RelationshipVO], db: Session = Depends(get_db)):
  215. try:
  216. graph_business = GraphBusiness(db)
  217. for rel in relationships:
  218. graph_business.delete_edge(graph_id=rel.graph_id, src_id=rel.start_id, dest_id=rel.end_id, category=rel.relationship_type, name=rel.relationship_type)
  219. return StandardResponse(records=[], code=SUCCESS, message="Success")
  220. except Exception as e:
  221. logger.error(f"Error deleting relationship: {str(e)}")
  222. raise HTTPException(status_code=500, detail="Internal Server Error")
  223. @router.post("/relationship/search", response_model=StandardResponse)
  224. def search_relationship(relation: RelationshipNameVO, db: Session = Depends(get_db)):
  225. try:
  226. graph_business = GraphBusiness(db)
  227. edges = graph_business.search_edges(graph_id=relation.graph_id, category=relation.relationship_type)
  228. if not edges:
  229. raise HTTPException(status_code=404, detail="Relationship not found")
  230. return StandardResponse(records=[edge.category for edge in edges], code=SUCCESS, message="Success")
  231. except Exception as e:
  232. logger.error(f"Error searching relationship: {str(e)}")
  233. raise HTTPException(status_code=500, detail="Internal Server Error")
  234. @router.post("/relationship/update", response_model=StandardResponse)
  235. def update_relationship(updates: List[UpdateRelationTypeVO], db: Session = Depends(get_db)):
  236. try:
  237. graph_business = GraphBusiness(db)
  238. for update in updates:
  239. graph_business.update_edges(graph_id=update.graph_id, old_category=update.old_relationship_type, new_category=update.new_relationship_type)
  240. return StandardResponse(records=[], code=SUCCESS, message="Success")
  241. except Exception as e:
  242. logger.error(f"Error updating relationship: {str(e)}")
  243. raise HTTPException(status_code=500, detail="Internal Server Error")
  244. graph_router = router