idea70-narrativeweave-real-.../idea70_narrativeweave_real_.../api.py

67 lines
2.0 KiB
Python

import json
from typing import Any, Dict
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from .storage import EventLog
from .adapters import build_block_from_events
from .ledger import SimpleLedger
from .narrative import diff_narrative_blocks, render_narrative_block
app = FastAPI(title="NarrativeWeave API")
_store = EventLog(path=":memory:")
_ledger = SimpleLedger()
class IngestPayload(BaseModel):
type: str
payload: Dict[str, Any]
@app.post("/ingest")
def ingest(ev: IngestPayload):
# store the raw event
_store.append_event(ev.type, ev.payload)
return {"status": "ok"}
@app.post("/build_block")
def build_block():
events = _store.read_events()
if not events:
raise HTTPException(status_code=404, detail="no events")
block = build_block_from_events(events)
# produce deterministic JSON for ledger anchoring
block_json = json.dumps(block.model_dump(), sort_keys=True, default=str)
anchor = _ledger.anchor(block_json)
_store.save_block(block, ledger_anchor=anchor)
return {"block_id": block.id, "ledger_anchor": anchor}
@app.get("/block/{block_id}")
def get_block(block_id: str):
b = _store.get_block(block_id)
if not b:
raise HTTPException(status_code=404, detail="block not found")
return b.dict()
@app.get("/block/{block_id}/render")
def render_block(block_id: str, redacted: bool = False):
b = _store.get_block(block_id)
if not b:
raise HTTPException(status_code=404, detail="block not found")
return {"block_id": block_id, "redacted": redacted, "markdown": render_narrative_block(b, redacted=redacted)}
@app.get("/block/{left_block_id}/diff/{right_block_id}")
def diff_blocks(left_block_id: str, right_block_id: str):
left = _store.get_block(left_block_id)
right = _store.get_block(right_block_id)
if not left or not right:
raise HTTPException(status_code=404, detail="block not found")
diff = diff_narrative_blocks(left, right)
return diff.dict()