From ba175168140417a0220df1e7426b24448c048327 Mon Sep 17 00:00:00 2001 From: Lars Date: Tue, 7 Oct 2025 11:31:47 +0200 Subject: [PATCH] =?UTF-8?q?app/routers/graph.py=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/routers/graph.py | 54 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 app/routers/graph.py diff --git a/app/routers/graph.py b/app/routers/graph.py new file mode 100644 index 0000000..8ef613a --- /dev/null +++ b/app/routers/graph.py @@ -0,0 +1,54 @@ +""" +app/routers/graph.py — Graph-Endpunkte (WP-04) + +Zweck: + Liefert die Nachbarschaft einer Note/ID als JSON-Graph (Nodes/Edges/Stats). +Kompatibilität: + Python 3.12+, FastAPI 0.110+, qdrant-client 1.x +Version: + 0.1.0 (Erstanlage) +Stand: + 2025-10-07 +Bezug: + - app/core/graph_adapter.py + - app/models/dto.py +Nutzung: + app.include_router(graph.router, prefix="/graph", tags=["graph"]) +Änderungsverlauf: + 0.1.0 (2025-10-07) – Erstanlage. +""" + +from __future__ import annotations +from typing import List, Optional +from fastapi import APIRouter, Query +from qdrant_client import QdrantClient +from app.models.dto import GraphResponse, NodeDTO, EdgeDTO +from app.core.graph_adapter import expand +from app.config import get_settings + +router = APIRouter() + +@router.get("/{note_id}", response_model=GraphResponse) +def get_graph(note_id: str, depth: int = 1, edge_types: Optional[List[str]] = Query(None)) -> GraphResponse: + s = get_settings() + client = QdrantClient(url=s.QDRANT_URL, api_key=s.QDRANT_API_KEY) + + sg = expand(client, s.COLLECTION_PREFIX, [note_id], depth=depth, edge_types=edge_types) + + # Seed-Node (Payload optional später ergänzen über get_note_payload) + nodes = [NodeDTO(id=note_id, type="note", + title=None, tags=[], + in_degree=sg.in_degree.get(note_id, 0), + out_degree=sg.out_degree.get(note_id, 0))] + + # direkte Out-Kanten des Seeds + edges = [] + for e in sg.adj.get(note_id, []): + edges.append(EdgeDTO( + id=f"{note_id}->{e['target']}:{e['kind']}", + kind=e["kind"], source=note_id, target=e["target"], + weight=float(e["weight"]), direction="out" + )) + + return GraphResponse(center_note_id=note_id, nodes=nodes, edges=edges, + stats={"node_count": len(nodes), "edge_count": len(edges)})