|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +`h5json` is a Python package for bidirectional conversion between HDF5 files and a JSON representation. It provides CLI tools (`h5tojson`, `jsontoh5`, `h5jvalidate`), a library API, and JSON Schema definitions for the h5json format. |
| 8 | + |
| 9 | +## Commands |
| 10 | + |
| 11 | +**Install for development:** |
| 12 | +```bash |
| 13 | +pip install -e . |
| 14 | +``` |
| 15 | + |
| 16 | +**Run all tests:** |
| 17 | +```bash |
| 18 | +python testall.py |
| 19 | +``` |
| 20 | + |
| 21 | +**Run a single unit test:** |
| 22 | +```bash |
| 23 | +python test/unit/<test_name>.py |
| 24 | +# e.g. python test/unit/hdf5db_test.py |
| 25 | +``` |
| 26 | + |
| 27 | +**Run integration tests (from repo root):** |
| 28 | +```bash |
| 29 | +cd test/integ && python h5tojson_test.py |
| 30 | +cd test/integ && python jsontoh5_test.py |
| 31 | +``` |
| 32 | + |
| 33 | +**Build distribution:** |
| 34 | +```bash |
| 35 | +python -m build |
| 36 | +``` |
| 37 | + |
| 38 | +**Linting:** flake8 with max line length 120 (E402, C901, F401 ignored). See `setup.cfg`. |
| 39 | + |
| 40 | +## Architecture |
| 41 | + |
| 42 | +The core design separates storage backends from the in-memory object model via abstract base classes. |
| 43 | + |
| 44 | +### Central Class: `Hdf5db` (`src/h5json/hdf5db.py`) |
| 45 | + |
| 46 | +`Hdf5db` is an in-memory store for HDF5 objects (groups, datasets, committed datatypes). It tracks object state (new, dirty, deleted) and delegates I/O to pluggable reader/writer instances. Opening reads from the reader into `_db`; closing flushes to the writer. Updates to the object state live in memory until the next flush. Reads from Hdfdb must take into account 'dirty' objects that have not yet been flushed to memory. |
| 47 | + |
| 48 | +### Storage Backends |
| 49 | + |
| 50 | +Abstract base classes in `src/h5json/h5reader.py` and `src/h5json/h5writer.py` define the interface. Two concrete pairs exist: |
| 51 | + |
| 52 | +| Backend | Reader | Writer | Storage | |
| 53 | +|---------|--------|--------|---------| |
| 54 | +| h5py | `h5pystore/h5py_reader.py` | `h5pystore/h5py_writer.py` | `.h5` HDF5 files via h5py | |
| 55 | +| json | `jsonstore/h5json_reader.py` | `jsonstore/h5json_writer.py` | h5json `.json` files | |
| 56 | + |
| 57 | +### CLI Apps (`src/h5json/apps/`) |
| 58 | + |
| 59 | +Each app wires a reader to a writer through `Hdf5db`: |
| 60 | +- `h5tojson`: `H5pyReader` → `H5JsonWriter` — converts HDF5 to JSON |
| 61 | +- `jsontoh5`: `H5JsonReader` → `H5pyWriter` — converts JSON to HDF5 |
| 62 | +- `validator.py`: validates a JSON file against the h5json JSON Schema |
| 63 | + |
| 64 | +### Key Utility Modules |
| 65 | + |
| 66 | +- `hdf5dtype.py` — bidirectional mapping between HDF5/numpy dtypes and h5json type descriptors; exports `getTypeItem`, `createDataType`, `Reference` |
| 67 | +- `selections.py` — HDF5 dataspace selection types (hyperslabs, point selections, fancy indexing); used by both reader backends |
| 68 | +- `array_util.py` — conversion between JSON array representations and numpy arrays |
| 69 | +- `query_util.py` — expression parser and evaluator for dataset value queries (used by `Hdf5db.getDatasetValuesByUuid`) |
| 70 | +- `filters.py` — HDF5 compression filter handling |
| 71 | +- `objid.py` — UUID generation and classification for HDF5 object IDs (Schema 1 vs Schema 2) |
| 72 | +- `shape_util.py`, `dset_util.py` — helpers for dataspace and dataset operations |
| 73 | + |
| 74 | +### JSON Schema |
| 75 | + |
| 76 | +`src/h5json/schema/` contains JSON Schema files defining the h5json format (`hdf5.schema.json` is the root, with sub-schemas for groups, datasets, datatypes, etc.). |
| 77 | + |
| 78 | +### Test Data |
| 79 | + |
| 80 | +`data/hdf5/` contains a large set of `.h5` test files covering various HDF5 features. Integration tests use `data/hdf5/` as input and write output to `test/integ/h5_out/` and `test/integ/json_out/`. |
| 81 | + |
| 82 | +Tests use `unittest` (not pytest) and are run directly with `python`. |
| 83 | + |
| 84 | +## Do / Don't |
| 85 | +- When making a change to any of the h5json/src/*_util.py files, update the corresponding unit test (e.g. if modifying src/h5json/array_util.py, the test would be test/unit/array_util_test.py) to validate the change |
| 86 | +- Be cafeful with memory usage - dataset spaces can be arbitrary large. Avoid reading all the dataset data into memory unless it's known to be relatively small (a few KB) |
| 87 | +- When making changes to hdf5db, first add a test to test/unit/hdf5db_test.py to verify functionality without any storage backend. Once those tests pass, add tests for the json and h5py storage backends |
| 88 | +- For tests with the storage backends, it's important to close the db and re-open, and then verify that any changes made to the mode were persisted to storage. |
| 89 | +- Files (HDF5 or JSON) created by the test cases should be in the test/unit/out directory. These should always be created by the test case (never re-opened from a previous run) |
| 90 | +- Files in data/hdf5/ and data/json/ should oly be modified if there is a change to the schema |
| 91 | +- DON'T read/write datasets data element by element if it can be avoided. Rely on Numpy operations as much as possible for performance |
| 92 | +- DON'T make any changes to the schema without authorization |
0 commit comments