67 lines
2.0 KiB
Python
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()
|