fix serialize research detail UUIDs
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user