Data specifications by data classes
Project description
dataspecs
Data specifications by data classes
Installation
pip install dataspecs
Basic usage
from dataclasses import dataclass
from dataspecs import TagBase, from_dataclass
from enum import auto
from typing import Annotated as Ann
Simple specifications
@dataclass
class Weather:
temp: list[float]
humid: list[float]
location: str
specs = from_dataclass(Weather([20.0, 25.0], [50.0, 55.0], "Tokyo"))
print(specs)
Specs([
Spec(path=Path('/temp'), name='temp', tags=(), type=list[float], data=[20.0, 25.0]),
Spec(path=Path('/temp/0'), name='0', tags=(), type=<class 'float'>, data=None),
Spec(path=Path('/humid'), name='humid', tags=(), type=list[float], data=[50.0, 55.0]),
Spec(path=Path('/humid/0'), name='0', tags=(), type=<class 'float'>, data=None),
Spec(path=Path('/location'), name='location', tags=(), type=<class 'str'>, data='Tokyo'),
])
Simple specifications with tags
class Tag(TagBase):
ATTR = auto()
DATA = auto()
@dataclass
class Weather:
temp: Ann[list[float], Tag.DATA]
humid: Ann[list[float], Tag.DATA]
location: Ann[str, Tag.ATTR]
specs = from_dataclass(Weather([20.0, 25.0], [50.0, 55.0], "Tokyo"))
print(specs)
Specs([
Spec(path=Path('/temp'), name='temp', tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0]),
Spec(path=Path('/temp/0'), name='0', tags=(), type=<class 'float'>, data=None),
Spec(path=Path('/humid'), name='humid', tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0]),
Spec(path=Path('/humid/0'), name='0', tags=(), type=<class 'float'>, data=None),
Spec(path=Path('/location'), name='location', tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo'),
])
Nested specifications (with tags)
class Tag(TagBase):
ATTR = auto()
DATA = auto()
DTYPE = auto()
NAME = auto()
UNITS = auto()
@dataclass
class Meta:
name: Ann[str, Tag.NAME]
units: Ann[str, Tag.UNITS]
@dataclass
class Weather:
temp: Ann[list[Ann[float, Tag.DTYPE]], Tag.DATA, Meta("Ground temperature", "K")]
humid: Ann[list[Ann[float, Tag.DTYPE]], Tag.DATA, Meta("Relative humidity", "%")]
location: Ann[str, Tag.ATTR]
specs = from_dataclass(Weather([20.0, 25.0], [50.0, 55.0], "Tokyo"))
print(specs)
Specs([
Spec(path=Path('/temp'), name='temp', tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0]),
Spec(path=Path('/temp/0'), name='0', tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None),
Spec(path=Path('/temp/name'), name='name', tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Ground temperature'),
Spec(path=Path('/temp/units'), name='units', tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='K'),
Spec(path=Path('/humid'), name='humid', tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0]),
Spec(path=Path('/humid/0'), name='0', tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None),
Spec(path=Path('/humid/name'), name='name', tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Relative humidity'),
Spec(path=Path('/humid/units'), name='units', tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='%'),
Spec(path=Path('/location'), name='location', tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo'),
])
Selecting specifications
specs[Tag.DATA]
Specs([
Spec(path=Path('/temp'), name='temp', tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0]),
Spec(path=Path('/humid'), name='humid', tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0]),
])
specs[Tag]
Specs([
Spec(path=Path('/temp'), name='temp', tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0]),
Spec(path=Path('/temp/0'), name='0', tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None),
Spec(path=Path('/temp/name'), name='name', tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Ground temperature'),
Spec(path=Path('/temp/units'), name='units', tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='K'),
Spec(path=Path('/humid'), name='humid', tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0]),
Spec(path=Path('/humid/0'), name='0', tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None),
Spec(path=Path('/humid/name'), name='name', tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Relative humidity'),
Spec(path=Path('/humid/units'), name='units', tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='%'),
Spec(path=Path('/location'), name='location', tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo'),
])
specs[str]
Specs([
Spec(path=Path('/temp/name'), name='name', tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Ground temperature'),
Spec(path=Path('/temp/units'), name='units', tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='K'),
Spec(path=Path('/humid/name'), name='name', tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Relative humidity'),
Spec(path=Path('/humid/units'), name='units', tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='%'),
Spec(path=Path('/location'), name='location', tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo'),
])
specs["/temp/[a-z]+"]
Specs([
Spec(path=Path('/temp/name'), name='name', tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Ground temperature'),
Spec(path=Path('/temp/units'), name='units', tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='K'),
])
Grouping specifications
specs.groupby("tags")
[
Specs([
Spec(path=Path('/temp'), name='temp', tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0]),
Spec(path=Path('/humid'), name='humid', tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0]),
]),
Specs([
Spec(path=Path('/temp/0'), name='0', tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None),
Spec(path=Path('/humid/0'), name='0', tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None),
]),
Specs([
Spec(path=Path('/temp/name'), name='name', tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Ground temperature'),
Spec(path=Path('/humid/name'), name='name', tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Relative humidity'),
]),
Specs([
Spec(path=Path('/temp/units'), name='units', tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='K'),
Spec(path=Path('/humid/units'), name='units', tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='%'),
]),
Specs([
Spec(path=Path('/location'), name='location', tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo'),
]),
]
Advanced usage
Formatting specifications
from dataspecs import Format, format
class Tag(TagBase):
ATTR = auto()
@dataclass
class Meta:
name: Ann[str, Tag.ATTR]
units: Ann[str, Tag.ATTR]
@dataclass
class Weather:
temp: Ann[list[float], Meta("Temperature ({0})", "{0}")]
units: Ann[str, Format("/temp/(name|units)")] = "degC"
format(from_dataclass(Weather([20.0, 25.0], "K")))
Specs([
Spec(path=Path('/temp'), name='temp', tags=(), type=list[float], data=[20.0, 25.0]),
Spec(path=Path('/temp/0'), name='0', tags=(), type=<class 'float'>, data=None),
Spec(path=Path('/temp/name'), name='name', tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Temperature (K)'), # <- data formatted
Spec(path=Path('/temp/units'), name='units', tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='K'), # <- data formatted
Spec(path=Path('/units'), name='units', tags=(), type=<class 'str'>, data='K'),
])
Naming specifications
from dataspecs import Name, name
@dataclass
class Weather:
temp: Ann[float, Name("Ground temperature")]
humid: Ann[float, Name("Relative humidity")]
name(from_dataclass(Weather(20.0, 50.0)))
Specs([
Spec(path=Path('/temp'), name='Ground temperature', tags=(), type=<class 'float'>, data=20.0), # <- name replaced
Spec(path=Path('/humid'), name='Relative humidity', tags=(), type=<class 'float'>, data=50.0), # <- name replaced
])
Replacing specifications
from dataspecs import Replace, replace
class Tag(TagBase):
ATTR = auto()
DATA = auto()
DTYPE = auto()
@dataclass
class Weather:
temp: Ann[list[Ann[float, Tag.DTYPE]], Tag.DATA]
humid: Ann[list[Ann[float, Tag.DTYPE]], Tag.DATA]
dtype: Ann[type, Replace("/[a-z]+/0", "type")] = None
replace(from_dataclass(Weather([20.0, 25.0], [50.0, 55.0], int)))
Specs([
Spec(path=Path('/temp'), name='temp', tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0]),
Spec(path=Path('/temp/0'), name='0', tags=(<Tag.DTYPE: 3>,), type=<class 'int'>, data=None), # <- type replaced
Spec(path=Path('/humid'), name='humid', tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0]),
Spec(path=Path('/humid/0'), name='0', tags=(<Tag.DTYPE: 3>,), type=<class 'int'>, data=None), # <- type replaced
Spec(path=Path('/dtype'), name='dtype', tags=(), type=<class 'type'>, data=<class 'int'>),
])
Specification rules
First union type as representative type
@dataclass
class Weather:
temp: list[int | float] | (int | float)
from_dataclass(Weather(0.0))
Specs([
Spec(path=Path('/temp'), name='temp', tags=(), type=list[int | float], data=0.0),
Spec(path=Path('/temp/0'), name='0', tags=(), type=<class 'int'>, data=None),
])
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
dataspecs-4.0.0.tar.gz
(50.5 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
dataspecs-4.0.0-py3-none-any.whl
(13.5 kB
view details)
File details
Details for the file dataspecs-4.0.0.tar.gz.
File metadata
- Download URL: dataspecs-4.0.0.tar.gz
- Upload date:
- Size: 50.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dee86f10aefd904274a41d1955b1d0b5e45addf008edbcb94ddac2c9a7faff03
|
|
| MD5 |
576372312287099b39dd84006f737914
|
|
| BLAKE2b-256 |
7402852cfd912b9e35b7b9929e686cbcc7e6dfdfcb91b9eb03a8800a8e8a0694
|
File details
Details for the file dataspecs-4.0.0-py3-none-any.whl.
File metadata
- Download URL: dataspecs-4.0.0-py3-none-any.whl
- Upload date:
- Size: 13.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b4052bd4e1997943d72632f5ca0e41a551d0bd59aa1b289429a0c42f78fe60ef
|
|
| MD5 |
860842913bd29d7e045e8f2be41c68f4
|
|
| BLAKE2b-256 |
87b5e2ef9cf7386cf77b74da3260fd1ef529a2491befd7373e235c8c19f2be92
|