cave_utils

Cave Utilities

PyPI version License: MIT

Python utilities for the 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

Requirements

  • Python ≥ 3.11

Installation

pip install cave_utils

Quick Start

Validating Session Data

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

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

LLM Docs

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

From Python:

from cave_utils import generate_docs
generate_docs("path/to/output_dir")

From the command line:

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

All development tasks run inside Docker. Make sure Docker is installed and running.

Command Description
./run.sh Drop into an interactive Docker shell
./run.sh test Run all tests
./run.sh prettify Format code with autoflake + black
./run.sh docs Regenerate pdoc documentation

./run.sh requires a TTY. Run it directly in your terminal, not from a non-interactive CI environment.

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.

./run.sh test

Hot-Reload with a Cave App

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

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 (./run.sh test) and code is formatted (./run.sh prettify)
  2. Update version in both pyproject.toml and setup.cfg
  3. Update the version in utils/docs.sh and regenerate docs (./run.sh docs)
  4. Build and publish:

    python3 -m virtualenv venv
    source venv/bin/activate
    pip install -r requirements.txt
    
  1"""
  2# Cave Utilities
  3
  4[![PyPI version](https://badge.fury.io/py/cave_utils.svg)](https://badge.fury.io/py/cave_utils)
  5[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
  6
  7Python utilities for the [CAVE App](https://github.com/MIT-CAVE/cave_app) framework: API validation, data builders, and shared helpers.
  8
  9## Overview
 10
 11`cave_utils` is a foundational library for building CAVE applications. It provides:
 12
 13- **API validation**: validate `session_data` dicts against the full CAVE API spec, with structured error and warning reporting
 14- **Data builders**: helper classes for constructing hierarchical and date-based group structures
 15- **Shared utilities**: logging, geographic calculations, coordinate systems, and argument parsing
 16
 17It is designed to be embedded in a CAVE API server, but can also be used standalone for testing and data development.
 18
 19## Features
 20
 21- Validates all 10 top-level CAVE API keys (`settings`, `appBar`, `pages`, `panes`, `maps`, `mapFeatures`, `globalOutputs`, `groupedOutputs`, `draggables`, `extraKwargs`)
 22- Cross-field validation with structured error paths (e.g. `maps.data.myMap.currentProjection`)
 23- Time-series (`timeValues`) and ordering (`order`) validation built in
 24- `GroupsBuilder` and `DateGroupsBuilder` for constructing hierarchical group structures from flat data
 25- `GeoUtils` for shortest-path calculations over geographic networks
 26- `CustomCoordinateSystem` for converting Cartesian 2D/3D coordinates to lat/long
 27- Runtime type enforcement via [`type_enforced`](https://github.com/connor-makowski/type_enforced)
 28
 29## Requirements
 30
 31- Python ≥ 3.11
 32
 33## Installation
 34
 35```sh
 36pip install cave_utils
 37```
 38
 39## Quick Start
 40
 41### Validating Session Data
 42
 43```python
 44from cave_utils import Validator
 45
 46session_data = {
 47    "settings": {
 48        "iconUrl": "https://example.com/icon.png",
 49    },
 50    "appBar": {
 51        "data": {
 52            "btn_home": {
 53                "icon": "md/MdHome",
 54                "type": "button",
 55            }
 56        }
 57    },
 58}
 59
 60result = Validator(session_data=session_data)
 61
 62# Inspect errors and warnings
 63for entry in result.log.log:
 64    print(entry)
 65# Empty list means fully valid
 66```
 67
 68### Using GroupsBuilder
 69
 70```python
 71from cave_utils.builders.groups import GroupsBuilder
 72
 73builder = GroupsBuilder(
 74    data=[
 75        {"id": "region_east", "name": "East", "parent": None},
 76        {"id": "state_ny", "name": "New York", "parent": "region_east"},
 77        {"id": "state_ma", "name": "Massachusetts", "parent": "region_east"},
 78    ],
 79    id_field="id",
 80    name_field="name",
 81    parent_field="parent",
 82)
 83
 84# Serialize to the CAVE API groupedOutputs format
 85groups_data = builder.serialize()
 86```
 87
 88## Public API
 89
 90| Class | Import | Description |
 91|---|---|---|
 92| `Validator` | `from cave_utils import Validator` | Validates a `session_data` dict against the full CAVE API spec |
 93| `LogObject` | `from cave_utils import LogObject` | Structured log container for errors and warnings |
 94| `Socket` | `from cave_utils import Socket` | No-op WebSocket stub for use in tests |
 95| `Arguments` | `from cave_utils import Arguments` | Parses kwargs, flags, and positional args from raw argument lists |
 96| `GeoUtils` | `from cave_utils import GeoUtils` | Geographic utilities including shortest-path via `scgraph` |
 97| `CustomCoordinateSystem` | `from cave_utils import CustomCoordinateSystem` | Converts 2D/3D Cartesian coordinates to lat/long |
 98
 99Full API reference: [mit-cave.github.io/cave_utils](https://mit-cave.github.io/cave_utils/index.html)
100
101## LLM Docs
102
103`cave_utils` can generate plain text documentation for all its modules, suitable for use with AI assistants (Claude, Gemini, etc.).
104
105**From Python:**
106```python
107from cave_utils import generate_docs
108generate_docs("path/to/output_dir")
109```
110
111**From the command line:**
112```sh
113cave-utils-docs path/to/output_dir
114```
115
116If no directory is specified, docs are written to `./cave_utils_docs/`.
117
118The 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.
119
120## Development
121
122All development tasks run inside Docker. Make sure Docker is installed and running.
123
124| Command | Description |
125|---|---|
126| `./run.sh` | Drop into an interactive Docker shell |
127| `./run.sh test` | Run all tests |
128| `./run.sh prettify` | Format code with autoflake + black |
129| `./run.sh docs` | Regenerate pdoc documentation |
130
131> `./run.sh` requires a TTY. Run it directly in your terminal, not from a non-interactive CI environment.
132
133### Running Tests
134
135Tests 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.
136
137```sh
138./run.sh test
139```
140
141### Hot-Reload with a Cave App
142
143To develop `cave_utils` against a running Cave App, mount the local source as a Docker volume:
144
145```sh
146cave run --docker-args "--volume {local_path_to_cave_utils}/cave_utils:/cave_utils"
147```
148
149Then 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.
150
151Set `LIVE_API_VALIDATION_PRINT=True` in the Cave App's `.env` to see validation output on every API command.
152
153## Release Process
154
1551. Ensure all tests pass (`./run.sh test`) and code is formatted (`./run.sh prettify`)
1562. Update `version` in both `pyproject.toml` and `setup.cfg`
1573. Update the version in `utils/docs.sh` and regenerate docs (`./run.sh docs`)
1584. Build and publish:
159    ```sh
160    python3 -m virtualenv venv
161    source venv/bin/activate
162    pip install -r requirements.txt
163    ```
164"""
165from .log import LogObject, LogHelper
166from .socket import Socket
167from .api_utils.validator import Validator
168from .arguments import Arguments
169from .geo_utils import GeoUtils
170from .custom_coordinates import CustomCoordinateSystem