runtime-narrative — model execution as human-readable stories
Project description
runtime_narrative
Model your application's execution as human-readable stories instead of scattered log lines.
When something fails, instead of a raw traceback you get:
❌ Failure detected
Story: Create Customer
Stage: Validate Input
Error: ValueError - invalid email
Location: handlers.py:24 (validate_customer)
Code: if "@" not in payload.email:
Progress: 33% (1 / 3 stages completed)
Recent stages: Validate Input=failed (0.001s)
Installation
# Core only (zero dependencies)
pip install runtime-narrative
# With colored console output
pip install "runtime-narrative[console]"
# With FastAPI middleware
pip install "runtime-narrative[fastapi]"
# Everything
pip install "runtime-narrative[all]"
Quick start
from runtime_narrative import story, stage
with story("Import Customers"):
with stage("Load CSV"):
load_file()
with stage("Validate Data"):
validate()
with stage("Insert Records"):
insert()
FastAPI — middleware (recommended)
Add middleware once and every request gets a story automatically. Route handlers only need to declare stages:
from runtime_narrative import RuntimeNarrativeMiddleware, stage
app.add_middleware(RuntimeNarrativeMiddleware)
@app.post("/customers")
async def create_customer(payload: CustomerIn):
with stage("Validate Input"):
...
with stage("Insert Into Database"):
...
with stage("Build Response"):
return {"ok": True}
FastAPI — decorator style
from runtime_narrative import runtime_narrative_story, runtime_narrative_stage
@app.post("/customers")
@runtime_narrative_story("Create Customer")
async def create_customer(payload: CustomerIn):
return await _save(payload)
@runtime_narrative_stage("Save to Database")
async def _save(payload):
...
Structured JSON output
Pipe one JSON object per lifecycle event to stdout, a file, or any stream:
from runtime_narrative import RuntimeNarrativeMiddleware, JsonRenderer
app.add_middleware(RuntimeNarrativeMiddleware, renderers=[JsonRenderer()])
Output (one line per event):
{"event": "StoryStarted", "story_id": "...", "story_name": "POST /customers", "timestamp": "..."}
{"event": "StageStarted", "story_id": "...", "stage_name": "Validate Input", "timestamp": "..."}
{"event": "StageCompleted", "story_id": "...", "stage_name": "Validate Input", "duration_seconds": 0.001, "timestamp": "..."}
{"event": "StoryCompleted", "story_id": "...", "success": true, "progress": {"percent": 100, ...}, "timestamp": "..."}
Write to a file instead of stdout:
JsonRenderer(output=open("runtime_narrative.log", "a"))
LLM failure analysis
Plug in any LLM backend — model name and endpoint are always required (no defaults).
OpenAI-compatible backends (vLLM, llama.cpp --server, LM Studio, Ollama OpenAI mode):
from runtime_narrative import LLMFailureAnalyzer, story
analyzer = LLMFailureAnalyzer(
model="llama3",
endpoint="http://localhost:8000/v1/chat/completions",
)
with story("Process Orders", failure_analyzer=analyzer):
...
Ollama native API:
from runtime_narrative import OllamaFailureAnalyzer, story
analyzer = OllamaFailureAnalyzer(
model="llama3",
endpoint="http://localhost:11434/api/generate",
)
with story("Process Orders", failure_analyzer=analyzer):
...
Falls back silently if the endpoint is unavailable.
Custom renderer
Implement a single handle method to receive all lifecycle events:
class MyRenderer:
def handle(self, event):
print(event.__class__.__name__, event.__dict__)
with story("My Story", renderers=[MyRenderer()]):
...
Events: StoryStarted, StageStarted, StageCompleted, FailureOccurred, StoryCompleted.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file runtime_narrative-0.1.0.tar.gz.
File metadata
- Download URL: runtime_narrative-0.1.0.tar.gz
- Upload date:
- Size: 13.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30766660c6177df2eda862f0d29d6146c45930d1c5cd4215bf877e19645624b9
|
|
| MD5 |
33fd7ba3552cc19ea8b4ae844bf45561
|
|
| BLAKE2b-256 |
7f1f8db8040a213c29ab52b1a5075831dc888ed9328ac3c440b55fdc5d36bddd
|
File details
Details for the file runtime_narrative-0.1.0-py3-none-any.whl.
File metadata
- Download URL: runtime_narrative-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d9501aa8e0176086f842cce455dca2a46df126319f3a541d20ec109231a25e6d
|
|
| MD5 |
55b87fe47b8c1f200e00a0c3edd97bc0
|
|
| BLAKE2b-256 |
bf181d7d32f82c9d3ae7ee9102edd07899ffe753e604620761e51d44e38582d5
|