Skip to main content

Replay and visualise the living architecture of a Python application.

Project description

skeleton

CI Coverage Python License

Skeleton: replay and visualise the living architecture of your code.

Skeleton is a developer-understanding tool, not a profiler. It runs a Python script under a lightweight runtime tracer and turns the observed execution into an interactive, replayable architecture map.

Core promise:

Replay and visualise the living architecture of a Python application.

Skeleton produces runtime evidence in four complementary forms:

Surface Purpose
Trace icon trace.jsonl Ordered public call and return events.
Snapshot icon snapshot.json Graph-shaped modules, classes, functions, instances, and edges.
Workflow icon workflow.md LLM-readable workflow evidence with stable event and node references.
Replay icon report.html Interactive visual replay for humans.

Package naming:

Product name:  Skeleton
PyPI package:  skeleton-replay
Import name:   skeleton_replay
CLI command:   skeleton
Module entry:  python -m skeleton_replay

MVP workflow

pip install skeleton-replay
skeleton run path/to/script.py

Skeleton writes:

~/.skeleton/<application-name>/
  trace.jsonl
  snapshot.json
  workflow.md
  report.html

The first version is intentionally non-invasive. You do not add decorators or modify application code. The runner wraps an existing script, traces only project-local public functions and methods by default, and records safe summaries of arguments and return values.

Skeleton is opinionated about what makes large Python systems understandable. It promotes explicit architectural actors, clear dependency direction, and I/O decoupled from business logic. Modules are visual shells, runtime object instances live inside the modules that define their classes, module-level public functions live inside their modules, and instance methods live inside the object that handled the call. Class definitions remain metadata, not runtime graph boxes. Entrypoints, services, repositories, adapters, and ports are roles or boundaries unless the codebase has a concrete object that owns that responsibility. See docs/design/software-design-principles.md for the design principles that guide the visual model.

workflow.md is a compact text explanation of the observed run. It is designed for humans and LLMs: event ids, node ids, caller/callee relationships, safe examples, and known trace gaps are written in a form that can be quoted and reasoned over without scraping the HTML report.

Install and develop

make setup
make check

Use make test for normal or targeted local pytest runs. Use make test-cov or make check when you want the full-suite coverage gate that CI enforces.

Print the local artifact locations:

make where

Run locally from the checkout:

uv run python -m skeleton_replay run examples/app.py

Generate a stable local demo report:

make demo

The demo writes artifacts to tests/dev/.temp/skeleton-demo/ and opens report.html in your default browser. For a headless run that writes the same files without opening a browser, use:

make demo-no-open

Pytest tests use tmp_path, so test-generated reports live in pytest-managed temporary directories under tests/dev/.temp/pytest/. The stable report to open while developing the UI is:

tests/dev/.temp/skeleton-demo/report.html

Regenerate it with:

make demo-no-open

CLI

skeleton run [options] path/to/script.py [args...]

The module entrypoint is also available:

python -m skeleton_replay run [options] path/to/script.py [args...]

Options:

--project-root PATH   Root used to decide which files are project-local.
--out-dir PATH        Output directory. Defaults to ~/.skeleton/<application-name>.
--include PATTERN     Only trace matching relative paths or module names.
--exclude PATTERN     Exclude matching relative paths or module names.
--max-events N        Stop writing trace events after N events.
--no-html             Skip report.html generation and opening.
--no-open             Do not open report.html after generation.

Output location precedence:

  1. --out-dir PATH
  2. SKELETON_OUT_DIR
  3. SKELETON_HOME/<application-name>
  4. ~/.skeleton/<application-name>

When HTML generation is enabled, Skeleton opens report.html in your default browser at the end of the run. Use --no-open for CI, scripts, or headless environments.

Python API

Use TraceSession when you want to generate Skeleton artifacts from Python without shelling out to the CLI:

from pathlib import Path

from skeleton_replay import TraceSession

result = TraceSession(
    project_root=Path("path/to/project"),
    out_dir=Path("path/to/project/.skeleton"),
).run_script("path/to/project/app.py")

print(result.report_path)
print(result.workflow_path)

The Python API writes the same trace.jsonl, snapshot.json, workflow.md, and optional report.html artifacts as the CLI. Unlike the CLI, it does not open the HTML report by default; pass open_report=True when that is wanted. See docs/api/python-api.md.

What gets traced

Skeleton uses sys.setprofile and records Python call and return events when all of these are true:

  • The frame's file is under the project root.
  • The file is not in ignored local infrastructure such as .venv, .git, or .skeleton.
  • The callable name is public. Names beginning with _ are ignored.

The trace identifies the module, class where practical, function or method, caller, callee, instance identity where practical, call depth, event order, timestamp, safe argument summaries, and safe return summaries.

How it works

Skeleton does not patch your source code. It uses Python's own runtime introspection:

  • runpy.run_path() runs the target script as __main__ inside a controlled runner.
  • sys.setprofile() receives callbacks whenever Python enters or returns from a function.
  • Each callback receives a frame object. From that frame Skeleton reads frame.f_code, frame.f_globals, and frame.f_locals to identify the file, module, function name, line number, arguments, and whether the call has self.
  • When self is present, Skeleton records type(self).__name__ and id(self), giving a run-local object identity such as service.Greeter@0x....
  • Values are summarized immediately, then the raw objects are discarded.

That is why the report can show instance-owned methods without decorators. It is not reading class source to guess behavior; it is watching Python call real functions on real objects. The object ids are only meaningful within one run, not across processes or commits.

For more detail, see docs/design/runtime-introspection.md.

Current scope and next integrations

Skeleton currently runs a script path:

python -m skeleton_replay run scripts/replay_checkout.py

That script can drive any kind of Python code: CLI workflows, service objects, batch jobs, web-app internals, or library calls. The application being traced does not need to be a CLI application, but v0 does need a script entrypoint that exercises the behavior.

Planned integrations:

  • run-module: support module execution such as python -m my_app.cli run-demo, exposed as something like skeleton run-module my_app.cli -- run-demo.
  • pytest plugin: trace selected tests or test sessions, because tests often encode real business workflows.
  • live web request tracing: trace one request or handler inside a running FastAPI, Flask, Django, or Starlette app through middleware or a capture context.
  • PyCharm plugin: a thin IDE frontend that invokes Skeleton with the configured interpreter and opens the generated report.

See docs/api/python-api.md, docs/development/missing-integration-plans.md, and docs/development/pypi-release-plan.md.

Release history is tracked in CHANGELOG.md. Keep the changelog updated in the same pull request or commit that changes user-visible behavior.

Event schema

Each line in .skeleton/trace.jsonl is a JSON object:

{
  "schema_version": 1,
  "event_type": "call",
  "order": 0,
  "timestamp": 1782740000.0,
  "depth": 0,
  "caller": null,
  "callee": {
    "module": "app",
    "class_name": null,
    "function": "main",
    "qualified_name": "app.main",
    "file": "/project/app.py",
    "line": 10,
    "node_id": "function:app.main",
    "instance_id": null
  },
  "args": {}
}

Return events use the same endpoint shape and include return_value.

Safety model

Skeleton records summaries, not full object contents.

  • Strings are truncated.
  • Containers include type, length, and a small preview.
  • Objects include only class name and object id.
  • Argument or mapping names containing password, token, secret, key, auth, or credential are redacted.

This is not a debugger replacement and not a performance profiler. It is a runtime architecture replay tool for understanding how a codebase behaves.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

skeleton_replay-0.1.3.tar.gz (34.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

skeleton_replay-0.1.3-py3-none-any.whl (42.2 kB view details)

Uploaded Python 3

File details

Details for the file skeleton_replay-0.1.3.tar.gz.

File metadata

  • Download URL: skeleton_replay-0.1.3.tar.gz
  • Upload date:
  • Size: 34.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for skeleton_replay-0.1.3.tar.gz
Algorithm Hash digest
SHA256 e5148a8906e33b876f2f22e6068272085adc704f5f44a687dc1ce154647f65b5
MD5 3439f0659bc6e3694b62d69b23e13aa9
BLAKE2b-256 a02b98ba620e2f3c650f3aea173d3f9df3322aee137371f770b364288a57d223

See more details on using hashes here.

Provenance

The following attestation bundles were made for skeleton_replay-0.1.3.tar.gz:

Publisher: publish.yml on ml-affairs/skeleton

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file skeleton_replay-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: skeleton_replay-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 42.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for skeleton_replay-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 0e94624c5f9f2cd1499d24f66931215e3d034c52071a1b2f8187ca9c4f8e1955
MD5 5d05b74eaaaa7b0152f545d87969da05
BLAKE2b-256 c16b87f943dc997d5be3d3cc1131d77d1d3e762df386ae5504cf61ce259ab741

See more details on using hashes here.

Provenance

The following attestation bundles were made for skeleton_replay-0.1.3-py3-none-any.whl:

Publisher: publish.yml on ml-affairs/skeleton

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page