# tuna Python Profile Viewer: Setup and Profile Inspection

> tuna is a Python profile viewer for runtime and import profiles, with notebook support and an icicle-style web interface. Its main distinction is a refusal to invent call-tree details that Python profilers do not retain.

**nschloe/tuna** — :fish: Python profile viewer

- Repository: https://github.com/nschloe/tuna
- Stars: 1,603 · Forks: 35
- Language: Python
- License: GPL-3.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/nschloe-tuna

## tuna's target is incomplete Python profile data

tuna addresses a specific problem: Python profile files contain useful timing and caller information, but they do not preserve every edge of the complete timed call tree. The project is for developers and performance-minded Python users who want to inspect profile data interactively rather than read raw records. It accepts runtime profiles produced by `cProfile` and import profiles produced through Python's `importtime` option. The package metadata describes it as a visualization utility for Python 3.10 and newer, with a console entry point and a browser-oriented web interface.

The choice to show less may appear restrictive, but it is the central engineering position of the project. The README explains that Python records parent data because it can do so with little overhead. A complete call tree would require contextual facts that are absent from the profile. Consequently, tuna presents the portion that can be derived from the stored records instead of presenting a visually complete but misleading hierarchy.

This scope makes tuna most useful when a developer wants to identify expensive functions, inspect relationships that the profile actually contains, or investigate slow imports. It does not promise source-level diagnostics, automatic bottleneck recommendations, or a complete history of every invocation. Those expectations would exceed both the documented feature set and the information present in the source profile.

## How tuna turns cProfile and importtime files into a profile

The documented flow separates profile creation from viewing. A Python program is first profiled by the interpreter or `cProfile`, producing either a `.prof` file or an import-time log. The `tuna` command receives the runtime profile and invokes the viewer. Repository metadata maps that command to `tuna.cli:main`, while the package configuration includes HTML, JavaScript, CSS, and a favicon under `tuna/web`. This indicates a Python CLI paired with packaged browser assets rather than a terminal-only report.

The interface uses d3 and Bootstrap. `package.json` pins d3 `7.9.0` and Bootstrap `5.3.8`, while the `justfile` copies their distribution files into `src/tuna/web/static/` for packaging. The static JavaScript includes `icicle.js`, which describes the visualization's partition-oriented presentation. The README's comparison image labels the tuna output as an icicle view.

For import profiles, the input is text emitted on standard error by `python -X importtime`. For runtime profiles, the input is the structured file created with `python -mcProfile`. Both paths therefore begin outside tuna. That separation gives the developer control over when profiling occurs and keeps tuna focused on reading existing results. It also means a malformed, unsupported, or incomplete input file will still limit what the viewer can show.

## Installing tuna and viewing a first runtime profile

The README directs users to the Python Package Index and gives `pip install tuna` as the installation command. No operating-system-specific installer or additional Python package is documented. The package requires Python 3.10 or newer according to `pyproject.toml`.

Install the viewer with:

```bash
pip install tuna
```

For an existing runtime profile, open the viewer with the same command form documented in the README:

```bash
tuna program.prof
```

The `.prof` file must first be created from a Python script. The documented profiling command is:

```bash
python -mcProfile -o program.prof yourfile.py
```

Replace `yourfile.py` with the script to profile and `program.prof` with the output name if needed. This command writes the profile rather than displaying it. Running `tuna program.prof` is the separate viewing step. The README includes a screencast for the browser presentation, but it does not document command-line flags for selecting a port, changing the output destination, or exporting an image.

The expected result is tuna's profile visualization based only on the recorded data. It is important not to expect every invocation and nested timing shown in the source program to appear independently in the displayed hierarchy.

## tuna import logs and IPython magic workflows

For startup or import cost, Python can write import timing information to a log. The README specifies redirection of standard error because `importtime` reports through that stream:

```bash
python -X importtime yourfile.py 2> import.log
```

That command creates `import.log`; it does not invoke tuna directly. The README does not give a separate `tuna import.log` command for this file, so the precise import-log rendering workflow is not documented. What is clear is that tuna handles runtime and import profiles, and that import timing originates with Python's `-X importtime` mechanism.

For notebooks, tuna supplies line and cell magics described as replacements for `prun`. Load the extension first:

```python
%load_ext tuna
```

A single statement can then be profiled in an IPython cell:

```python
%tuna sleep(3)
```

A multiline cell follows the documented notebook syntax:

```python
%%tuna
sleep(3)
```

The underlying profiling remains delegated to `prun`. According to the README, tuna collects or presents the result and displays it in the notebook. This makes notebook use a thin integration layer rather than a separate execution engine.

## Why tuna shows an incomplete call tree by design

The clearest limitation is also tuna's defining design choice. Python profiles do not contain the entire timed call tree. They retain a function's total time and enough parent information to deduce part of its context, but they do not distinguish how that time was distributed among every possible invocation path.

The README demonstrates this with two calls to the same function through different parent paths. Although the runtime behavior differs between the paths, the profile contains only the combined total for the child functions. Reconstructing the missing split would require information that was never recorded. tuna therefore shows only what can be retrieved. SnakeViz takes the opposite approach by attempting to construct the whole call tree, and the README states that this can produce wrong timings.

This distinction matters when choosing an analysis tool. A graph that looks more complete is not necessarily more faithful. Users investigating recurring calls, dynamic dispatch, recursion, or context-sensitive timing should inspect the Python profiler format first. If the needed distinction cannot be derived from the profile, changing visualization software cannot recover it. Collecting different profile data, changing the code under study, or using instrumentation that records additional events may answer a different question, but those are outside what the README promises for tuna.

## tuna maintenance, packaging, and GPL obligations

The repository is not archived, and its last push was on 2026-06-16. Recent releases include `v0.5.15` on 2026-05-19, `v0.5.14` on 2026-05-19, and `v0.5.13` on 2026-04-12. These dates indicate recent project activity, although release frequency alone does not establish compatibility with every Python release or deployment.

The package is built with setuptools and wheel. `pyproject.toml` declares `requires-python = ">=3.10"`, classifies Python 3.10 through 3.14, and records version `0.5.15`. Package data explicitly includes the web templates, JavaScript, CSS, and favicon. Contributors cloning the repository need additional frontend dependencies that are not stored in it. The documented setup command is:

```bash
just dep
```

That command runs `npm install` and copies Bootstrap and d3 distribution files into the package's static directory. It is a development setup step rather than part of the PyPI installation instructions.

The project metadata and README identify the license as GPL-3.0-or-later. Any distribution or integration must account for that license's stated conditions. This review does not interpret legal obligations, but the license identifier is concrete and should be checked against the intended use before adoption.

## Conclusion

Developers who want an honest visualization of Python runtime or import profiles should consider tuna, especially in IPython workflows. It is unsuitable for reconstructing a complete call tree or examining non-Python execution. The first checks are whether Python 3.10 or newer fits the environment, whether the GPL-3.0-or-later terms suit the intended distribution, and whether the omitted call-path detail affects the analysis.

## FAQ

### How do I install tuna for Python?

The README says to install it from the Python Package Index with `pip install tuna`. The package metadata requires Python 3.10 or newer.

### How do I view a Python runtime profile with tuna?

Create a profile using `python -mcProfile -o program.prof yourfile.py`, then open it with `tuna program.prof`. Profile creation and profile viewing are separate operations.

### Does tuna show the complete Python call tree?

No. The README states that the complete timed call tree cannot be recovered from Python profile data, so tuna displays only the part that can be deduced from the stored records.

### Can I use tuna in an IPython notebook?

Yes. Load it with `%load_ext tuna`, then use `%tuna sleep(3)` for a line or the documented `%%tuna` cell syntax. The README says `prun` performs the underlying profiling.

## Sources

- [Issues](https://github.com/nschloe/tuna/issues)
- [License: GPL-3.0](https://github.com/nschloe/tuna/blob/main/LICENSE)
- [nschloe/tuna on GitHub](https://github.com/nschloe/tuna)
- [README](https://github.com/nschloe/tuna/blob/main/README.md)
- [Releases](https://github.com/nschloe/tuna/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/nschloe-tuna
