Metadata-Version: 2.4
Name: stele1-datatypes
Version: 0.3.8
Summary: Core datatypes for stele1 climbing catalogs
Author-email: Daniel M <contact@steleclimbing.org>
License-Expression: MIT
Project-URL: Homepage, https://stele1.steleclimbing.org
Project-URL: Repository, https://codeberg.org/stele-climbing/stele1
Project-URL: Issues, https://codeberg.org/stele-climbing/stele1/issues
Keywords: stele1,climbing,guidebook
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: Development Status :: 4 - Beta
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# stele1-datatypes

Core datatypes for [stele1](https://stele1.steleclimbing.org) catalogs.

Covers `Metadata`, `Climb`, `Area`, `Photo`, `Parking`, and `Trail`.
See the [stele1 spec](https://stele1.steleclimbing.org/spec/) for the data
model these implement.

Each datatype validates its input
and exposes `from_data` / `to_data` for serialization
to and from plain dicts.

## Use

```python
from uuid import uuid4
from stele1.climb import Climb

# from existing data
climb = Climb.from_data({
    'uuid': '550e8400-e29b-41d4-a716-446655440000',
    'name': 'Centerpede',
    'rating': {'difficulty': 'V4'},
})

# or built up directly
other = Climb(uuid4())
other.name = 'Millipede'
other.rating = {'difficulty': 'V5'}

climb.name                       # 'Centerpede'
climb.name = 'Centerpede Low'
climb.rating = None              # remove an attribute

climb.to_data()                  # plain dict, ready for json.dumps
```

Attributes are plain values: strings, numbers, tuples, dicts.
Assigning validates immediately;
invalid values raise `TypeError` or `ValueError` at the assignment,
naming the problem:

```python
climb.length = {'lower_estimate': 3, 'upper_estimate': 2, 'unit': 'meters'}
# ValueError: climb .length lower_estimate must not exceed upper_estimate
```

Every record requires a uuid at construction.
`uuid.UUID` instances are accepted and stored
as the canonical lowercase string.

`to_data` returns fresh plain dicts.
`json.dumps(climb.to_data())` produces spec-compliant output;
formatting is up to the caller.
Sequence attributes are returned as tuples;
to change one, assign a new value:

```python
climb.tags = [*(climb.tags or ()), 'highball']
```

## Attribute validators

Each datatype module also exposes its attribute validators,
usable on their own:

```python
from stele1.climb import validate_rating

validate_rating({'difficulty': 'V12'})   # returns the validated value
validate_rating({})                      # raises ValueError
```

## Compatibility behavior

Per the spec's versioning rules:
unknown top-level attributes are preserved verbatim
through `from_data` / `to_data`,
and unknown nested keys raise.

Some checks here are deliberately stricter than the spec;
they are marked `beyond spec` in the source.
To read records that this strictness rejects,
use `DictCatalog` from
[stele1-filesystem](https://codeberg.org/stele-climbing/stele1).

## Install

```
pip install stele1-datatypes
```

## Development

Source and issues live at
[codeberg.org/stele-climbing/stele1](https://codeberg.org/stele-climbing/stele1).

## License

MIT
