174 lines
8.4 KiB
Python
174 lines
8.4 KiB
Python
from dotenv import load_dotenv, find_dotenv
|
|
load_dotenv(find_dotenv())
|
|
import os
|
|
import modules.logger_tool as logger
|
|
log_name = 'api_routers_database_tools_get_nodes'
|
|
log_dir = os.getenv("LOG_PATH", "/logs") # Default path as fallback
|
|
logging = logger.get_logger(
|
|
name=log_name,
|
|
log_level=os.getenv("LOG_LEVEL", "DEBUG"),
|
|
log_path=log_dir,
|
|
log_file=log_name,
|
|
runtime=True,
|
|
log_format='default'
|
|
)
|
|
import modules.database.tools.neo4j_driver_tools as driver
|
|
import modules.database.tools.neo4j_session_tools as session
|
|
from modules.database.schemas.nodes.calendars import CalendarNode, CalendarYearNode, CalendarMonthNode, CalendarWeekNode, CalendarDayNode, CalendarTimeChunkNode
|
|
from modules.database.schemas.nodes.users import UserNode
|
|
from modules.database.schemas.nodes.workers.workers import TeacherNode, StudentNode, DeveloperNode, SchoolAdminNode
|
|
from modules.database.schemas.nodes.structures.schools import PastoralStructureNode, CurriculumStructureNode
|
|
from modules.database.schemas.nodes.schools.pastoral import YearGroupNode, YearGroupSyllabusNode
|
|
from modules.database.schemas.nodes.schools.curriculum import SubjectNode, TopicNode, TopicLessonNode, LearningStatementNode, ScienceLabNode
|
|
from modules.database.schemas.nodes.schools.timetable import SchoolTimetableNode, AcademicYearNode, AcademicTermNode, AcademicWeekNode, AcademicDayNode, OffTimetableDayNode, StaffDayNode, AcademicPeriodNode, RegistrationPeriodNode, OffTimetablePeriodNode, AcademicTermBreakNode, BreakPeriodNode, HolidayDayNode, HolidayWeekNode
|
|
from modules.database.schemas.nodes.workers.timetable import TeacherTimetableNode, TimetableLessonNode, PlannedLessonNode, UserTeacherTimetableNode, StudentTimetableNode, SchoolAdminTimetableNode, DeveloperTimetableNode, SuperAdminTimetableNode
|
|
from modules.database.schemas.nodes.schools.schools import SchoolNode, DepartmentNode, SubjectClassNode, RoomNode
|
|
from fastapi import APIRouter, HTTPException, Query
|
|
|
|
router = APIRouter()
|
|
|
|
@router.get("/get-all-nodes-and-edges")
|
|
async def get_all_nodes_and_edges():
|
|
db_name = os.getenv("NEO4J_DB_NAME", "cc.institutes.kevlarai")
|
|
logging.info(f"Getting all nodes and edges from database {db_name}")
|
|
neo_driver = driver.get_driver(db_name=db_name)
|
|
if neo_driver is None:
|
|
return {"status": "error", "message": "Failed to connect to the database"}
|
|
|
|
try:
|
|
with neo_driver.session(database=db_name) as neo_session:
|
|
query = """
|
|
MATCH (n)-[r]->(m)
|
|
RETURN n, r, m
|
|
"""
|
|
result = neo_session.run(query)
|
|
nodes = {}
|
|
relationships = []
|
|
|
|
for record in result:
|
|
source = record['n']
|
|
target = record['m']
|
|
relationship = record['r']
|
|
|
|
for node in [source, target]:
|
|
if node.id not in nodes:
|
|
node_labels = list(node.labels)
|
|
node_type = node_labels[0] if node_labels else "Unknown"
|
|
node_data = dict(node)
|
|
try:
|
|
node_class = globals()[f"{node_type}Node"]
|
|
node_object = node_class(**node_data)
|
|
node_dict = node_object.to_dict()
|
|
except Exception as e:
|
|
logging.error(f"Error converting node to dict: {str(e)}")
|
|
node_dict = node_data
|
|
|
|
nodes[node.id] = {
|
|
"node_type": node_type,
|
|
"node_data": node_dict
|
|
}
|
|
|
|
relationship_info = {
|
|
"start_node": source.id,
|
|
"end_node": target.id,
|
|
"relationship_type": relationship.type,
|
|
"relationship_properties": dict(relationship)
|
|
}
|
|
relationships.append(relationship_info)
|
|
|
|
return {
|
|
"status": "success",
|
|
"nodes": list(nodes.values()),
|
|
"relationships": relationships
|
|
}
|
|
except Exception as e:
|
|
logging.error(f"Error retrieving all nodes and edges: {str(e)}")
|
|
return {"status": "error", "message": "Internal server error"}
|
|
finally:
|
|
driver.close_driver(neo_driver)
|
|
|
|
|
|
@router.get("/get-connected-nodes-and-edges")
|
|
async def get_connected_nodes_and_edges(uuid_string: str = Query(...), db_name: str = Query(...)):
|
|
logging.info(f"Getting connected nodes and edges for {uuid_string} from database {db_name}")
|
|
neo_driver = driver.get_driver(db_name=db_name)
|
|
if neo_driver is None:
|
|
return {"status": "error", "message": "Failed to connect to the database"}
|
|
|
|
try:
|
|
with neo_driver.session(database=db_name) as neo_session:
|
|
query = """
|
|
MATCH (n {uuid_string: $uuid_string})
|
|
OPTIONAL MATCH (n)-[r]-(connected)
|
|
RETURN n, collect(connected) as connected_nodes, collect(r) as relationships
|
|
"""
|
|
result = neo_session.run(query, uuid_string=uuid_string)
|
|
record = result.single()
|
|
if record:
|
|
main_node = record['n']
|
|
connected_nodes = record['connected_nodes']
|
|
relationships = record['relationships']
|
|
|
|
main_node_labels = list(main_node.labels)
|
|
main_node_type = main_node_labels[0] if main_node_labels else "Unknown"
|
|
main_node_data = dict(main_node)
|
|
|
|
try:
|
|
main_node_class = globals()[f"{main_node_type}Node"]
|
|
main_node_object = main_node_class(**main_node_data)
|
|
main_node_dict = main_node_object.to_dict()
|
|
except Exception as e:
|
|
logging.error(f"Error converting main node to dict: {str(e)}")
|
|
main_node_dict = main_node_data
|
|
|
|
connected_nodes_list = []
|
|
relationship_list = []
|
|
|
|
for node, relationship in zip(connected_nodes, relationships):
|
|
node_labels = list(node.labels)
|
|
node_type = node_labels[0] if node_labels else "Unknown"
|
|
node_data = dict(node)
|
|
try:
|
|
node_class = globals()[f"{node_type}Node"]
|
|
node_object = node_class(**node_data)
|
|
connected_node_dict = node_object.to_dict()
|
|
except Exception as e:
|
|
logging.error(f"Error converting connected node to dict: {str(e)}")
|
|
connected_node_dict = node_data
|
|
|
|
connected_node_info = {
|
|
"node_type": node_type,
|
|
"node_data": connected_node_dict,
|
|
"relationship_type": relationship.type, # Get relationship type
|
|
"relationship_properties": dict(relationship) # Relationship properties, if any
|
|
}
|
|
connected_nodes_list.append(connected_node_info)
|
|
|
|
relationship_info = {
|
|
"start_node": dict(relationship.start_node),
|
|
"end_node": dict(relationship.end_node),
|
|
"relationship_type": relationship.type,
|
|
"relationship_properties": dict(relationship)
|
|
}
|
|
relationship_list.append(relationship_info)
|
|
|
|
logging.info(f"Main node: {main_node_dict}")
|
|
logging.info(f"Connected nodes: {connected_nodes_list}")
|
|
logging.info(f"Relationships: {relationship_list}")
|
|
|
|
return {
|
|
"status": "success",
|
|
"main_node": {
|
|
"node_type": main_node_type,
|
|
"node_data": main_node_dict
|
|
},
|
|
"connected_nodes": connected_nodes_list,
|
|
"relationships": relationship_list
|
|
}
|
|
else:
|
|
return {"status": "not_found", "message": "Node not found"}
|
|
except Exception as e:
|
|
logging.error(f"Error retrieving connected nodes: {str(e)}")
|
|
raise HTTPException(status_code=500, detail="Internal server error")
|
|
finally:
|
|
driver.close_driver(neo_driver) |