Metadata-Version: 2.5
Name: pyinsider
Version: 1.0.0
Summary: See what your Python program actually did — execution tracing, timeline and call-tree exploration.
Project-URL: Homepage, https://github.com/yashsutar/insider
Project-URL: Repository, https://github.com/yashsutar/insider
Project-URL: Issues, https://github.com/yashsutar/insider/issues
Project-URL: Changelog, https://github.com/yashsutar/insider/blob/main/CHANGELOG.md
Author: PyInsider contributors
License: MIT License
        
        Copyright (c) 2026 PyInsider contributors
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: call-graph,debugging,developer-tools,flame-graph,observability,performance,profiler,tracing
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Debuggers
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: System :: Monitoring
Classifier: Typing :: Typed
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: pytest-cov>=4.1; extra == 'dev'
Requires-Dist: pytest>=7.4; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# PyInsider

**See what your Python program actually did.**

PyInsider records the real execution of a Python program — every function call,
how long each took, how calls nested, what arguments went in, what came back,
and the exact path that led to an exception — and lets you explore it afterward
in an interactive local viewer.

It is not a profiler that gives you aggregate numbers, and it is not a debugger
that stops the world. It is an **execution recorder**: run once, then look at
what happened.

```console
$ pyinsider run examples/nested_calls.py
  recorded 22 calls · max depth 5 · 3.14 ms
  trace written to traces/run-2026-08-29-001.tl

$ pyinsider open traces/run-2026-08-29-001.tl
  serving viewer at http://127.0.0.1:8721  (Ctrl-C to stop)
```

- **Deterministic, not sampled.** Every call is recorded via CPython's
  `sys.setprofile` hook — no statistical guessing.
- **No AI, no telemetry, no cloud.** Everything runs and stays on your machine.
  The viewer binds only to `127.0.0.1`. Nothing is uploaded, ever.
- **Local-first trace files.** A run produces a single versioned `.tl` file you
  can save, diff, and share.
- **Four clean layers.** The tracing and analysis engines have no dependency on
  the UI, so you can use PyInsider entirely from Python if you prefer.

---

## Installation

Requires **Python 3.10+**. PyInsider has **no runtime dependencies**.

```console
pip install pyinsider
```

Or from a clone, for development:

```console
git clone https://github.com/Yashjindal11/pyinsider.git
cd pyinsider
pip install -e ".[dev]"
```

## Quickstart

Record a script and open the result:

```console
pyinsider run examples/simple.py
pyinsider open traces/          # opens the most recent trace in your browser
```

Capture arguments and return values too:

```console
pyinsider run examples/complex_values.py --detail
```

Forward arguments to your program (everything after `--` goes to the script):

```console
pyinsider run app.py -- --verbose input.csv
```

Prefer to stay in the terminal? Skip the browser:

```console
pyinsider open traces/run-2026-08-29-001.tl --summary   # top-level summary
pyinsider open traces/run-2026-08-29-001.tl --tree      # printed call tree
```

## Using it from Python

The recorder is a plain context manager. The UI is optional.

```python
import pyinsider

with pyinsider.trace() as run:
    result = do_some_work()

trace = run.result
run.save("work.tl")

# Analyse without any UI:
for stat in pyinsider.hot_paths(trace):
    print(stat.key, stat.inclusive_ms)
```

`pyinsider.checkpoint("loaded config")` drops a labelled marker into the active
trace so you can find a moment on the timeline later.

## The CLI

```
pyinsider run     <script.py | -m module> [--detail] [-o FILE] [-- args...]
pyinsider open    <file.tl | dir> [--summary | --tree | --no-browser]
pyinsider compare <before.tl> <after.tl>
pyinsider --version
```

- `run` preserves your program's exit code and forwards its arguments, so it is
  safe to drop in front of an existing command.
- `open` accepts either a file or a directory (it picks the newest `.tl`).
- `compare` diffs two runs and highlights functions that got slower, faster,
  appeared, or disappeared.

Colour output honours `NO_COLOR`, `TERM=dumb`, and non-TTY pipes.

## Trace files (`.tl`)

A `.tl` file is gzip-compressed JSON with an explicit schema version. It
contains the full call tree, timings (nanoseconds relative to run start),
captured values, exception information, and run metadata (Python version,
platform, detail level). There is **no pickle** and no code in a trace file —
it is safe to open and inspect by hand.

Trace files are forward-compatible within a major schema version and are
rejected if the major version is newer than the reader understands.

## The viewer

`pyinsider open` starts a tiny local web app (stdlib only, `127.0.0.1`) that
shows:

- an interactive, zoomable **timeline** of the run,
- a virtualised **call tree** with inclusive/self timings,
- a **source view** pointing at where each call was defined,
- a **details** panel with arguments and return values,
- an **exceptions** view with the call path that led to each failure,
- **hot paths** and an aggregated **flame graph**,
- filtering by module, name, duration, and project-vs-library code.

## Architecture

PyInsider is built in four layers, each depending only on the ones below it:

```
  cli / api / viewer        <- presentation (never imported by the engine)
        |
  trace model + analysis    <- Trace, function_stats, hot_paths, compare
        |
  trace events              <- typed, serialisable ExecutionEvent records
        |
  tracer / collector        <- sys.setprofile instrumentation
```

The tracer and analysis code never import the CLI or viewer, so the engine is
usable as a library and the UI can be replaced without touching the core.

## Limitations

PyInsider is deliberately honest about what it can and cannot see. Highlights:

- **Caught exceptions** are attributed by walking the exception's traceback, so
  only exceptions that propagate are marked; an exception swallowed by a
  `try/except` is not attributed to the function that raised it.
- **C-level functions** (built-ins, C extensions) are not recorded as calls.
- Timings include tracing overhead; treat them as *relative*, not absolute.
- Async and multi-threaded code is recorded per-thread/per-task but concurrency
  interleaving is simplified.
- Subprocesses are invisible to the tracer.

See [`docs/limitations.md`](docs/limitations.md) for the full, detailed list —
it is required reading before you trust a number.

## Development

```console
pip install -e ".[dev]"
pytest                 # run the test suite
ruff check pyinsider   # lint
mypy pyinsider         # type-check
```

See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the workflow and project layout.

## License

[MIT](LICENSE). PyInsider is free and open source.
