# narrativetrace-python > Zero-boilerplate execution tracing: your method and parameter names become the log. A uv > workspace with a dependency-free core and thin integration packages. Wrap an object with `trace_object(obj, context)`; call it; render `context.capture_trace()`. The narrative is generated from names and values — no logging calls in the business code. ## Install and first trace (copy this) ```bash uv add narrativetrace ``` ```python # main.py from narrativetrace import ( ContextVarNarrativeContext, IndentedTextRenderer, not_traced, trace_object, ) class OrderService: @not_traced("customer_id") def place_order(self, customer_id, product_id, quantity): return f"ORD-{customer_id}-{product_id}-{quantity}" context = ContextVarNarrativeContext() service = trace_object(OrderService(), context) service.place_order("cust-1", "prod-42", 3) print(IndentedTextRenderer().render(context.capture_trace())) ``` Run: `uv run main.py`. Expected output (duration varies by machine): ```text trace: meek gull dips (6a17832) OrderService.place_order(customer_id: [REDACTED], product_id: "prod-42", quantity: 3) → "ORD-cust-1-prod-42-3" — 0ms ``` ## Before you start - One `LoggingTraceConsumer` per event stream, always — a second instance is needless (add `logging.Handler`s instead). - Sending a trace to your logger: one-call `export_to_logger(trace)`. - Every package installs from PyPI today (`uv add ...`); a workspace checkout is only for contributing to this repo, never required to use it. - `narrativetrace-pytest` artifact-writing defaults **on**. - `narrativetrace-structlog` pulls in `structlog` itself. - A composite's own `__str__`/`__repr__` is never trusted for redaction — any object carrying instance state is introspected field-by-field regardless, **except a platform-defined type** (`pathlib.Path`, `datetime`, `decimal.Decimal`, `uuid.UUID`, `fractions.Fraction`, `ipaddress.*`), which keeps its own short `str()` — decided by origin (`__module__`, never a name prefix), so a lookalike or a subclass is still walked (see [Privacy and Redaction](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/documentation/privacy-and-redaction.md)). - `__nt_not_traced__` is a class attribute — a tuple/list/set of field names — for redacting fields on any object a dataclass field can't reach (see the [Decorators guide](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/documentation/guides/decorators.md)). - `narrativetrace-pytest` now also writes a value-free `.nt` structural artifact per test invocation, with a `manifest.json` index and a last-green delta on the suite footer; `NARRATIVETRACE_APPROVAL=true` turns on approval mode against a committed `.approved.nt` trace, promoted with `uv run poe approve` / `narrativetrace-approve` (see [Structural Trace Format](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/documentation/structural-trace-format.md)). - The run has a name: one id per pytest session, its three-word phrase in the suite footer, `manifest.json`'s top-level `run` object, every trace document's frontmatter, and the logging bridge's `runName` key — never in the structural `.nt` text (see [Configuration Guide § The run has a name](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/documentation/guides/configuration.md#the-run-has-a-name)). - Importing `not_traced` or `narrated` protects nothing by itself — apply each to a real parameter/field/method and prove it with `assert "[REDACTED]" in rendered`; `uv run narrativetrace doctor` catches the unapplied-marker shape of this (`trap.silent-sink`, `trap.redaction-proof`) — see [Privacy and Redaction § You imported this — apply it like this](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/documentation/privacy-and-redaction.md#you-imported-this--apply-it-like-this). ## Field notes from AI agents (self-reported, not a benchmark) We asked AI agents to build a claims service with NarrativeTrace and write up the experience for another engineer, naming what was awkward. Prompted, one run each, unedited, model named; we wrote the library. The reports so far are from the Java runtime; the same exercise runs for Python next, and the principle they describe — the trace as evidence, redaction by parameter name, output on by default — is the same here. All six reports, the exact prompt and the task: https://narrativetrace.ai/#agents-saying - "…the release call is present, generated from a real run, not asserted from inside the process being tested." — Claude Sonnet, 2026-09-11 - "The always-on name-based deny-list is a genuinely nice piece of design: naming a parameter `paymentToken` gets you redaction for free, and I could prove it in a test." — Claude Sonnet, 2026-09-11 - "The trace of a failed payment made missing compensation immediately visible, and approval testing caught an extra call that ordinary value assertions accepted." — GPT-6, 2026-09-08 ## Packages - [narrativetrace](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/packages/narrativetrace/README.md): core — capture context, `trace_object`, `@narrated`/`@on_error`/`@not_traced`, renderers (Markdown/Prose/Indented), redaction, fork-join/fire-and-forget concurrency, canonical JSON export, stdlib logging bridge. - [narrativetrace-pytest](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/packages/narrativetrace-pytest/README.md): pytest plugin — `narrative_trace` fixture, per-test artifacts, failure narratives, suite footer with clarity split. - [narrativetrace-diagrams](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/packages/narrativetrace-diagrams/README.md): Mermaid and PlantUML sequence-diagram renderers. - [narrativetrace-otel](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/packages/narrativetrace-otel/README.md): OpenTelemetry bridge — live `OtelTraceEventListener` and batch `TraceSpanExporter` with typed `narrative.*` attributes. - [narrativetrace-asgi](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/packages/narrativetrace-asgi/README.md): ASGI middleware for Starlette/FastAPI — fail-safe request-boundary capture, W3C traceparent adopt/inject, `get_narrative_context()`. - [narrativetrace-clarity](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/packages/narrativetrace-clarity/README.md): naming-clarity engine and CI gate — 1053 verbs, abbreviation/collocation/role dictionaries, five weighted scorers, `narrativetrace-clarity` console script. - [narrativetrace-structlog](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/packages/narrativetrace-structlog/README.md): structlog processor injecting the same correlation keys as the stdlib filter. - [narrativetrace-glossary](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/packages/narrativetrace-glossary/README.md): domain glossary — ubiquitous-language harvesting, trace translation, and the vocabulary norm the clarity gate enforces. ## Guides - [Installation](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/documentation/guides/installation.md) - [Configuration](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/documentation/guides/configuration.md) - [Decorators](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/documentation/guides/decorators.md) - [pytest plugin](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/documentation/guides/pytest.md) - [FastAPI / ASGI](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/documentation/guides/fastapi-asgi.md) - [Logging & structlog](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/documentation/guides/logging.md) - [OpenTelemetry](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/documentation/guides/opentelemetry.md) - [Clarity](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/documentation/guides/clarity.md) - [Agent Skills](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/documentation/agent-skills.md): `add-narrative-tracing` — install and first trace, ending at the doctor — and `narrativetrace-doctor` — a thin, read-only agent skill over `uv run narrativetrace doctor`, installable today via `.claude/skills/{add-narrative-tracing,narrativetrace-doctor}/`, `.agents/skills/{add-narrative-tracing,narrativetrace-doctor}/` for Codex CLI, or the always-on `AGENTS.md` pointer ## Examples - [ecommerce](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/examples/ecommerce): fork-join + fire-and-forget concurrency. - [minecraft](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/examples/minecraft): generic vs domain naming, identical structure. - [hotel_booking](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/examples/hotel_booking): a generic-verb class flagged HIGH by clarity. - [fastapi_service](https://github.com/narrativetrace/narrativetrace-python/blob/v0.1.2/examples/fastapi_service): ASGI request traced end-to-end.