from fastapi import FastAPI, HTTPException from pydantic import BaseModel from typing import Any, Dict from .storage import EventLog from .adapters import build_block_from_events from .ledger import SimpleLedger 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") # events are read as dicts with ts,type,payload payloads = [e["payload"] for e in events] block = build_block_from_events(payloads) # produce deterministic JSON for ledger anchoring import json 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()