49 lines
1.3 KiB
Python
49 lines
1.3 KiB
Python
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()
|