Metadata-Version: 2.4
Name: cave_utils
Version: 3.5.6
Summary: Python wrapper for api use in the cave_app
Author-email: Connor Makowski <conmak@mit.edu>
Project-URL: Homepage, https://github.com/mit-cave/cave_utils
Project-URL: Bug Tracker, https://github.com/mit-cave/cave_utils/issues
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE.md
Requires-Dist: pamda<3.0.0,>=2.8.0
Requires-Dist: type_enforced<3.0.0,>=2.2.0
Provides-Extra: dev
Requires-Dist: pytest>=9.0.3; extra == "dev"
Requires-Dist: autoflake>=2.3.1; extra == "dev"
Requires-Dist: black>=25.1.0; extra == "dev"
Requires-Dist: build>=1.2.2; extra == "dev"
Requires-Dist: nox>=2026.4.10; extra == "dev"
Requires-Dist: nox-uv>=0.8.0; extra == "dev"
Requires-Dist: pdoc>=15.0.1; extra == "dev"
Requires-Dist: twine>=6.1.0; extra == "dev"
Requires-Dist: scgraph<4.0.0,>=3.1.0; extra == "dev"
Dynamic: license-file

# Cave Utilities

[![PyPI version](https://badge.fury.io/py/cave_utils.svg)](https://badge.fury.io/py/cave_utils)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Python utilities for the [CAVE App](https://github.com/MIT-CAVE/cave_app) framework: API validation, data builders, and shared helpers.

## Overview

`cave_utils` is a foundational library for building CAVE applications. It provides:

- **API validation**: validate `session_data` dicts against the full CAVE API spec, with structured error and warning reporting
- **Data builders**: helper classes for constructing hierarchical and date-based group structures
- **Shared utilities**: logging, geographic calculations, coordinate systems, and argument parsing

It is designed to be embedded in a CAVE API server, but can also be used standalone for testing and data development.

## Features

- Validates all 10 top-level CAVE API keys (`settings`, `appBar`, `pages`, `panes`, `maps`, `mapFeatures`, `globalOutputs`, `groupedOutputs`, `draggables`, `extraKwargs`)
- Cross-field validation with structured error paths (e.g. `maps.data.myMap.currentProjection`)
- Time-series (`timeValues`) and ordering (`order`) validation built in
- `GroupsBuilder` and `DateGroupsBuilder` for constructing hierarchical group structures from flat data
- `GeoUtils` for shortest-path calculations over geographic networks
- `CustomCoordinateSystem` for converting Cartesian 2D/3D coordinates to lat/long
- Runtime type enforcement via [`type_enforced`](https://github.com/connor-makowski/type_enforced)

## Requirements

- Python ≥ 3.11

## Installation

```sh
pip install cave_utils
```

## Quick Start

### Validating Session Data

```python
from cave_utils import Validator

session_data = {
    "settings": {
        "iconUrl": "https://example.com/icon.png",
    },
    "appBar": {
        "data": {
            "btn_home": {
                "icon": "md/MdHome",
                "type": "button",
            }
        }
    },
}

result = Validator(session_data=session_data)

# Inspect errors and warnings
for entry in result.log.log:
    print(entry)
# Empty list means fully valid
```

### Using GroupsBuilder

```python
from cave_utils.builders.groups import GroupsBuilder

builder = GroupsBuilder(
    data=[
        {"id": "region_east", "name": "East", "parent": None},
        {"id": "state_ny", "name": "New York", "parent": "region_east"},
        {"id": "state_ma", "name": "Massachusetts", "parent": "region_east"},
    ],
    id_field="id",
    name_field="name",
    parent_field="parent",
)

# Serialize to the CAVE API groupedOutputs format
groups_data = builder.serialize()
```

## Public API

| Class | Import | Description |
|---|---|---|
| `Validator` | `from cave_utils import Validator` | Validates a `session_data` dict against the full CAVE API spec |
| `LogObject` | `from cave_utils import LogObject` | Structured log container for errors and warnings |
| `Socket` | `from cave_utils import Socket` | No-op WebSocket stub for use in tests |
| `Arguments` | `from cave_utils import Arguments` | Parses kwargs, flags, and positional args from raw argument lists |
| `GeoUtils` | `from cave_utils import GeoUtils` | Geographic utilities including shortest-path via `scgraph` |
| `CustomCoordinateSystem` | `from cave_utils import CustomCoordinateSystem` | Converts 2D/3D Cartesian coordinates to lat/long |

Full API reference: [mit-cave.github.io/cave_utils](https://mit-cave.github.io/cave_utils/index.html)

## LLM Docs

`cave_utils` can generate plain text documentation for all its modules, suitable for use with AI assistants (Claude, Gemini, etc.).

**From Python:**
```python
from cave_utils import generate_docs
generate_docs("path/to/output_dir")
```

**From the command line:**
```sh
cave-utils-docs path/to/output_dir
```

If no directory is specified, docs are written to `./cave_utils_docs/`.

The output directory will contain one `.txt` file per module plus a `README.txt` index and a `PROJECT_README.md` with this project overview. You can point your AI assistant at this directory or reference individual files in a system prompt.

## Development

Dev dependencies are declared in `[project.optional-dependencies] dev` in `pyproject.toml`. Install them with `uv sync --extra dev`.

| Command | Description |
|---|---|
| `uv run pytest` | Run all tests |
| `uv run pytest -v` | Run tests with verbose output |
| `uv run nox` | Run tests across Python 3.11, 3.12, 3.13, 3.14 |
| `uv run nox -s tests-3.14` | Run tests on a single Python version |
| `uv run python utils/prettify.py` | Format code with autoflake + black |
| `uv run python utils/docs.py` | Regenerate pdoc documentation |

### Running Tests

Tests live in `test/`. The main test file (`test_validator.py`) imports every example in `test/api_examples/`, runs it through `Validator`, and asserts no errors or warnings are produced. Unit tests exist for each module.

```sh
uv run pytest
```

### Hot-Reload with a Cave App

To develop `cave_utils` against a running Cave App, mount the local source as a Docker volume:

```sh
cave run --docker-args "--volume {local_path_to_cave_utils}/cave_utils:/cave_utils"
```

Then in the Cave App's `utils/run_server.sh`, add `pip install -e /cave_utils` before the server starts. Changes to `cave_utils` source will be reflected on the next API call without rebuilding the container.

Set `LIVE_API_VALIDATION_PRINT=True` in the Cave App's `.env` to see validation output on every API command.

## Release Process

1. Ensure all tests pass and code is formatted:
    ```sh
    uv run nox
    uv run python utils/prettify.py
    ```
2. Update `version` in both `pyproject.toml` and `setup.cfg`
3. Run tests across all supported Python versions: `uv run nox`
4. Update `VERSION` in `utils/docs.py` and regenerate docs:
    ```sh
    uv run python utils/docs.py
    ```
