Skip to main content

Data specifications by data classes

Project description

dataspecs

Release Python Downloads DOI Tests

Data specifications by data classes

Installation

pip install dataspecs

Usage

from dataclasses import dataclass
from dataspecs import TagBase, from_dataclass
from enum import auto
from typing import Annotated as Ann

Simple specifications

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"))
specs
Specs([
    Spec(id=ID('/'), tags=(), type=<class '__main__.Weather'>, data=Weather(temp=[20.0, 25.0], humid=[50.0, 55.0], location='Tokyo')),
    Spec(id=ID('/temp'), tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0]),
    Spec(id=ID('/temp/0'), tags=(), type=<class 'float'>, data=None),
    Spec(id=ID('/humid'), tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0]),
    Spec(id=ID('/humid/0'), tags=(), type=<class 'float'>, data=None),
    Spec(id=ID('/location'), tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo'),
])

Nested specifications

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"))
specs
Specs([
    Spec(id=ID('/'), tags=(), type=<class '__main__.Weather'>, data=Weather(temp=[20.0, 25.0], humid=[50.0, 55.0], location='Tokyo')),
    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/meta'), tags=(), type=<class '__main__.Meta'>, data=Meta(name='Ground temperature', units='K')),
    Spec(id=ID('/temp/meta/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Ground temperature'),
    Spec(id=ID('/temp/meta/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/meta'), tags=(), type=<class '__main__.Meta'>, data=Meta(name='Relative humidity', units='%')),
    Spec(id=ID('/humid/meta/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Relative humidity'),
    Spec(id=ID('/humid/meta/units'), tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='%'),
    Spec(id=ID('/location'), tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo'),
])

Selecting specifications

specs[Tag.DATA]
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]),
])
specs[Tag]
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/meta/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Ground temperature'),
    Spec(id=ID('/temp/meta/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/meta/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Relative humidity'),
    Spec(id=ID('/humid/meta/units'), tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='%'),
    Spec(id=ID('/location'), tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo'),
])
specs[str]
Specs([
    Spec(id=ID('/temp/meta/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Ground temperature'),
    Spec(id=ID('/temp/meta/units'), tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='K'),
    Spec(id=ID('/humid/meta/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Relative humidity'),
    Spec(id=ID('/humid/meta/units'), tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='%'),
    Spec(id=ID('/location'), tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo'),
])
specs["/temp/meta/[a-z]+"]
Specs([
    Spec(id=ID('/temp/meta/name'), tags=(<Tag.NAME: 4>,), type=<class 'str'>, data='Ground temperature'),
    Spec(id=ID('/temp/meta/units'), tags=(<Tag.UNITS: 5>,), type=<class 'str'>, data='K'),
])

Formatting specifications

from enum import auto
from dataclasses import dataclass
from dataspecs import TagBase, Format, from_dataclass, format
from typing import Annotated as Ann

class Tag(TagBase):
    ATTR = auto()

@dataclass
class Attrs:
    name: Ann[str, Tag.ATTR]
    units: Ann[str, Tag.ATTR]

@dataclass
class Weather:
    temp: Ann[list[float], Attrs("Temperature ({0})", "{0}")]
    units: Ann[str, Format("/temp/attrs/[a-z]+")] = "degC"

format(from_dataclass(Weather([20.0, 25.0], "K")))
Specs([
    Spec(id=ID('/'), tags=(), type=<class '__main__.Weather'>, data=Weather(temp=[20.0, 25.0], units='K')),
    Spec(id=ID('/temp'), tags=(), type=list[float], data=[20.0, 25.0]),
    Spec(id=ID('/temp/0'), tags=(), type=<class 'float'>, data=None),
    Spec(id=ID('/temp/attrs'), tags=(), type=<class '__main__.Attrs'>, data=Attrs(name='Temperature ({0})', units='{0}')),
    Spec(id=ID('/temp/attrs/name'), tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Temperature (K)'),
    Spec(id=ID('/temp/attrs/units'), tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='K'),
    Spec(id=ID('/units'), tags=(), type=<class 'str'>, data='K'),
    Spec(id=ID('/units/format'), tags=(), type=<class 'dataspecs.extras.formatting.Format'>, data=Format(id='/temp/attrs/[a-z]+', of='data', skipif=None)),
    Spec(id=ID('/units/format/id'), tags=(<Tag.ID: 1>,), type=<class 'str'>, data='/temp/attrs/[a-z]+'),
    Spec(id=ID('/units/format/of'), tags=(<Tag.OF: 2>,), type=<class 'str'>, data='data'),
    Spec(id=ID('/units/format/skipif'), tags=(<Tag.SKIPIF: 3>,), type=typing.Any, data=None),
])

Replacing specifications

from enum import auto
from dataclasses import dataclass
from dataspecs import Replace, TagBase, from_dataclass, replace
from typing import Annotated as Ann

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(id=ID('/'), tags=(), type=<class '__main__.Weather'>, data=Weather(temp=[20.0, 25.0], humid=[50.0, 55.0], dtype=<class 'int'>)),
    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 'int'>, data=None),
    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 'int'>, data=None),
    Spec(id=ID('/dtype'), tags=(), type=<class 'type'>, data=<class 'int'>),
    Spec(id=ID('/dtype/replace'), tags=(), type=<class 'dataspecs.extras.replacing.Replace'>, data=Replace(id='/[a-z]+/0', of='type', skipif=None)),
    Spec(id=ID('/dtype/replace/id'), tags=(<Tag.ID: 1>,), type=<class 'str'>, data='/[a-z]+/0'),
    Spec(id=ID('/dtype/replace/of'), tags=(<Tag.OF: 2>,), type=<class 'str'>, data='type'),
    Spec(id=ID('/dtype/replace/skipif'), tags=(<Tag.SKIPIF: 3>,), type=typing.Any, data=None),
])

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dataspecs-2.0.0.tar.gz (50.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dataspecs-2.0.0-py3-none-any.whl (12.4 kB view details)

Uploaded Python 3

File details

Details for the file dataspecs-2.0.0.tar.gz.

File metadata

  • Download URL: dataspecs-2.0.0.tar.gz
  • Upload date:
  • Size: 50.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.13

File hashes

Hashes for dataspecs-2.0.0.tar.gz
Algorithm Hash digest
SHA256 51ef376e804264f4865ff3538c278a84662458f6d68cdd34b3b01c8ec26f9e40
MD5 166f0c67b305e6857b3df1a399900a72
BLAKE2b-256 6bd95283951c2f01a19cf003f93214ffa98e3955c532fd683deef315e5e3c4a5

See more details on using hashes here.

File details

Details for the file dataspecs-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: dataspecs-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 12.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.13

File hashes

Hashes for dataspecs-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2abf3b8265f363f2d139b38d9176aef07ea5d808d996b8655a95699cb14bc74a
MD5 b813efb5ceca958b5ce3ac1361e783b5
BLAKE2b-256 196f584be31e37cce9d98c4f14cad697a9cc0db9c58c29cbe987bafdd884177c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page