# dataspecs
[![Release](https://img.shields.io/pypi/v/dataspecs?label=Release&color=cornflowerblue&style=flat-square)](https://pypi.org/project/dataspecs/)
[![Python](https://img.shields.io/pypi/pyversions/dataspecs?label=Python&color=cornflowerblue&style=flat-square)](https://pypi.org/project/dataspecs/)
[![Downloads](https://img.shields.io/pypi/dm/dataspecs?label=Downloads&color=cornflowerblue&style=flat-square)](https://pepy.tech/project/dataspecs)
[![DOI](https://img.shields.io/badge/DOI-10.5281/zenodo.10652375-cornflowerblue?style=flat-square)](https://doi.org/10.5281/zenodo.10652375)
[![Tests](https://img.shields.io/github/actions/workflow/status/astropenguin/dataspecs/tests.yaml?label=Tests&style=flat-square)](https://github.com/astropenguin/dataspecs/actions)
Data specifications by data classes
## Installation
```shell
pip install dataspecs==1.0.1
```
## Usage
```python
from dataclasses import dataclass
from dataspecs import TagBase, from_dataclass
from enum import auto
from typing import Annotated as Ann
```
### Simple specifications
```python
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]
simple_specs = from_dataclass(Weather([20.0, 25.0], [50.0, 55.0], "Tokyo"))
simple_specs
```
```python
Specs([Spec(id=ID('/temp'), tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0]),
Spec(id=ID('/humid'), tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0]),
Spec(id=ID('/location'), tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo')])
```
### Nested specifications
```python
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]
nested_specs = from_dataclass(Weather([20.0, 25.0], [50.0, 55.0], "Tokyo"))
nested_specs
```
```python
Specs([Spec(id=ID('/temp'), tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0]),
Spec(id=ID('/temp/0'), tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None),
Spec(id=ID('/temp/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Ground temperature'),
Spec(id=ID('/temp/units'), tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='K'),
Spec(id=ID('/humid'), tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0]),
Spec(id=ID('/humid/0'), tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None),
Spec(id=ID('/humid/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Relative humidity'),
Spec(id=ID('/humid/units'), tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='%'),
Spec(id=ID('/location'), tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo')])
```
### Selecting specifications
```python
nested_specs[Tag.DATA]
```
```python
Specs([Spec(id=ID('/temp'), tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0]),
Spec(id=ID('/humid'), tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0])])
```
```python
nested_specs["/temp/[a-z]+"]
```
```python
Specs([Spec(id=ID('/temp/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Ground temperature'),
Spec(id=ID('/temp/units'), tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='K')])
```
### Grouping specifications
```python
nested_specs.groups()
```
```python
[Specs([Spec(id=ID('/temp'), tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0]),
Spec(id=ID('/temp/0'), tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None),
Spec(id=ID('/temp/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Ground temperature'),
Spec(id=ID('/temp/units'), tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='K')]),
Specs([Spec(id=ID('/humid'), tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0]),
Spec(id=ID('/humid/0'), tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None),
Spec(id=ID('/humid/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Relative humidity'),
Spec(id=ID('/humid/units'), tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='%')]),
Specs([Spec(id=ID('/location'), tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo')])]
```
Raw data
{
"_id": null,
"home_page": "https://github.com/astropenguin/dataspecs/",
"name": "dataspecs",
"maintainer": null,
"docs_url": null,
"requires_python": "<3.13,>=3.9",
"maintainer_email": null,
"keywords": "dataclasses, specifications, typing",
"author": "Akio Taniguchi",
"author_email": "taniguchi@a.phys.nagoya-u.ac.jp",
"download_url": "https://files.pythonhosted.org/packages/f6/b3/15c0e80181f1eba9a635fda05d27a43d5bb15b188c17b3f1a75c5478b852/dataspecs-1.0.1.tar.gz",
"platform": null,
"description": "# dataspecs\n\n[![Release](https://img.shields.io/pypi/v/dataspecs?label=Release&color=cornflowerblue&style=flat-square)](https://pypi.org/project/dataspecs/)\n[![Python](https://img.shields.io/pypi/pyversions/dataspecs?label=Python&color=cornflowerblue&style=flat-square)](https://pypi.org/project/dataspecs/)\n[![Downloads](https://img.shields.io/pypi/dm/dataspecs?label=Downloads&color=cornflowerblue&style=flat-square)](https://pepy.tech/project/dataspecs)\n[![DOI](https://img.shields.io/badge/DOI-10.5281/zenodo.10652375-cornflowerblue?style=flat-square)](https://doi.org/10.5281/zenodo.10652375)\n[![Tests](https://img.shields.io/github/actions/workflow/status/astropenguin/dataspecs/tests.yaml?label=Tests&style=flat-square)](https://github.com/astropenguin/dataspecs/actions)\n\nData specifications by data classes\n\n## Installation\n\n```shell\npip install dataspecs==1.0.1\n```\n\n## Usage\n\n```python\nfrom dataclasses import dataclass\nfrom dataspecs import TagBase, from_dataclass\nfrom enum import auto\nfrom typing import Annotated as Ann\n```\n\n### Simple specifications\n\n```python\nclass Tag(TagBase):\n ATTR = auto()\n DATA = auto()\n\n\n@dataclass\nclass Weather:\n temp: Ann[list[float], Tag.DATA]\n humid: Ann[list[float], Tag.DATA]\n location: Ann[str, Tag.ATTR]\n\n\nsimple_specs = from_dataclass(Weather([20.0, 25.0], [50.0, 55.0], \"Tokyo\"))\nsimple_specs\n```\n```python\nSpecs([Spec(id=ID('/temp'), tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0]),\n Spec(id=ID('/humid'), tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0]),\n Spec(id=ID('/location'), tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo')])\n```\n\n### Nested specifications\n\n```python\nclass Tag(TagBase):\n ATTR = auto()\n DATA = auto()\n DTYPE = auto()\n NAME = auto()\n UNITS = auto()\n\n\n@dataclass\nclass Meta:\n name: Ann[str, Tag.NAME]\n units: Ann[str, Tag.UNITS]\n\n\n@dataclass\nclass Weather:\n temp: Ann[list[Ann[float, Tag.DTYPE]], Tag.DATA, Meta(\"Ground temperature\", \"K\")]\n humid: Ann[list[Ann[float, Tag.DTYPE]], Tag.DATA, Meta(\"Relative humidity\", \"%\")]\n location: Ann[str, Tag.ATTR]\n\n\nnested_specs = from_dataclass(Weather([20.0, 25.0], [50.0, 55.0], \"Tokyo\"))\nnested_specs\n```\n```python\nSpecs([Spec(id=ID('/temp'), tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0]),\n Spec(id=ID('/temp/0'), tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None),\n Spec(id=ID('/temp/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Ground temperature'),\n Spec(id=ID('/temp/units'), tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='K'),\n Spec(id=ID('/humid'), tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0]),\n Spec(id=ID('/humid/0'), tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None),\n Spec(id=ID('/humid/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Relative humidity'),\n Spec(id=ID('/humid/units'), tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='%'),\n Spec(id=ID('/location'), tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo')])\n```\n\n### Selecting specifications\n\n```python\nnested_specs[Tag.DATA]\n```\n```python\nSpecs([Spec(id=ID('/temp'), tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0]),\n Spec(id=ID('/humid'), tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0])])\n```\n\n```python\nnested_specs[\"/temp/[a-z]+\"]\n```\n```python\nSpecs([Spec(id=ID('/temp/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Ground temperature'),\n Spec(id=ID('/temp/units'), tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='K')])\n```\n\n### Grouping specifications\n\n```python\nnested_specs.groups()\n```\n```python\n[Specs([Spec(id=ID('/temp'), tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0]),\n Spec(id=ID('/temp/0'), tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None),\n Spec(id=ID('/temp/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Ground temperature'),\n Spec(id=ID('/temp/units'), tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='K')]),\n Specs([Spec(id=ID('/humid'), tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0]),\n Spec(id=ID('/humid/0'), tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None),\n Spec(id=ID('/humid/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Relative humidity'),\n Spec(id=ID('/humid/units'), tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='%')]),\n Specs([Spec(id=ID('/location'), tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo')])]\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Data specifications by data classes",
"version": "1.0.1",
"project_urls": {
"Documentation": "https://astropenguin.github.io/dataspecs/",
"Homepage": "https://github.com/astropenguin/dataspecs/"
},
"split_keywords": [
"dataclasses",
" specifications",
" typing"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "f8a0824536583389134adde5dbee6f5b735d4d6a42a9a2756283be482dcbdbb2",
"md5": "3199b203e21360ef387a7b513430e74c",
"sha256": "e9f4f30cd79f38015e439acbc4898955bbccea0ded3080ae19a531a79549ab37"
},
"downloads": -1,
"filename": "dataspecs-1.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "3199b203e21360ef387a7b513430e74c",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<3.13,>=3.9",
"size": 9548,
"upload_time": "2024-08-10T16:02:45",
"upload_time_iso_8601": "2024-08-10T16:02:45.582246Z",
"url": "https://files.pythonhosted.org/packages/f8/a0/824536583389134adde5dbee6f5b735d4d6a42a9a2756283be482dcbdbb2/dataspecs-1.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "f6b315c0e80181f1eba9a635fda05d27a43d5bb15b188c17b3f1a75c5478b852",
"md5": "46a0d67a98e4a983b20209def87426a4",
"sha256": "0c576434d8aa885dee80e601723e3a11934871e3958d6a7162d9bf5090e7892f"
},
"downloads": -1,
"filename": "dataspecs-1.0.1.tar.gz",
"has_sig": false,
"md5_digest": "46a0d67a98e4a983b20209def87426a4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<3.13,>=3.9",
"size": 7699,
"upload_time": "2024-08-10T16:02:46",
"upload_time_iso_8601": "2024-08-10T16:02:46.858659Z",
"url": "https://files.pythonhosted.org/packages/f6/b3/15c0e80181f1eba9a635fda05d27a43d5bb15b188c17b3f1a75c5478b852/dataspecs-1.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-10 16:02:46",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "astropenguin",
"github_project": "dataspecs",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "dataspecs"
}