fix serialize research detail UUIDs

This commit is contained in:
faligam
2026-09-07 13:01:46 +02:00
parent e483c4d13f
commit 7b279dceea
2 changed files with 60 additions and 4 deletions

View File

@@ -686,7 +686,11 @@ async def get_sources(research_id: str) -> SourcesResponse:
run = _load_run(research_id) run = _load_run(research_id)
sources = [ sources = [
SourceListItem( SourceListItem(
id=s.get("id", str(uuid.uuid4())), # Pipeline models retain identifiers as UUID objects. The public
# REST contract deliberately exposes JSON strings, so normalize
# here instead of letting strict Pydantic validation turn a
# successful research run into a 500 response.
id=str(s.get("id", uuid.uuid4())),
url=s.get("url", ""), url=s.get("url", ""),
title=s.get("title"), title=s.get("title"),
domain=s.get("domain", ""), domain=s.get("domain", ""),
@@ -712,9 +716,9 @@ async def get_claims(research_id: str) -> ClaimsResponse:
run = _load_run(research_id) run = _load_run(research_id)
claims = [ claims = [
ClaimListItem( ClaimListItem(
id=c.get("id", str(uuid.uuid4())), id=str(c.get("id", uuid.uuid4())),
research_run_id=run.research_id, research_run_id=run.research_id,
source_id=c.get("source_id", ""), source_id=str(c.get("source_id", "")),
claim_text=c.get("claim_text", c.get("claim", "")), claim_text=c.get("claim_text", c.get("claim", "")),
evidence_span=c.get("evidence_span", ""), evidence_span=c.get("evidence_span", ""),
claim_type=c.get("claim_type", "claim"), claim_type=c.get("claim_type", "claim"),
@@ -737,7 +741,16 @@ async def get_claims(research_id: str) -> ClaimsResponse:
async def get_evidence(research_id: str) -> EvidenceResponse: async def get_evidence(research_id: str) -> EvidenceResponse:
"""Evidence-Scores für einen Research-Run abrufen.""" """Evidence-Scores für einen Research-Run abrufen."""
run = _load_run(research_id) run = _load_run(research_id)
scores = [EvidenceScoreItem(**s) for s in run.evidence_scores] scores = [
EvidenceScoreItem(
**{
**score,
"claim_id": str(score.get("claim_id", "")),
"research_run_id": str(score.get("research_run_id", run.research_id)),
}
)
for score in run.evidence_scores
]
return EvidenceResponse( return EvidenceResponse(
research_id=run.research_id, research_id=run.research_id,
evidence=scores, evidence=scores,

View File

@@ -4,6 +4,7 @@ from __future__ import annotations
from typing import Generator from typing import Generator
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from uuid import uuid4
import pytest import pytest
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
@@ -307,6 +308,48 @@ def test_get_claims_empty(client: TestClient) -> None:
assert body["claims"] == [] assert body["claims"] == []
def test_detail_endpoints_serialize_pipeline_uuid_identifiers(client: TestClient) -> None:
"""Completed pipeline data must satisfy the string-based REST contract."""
from nsct.api.rest_research import _ResearchRunState, _research_store
from nsct.orchestration.budget import HardBudgetConfig
_research_store.clear()
research_id = str(uuid4())
source_id = uuid4()
claim_id = uuid4()
_research_store[research_id] = _ResearchRunState(
research_id=research_id,
query="UUID serialization",
language="de",
depth="quick",
budget=HardBudgetConfig(),
sources=[{"id": source_id, "url": "https://example.org/article"}],
claims=[
{
"id": claim_id,
"source_id": source_id,
"claim_text": "Eine überprüfbare Behauptung.",
"evidence_span": "Überprüfbare Passage.",
"claim_type": "claim",
}
],
evidence_scores=[{"claim_id": claim_id, "research_run_id": uuid4()}],
report={"summary": "Zusammenfassung", "findings": [], "methodology": "Methodik"},
)
sources = client.get(f"/v1/research/{research_id}/sources")
claims = client.get(f"/v1/research/{research_id}/claims")
evidence = client.get(f"/v1/research/{research_id}/evidence")
report = client.get(f"/v1/research/{research_id}/report")
assert [response.status_code for response in (sources, claims, evidence, report)] == [200] * 4
assert sources.json()["sources"][0]["id"] == str(source_id)
assert claims.json()["claims"][0]["id"] == str(claim_id)
assert claims.json()["claims"][0]["source_id"] == str(source_id)
assert evidence.json()["evidence"][0]["claim_id"] == str(claim_id)
assert report.json()["methodology"] == "Methodik"
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# GET /v1/research/{id}/evidence — evidence # GET /v1/research/{id}/evidence — evidence
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------