# scope_profiler.json_export

*module*

Export and re-read profiling runs as JSON.

The HDF5 file remains the default output: it is compact, appendable rank by
rank, and the only format the parallel writer can produce. This module adds a
second, dependency-free representation of exactly the same run, for the cases
where HDF5 is the wrong shape - a browser, ``jq``, a notebook on a machine
without h5py, or a diff in code review.

The document is *lossless*: :func:`read_json` rebuilds a
:class:`~scope_profiler.results.ProfilingResults` that is indistinguishable
from the one :func:`~scope_profiler.h5reader.read_h5` gives back for the same
run, per-call timestamps, lane tables, LIKWID counters and line-profiler
records included. Timestamps stay in the integer nanoseconds the run recorded
rather than being converted to seconds, so a round trip is exact.

Files ending in ``.gz`` are written (and read) gzip-compressed, which is what
a real run wants: the event columns are the bulk of the document and they
compress by roughly an order of magnitude.

[View source](https://github.com/max-models/scope-profiler/blob/devel/src/scope_profiler/json_export.py#L1-L1)

## scope_profiler.json_export.FORMAT_NAME

*attribute* · *module attribute*

```python
FORMAT_NAME = 'scope-profiler-profile'
```

[View source](https://github.com/max-models/scope-profiler/blob/devel/src/scope_profiler/json_export.py#L38-L38)

## scope_profiler.json_export.FORMAT_VERSION

*attribute* · *module attribute*

```python
FORMAT_VERSION = 1
```

[View source](https://github.com/max-models/scope-profiler/blob/devel/src/scope_profiler/json_export.py#L41-L41)

## scope_profiler.json_export.JSON_SUFFIXES

*attribute* · *module attribute*

```python
JSON_SUFFIXES = ('.json', '.json.gz')
```

[View source](https://github.com/max-models/scope-profiler/blob/devel/src/scope_profiler/json_export.py#L44-L44)

## scope_profiler.json_export.JSONProfileError

*class*

```python
class JSONProfileError(ValueError)
```

Bases: `ValueError`

Raised when a file is not a scope-profiler JSON profile.

[View source](https://github.com/max-models/scope-profiler/blob/devel/src/scope_profiler/json_export.py#L447-L448)

## scope_profiler.json_export.build_json_document

*function*

```python
def build_json_document(results: ProfilingResults, include=None, exclude=None, ranks: list[int] | int | None = None) -> dict
```

Build the JSON document describing one run.

Parameters
----------
results : ProfilingResults
    The run to serialize, from a file or straight out of
    ``ProfileManager.finalize(return_results=True)``.
include, exclude : list[str] | str, optional
    Region name filters, as for the plotting functions.
ranks : list[int] | int, optional
    Ranks to keep (default: every rank the run recorded).

Returns
-------
dict
    A JSON-serializable document; see :func:`write_json`.

[View source](https://github.com/max-models/scope-profiler/blob/devel/src/scope_profiler/json_export.py#L278-L337)

## scope_profiler.json_export.export_json

*function*

```python
def export_json(profiling_data: ProfilingResults | Sequence[ProfilingResults], filepath: str | Path, ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, verbose: bool = True, indent: int | None = None) -> list[Path]
```

Write one JSON document per run, exactly as ``export_speedscope`` does.

Parameters
----------
profiling_data : ProfilingResults | Sequence[ProfilingResults]
    The run(s) to export: file runs, in-memory results, or a mix.
filepath : str | Path
    Base output path, e.g. ``figures/profile.json``. Ending it in ``.gz``
    compresses the output. The run's label is appended to the stem when
    more than one run is exported.
ranks : list[int] | int, optional
    Ranks to export (default: every rank).
include, exclude : list[str] | str, optional
    Region name filters, as for the plotting functions.
indent : int, optional
    Passed to ``json.dumps``; the default writes the document on one line.

Returns
-------
list[Path]
    The files written, in the order they were written.

[View source](https://github.com/max-models/scope-profiler/blob/devel/src/scope_profiler/json_export.py#L376-L444)

## scope_profiler.json_export.is_json_path

*function*

```python
def is_json_path(path) -> bool
```

Whether ``path`` names a JSON profile rather than an HDF5 one.

[View source](https://github.com/max-models/scope-profiler/blob/devel/src/scope_profiler/json_export.py#L47-L50)

## scope_profiler.json_export.load_json

*function*

```python
def load_json(file_path: str | Path, verbose: bool = False) -> dict
```

Parse a JSON profile into :class:`ProfilingResults` arguments.

The JSON twin of :func:`~scope_profiler.h5reader.load_h5`, and the parsing
half of :func:`read_json`.

[View source](https://github.com/max-models/scope-profiler/blob/devel/src/scope_profiler/json_export.py#L593-L633)

## scope_profiler.json_export.read_json

*function*

```python
def read_json(file_path: str | Path, verbose: bool = False) -> ProfilingResults
```

Read a JSON profile back into :class:`ProfilingResults`.

The JSON twin of :func:`~scope_profiler.h5reader.read_h5`::

    results = read_json("profiling_data.json")
    results.print_summary()

[View source](https://github.com/max-models/scope-profiler/blob/devel/src/scope_profiler/json_export.py#L636-L644)

## scope_profiler.json_export.write_json

*function*

```python
def write_json(results: ProfilingResults, filepath: str | Path, *, include=None, exclude=None, ranks: list[int] | int | None = None, indent: int | None = None) -> Path
```

Write one run to ``filepath`` as JSON, and return the path written.

[View source](https://github.com/max-models/scope-profiler/blob/devel/src/scope_profiler/json_export.py#L359-L373)

## scope_profiler.json_export.write_json_file

*function*

```python
def write_json_file(filepath: str | Path, document: dict, indent=None) -> Path
```

Write ``document`` to ``filepath``, gzip-compressed for a ``.gz`` name.

[View source](https://github.com/max-models/scope-profiler/blob/devel/src/scope_profiler/json_export.py#L340-L356)
