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.

When project-local code is already on the trace stack, Skeleton also records a small allow-list of standard-library boundary calls. Today that includes stdout, filesystem operations, SQLite operations, and basic network socket calls. Filesystems, stdout, and databases appear as resource cylinders. Network calls appear as external-service diamonds, because an external service is an architectural collaborator rather than an I/O resource.

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, plus selected C-level resource calls such as print or sqlite3.connect.
  • 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,
    "endpoint_type": "function",
    "resource_category": null
  },
  "args": {}
}

Return events use the same endpoint shape and include return_value. Resource endpoints use the same shape with endpoint_type: "resource", a resource_category such as stdout, file, or db, and a node_id beginning with resource:. Resource nodes are aggregated by boundary kind, for example resource.database or resource.stdout; the specific operation, such as connect or print, is kept in the safe event evidence. Network endpoints use endpoint_type: "external_service" and render as diamond-shaped external service entities.

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.3.0.tar.gz (59.6 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.3.0-py3-none-any.whl (68.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: skeleton_replay-0.3.0.tar.gz
  • Upload date:
  • Size: 59.6 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.3.0.tar.gz
Algorithm Hash digest
SHA256 890876ed48ffae361efb5ac0ef9db32cc7f45b176875e03db637fc4f61d0bbdf
MD5 eec0f9f771d8b39e56bc2c5facd5c270
BLAKE2b-256 c0d491dacf2005b444dc46aeb9dcf47258daab5b0015c665762063e3f2afe148

See more details on using hashes here.

Provenance

The following attestation bundles were made for skeleton_replay-0.3.0.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.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for skeleton_replay-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5e7f2337404fb12f821fb92c3f5a75c35936331f1950f2018294e4e0fa07ee0b
MD5 5caf147707e4857eeddf04ec6c09b3cf
BLAKE2b-256 36d1944edd5dfb67984ed15eb25b8464e5e326c64fa2f92bee923955749407f8

See more details on using hashes here.

Provenance

The following attestation bundles were made for skeleton_replay-0.3.0-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