From 6ad73fcbbebf9b63fd62e2526287ed8848c7bd00 Mon Sep 17 00:00:00 2001 From: rly Date: Wed, 3 Jul 2024 12:21:19 -0700 Subject: [PATCH 01/38] Work with new array schema and LoL generator --- my_temperature.DaySeries.values.h5 | Bin 2072 -> 0 bytes my_temperature.DaySeries.values.npy | Bin 152 -> 0 bytes my_temperature.LatitudeSeries.values.h5 | Bin 2072 -> 0 bytes my_temperature.LatitudeSeries.values.npy | Bin 152 -> 0 bytes my_temperature.LongitudeSeries.values.h5 | Bin 2072 -> 0 bytes my_temperature.LongitudeSeries.values.npy | Bin 152 -> 0 bytes my_temperature.TemperatureMatrix.values.h5 | Bin 2264 -> 0 bytes my_temperature.TemperatureMatrix.values.npy | Bin 344 -> 0 bytes .../dumpers/yaml_numpy_dumper.py | 31 ++- tests/array_classes_lol.py | 236 ++++++++++++++++++ tests/input/container.yaml | 39 +++ tests/input/container_npy_dumped.yaml | 32 +++ tests/input/temperature_schema.yaml | 164 ++++++++++++ tests/test_dumpers/array_classes.py | 68 ----- tests/test_dumpers/test_dumpers.py | 134 +++++----- tests/test_loaders/test_loaders.py | 60 +++-- 16 files changed, 593 insertions(+), 171 deletions(-) delete mode 100644 my_temperature.DaySeries.values.h5 delete mode 100644 my_temperature.DaySeries.values.npy delete mode 100644 my_temperature.LatitudeSeries.values.h5 delete mode 100644 my_temperature.LatitudeSeries.values.npy delete mode 100644 my_temperature.LongitudeSeries.values.h5 delete mode 100644 my_temperature.LongitudeSeries.values.npy delete mode 100644 my_temperature.TemperatureMatrix.values.h5 delete mode 100644 my_temperature.TemperatureMatrix.values.npy create mode 100644 tests/array_classes_lol.py create mode 100644 tests/input/container.yaml create mode 100644 tests/input/container_npy_dumped.yaml create mode 100644 tests/input/temperature_schema.yaml delete mode 100644 tests/test_dumpers/array_classes.py diff --git a/my_temperature.DaySeries.values.h5 b/my_temperature.DaySeries.values.h5 deleted file mode 100644 index a6d90ade276e96dd164c26a549cb4a322cfb1887..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2072 zcmeD5aB<`1lHy_j0S*oZ76t(@6Gr@p0tpU?2#gPtPk=HQp>zk7Ucm%mFfxE31A_!q zTo7tLy1I}cS62q0N|^aD8mf)KfCa*WIs+y=N{^5b@Njhu0C_b6>R(tYJpoN;uwY0@ zEJ*~hVd>EWCP606$iNCQ3u+)EG$k`KLIjwh<|1eTuzCStLWQJN2e1lOAP=O2iHQlU zkppTDGb2`+Cp{LBgE F0|2O?EnENq diff --git a/my_temperature.DaySeries.values.npy b/my_temperature.DaySeries.values.npy deleted file mode 100644 index a5c43d4c73360962c109863b418c45955ca4fa4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlWC!@qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= eXCxM+0{I%oI+{8PwF(pfE_Mb8;DFMcP#OT}U>kV= diff --git a/my_temperature.LatitudeSeries.values.h5 b/my_temperature.LatitudeSeries.values.h5 deleted file mode 100644 index 0ff9a437290f091d9465bda18d06da8bc9de1125..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2072 zcmeD5aB<`1lHy_j0S*oZ76t(@6Gr@p0tpU?2#gPtPk=HQp>zk7Ucm%mFfxE31A_!q zTo7tLy1I}cS62q0N|^aD8mf)KfCa*WIs+y=N{^5b@Njhu0C_b6>R(tYJpoN;uwY0@ zEJ*~hVd>EWCP606$iNCQ3u+)EG$k`KLIjwh<|1eTuzCStLWQJN2e1lOAP=O2iHQlU zkppTDGb2zk7Ucm%mFfxE31A_!q zTo7tLy1I}cS62q0N|^aD8mf)KfCa*WIs+y=N{^5b@Njhu0C_b6>R(tYJpoN;uwY0@ zEJ*~hVd>EWCP606$iNCQ3u+)EG$k`KLIjwh<|1eTuzCStLWQJN2e1lOAP=O2iHQlU zkppTDGb2L_7 diff --git a/my_temperature.TemperatureMatrix.values.h5 b/my_temperature.TemperatureMatrix.values.h5 deleted file mode 100644 index f1310c89cb4cc87770213b760c6ae930a0b9064b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2264 zcmeD5aB<`1lHy_j0S*oZ76t(@6Gr@pf*TwV5f~pPp8#brLg@}Dy@CnCU}OM61_lYJ zxFFPgbaf#?uC5F~l`!*RG*lad0Skl$bp}j$lpY}=;Nj{R0P<=C)W5J)dIFlxV8M`* zSds{0!_uP%OoB|Bk%1Lr7SupS1`DuBjLZ-LW~jNu(-L6w1QqNVAZgiw!GxQ^ L@WCEp^zfkp`7BVB diff --git a/my_temperature.TemperatureMatrix.values.npy b/my_temperature.TemperatureMatrix.values.npy deleted file mode 100644 index 172e1282d698b19aa9ed17ad20ca53d2461d38e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 344 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= fXCxM+0{I%oItn19siRP str: + def dumps(self, element: Union[YAMLRoot, BaseModel], schemaview: SchemaView, output_dir: Union[str, Path] = None, **kwargs) -> str: """Return element formatted as a YAML string.""" - input = _iterate_element(element, schemaview) + if output_dir is None: + output_dir = "." + input = _iterate_element(element, schemaview, Path(output_dir)) return yaml.dump(input) diff --git a/tests/array_classes_lol.py b/tests/array_classes_lol.py new file mode 100644 index 0000000..f3fcd03 --- /dev/null +++ b/tests/array_classes_lol.py @@ -0,0 +1,236 @@ +from __future__ import annotations +from datetime import ( + datetime, + date +) +from decimal import Decimal +from enum import Enum +import re +import sys +from typing import ( + Any, + ClassVar, + List, + Literal, + Dict, + Optional, + Union +) +from pydantic.version import VERSION as PYDANTIC_VERSION +if int(PYDANTIC_VERSION[0])>=2: + from pydantic import ( + BaseModel, + ConfigDict, + Field, + RootModel, + field_validator + ) +else: + from pydantic import ( + BaseModel, + Field, + validator + ) + +from pydantic import conlist +metamodel_version = "None" +version = "None" + + +class WeakRefShimBaseModel(BaseModel): + __slots__ = '__weakref__' + +class ConfiguredBaseModel(WeakRefShimBaseModel, + validate_assignment = True, + validate_all = True, + underscore_attrs_are_private = True, + extra = "forbid", + arbitrary_types_allowed = True, + use_enum_values = True): + pass + + + + +class LinkMLMeta(BaseModel): + __root__: Dict[str, Any] = {} + + def __getattr__(self, key:str): + return getattr(self.__root__, key) + + def __getitem__(self, key:str): + return self.__root__[key] + + def __setitem__(self, key:str, value): + self.__root__[key] = value + + class Config: + allow_mutation = False + +linkml_meta = LinkMLMeta(__root__={'default_prefix': 'https://example.org/arrays/', + 'description': 'Example LinkML schema to demonstrate a 3D DataArray of ' + 'temperature values with labeled axes\n' + 'using classes containing arrays for the axes and data instead ' + 'of using array slots/attributes.\n' + 'Creating separate types for the array slots enables reuse and ' + 'extension.', + 'id': 'https://example.org/arrays', + 'name': 'arrays-temperature-example-2'} ) + + +class Container(ConfiguredBaseModel): + """ + A container for a temperature dataset + """ + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta(__root__={'from_schema': 'https://example.org/arrays', 'tree_root': True}) + + name: str = Field(..., linkml_meta = {'alias': 'name', + 'domain_of': ['Container', + 'TemperatureDataset', + 'LatitudeInDegSeries', + 'LongitudeInDegSeries']} +) + temperature_dataset: TemperatureDataset = Field(..., linkml_meta = {'alias': 'temperature_dataset', 'domain_of': ['Container']} +) + latitude_series: LatitudeInDegSeries = Field(..., linkml_meta = {'alias': 'latitude_series', 'domain_of': ['Container']} +) + longitude_series: LongitudeInDegSeries = Field(..., linkml_meta = {'alias': 'longitude_series', 'domain_of': ['Container']} +) + + +class TemperatureDataset(ConfiguredBaseModel): + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta(__root__={'from_schema': 'https://example.org/arrays', + 'implements': ['linkml:DataArray'], + 'tree_root': True}) + + name: str = Field(..., linkml_meta = {'alias': 'name', + 'domain_of': ['Container', + 'TemperatureDataset', + 'LatitudeInDegSeries', + 'LongitudeInDegSeries']} +) + latitude_in_deg: str = Field(..., linkml_meta = {'alias': 'latitude_in_deg', 'domain_of': ['TemperatureDataset']} +) + longitude_in_deg: str = Field(..., linkml_meta = {'alias': 'longitude_in_deg', 'domain_of': ['TemperatureDataset']} +) + date: DateSeries = Field(..., linkml_meta = {'alias': 'date', 'domain_of': ['TemperatureDataset']} +) + day_in_d: Optional[DaysInDSinceSeries] = Field(None, linkml_meta = {'alias': 'day_in_d', 'domain_of': ['TemperatureDataset']} +) + temperatures_in_K: TemperaturesInKMatrix = Field(..., linkml_meta = {'alias': 'temperatures_in_K', 'domain_of': ['TemperatureDataset']} +) + + +class LatitudeInDegSeries(ConfiguredBaseModel): + """ + A 2D array whose values represent latitude + """ + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta(__root__={'from_schema': 'https://example.org/arrays'}) + + name: str = Field(..., linkml_meta = {'alias': 'name', + 'domain_of': ['Container', + 'TemperatureDataset', + 'LatitudeInDegSeries', + 'LongitudeInDegSeries']} +) + values: List[List[float]] = Field(default_factory=list, linkml_meta = {'alias': 'values', + 'array': {'exact_number_dimensions': 2}, + 'domain_of': ['LatitudeInDegSeries', + 'LongitudeInDegSeries', + 'DateSeries', + 'DaysInDSinceSeries', + 'TemperaturesInKMatrix'], + 'unit': {'ucum_code': 'deg'}} +) + + +class LongitudeInDegSeries(ConfiguredBaseModel): + """ + A 2D array whose values represent longitude + """ + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta(__root__={'from_schema': 'https://example.org/arrays'}) + + name: str = Field(..., linkml_meta = {'alias': 'name', + 'domain_of': ['Container', + 'TemperatureDataset', + 'LatitudeInDegSeries', + 'LongitudeInDegSeries']} +) + values: List[List[float]] = Field(default_factory=list, linkml_meta = {'alias': 'values', + 'array': {'exact_number_dimensions': 2}, + 'domain_of': ['LatitudeInDegSeries', + 'LongitudeInDegSeries', + 'DateSeries', + 'DaysInDSinceSeries', + 'TemperaturesInKMatrix'], + 'unit': {'ucum_code': 'deg'}} +) + + +class DateSeries(ConfiguredBaseModel): + """ + A 1D series of dates + """ + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta(__root__={'from_schema': 'https://example.org/arrays'}) + + values: List[str] = Field(default_factory=list, linkml_meta = {'alias': 'values', + 'array': {'exact_number_dimensions': 1}, + 'domain_of': ['LatitudeInDegSeries', + 'LongitudeInDegSeries', + 'DateSeries', + 'DaysInDSinceSeries', + 'TemperaturesInKMatrix']} +) + + +class DaysInDSinceSeries(ConfiguredBaseModel): + """ + A 1D series whose values represent the number of days since a reference date + """ + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta(__root__={'from_schema': 'https://example.org/arrays'}) + + values: List[int] = Field(default_factory=list, linkml_meta = {'alias': 'values', + 'array': {'exact_number_dimensions': 1}, + 'domain_of': ['LatitudeInDegSeries', + 'LongitudeInDegSeries', + 'DateSeries', + 'DaysInDSinceSeries', + 'TemperaturesInKMatrix'], + 'unit': {'ucum_code': 'd'}} +) + reference_date: str = Field(..., description="""The reference date for the `day_in_d` values""", linkml_meta = {'alias': 'reference_date', 'domain_of': ['DaysInDSinceSeries']} +) + + +class TemperaturesInKMatrix(ConfiguredBaseModel): + """ + A 3D array of temperatures + """ + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta(__root__={'from_schema': 'https://example.org/arrays'}) + + conversion_factor: Optional[float] = Field(None, description="""A conversion factor to apply to the temperature values""", linkml_meta = {'alias': 'conversion_factor', + 'domain_of': ['TemperaturesInKMatrix'], + 'unit': {'ucum_code': 'K'}} +) + values: List[List[List[float]]] = Field(default_factory=list, linkml_meta = {'alias': 'values', + 'array': {'dimensions': [{'alias': 'x'}, {'alias': 'y'}, {'alias': 'date'}], + 'exact_number_dimensions': 3}, + 'domain_of': ['LatitudeInDegSeries', + 'LongitudeInDegSeries', + 'DateSeries', + 'DaysInDSinceSeries', + 'TemperaturesInKMatrix'], + 'unit': {'ucum_code': 'K'}} +) + + +# Update forward refs +# see https://pydantic-docs.helpmanual.io/usage/postponed_annotations/ +Container.update_forward_refs() +TemperatureDataset.update_forward_refs() +LatitudeInDegSeries.update_forward_refs() +LongitudeInDegSeries.update_forward_refs() +DateSeries.update_forward_refs() +DaysInDSinceSeries.update_forward_refs() +TemperaturesInKMatrix.update_forward_refs() + diff --git a/tests/input/container.yaml b/tests/input/container.yaml new file mode 100644 index 0000000..3c5b479 --- /dev/null +++ b/tests/input/container.yaml @@ -0,0 +1,39 @@ +name: my_container +temperature_dataset: + name: my_temperature + latitude_in_deg: my_latitude + longitude_in_deg: my_longitude + temperatures_in_K: + conversion_factor: 1000 + values: + - - - 0 + - 1 + - - 2 + - 3 + - - - 4 + - 5 + - - 6 + - 7 + date: + values: + - "2020-01-01" + - "2020-01-02" + day_in_d: + values: + - 0 + - 1 + reference_date: "2020-01-01" +latitude_series: + name: my_latitude + values: + - - 1 + - 2 + - - 3 + - 4 +longitude_series: + name: my_longitude + values: + - - 5 + - 6 + - - 7 + - 8 diff --git a/tests/input/container_npy_dumped.yaml b/tests/input/container_npy_dumped.yaml new file mode 100644 index 0000000..e182a61 --- /dev/null +++ b/tests/input/container_npy_dumped.yaml @@ -0,0 +1,32 @@ +name: my_container +temperature_dataset: + name: my_temperature + latitude_in_deg: my_latitude + longitude_in_deg: my_longitude + temperatures_in_K: + conversion_factor: 1000 + # TODO revisit this + values: file:./tests/input/my_container.my_temperature.temperatures_in_K.values.npy + date: + values: + - "2020-01-01" + - "2020-01-02" + day_in_d: + values: + - 0 + - 1 + reference_date: "2020-01-01" +latitude_series: + name: my_latitude + values: + - - 1 + - 2 + - - 3 + - 4 +longitude_series: + name: my_longitude + values: + - - 5 + - 6 + - - 7 + - 8 diff --git a/tests/input/temperature_schema.yaml b/tests/input/temperature_schema.yaml new file mode 100644 index 0000000..f836590 --- /dev/null +++ b/tests/input/temperature_schema.yaml @@ -0,0 +1,164 @@ +id: https://example.org/arrays +name: arrays-temperature-example-2 +title: Array Temperature Example Using NDArray Classes +description: |- + Example LinkML schema to demonstrate a 3D DataArray of temperature values with labeled axes + using classes containing arrays for the axes and data instead of using array slots/attributes. + Creating separate types for the array slots enables reuse and extension. +license: MIT + +prefixes: + linkml: https://w3id.org/linkml/ + wgs84: http://www.w3.org/2003/01/geo/wgs84_pos# + example: https://example.org/ + +default_prefix: example + +imports: + - linkml:types + +classes: + + Container: + tree_root: true + description: A container for a temperature dataset + attributes: + name: + identifier: true + range: string + temperature_dataset: + range: TemperatureDataset + required: true + inlined: true + latitude_series: + range: LatitudeInDegSeries + required: true + inlined: true + longitude_series: + range: LongitudeInDegSeries + required: true + inlined: true + + TemperatureDataset: + tree_root: true + implements: + - linkml:DataArray + attributes: + name: + identifier: true + range: string + latitude_in_deg: + range: LatitudeInDegSeries # schema requires this data not to be inlined + required: true + longitude_in_deg: + range: LongitudeInDegSeries + required: true + date: + range: DateSeries + required: true + inlined: true # this could also be not inlined but for example sake it is inlined + day_in_d: + range: DaysInDSinceSeries + inlined: true + # one could define `reference_date` at this level but it really should be an attribute on `DaysSinceSeries`. + # however, this means `reference_date` cannot be a non-dimension (constant) coordinate of `temperatures_in_K` + # as structured in Xarray. + temperatures_in_K: + range: TemperaturesInKMatrix + required: true + inlined: true + array: + # it does not make sense to put `labeled_by` on `TemperatureMatrix` because the index slots are only + # accessible from this DataArray class. + # TODO uncomment this once it is supported by the metamodel + # labeled_by: + # - alias: lat + # label_slot: latitude_in_deg + # labeled_dimensions: [0, 1] + # - alias: lon + # label_slot: longitude_in_deg + # labeled_dimensions: [0, 1] + # - alias: date + # label_slot: date + # labeled_dimensions: [2] + # - alias: day + # label_slot: day_in_d + # labeled_dimensions: [2] + + LatitudeInDegSeries: + description: A 2D array whose values represent latitude + attributes: + name: + identifier: true # an identifier is required for referencing in other classes + range: string + values: + required: true + multivalued: true + range: float + unit: + ucum_code: deg + array: # exactly one attribute within this class must be an array + exact_number_dimensions: 2 + + LongitudeInDegSeries: + description: A 2D array whose values represent longitude + attributes: + name: + identifier: true + range: string + values: + required: true + multivalued: true + range: float + unit: + ucum_code: deg + array: + exact_number_dimensions: 2 + + DateSeries: + description: A 1D series of dates + attributes: + values: + required: true + multivalued: true + range: string # for now, we are using a string to represent a date + array: + exact_number_dimensions: 1 + + DaysInDSinceSeries: + description: A 1D series whose values represent the number of days since a reference date + attributes: + values: + required: true + multivalued: true + range: integer + unit: + ucum_code: d + array: + exact_number_dimensions: 1 + reference_date: + description: The reference date for the `day_in_d` values + required: true + range: string # for now, we are using a string to represent a date + + TemperaturesInKMatrix: + description: A 3D array of temperatures + attributes: + # no name because this should not be directly referenced + conversion_factor: + description: A conversion factor to apply to the temperature values + range: float + unit: + ucum_code: K + values: + required: true + multivalued: true + range: float + unit: + ucum_code: K + array: + exact_number_dimensions: 3 + dimensions: + - alias: "x" + - alias: "y" + - alias: "date" diff --git a/tests/test_dumpers/array_classes.py b/tests/test_dumpers/array_classes.py deleted file mode 100644 index 1656a5c..0000000 --- a/tests/test_dumpers/array_classes.py +++ /dev/null @@ -1,68 +0,0 @@ -from __future__ import annotations -import numpy as np -from pydantic import BaseModel as BaseModel, ConfigDict, Field - - -metamodel_version = "None" -version = "None" - - -class ConfiguredBaseModel(BaseModel): - model_config = ConfigDict( - validate_assignment=True, - validate_default=True, - extra="forbid", - arbitrary_types_allowed=True, - use_enum_values=True, - ) - pass - - -class TemperatureDataset(ConfiguredBaseModel): - - name: str = Field(...) - latitude_in_deg: LatitudeSeries = Field(...) - longitude_in_deg: LongitudeSeries = Field(...) - time_in_d: DaySeries = Field(...) - temperatures_in_K: TemperatureMatrix = Field(...) - - -class TemperatureMatrix(ConfiguredBaseModel): - """ - A 3D array of temperatures - """ - - values: np.ndarray = Field(None) - - -class LatitudeSeries(ConfiguredBaseModel): - """ - A series whose values represent latitude - """ - - values: np.ndarray = Field(None) - - -class LongitudeSeries(ConfiguredBaseModel): - """ - A series whose values represent longitude - """ - - values: np.ndarray = Field(None) - - -class DaySeries(ConfiguredBaseModel): - """ - A series whose values represent the days since the start of the measurement period - """ - - values: np.ndarray = Field(None) - - -# Model rebuild -# see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model -TemperatureDataset.model_rebuild() -TemperatureMatrix.model_rebuild() -LatitudeSeries.model_rebuild() -LongitudeSeries.model_rebuild() -DaySeries.model_rebuild() diff --git a/tests/test_dumpers/test_dumpers.py b/tests/test_dumpers/test_dumpers.py index c7ea289..2d5e30b 100644 --- a/tests/test_dumpers/test_dumpers.py +++ b/tests/test_dumpers/test_dumpers.py @@ -2,6 +2,7 @@ import os import unittest +from ruamel.yaml import YAML from pathlib import Path import numpy as np @@ -14,62 +15,63 @@ YamlNumpyDumper, ZarrDirectoryStoreDumper, ) -from tests.test_dumpers.array_classes import ( - DaySeries, - LatitudeSeries, - LongitudeSeries, +from tests.array_classes_lol import ( + Container, + DateSeries, + DaysInDSinceSeries, + LatitudeInDegSeries, + LongitudeInDegSeries, TemperatureDataset, - TemperatureMatrix, + TemperaturesInKMatrix, ) +INPUT_DIR = Path(__file__).parent.parent / "input" + + +def create_container() -> Container: + latitude_in_deg = LatitudeInDegSeries(name="my_latitude", values=[[1, 2], [3, 4]]) + longitude_in_deg = LongitudeInDegSeries(name="my_longitude", values=[[5, 6], [7, 8]]) + date = DateSeries(values=["2020-01-01", "2020-01-02"]) + days_in_d_since = DaysInDSinceSeries(values=[0, 1], reference_date="2020-01-01") + temperatures_in_K = TemperaturesInKMatrix( + conversion_factor=1000.0, + values=[[[0, 1], [2, 3]], [[4, 5], [6, 7]]], + ) + temperature_dataset = TemperatureDataset( + name="my_temperature", + latitude_in_deg="my_latitude", # currently no way to pass in the actual LatitudeInDegSeries object + longitude_in_deg="my_longitude", + date=date, + day_in_d=days_in_d_since, + temperatures_in_K=temperatures_in_K, + ) + container = Container( + name="my_container", + latitude_series=latitude_in_deg, + longitude_series=longitude_in_deg, + temperature_dataset=temperature_dataset, + ) + + return container + class YamlDumpersTestCase(unittest.TestCase): - """Test dumping of pydantic-style classes from LinkML schemas into YAML files.""" + """Test dumping of pydantic-style lists-of-lists classes from LinkML schemas into YAML files.""" def test_dump_pydantic_arrays(self): - """Test dumping pydantic classes with numpy arrays to a YAML file.""" - latitude_in_deg = LatitudeSeries(values=np.array([1, 2])) - longitude_in_deg = LongitudeSeries(values=np.array([4, 5])) - time_in_d = DaySeries(values=np.array([7, 8])) - temperatures_in_K = TemperatureMatrix( - values=np.arange(8).reshape((2, 2, 2)), - ) - temperature = TemperatureDataset( - name="my_temperature", - latitude_in_deg=latitude_in_deg, - longitude_in_deg=longitude_in_deg, - time_in_d=time_in_d, - temperatures_in_K=temperatures_in_K, - ) + """Test dumping pydantic classes with lists of lists to a YAML file.""" + container = create_container() - schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") - ret = YamlDumper().dumps(temperature, schemaview=schemaview) + schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") + ret = YamlDumper().dumps(container, schemaview=schemaview) - expected = """latitude_in_deg: - values: - - 1 - - 2 -longitude_in_deg: - values: - - 4 - - 5 -name: my_temperature -temperatures_in_K: - values: - - - - 0 - - 1 - - - 2 - - 3 - - - - 4 - - 5 - - - 6 - - 7 -time_in_d: - values: - - 7 - - 8 -""" - assert ret == expected + # read and compare with the expected YAML file ignoring order of keys + expected_yaml_file = INPUT_DIR / "container.yaml" + yaml = YAML(typ="safe") + with open(expected_yaml_file) as f: + expected = yaml.load(f) # load yaml into dictionary + actual = yaml.load(ret) + assert actual == expected class YamlNumpyDumpersTestCase(unittest.TestCase): @@ -77,34 +79,20 @@ class YamlNumpyDumpersTestCase(unittest.TestCase): def test_dump_pydantic_arrays(self): """Test dumping pydantic classes with numpy arrays to a YAML + NumPy files.""" - latitude_in_deg = LatitudeSeries(values=np.array([1, 2, 3])) - longitude_in_deg = LongitudeSeries(values=np.array([4, 5, 6])) - time_in_d = DaySeries(values=np.array([7, 8, 9])) - temperatures_in_K = TemperatureMatrix( - values=np.ones((3, 3, 3)), - ) - temperature = TemperatureDataset( - name="my_temperature", - latitude_in_deg=latitude_in_deg, - longitude_in_deg=longitude_in_deg, - time_in_d=time_in_d, - temperatures_in_K=temperatures_in_K, - ) + container = create_container() - schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") - ret = YamlNumpyDumper().dumps(temperature, schemaview=schemaview) + schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") + ret = YamlNumpyDumper().dumps(container, schemaview=schemaview, output_dir="tmp") - expected = """latitude_in_deg: - values: file:./my_temperature.LatitudeSeries.values.npy -longitude_in_deg: - values: file:./my_temperature.LongitudeSeries.values.npy -name: my_temperature -temperatures_in_K: - values: file:./my_temperature.TemperatureMatrix.values.npy -time_in_d: - values: file:./my_temperature.DaySeries.values.npy -""" - assert ret == expected + print(ret) + + # # read and compare with the expected YAML file ignoring order of keys + # expected_yaml_file = INPUT_DIR / "container.yaml" + # yaml = YAML(typ="safe") + # with open(expected_yaml_file) as f: + # expected = yaml.load(f) # load yaml into dictionary + # actual = yaml.load(ret) + # assert actual == expected class YamlHdf5DumpersTestCase(unittest.TestCase): diff --git a/tests/test_loaders/test_loaders.py b/tests/test_loaders/test_loaders.py index 6ce15f6..e7ef6e6 100644 --- a/tests/test_loaders/test_loaders.py +++ b/tests/test_loaders/test_loaders.py @@ -14,40 +14,60 @@ YamlNumpyLoader, ZarrDirectoryStoreLoader, ) -from tests.test_dumpers.array_classes import ( - DaySeries, - LatitudeSeries, - LongitudeSeries, +from tests.array_classes_lol import ( + Container, + DateSeries, + DaysInDSinceSeries, + LatitudeInDegSeries, + LongitudeInDegSeries, TemperatureDataset, - TemperatureMatrix, + TemperaturesInKMatrix, ) class YamlLoadersTestCase(unittest.TestCase): - """Test loading of pydantic-style classes from YAML arrays.""" + """Test loading of pydantic lists-of-lists classes from YAML arrays.""" def test_load_pydantic_arrays(self): """Test loading of pydantic-style classes from YAML arrays.""" - read_yaml = hbread( - "temperature_dataset_yaml.yaml", base_path=str(Path(__file__) / "../../input") + data_yaml = hbread( + "container.yaml", base_path=str(Path(__file__) / "../../input") ) - schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") - ret = YamlLoader().loads(read_yaml, target_class=TemperatureDataset, schemaview=schemaview) + schemaview = SchemaView(Path(__file__) / "../../input/temperature_schema.yaml") + container = YamlLoader().loads(data_yaml, target_class=Container, schemaview=schemaview) - assert isinstance(ret, TemperatureDataset) - assert ret.name == "my_temperature" + assert isinstance(container, Container) + assert container.name == "my_container" - assert isinstance(ret.latitude_in_deg, LatitudeSeries) - np.testing.assert_array_equal(ret.latitude_in_deg.values, np.array([1, 2])) + assert isinstance(container.latitude_series, LatitudeInDegSeries) + assert container.latitude_series.name == "my_latitude" + np.testing.assert_array_equal(container.latitude_series.values, np.array([[1, 2], [3, 4]])) - assert isinstance(ret.longitude_in_deg, LongitudeSeries) - np.testing.assert_array_equal(ret.longitude_in_deg.values, np.array([4, 5])) + assert isinstance(container.longitude_series, LongitudeInDegSeries) + assert container.longitude_series.name == "my_longitude" + np.testing.assert_array_equal(container.longitude_series.values, np.array([[5, 6], [7, 8]])) - assert isinstance(ret.time_in_d, DaySeries) - np.testing.assert_array_equal(ret.time_in_d.values, np.array([7, 8])) + assert isinstance(container.temperature_dataset, TemperatureDataset) + assert container.temperature_dataset.name == "my_temperature" + assert container.temperature_dataset.latitude_in_deg == "my_latitude" + # currently no way to get the actual LatitudeInDegSeries object from the TemperatureDataset object + # because the TemperatureDataset Pydantic object expects a string for the latitude_in_deg field + # to be isomorphic with the json schema / yaml representation - assert isinstance(ret.temperatures_in_K, TemperatureMatrix) - np.testing.assert_array_equal(ret.temperatures_in_K.values, np.arange(8).reshape((2, 2, 2))) + assert container.temperature_dataset.longitude_in_deg == "my_longitude" + + assert isinstance(container.temperature_dataset.date, DateSeries) + assert container.temperature_dataset.date.values == ["2020-01-01", "2020-01-02"] + + assert isinstance(container.temperature_dataset.day_in_d, DaysInDSinceSeries) + assert container.temperature_dataset.day_in_d.values == [0, 1] + assert container.temperature_dataset.day_in_d.reference_date == "2020-01-01" + + assert isinstance(container.temperature_dataset.temperatures_in_K, TemperaturesInKMatrix) + np.testing.assert_array_equal( + container.temperature_dataset.temperatures_in_K.values, + np.array([[[0, 1], [2, 3]], [[4, 5], [6, 7]]]), + ) class YamlNumpyLoadersTestCase(unittest.TestCase): From 92ed77bd3f5d39004e054b0985c59551e0a85895 Mon Sep 17 00:00:00 2001 From: rly Date: Wed, 3 Jul 2024 12:24:47 -0700 Subject: [PATCH 02/38] Put labeled by as string annotation on array --- tests/input/temperature_schema.yaml | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/tests/input/temperature_schema.yaml b/tests/input/temperature_schema.yaml index f836590..7b83c58 100644 --- a/tests/input/temperature_schema.yaml +++ b/tests/input/temperature_schema.yaml @@ -71,19 +71,22 @@ classes: # it does not make sense to put `labeled_by` on `TemperatureMatrix` because the index slots are only # accessible from this DataArray class. # TODO uncomment this once it is supported by the metamodel - # labeled_by: - # - alias: lat - # label_slot: latitude_in_deg - # labeled_dimensions: [0, 1] - # - alias: lon - # label_slot: longitude_in_deg - # labeled_dimensions: [0, 1] - # - alias: date - # label_slot: date - # labeled_dimensions: [2] - # - alias: day - # label_slot: day_in_d - # labeled_dimensions: [2] + annotations: + labeled_by: + " + - alias: lat + label_slot: latitude_in_deg + labeled_dimensions: [0, 1] + - alias: lon + label_slot: longitude_in_deg + labeled_dimensions: [0, 1] + - alias: date + label_slot: date + labeled_dimensions: [2] + - alias: day + label_slot: day_in_d + labeled_dimensions: [2] + " LatitudeInDegSeries: description: A 2D array whose values represent latitude From bbfb77a36192f18bd5eb64eb1ec21e8772ce83b4 Mon Sep 17 00:00:00 2001 From: rly Date: Wed, 3 Jul 2024 19:32:10 -0700 Subject: [PATCH 03/38] Use pydantic 2 in array classes --- tests/array_classes.py | 284 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 tests/array_classes.py diff --git a/tests/array_classes.py b/tests/array_classes.py new file mode 100644 index 0000000..a022616 --- /dev/null +++ b/tests/array_classes.py @@ -0,0 +1,284 @@ +from __future__ import annotations +from datetime import ( + datetime, + date +) +from decimal import Decimal +from enum import Enum +import re +import sys +from pydantic.version import VERSION as PYDANTIC_VERSION +from typing import ( + Any, + ClassVar, + List, + Literal, + Dict, + Optional, + Union, + Generic, + Iterable, + TypeVar, + get_args +) +if sys.version_info.minor > 8: + from typing import Annotated +else: + from typing_extensions import Annotated + +from pydantic import GetCoreSchemaHandler +from pydantic_core import ( + CoreSchema, + core_schema +) +if int(PYDANTIC_VERSION[0])>=2: + from pydantic import ( + BaseModel, + ConfigDict, + Field, + RootModel, + field_validator + ) +else: + from pydantic import ( + BaseModel, + Field, + validator + ) + +from pydantic import conlist +metamodel_version = "None" +version = "None" + + +class ConfiguredBaseModel(BaseModel): + model_config = ConfigDict( + validate_assignment = True, + validate_default = True, + extra = "forbid", + arbitrary_types_allowed = True, + use_enum_values = True, + strict = False, + ) + pass + + + + +class LinkMLMeta(RootModel): + root: Dict[str, Any] = {} + model_config = ConfigDict(frozen=True) + + def __getattr__(self, key:str): + return getattr(self.root, key) + + def __getitem__(self, key:str): + return self.root[key] + + def __setitem__(self, key:str, value): + self.root[key] = value + + + +_T = TypeVar("_T") + +_RecursiveListType = Iterable[Union[_T, Iterable["_RecursiveListType"]]] + +class AnyShapeArrayType(Generic[_T]): + @classmethod + def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema: + # double-nested parameterized types here + # source_type: List[Union[T,List[...]]] + item_type = Any if get_args(get_args(source_type)[0])[0] is _T else get_args(get_args(source_type)[0])[0] + + item_schema = handler.generate_schema(item_type) + if item_schema.get("type", "any") != "any": + item_schema["strict"] = True + + if item_type is Any: + # Before python 3.11, `Any` type was a special object without a __name__ + item_name = "Any" + else: + item_name = item_type.__name__ + + array_ref = f"any-shape-array-{item_name}" + + schema = core_schema.definitions_schema( + core_schema.list_schema(core_schema.definition_reference_schema(array_ref)), + [ + core_schema.union_schema( + [ + core_schema.list_schema(core_schema.definition_reference_schema(array_ref)), + item_schema, + ], + ref=array_ref, + ) + ], + ) + + return schema + + +AnyShapeArray = Annotated[_RecursiveListType, AnyShapeArrayType] +linkml_meta = LinkMLMeta({'default_prefix': 'https://example.org/arrays/', + 'description': 'Example LinkML schema to demonstrate a 3D DataArray of ' + 'temperature values with labeled axes\n' + 'using classes containing arrays for the axes and data instead ' + 'of using array slots/attributes.\n' + 'Creating separate types for the array slots enables reuse and ' + 'extension.', + 'id': 'https://example.org/arrays', + 'name': 'arrays-temperature-example-2'} ) + + +class Container(ConfiguredBaseModel): + """ + A container for a temperature dataset + """ + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays', 'tree_root': True}) + + name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', + 'domain_of': ['Container', + 'TemperatureDataset', + 'LatitudeInDegSeries', + 'LongitudeInDegSeries']} }) + temperature_dataset: TemperatureDataset = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'temperature_dataset', 'domain_of': ['Container']} }) + latitude_series: LatitudeInDegSeries = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'latitude_series', 'domain_of': ['Container']} }) + longitude_series: LongitudeInDegSeries = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'longitude_series', 'domain_of': ['Container']} }) + + +class TemperatureDataset(ConfiguredBaseModel): + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays', + 'implements': ['linkml:DataArray'], + 'tree_root': True}) + + name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', + 'domain_of': ['Container', + 'TemperatureDataset', + 'LatitudeInDegSeries', + 'LongitudeInDegSeries']} }) + latitude_in_deg: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'latitude_in_deg', 'domain_of': ['TemperatureDataset']} }) + longitude_in_deg: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'longitude_in_deg', 'domain_of': ['TemperatureDataset']} }) + date: DateSeries = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'date', 'domain_of': ['TemperatureDataset']} }) + day_in_d: Optional[DaysInDSinceSeries] = Field(None, json_schema_extra = { "linkml_meta": {'alias': 'day_in_d', 'domain_of': ['TemperatureDataset']} }) + temperatures_in_K: AnyShapeArray[TemperaturesInKMatrix] = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'temperatures_in_K', + 'array': {'annotations': {'labeled_by': {'tag': 'labeled_by', + 'value': ' - alias: lat label_slot: ' + 'latitude_in_deg ' + 'labeled_dimensions: [0, 1] ' + '- alias: lon label_slot: ' + 'longitude_in_deg ' + 'labeled_dimensions: [0, 1] ' + '- alias: date label_slot: ' + 'date labeled_dimensions: ' + '[2] - alias: day ' + 'label_slot: day_in_d ' + 'labeled_dimensions: ' + '[2] '}}}, + 'domain_of': ['TemperatureDataset']} }) + + +class LatitudeInDegSeries(ConfiguredBaseModel): + """ + A 2D array whose values represent latitude + """ + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) + + name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', + 'domain_of': ['Container', + 'TemperatureDataset', + 'LatitudeInDegSeries', + 'LongitudeInDegSeries']} }) + values: List[List[float]] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', + 'array': {'exact_number_dimensions': 2}, + 'domain_of': ['LatitudeInDegSeries', + 'LongitudeInDegSeries', + 'DateSeries', + 'DaysInDSinceSeries', + 'TemperaturesInKMatrix'], + 'unit': {'ucum_code': 'deg'}} }) + + +class LongitudeInDegSeries(ConfiguredBaseModel): + """ + A 2D array whose values represent longitude + """ + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) + + name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', + 'domain_of': ['Container', + 'TemperatureDataset', + 'LatitudeInDegSeries', + 'LongitudeInDegSeries']} }) + values: List[List[float]] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', + 'array': {'exact_number_dimensions': 2}, + 'domain_of': ['LatitudeInDegSeries', + 'LongitudeInDegSeries', + 'DateSeries', + 'DaysInDSinceSeries', + 'TemperaturesInKMatrix'], + 'unit': {'ucum_code': 'deg'}} }) + + +class DateSeries(ConfiguredBaseModel): + """ + A 1D series of dates + """ + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) + + values: List[str] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', + 'array': {'exact_number_dimensions': 1}, + 'domain_of': ['LatitudeInDegSeries', + 'LongitudeInDegSeries', + 'DateSeries', + 'DaysInDSinceSeries', + 'TemperaturesInKMatrix']} }) + + +class DaysInDSinceSeries(ConfiguredBaseModel): + """ + A 1D series whose values represent the number of days since a reference date + """ + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) + + values: List[int] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', + 'array': {'exact_number_dimensions': 1}, + 'domain_of': ['LatitudeInDegSeries', + 'LongitudeInDegSeries', + 'DateSeries', + 'DaysInDSinceSeries', + 'TemperaturesInKMatrix'], + 'unit': {'ucum_code': 'd'}} }) + reference_date: str = Field(..., description="""The reference date for the `day_in_d` values""", json_schema_extra = { "linkml_meta": {'alias': 'reference_date', 'domain_of': ['DaysInDSinceSeries']} }) + + +class TemperaturesInKMatrix(ConfiguredBaseModel): + """ + A 3D array of temperatures + """ + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) + + conversion_factor: Optional[float] = Field(None, description="""A conversion factor to apply to the temperature values""", json_schema_extra = { "linkml_meta": {'alias': 'conversion_factor', + 'domain_of': ['TemperaturesInKMatrix'], + 'unit': {'ucum_code': 'K'}} }) + values: List[List[List[float]]] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', + 'array': {'dimensions': [{'alias': 'x'}, {'alias': 'y'}, {'alias': 'date'}], + 'exact_number_dimensions': 3}, + 'domain_of': ['LatitudeInDegSeries', + 'LongitudeInDegSeries', + 'DateSeries', + 'DaysInDSinceSeries', + 'TemperaturesInKMatrix'], + 'unit': {'ucum_code': 'K'}} }) + + +# Model rebuild +# see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model +Container.model_rebuild() +TemperatureDataset.model_rebuild() +LatitudeInDegSeries.model_rebuild() +LongitudeInDegSeries.model_rebuild() +DateSeries.model_rebuild() +DaysInDSinceSeries.model_rebuild() +TemperaturesInKMatrix.model_rebuild() + From f1754fb051672097db15da25a5018fd1820cf6ef Mon Sep 17 00:00:00 2001 From: rly Date: Fri, 5 Jul 2024 12:11:13 -0700 Subject: [PATCH 04/38] Temp workaround for multivalued annotation value --- tests/input/temperature_schema.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/input/temperature_schema.yaml b/tests/input/temperature_schema.yaml index 7b83c58..e56bc79 100644 --- a/tests/input/temperature_schema.yaml +++ b/tests/input/temperature_schema.yaml @@ -71,9 +71,9 @@ classes: # it does not make sense to put `labeled_by` on `TemperatureMatrix` because the index slots are only # accessible from this DataArray class. # TODO uncomment this once it is supported by the metamodel - annotations: - labeled_by: - " + annotations: + labeled_by: + value: - alias: lat label_slot: latitude_in_deg labeled_dimensions: [0, 1] @@ -86,7 +86,6 @@ classes: - alias: day label_slot: day_in_d labeled_dimensions: [2] - " LatitudeInDegSeries: description: A 2D array whose values represent latitude From 3bf80a1133ea263cf8f82b64882e90d19682feba Mon Sep 17 00:00:00 2001 From: rly Date: Fri, 5 Jul 2024 12:11:57 -0700 Subject: [PATCH 05/38] Use pydantic 2 in classes --- tests/array_classes.py | 284 ------------------------------------- tests/array_classes_lol.py | 147 ++++++++----------- 2 files changed, 63 insertions(+), 368 deletions(-) delete mode 100644 tests/array_classes.py diff --git a/tests/array_classes.py b/tests/array_classes.py deleted file mode 100644 index a022616..0000000 --- a/tests/array_classes.py +++ /dev/null @@ -1,284 +0,0 @@ -from __future__ import annotations -from datetime import ( - datetime, - date -) -from decimal import Decimal -from enum import Enum -import re -import sys -from pydantic.version import VERSION as PYDANTIC_VERSION -from typing import ( - Any, - ClassVar, - List, - Literal, - Dict, - Optional, - Union, - Generic, - Iterable, - TypeVar, - get_args -) -if sys.version_info.minor > 8: - from typing import Annotated -else: - from typing_extensions import Annotated - -from pydantic import GetCoreSchemaHandler -from pydantic_core import ( - CoreSchema, - core_schema -) -if int(PYDANTIC_VERSION[0])>=2: - from pydantic import ( - BaseModel, - ConfigDict, - Field, - RootModel, - field_validator - ) -else: - from pydantic import ( - BaseModel, - Field, - validator - ) - -from pydantic import conlist -metamodel_version = "None" -version = "None" - - -class ConfiguredBaseModel(BaseModel): - model_config = ConfigDict( - validate_assignment = True, - validate_default = True, - extra = "forbid", - arbitrary_types_allowed = True, - use_enum_values = True, - strict = False, - ) - pass - - - - -class LinkMLMeta(RootModel): - root: Dict[str, Any] = {} - model_config = ConfigDict(frozen=True) - - def __getattr__(self, key:str): - return getattr(self.root, key) - - def __getitem__(self, key:str): - return self.root[key] - - def __setitem__(self, key:str, value): - self.root[key] = value - - - -_T = TypeVar("_T") - -_RecursiveListType = Iterable[Union[_T, Iterable["_RecursiveListType"]]] - -class AnyShapeArrayType(Generic[_T]): - @classmethod - def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema: - # double-nested parameterized types here - # source_type: List[Union[T,List[...]]] - item_type = Any if get_args(get_args(source_type)[0])[0] is _T else get_args(get_args(source_type)[0])[0] - - item_schema = handler.generate_schema(item_type) - if item_schema.get("type", "any") != "any": - item_schema["strict"] = True - - if item_type is Any: - # Before python 3.11, `Any` type was a special object without a __name__ - item_name = "Any" - else: - item_name = item_type.__name__ - - array_ref = f"any-shape-array-{item_name}" - - schema = core_schema.definitions_schema( - core_schema.list_schema(core_schema.definition_reference_schema(array_ref)), - [ - core_schema.union_schema( - [ - core_schema.list_schema(core_schema.definition_reference_schema(array_ref)), - item_schema, - ], - ref=array_ref, - ) - ], - ) - - return schema - - -AnyShapeArray = Annotated[_RecursiveListType, AnyShapeArrayType] -linkml_meta = LinkMLMeta({'default_prefix': 'https://example.org/arrays/', - 'description': 'Example LinkML schema to demonstrate a 3D DataArray of ' - 'temperature values with labeled axes\n' - 'using classes containing arrays for the axes and data instead ' - 'of using array slots/attributes.\n' - 'Creating separate types for the array slots enables reuse and ' - 'extension.', - 'id': 'https://example.org/arrays', - 'name': 'arrays-temperature-example-2'} ) - - -class Container(ConfiguredBaseModel): - """ - A container for a temperature dataset - """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays', 'tree_root': True}) - - name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', - 'domain_of': ['Container', - 'TemperatureDataset', - 'LatitudeInDegSeries', - 'LongitudeInDegSeries']} }) - temperature_dataset: TemperatureDataset = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'temperature_dataset', 'domain_of': ['Container']} }) - latitude_series: LatitudeInDegSeries = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'latitude_series', 'domain_of': ['Container']} }) - longitude_series: LongitudeInDegSeries = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'longitude_series', 'domain_of': ['Container']} }) - - -class TemperatureDataset(ConfiguredBaseModel): - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays', - 'implements': ['linkml:DataArray'], - 'tree_root': True}) - - name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', - 'domain_of': ['Container', - 'TemperatureDataset', - 'LatitudeInDegSeries', - 'LongitudeInDegSeries']} }) - latitude_in_deg: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'latitude_in_deg', 'domain_of': ['TemperatureDataset']} }) - longitude_in_deg: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'longitude_in_deg', 'domain_of': ['TemperatureDataset']} }) - date: DateSeries = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'date', 'domain_of': ['TemperatureDataset']} }) - day_in_d: Optional[DaysInDSinceSeries] = Field(None, json_schema_extra = { "linkml_meta": {'alias': 'day_in_d', 'domain_of': ['TemperatureDataset']} }) - temperatures_in_K: AnyShapeArray[TemperaturesInKMatrix] = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'temperatures_in_K', - 'array': {'annotations': {'labeled_by': {'tag': 'labeled_by', - 'value': ' - alias: lat label_slot: ' - 'latitude_in_deg ' - 'labeled_dimensions: [0, 1] ' - '- alias: lon label_slot: ' - 'longitude_in_deg ' - 'labeled_dimensions: [0, 1] ' - '- alias: date label_slot: ' - 'date labeled_dimensions: ' - '[2] - alias: day ' - 'label_slot: day_in_d ' - 'labeled_dimensions: ' - '[2] '}}}, - 'domain_of': ['TemperatureDataset']} }) - - -class LatitudeInDegSeries(ConfiguredBaseModel): - """ - A 2D array whose values represent latitude - """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) - - name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', - 'domain_of': ['Container', - 'TemperatureDataset', - 'LatitudeInDegSeries', - 'LongitudeInDegSeries']} }) - values: List[List[float]] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', - 'array': {'exact_number_dimensions': 2}, - 'domain_of': ['LatitudeInDegSeries', - 'LongitudeInDegSeries', - 'DateSeries', - 'DaysInDSinceSeries', - 'TemperaturesInKMatrix'], - 'unit': {'ucum_code': 'deg'}} }) - - -class LongitudeInDegSeries(ConfiguredBaseModel): - """ - A 2D array whose values represent longitude - """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) - - name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', - 'domain_of': ['Container', - 'TemperatureDataset', - 'LatitudeInDegSeries', - 'LongitudeInDegSeries']} }) - values: List[List[float]] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', - 'array': {'exact_number_dimensions': 2}, - 'domain_of': ['LatitudeInDegSeries', - 'LongitudeInDegSeries', - 'DateSeries', - 'DaysInDSinceSeries', - 'TemperaturesInKMatrix'], - 'unit': {'ucum_code': 'deg'}} }) - - -class DateSeries(ConfiguredBaseModel): - """ - A 1D series of dates - """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) - - values: List[str] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', - 'array': {'exact_number_dimensions': 1}, - 'domain_of': ['LatitudeInDegSeries', - 'LongitudeInDegSeries', - 'DateSeries', - 'DaysInDSinceSeries', - 'TemperaturesInKMatrix']} }) - - -class DaysInDSinceSeries(ConfiguredBaseModel): - """ - A 1D series whose values represent the number of days since a reference date - """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) - - values: List[int] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', - 'array': {'exact_number_dimensions': 1}, - 'domain_of': ['LatitudeInDegSeries', - 'LongitudeInDegSeries', - 'DateSeries', - 'DaysInDSinceSeries', - 'TemperaturesInKMatrix'], - 'unit': {'ucum_code': 'd'}} }) - reference_date: str = Field(..., description="""The reference date for the `day_in_d` values""", json_schema_extra = { "linkml_meta": {'alias': 'reference_date', 'domain_of': ['DaysInDSinceSeries']} }) - - -class TemperaturesInKMatrix(ConfiguredBaseModel): - """ - A 3D array of temperatures - """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) - - conversion_factor: Optional[float] = Field(None, description="""A conversion factor to apply to the temperature values""", json_schema_extra = { "linkml_meta": {'alias': 'conversion_factor', - 'domain_of': ['TemperaturesInKMatrix'], - 'unit': {'ucum_code': 'K'}} }) - values: List[List[List[float]]] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', - 'array': {'dimensions': [{'alias': 'x'}, {'alias': 'y'}, {'alias': 'date'}], - 'exact_number_dimensions': 3}, - 'domain_of': ['LatitudeInDegSeries', - 'LongitudeInDegSeries', - 'DateSeries', - 'DaysInDSinceSeries', - 'TemperaturesInKMatrix'], - 'unit': {'ucum_code': 'K'}} }) - - -# Model rebuild -# see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model -Container.model_rebuild() -TemperatureDataset.model_rebuild() -LatitudeInDegSeries.model_rebuild() -LongitudeInDegSeries.model_rebuild() -DateSeries.model_rebuild() -DaysInDSinceSeries.model_rebuild() -TemperaturesInKMatrix.model_rebuild() - diff --git a/tests/array_classes_lol.py b/tests/array_classes_lol.py index f3fcd03..47b1d36 100644 --- a/tests/array_classes_lol.py +++ b/tests/array_classes_lol.py @@ -37,37 +37,35 @@ version = "None" -class WeakRefShimBaseModel(BaseModel): - __slots__ = '__weakref__' - -class ConfiguredBaseModel(WeakRefShimBaseModel, - validate_assignment = True, - validate_all = True, - underscore_attrs_are_private = True, - extra = "forbid", - arbitrary_types_allowed = True, - use_enum_values = True): +class ConfiguredBaseModel(BaseModel): + model_config = ConfigDict( + validate_assignment = True, + validate_default = True, + extra = "forbid", + arbitrary_types_allowed = True, + use_enum_values = True, + strict = False, + ) pass -class LinkMLMeta(BaseModel): - __root__: Dict[str, Any] = {} +class LinkMLMeta(RootModel): + root: Dict[str, Any] = {} + model_config = ConfigDict(frozen=True) def __getattr__(self, key:str): - return getattr(self.__root__, key) + return getattr(self.root, key) def __getitem__(self, key:str): - return self.__root__[key] + return self.root[key] def __setitem__(self, key:str, value): - self.__root__[key] = value + self.root[key] = value - class Config: - allow_mutation = False -linkml_meta = LinkMLMeta(__root__={'default_prefix': 'https://example.org/arrays/', +linkml_meta = LinkMLMeta({'default_prefix': 'https://example.org/arrays/', 'description': 'Example LinkML schema to demonstrate a 3D DataArray of ' 'temperature values with labeled axes\n' 'using classes containing arrays for the axes and data instead ' @@ -82,137 +80,119 @@ class Container(ConfiguredBaseModel): """ A container for a temperature dataset """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta(__root__={'from_schema': 'https://example.org/arrays', 'tree_root': True}) + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays', 'tree_root': True}) - name: str = Field(..., linkml_meta = {'alias': 'name', + name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', 'domain_of': ['Container', 'TemperatureDataset', 'LatitudeInDegSeries', - 'LongitudeInDegSeries']} -) - temperature_dataset: TemperatureDataset = Field(..., linkml_meta = {'alias': 'temperature_dataset', 'domain_of': ['Container']} -) - latitude_series: LatitudeInDegSeries = Field(..., linkml_meta = {'alias': 'latitude_series', 'domain_of': ['Container']} -) - longitude_series: LongitudeInDegSeries = Field(..., linkml_meta = {'alias': 'longitude_series', 'domain_of': ['Container']} -) + 'LongitudeInDegSeries']} }) + temperature_dataset: TemperatureDataset = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'temperature_dataset', 'domain_of': ['Container']} }) + latitude_series: LatitudeInDegSeries = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'latitude_series', 'domain_of': ['Container']} }) + longitude_series: LongitudeInDegSeries = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'longitude_series', 'domain_of': ['Container']} }) class TemperatureDataset(ConfiguredBaseModel): - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta(__root__={'from_schema': 'https://example.org/arrays', + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays', 'implements': ['linkml:DataArray'], 'tree_root': True}) - name: str = Field(..., linkml_meta = {'alias': 'name', + name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', 'domain_of': ['Container', 'TemperatureDataset', 'LatitudeInDegSeries', - 'LongitudeInDegSeries']} -) - latitude_in_deg: str = Field(..., linkml_meta = {'alias': 'latitude_in_deg', 'domain_of': ['TemperatureDataset']} -) - longitude_in_deg: str = Field(..., linkml_meta = {'alias': 'longitude_in_deg', 'domain_of': ['TemperatureDataset']} -) - date: DateSeries = Field(..., linkml_meta = {'alias': 'date', 'domain_of': ['TemperatureDataset']} -) - day_in_d: Optional[DaysInDSinceSeries] = Field(None, linkml_meta = {'alias': 'day_in_d', 'domain_of': ['TemperatureDataset']} -) - temperatures_in_K: TemperaturesInKMatrix = Field(..., linkml_meta = {'alias': 'temperatures_in_K', 'domain_of': ['TemperatureDataset']} -) + 'LongitudeInDegSeries']} }) + latitude_in_deg: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'latitude_in_deg', 'domain_of': ['TemperatureDataset']} }) + longitude_in_deg: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'longitude_in_deg', 'domain_of': ['TemperatureDataset']} }) + date: DateSeries = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'date', 'domain_of': ['TemperatureDataset']} }) + day_in_d: Optional[DaysInDSinceSeries] = Field(None, json_schema_extra = { "linkml_meta": {'alias': 'day_in_d', 'domain_of': ['TemperatureDataset']} }) + temperatures_in_K: TemperaturesInKMatrix = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'temperatures_in_K', 'domain_of': ['TemperatureDataset']} }) class LatitudeInDegSeries(ConfiguredBaseModel): """ A 2D array whose values represent latitude """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta(__root__={'from_schema': 'https://example.org/arrays'}) + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) - name: str = Field(..., linkml_meta = {'alias': 'name', + name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', 'domain_of': ['Container', 'TemperatureDataset', 'LatitudeInDegSeries', - 'LongitudeInDegSeries']} -) - values: List[List[float]] = Field(default_factory=list, linkml_meta = {'alias': 'values', + 'LongitudeInDegSeries']} }) + values: List[List[float]] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', 'array': {'exact_number_dimensions': 2}, 'domain_of': ['LatitudeInDegSeries', 'LongitudeInDegSeries', 'DateSeries', 'DaysInDSinceSeries', 'TemperaturesInKMatrix'], - 'unit': {'ucum_code': 'deg'}} -) + 'unit': {'ucum_code': 'deg'}} }) class LongitudeInDegSeries(ConfiguredBaseModel): """ A 2D array whose values represent longitude """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta(__root__={'from_schema': 'https://example.org/arrays'}) + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) - name: str = Field(..., linkml_meta = {'alias': 'name', + name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', 'domain_of': ['Container', 'TemperatureDataset', 'LatitudeInDegSeries', - 'LongitudeInDegSeries']} -) - values: List[List[float]] = Field(default_factory=list, linkml_meta = {'alias': 'values', + 'LongitudeInDegSeries']} }) + values: List[List[float]] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', 'array': {'exact_number_dimensions': 2}, 'domain_of': ['LatitudeInDegSeries', 'LongitudeInDegSeries', 'DateSeries', 'DaysInDSinceSeries', 'TemperaturesInKMatrix'], - 'unit': {'ucum_code': 'deg'}} -) + 'unit': {'ucum_code': 'deg'}} }) class DateSeries(ConfiguredBaseModel): """ A 1D series of dates """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta(__root__={'from_schema': 'https://example.org/arrays'}) + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) - values: List[str] = Field(default_factory=list, linkml_meta = {'alias': 'values', + values: List[str] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', 'array': {'exact_number_dimensions': 1}, 'domain_of': ['LatitudeInDegSeries', 'LongitudeInDegSeries', 'DateSeries', 'DaysInDSinceSeries', - 'TemperaturesInKMatrix']} -) + 'TemperaturesInKMatrix']} }) class DaysInDSinceSeries(ConfiguredBaseModel): """ A 1D series whose values represent the number of days since a reference date """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta(__root__={'from_schema': 'https://example.org/arrays'}) + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) - values: List[int] = Field(default_factory=list, linkml_meta = {'alias': 'values', + values: List[int] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', 'array': {'exact_number_dimensions': 1}, 'domain_of': ['LatitudeInDegSeries', 'LongitudeInDegSeries', 'DateSeries', 'DaysInDSinceSeries', 'TemperaturesInKMatrix'], - 'unit': {'ucum_code': 'd'}} -) - reference_date: str = Field(..., description="""The reference date for the `day_in_d` values""", linkml_meta = {'alias': 'reference_date', 'domain_of': ['DaysInDSinceSeries']} -) + 'unit': {'ucum_code': 'd'}} }) + reference_date: str = Field(..., description="""The reference date for the `day_in_d` values""", json_schema_extra = { "linkml_meta": {'alias': 'reference_date', 'domain_of': ['DaysInDSinceSeries']} }) class TemperaturesInKMatrix(ConfiguredBaseModel): """ A 3D array of temperatures """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta(__root__={'from_schema': 'https://example.org/arrays'}) + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) - conversion_factor: Optional[float] = Field(None, description="""A conversion factor to apply to the temperature values""", linkml_meta = {'alias': 'conversion_factor', + conversion_factor: Optional[float] = Field(None, description="""A conversion factor to apply to the temperature values""", json_schema_extra = { "linkml_meta": {'alias': 'conversion_factor', 'domain_of': ['TemperaturesInKMatrix'], - 'unit': {'ucum_code': 'K'}} -) - values: List[List[List[float]]] = Field(default_factory=list, linkml_meta = {'alias': 'values', + 'unit': {'ucum_code': 'K'}} }) + values: List[List[List[float]]] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', 'array': {'dimensions': [{'alias': 'x'}, {'alias': 'y'}, {'alias': 'date'}], 'exact_number_dimensions': 3}, 'domain_of': ['LatitudeInDegSeries', @@ -220,17 +200,16 @@ class TemperaturesInKMatrix(ConfiguredBaseModel): 'DateSeries', 'DaysInDSinceSeries', 'TemperaturesInKMatrix'], - 'unit': {'ucum_code': 'K'}} -) - - -# Update forward refs -# see https://pydantic-docs.helpmanual.io/usage/postponed_annotations/ -Container.update_forward_refs() -TemperatureDataset.update_forward_refs() -LatitudeInDegSeries.update_forward_refs() -LongitudeInDegSeries.update_forward_refs() -DateSeries.update_forward_refs() -DaysInDSinceSeries.update_forward_refs() -TemperaturesInKMatrix.update_forward_refs() + 'unit': {'ucum_code': 'K'}} }) + + +# Model rebuild +# see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model +Container.model_rebuild() +TemperatureDataset.model_rebuild() +LatitudeInDegSeries.model_rebuild() +LongitudeInDegSeries.model_rebuild() +DateSeries.model_rebuild() +DaysInDSinceSeries.model_rebuild() +TemperaturesInKMatrix.model_rebuild() From fc77a6da4f024822fb8135936be805192373694d Mon Sep 17 00:00:00 2001 From: rly Date: Fri, 5 Jul 2024 14:49:41 -0700 Subject: [PATCH 06/38] Update tests, dumpers, loaders --- .gitignore | 3 +- .../dumpers/yaml_array_file_dumper.py | 94 ++++ src/linkml_arrays/dumpers/yaml_hdf5_dumper.py | 78 +--- .../dumpers/yaml_numpy_dumper.py | 85 +--- src/linkml_arrays/loaders/yaml_hdf5_loader.py | 4 +- src/linkml_arrays/loaders/yaml_loader.py | 4 +- .../loaders/yaml_numpy_loader.py | 8 +- tests/array_classes_lol.py | 401 ++++++++++++------ tests/input/container_npy_dumped.yaml | 32 -- .../{container.yaml => container_yaml.yaml} | 28 +- tests/input/container_yaml_hdf5.yaml | 19 + tests/input/container_yaml_numpy.yaml | 19 + .../temperature_dataset_inlined_def_yaml.yaml | 23 + tests/input/temperature_dataset_old_yaml.yaml | 23 + tests/input/temperature_dataset_yaml.yaml | 46 +- .../input/temperature_schema_inlined_def.yaml | 96 +++++ ...taset.yaml => temperature_schema_old.yaml} | 0 tests/test_dumpers/test_dumpers.py | 229 +++++----- tests/test_loaders/test_loaders.py | 204 ++++----- 19 files changed, 799 insertions(+), 597 deletions(-) create mode 100644 src/linkml_arrays/dumpers/yaml_array_file_dumper.py delete mode 100644 tests/input/container_npy_dumped.yaml rename tests/input/{container.yaml => container_yaml.yaml} (100%) create mode 100644 tests/input/container_yaml_hdf5.yaml create mode 100644 tests/input/container_yaml_numpy.yaml create mode 100644 tests/input/temperature_dataset_inlined_def_yaml.yaml create mode 100644 tests/input/temperature_dataset_old_yaml.yaml create mode 100644 tests/input/temperature_schema_inlined_def.yaml rename tests/input/{temperature_dataset.yaml => temperature_schema_old.yaml} (100%) diff --git a/.gitignore b/.gitignore index 9193982..3f66cf8 100644 --- a/.gitignore +++ b/.gitignore @@ -129,5 +129,4 @@ dmypy.json .pyre/ .DS_Store -/my_temperature.zarr -/my_temperature.h5 +out \ No newline at end of file diff --git a/src/linkml_arrays/dumpers/yaml_array_file_dumper.py b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py new file mode 100644 index 0000000..0dff67b --- /dev/null +++ b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py @@ -0,0 +1,94 @@ +"""Base class for dumpling a LinkML model to a YAML file with paths to NumPy files.""" + +from typing import Union, List +from pathlib import Path +import os +from abc import ABCMeta, abstractmethod +from collections.abc import Callable + +import numpy as np +import yaml +from linkml_runtime import SchemaView +from linkml_runtime.dumpers.dumper_root import Dumper +from linkml_runtime.utils.yamlutils import YAMLRoot +from pydantic import BaseModel + + +def _iterate_element( + element: Union[YAMLRoot, BaseModel], schemaview: SchemaView, output_dir: Path, + write_array: Callable, parent_identifier=None, inlined_name=None +): + """Recursively iterate through the elements of a LinkML model and save them. + + Returns a dictionary with the same structure as the input element, but with the slots + that implement "linkml:elements" (arrays) are written to HDF5 files and the paths to these + files are returned in the dictionary. Each array is written to an HDF5 dataset at path + "/data" in a new HDF5 file. + + Raises: + ValueError: If the class requires an identifier and it is not provided. + """ + # get the type of the element + element_type = type(element).__name__ + + # ask schemaview whether it has a class by this name + found_class = schemaview.get_class(element_type) + + id_slot = schemaview.get_identifier_slot(found_class.name) + if id_slot is not None: + id_value = getattr(element, id_slot.name) + else: + id_value = None + + ret_dict = dict() + for k, v in vars(element).items(): + found_slot = schemaview.induced_slot(k, element_type) + if found_slot.array: + if id_slot is None and parent_identifier is None: + raise ValueError("The class requires an identifier.") + + # determine the output file name without the suffix + if id_slot is not None: + output_file_name = f"{id_value}.{found_slot.name}" + elif inlined_name is not None: + output_file_name = f"{parent_identifier}.{inlined_name}.{found_slot.name}" + elif parent_identifier is not None: + output_file_name = f"{parent_identifier}.{found_slot.name}" + else: + output_file_name = f"{found_slot.name}" + + # if output_dir is absolute, make it relative to current working directory + # and create the directory if it does not exist + if output_dir.is_absolute(): + output_dir = Path(os.path.relpath(output_dir, start=os.getcwd())) + output_dir.mkdir(exist_ok=True) + output_file_path_no_suffix = output_dir / output_file_name + + # save the numpy array to file and write the file path to the dictionary + output_file_path = write_array(v, output_file_path_no_suffix) + ret_dict[k] = f"file:./{output_file_path}" + else: + if isinstance(v, BaseModel): + v2 = _iterate_element(v, schemaview, output_dir, write_array, id_value, inlined_name=found_slot.name) + ret_dict[k] = v2 + else: + ret_dict[k] = v + return ret_dict + + +class YamlArrayFileDumper(Dumper, metaclass=ABCMeta): + """Base dumper class for LinkML models to YAML files with paths to array files.""" + + def dumps(self, element: Union[YAMLRoot, BaseModel], schemaview: SchemaView, output_dir: Union[str, Path] = None, **kwargs) -> str: + """Return element formatted as a YAML string.""" + if output_dir is None: + output_dir = "." + input = _iterate_element(element, schemaview, Path(output_dir), self.write_array) + + return yaml.dump(input) + + @classmethod + @abstractmethod + def write_array(cls, array: Union[List, np.ndarray], output_file_path: Union[str, Path]): + """Write an array to a file.""" + raise NotImplementedError("Subclasses must implement this method.") \ No newline at end of file diff --git a/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py b/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py index 0d95fe8..d3ac0f1 100644 --- a/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py @@ -1,70 +1,24 @@ """Class for dumping a LinkML model to a YAML file with paths to HDF5 files.""" -from typing import Union - import h5py -import yaml -from linkml_runtime import SchemaView -from linkml_runtime.dumpers.dumper_root import Dumper -from linkml_runtime.utils.yamlutils import YAMLRoot -from pydantic import BaseModel - - -def _iterate_element( - element: Union[YAMLRoot, BaseModel], schemaview: SchemaView, parent_identifier=None -): - """Recursively iterate through the elements of a LinkML model and save them. - - Returns a dictionary with the same structure as the input element, but with the slots - that implement "linkml:elements" (arrays) are written to HDF5 files and the paths to these - files are returned in the dictionary. Each array is written to an HDF5 dataset at path - "/data" in a new HDF5 file. - - Raises: - ValueError: If the class requires an identifier and it is not provided. - """ - # get the type of the element - element_type = type(element).__name__ - - # ask schemaview whether it has a class by this name - found_class = schemaview.get_class(element_type) - - id_slot = schemaview.get_identifier_slot(found_class.name) - if id_slot is not None: - id_value = getattr(element, id_slot.name) - else: - id_value = None +import numpy as np +from pathlib import Path +from typing import Union, List - ret_dict = dict() - for k, v in vars(element).items(): - found_slot = schemaview.induced_slot(k, element_type) - if "linkml:elements" in found_slot.implements: - if id_slot is None and parent_identifier is None: - raise ValueError("The class requires an identifier.") - # save the numpy array to file - if parent_identifier is not None: - output_file_path = f"{parent_identifier}.{found_class.name}.{found_slot.name}.h5" - else: - output_file_path = f"{found_class.name}.{found_slot.name}.h5" - with h5py.File( - output_file_path, "w" - ) as f: # TODO do not assume that there is only one by this name - f.create_dataset("data", data=v) - ret_dict[k] = f"file:./{output_file_path}" # TODO make this nicer - else: - if isinstance(v, BaseModel): - v2 = _iterate_element(v, schemaview, id_value) - ret_dict[k] = v2 - else: - ret_dict[k] = v - return ret_dict +from .yaml_array_file_dumper import YamlArrayFileDumper -class YamlHdf5Dumper(Dumper): - """Class for dumping a LinkML model to a YAML file with paths to HDF5 files.""" +class YamlHdf5Dumper(YamlArrayFileDumper): + """Dumper class for LinkML models to YAML files with paths to NumPy files.""" - def dumps(self, element: Union[YAMLRoot, BaseModel], schemaview: SchemaView, **kwargs) -> str: - """Return element formatted as a YAML string.""" - input = _iterate_element(element, schemaview) + FILE_SUFFIX = ".h5" # used in parent class - return yaml.dump(input) + @classmethod + def write_array(cls, array: Union[List, np.ndarray], output_file_path_no_suffix: Union[str, Path]): + """Write an array to a file.""" + # TODO do not assume that there is only one by this name + # add suffix to the file name + output_file_path = output_file_path_no_suffix.parent / (output_file_path_no_suffix.name + cls.FILE_SUFFIX) + with h5py.File(output_file_path, "w") as f: + f.create_dataset("data", data=array) + return output_file_path diff --git a/src/linkml_arrays/dumpers/yaml_numpy_dumper.py b/src/linkml_arrays/dumpers/yaml_numpy_dumper.py index 25de3b0..509419e 100644 --- a/src/linkml_arrays/dumpers/yaml_numpy_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_numpy_dumper.py @@ -1,78 +1,23 @@ """Class for dumpling a LinkML model to a YAML file with paths to NumPy files.""" -from typing import Union -from pathlib import Path -import os - import numpy as np -import yaml -from linkml_runtime import SchemaView -from linkml_runtime.dumpers.dumper_root import Dumper -from linkml_runtime.utils.yamlutils import YAMLRoot -from pydantic import BaseModel - - -def _iterate_element( - element: Union[YAMLRoot, BaseModel], schemaview: SchemaView, output_dir: Path, parent_identifier=None, inlined_name=None -): - """Recursively iterate through the elements of a LinkML model and save them. - - Returns a dictionary with the same structure as the input element, but with the slots - that implement "linkml:elements" (arrays) are written to HDF5 files and the paths to these - files are returned in the dictionary. Each array is written to an HDF5 dataset at path - "/data" in a new HDF5 file. - - Raises: - ValueError: If the class requires an identifier and it is not provided. - """ - # get the type of the element - element_type = type(element).__name__ - - # ask schemaview whether it has a class by this name - found_class = schemaview.get_class(element_type) - - id_slot = schemaview.get_identifier_slot(found_class.name) - if id_slot is not None: - id_value = getattr(element, id_slot.name) - else: - id_value = None +from pathlib import Path +from typing import Union, List - ret_dict = dict() - for k, v in vars(element).items(): - found_slot = schemaview.induced_slot(k, element_type) - if found_slot.array: - if id_slot is None and parent_identifier is None: - raise ValueError("The class requires an identifier.") - # save the numpy array to file - if id_slot is not None: - output_file_path = f"{id_value}.{found_slot.name}.npy" - elif inlined_name is not None: - output_file_path = f"{parent_identifier}.{inlined_name}.{found_slot.name}.npy" - elif parent_identifier is not None: - output_file_path = f"{parent_identifier}.{found_slot.name}.npy" - else: - output_file_path = f"{found_slot.name}.npy" - arr = np.array(v) - output_dir.mkdir(exist_ok=True) - output_file_path = output_dir / output_file_path - np.save(output_file_path, arr) # TODO do not assume that there is only one by this name - ret_dict[k] = f"file:{output_file_path}" # TODO make this nicer - else: - if isinstance(v, BaseModel): - v2 = _iterate_element(v, schemaview, output_dir, id_value, inlined_name=found_slot.name) - ret_dict[k] = v2 - else: - ret_dict[k] = v - return ret_dict +from .yaml_array_file_dumper import YamlArrayFileDumper -class YamlNumpyDumper(Dumper): +class YamlNumpyDumper(YamlArrayFileDumper): """Dumper class for LinkML models to YAML files with paths to NumPy files.""" - def dumps(self, element: Union[YAMLRoot, BaseModel], schemaview: SchemaView, output_dir: Union[str, Path] = None, **kwargs) -> str: - """Return element formatted as a YAML string.""" - if output_dir is None: - output_dir = "." - input = _iterate_element(element, schemaview, Path(output_dir)) - - return yaml.dump(input) + FILE_SUFFIX = ".npy" # used in parent class + + @classmethod + def write_array(cls, array: Union[List, np.ndarray], output_file_path_no_suffix: Union[str, Path]): + """Write an array to a file.""" + # TODO do not assume that there is only one by this name + # add suffix to the file name + output_file_path = output_file_path_no_suffix.parent / (output_file_path_no_suffix.name + cls.FILE_SUFFIX) + arr = np.array(array) + np.save(output_file_path, arr) + return output_file_path diff --git a/src/linkml_arrays/loaders/yaml_hdf5_loader.py b/src/linkml_arrays/loaders/yaml_hdf5_loader.py index 771600f..e2b8289 100644 --- a/src/linkml_arrays/loaders/yaml_hdf5_loader.py +++ b/src/linkml_arrays/loaders/yaml_hdf5_loader.py @@ -21,8 +21,8 @@ def _iterate_element( ret_dict = dict() for k, v in input_dict.items(): found_slot = schemaview.induced_slot(k, element_type.name) - if "linkml:elements" in found_slot.implements: - array_file_path = v.replace("file:./", "") + if found_slot.array: + array_file_path = v.replace("file:", "") with h5py.File(array_file_path, "r") as f: v = f["data"][()] # read all the values into memory TODO: support lazy loading elif isinstance(v, dict): diff --git a/src/linkml_arrays/loaders/yaml_loader.py b/src/linkml_arrays/loaders/yaml_loader.py index 6211ea8..a37ff87 100644 --- a/src/linkml_arrays/loaders/yaml_loader.py +++ b/src/linkml_arrays/loaders/yaml_loader.py @@ -21,9 +21,7 @@ def _iterate_element( ret_dict = dict() for k, v in input_dict.items(): found_slot = schemaview.induced_slot(k, element_type.name) - if "linkml:elements" in found_slot.implements: - v = np.asarray(v) - elif isinstance(v, dict): + if isinstance(v, dict): found_slot_range = schemaview.get_class(found_slot.range) v = _iterate_element(v, found_slot_range, schemaview) # else: do not transform v diff --git a/src/linkml_arrays/loaders/yaml_numpy_loader.py b/src/linkml_arrays/loaders/yaml_numpy_loader.py index 5b2bd63..a118ec1 100644 --- a/src/linkml_arrays/loaders/yaml_numpy_loader.py +++ b/src/linkml_arrays/loaders/yaml_numpy_loader.py @@ -11,9 +11,7 @@ from pydantic import BaseModel -def _iterate_element( - input_dict: dict, element_type: ClassDefinition, schemaview: SchemaView -) -> dict: +def _iterate_element(input_dict: dict, element_type: ClassDefinition, schemaview: SchemaView) -> dict: """Recursively iterate through the elements of a LinkML model and load them into a dict. Datasets are read into memory. @@ -21,8 +19,8 @@ def _iterate_element( ret_dict = dict() for k, v in input_dict.items(): found_slot = schemaview.induced_slot(k, element_type.name) - if "linkml:elements" in found_slot.implements: - array_file_path = v.replace("file:./", "") + if found_slot.array: + array_file_path = v.replace("file:", "") v = np.load(array_file_path) # TODO: support lazy loading elif isinstance(v, dict): found_slot_range = schemaview.get_class(found_slot.range) diff --git a/tests/array_classes_lol.py b/tests/array_classes_lol.py index 47b1d36..3b043a8 100644 --- a/tests/array_classes_lol.py +++ b/tests/array_classes_lol.py @@ -1,206 +1,334 @@ -from __future__ import annotations -from datetime import ( - datetime, - date -) -from decimal import Decimal -from enum import Enum +from __future__ import annotations +from datetime import datetime, date +from decimal import Decimal +from enum import Enum import re import sys -from typing import ( - Any, - ClassVar, - List, - Literal, - Dict, - Optional, - Union -) -from pydantic.version import VERSION as PYDANTIC_VERSION -if int(PYDANTIC_VERSION[0])>=2: - from pydantic import ( - BaseModel, - ConfigDict, - Field, - RootModel, - field_validator - ) +from typing import Any, ClassVar, List, Literal, Dict, Optional, Union +from pydantic.version import VERSION as PYDANTIC_VERSION + +if int(PYDANTIC_VERSION[0]) >= 2: + from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator else: - from pydantic import ( - BaseModel, - Field, - validator - ) + from pydantic import BaseModel, Field, validator + +from pydantic import conlist -from pydantic import conlist metamodel_version = "None" version = "None" class ConfiguredBaseModel(BaseModel): model_config = ConfigDict( - validate_assignment = True, - validate_default = True, - extra = "forbid", - arbitrary_types_allowed = True, - use_enum_values = True, - strict = False, + validate_assignment=True, + validate_default=True, + extra="forbid", + arbitrary_types_allowed=True, + use_enum_values=True, + strict=False, ) pass - - class LinkMLMeta(RootModel): root: Dict[str, Any] = {} model_config = ConfigDict(frozen=True) - def __getattr__(self, key:str): + def __getattr__(self, key: str): return getattr(self.root, key) - def __getitem__(self, key:str): + def __getitem__(self, key: str): return self.root[key] - def __setitem__(self, key:str, value): + def __setitem__(self, key: str, value): self.root[key] = value -linkml_meta = LinkMLMeta({'default_prefix': 'https://example.org/arrays/', - 'description': 'Example LinkML schema to demonstrate a 3D DataArray of ' - 'temperature values with labeled axes\n' - 'using classes containing arrays for the axes and data instead ' - 'of using array slots/attributes.\n' - 'Creating separate types for the array slots enables reuse and ' - 'extension.', - 'id': 'https://example.org/arrays', - 'name': 'arrays-temperature-example-2'} ) +linkml_meta = LinkMLMeta( + { + "default_prefix": "https://example.org/arrays/", + "description": "Example LinkML schema to demonstrate a 3D DataArray of " + "temperature values with labeled axes\n" + "using classes containing arrays for the axes and data instead " + "of using array slots/attributes.\n" + "Creating separate types for the array slots enables reuse and " + "extension.", + "id": "https://example.org/arrays", + "name": "arrays-temperature-example-2", + } +) class Container(ConfiguredBaseModel): """ A container for a temperature dataset """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays', 'tree_root': True}) - name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', - 'domain_of': ['Container', - 'TemperatureDataset', - 'LatitudeInDegSeries', - 'LongitudeInDegSeries']} }) - temperature_dataset: TemperatureDataset = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'temperature_dataset', 'domain_of': ['Container']} }) - latitude_series: LatitudeInDegSeries = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'latitude_series', 'domain_of': ['Container']} }) - longitude_series: LongitudeInDegSeries = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'longitude_series', 'domain_of': ['Container']} }) + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta( + {"from_schema": "https://example.org/arrays", "tree_root": True} + ) + + name: str = Field( + ..., + json_schema_extra={ + "linkml_meta": { + "alias": "name", + "domain_of": [ + "Container", + "TemperatureDataset", + "LatitudeInDegSeries", + "LongitudeInDegSeries", + ], + } + }, + ) + temperature_dataset: TemperatureDataset = Field( + ..., + json_schema_extra={ + "linkml_meta": {"alias": "temperature_dataset", "domain_of": ["Container"]} + }, + ) + latitude_series: LatitudeInDegSeries = Field( + ..., + json_schema_extra={"linkml_meta": {"alias": "latitude_series", "domain_of": ["Container"]}}, + ) + longitude_series: LongitudeInDegSeries = Field( + ..., + json_schema_extra={ + "linkml_meta": {"alias": "longitude_series", "domain_of": ["Container"]} + }, + ) class TemperatureDataset(ConfiguredBaseModel): - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays', - 'implements': ['linkml:DataArray'], - 'tree_root': True}) - - name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', - 'domain_of': ['Container', - 'TemperatureDataset', - 'LatitudeInDegSeries', - 'LongitudeInDegSeries']} }) - latitude_in_deg: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'latitude_in_deg', 'domain_of': ['TemperatureDataset']} }) - longitude_in_deg: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'longitude_in_deg', 'domain_of': ['TemperatureDataset']} }) - date: DateSeries = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'date', 'domain_of': ['TemperatureDataset']} }) - day_in_d: Optional[DaysInDSinceSeries] = Field(None, json_schema_extra = { "linkml_meta": {'alias': 'day_in_d', 'domain_of': ['TemperatureDataset']} }) - temperatures_in_K: TemperaturesInKMatrix = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'temperatures_in_K', 'domain_of': ['TemperatureDataset']} }) + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta( + { + "from_schema": "https://example.org/arrays", + "implements": ["linkml:DataArray"], + "tree_root": True, + } + ) + + name: str = Field( + ..., + json_schema_extra={ + "linkml_meta": { + "alias": "name", + "domain_of": [ + "Container", + "TemperatureDataset", + "LatitudeInDegSeries", + "LongitudeInDegSeries", + ], + } + }, + ) + latitude_in_deg: str = Field( + ..., + json_schema_extra={ + "linkml_meta": {"alias": "latitude_in_deg", "domain_of": ["TemperatureDataset"]} + }, + ) + longitude_in_deg: str = Field( + ..., + json_schema_extra={ + "linkml_meta": {"alias": "longitude_in_deg", "domain_of": ["TemperatureDataset"]} + }, + ) + date: DateSeries = Field( + ..., + json_schema_extra={"linkml_meta": {"alias": "date", "domain_of": ["TemperatureDataset"]}}, + ) + day_in_d: Optional[DaysInDSinceSeries] = Field( + None, + json_schema_extra={ + "linkml_meta": {"alias": "day_in_d", "domain_of": ["TemperatureDataset"]} + }, + ) + temperatures_in_K: TemperaturesInKMatrix = Field( + ..., + json_schema_extra={ + "linkml_meta": {"alias": "temperatures_in_K", "domain_of": ["TemperatureDataset"]} + }, + ) class LatitudeInDegSeries(ConfiguredBaseModel): """ A 2D array whose values represent latitude """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) - - name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', - 'domain_of': ['Container', - 'TemperatureDataset', - 'LatitudeInDegSeries', - 'LongitudeInDegSeries']} }) - values: List[List[float]] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', - 'array': {'exact_number_dimensions': 2}, - 'domain_of': ['LatitudeInDegSeries', - 'LongitudeInDegSeries', - 'DateSeries', - 'DaysInDSinceSeries', - 'TemperaturesInKMatrix'], - 'unit': {'ucum_code': 'deg'}} }) + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "https://example.org/arrays"}) + + name: str = Field( + ..., + json_schema_extra={ + "linkml_meta": { + "alias": "name", + "domain_of": [ + "Container", + "TemperatureDataset", + "LatitudeInDegSeries", + "LongitudeInDegSeries", + ], + } + }, + ) + values: List[List[float]] = Field( + default_factory=list, + json_schema_extra={ + "linkml_meta": { + "alias": "values", + "array": {"exact_number_dimensions": 2}, + "domain_of": [ + "LatitudeInDegSeries", + "LongitudeInDegSeries", + "DateSeries", + "DaysInDSinceSeries", + "TemperaturesInKMatrix", + ], + "unit": {"ucum_code": "deg"}, + } + }, + ) class LongitudeInDegSeries(ConfiguredBaseModel): """ A 2D array whose values represent longitude """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) - - name: str = Field(..., json_schema_extra = { "linkml_meta": {'alias': 'name', - 'domain_of': ['Container', - 'TemperatureDataset', - 'LatitudeInDegSeries', - 'LongitudeInDegSeries']} }) - values: List[List[float]] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', - 'array': {'exact_number_dimensions': 2}, - 'domain_of': ['LatitudeInDegSeries', - 'LongitudeInDegSeries', - 'DateSeries', - 'DaysInDSinceSeries', - 'TemperaturesInKMatrix'], - 'unit': {'ucum_code': 'deg'}} }) + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "https://example.org/arrays"}) + + name: str = Field( + ..., + json_schema_extra={ + "linkml_meta": { + "alias": "name", + "domain_of": [ + "Container", + "TemperatureDataset", + "LatitudeInDegSeries", + "LongitudeInDegSeries", + ], + } + }, + ) + values: List[List[float]] = Field( + default_factory=list, + json_schema_extra={ + "linkml_meta": { + "alias": "values", + "array": {"exact_number_dimensions": 2}, + "domain_of": [ + "LatitudeInDegSeries", + "LongitudeInDegSeries", + "DateSeries", + "DaysInDSinceSeries", + "TemperaturesInKMatrix", + ], + "unit": {"ucum_code": "deg"}, + } + }, + ) class DateSeries(ConfiguredBaseModel): """ A 1D series of dates """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) - values: List[str] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', - 'array': {'exact_number_dimensions': 1}, - 'domain_of': ['LatitudeInDegSeries', - 'LongitudeInDegSeries', - 'DateSeries', - 'DaysInDSinceSeries', - 'TemperaturesInKMatrix']} }) + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "https://example.org/arrays"}) + + values: List[str] = Field( + default_factory=list, + json_schema_extra={ + "linkml_meta": { + "alias": "values", + "array": {"exact_number_dimensions": 1}, + "domain_of": [ + "LatitudeInDegSeries", + "LongitudeInDegSeries", + "DateSeries", + "DaysInDSinceSeries", + "TemperaturesInKMatrix", + ], + } + }, + ) class DaysInDSinceSeries(ConfiguredBaseModel): """ A 1D series whose values represent the number of days since a reference date """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) - values: List[int] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', - 'array': {'exact_number_dimensions': 1}, - 'domain_of': ['LatitudeInDegSeries', - 'LongitudeInDegSeries', - 'DateSeries', - 'DaysInDSinceSeries', - 'TemperaturesInKMatrix'], - 'unit': {'ucum_code': 'd'}} }) - reference_date: str = Field(..., description="""The reference date for the `day_in_d` values""", json_schema_extra = { "linkml_meta": {'alias': 'reference_date', 'domain_of': ['DaysInDSinceSeries']} }) + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "https://example.org/arrays"}) + + values: List[int] = Field( + default_factory=list, + json_schema_extra={ + "linkml_meta": { + "alias": "values", + "array": {"exact_number_dimensions": 1}, + "domain_of": [ + "LatitudeInDegSeries", + "LongitudeInDegSeries", + "DateSeries", + "DaysInDSinceSeries", + "TemperaturesInKMatrix", + ], + "unit": {"ucum_code": "d"}, + } + }, + ) + reference_date: str = Field( + ..., + description="""The reference date for the `day_in_d` values""", + json_schema_extra={ + "linkml_meta": {"alias": "reference_date", "domain_of": ["DaysInDSinceSeries"]} + }, + ) class TemperaturesInKMatrix(ConfiguredBaseModel): """ A 3D array of temperatures """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://example.org/arrays'}) - - conversion_factor: Optional[float] = Field(None, description="""A conversion factor to apply to the temperature values""", json_schema_extra = { "linkml_meta": {'alias': 'conversion_factor', - 'domain_of': ['TemperaturesInKMatrix'], - 'unit': {'ucum_code': 'K'}} }) - values: List[List[List[float]]] = Field(default_factory=list, json_schema_extra = { "linkml_meta": {'alias': 'values', - 'array': {'dimensions': [{'alias': 'x'}, {'alias': 'y'}, {'alias': 'date'}], - 'exact_number_dimensions': 3}, - 'domain_of': ['LatitudeInDegSeries', - 'LongitudeInDegSeries', - 'DateSeries', - 'DaysInDSinceSeries', - 'TemperaturesInKMatrix'], - 'unit': {'ucum_code': 'K'}} }) + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "https://example.org/arrays"}) + + conversion_factor: Optional[float] = Field( + None, + description="""A conversion factor to apply to the temperature values""", + json_schema_extra={ + "linkml_meta": { + "alias": "conversion_factor", + "domain_of": ["TemperaturesInKMatrix"], + "unit": {"ucum_code": "K"}, + } + }, + ) + values: List[List[List[float]]] = Field( + default_factory=list, + json_schema_extra={ + "linkml_meta": { + "alias": "values", + "array": { + "dimensions": [{"alias": "x"}, {"alias": "y"}, {"alias": "date"}], + "exact_number_dimensions": 3, + }, + "domain_of": [ + "LatitudeInDegSeries", + "LongitudeInDegSeries", + "DateSeries", + "DaysInDSinceSeries", + "TemperaturesInKMatrix", + ], + "unit": {"ucum_code": "K"}, + } + }, + ) # Model rebuild @@ -212,4 +340,3 @@ class TemperaturesInKMatrix(ConfiguredBaseModel): DateSeries.model_rebuild() DaysInDSinceSeries.model_rebuild() TemperaturesInKMatrix.model_rebuild() - diff --git a/tests/input/container_npy_dumped.yaml b/tests/input/container_npy_dumped.yaml deleted file mode 100644 index e182a61..0000000 --- a/tests/input/container_npy_dumped.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: my_container -temperature_dataset: - name: my_temperature - latitude_in_deg: my_latitude - longitude_in_deg: my_longitude - temperatures_in_K: - conversion_factor: 1000 - # TODO revisit this - values: file:./tests/input/my_container.my_temperature.temperatures_in_K.values.npy - date: - values: - - "2020-01-01" - - "2020-01-02" - day_in_d: - values: - - 0 - - 1 - reference_date: "2020-01-01" -latitude_series: - name: my_latitude - values: - - - 1 - - 2 - - - 3 - - 4 -longitude_series: - name: my_longitude - values: - - - 5 - - 6 - - - 7 - - 8 diff --git a/tests/input/container.yaml b/tests/input/container_yaml.yaml similarity index 100% rename from tests/input/container.yaml rename to tests/input/container_yaml.yaml index 3c5b479..8c1c32c 100644 --- a/tests/input/container.yaml +++ b/tests/input/container_yaml.yaml @@ -1,4 +1,18 @@ name: my_container +latitude_series: + name: my_latitude + values: + - - 1 + - 2 + - - 3 + - 4 +longitude_series: + name: my_longitude + values: + - - 5 + - 6 + - - 7 + - 8 temperature_dataset: name: my_temperature latitude_in_deg: my_latitude @@ -23,17 +37,3 @@ temperature_dataset: - 0 - 1 reference_date: "2020-01-01" -latitude_series: - name: my_latitude - values: - - - 1 - - 2 - - - 3 - - 4 -longitude_series: - name: my_longitude - values: - - - 5 - - 6 - - - 7 - - 8 diff --git a/tests/input/container_yaml_hdf5.yaml b/tests/input/container_yaml_hdf5.yaml new file mode 100644 index 0000000..85396e8 --- /dev/null +++ b/tests/input/container_yaml_hdf5.yaml @@ -0,0 +1,19 @@ +name: my_container +latitude_series: + name: my_latitude + values: file:./out/my_latitude.values.h5 +longitude_series: + name: my_longitude + values: file:./out/my_longitude.values.h5 +temperature_dataset: + date: + values: file:./out/my_temperature.date.values.h5 + day_in_d: + reference_date: '2020-01-01' + values: file:./out/my_temperature.day_in_d.values.h5 + latitude_in_deg: my_latitude + longitude_in_deg: my_longitude + name: my_temperature + temperatures_in_K: + conversion_factor: 1000.0 + values: file:./out/my_temperature.temperatures_in_K.values.h5 \ No newline at end of file diff --git a/tests/input/container_yaml_numpy.yaml b/tests/input/container_yaml_numpy.yaml new file mode 100644 index 0000000..83939a4 --- /dev/null +++ b/tests/input/container_yaml_numpy.yaml @@ -0,0 +1,19 @@ +name: my_container +latitude_series: + name: my_latitude + values: file:./out/my_latitude.values.npy +longitude_series: + name: my_longitude + values: file:./out/my_longitude.values.npy +temperature_dataset: + date: + values: file:./out/my_temperature.date.values.npy + day_in_d: + reference_date: '2020-01-01' + values: file:./out/my_temperature.day_in_d.values.npy + latitude_in_deg: my_latitude + longitude_in_deg: my_longitude + name: my_temperature + temperatures_in_K: + conversion_factor: 1000.0 + values: file:./out/my_temperature.temperatures_in_K.values.npy \ No newline at end of file diff --git a/tests/input/temperature_dataset_inlined_def_yaml.yaml b/tests/input/temperature_dataset_inlined_def_yaml.yaml new file mode 100644 index 0000000..b66df95 --- /dev/null +++ b/tests/input/temperature_dataset_inlined_def_yaml.yaml @@ -0,0 +1,23 @@ +latitude_in_deg: + - 1 + - 2 +longitude_in_deg: + - 4 + - 5 +name: my_temperature +temperatures_in_K: + - - - 0 + - 1 + - - 2 + - 3 + - - - 4 + - 5 + - - 6 + - 7 +date: + - "2020-01-01" + - "2020-01-02" +day_in_d: + - 0 + - 1 +reference_date: "2020-01-01" \ No newline at end of file diff --git a/tests/input/temperature_dataset_old_yaml.yaml b/tests/input/temperature_dataset_old_yaml.yaml new file mode 100644 index 0000000..37a5dfb --- /dev/null +++ b/tests/input/temperature_dataset_old_yaml.yaml @@ -0,0 +1,23 @@ +latitude_in_deg: + values: + - 1 + - 2 +longitude_in_deg: + values: + - 4 + - 5 +name: my_temperature +temperatures_in_K: + values: + - - - 0 + - 1 + - - 2 + - 3 + - - - 4 + - 5 + - - 6 + - 7 +time_in_d: + values: + - 7 + - 8 \ No newline at end of file diff --git a/tests/input/temperature_dataset_yaml.yaml b/tests/input/temperature_dataset_yaml.yaml index 37a5dfb..effcadb 100644 --- a/tests/input/temperature_dataset_yaml.yaml +++ b/tests/input/temperature_dataset_yaml.yaml @@ -1,23 +1,33 @@ latitude_in_deg: - values: - - 1 - - 2 + # name: my_latitude + latitude: + - 1 + - 2 longitude_in_deg: - values: - - 4 - - 5 + # name: my_longitude + longitude_in_deg: + - 4 + - 5 name: my_temperature temperatures_in_K: + # name: my_temperature values: - - - - 0 - - 1 - - - 2 - - 3 - - - - 4 - - 5 - - - 6 - - 7 -time_in_d: - values: - - 7 - - 8 \ No newline at end of file + - - - 0 + - 1 + - - 2 + - 3 + - - - 4 + - 5 + - - 6 + - 7 +date: + # name: my_date + date: + - "2020-01-01" + - "2020-01-02" +day_in_d: + # name: my_day_in_d + day_in_d: + - 0 + - 1 + reference_date: "2020-01-01" \ No newline at end of file diff --git a/tests/input/temperature_schema_inlined_def.yaml b/tests/input/temperature_schema_inlined_def.yaml new file mode 100644 index 0000000..f57c50f --- /dev/null +++ b/tests/input/temperature_schema_inlined_def.yaml @@ -0,0 +1,96 @@ +id: https://example.org/arrays +name: arrays-temperature-example-3 +title: Array Temperature Example Using NDArray Classes +description: |- + Example LinkML schema to demonstrate a complex 3D DataArray of temperature values + with labeled axes using array slots for the axes and data instead of classes containing + arrays +license: MIT + +prefixes: + linkml: https://w3id.org/linkml/ + wgs84: http://www.w3.org/2003/01/geo/wgs84_pos# + example: https://example.org/ + +default_prefix: example + +imports: + - linkml:types + +classes: + + TemperatureDataset: + tree_root: true + implements: + - linkml:DataArray + attributes: + name: + identifier: true + range: string + latitude_in_deg: + required: true + multivalued: true + range: float + unit: + ucum_code: deg + array: + exact_number_dimensions: 2 + longitude_in_deg: + required: true + multivalued: true + range: float + unit: + ucum_code: deg + array: + exact_number_dimensions: 2 + date: + required: true + multivalued: true + range: date + array: + exact_number_dimensions: 1 + day_in_d: + description: Number of days since `reference_date` + required: true + multivalued: true + range: integer + unit: + ucum_code: d + array: + exact_number_dimensions: 1 + reference_date: + description: The reference date for the `day_in_d` values + required: true + range: date + temperatures_in_K: + required: true + multivalued: true + inlined: true + range: float + unit: + ucum_code: K + array: + exact_number_dimensions: 3 + dimensions: + - alias: "x" + - alias: "y" + - alias: "date" + # labeled_by: + # - alias: lat + # label_slot: latitude_in_deg + # labeled_dimensions: [0, 1] + # - alias: lon + # label_slot: longitude_in_deg + # labeled_dimensions: [0, 1] + # - alias: date + # label_slot: date + # labeled_dimensions: [2] + # - alias: day + # label_slot: day_in_d + # labeled_dimensions: [2] + # - alias: reference_date + # label_slot: reference_date + # labeled_dimensions: null + # this is a non-dimension (constant) coordinate for the entire array and is supported by xarray. + # the use case is not clear; this should just be an attribute on `day_in_d`. but we can support it by + # allowing index_dims: null diff --git a/tests/input/temperature_dataset.yaml b/tests/input/temperature_schema_old.yaml similarity index 100% rename from tests/input/temperature_dataset.yaml rename to tests/input/temperature_schema_old.yaml diff --git a/tests/test_dumpers/test_dumpers.py b/tests/test_dumpers/test_dumpers.py index 2d5e30b..017e4b8 100644 --- a/tests/test_dumpers/test_dumpers.py +++ b/tests/test_dumpers/test_dumpers.py @@ -1,4 +1,4 @@ -"""Test dumping LinkML models in pydantic-style classes to various file formats.""" +"""Test dumping LinkML pydantic models with arrays as lists-of-lists to various file formats.""" import os import unittest @@ -55,130 +55,103 @@ def create_container() -> Container: return container -class YamlDumpersTestCase(unittest.TestCase): - """Test dumping of pydantic-style lists-of-lists classes from LinkML schemas into YAML files.""" - - def test_dump_pydantic_arrays(self): - """Test dumping pydantic classes with lists of lists to a YAML file.""" - container = create_container() - - schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") - ret = YamlDumper().dumps(container, schemaview=schemaview) - - # read and compare with the expected YAML file ignoring order of keys - expected_yaml_file = INPUT_DIR / "container.yaml" - yaml = YAML(typ="safe") - with open(expected_yaml_file) as f: - expected = yaml.load(f) # load yaml into dictionary - actual = yaml.load(ret) - assert actual == expected - - -class YamlNumpyDumpersTestCase(unittest.TestCase): - """Test dumping of pydantic-style classes from LinkML schemas into YAML + NumPy files.""" - - def test_dump_pydantic_arrays(self): - """Test dumping pydantic classes with numpy arrays to a YAML + NumPy files.""" - container = create_container() - - schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") - ret = YamlNumpyDumper().dumps(container, schemaview=schemaview, output_dir="tmp") - - print(ret) - - # # read and compare with the expected YAML file ignoring order of keys - # expected_yaml_file = INPUT_DIR / "container.yaml" - # yaml = YAML(typ="safe") - # with open(expected_yaml_file) as f: - # expected = yaml.load(f) # load yaml into dictionary - # actual = yaml.load(ret) - # assert actual == expected - - -class YamlHdf5DumpersTestCase(unittest.TestCase): - """Test dumping of pydantic-style classes from LinkML schemas into YAML + HDF5 datasets.""" - - def test_dump_pydantic_arrays(self): - """Test dumping pydantic classes with numpy arrays to a YAML + HDF5 datasets.""" - latitude_in_deg = LatitudeSeries(values=np.array([1, 2, 3])) - longitude_in_deg = LongitudeSeries(values=np.array([4, 5, 6])) - time_in_d = DaySeries(values=np.array([7, 8, 9])) - temperatures_in_K = TemperatureMatrix( - values=np.ones((3, 3, 3)), - ) - temperature = TemperatureDataset( - name="my_temperature", - latitude_in_deg=latitude_in_deg, - longitude_in_deg=longitude_in_deg, - time_in_d=time_in_d, - temperatures_in_K=temperatures_in_K, - ) - - schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") - ret = YamlHdf5Dumper().dumps(temperature, schemaview=schemaview) - - expected = """latitude_in_deg: - values: file:./my_temperature.LatitudeSeries.values.h5 -longitude_in_deg: - values: file:./my_temperature.LongitudeSeries.values.h5 -name: my_temperature -temperatures_in_K: - values: file:./my_temperature.TemperatureMatrix.values.h5 -time_in_d: - values: file:./my_temperature.DaySeries.values.h5 -""" - assert ret == expected - - -class Hdf5DumpersTestCase(unittest.TestCase): - """Test dumping of pydantic-style classes from LinkML schemas into a single HDF5 file.""" - - def test_dump_pydantic_arrays(self): - """Test dumping pydantic classes with numpy arrays to a signle HDF5 file.""" - latitude_in_deg = LatitudeSeries(values=np.array([1, 2, 3])) - longitude_in_deg = LongitudeSeries(values=np.array([4, 5, 6])) - time_in_d = DaySeries(values=np.array([7, 8, 9])) - temperatures_in_K = TemperatureMatrix( - values=np.ones((3, 3, 3)), - ) - temperature = TemperatureDataset( - name="my_temperature", - latitude_in_deg=latitude_in_deg, - longitude_in_deg=longitude_in_deg, - time_in_d=time_in_d, - temperatures_in_K=temperatures_in_K, - ) - - schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") - Hdf5Dumper().dumps(temperature, schemaview=schemaview) - - assert os.path.exists("my_temperature.h5") - - # TODO use h5py to assert that the data is correct - - -class ZarrDirectoryStoreDumpersTestCase(unittest.TestCase): - """Test dumping of pydantic-style classes from LinkML schemas into a Zarr directory store.""" - - def test_dump_pydantic_arrays(self): - """Test dumping pydantic classes with numpy arrays to a Zarr directory store.""" - latitude_in_deg = LatitudeSeries(values=np.array([1, 2, 3])) - longitude_in_deg = LongitudeSeries(values=np.array([4, 5, 6])) - time_in_d = DaySeries(values=np.array([7, 8, 9])) - temperatures_in_K = TemperatureMatrix( - values=np.ones((3, 3, 3)), - ) - temperature = TemperatureDataset( - name="my_temperature", - latitude_in_deg=latitude_in_deg, - longitude_in_deg=longitude_in_deg, - time_in_d=time_in_d, - temperatures_in_K=temperatures_in_K, - ) - - schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") - ZarrDirectoryStoreDumper().dumps(temperature, schemaview=schemaview) - - assert os.path.exists("my_temperature.zarr") - - # TODO use Zarr to assert that the data is correct +def test_yaml_dumper(): + """Test YamlDumper dumping to a YAML file.""" + container = create_container() + + schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") + ret = YamlDumper().dumps(container, schemaview=schemaview) + + # read and compare with the expected YAML file ignoring order of keys + expected_yaml_file = INPUT_DIR / "container_yaml.yaml" + yaml = YAML(typ="safe") + with open(expected_yaml_file) as f: + expected = yaml.load(f) # load yaml into dictionary + actual = yaml.load(ret) + assert actual == expected + + +def test_yaml_numpy_dumper(): + """Test YamlNumpyDumper dumping to a YAML file and NumPy .npy files in a directory.""" + container = create_container() + + schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") + ret = YamlNumpyDumper().dumps(container, schemaview=schemaview, output_dir="./out") + + # read and compare with the expected YAML file ignoring order of keys + expected_yaml_file = INPUT_DIR / "container_yaml_numpy.yaml" + yaml = YAML(typ="safe") + with open(expected_yaml_file) as f: + expected = yaml.load(f) # load yaml into dictionary + actual = yaml.load(ret) + assert actual == expected + + +def test_yaml_hdf5_dumper(): + """Test YamlNumpyDumper dumping to a YAML file and HDF5 datasets in a directory.""" + container = create_container() + + schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") + ret = YamlHdf5Dumper().dumps(container, schemaview=schemaview, output_dir="./out") + + # read and compare with the expected YAML file ignoring order of keys + expected_yaml_file = INPUT_DIR / "container_yaml_hdf5.yaml" + yaml = YAML(typ="safe") + with open(expected_yaml_file) as f: + expected = yaml.load(f) # load yaml into dictionary + actual = yaml.load(ret) + assert actual == expected + + +# class Hdf5DumpersTestCase(unittest.TestCase): +# """Test dumping of pydantic-style classes from LinkML schemas into a single HDF5 file.""" + +# def test_dump_pydantic_arrays(self): +# """Test dumping pydantic classes with numpy arrays to a signle HDF5 file.""" +# latitude_in_deg = LatitudeSeries(values=np.array([1, 2, 3])) +# longitude_in_deg = LongitudeSeries(values=np.array([4, 5, 6])) +# time_in_d = DaySeries(values=np.array([7, 8, 9])) +# temperatures_in_K = TemperatureMatrix( +# values=np.ones((3, 3, 3)), +# ) +# temperature = TemperatureDataset( +# name="my_temperature", +# latitude_in_deg=latitude_in_deg, +# longitude_in_deg=longitude_in_deg, +# time_in_d=time_in_d, +# temperatures_in_K=temperatures_in_K, +# ) + +# schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") +# Hdf5Dumper().dumps(temperature, schemaview=schemaview) + +# assert os.path.exists("my_temperature.h5") + +# # TODO use h5py to assert that the data is correct + + +# class ZarrDirectoryStoreDumpersTestCase(unittest.TestCase): +# """Test dumping of pydantic-style classes from LinkML schemas into a Zarr directory store.""" + +# def test_dump_pydantic_arrays(self): +# """Test dumping pydantic classes with numpy arrays to a Zarr directory store.""" +# latitude_in_deg = LatitudeSeries(values=np.array([1, 2, 3])) +# longitude_in_deg = LongitudeSeries(values=np.array([4, 5, 6])) +# time_in_d = DaySeries(values=np.array([7, 8, 9])) +# temperatures_in_K = TemperatureMatrix( +# values=np.ones((3, 3, 3)), +# ) +# temperature = TemperatureDataset( +# name="my_temperature", +# latitude_in_deg=latitude_in_deg, +# longitude_in_deg=longitude_in_deg, +# time_in_d=time_in_d, +# temperatures_in_K=temperatures_in_K, +# ) + +# schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") +# ZarrDirectoryStoreDumper().dumps(temperature, schemaview=schemaview) + +# assert os.path.exists("my_temperature.zarr") + +# # TODO use Zarr to assert that the data is correct diff --git a/tests/test_loaders/test_loaders.py b/tests/test_loaders/test_loaders.py index e7ef6e6..334d151 100644 --- a/tests/test_loaders/test_loaders.py +++ b/tests/test_loaders/test_loaders.py @@ -1,4 +1,4 @@ -"""Test loading data from various file formats into LinkML models.""" +"""Test loading data from various file formats into LinkML pydantic models with arrays as lists-of-lists.""" import unittest from pathlib import Path @@ -25,156 +25,112 @@ ) -class YamlLoadersTestCase(unittest.TestCase): - """Test loading of pydantic lists-of-lists classes from YAML arrays.""" +def check_container(container: Container): + assert isinstance(container, Container) + assert container.name == "my_container" - def test_load_pydantic_arrays(self): - """Test loading of pydantic-style classes from YAML arrays.""" - data_yaml = hbread( - "container.yaml", base_path=str(Path(__file__) / "../../input") - ) - schemaview = SchemaView(Path(__file__) / "../../input/temperature_schema.yaml") - container = YamlLoader().loads(data_yaml, target_class=Container, schemaview=schemaview) + assert isinstance(container.latitude_series, LatitudeInDegSeries) + assert container.latitude_series.name == "my_latitude" + assert container.latitude_series.values == [[1, 2], [3, 4]] - assert isinstance(container, Container) - assert container.name == "my_container" + assert isinstance(container.longitude_series, LongitudeInDegSeries) + assert container.longitude_series.name == "my_longitude" + assert container.longitude_series.values == [[5, 6], [7, 8]] - assert isinstance(container.latitude_series, LatitudeInDegSeries) - assert container.latitude_series.name == "my_latitude" - np.testing.assert_array_equal(container.latitude_series.values, np.array([[1, 2], [3, 4]])) + assert isinstance(container.temperature_dataset, TemperatureDataset) + assert container.temperature_dataset.name == "my_temperature" + assert container.temperature_dataset.latitude_in_deg == "my_latitude" + # currently no way to get the actual LatitudeInDegSeries object from the TemperatureDataset object + # because the TemperatureDataset Pydantic object expects a string for the latitude_in_deg field + # to be isomorphic with the json schema / yaml representation - assert isinstance(container.longitude_series, LongitudeInDegSeries) - assert container.longitude_series.name == "my_longitude" - np.testing.assert_array_equal(container.longitude_series.values, np.array([[5, 6], [7, 8]])) + assert container.temperature_dataset.longitude_in_deg == "my_longitude" - assert isinstance(container.temperature_dataset, TemperatureDataset) - assert container.temperature_dataset.name == "my_temperature" - assert container.temperature_dataset.latitude_in_deg == "my_latitude" - # currently no way to get the actual LatitudeInDegSeries object from the TemperatureDataset object - # because the TemperatureDataset Pydantic object expects a string for the latitude_in_deg field - # to be isomorphic with the json schema / yaml representation + assert isinstance(container.temperature_dataset.date, DateSeries) + assert container.temperature_dataset.date.values == ["2020-01-01", "2020-01-02"] - assert container.temperature_dataset.longitude_in_deg == "my_longitude" + assert isinstance(container.temperature_dataset.day_in_d, DaysInDSinceSeries) + assert container.temperature_dataset.day_in_d.values == [0, 1] + assert container.temperature_dataset.day_in_d.reference_date == "2020-01-01" - assert isinstance(container.temperature_dataset.date, DateSeries) - assert container.temperature_dataset.date.values == ["2020-01-01", "2020-01-02"] + assert isinstance(container.temperature_dataset.temperatures_in_K, TemperaturesInKMatrix) + assert container.temperature_dataset.temperatures_in_K.values == [ + [[0, 1], [2, 3]], + [[4, 5], [6, 7]], + ] - assert isinstance(container.temperature_dataset.day_in_d, DaysInDSinceSeries) - assert container.temperature_dataset.day_in_d.values == [0, 1] - assert container.temperature_dataset.day_in_d.reference_date == "2020-01-01" - assert isinstance(container.temperature_dataset.temperatures_in_K, TemperaturesInKMatrix) - np.testing.assert_array_equal( - container.temperature_dataset.temperatures_in_K.values, - np.array([[[0, 1], [2, 3]], [[4, 5], [6, 7]]]), - ) +def test_yaml_loader(): + """Test YamlLoader loading pydantic classes from YAML arrays.""" + data_yaml = hbread("container_yaml.yaml", base_path=str(Path(__file__) / "../../input")) + schemaview = SchemaView(Path(__file__) / "../../input/temperature_schema.yaml") + container = YamlLoader().loads(data_yaml, target_class=Container, schemaview=schemaview) + check_container(container) -class YamlNumpyLoadersTestCase(unittest.TestCase): +def test_yaml_numpy_loader(): """Test loading of pydantic-style classes from YAML + Numpy arrays.""" + read_yaml = hbread("container_yaml_numpy.yaml", base_path=str(Path(__file__) / "../../input")) + schemaview = SchemaView(Path(__file__) / "../../input/temperature_schema.yaml") + container = YamlNumpyLoader().loads(read_yaml, target_class=Container, schemaview=schemaview) + check_container(container) - def test_load_pydantic_arrays(self): - """Test loading of pydantic-style classes from YAML + Numpy arrays.""" - read_yaml = hbread( - "temperature_dataset_npy_dumped.yaml", base_path=str(Path(__file__) / "../../input") - ) - schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") - ret = YamlNumpyLoader().loads( - read_yaml, target_class=TemperatureDataset, schemaview=schemaview - ) - assert isinstance(ret, TemperatureDataset) - assert ret.name == "my_temperature" - - assert isinstance(ret.latitude_in_deg, LatitudeSeries) - np.testing.assert_array_equal(ret.latitude_in_deg.values, np.array([1, 2, 3])) - - assert isinstance(ret.longitude_in_deg, LongitudeSeries) - np.testing.assert_array_equal(ret.longitude_in_deg.values, np.array([4, 5, 6])) - - assert isinstance(ret.time_in_d, DaySeries) - np.testing.assert_array_equal(ret.time_in_d.values, np.array([7, 8, 9])) - - assert isinstance(ret.temperatures_in_K, TemperatureMatrix) - np.testing.assert_array_equal(ret.temperatures_in_K.values, np.ones((3, 3, 3))) - - -class YamlHdf5LoadersTestCase(unittest.TestCase): - """Test loading of pydantic-style classes from YAML + HDF5 datasets.""" - - def test_load_pydantic_arrays(self): - """Test loading of pydantic-style classes from YAML + HDF5 datasets.""" - read_yaml = hbread( - "temperature_dataset_hdf5_dumped.yaml", base_path=str(Path(__file__) / "../../input") - ) - schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") - ret = YamlHdf5Loader().loads( - read_yaml, target_class=TemperatureDataset, schemaview=schemaview - ) - - assert isinstance(ret, TemperatureDataset) - assert ret.name == "my_temperature" - - assert isinstance(ret.latitude_in_deg, LatitudeSeries) - np.testing.assert_array_equal(ret.latitude_in_deg.values, np.array([1, 2, 3])) - - assert isinstance(ret.longitude_in_deg, LongitudeSeries) - np.testing.assert_array_equal(ret.longitude_in_deg.values, np.array([4, 5, 6])) - - assert isinstance(ret.time_in_d, DaySeries) - np.testing.assert_array_equal(ret.time_in_d.values, np.array([7, 8, 9])) - - assert isinstance(ret.temperatures_in_K, TemperatureMatrix) - np.testing.assert_array_equal(ret.temperatures_in_K.values, np.ones((3, 3, 3))) +def test_yaml_hdf5_loader(): + """Test loading of pydantic-style classes from YAML + Numpy arrays.""" + read_yaml = hbread("container_yaml_hdf5.yaml", base_path=str(Path(__file__) / "../../input")) + schemaview = SchemaView(Path(__file__) / "../../input/temperature_schema.yaml") + container = YamlHdf5Loader().loads(read_yaml, target_class=Container, schemaview=schemaview) + check_container(container) -class Hdf5LoadersTestCase(unittest.TestCase): - """Test loading of pydantic-style classes from an HDF5 file.""" +# class Hdf5LoadersTestCase(unittest.TestCase): +# """Test loading of pydantic-style classes from an HDF5 file.""" - def test_load_pydantic_arrays(self): - """Test loading of pydantic-style classes from an HDF5 file.""" - file_path = str(Path(__file__).parent.parent / "input" / "my_temperature.h5") - schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") - ret = Hdf5Loader().loads(file_path, target_class=TemperatureDataset, schemaview=schemaview) +# def test_load_pydantic_arrays(self): +# """Test loading of pydantic-style classes from an HDF5 file.""" +# file_path = str(Path(__file__).parent.parent / "input" / "my_temperature.h5") +# schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") +# ret = Hdf5Loader().loads(file_path, target_class=TemperatureDataset, schemaview=schemaview) - assert isinstance(ret, TemperatureDataset) - assert ret.name == "my_temperature" +# assert isinstance(ret, TemperatureDataset) +# assert ret.name == "my_temperature" - assert isinstance(ret.latitude_in_deg, LatitudeSeries) - np.testing.assert_array_equal(ret.latitude_in_deg.values, np.array([1, 2, 3])) +# assert isinstance(ret.latitude_in_deg, LatitudeSeries) +# np.testing.assert_array_equal(ret.latitude_in_deg.values, np.array([1, 2, 3])) - assert isinstance(ret.longitude_in_deg, LongitudeSeries) - np.testing.assert_array_equal(ret.longitude_in_deg.values, np.array([4, 5, 6])) +# assert isinstance(ret.longitude_in_deg, LongitudeSeries) +# np.testing.assert_array_equal(ret.longitude_in_deg.values, np.array([4, 5, 6])) - assert isinstance(ret.time_in_d, DaySeries) - np.testing.assert_array_equal(ret.time_in_d.values, np.array([7, 8, 9])) +# assert isinstance(ret.time_in_d, DaySeries) +# np.testing.assert_array_equal(ret.time_in_d.values, np.array([7, 8, 9])) - assert isinstance(ret.temperatures_in_K, TemperatureMatrix) - np.testing.assert_array_equal(ret.temperatures_in_K.values, np.ones((3, 3, 3))) +# assert isinstance(ret.temperatures_in_K, TemperatureMatrix) +# np.testing.assert_array_equal(ret.temperatures_in_K.values, np.ones((3, 3, 3))) -class ZarrDirectoryStoreLoadersTestCase(unittest.TestCase): - """Test loading of pydantic-style classes from a Zarr directory store.""" +# class ZarrDirectoryStoreLoadersTestCase(unittest.TestCase): +# """Test loading of pydantic-style classes from a Zarr directory store.""" - def test_load_pydantic_arrays(self): - """Test loading of pydantic-style classes from a Zarr directory store.""" - file_path = str(Path(__file__).parent.parent / "input" / "my_temperature.zarr") - schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") - ret = ZarrDirectoryStoreLoader().loads( - file_path, target_class=TemperatureDataset, schemaview=schemaview - ) +# def test_load_pydantic_arrays(self): +# """Test loading of pydantic-style classes from a Zarr directory store.""" +# file_path = str(Path(__file__).parent.parent / "input" / "my_temperature.zarr") +# schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") +# ret = ZarrDirectoryStoreLoader().loads( +# file_path, target_class=TemperatureDataset, schemaview=schemaview +# ) - assert isinstance(ret, TemperatureDataset) - assert ret.name == "my_temperature" +# assert isinstance(ret, TemperatureDataset) +# assert ret.name == "my_temperature" - assert isinstance(ret.latitude_in_deg, LatitudeSeries) - np.testing.assert_array_equal(ret.latitude_in_deg.values, np.array([1, 2, 3])) +# assert isinstance(ret.latitude_in_deg, LatitudeSeries) +# np.testing.assert_array_equal(ret.latitude_in_deg.values, np.array([1, 2, 3])) - assert isinstance(ret.longitude_in_deg, LongitudeSeries) - np.testing.assert_array_equal(ret.longitude_in_deg.values, np.array([4, 5, 6])) +# assert isinstance(ret.longitude_in_deg, LongitudeSeries) +# np.testing.assert_array_equal(ret.longitude_in_deg.values, np.array([4, 5, 6])) - assert isinstance(ret.time_in_d, DaySeries) - np.testing.assert_array_equal(ret.time_in_d.values, np.array([7, 8, 9])) +# assert isinstance(ret.time_in_d, DaySeries) +# np.testing.assert_array_equal(ret.time_in_d.values, np.array([7, 8, 9])) - assert isinstance(ret.temperatures_in_K, TemperatureMatrix) - np.testing.assert_array_equal(ret.temperatures_in_K.values, np.ones((3, 3, 3))) +# assert isinstance(ret.temperatures_in_K, TemperatureMatrix) +# np.testing.assert_array_equal(ret.temperatures_in_K.values, np.ones((3, 3, 3))) From 3432b90c7742ba9f48a3c2b06f6412e9e835f98b Mon Sep 17 00:00:00 2001 From: rly Date: Fri, 5 Jul 2024 15:19:38 -0700 Subject: [PATCH 07/38] Update tests, style --- .gitignore | 4 +- docs/conf.py | 2 +- src/linkml_arrays/dumpers/hdf5_dumper.py | 22 ++-- .../dumpers/yaml_array_file_dumper.py | 22 +++- src/linkml_arrays/dumpers/yaml_hdf5_dumper.py | 8 +- .../dumpers/yaml_numpy_dumper.py | 8 +- .../dumpers/zarr_directory_store_dumper.py | 22 ++-- src/linkml_arrays/loaders/hdf5_loader.py | 2 +- .../loaders/yaml_numpy_loader.py | 4 +- .../loaders/zarr_directory_store_loader.py | 2 +- tests/input/my_temperature.h5 | Bin 12648 -> 0 bytes tests/input/my_temperature.zarr/.zattrs | 3 - tests/input/my_temperature.zarr/.zgroup | 3 - .../latitude_in_deg/.zgroup | 3 - .../latitude_in_deg/values/.zarray | 20 --- .../latitude_in_deg/values/0 | Bin 40 -> 0 bytes .../longitude_in_deg/.zgroup | 3 - .../longitude_in_deg/values/.zarray | 20 --- .../longitude_in_deg/values/0 | Bin 40 -> 0 bytes .../temperatures_in_K/.zgroup | 3 - .../temperatures_in_K/values/.zarray | 24 ---- .../temperatures_in_K/values/0.0.0 | Bin 45 -> 0 bytes .../my_temperature.zarr/time_in_d/.zgroup | 3 - .../time_in_d/values/.zarray | 20 --- .../my_temperature.zarr/time_in_d/values/0 | Bin 40 -> 0 bytes .../temperature_dataset_hdf5_dumped.yaml | 9 -- .../temperature_dataset_inlined_def_yaml.yaml | 23 ---- .../input/temperature_dataset_npy_dumped.yaml | 9 -- tests/input/temperature_dataset_old_yaml.yaml | 23 ---- tests/input/temperature_dataset_yaml.yaml | 33 ----- .../input/temperature_schema_inlined_def.yaml | 96 -------------- tests/input/temperature_schema_old.yaml | 118 ------------------ tests/test_dumpers/test_dumpers.py | 117 +++++++++-------- tests/test_loaders/test_loaders.py | 18 +++ 34 files changed, 141 insertions(+), 503 deletions(-) delete mode 100644 tests/input/my_temperature.h5 delete mode 100644 tests/input/my_temperature.zarr/.zattrs delete mode 100644 tests/input/my_temperature.zarr/.zgroup delete mode 100644 tests/input/my_temperature.zarr/latitude_in_deg/.zgroup delete mode 100644 tests/input/my_temperature.zarr/latitude_in_deg/values/.zarray delete mode 100644 tests/input/my_temperature.zarr/latitude_in_deg/values/0 delete mode 100644 tests/input/my_temperature.zarr/longitude_in_deg/.zgroup delete mode 100644 tests/input/my_temperature.zarr/longitude_in_deg/values/.zarray delete mode 100644 tests/input/my_temperature.zarr/longitude_in_deg/values/0 delete mode 100644 tests/input/my_temperature.zarr/temperatures_in_K/.zgroup delete mode 100644 tests/input/my_temperature.zarr/temperatures_in_K/values/.zarray delete mode 100644 tests/input/my_temperature.zarr/temperatures_in_K/values/0.0.0 delete mode 100644 tests/input/my_temperature.zarr/time_in_d/.zgroup delete mode 100644 tests/input/my_temperature.zarr/time_in_d/values/.zarray delete mode 100644 tests/input/my_temperature.zarr/time_in_d/values/0 delete mode 100644 tests/input/temperature_dataset_hdf5_dumped.yaml delete mode 100644 tests/input/temperature_dataset_inlined_def_yaml.yaml delete mode 100644 tests/input/temperature_dataset_npy_dumped.yaml delete mode 100644 tests/input/temperature_dataset_old_yaml.yaml delete mode 100644 tests/input/temperature_dataset_yaml.yaml delete mode 100644 tests/input/temperature_schema_inlined_def.yaml delete mode 100644 tests/input/temperature_schema_old.yaml diff --git a/.gitignore b/.gitignore index 3f66cf8..8f654b2 100644 --- a/.gitignore +++ b/.gitignore @@ -129,4 +129,6 @@ dmypy.json .pyre/ .DS_Store -out \ No newline at end of file +out +my_container.h5 +my_container.zarr \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 0c3068c..9048edf 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -24,7 +24,7 @@ "sphinx_rtd_theme", "sphinx_click", # "sphinx_autodoc_typehints", - "myst_parser" + "myst_parser", ] # generate autosummary pages diff --git a/src/linkml_arrays/dumpers/hdf5_dumper.py b/src/linkml_arrays/dumpers/hdf5_dumper.py index 28e8bf0..2a90137 100644 --- a/src/linkml_arrays/dumpers/hdf5_dumper.py +++ b/src/linkml_arrays/dumpers/hdf5_dumper.py @@ -1,5 +1,6 @@ """Class for dumping a LinkML model to an HDF5 file.""" +from pathlib import Path from typing import Union import h5py @@ -22,7 +23,7 @@ def _iterate_element( for k, v in vars(element).items(): found_slot = schemaview.induced_slot(k, element_type) - if "linkml:elements" in found_slot.implements: + if found_slot.array: # save the numpy array to an hdf5 dataset group.create_dataset(found_slot.name, data=v) else: @@ -39,16 +40,13 @@ class Hdf5Dumper(Dumper): """Dumper class for LinkML models to HDF5 files.""" # TODO is this the right method to overwrite? it does not dump a string - def dumps(self, element: Union[YAMLRoot, BaseModel], schemaview: SchemaView, **kwargs): - """Dump the element to an HDF5 file. - - Raises: - ValueError: If the class requires an identifier and it is not provided. - """ - id_slot = schemaview.get_identifier_slot(element.__class__.__name__) - if id_slot is None: - raise ValueError("The class requires an identifier.") - id_value = getattr(element, id_slot.name) - output_file_path = f"{id_value}.h5" + def dumps( + self, + element: Union[YAMLRoot, BaseModel], + schemaview: SchemaView, + output_file_path: Union[str, Path], + **kwargs, + ): + """Dump the element to an HDF5 file.""" with h5py.File(output_file_path, "w") as f: _iterate_element(element, schemaview, f) diff --git a/src/linkml_arrays/dumpers/yaml_array_file_dumper.py b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py index 0dff67b..e61fec4 100644 --- a/src/linkml_arrays/dumpers/yaml_array_file_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py @@ -15,8 +15,12 @@ def _iterate_element( - element: Union[YAMLRoot, BaseModel], schemaview: SchemaView, output_dir: Path, - write_array: Callable, parent_identifier=None, inlined_name=None + element: Union[YAMLRoot, BaseModel], + schemaview: SchemaView, + output_dir: Path, + write_array: Callable, + parent_identifier=None, + inlined_name=None, ): """Recursively iterate through the elements of a LinkML model and save them. @@ -69,7 +73,9 @@ def _iterate_element( ret_dict[k] = f"file:./{output_file_path}" else: if isinstance(v, BaseModel): - v2 = _iterate_element(v, schemaview, output_dir, write_array, id_value, inlined_name=found_slot.name) + v2 = _iterate_element( + v, schemaview, output_dir, write_array, id_value, inlined_name=found_slot.name + ) ret_dict[k] = v2 else: ret_dict[k] = v @@ -79,7 +85,13 @@ def _iterate_element( class YamlArrayFileDumper(Dumper, metaclass=ABCMeta): """Base dumper class for LinkML models to YAML files with paths to array files.""" - def dumps(self, element: Union[YAMLRoot, BaseModel], schemaview: SchemaView, output_dir: Union[str, Path] = None, **kwargs) -> str: + def dumps( + self, + element: Union[YAMLRoot, BaseModel], + schemaview: SchemaView, + output_dir: Union[str, Path] = None, + **kwargs, + ) -> str: """Return element formatted as a YAML string.""" if output_dir is None: output_dir = "." @@ -91,4 +103,4 @@ def dumps(self, element: Union[YAMLRoot, BaseModel], schemaview: SchemaView, out @abstractmethod def write_array(cls, array: Union[List, np.ndarray], output_file_path: Union[str, Path]): """Write an array to a file.""" - raise NotImplementedError("Subclasses must implement this method.") \ No newline at end of file + raise NotImplementedError("Subclasses must implement this method.") diff --git a/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py b/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py index d3ac0f1..b6b348a 100644 --- a/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py @@ -14,11 +14,15 @@ class YamlHdf5Dumper(YamlArrayFileDumper): FILE_SUFFIX = ".h5" # used in parent class @classmethod - def write_array(cls, array: Union[List, np.ndarray], output_file_path_no_suffix: Union[str, Path]): + def write_array( + cls, array: Union[List, np.ndarray], output_file_path_no_suffix: Union[str, Path] + ): """Write an array to a file.""" # TODO do not assume that there is only one by this name # add suffix to the file name - output_file_path = output_file_path_no_suffix.parent / (output_file_path_no_suffix.name + cls.FILE_SUFFIX) + output_file_path = output_file_path_no_suffix.parent / ( + output_file_path_no_suffix.name + cls.FILE_SUFFIX + ) with h5py.File(output_file_path, "w") as f: f.create_dataset("data", data=array) return output_file_path diff --git a/src/linkml_arrays/dumpers/yaml_numpy_dumper.py b/src/linkml_arrays/dumpers/yaml_numpy_dumper.py index 509419e..a08f763 100644 --- a/src/linkml_arrays/dumpers/yaml_numpy_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_numpy_dumper.py @@ -13,11 +13,15 @@ class YamlNumpyDumper(YamlArrayFileDumper): FILE_SUFFIX = ".npy" # used in parent class @classmethod - def write_array(cls, array: Union[List, np.ndarray], output_file_path_no_suffix: Union[str, Path]): + def write_array( + cls, array: Union[List, np.ndarray], output_file_path_no_suffix: Union[str, Path] + ): """Write an array to a file.""" # TODO do not assume that there is only one by this name # add suffix to the file name - output_file_path = output_file_path_no_suffix.parent / (output_file_path_no_suffix.name + cls.FILE_SUFFIX) + output_file_path = output_file_path_no_suffix.parent / ( + output_file_path_no_suffix.name + cls.FILE_SUFFIX + ) arr = np.array(array) np.save(output_file_path, arr) return output_file_path diff --git a/src/linkml_arrays/dumpers/zarr_directory_store_dumper.py b/src/linkml_arrays/dumpers/zarr_directory_store_dumper.py index 2c899ec..0dff5b7 100644 --- a/src/linkml_arrays/dumpers/zarr_directory_store_dumper.py +++ b/src/linkml_arrays/dumpers/zarr_directory_store_dumper.py @@ -1,5 +1,6 @@ """Class for dumping a LinkML model to a Zarr directory store.""" +from pathlib import Path from typing import Union import zarr @@ -22,7 +23,7 @@ def _iterate_element( for k, v in vars(element).items(): found_slot = schemaview.induced_slot(k, element_type) - if "linkml:elements" in found_slot.implements: + if found_slot.array: # save the numpy array to an hdf5 dataset group.create_dataset(found_slot.name, data=v) else: @@ -39,17 +40,14 @@ class ZarrDirectoryStoreDumper(Dumper): """Dumper class for LinkML models to Zarr directory stores.""" # TODO is this the right method to overwrite? it does not dump a string - def dumps(self, element: Union[YAMLRoot, BaseModel], schemaview: SchemaView, **kwargs): - """Dump the element to a Zarr directory store. - - Raises: - ValueError: If the class requires an identifier and it is not provided. - """ - id_slot = schemaview.get_identifier_slot(element.__class__.__name__) - if id_slot is None: - raise ValueError("The class requires an identifier.") - id_value = getattr(element, id_slot.name) - output_file_path = f"{id_value}.zarr" + def dumps( + self, + element: Union[YAMLRoot, BaseModel], + schemaview: SchemaView, + output_file_path: Union[str, Path], + **kwargs, + ): + """Dump the element to a Zarr directory store.""" store = zarr.DirectoryStore(output_file_path) root = zarr.group(store=store, overwrite=True) _iterate_element(element, schemaview, root) diff --git a/src/linkml_arrays/loaders/hdf5_loader.py b/src/linkml_arrays/loaders/hdf5_loader.py index 92e6bff..e575d68 100644 --- a/src/linkml_arrays/loaders/hdf5_loader.py +++ b/src/linkml_arrays/loaders/hdf5_loader.py @@ -25,7 +25,7 @@ def _iterate_element( found_slot = schemaview.induced_slot( k, element_type.name ) # assumes the slot name has been written as the name which is OK for now. - if "linkml:elements" in found_slot.implements: + if found_slot.array: assert isinstance(v, h5py.Dataset) v = v[()] # read all the values into memory TODO: support lazy loading elif isinstance(v, h5py.Group): # it's a subgroup diff --git a/src/linkml_arrays/loaders/yaml_numpy_loader.py b/src/linkml_arrays/loaders/yaml_numpy_loader.py index a118ec1..af9ee44 100644 --- a/src/linkml_arrays/loaders/yaml_numpy_loader.py +++ b/src/linkml_arrays/loaders/yaml_numpy_loader.py @@ -11,7 +11,9 @@ from pydantic import BaseModel -def _iterate_element(input_dict: dict, element_type: ClassDefinition, schemaview: SchemaView) -> dict: +def _iterate_element( + input_dict: dict, element_type: ClassDefinition, schemaview: SchemaView +) -> dict: """Recursively iterate through the elements of a LinkML model and load them into a dict. Datasets are read into memory. diff --git a/src/linkml_arrays/loaders/zarr_directory_store_loader.py b/src/linkml_arrays/loaders/zarr_directory_store_loader.py index 29707d5..fdd6e09 100644 --- a/src/linkml_arrays/loaders/zarr_directory_store_loader.py +++ b/src/linkml_arrays/loaders/zarr_directory_store_loader.py @@ -25,7 +25,7 @@ def _iterate_element( found_slot = schemaview.induced_slot( k, element_type.name ) # assumes the slot name has been written as the name which is OK for now. - if "linkml:elements" in found_slot.implements: + if found_slot.array: assert isinstance(v, zarr.Array) v = v[()] # read all the values into memory # TODO support lazy loading elif isinstance(v, zarr.hierarchy.Group): # it's a subgroup diff --git a/tests/input/my_temperature.h5 b/tests/input/my_temperature.h5 deleted file mode 100644 index b23a8072b16f3bd7193305e8ea8dd36e4d07ebeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12648 zcmeHNy>1gh5T3PTIKtmWqHrPvS0X@Qq!e^9N(?7~2m*?9j-{MpOSVDD8HJ8A=~Ctq zQl{h)Qc~s-DDwtkcW34tZ*)0i+0i+kD{l5@c6au>*;(zkw->Iwy*s-w3+C}Wm;v7= z`E^E5^A(nGp6k~sp-AqMJS<>BK@m({naX|YKPY0sI+cI@T&scB;|-r54@cOIgwqJR@eZ|6By9K1lu`@xZ;2T!m*d`unXT%^ST7nd|W zcfM(QE`INpS3lTqKn}y-!^SC%S?6ax?uW)ch=1<)(~=Sd1OY)n5D)|e0YN|z5CjAP zK|l}?1O$P6BVhPTd*-KuzapkyX&%!&MCY87zSZ|N;e(t{)#{aW&a@~L3bvs~{S*}h zRw20oz#PCnCvqi`&r%7Wb;0ahS({&DviNFvgtjwpnBSR*W#d2~jjui+{+GubHD5jc zcvlY4c4oSHCX*5GP96N&dXbkSkmk=#=l)^T{(QMr*|oUK>wTM4dB2~bJYOHt^*hit zOR_)S8W`eq3A5Kt4op%qf`A|(2nYg#z{Devbxx~1!zs!+ZQ?)mP!kycd8rbhVUu}Y z3Z4!H>(n>OiaP=Q*d=jiI$b60JpG&g`(so_eV)D;?_S%XlqRyx!{_7wmu1U~&jm{f mU%q%77SE`IblyA+?0|5BB6&BH)Kw&0KHPtK6{B9iG5!I4^yGg4 diff --git a/tests/input/my_temperature.zarr/.zattrs b/tests/input/my_temperature.zarr/.zattrs deleted file mode 100644 index 35dc0fe..0000000 --- a/tests/input/my_temperature.zarr/.zattrs +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "my_temperature" -} \ No newline at end of file diff --git a/tests/input/my_temperature.zarr/.zgroup b/tests/input/my_temperature.zarr/.zgroup deleted file mode 100644 index 3b7daf2..0000000 --- a/tests/input/my_temperature.zarr/.zgroup +++ /dev/null @@ -1,3 +0,0 @@ -{ - "zarr_format": 2 -} \ No newline at end of file diff --git a/tests/input/my_temperature.zarr/latitude_in_deg/.zgroup b/tests/input/my_temperature.zarr/latitude_in_deg/.zgroup deleted file mode 100644 index 3b7daf2..0000000 --- a/tests/input/my_temperature.zarr/latitude_in_deg/.zgroup +++ /dev/null @@ -1,3 +0,0 @@ -{ - "zarr_format": 2 -} \ No newline at end of file diff --git a/tests/input/my_temperature.zarr/latitude_in_deg/values/.zarray b/tests/input/my_temperature.zarr/latitude_in_deg/values/.zarray deleted file mode 100644 index 82cf922..0000000 --- a/tests/input/my_temperature.zarr/latitude_in_deg/values/.zarray +++ /dev/null @@ -1,20 +0,0 @@ -{ - "chunks": [ - 3 - ], - "compressor": { - "blocksize": 0, - "clevel": 5, - "cname": "lz4", - "id": "blosc", - "shuffle": 1 - }, - "dtype": " Date: Fri, 5 Jul 2024 21:13:26 -0700 Subject: [PATCH 08/38] Update gitignore --- .gitignore | 6 ++--- tests/input/my_container.h5 | Bin 0 -> 15656 bytes tests/input/my_container.zarr/.zattrs | 3 +++ tests/input/my_container.zarr/.zgroup | 3 +++ .../my_container.zarr/latitude_series/.zattrs | 3 +++ .../my_container.zarr/latitude_series/.zgroup | 3 +++ .../latitude_series/values/.zarray | 22 ++++++++++++++++ .../latitude_series/values/0.0 | Bin 0 -> 48 bytes .../longitude_series/.zattrs | 3 +++ .../longitude_series/.zgroup | 3 +++ .../longitude_series/values/.zarray | 22 ++++++++++++++++ .../longitude_series/values/0.0 | Bin 0 -> 48 bytes .../temperature_dataset/.zattrs | 5 ++++ .../temperature_dataset/.zgroup | 3 +++ .../temperature_dataset/date/.zgroup | 3 +++ .../temperature_dataset/date/values/.zarray | 20 +++++++++++++++ .../temperature_dataset/date/values/0 | Bin 0 -> 96 bytes .../temperature_dataset/day_in_d/.zattrs | 3 +++ .../temperature_dataset/day_in_d/.zgroup | 3 +++ .../day_in_d/values/.zarray | 20 +++++++++++++++ .../temperature_dataset/day_in_d/values/0 | Bin 0 -> 32 bytes .../temperatures_in_K/.zattrs | 3 +++ .../temperatures_in_K/.zgroup | 3 +++ .../temperatures_in_K/values/.zarray | 24 ++++++++++++++++++ .../temperatures_in_K/values/0.0.0 | Bin 0 -> 80 bytes 25 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 tests/input/my_container.h5 create mode 100644 tests/input/my_container.zarr/.zattrs create mode 100644 tests/input/my_container.zarr/.zgroup create mode 100644 tests/input/my_container.zarr/latitude_series/.zattrs create mode 100644 tests/input/my_container.zarr/latitude_series/.zgroup create mode 100644 tests/input/my_container.zarr/latitude_series/values/.zarray create mode 100644 tests/input/my_container.zarr/latitude_series/values/0.0 create mode 100644 tests/input/my_container.zarr/longitude_series/.zattrs create mode 100644 tests/input/my_container.zarr/longitude_series/.zgroup create mode 100644 tests/input/my_container.zarr/longitude_series/values/.zarray create mode 100644 tests/input/my_container.zarr/longitude_series/values/0.0 create mode 100644 tests/input/my_container.zarr/temperature_dataset/.zattrs create mode 100644 tests/input/my_container.zarr/temperature_dataset/.zgroup create mode 100644 tests/input/my_container.zarr/temperature_dataset/date/.zgroup create mode 100644 tests/input/my_container.zarr/temperature_dataset/date/values/.zarray create mode 100644 tests/input/my_container.zarr/temperature_dataset/date/values/0 create mode 100644 tests/input/my_container.zarr/temperature_dataset/day_in_d/.zattrs create mode 100644 tests/input/my_container.zarr/temperature_dataset/day_in_d/.zgroup create mode 100644 tests/input/my_container.zarr/temperature_dataset/day_in_d/values/.zarray create mode 100644 tests/input/my_container.zarr/temperature_dataset/day_in_d/values/0 create mode 100644 tests/input/my_container.zarr/temperature_dataset/temperatures_in_K/.zattrs create mode 100644 tests/input/my_container.zarr/temperature_dataset/temperatures_in_K/.zgroup create mode 100644 tests/input/my_container.zarr/temperature_dataset/temperatures_in_K/values/.zarray create mode 100644 tests/input/my_container.zarr/temperature_dataset/temperatures_in_K/values/0.0.0 diff --git a/.gitignore b/.gitignore index 8f654b2..063aa16 100644 --- a/.gitignore +++ b/.gitignore @@ -129,6 +129,6 @@ dmypy.json .pyre/ .DS_Store -out -my_container.h5 -my_container.zarr \ No newline at end of file +/out/* +/my_container.h5 +/my_container.zarr \ No newline at end of file diff --git a/tests/input/my_container.h5 b/tests/input/my_container.h5 new file mode 100644 index 0000000000000000000000000000000000000000..1938a66e8fe890c8d6a13ddad67864f83628ddc1 GIT binary patch literal 15656 zcmeHO&ref95S~{At5z+>1OAHd*r>!xP*G#3QM8FhhV$JiY@3-q? z?WFEVR5Vwjxb?Amg**D_@5u2&z+N9CnEp=hZXDE_Fn&56tQ1P+!n8=6)=gClUP2&# z>q|$AzI{FZOviYUj|_1K8COJmb(r~CjQ@IncfT#Pe>`A5mI$rlcS7{7qrGX(3u?QT z$nT>3P;Ou*?Z%mNdOSe1LL@XZdGU1omBAJPPjEJIN_AOSDNHSvYeA_TR`dwbW%RSW z$#qD10+%zOYP^JA!#M$dlm2=r)*|^@`GJIJC_9uL%-$Ky!jJG6KzrnOSTVw8q+I+e z%Dz)E_CZYF1OQ<;>JV@UI0PI54grUNL%<>65O4@M1RMemfeuDM@|$*EB}I8-wa#Yh z{HAQ;P0}cwjm>kK{WUh*Iwz2#3Fzx*ef9jS&O#}LD6QmAbuPg(pT_$Ina>VhI3$r5 zjmw{IU1I|zKOpuvdOQ%Y^QTCMQ3n1aD7+8mm(}Y7le5=6UL_)Jol5>x{B8q&D|tBE zkHs$kI^RqBQHI-j@O_xFVfEX-1;K65BSQ3h7=r}>@sLRM)cY7+ByTCSN6ED$D&F*} zn5X551glL#Uynz=VyohtYvZ!ksCGb&{mPRRFl}D#0HeClgsAt|AFz(*FsG>aF^Bah zQ{V6S5osURx7a85x2egaCz-2r>&M2gR!l30VV}vFX*c#$3G*n~ z*iZRB<03m-ZV`Q!N=H$9U*+HEDD%3;7|GMwd5cEg@w~|sR>GOE5|*dTX-;)=Eo#3m z`;+GVi#`h!7vH{T88R2&y2f?()zGMYyKm*k_Iuwh{%_~w8vcL5_`f=Q_dcvtON-^g zOfXejG>7mM0{#AIJ-!Z~q2Zs_IY|Rj?o)1W{N|IPo=RltBKfetrII&`x_@+>&-&(u zlw(rA&edxNQL*Fqw)H(9gbhdG9#MIxA2{b*#3bY5@7z7^=;H5D@QT*w5EXyFz>h@Z z|BAo%`Sf?X0-_&H8@pX1dBB5%>j%E?{;5 literal 0 HcmV?d00001 diff --git a/tests/input/my_container.zarr/.zattrs b/tests/input/my_container.zarr/.zattrs new file mode 100644 index 0000000..060eade --- /dev/null +++ b/tests/input/my_container.zarr/.zattrs @@ -0,0 +1,3 @@ +{ + "name": "my_container" +} \ No newline at end of file diff --git a/tests/input/my_container.zarr/.zgroup b/tests/input/my_container.zarr/.zgroup new file mode 100644 index 0000000..3b7daf2 --- /dev/null +++ b/tests/input/my_container.zarr/.zgroup @@ -0,0 +1,3 @@ +{ + "zarr_format": 2 +} \ No newline at end of file diff --git a/tests/input/my_container.zarr/latitude_series/.zattrs b/tests/input/my_container.zarr/latitude_series/.zattrs new file mode 100644 index 0000000..6b698b1 --- /dev/null +++ b/tests/input/my_container.zarr/latitude_series/.zattrs @@ -0,0 +1,3 @@ +{ + "name": "my_latitude" +} \ No newline at end of file diff --git a/tests/input/my_container.zarr/latitude_series/.zgroup b/tests/input/my_container.zarr/latitude_series/.zgroup new file mode 100644 index 0000000..3b7daf2 --- /dev/null +++ b/tests/input/my_container.zarr/latitude_series/.zgroup @@ -0,0 +1,3 @@ +{ + "zarr_format": 2 +} \ No newline at end of file diff --git a/tests/input/my_container.zarr/latitude_series/values/.zarray b/tests/input/my_container.zarr/latitude_series/values/.zarray new file mode 100644 index 0000000..fe4bc83 --- /dev/null +++ b/tests/input/my_container.zarr/latitude_series/values/.zarray @@ -0,0 +1,22 @@ +{ + "chunks": [ + 2, + 2 + ], + "compressor": { + "blocksize": 0, + "clevel": 5, + "cname": "lz4", + "id": "blosc", + "shuffle": 1 + }, + "dtype": "v7s@vT(#ULL)Pd9h02qV?AOHXW literal 0 HcmV?d00001 diff --git a/tests/input/my_container.zarr/temperature_dataset/day_in_d/.zattrs b/tests/input/my_container.zarr/temperature_dataset/day_in_d/.zattrs new file mode 100644 index 0000000..fc6cdcb --- /dev/null +++ b/tests/input/my_container.zarr/temperature_dataset/day_in_d/.zattrs @@ -0,0 +1,3 @@ +{ + "reference_date": "2020-01-01" +} \ No newline at end of file diff --git a/tests/input/my_container.zarr/temperature_dataset/day_in_d/.zgroup b/tests/input/my_container.zarr/temperature_dataset/day_in_d/.zgroup new file mode 100644 index 0000000..3b7daf2 --- /dev/null +++ b/tests/input/my_container.zarr/temperature_dataset/day_in_d/.zgroup @@ -0,0 +1,3 @@ +{ + "zarr_format": 2 +} \ No newline at end of file diff --git a/tests/input/my_container.zarr/temperature_dataset/day_in_d/values/.zarray b/tests/input/my_container.zarr/temperature_dataset/day_in_d/values/.zarray new file mode 100644 index 0000000..49bcc3c --- /dev/null +++ b/tests/input/my_container.zarr/temperature_dataset/day_in_d/values/.zarray @@ -0,0 +1,20 @@ +{ + "chunks": [ + 2 + ], + "compressor": { + "blocksize": 0, + "clevel": 5, + "cname": "lz4", + "id": "blosc", + "shuffle": 1 + }, + "dtype": " Date: Fri, 5 Jul 2024 21:16:59 -0700 Subject: [PATCH 09/38] Clean up --- docs/conf.py | 1 + .../dumpers/yaml_array_file_dumper.py | 4 ++-- src/linkml_arrays/dumpers/yaml_hdf5_dumper.py | 5 +++-- .../dumpers/yaml_numpy_dumper.py | 5 +++-- tests/array_classes_lol.py | 10 ++++++---- tests/test_dumpers/test_dumpers.py | 19 +++++++++---------- 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 9048edf..0d10d98 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -5,6 +5,7 @@ import os from datetime import date + from linkml_arrays import __version__ # -- Project information ----------------------------------------------------- diff --git a/src/linkml_arrays/dumpers/yaml_array_file_dumper.py b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py index e61fec4..f02adf2 100644 --- a/src/linkml_arrays/dumpers/yaml_array_file_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py @@ -1,10 +1,10 @@ """Base class for dumpling a LinkML model to a YAML file with paths to NumPy files.""" -from typing import Union, List -from pathlib import Path import os from abc import ABCMeta, abstractmethod from collections.abc import Callable +from pathlib import Path +from typing import List, Union import numpy as np import yaml diff --git a/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py b/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py index b6b348a..7579acf 100644 --- a/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py @@ -1,9 +1,10 @@ """Class for dumping a LinkML model to a YAML file with paths to HDF5 files.""" +from pathlib import Path +from typing import List, Union + import h5py import numpy as np -from pathlib import Path -from typing import Union, List from .yaml_array_file_dumper import YamlArrayFileDumper diff --git a/src/linkml_arrays/dumpers/yaml_numpy_dumper.py b/src/linkml_arrays/dumpers/yaml_numpy_dumper.py index a08f763..145b660 100644 --- a/src/linkml_arrays/dumpers/yaml_numpy_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_numpy_dumper.py @@ -1,8 +1,9 @@ """Class for dumpling a LinkML model to a YAML file with paths to NumPy files.""" -import numpy as np from pathlib import Path -from typing import Union, List +from typing import List, Union + +import numpy as np from .yaml_array_file_dumper import YamlArrayFileDumper diff --git a/tests/array_classes_lol.py b/tests/array_classes_lol.py index 3b043a8..4b2cb4c 100644 --- a/tests/array_classes_lol.py +++ b/tests/array_classes_lol.py @@ -1,10 +1,12 @@ from __future__ import annotations -from datetime import datetime, date -from decimal import Decimal -from enum import Enum + import re import sys -from typing import Any, ClassVar, List, Literal, Dict, Optional, Union +from datetime import date, datetime +from decimal import Decimal +from enum import Enum +from typing import Any, ClassVar, Dict, List, Literal, Optional, Union + from pydantic.version import VERSION as PYDANTIC_VERSION if int(PYDANTIC_VERSION[0]) >= 2: diff --git a/tests/test_dumpers/test_dumpers.py b/tests/test_dumpers/test_dumpers.py index c02a33a..23f12be 100644 --- a/tests/test_dumpers/test_dumpers.py +++ b/tests/test_dumpers/test_dumpers.py @@ -2,13 +2,13 @@ import os import unittest -import h5py -import zarr -from ruamel.yaml import YAML from pathlib import Path +import h5py import numpy as np +import zarr from linkml_runtime import SchemaView +from ruamel.yaml import YAML from linkml_arrays.dumpers import ( Hdf5Dumper, @@ -105,12 +105,12 @@ def test_yaml_hdf5_dumper(): assert actual == expected -def test_hdf5_dumper(): +def test_hdf5_dumper(tmp_path): """Test Hdf5Dumper dumping to an HDF5 file.""" container = create_container() schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") - output_file_path = "my_container.h5" + output_file_path = tmp_path / "my_container.h5" Hdf5Dumper().dumps(container, schemaview=schemaview, output_file_path=output_file_path) assert os.path.exists(output_file_path) @@ -135,20 +135,19 @@ def test_hdf5_dumper(): ) -def test_zarr_directory_store_dumper(): +def test_zarr_directory_store_dumper(tmp_path): """Test ZarrDumper dumping to an HDF5 file.""" container = create_container() schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") - output_file_path = "my_container.zarr" + output_file_path = tmp_path / "my_container.zarr" ZarrDirectoryStoreDumper().dumps( container, schemaview=schemaview, output_file_path=output_file_path ) - file_path = "my_container.zarr" - assert os.path.exists(file_path) + assert os.path.exists(output_file_path) - root = zarr.group(store=file_path) + root = zarr.group(store=output_file_path) # NOTE this is pretty much the same code as test_hdf5_dumper assert root.attrs["name"] == "my_container" assert set(root["latitude_series"].keys()) == set(["values"]) From 0af7a87f8f053dd8542aa2500115fe1aa66dc387 Mon Sep 17 00:00:00 2001 From: rly Date: Fri, 5 Jul 2024 21:30:05 -0700 Subject: [PATCH 10/38] Clean up --- .gitignore | 2 +- src/linkml_arrays/dumpers/hdf5_dumper.py | 2 +- src/linkml_arrays/dumpers/yaml_array_file_dumper.py | 9 ++++----- src/linkml_arrays/dumpers/yaml_dumper.py | 11 ++++++----- src/linkml_arrays/dumpers/yaml_hdf5_dumper.py | 7 +++++-- src/linkml_arrays/dumpers/yaml_numpy_dumper.py | 9 ++++++--- .../dumpers/zarr_directory_store_dumper.py | 6 +++--- src/linkml_arrays/loaders/yaml_loader.py | 5 +---- 8 files changed, 27 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 063aa16..4fc146e 100644 --- a/.gitignore +++ b/.gitignore @@ -131,4 +131,4 @@ dmypy.json .DS_Store /out/* /my_container.h5 -/my_container.zarr \ No newline at end of file +/my_container.zarr diff --git a/src/linkml_arrays/dumpers/hdf5_dumper.py b/src/linkml_arrays/dumpers/hdf5_dumper.py index 2a90137..eb50a03 100644 --- a/src/linkml_arrays/dumpers/hdf5_dumper.py +++ b/src/linkml_arrays/dumpers/hdf5_dumper.py @@ -15,7 +15,7 @@ def _iterate_element( ): """Recursively iterate through the elements of a LinkML model and save them. - Writes Pydantic BaseModel objects as groups, slots that implement "linkml:elements" + Write Pydantic BaseModel objects as groups, slots with the "array" element as datasets, and other slots as attributes. """ # get the type of the element diff --git a/src/linkml_arrays/dumpers/yaml_array_file_dumper.py b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py index f02adf2..71f10b8 100644 --- a/src/linkml_arrays/dumpers/yaml_array_file_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py @@ -1,4 +1,4 @@ -"""Base class for dumpling a LinkML model to a YAML file with paths to NumPy files.""" +"""Base class for dumping a LinkML model to a YAML file with paths to files containing individual arrays.""" import os from abc import ABCMeta, abstractmethod @@ -24,10 +24,9 @@ def _iterate_element( ): """Recursively iterate through the elements of a LinkML model and save them. - Returns a dictionary with the same structure as the input element, but with the slots - that implement "linkml:elements" (arrays) are written to HDF5 files and the paths to these - files are returned in the dictionary. Each array is written to an HDF5 dataset at path - "/data" in a new HDF5 file. + Return a dictionary with the same structure as the input element, but where the slots + with the "array" element are written to an array file and the paths to these + files are returned in the dictionary. The paths are relative to the output directory. Raises: ValueError: If the class requires an identifier and it is not provided. diff --git a/src/linkml_arrays/dumpers/yaml_dumper.py b/src/linkml_arrays/dumpers/yaml_dumper.py index b007a15..da9fd6b 100644 --- a/src/linkml_arrays/dumpers/yaml_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_dumper.py @@ -1,4 +1,4 @@ -"""Class for dumpling a LinkML model to a YAML file.""" +"""Class for dumping a LinkML model to a YAML file.""" from typing import Union @@ -14,8 +14,8 @@ def _iterate_element( ): """Recursively iterate through the elements of a LinkML model and save them. - Returns a dictionary with the same structure as the input element, but with the slots - that implement "linkml:elements" (arrays) are written as lists or lists of lists. + Returns a dictionary with the same structure as the input element, but where the slots + with the "array" element are written as lists of lists in YAML. Raises: ValueError: If the class requires an identifier and it is not provided. @@ -35,10 +35,11 @@ def _iterate_element( ret_dict = dict() for k, v in vars(element).items(): found_slot = schemaview.induced_slot(k, element_type) - if "linkml:elements" in found_slot.implements: + if found_slot.array: if id_slot is None and parent_identifier is None: raise ValueError("The class requires an identifier.") - ret_dict[k] = v.tolist() + assert isinstance(v, list) + ret_dict[k] = v else: if isinstance(v, BaseModel): v2 = _iterate_element(v, schemaview, id_value) diff --git a/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py b/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py index 7579acf..c790f0e 100644 --- a/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py @@ -10,7 +10,10 @@ class YamlHdf5Dumper(YamlArrayFileDumper): - """Dumper class for LinkML models to YAML files with paths to NumPy files.""" + """Dumper class for LinkML models to YAML files with paths to HDF5 files, one for each array. + + Each array is written to an HDF5 dataset at path "/data" in a new HDF5 file. + """ FILE_SUFFIX = ".h5" # used in parent class @@ -18,7 +21,7 @@ class YamlHdf5Dumper(YamlArrayFileDumper): def write_array( cls, array: Union[List, np.ndarray], output_file_path_no_suffix: Union[str, Path] ): - """Write an array to a file.""" + """Write an array to an HDF5 file.""" # TODO do not assume that there is only one by this name # add suffix to the file name output_file_path = output_file_path_no_suffix.parent / ( diff --git a/src/linkml_arrays/dumpers/yaml_numpy_dumper.py b/src/linkml_arrays/dumpers/yaml_numpy_dumper.py index 145b660..611bcdc 100644 --- a/src/linkml_arrays/dumpers/yaml_numpy_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_numpy_dumper.py @@ -1,4 +1,4 @@ -"""Class for dumpling a LinkML model to a YAML file with paths to NumPy files.""" +"""Class for dumping a LinkML model to a YAML file with paths to NumPy files.""" from pathlib import Path from typing import List, Union @@ -9,7 +9,10 @@ class YamlNumpyDumper(YamlArrayFileDumper): - """Dumper class for LinkML models to YAML files with paths to NumPy files.""" + """Dumper class for LinkML models to YAML files with paths to NumPy .npy files, one for each array. + + Each array is written to an HDF5 dataset at path "/data" in a new HDF5 file. + """ FILE_SUFFIX = ".npy" # used in parent class @@ -17,7 +20,7 @@ class YamlNumpyDumper(YamlArrayFileDumper): def write_array( cls, array: Union[List, np.ndarray], output_file_path_no_suffix: Union[str, Path] ): - """Write an array to a file.""" + """Write an array to a NumPy file.""" # TODO do not assume that there is only one by this name # add suffix to the file name output_file_path = output_file_path_no_suffix.parent / ( diff --git a/src/linkml_arrays/dumpers/zarr_directory_store_dumper.py b/src/linkml_arrays/dumpers/zarr_directory_store_dumper.py index 0dff5b7..ca4e1d2 100644 --- a/src/linkml_arrays/dumpers/zarr_directory_store_dumper.py +++ b/src/linkml_arrays/dumpers/zarr_directory_store_dumper.py @@ -15,8 +15,8 @@ def _iterate_element( ): """Recursively iterate through the elements of a LinkML model and save them. - Writes Pydantic BaseModel objects as groups, slots that implement "linkml:elements" - as datasets, and other slots as attributes. + Write Pydantic BaseModel objects as groups, slots with the "array" element + as arrays, and other slots as attributes. """ # get the type of the element element_type = type(element).__name__ @@ -24,7 +24,7 @@ def _iterate_element( for k, v in vars(element).items(): found_slot = schemaview.induced_slot(k, element_type) if found_slot.array: - # save the numpy array to an hdf5 dataset + # save the numpy array to a zarr array group.create_dataset(found_slot.name, data=v) else: if isinstance(v, BaseModel): diff --git a/src/linkml_arrays/loaders/yaml_loader.py b/src/linkml_arrays/loaders/yaml_loader.py index a37ff87..39da3aa 100644 --- a/src/linkml_arrays/loaders/yaml_loader.py +++ b/src/linkml_arrays/loaders/yaml_loader.py @@ -14,10 +14,7 @@ def _iterate_element( input_dict: dict, element_type: ClassDefinition, schemaview: SchemaView ) -> dict: - """Recursively iterate through the elements of a LinkML model and load them into a dict. - - Datasets are loaded into NumPy arrays. - """ + """Recursively iterate through the elements of a LinkML model and load them into a dict.""" ret_dict = dict() for k, v in input_dict.items(): found_slot = schemaview.induced_slot(k, element_type.name) From 1f6a7f563117c267938a7e98d03218cd04e2ca86 Mon Sep 17 00:00:00 2001 From: rly Date: Fri, 5 Jul 2024 21:33:26 -0700 Subject: [PATCH 11/38] Clean up --- tests/test_loaders/test_loaders.py | 51 ------------------------------ 1 file changed, 51 deletions(-) diff --git a/tests/test_loaders/test_loaders.py b/tests/test_loaders/test_loaders.py index fe97ab3..62985fd 100644 --- a/tests/test_loaders/test_loaders.py +++ b/tests/test_loaders/test_loaders.py @@ -101,54 +101,3 @@ def test_zarr_directory_store_loader(): ) check_container(container) - -# class Hdf5LoadersTestCase(unittest.TestCase): -# """Test loading of pydantic-style classes from an HDF5 file.""" - -# def test_load_pydantic_arrays(self): -# """Test loading of pydantic-style classes from an HDF5 file.""" -# file_path = str(Path(__file__).parent.parent / "input" / "my_temperature.h5") -# schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") -# ret = Hdf5Loader().loads(file_path, target_class=TemperatureDataset, schemaview=schemaview) - -# assert isinstance(ret, TemperatureDataset) -# assert ret.name == "my_temperature" - -# assert isinstance(ret.latitude_in_deg, LatitudeSeries) -# np.testing.assert_array_equal(ret.latitude_in_deg.values, np.array([1, 2, 3])) - -# assert isinstance(ret.longitude_in_deg, LongitudeSeries) -# np.testing.assert_array_equal(ret.longitude_in_deg.values, np.array([4, 5, 6])) - -# assert isinstance(ret.time_in_d, DaySeries) -# np.testing.assert_array_equal(ret.time_in_d.values, np.array([7, 8, 9])) - -# assert isinstance(ret.temperatures_in_K, TemperatureMatrix) -# np.testing.assert_array_equal(ret.temperatures_in_K.values, np.ones((3, 3, 3))) - - -# class ZarrDirectoryStoreLoadersTestCase(unittest.TestCase): -# """Test loading of pydantic-style classes from a Zarr directory store.""" - -# def test_load_pydantic_arrays(self): -# """Test loading of pydantic-style classes from a Zarr directory store.""" -# file_path = str(Path(__file__).parent.parent / "input" / "my_temperature.zarr") -# schemaview = SchemaView(Path(__file__) / "../../input/temperature_dataset.yaml") -# ret = ZarrDirectoryStoreLoader().loads( -# file_path, target_class=TemperatureDataset, schemaview=schemaview -# ) - -# assert isinstance(ret, TemperatureDataset) -# assert ret.name == "my_temperature" - -# assert isinstance(ret.latitude_in_deg, LatitudeSeries) -# np.testing.assert_array_equal(ret.latitude_in_deg.values, np.array([1, 2, 3])) - -# assert isinstance(ret.longitude_in_deg, LongitudeSeries) -# np.testing.assert_array_equal(ret.longitude_in_deg.values, np.array([4, 5, 6])) - -# assert isinstance(ret.time_in_d, DaySeries) -# np.testing.assert_array_equal(ret.time_in_d.values, np.array([7, 8, 9])) - -# assert isinstance(ret.temperatures_in_K, TemperatureMatrix) -# np.testing.assert_array_equal(ret.temperatures_in_K.values, np.ones((3, 3, 3))) From 188e5aab7f6526efcf3026d71ce29a3add39b069 Mon Sep 17 00:00:00 2001 From: rly Date: Sat, 6 Jul 2024 00:51:48 -0400 Subject: [PATCH 12/38] Clean up --- README.md | 4 +--- .../dumpers/yaml_array_file_dumper.py | 2 +- src/linkml_arrays/dumpers/yaml_dumper.py | 2 +- src/linkml_arrays/dumpers/yaml_hdf5_dumper.py | 4 ++-- .../dumpers/yaml_numpy_dumper.py | 4 ++-- src/linkml_arrays/loaders/yaml_loader.py | 1 - tests/test_dumpers/test_dumpers.py | 16 +++++++------- tests/test_loaders/test_loaders.py | 22 +++++++++---------- tox.ini | 22 ++++++++++++------- 9 files changed, 39 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 6037369..7dfed81 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,7 @@ Support for N-dimensional arrays in LinkML. # Quick reference for common commands ```bash -cd linkml-model -poetry run gen-json-schema tests/input/examples/schema_definition-array-2.yaml -poetry run gen-pydantic tests/input/examples/schema_definition-array-2.yaml +poetry run gen-pydantic tests/input/temperature_schema.yaml > tests/array_classes_lol.py ``` # Acknowledgements diff --git a/src/linkml_arrays/dumpers/yaml_array_file_dumper.py b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py index 71f10b8..bb2c377 100644 --- a/src/linkml_arrays/dumpers/yaml_array_file_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py @@ -1,4 +1,4 @@ -"""Base class for dumping a LinkML model to a YAML file with paths to files containing individual arrays.""" +"""Base class for dumping a LinkML model to YAML with paths to files containing arrays.""" import os from abc import ABCMeta, abstractmethod diff --git a/src/linkml_arrays/dumpers/yaml_dumper.py b/src/linkml_arrays/dumpers/yaml_dumper.py index da9fd6b..891c870 100644 --- a/src/linkml_arrays/dumpers/yaml_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_dumper.py @@ -1,4 +1,4 @@ -"""Class for dumping a LinkML model to a YAML file.""" +"""Class for dumping a LinkML model to YAML.""" from typing import Union diff --git a/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py b/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py index c790f0e..691be5d 100644 --- a/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py @@ -1,4 +1,4 @@ -"""Class for dumping a LinkML model to a YAML file with paths to HDF5 files.""" +"""Class for dumping a LinkML model to YAML with paths to HDF5 files.""" from pathlib import Path from typing import List, Union @@ -10,7 +10,7 @@ class YamlHdf5Dumper(YamlArrayFileDumper): - """Dumper class for LinkML models to YAML files with paths to HDF5 files, one for each array. + """Dumper class for LinkML models to YAML with paths to HDF5 files, one per array. Each array is written to an HDF5 dataset at path "/data" in a new HDF5 file. """ diff --git a/src/linkml_arrays/dumpers/yaml_numpy_dumper.py b/src/linkml_arrays/dumpers/yaml_numpy_dumper.py index 611bcdc..5f3eea3 100644 --- a/src/linkml_arrays/dumpers/yaml_numpy_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_numpy_dumper.py @@ -1,4 +1,4 @@ -"""Class for dumping a LinkML model to a YAML file with paths to NumPy files.""" +"""Class for dumping a LinkML model to YAML with paths to NumPy files.""" from pathlib import Path from typing import List, Union @@ -9,7 +9,7 @@ class YamlNumpyDumper(YamlArrayFileDumper): - """Dumper class for LinkML models to YAML files with paths to NumPy .npy files, one for each array. + """Dumper class for LinkML models to YAML with paths to .npy files, one per array. Each array is written to an HDF5 dataset at path "/data" in a new HDF5 file. """ diff --git a/src/linkml_arrays/loaders/yaml_loader.py b/src/linkml_arrays/loaders/yaml_loader.py index 39da3aa..3c691f9 100644 --- a/src/linkml_arrays/loaders/yaml_loader.py +++ b/src/linkml_arrays/loaders/yaml_loader.py @@ -2,7 +2,6 @@ from typing import Type, Union -import numpy as np import yaml from linkml_runtime import SchemaView from linkml_runtime.linkml_model import ClassDefinition diff --git a/tests/test_dumpers/test_dumpers.py b/tests/test_dumpers/test_dumpers.py index 23f12be..3b83bd5 100644 --- a/tests/test_dumpers/test_dumpers.py +++ b/tests/test_dumpers/test_dumpers.py @@ -1,7 +1,6 @@ """Test dumping LinkML pydantic models with arrays as lists-of-lists to various file formats.""" import os -import unittest from pathlib import Path import h5py @@ -30,7 +29,7 @@ INPUT_DIR = Path(__file__).parent.parent / "input" -def create_container() -> Container: +def _create_container() -> Container: latitude_in_deg = LatitudeInDegSeries(name="my_latitude", values=[[1, 2], [3, 4]]) longitude_in_deg = LongitudeInDegSeries(name="my_longitude", values=[[5, 6], [7, 8]]) date = DateSeries(values=["2020-01-01", "2020-01-02"]) @@ -39,9 +38,10 @@ def create_container() -> Container: conversion_factor=1000.0, values=[[[0, 1], [2, 3]], [[4, 5], [6, 7]]], ) + # NOTE: currently no way to pass in the actual LatitudeInDegSeries object temperature_dataset = TemperatureDataset( name="my_temperature", - latitude_in_deg="my_latitude", # currently no way to pass in the actual LatitudeInDegSeries object + latitude_in_deg="my_latitude", longitude_in_deg="my_longitude", date=date, day_in_d=days_in_d_since, @@ -59,7 +59,7 @@ def create_container() -> Container: def test_yaml_dumper(): """Test YamlDumper dumping to a YAML file.""" - container = create_container() + container = _create_container() schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") ret = YamlDumper().dumps(container, schemaview=schemaview) @@ -75,7 +75,7 @@ def test_yaml_dumper(): def test_yaml_numpy_dumper(): """Test YamlNumpyDumper dumping to a YAML file and NumPy .npy files in a directory.""" - container = create_container() + container = _create_container() schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") ret = YamlNumpyDumper().dumps(container, schemaview=schemaview, output_dir="./out") @@ -91,7 +91,7 @@ def test_yaml_numpy_dumper(): def test_yaml_hdf5_dumper(): """Test YamlNumpyDumper dumping to a YAML file and HDF5 datasets in a directory.""" - container = create_container() + container = _create_container() schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") ret = YamlHdf5Dumper().dumps(container, schemaview=schemaview, output_dir="./out") @@ -107,7 +107,7 @@ def test_yaml_hdf5_dumper(): def test_hdf5_dumper(tmp_path): """Test Hdf5Dumper dumping to an HDF5 file.""" - container = create_container() + container = _create_container() schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") output_file_path = tmp_path / "my_container.h5" @@ -137,7 +137,7 @@ def test_hdf5_dumper(tmp_path): def test_zarr_directory_store_dumper(tmp_path): """Test ZarrDumper dumping to an HDF5 file.""" - container = create_container() + container = _create_container() schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") output_file_path = tmp_path / "my_container.zarr" diff --git a/tests/test_loaders/test_loaders.py b/tests/test_loaders/test_loaders.py index 62985fd..20d5951 100644 --- a/tests/test_loaders/test_loaders.py +++ b/tests/test_loaders/test_loaders.py @@ -1,9 +1,7 @@ -"""Test loading data from various file formats into LinkML pydantic models with arrays as lists-of-lists.""" +"""Test loading data from various file formats into pydantic models with arrays as LoLs.""" -import unittest from pathlib import Path -import numpy as np from hbreader import hbread from linkml_runtime import SchemaView @@ -25,7 +23,7 @@ ) -def check_container(container: Container): +def _check_container(container: Container): assert isinstance(container, Container) assert container.name == "my_container" @@ -40,8 +38,9 @@ def check_container(container: Container): assert isinstance(container.temperature_dataset, TemperatureDataset) assert container.temperature_dataset.name == "my_temperature" assert container.temperature_dataset.latitude_in_deg == "my_latitude" - # currently no way to get the actual LatitudeInDegSeries object from the TemperatureDataset object - # because the TemperatureDataset Pydantic object expects a string for the latitude_in_deg field + # currently no way to get the actual LatitudeInDegSeries object from the + # TemperatureDataset object because the TemperatureDataset Pydantic object + # expects a string for the latitude_in_deg field # to be isomorphic with the json schema / yaml representation assert container.temperature_dataset.longitude_in_deg == "my_longitude" @@ -65,7 +64,7 @@ def test_yaml_loader(): data_yaml = hbread("container_yaml.yaml", base_path=str(Path(__file__) / "../../input")) schemaview = SchemaView(Path(__file__) / "../../input/temperature_schema.yaml") container = YamlLoader().loads(data_yaml, target_class=Container, schemaview=schemaview) - check_container(container) + _check_container(container) def test_yaml_numpy_loader(): @@ -73,7 +72,7 @@ def test_yaml_numpy_loader(): read_yaml = hbread("container_yaml_numpy.yaml", base_path=str(Path(__file__) / "../../input")) schemaview = SchemaView(Path(__file__) / "../../input/temperature_schema.yaml") container = YamlNumpyLoader().loads(read_yaml, target_class=Container, schemaview=schemaview) - check_container(container) + _check_container(container) def test_yaml_hdf5_loader(): @@ -81,7 +80,7 @@ def test_yaml_hdf5_loader(): read_yaml = hbread("container_yaml_hdf5.yaml", base_path=str(Path(__file__) / "../../input")) schemaview = SchemaView(Path(__file__) / "../../input/temperature_schema.yaml") container = YamlHdf5Loader().loads(read_yaml, target_class=Container, schemaview=schemaview) - check_container(container) + _check_container(container) def test_hdf5_loader(): @@ -89,7 +88,7 @@ def test_hdf5_loader(): file_path = str(Path(__file__).parent.parent / "input" / "my_container.h5") schemaview = SchemaView(Path(__file__) / "../../input/temperature_schema.yaml") container = Hdf5Loader().loads(file_path, target_class=Container, schemaview=schemaview) - check_container(container) + _check_container(container) def test_zarr_directory_store_loader(): @@ -99,5 +98,4 @@ def test_zarr_directory_store_loader(): container = ZarrDirectoryStoreLoader().loads( file_path, target_class=Container, schemaview=schemaview ) - check_container(container) - + _check_container(container) diff --git a/tox.ini b/tox.ini index 19869bd..75cdc10 100644 --- a/tox.ini +++ b/tox.ini @@ -53,7 +53,7 @@ description = Run documentation linters. skip_install = true deps = darglint - flake8<5.0.0 + flake8 flake8-black flake8-bandit flake8-bugbear @@ -73,14 +73,20 @@ description = Run the flake8 tool with several plugins (bandit, docstrings, impo [flake8] max-line-length = 100 ignore = - DAR101 # Missing parameter(s) in Docstring: - with_git_hash - DAR201 # Missing "Returns" in Docstring: - return - DAR301 # Missing "Yields" in Docstring: - yield - E111 # indentation is not a multiple of 4 - T201 # print found. - S101 # Use of assert detected. + DAR101 + DAR201 + DAR301 + E111 + T201 + S101 + ; DAR101 # Missing parameter(s) in Docstring: - with_git_hash + ; DAR201 # Missing "Returns" in Docstring: - return + ; DAR301 # Missing "Yields" in Docstring: - yield + ; E111 # indentation is not a multiple of 4 + ; T201 # print found. + ; S101 # Use of assert detected. exclude = - tests/test_dumpers/array_classes.py + tests/array_classes_lol.py [testenv:mypy] deps = mypy From 3a4d78563a983bd86b4c22fa774defa4112b4b4b Mon Sep 17 00:00:00 2001 From: rly Date: Sat, 6 Jul 2024 01:04:24 -0400 Subject: [PATCH 13/38] Clean up --- src/linkml_arrays/dumpers/yaml_array_file_dumper.py | 4 ++-- src/linkml_arrays/dumpers/yaml_hdf5_dumper.py | 2 ++ src/linkml_arrays/dumpers/yaml_numpy_dumper.py | 2 ++ tox.ini | 4 ++-- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/linkml_arrays/dumpers/yaml_array_file_dumper.py b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py index bb2c377..681cb35 100644 --- a/src/linkml_arrays/dumpers/yaml_array_file_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py @@ -4,7 +4,7 @@ from abc import ABCMeta, abstractmethod from collections.abc import Callable from pathlib import Path -from typing import List, Union +from typing import List, Optional, Union import numpy as np import yaml @@ -88,7 +88,7 @@ def dumps( self, element: Union[YAMLRoot, BaseModel], schemaview: SchemaView, - output_dir: Union[str, Path] = None, + output_dir: Optional[Union[str, Path]] = None, **kwargs, ) -> str: """Return element formatted as a YAML string.""" diff --git a/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py b/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py index 691be5d..1e7b438 100644 --- a/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py @@ -24,6 +24,8 @@ def write_array( """Write an array to an HDF5 file.""" # TODO do not assume that there is only one by this name # add suffix to the file name + if isinstance(output_file_path_no_suffix, str): + output_file_path_no_suffix = Path(output_file_path_no_suffix) output_file_path = output_file_path_no_suffix.parent / ( output_file_path_no_suffix.name + cls.FILE_SUFFIX ) diff --git a/src/linkml_arrays/dumpers/yaml_numpy_dumper.py b/src/linkml_arrays/dumpers/yaml_numpy_dumper.py index 5f3eea3..8e83a58 100644 --- a/src/linkml_arrays/dumpers/yaml_numpy_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_numpy_dumper.py @@ -23,6 +23,8 @@ def write_array( """Write an array to a NumPy file.""" # TODO do not assume that there is only one by this name # add suffix to the file name + if isinstance(output_file_path_no_suffix, str): + output_file_path_no_suffix = Path(output_file_path_no_suffix) output_file_path = output_file_path_no_suffix.parent / ( output_file_path_no_suffix.name + cls.FILE_SUFFIX ) diff --git a/tox.ini b/tox.ini index 75cdc10..741f9b9 100644 --- a/tox.ini +++ b/tox.ini @@ -15,7 +15,7 @@ envlist = lint flake8 mypy - docstr-coverage + ; docstr-coverage py [testenv] @@ -100,4 +100,4 @@ deps = docstr-coverage commands = docstr-coverage src/ tests/ --skip-private --skip-magic -description = Run the docstr-coverage tool to check documentation coverage \ No newline at end of file +description = Run the docstr-coverage tool to check documentation coverage From 077ca539ca3bdef88ff4dad9286e9f5d15db7c98 Mon Sep 17 00:00:00 2001 From: rly Date: Sat, 6 Jul 2024 22:38:32 -0400 Subject: [PATCH 14/38] Update array file format to be dict of sources --- .../dumpers/yaml_array_file_dumper.py | 24 ++++- src/linkml_arrays/dumpers/yaml_hdf5_dumper.py | 1 + .../dumpers/yaml_numpy_dumper.py | 1 + src/linkml_arrays/loaders/__init__.py | 6 +- .../loaders/yaml_array_file_loader.py | 89 +++++++++++++++++++ src/linkml_arrays/loaders/yaml_hdf5_loader.py | 62 ------------- .../loaders/yaml_numpy_loader.py | 61 ------------- tests/input/container_yaml_hdf5.yaml | 25 ++++-- tests/input/container_yaml_numpy.yaml | 25 ++++-- tests/test_loaders/test_loaders.py | 17 ++-- 10 files changed, 164 insertions(+), 147 deletions(-) create mode 100644 src/linkml_arrays/loaders/yaml_array_file_loader.py delete mode 100644 src/linkml_arrays/loaders/yaml_hdf5_loader.py delete mode 100644 src/linkml_arrays/loaders/yaml_numpy_loader.py diff --git a/src/linkml_arrays/dumpers/yaml_array_file_dumper.py b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py index 681cb35..18f9807 100644 --- a/src/linkml_arrays/dumpers/yaml_array_file_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py @@ -19,6 +19,7 @@ def _iterate_element( schemaview: SchemaView, output_dir: Path, write_array: Callable, + format: str, parent_identifier=None, inlined_name=None, ): @@ -69,11 +70,24 @@ def _iterate_element( # save the numpy array to file and write the file path to the dictionary output_file_path = write_array(v, output_file_path_no_suffix) - ret_dict[k] = f"file:./{output_file_path}" + ret_dict[k] = { + "source": [ + { + "file": f"./{output_file_path}", + "format": format, + } + ] + } else: if isinstance(v, BaseModel): v2 = _iterate_element( - v, schemaview, output_dir, write_array, id_value, inlined_name=found_slot.name + v, + schemaview, + output_dir, + write_array, + format, + id_value, + inlined_name=found_slot.name, ) ret_dict[k] = v2 else: @@ -84,6 +98,8 @@ def _iterate_element( class YamlArrayFileDumper(Dumper, metaclass=ABCMeta): """Base dumper class for LinkML models to YAML files with paths to array files.""" + # FORMAT is a class attribute that must be set by subclasses + def dumps( self, element: Union[YAMLRoot, BaseModel], @@ -94,7 +110,9 @@ def dumps( """Return element formatted as a YAML string.""" if output_dir is None: output_dir = "." - input = _iterate_element(element, schemaview, Path(output_dir), self.write_array) + input = _iterate_element( + element, schemaview, Path(output_dir), self.write_array, self.FORMAT + ) return yaml.dump(input) diff --git a/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py b/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py index 1e7b438..95a46c5 100644 --- a/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_hdf5_dumper.py @@ -16,6 +16,7 @@ class YamlHdf5Dumper(YamlArrayFileDumper): """ FILE_SUFFIX = ".h5" # used in parent class + FORMAT = "hdf5" @classmethod def write_array( diff --git a/src/linkml_arrays/dumpers/yaml_numpy_dumper.py b/src/linkml_arrays/dumpers/yaml_numpy_dumper.py index 8e83a58..62d4b6e 100644 --- a/src/linkml_arrays/dumpers/yaml_numpy_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_numpy_dumper.py @@ -15,6 +15,7 @@ class YamlNumpyDumper(YamlArrayFileDumper): """ FILE_SUFFIX = ".npy" # used in parent class + FORMAT = "numpy" @classmethod def write_array( diff --git a/src/linkml_arrays/loaders/__init__.py b/src/linkml_arrays/loaders/__init__.py index 0778b0d..af71135 100644 --- a/src/linkml_arrays/loaders/__init__.py +++ b/src/linkml_arrays/loaders/__init__.py @@ -1,15 +1,13 @@ """Dumper classes for linkml-arrays.""" from .hdf5_loader import Hdf5Loader -from .yaml_hdf5_loader import YamlHdf5Loader +from .yaml_array_file_loader import YamlArrayFileLoader from .yaml_loader import YamlLoader -from .yaml_numpy_loader import YamlNumpyLoader from .zarr_directory_store_loader import ZarrDirectoryStoreLoader __all__ = [ "Hdf5Loader", - "YamlHdf5Loader", + "YamlArrayFileLoader", "YamlLoader", - "YamlNumpyLoader", "ZarrDirectoryStoreLoader", ] diff --git a/src/linkml_arrays/loaders/yaml_array_file_loader.py b/src/linkml_arrays/loaders/yaml_array_file_loader.py new file mode 100644 index 0000000..d40b61d --- /dev/null +++ b/src/linkml_arrays/loaders/yaml_array_file_loader.py @@ -0,0 +1,89 @@ +"""Class for loading a LinkML model from a YAML file with arrays at supported file paths.""" + +from typing import Type, Union + +import h5py +import numpy as np +import yaml +from linkml_runtime import SchemaView +from linkml_runtime.linkml_model import ClassDefinition +from linkml_runtime.loaders.loader_root import Loader +from linkml_runtime.utils.yamlutils import YAMLRoot +from pydantic import BaseModel + + +def _iterate_element( + input_dict: dict, element_type: ClassDefinition, schemaview: SchemaView +) -> dict: + """Recursively iterate through the elements of a LinkML model and load them into a dict. + + Datasets are read into memory. + + Raises: + ValueError: If the array slot has no source or format, or if the format is not supported. + """ + ret_dict = dict() + for k, v in input_dict.items(): + found_slot = schemaview.induced_slot(k, element_type.name) + if found_slot.array: + sources = v.get("source", None) + if sources is None: + raise ValueError(f"Array slot {k} has no source.") + for source in sources: + format = source.get("format", None) + if format is None: + raise ValueError(f"Array slot {k}, source {source} has no format.") + if format == "hdf5": + file = source.get("file", None) + if file is None: + raise ValueError( + f"Array slot {k}, source {source}, format {format} has no file." + ) + array_file_path = file + with h5py.File(array_file_path, "r") as f: + # read all the values into memory TODO: support lazy loading + v = f["data"][()] + elif format == "numpy": + file = source.get("file", None) + if file is None: + raise ValueError( + f"Array slot {k}, source {source}, format {format} has no file." + ) + array_file_path = file + # read all the values into memory TODO: support lazy loading + v = np.load(array_file_path) + elif isinstance(v, dict): + found_slot_range = schemaview.get_class(found_slot.range) + v = _iterate_element(v, found_slot_range, schemaview) + # else: do not transform v + ret_dict[k] = v + + return ret_dict + + +class YamlArrayFileLoader(Loader): + """Class for loading a model from a YAML file with arrays at supported file paths.""" + + def load_any(self, source: str, **kwargs): + """Create an instance of the target class from a YAML file with arrays in files.""" + return self.load(source, **kwargs) + + def loads(self, source: str, **kwargs): + """Create an instance of the target class from a YAML file with arrays in files.""" + return self.load(source, **kwargs) + + def load( + self, + source: str, + target_class: Type[Union[YAMLRoot, BaseModel]], + schemaview: SchemaView, + **kwargs, + ): + """Create an instance of the target class from a YAML file with arrays in files.""" + input_dict = yaml.safe_load(source) + + element_type = schemaview.get_class(target_class.__name__) + element = _iterate_element(input_dict, element_type, schemaview) + obj = target_class(**element) + + return obj diff --git a/src/linkml_arrays/loaders/yaml_hdf5_loader.py b/src/linkml_arrays/loaders/yaml_hdf5_loader.py deleted file mode 100644 index e2b8289..0000000 --- a/src/linkml_arrays/loaders/yaml_hdf5_loader.py +++ /dev/null @@ -1,62 +0,0 @@ -"""Class for loading a LinkML model from a YAML file with HDF5 file paths.""" - -from typing import Type, Union - -import h5py -import yaml -from linkml_runtime import SchemaView -from linkml_runtime.linkml_model import ClassDefinition -from linkml_runtime.loaders.loader_root import Loader -from linkml_runtime.utils.yamlutils import YAMLRoot -from pydantic import BaseModel - - -def _iterate_element( - input_dict: dict, element_type: ClassDefinition, schemaview: SchemaView -) -> dict: - """Recursively iterate through the elements of a LinkML model and load them into a dict. - - Datasets are read into memory. - """ - ret_dict = dict() - for k, v in input_dict.items(): - found_slot = schemaview.induced_slot(k, element_type.name) - if found_slot.array: - array_file_path = v.replace("file:", "") - with h5py.File(array_file_path, "r") as f: - v = f["data"][()] # read all the values into memory TODO: support lazy loading - elif isinstance(v, dict): - found_slot_range = schemaview.get_class(found_slot.range) - v = _iterate_element(v, found_slot_range, schemaview) - # else: do not transform v - ret_dict[k] = v - - return ret_dict - - -class YamlHdf5Loader(Loader): - """Class for loading a LinkML model from a YAML file with HDF5 file paths.""" - - def load_any(self, source: str, **kwargs): - """Create an instance of the target class from a YAML file with HDF5 file paths.""" - return self.load(source, **kwargs) - - def loads(self, source: str, **kwargs): - """Create an instance of the target class from a YAML file with HDF5 file paths.""" - return self.load(source, **kwargs) - - def load( - self, - source: str, - target_class: Type[Union[YAMLRoot, BaseModel]], - schemaview: SchemaView, - **kwargs, - ): - """Create an instance of the target class from a YAML file with HDF5 file paths.""" - input_dict = yaml.safe_load(source) - - element_type = schemaview.get_class(target_class.__name__) - element = _iterate_element(input_dict, element_type, schemaview) - obj = target_class(**element) - - return obj diff --git a/src/linkml_arrays/loaders/yaml_numpy_loader.py b/src/linkml_arrays/loaders/yaml_numpy_loader.py deleted file mode 100644 index af9ee44..0000000 --- a/src/linkml_arrays/loaders/yaml_numpy_loader.py +++ /dev/null @@ -1,61 +0,0 @@ -"""Class for loading a LinkML model from a YAML file with NumPy file paths.""" - -from typing import Type, Union - -import numpy as np -import yaml -from linkml_runtime import SchemaView -from linkml_runtime.linkml_model import ClassDefinition -from linkml_runtime.loaders.loader_root import Loader -from linkml_runtime.utils.yamlutils import YAMLRoot -from pydantic import BaseModel - - -def _iterate_element( - input_dict: dict, element_type: ClassDefinition, schemaview: SchemaView -) -> dict: - """Recursively iterate through the elements of a LinkML model and load them into a dict. - - Datasets are read into memory. - """ - ret_dict = dict() - for k, v in input_dict.items(): - found_slot = schemaview.induced_slot(k, element_type.name) - if found_slot.array: - array_file_path = v.replace("file:", "") - v = np.load(array_file_path) # TODO: support lazy loading - elif isinstance(v, dict): - found_slot_range = schemaview.get_class(found_slot.range) - v = _iterate_element(v, found_slot_range, schemaview) - # else: do not transform v - ret_dict[k] = v - - return ret_dict - - -class YamlNumpyLoader(Loader): - """Class for loading a LinkML model from a YAML file with NumPy file paths.""" - - def load_any(self, source: str, **kwargs): - """Create an instance of the target class from a YAML file with NumPy file paths.""" - return self.load(source, **kwargs) - - def loads(self, source: str, **kwargs): - """Create an instance of the target class from a YAML file with NumPy file paths.""" - return self.load(source, **kwargs) - - def load( - self, - source: str, - target_class: Type[Union[YAMLRoot, BaseModel]], - schemaview: SchemaView, - **kwargs, - ): - """Create an instance of the target class from a YAML file with NumPy file paths.""" - input_dict = yaml.safe_load(source) - - element_type = schemaview.get_class(target_class.__name__) - element = _iterate_element(input_dict, element_type, schemaview) - obj = target_class(**element) - - return obj diff --git a/tests/input/container_yaml_hdf5.yaml b/tests/input/container_yaml_hdf5.yaml index 85396e8..b2e8d1a 100644 --- a/tests/input/container_yaml_hdf5.yaml +++ b/tests/input/container_yaml_hdf5.yaml @@ -1,19 +1,34 @@ name: my_container latitude_series: name: my_latitude - values: file:./out/my_latitude.values.h5 + values: + source: + - file: ./out/my_latitude.values.h5 + format: hdf5 longitude_series: name: my_longitude - values: file:./out/my_longitude.values.h5 + values: + source: + - file: ./out/my_longitude.values.h5 + format: hdf5 temperature_dataset: date: - values: file:./out/my_temperature.date.values.h5 + values: + source: + - file: ./out/my_temperature.date.values.h5 + format: hdf5 day_in_d: reference_date: '2020-01-01' - values: file:./out/my_temperature.day_in_d.values.h5 + values: + source: + - file: ./out/my_temperature.day_in_d.values.h5 + format: hdf5 latitude_in_deg: my_latitude longitude_in_deg: my_longitude name: my_temperature temperatures_in_K: conversion_factor: 1000.0 - values: file:./out/my_temperature.temperatures_in_K.values.h5 \ No newline at end of file + values: + source: + - file: ./out/my_temperature.temperatures_in_K.values.h5 + format: hdf5 diff --git a/tests/input/container_yaml_numpy.yaml b/tests/input/container_yaml_numpy.yaml index 83939a4..1e8d765 100644 --- a/tests/input/container_yaml_numpy.yaml +++ b/tests/input/container_yaml_numpy.yaml @@ -1,19 +1,34 @@ name: my_container latitude_series: name: my_latitude - values: file:./out/my_latitude.values.npy + values: + source: + - file: "./out/my_latitude.values.npy" + format: numpy longitude_series: name: my_longitude - values: file:./out/my_longitude.values.npy + values: + source: + - file: "./out/my_longitude.values.npy" + format: numpy temperature_dataset: date: - values: file:./out/my_temperature.date.values.npy + values: + source: + - file: "./out/my_temperature.date.values.npy" + format: numpy day_in_d: reference_date: '2020-01-01' - values: file:./out/my_temperature.day_in_d.values.npy + values: + source: + - file: "./out/my_temperature.day_in_d.values.npy" + format: numpy latitude_in_deg: my_latitude longitude_in_deg: my_longitude name: my_temperature temperatures_in_K: conversion_factor: 1000.0 - values: file:./out/my_temperature.temperatures_in_K.values.npy \ No newline at end of file + values: + source: + - file: "./out/my_temperature.temperatures_in_K.values.npy" + format: numpy diff --git a/tests/test_loaders/test_loaders.py b/tests/test_loaders/test_loaders.py index 20d5951..ca6e481 100644 --- a/tests/test_loaders/test_loaders.py +++ b/tests/test_loaders/test_loaders.py @@ -7,9 +7,8 @@ from linkml_arrays.loaders import ( Hdf5Loader, - YamlHdf5Loader, + YamlArrayFileLoader, YamlLoader, - YamlNumpyLoader, ZarrDirectoryStoreLoader, ) from tests.array_classes_lol import ( @@ -67,19 +66,23 @@ def test_yaml_loader(): _check_container(container) -def test_yaml_numpy_loader(): +def test_yaml_array_file_loader_numpy(): """Test loading of pydantic-style classes from YAML + Numpy arrays.""" read_yaml = hbread("container_yaml_numpy.yaml", base_path=str(Path(__file__) / "../../input")) schemaview = SchemaView(Path(__file__) / "../../input/temperature_schema.yaml") - container = YamlNumpyLoader().loads(read_yaml, target_class=Container, schemaview=schemaview) + container = YamlArrayFileLoader().loads( + read_yaml, target_class=Container, schemaview=schemaview + ) _check_container(container) -def test_yaml_hdf5_loader(): - """Test loading of pydantic-style classes from YAML + Numpy arrays.""" +def test_yaml_array_file_loader_hdf5(): + """Test loading of pydantic-style classes from YAML + HDF5 arrays.""" read_yaml = hbread("container_yaml_hdf5.yaml", base_path=str(Path(__file__) / "../../input")) schemaview = SchemaView(Path(__file__) / "../../input/temperature_schema.yaml") - container = YamlHdf5Loader().loads(read_yaml, target_class=Container, schemaview=schemaview) + container = YamlArrayFileLoader().loads( + read_yaml, target_class=Container, schemaview=schemaview + ) _check_container(container) From 175c882d1ecfaf1ac6ee6d6824b3e518ea0b9509 Mon Sep 17 00:00:00 2001 From: rly Date: Sat, 6 Jul 2024 23:09:42 -0400 Subject: [PATCH 15/38] Update deps, remove cookiecutter cli --- poetry.lock | 3658 ++++++++----------------------------- pyproject.toml | 61 +- src/linkml_arrays/cli.py | 44 - src/linkml_arrays/main.py | 10 - 4 files changed, 794 insertions(+), 2979 deletions(-) delete mode 100644 src/linkml_arrays/cli.py delete mode 100644 src/linkml_arrays/main.py diff --git a/poetry.lock b/poetry.lock index 94d24ca..5b6abd4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,136 +1,16 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. - -[[package]] -name = "alabaster" -version = "0.7.16" -description = "A light, configurable Sphinx theme" -optional = false -python-versions = ">=3.9" -files = [ - {file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"}, - {file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"}, -] +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "annotated-types" -version = "0.6.0" +version = "0.7.0" description = "Reusable constraint types to use with typing.Annotated" optional = false python-versions = ">=3.8" files = [ - {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, - {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, -] - -[[package]] -name = "anyio" -version = "4.2.0" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.8" -files = [ - {file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"}, - {file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"}, -] - -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} - -[package.extras] -doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (>=0.23)"] - -[[package]] -name = "appnope" -version = "0.1.4" -description = "Disable App Nap on macOS >= 10.9" -optional = false -python-versions = ">=3.6" -files = [ - {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, - {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, -] - -[[package]] -name = "argon2-cffi" -version = "23.1.0" -description = "Argon2 for Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea"}, - {file = "argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08"}, -] - -[package.dependencies] -argon2-cffi-bindings = "*" - -[package.extras] -dev = ["argon2-cffi[tests,typing]", "tox (>4)"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-copybutton", "sphinx-notfound-page"] -tests = ["hypothesis", "pytest"] -typing = ["mypy"] - -[[package]] -name = "argon2-cffi-bindings" -version = "21.2.0" -description = "Low-level CFFI bindings for Argon2" -optional = false -python-versions = ">=3.6" -files = [ - {file = "argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f"}, - {file = "argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a"}, -] - -[package.dependencies] -cffi = ">=1.0.1" - -[package.extras] -dev = ["cogapp", "pre-commit", "pytest", "wheel"] -tests = ["pytest"] - -[[package]] -name = "arrow" -version = "1.3.0" -description = "Better dates & times for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80"}, - {file = "arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"}, + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, ] -[package.dependencies] -python-dateutil = ">=2.7.0" -types-python-dateutil = ">=2.8.10" - -[package.extras] -doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"] -test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"] - [[package]] name = "asciitree" version = "0.3.3" @@ -141,38 +21,6 @@ files = [ {file = "asciitree-0.3.3.tar.gz", hash = "sha256:4aa4b9b649f85e3fcb343363d97564aa1fb62e249677f2e18a96765145cc0f6e"}, ] -[[package]] -name = "asttokens" -version = "2.4.1" -description = "Annotate AST trees with source code positions" -optional = false -python-versions = "*" -files = [ - {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, - {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, -] - -[package.dependencies] -six = ">=1.12.0" - -[package.extras] -astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] -test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] - -[[package]] -name = "async-lru" -version = "2.0.4" -description = "Simple LRU cache for asyncio" -optional = false -python-versions = ">=3.8" -files = [ - {file = "async-lru-2.0.4.tar.gz", hash = "sha256:b8a59a5df60805ff63220b2a0c5b5393da5521b113cd5465a44eb037d81a5627"}, - {file = "async_lru-2.0.4-py3-none-any.whl", hash = "sha256:ff02944ce3c288c5be660c42dbcca0742b32c3b279d6dceda655190240b99224"}, -] - -[package.dependencies] -typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} - [[package]] name = "attrs" version = "23.2.0" @@ -193,179 +41,38 @@ tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] [[package]] -name = "babel" -version = "2.14.0" -description = "Internationalization utilities" +name = "cachetools" +version = "5.3.3" +description = "Extensible memoizing collections and decorators" optional = false python-versions = ">=3.7" files = [ - {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"}, - {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"}, -] - -[package.extras] -dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] - -[[package]] -name = "beautifulsoup4" -version = "4.12.3" -description = "Screen-scraping library" -optional = false -python-versions = ">=3.6.0" -files = [ - {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, - {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, -] - -[package.dependencies] -soupsieve = ">1.2" - -[package.extras] -cchardet = ["cchardet"] -chardet = ["chardet"] -charset-normalizer = ["charset-normalizer"] -html5lib = ["html5lib"] -lxml = ["lxml"] - -[[package]] -name = "black" -version = "24.1.1" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.8" -files = [ - {file = "black-24.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2588021038bd5ada078de606f2a804cadd0a3cc6a79cb3e9bb3a8bf581325a4c"}, - {file = "black-24.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a95915c98d6e32ca43809d46d932e2abc5f1f7d582ffbe65a5b4d1588af7445"}, - {file = "black-24.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fa6a0e965779c8f2afb286f9ef798df770ba2b6cee063c650b96adec22c056a"}, - {file = "black-24.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:5242ecd9e990aeb995b6d03dc3b2d112d4a78f2083e5a8e86d566340ae80fec4"}, - {file = "black-24.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fc1ec9aa6f4d98d022101e015261c056ddebe3da6a8ccfc2c792cbe0349d48b7"}, - {file = "black-24.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0269dfdea12442022e88043d2910429bed717b2d04523867a85dacce535916b8"}, - {file = "black-24.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3d64db762eae4a5ce04b6e3dd745dcca0fb9560eb931a5be97472e38652a161"}, - {file = "black-24.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:5d7b06ea8816cbd4becfe5f70accae953c53c0e53aa98730ceccb0395520ee5d"}, - {file = "black-24.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e2c8dfa14677f90d976f68e0c923947ae68fa3961d61ee30976c388adc0b02c8"}, - {file = "black-24.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a21725862d0e855ae05da1dd25e3825ed712eaaccef6b03017fe0853a01aa45e"}, - {file = "black-24.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07204d078e25327aad9ed2c64790d681238686bce254c910de640c7cc4fc3aa6"}, - {file = "black-24.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:a83fe522d9698d8f9a101b860b1ee154c1d25f8a82ceb807d319f085b2627c5b"}, - {file = "black-24.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:08b34e85170d368c37ca7bf81cf67ac863c9d1963b2c1780c39102187ec8dd62"}, - {file = "black-24.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7258c27115c1e3b5de9ac6c4f9957e3ee2c02c0b39222a24dc7aa03ba0e986f5"}, - {file = "black-24.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40657e1b78212d582a0edecafef133cf1dd02e6677f539b669db4746150d38f6"}, - {file = "black-24.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e298d588744efda02379521a19639ebcd314fba7a49be22136204d7ed1782717"}, - {file = "black-24.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:34afe9da5056aa123b8bfda1664bfe6fb4e9c6f311d8e4a6eb089da9a9173bf9"}, - {file = "black-24.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:854c06fb86fd854140f37fb24dbf10621f5dab9e3b0c29a690ba595e3d543024"}, - {file = "black-24.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3897ae5a21ca132efa219c029cce5e6bfc9c3d34ed7e892113d199c0b1b444a2"}, - {file = "black-24.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:ecba2a15dfb2d97105be74bbfe5128bc5e9fa8477d8c46766505c1dda5883aac"}, - {file = "black-24.1.1-py3-none-any.whl", hash = "sha256:5cdc2e2195212208fbcae579b931407c1fa9997584f0a415421748aeafff1168"}, - {file = "black-24.1.1.tar.gz", hash = "sha256:48b5760dcbfe5cf97fd4fba23946681f3a81514c6ab8a45b50da67ac8fbc6c7b"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - -[[package]] -name = "bleach" -version = "6.1.0" -description = "An easy safelist-based HTML-sanitizing tool." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6"}, - {file = "bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe"}, + {file = "cachetools-5.3.3-py3-none-any.whl", hash = "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945"}, + {file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"}, ] -[package.dependencies] -six = ">=1.9.0" -webencodings = "*" - -[package.extras] -css = ["tinycss2 (>=1.1.0,<1.3)"] - [[package]] name = "certifi" -version = "2024.2.2" +version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, - {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, ] [[package]] -name = "cffi" -version = "1.16.0" -description = "Foreign Function Interface for Python calling C code." +name = "chardet" +version = "5.2.0" +description = "Universal encoding detector for Python 3" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, - {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, - {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, - {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, - {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, - {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, - {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, - {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, - {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, - {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, - {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, - {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, - {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, - {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, - {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, + {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, + {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, ] -[package.dependencies] -pycparser = "*" - [[package]] name = "charset-normalizer" version = "3.3.2" @@ -490,32 +197,15 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] -[[package]] -name = "comm" -version = "0.2.1" -description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." -optional = false -python-versions = ">=3.8" -files = [ - {file = "comm-0.2.1-py3-none-any.whl", hash = "sha256:87928485c0dfc0e7976fd89fc1e187023cf587e7c353e4a9b417555b44adf021"}, - {file = "comm-0.2.1.tar.gz", hash = "sha256:0bc91edae1344d39d3661dcbc36937181fdaddb304790458f8b044dbc064b89a"}, -] - -[package.dependencies] -traitlets = ">=4" - -[package.extras] -test = ["pytest"] - [[package]] name = "curies" -version = "0.7.7" +version = "0.7.9" description = "Idiomatic conversion between URIs and compact URIs (CURIEs)." optional = false python-versions = ">=3.8" files = [ - {file = "curies-0.7.7-py3-none-any.whl", hash = "sha256:609de3e8cdf39f410e8f4d9f06eb7df379465860f4fb441bf0e79672430f8e2a"}, - {file = "curies-0.7.7.tar.gz", hash = "sha256:a8d674029f906fb9c3564eafa0862ce96725932bd801fa751e076265b111cb34"}, + {file = "curies-0.7.9-py3-none-any.whl", hash = "sha256:e4c5beb91642376953c94db0ee2fb5d2b011c3b16749516436114ba61442f260"}, + {file = "curies-0.7.9.tar.gz", hash = "sha256:3b63c5fea7b0e967629a3a384b1a8c59b56c503487c1dcbacddeab59e25db4d8"}, ] [package.dependencies] @@ -531,55 +221,6 @@ pandas = ["pandas"] rdflib = ["rdflib"] tests = ["coverage", "pytest"] -[[package]] -name = "debugpy" -version = "1.8.0" -description = "An implementation of the Debug Adapter Protocol for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "debugpy-1.8.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:7fb95ca78f7ac43393cd0e0f2b6deda438ec7c5e47fa5d38553340897d2fbdfb"}, - {file = "debugpy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef9ab7df0b9a42ed9c878afd3eaaff471fce3fa73df96022e1f5c9f8f8c87ada"}, - {file = "debugpy-1.8.0-cp310-cp310-win32.whl", hash = "sha256:a8b7a2fd27cd9f3553ac112f356ad4ca93338feadd8910277aff71ab24d8775f"}, - {file = "debugpy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:5d9de202f5d42e62f932507ee8b21e30d49aae7e46d5b1dd5c908db1d7068637"}, - {file = "debugpy-1.8.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:ef54404365fae8d45cf450d0544ee40cefbcb9cb85ea7afe89a963c27028261e"}, - {file = "debugpy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60009b132c91951354f54363f8ebdf7457aeb150e84abba5ae251b8e9f29a8a6"}, - {file = "debugpy-1.8.0-cp311-cp311-win32.whl", hash = "sha256:8cd0197141eb9e8a4566794550cfdcdb8b3db0818bdf8c49a8e8f8053e56e38b"}, - {file = "debugpy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:a64093656c4c64dc6a438e11d59369875d200bd5abb8f9b26c1f5f723622e153"}, - {file = "debugpy-1.8.0-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:b05a6b503ed520ad58c8dc682749113d2fd9f41ffd45daec16e558ca884008cd"}, - {file = "debugpy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c6fb41c98ec51dd010d7ed650accfd07a87fe5e93eca9d5f584d0578f28f35f"}, - {file = "debugpy-1.8.0-cp38-cp38-win32.whl", hash = "sha256:46ab6780159eeabb43c1495d9c84cf85d62975e48b6ec21ee10c95767c0590aa"}, - {file = "debugpy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:bdc5ef99d14b9c0fcb35351b4fbfc06ac0ee576aeab6b2511702e5a648a2e595"}, - {file = "debugpy-1.8.0-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:61eab4a4c8b6125d41a34bad4e5fe3d2cc145caecd63c3fe953be4cc53e65bf8"}, - {file = "debugpy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:125b9a637e013f9faac0a3d6a82bd17c8b5d2c875fb6b7e2772c5aba6d082332"}, - {file = "debugpy-1.8.0-cp39-cp39-win32.whl", hash = "sha256:57161629133113c97b387382045649a2b985a348f0c9366e22217c87b68b73c6"}, - {file = "debugpy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:e3412f9faa9ade82aa64a50b602544efcba848c91384e9f93497a458767e6926"}, - {file = "debugpy-1.8.0-py2.py3-none-any.whl", hash = "sha256:9c9b0ac1ce2a42888199df1a1906e45e6f3c9555497643a85e0bf2406e3ffbc4"}, - {file = "debugpy-1.8.0.zip", hash = "sha256:12af2c55b419521e33d5fb21bd022df0b5eb267c3e178f1d374a63a2a6bdccd0"}, -] - -[[package]] -name = "decorator" -version = "5.1.1" -description = "Decorators for Humans" -optional = false -python-versions = ">=3.5" -files = [ - {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, - {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, -] - -[[package]] -name = "defusedxml" -version = "0.7.1" -description = "XML bomb protection for Python stdlib modules" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, - {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, -] - [[package]] name = "deprecated" version = "1.2.14" @@ -608,45 +249,20 @@ files = [ {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, ] -[[package]] -name = "docutils" -version = "0.18.1" -description = "Docutils -- Python Documentation Utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"}, - {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"}, -] - [[package]] name = "exceptiongroup" -version = "1.2.0" +version = "1.2.1" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, - {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, + {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, + {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, ] [package.extras] test = ["pytest (>=6)"] -[[package]] -name = "executing" -version = "2.0.1" -description = "Get the currently executing AST node of a frame, and other information" -optional = false -python-versions = ">=3.5" -files = [ - {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, - {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, -] - -[package.extras] -tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] - [[package]] name = "fasteners" version = "0.19" @@ -658,163 +274,50 @@ files = [ {file = "fasteners-0.19.tar.gz", hash = "sha256:b4f37c3ac52d8a445af3a66bce57b33b5e90b97c696b7b984f530cf8f0ded09c"}, ] -[[package]] -name = "fastjsonschema" -version = "2.19.1" -description = "Fastest Python implementation of JSON schema" -optional = false -python-versions = "*" -files = [ - {file = "fastjsonschema-2.19.1-py3-none-any.whl", hash = "sha256:3672b47bc94178c9f23dbb654bf47440155d4db9df5f7bc47643315f9c405cd0"}, - {file = "fastjsonschema-2.19.1.tar.gz", hash = "sha256:e3126a94bdc4623d3de4485f8d468a12f02a67921315ddc87836d6e456dc789d"}, -] - -[package.extras] -devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] - [[package]] name = "filelock" -version = "3.13.1" +version = "3.15.4" description = "A platform independent file lock." optional = false python-versions = ">=3.8" files = [ - {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, - {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, + {file = "filelock-3.15.4-py3-none-any.whl", hash = "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7"}, + {file = "filelock-3.15.4.tar.gz", hash = "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)", "virtualenv (>=20.26.2)"] typing = ["typing-extensions (>=4.8)"] -[[package]] -name = "fqdn" -version = "1.5.1" -description = "Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers" -optional = false -python-versions = ">=2.7, !=3.0, !=3.1, !=3.2, !=3.3, !=3.4, <4" -files = [ - {file = "fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014"}, - {file = "fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f"}, -] - -[[package]] -name = "greenlet" -version = "2.0.1" -description = "Lightweight in-process concurrent programming" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" -files = [ - {file = "greenlet-2.0.1-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:9ed358312e63bf683b9ef22c8e442ef6c5c02973f0c2a939ec1d7b50c974015c"}, - {file = "greenlet-2.0.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4f09b0010e55bec3239278f642a8a506b91034f03a4fb28289a7d448a67f1515"}, - {file = "greenlet-2.0.1-cp27-cp27m-win32.whl", hash = "sha256:1407fe45246632d0ffb7a3f4a520ba4e6051fc2cbd61ba1f806900c27f47706a"}, - {file = "greenlet-2.0.1-cp27-cp27m-win_amd64.whl", hash = "sha256:3001d00eba6bbf084ae60ec7f4bb8ed375748f53aeaefaf2a37d9f0370558524"}, - {file = "greenlet-2.0.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d566b82e92ff2e09dd6342df7e0eb4ff6275a3f08db284888dcd98134dbd4243"}, - {file = "greenlet-2.0.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:0722c9be0797f544a3ed212569ca3fe3d9d1a1b13942d10dd6f0e8601e484d26"}, - {file = "greenlet-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d37990425b4687ade27810e3b1a1c37825d242ebc275066cfee8cb6b8829ccd"}, - {file = "greenlet-2.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be35822f35f99dcc48152c9839d0171a06186f2d71ef76dc57fa556cc9bf6b45"}, - {file = "greenlet-2.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c140e7eb5ce47249668056edf3b7e9900c6a2e22fb0eaf0513f18a1b2c14e1da"}, - {file = "greenlet-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d21681f09e297a5adaa73060737e3aa1279a13ecdcfcc6ef66c292cb25125b2d"}, - {file = "greenlet-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fb412b7db83fe56847df9c47b6fe3f13911b06339c2aa02dcc09dce8bbf582cd"}, - {file = "greenlet-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:c6a08799e9e88052221adca55741bf106ec7ea0710bca635c208b751f0d5b617"}, - {file = "greenlet-2.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9e112e03d37987d7b90c1e98ba5e1b59e1645226d78d73282f45b326f7bddcb9"}, - {file = "greenlet-2.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56961cfca7da2fdd178f95ca407fa330c64f33289e1804b592a77d5593d9bd94"}, - {file = "greenlet-2.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:13ba6e8e326e2116c954074c994da14954982ba2795aebb881c07ac5d093a58a"}, - {file = "greenlet-2.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bf633a50cc93ed17e494015897361010fc08700d92676c87931d3ea464123ce"}, - {file = "greenlet-2.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9f2c221eecb7ead00b8e3ddb913c67f75cba078fd1d326053225a3f59d850d72"}, - {file = "greenlet-2.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:13ebf93c343dd8bd010cd98e617cb4c1c1f352a0cf2524c82d3814154116aa82"}, - {file = "greenlet-2.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:6f61d71bbc9b4a3de768371b210d906726535d6ca43506737682caa754b956cd"}, - {file = "greenlet-2.0.1-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:2d0bac0385d2b43a7bd1d651621a4e0f1380abc63d6fb1012213a401cbd5bf8f"}, - {file = "greenlet-2.0.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:f6327b6907b4cb72f650a5b7b1be23a2aab395017aa6f1adb13069d66360eb3f"}, - {file = "greenlet-2.0.1-cp35-cp35m-win32.whl", hash = "sha256:81b0ea3715bf6a848d6f7149d25bf018fd24554a4be01fcbbe3fdc78e890b955"}, - {file = "greenlet-2.0.1-cp35-cp35m-win_amd64.whl", hash = "sha256:38255a3f1e8942573b067510f9611fc9e38196077b0c8eb7a8c795e105f9ce77"}, - {file = "greenlet-2.0.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:04957dc96669be041e0c260964cfef4c77287f07c40452e61abe19d647505581"}, - {file = "greenlet-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:4aeaebcd91d9fee9aa768c1b39cb12214b30bf36d2b7370505a9f2165fedd8d9"}, - {file = "greenlet-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:974a39bdb8c90a85982cdb78a103a32e0b1be986d411303064b28a80611f6e51"}, - {file = "greenlet-2.0.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dca09dedf1bd8684767bc736cc20c97c29bc0c04c413e3276e0962cd7aeb148"}, - {file = "greenlet-2.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4c0757db9bd08470ff8277791795e70d0bf035a011a528ee9a5ce9454b6cba2"}, - {file = "greenlet-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:5067920de254f1a2dee8d3d9d7e4e03718e8fd2d2d9db962c8c9fa781ae82a39"}, - {file = "greenlet-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:5a8e05057fab2a365c81abc696cb753da7549d20266e8511eb6c9d9f72fe3e92"}, - {file = "greenlet-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:3d75b8d013086b08e801fbbb896f7d5c9e6ccd44f13a9241d2bf7c0df9eda928"}, - {file = "greenlet-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:097e3dae69321e9100202fc62977f687454cd0ea147d0fd5a766e57450c569fd"}, - {file = "greenlet-2.0.1-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:cb242fc2cda5a307a7698c93173d3627a2a90d00507bccf5bc228851e8304963"}, - {file = "greenlet-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:72b00a8e7c25dcea5946692a2485b1a0c0661ed93ecfedfa9b6687bd89a24ef5"}, - {file = "greenlet-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5b0ff9878333823226d270417f24f4d06f235cb3e54d1103b71ea537a6a86ce"}, - {file = "greenlet-2.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be9e0fb2ada7e5124f5282d6381903183ecc73ea019568d6d63d33f25b2a9000"}, - {file = "greenlet-2.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b493db84d124805865adc587532ebad30efa68f79ad68f11b336e0a51ec86c2"}, - {file = "greenlet-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0459d94f73265744fee4c2d5ec44c6f34aa8a31017e6e9de770f7bcf29710be9"}, - {file = "greenlet-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a20d33124935d27b80e6fdacbd34205732660e0a1d35d8b10b3328179a2b51a1"}, - {file = "greenlet-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:ea688d11707d30e212e0110a1aac7f7f3f542a259235d396f88be68b649e47d1"}, - {file = "greenlet-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:afe07421c969e259e9403c3bb658968702bc3b78ec0b6fde3ae1e73440529c23"}, - {file = "greenlet-2.0.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:cd4ccc364cf75d1422e66e247e52a93da6a9b73cefa8cad696f3cbbb75af179d"}, - {file = "greenlet-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4c8b1c43e75c42a6cafcc71defa9e01ead39ae80bd733a2608b297412beede68"}, - {file = "greenlet-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:659f167f419a4609bc0516fb18ea69ed39dbb25594934bd2dd4d0401660e8a1e"}, - {file = "greenlet-2.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:356e4519d4dfa766d50ecc498544b44c0249b6de66426041d7f8b751de4d6b48"}, - {file = "greenlet-2.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:811e1d37d60b47cb8126e0a929b58c046251f28117cb16fcd371eed61f66b764"}, - {file = "greenlet-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d38ffd0e81ba8ef347d2be0772e899c289b59ff150ebbbbe05dc61b1246eb4e0"}, - {file = "greenlet-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0109af1138afbfb8ae647e31a2b1ab030f58b21dd8528c27beaeb0093b7938a9"}, - {file = "greenlet-2.0.1-cp38-cp38-win32.whl", hash = "sha256:88c8d517e78acdf7df8a2134a3c4b964415b575d2840a2746ddb1cc6175f8608"}, - {file = "greenlet-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:d6ee1aa7ab36475035eb48c01efae87d37936a8173fc4d7b10bb02c2d75dd8f6"}, - {file = "greenlet-2.0.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:b1992ba9d4780d9af9726bbcef6a1db12d9ab1ccc35e5773685a24b7fb2758eb"}, - {file = "greenlet-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:b5e83e4de81dcc9425598d9469a624826a0b1211380ac444c7c791d4a2137c19"}, - {file = "greenlet-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:505138d4fa69462447a562a7c2ef723c6025ba12ac04478bc1ce2fcc279a2db5"}, - {file = "greenlet-2.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cce1e90dd302f45716a7715517c6aa0468af0bf38e814ad4eab58e88fc09f7f7"}, - {file = "greenlet-2.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e9744c657d896c7b580455e739899e492a4a452e2dd4d2b3e459f6b244a638d"}, - {file = "greenlet-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:662e8f7cad915ba75d8017b3e601afc01ef20deeeabf281bd00369de196d7726"}, - {file = "greenlet-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:41b825d65f31e394b523c84db84f9383a2f7eefc13d987f308f4663794d2687e"}, - {file = "greenlet-2.0.1-cp39-cp39-win32.whl", hash = "sha256:db38f80540083ea33bdab614a9d28bcec4b54daa5aff1668d7827a9fc769ae0a"}, - {file = "greenlet-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:b23d2a46d53210b498e5b701a1913697671988f4bf8e10f935433f6e7c332fb6"}, - {file = "greenlet-2.0.1.tar.gz", hash = "sha256:42e602564460da0e8ee67cb6d7236363ee5e131aa15943b6670e44e5c2ed0f67"}, -] - -[package.extras] -docs = ["Sphinx", "docutils (<0.18)"] -test = ["faulthandler", "objgraph", "psutil"] - -[[package]] -name = "h11" -version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.7" -files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] - [[package]] name = "h5py" -version = "3.10.0" +version = "3.11.0" description = "Read and write HDF5 files from Python" optional = false python-versions = ">=3.8" files = [ - {file = "h5py-3.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b963fb772964fc1d1563c57e4e2e874022ce11f75ddc6df1a626f42bd49ab99f"}, - {file = "h5py-3.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:012ab448590e3c4f5a8dd0f3533255bc57f80629bf7c5054cf4c87b30085063c"}, - {file = "h5py-3.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:781a24263c1270a62cd67be59f293e62b76acfcc207afa6384961762bb88ea03"}, - {file = "h5py-3.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f42e6c30698b520f0295d70157c4e202a9e402406f50dc08f5a7bc416b24e52d"}, - {file = "h5py-3.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:93dd840bd675787fc0b016f7a05fc6efe37312a08849d9dd4053fd0377b1357f"}, - {file = "h5py-3.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2381e98af081b6df7f6db300cd88f88e740649d77736e4b53db522d8874bf2dc"}, - {file = "h5py-3.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:667fe23ab33d5a8a6b77970b229e14ae3bb84e4ea3382cc08567a02e1499eedd"}, - {file = "h5py-3.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90286b79abd085e4e65e07c1bd7ee65a0f15818ea107f44b175d2dfe1a4674b7"}, - {file = "h5py-3.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c013d2e79c00f28ffd0cc24e68665ea03ae9069e167087b2adb5727d2736a52"}, - {file = "h5py-3.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:92273ce69ae4983dadb898fd4d3bea5eb90820df953b401282ee69ad648df684"}, - {file = "h5py-3.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c97d03f87f215e7759a354460fb4b0d0f27001450b18b23e556e7856a0b21c3"}, - {file = "h5py-3.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:86df4c2de68257b8539a18646ceccdcf2c1ce6b1768ada16c8dcfb489eafae20"}, - {file = "h5py-3.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba9ab36be991119a3ff32d0c7cbe5faf9b8d2375b5278b2aea64effbeba66039"}, - {file = "h5py-3.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:2c8e4fda19eb769e9a678592e67eaec3a2f069f7570c82d2da909c077aa94339"}, - {file = "h5py-3.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:492305a074327e8d2513011fa9fffeb54ecb28a04ca4c4227d7e1e9616d35641"}, - {file = "h5py-3.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9450464b458cca2c86252b624279115dcaa7260a40d3cb1594bf2b410a2bd1a3"}, - {file = "h5py-3.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd6f6d1384a9f491732cee233b99cd4bfd6e838a8815cc86722f9d2ee64032af"}, - {file = "h5py-3.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3074ec45d3dc6e178c6f96834cf8108bf4a60ccb5ab044e16909580352010a97"}, - {file = "h5py-3.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:212bb997a91e6a895ce5e2f365ba764debeaef5d2dca5c6fb7098d66607adf99"}, - {file = "h5py-3.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5dfc65ac21fa2f630323c92453cadbe8d4f504726ec42f6a56cf80c2f90d6c52"}, - {file = "h5py-3.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d4682b94fd36ab217352be438abd44c8f357c5449b8995e63886b431d260f3d3"}, - {file = "h5py-3.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aece0e2e1ed2aab076c41802e50a0c3e5ef8816d60ece39107d68717d4559824"}, - {file = "h5py-3.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43a61b2c2ad65b1fabc28802d133eed34debcc2c8b420cb213d3d4ef4d3e2229"}, - {file = "h5py-3.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:ae2f0201c950059676455daf92700eeb57dcf5caaf71b9e1328e6e6593601770"}, - {file = "h5py-3.10.0.tar.gz", hash = "sha256:d93adc48ceeb33347eb24a634fb787efc7ae4644e6ea4ba733d099605045c049"}, + {file = "h5py-3.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1625fd24ad6cfc9c1ccd44a66dac2396e7ee74940776792772819fc69f3a3731"}, + {file = "h5py-3.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c072655ad1d5fe9ef462445d3e77a8166cbfa5e599045f8aa3c19b75315f10e5"}, + {file = "h5py-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77b19a40788e3e362b54af4dcf9e6fde59ca016db2c61360aa30b47c7b7cef00"}, + {file = "h5py-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:ef4e2f338fc763f50a8113890f455e1a70acd42a4d083370ceb80c463d803972"}, + {file = "h5py-3.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bbd732a08187a9e2a6ecf9e8af713f1d68256ee0f7c8b652a32795670fb481ba"}, + {file = "h5py-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75bd7b3d93fbeee40860fd70cdc88df4464e06b70a5ad9ce1446f5f32eb84007"}, + {file = "h5py-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52c416f8eb0daae39dabe71415cb531f95dce2d81e1f61a74537a50c63b28ab3"}, + {file = "h5py-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:083e0329ae534a264940d6513f47f5ada617da536d8dccbafc3026aefc33c90e"}, + {file = "h5py-3.11.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a76cae64080210389a571c7d13c94a1a6cf8cb75153044fd1f822a962c97aeab"}, + {file = "h5py-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3736fe21da2b7d8a13fe8fe415f1272d2a1ccdeff4849c1421d2fb30fd533bc"}, + {file = "h5py-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa6ae84a14103e8dc19266ef4c3e5d7c00b68f21d07f2966f0ca7bdb6c2761fb"}, + {file = "h5py-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:21dbdc5343f53b2e25404673c4f00a3335aef25521bd5fa8c707ec3833934892"}, + {file = "h5py-3.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:754c0c2e373d13d6309f408325343b642eb0f40f1a6ad21779cfa9502209e150"}, + {file = "h5py-3.11.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:731839240c59ba219d4cb3bc5880d438248533366f102402cfa0621b71796b62"}, + {file = "h5py-3.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ec9df3dd2018904c4cc06331951e274f3f3fd091e6d6cc350aaa90fa9b42a76"}, + {file = "h5py-3.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:55106b04e2c83dfb73dc8732e9abad69d83a436b5b82b773481d95d17b9685e1"}, + {file = "h5py-3.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f4e025e852754ca833401777c25888acb96889ee2c27e7e629a19aee288833f0"}, + {file = "h5py-3.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6c4b760082626120031d7902cd983d8c1f424cdba2809f1067511ef283629d4b"}, + {file = "h5py-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67462d0669f8f5459529de179f7771bd697389fcb3faab54d63bf788599a48ea"}, + {file = "h5py-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:d9c944d364688f827dc889cf83f1fca311caf4fa50b19f009d1f2b525edd33a3"}, + {file = "h5py-3.11.0.tar.gz", hash = "sha256:7b7e8f78072a2edec87c9836f25f34203fd492a4475709a18b417a33cfb21fa9"}, ] [package.dependencies] @@ -831,92 +334,17 @@ files = [ {file = "hbreader-0.9.1.tar.gz", hash = "sha256:d2c132f8ba6276d794c66224c3297cec25c8079d0a4cf019c061611e0a3b94fa"}, ] -[[package]] -name = "httpcore" -version = "1.0.2" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7"}, - {file = "httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<0.23.0)"] - -[[package]] -name = "httpx" -version = "0.26.0" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, - {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] - [[package]] name = "idna" -version = "3.6" +version = "3.7" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, - {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, -] - -[[package]] -name = "imagesize" -version = "1.4.1" -description = "Getting image size from png/jpeg/jpeg2000/gif file" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, - {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, -] - -[[package]] -name = "importlib-metadata" -version = "7.0.1" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "importlib_metadata-7.0.1-py3-none-any.whl", hash = "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e"}, - {file = "importlib_metadata-7.0.1.tar.gz", hash = "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"}, + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, ] -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] - [[package]] name = "iniconfig" version = "2.0.0" @@ -929,238 +357,64 @@ files = [ ] [[package]] -name = "ipykernel" -version = "6.29.2" -description = "IPython Kernel for Jupyter" +name = "isodate" +version = "0.6.1" +description = "An ISO 8601 date/time/duration parser and formatter" optional = false -python-versions = ">=3.8" +python-versions = "*" files = [ - {file = "ipykernel-6.29.2-py3-none-any.whl", hash = "sha256:50384f5c577a260a1d53f1f59a828c7266d321c9b7d00d345693783f66616055"}, - {file = "ipykernel-6.29.2.tar.gz", hash = "sha256:3bade28004e3ff624ed57974948116670604ac5f676d12339693f3142176d3f0"}, + {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, + {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, ] [package.dependencies] -appnope = {version = "*", markers = "platform_system == \"Darwin\""} -comm = ">=0.1.1" -debugpy = ">=1.6.5" -ipython = ">=7.23.1" -jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -matplotlib-inline = ">=0.1" -nest-asyncio = "*" -packaging = "*" -psutil = "*" -pyzmq = ">=24" -tornado = ">=6.1" -traitlets = ">=5.4.0" - -[package.extras] -cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] -pyqt5 = ["pyqt5"] -pyside6 = ["pyside6"] -test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (==0.23.4)", "pytest-cov", "pytest-timeout"] +six = "*" [[package]] -name = "ipython" -version = "8.18.1" -description = "IPython: Productive Interactive Computing" +name = "json-flattener" +version = "0.1.9" +description = "Python library for denormalizing nested dicts or json objects to tables and back" optional = false -python-versions = ">=3.9" +python-versions = ">=3.7.0" files = [ - {file = "ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397"}, - {file = "ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27"}, + {file = "json_flattener-0.1.9-py3-none-any.whl", hash = "sha256:6b027746f08bf37a75270f30c6690c7149d5f704d8af1740c346a3a1236bc941"}, + {file = "json_flattener-0.1.9.tar.gz", hash = "sha256:84cf8523045ffb124301a602602201665fcb003a171ece87e6f46ed02f7f0c15"}, ] [package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -decorator = "*" -exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} -jedi = ">=0.16" -matplotlib-inline = "*" -pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -prompt-toolkit = ">=3.0.41,<3.1.0" -pygments = ">=2.4.0" -stack-data = "*" -traitlets = ">=5" -typing-extensions = {version = "*", markers = "python_version < \"3.10\""} - -[package.extras] -all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] -black = ["black"] -doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] -kernel = ["ipykernel"] -nbconvert = ["nbconvert"] -nbformat = ["nbformat"] -notebook = ["ipywidgets", "notebook"] -parallel = ["ipyparallel"] -qtconsole = ["qtconsole"] -test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] +click = "*" +pyyaml = "*" [[package]] -name = "ipywidgets" -version = "8.1.2" -description = "Jupyter interactive widgets" +name = "jsonasobj2" +version = "1.0.4" +description = "JSON as python objects - version 2" optional = false -python-versions = ">=3.7" +python-versions = ">=3.6" files = [ - {file = "ipywidgets-8.1.2-py3-none-any.whl", hash = "sha256:bbe43850d79fb5e906b14801d6c01402857996864d1e5b6fa62dd2ee35559f60"}, - {file = "ipywidgets-8.1.2.tar.gz", hash = "sha256:d0b9b41e49bae926a866e613a39b0f0097745d2b9f1f3dd406641b4a57ec42c9"}, + {file = "jsonasobj2-1.0.4-py3-none-any.whl", hash = "sha256:12e86f86324d54fcf60632db94ea74488d5314e3da554c994fe1e2c6f29acb79"}, + {file = "jsonasobj2-1.0.4.tar.gz", hash = "sha256:f50b1668ef478004aa487b2d2d094c304e5cb6b79337809f4a1f2975cc7fbb4e"}, ] [package.dependencies] -comm = ">=0.1.3" -ipython = ">=6.1.0" -jupyterlab-widgets = ">=3.0.10,<3.1.0" -traitlets = ">=4.3.1" -widgetsnbextension = ">=4.0.10,<4.1.0" - -[package.extras] -test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] +hbreader = "*" [[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" +name = "jsonschema" +version = "4.22.0" +description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "isoduration" -version = "20.11.0" -description = "Operations with ISO 8601 durations" -optional = false -python-versions = ">=3.7" -files = [ - {file = "isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042"}, - {file = "isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9"}, -] - -[package.dependencies] -arrow = ">=0.15.0" - -[[package]] -name = "jedi" -version = "0.19.1" -description = "An autocompletion tool for Python that can be used for text editors." -optional = false -python-versions = ">=3.6" -files = [ - {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, - {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, -] - -[package.dependencies] -parso = ">=0.8.3,<0.9.0" - -[package.extras] -docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] -qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] - -[[package]] -name = "jinja2" -version = "3.1.3" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, - {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "json-flattener" -version = "0.1.9" -description = "Python library for denormalizing nested dicts or json objects to tables and back" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "json_flattener-0.1.9-py3-none-any.whl", hash = "sha256:6b027746f08bf37a75270f30c6690c7149d5f704d8af1740c346a3a1236bc941"}, - {file = "json_flattener-0.1.9.tar.gz", hash = "sha256:84cf8523045ffb124301a602602201665fcb003a171ece87e6f46ed02f7f0c15"}, -] - -[package.dependencies] -click = "*" -pyyaml = "*" - -[[package]] -name = "json5" -version = "0.9.14" -description = "A Python implementation of the JSON5 data format." -optional = false -python-versions = "*" -files = [ - {file = "json5-0.9.14-py2.py3-none-any.whl", hash = "sha256:740c7f1b9e584a468dbb2939d8d458db3427f2c93ae2139d05f47e453eae964f"}, - {file = "json5-0.9.14.tar.gz", hash = "sha256:9ed66c3a6ca3510a976a9ef9b8c0787de24802724ab1860bc0153c7fdd589b02"}, -] - -[package.extras] -dev = ["hypothesis"] - -[[package]] -name = "jsonasobj2" -version = "1.0.4" -description = "JSON as python objects - version 2" -optional = false -python-versions = ">=3.6" -files = [ - {file = "jsonasobj2-1.0.4-py3-none-any.whl", hash = "sha256:12e86f86324d54fcf60632db94ea74488d5314e3da554c994fe1e2c6f29acb79"}, - {file = "jsonasobj2-1.0.4.tar.gz", hash = "sha256:f50b1668ef478004aa487b2d2d094c304e5cb6b79337809f4a1f2975cc7fbb4e"}, -] - -[package.dependencies] -hbreader = "*" - -[[package]] -name = "jsonpointer" -version = "2.4" -description = "Identify specific nodes in a JSON document (RFC 6901)" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" -files = [ - {file = "jsonpointer-2.4-py2.py3-none-any.whl", hash = "sha256:15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a"}, - {file = "jsonpointer-2.4.tar.gz", hash = "sha256:585cee82b70211fa9e6043b7bb89db6e1aa49524340dde8ad6b63206ea689d88"}, -] - -[[package]] -name = "jsonschema" -version = "4.21.1" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jsonschema-4.21.1-py3-none-any.whl", hash = "sha256:7996507afae316306f9e2290407761157c6f78002dcf7419acb99822143d1c6f"}, - {file = "jsonschema-4.21.1.tar.gz", hash = "sha256:85727c00279f5fa6bedbe6238d2aa6403bedd8b4864ab11207d07df3cc1b2ee5"}, + {file = "jsonschema-4.22.0-py3-none-any.whl", hash = "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802"}, + {file = "jsonschema-4.22.0.tar.gz", hash = "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7"}, ] [package.dependencies] attrs = ">=22.2.0" -fqdn = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -idna = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -isoduration = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -jsonpointer = {version = ">1.13", optional = true, markers = "extra == \"format-nongpl\""} jsonschema-specifications = ">=2023.03.6" referencing = ">=0.28.4" -rfc3339-validator = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""} rpds-py = ">=0.7.1" -uri-template = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -webcolors = {version = ">=1.11", optional = true, markers = "extra == \"format-nongpl\""} [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] @@ -1181,2185 +435,883 @@ files = [ referencing = ">=0.31.0" [[package]] -name = "jupyter" -version = "1.0.0" -description = "Jupyter metapackage. Install all the Jupyter components in one go." +name = "linkml-runtime" +version = "1.8.0" +description = "Runtime environment for LinkML, the Linked open data modeling language" optional = false -python-versions = "*" +python-versions = "<4.0,>=3.8" files = [ - {file = "jupyter-1.0.0-py2.py3-none-any.whl", hash = "sha256:5b290f93b98ffbc21c0c7e749f054b3267782166d72fa5e3ed1ed4eaf34a2b78"}, - {file = "jupyter-1.0.0.tar.gz", hash = "sha256:d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f"}, - {file = "jupyter-1.0.0.zip", hash = "sha256:3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7"}, + {file = "linkml_runtime-1.8.0-py3-none-any.whl", hash = "sha256:e99a809eda52640633f07a9e8b391d1a9da863eb68a475dfd74a79335b909931"}, + {file = "linkml_runtime-1.8.0.tar.gz", hash = "sha256:436381a7bf791e9af4ef0a5adcac86762d451b77670fbdb3ba083d2c177fb5f2"}, ] [package.dependencies] -ipykernel = "*" -ipywidgets = "*" -jupyter-console = "*" -nbconvert = "*" -notebook = "*" -qtconsole = "*" +click = "*" +curies = ">=0.5.4" +deprecated = "*" +hbreader = "*" +json-flattener = ">=0.1.9" +jsonasobj2 = ">=1.0.4,<2.dev0" +jsonschema = ">=3.2.0" +prefixcommons = ">=0.1.12" +prefixmaps = ">=0.1.4" +pydantic = ">=1.10.2,<3.0.0" +pyyaml = "*" +rdflib = ">=6.0.0" +requests = "*" [[package]] -name = "jupyter-client" -version = "8.6.0" -description = "Jupyter protocol implementation and client libraries" +name = "numcodecs" +version = "0.12.1" +description = "A Python package providing buffer compression and transformation codecs for use in data storage and communication applications." optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_client-8.6.0-py3-none-any.whl", hash = "sha256:909c474dbe62582ae62b758bca86d6518c85234bdee2d908c778db6d72f39d99"}, - {file = "jupyter_client-8.6.0.tar.gz", hash = "sha256:0642244bb83b4764ae60d07e010e15f0e2d275ec4e918a8f7b80fbbef3ca60c7"}, -] - -[package.dependencies] -importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -python-dateutil = ">=2.8.2" -pyzmq = ">=23.0" -tornado = ">=6.2" -traitlets = ">=5.3" - -[package.extras] -docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] - -[[package]] -name = "jupyter-console" -version = "6.6.3" -description = "Jupyter terminal console" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jupyter_console-6.6.3-py3-none-any.whl", hash = "sha256:309d33409fcc92ffdad25f0bcdf9a4a9daa61b6f341177570fdac03de5352485"}, - {file = "jupyter_console-6.6.3.tar.gz", hash = "sha256:566a4bf31c87adbfadf22cdf846e3069b59a71ed5da71d6ba4d8aaad14a53539"}, + {file = "numcodecs-0.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d37f628fe92b3699e65831d5733feca74d2e33b50ef29118ffd41c13c677210e"}, + {file = "numcodecs-0.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:941b7446b68cf79f089bcfe92edaa3b154533dcbcd82474f994b28f2eedb1c60"}, + {file = "numcodecs-0.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e79bf9d1d37199ac00a60ff3adb64757523291d19d03116832e600cac391c51"}, + {file = "numcodecs-0.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:82d7107f80f9307235cb7e74719292d101c7ea1e393fe628817f0d635b7384f5"}, + {file = "numcodecs-0.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:eeaf42768910f1c6eebf6c1bb00160728e62c9343df9e2e315dc9fe12e3f6071"}, + {file = "numcodecs-0.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:135b2d47563f7b9dc5ee6ce3d1b81b0f1397f69309e909f1a35bb0f7c553d45e"}, + {file = "numcodecs-0.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a191a8e347ecd016e5c357f2bf41fbcb026f6ffe78fff50c77ab12e96701d155"}, + {file = "numcodecs-0.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:21d8267bd4313f4d16f5b6287731d4c8ebdab236038f29ad1b0e93c9b2ca64ee"}, + {file = "numcodecs-0.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2f84df6b8693206365a5b37c005bfa9d1be486122bde683a7b6446af4b75d862"}, + {file = "numcodecs-0.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:760627780a8b6afdb7f942f2a0ddaf4e31d3d7eea1d8498cf0fd3204a33c4618"}, + {file = "numcodecs-0.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c258bd1d3dfa75a9b708540d23b2da43d63607f9df76dfa0309a7597d1de3b73"}, + {file = "numcodecs-0.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:e04649ea504aff858dbe294631f098fbfd671baf58bfc04fc48d746554c05d67"}, + {file = "numcodecs-0.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:caf1a1e6678aab9c1e29d2109b299f7a467bd4d4c34235b1f0e082167846b88f"}, + {file = "numcodecs-0.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c17687b1fd1fef68af616bc83f896035d24e40e04e91e7e6dae56379eb59fe33"}, + {file = "numcodecs-0.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29dfb195f835a55c4d490fb097aac8c1bcb96c54cf1b037d9218492c95e9d8c5"}, + {file = "numcodecs-0.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:2f1ba2f4af3fd3ba65b1bcffb717fe65efe101a50a91c368f79f3101dbb1e243"}, + {file = "numcodecs-0.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2fbb12a6a1abe95926f25c65e283762d63a9bf9e43c0de2c6a1a798347dfcb40"}, + {file = "numcodecs-0.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f2207871868b2464dc11c513965fd99b958a9d7cde2629be7b2dc84fdaab013b"}, + {file = "numcodecs-0.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abff3554a6892a89aacf7b642a044e4535499edf07aeae2f2e6e8fc08c9ba07f"}, + {file = "numcodecs-0.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:ef964d4860d3e6b38df0633caf3e51dc850a6293fd8e93240473642681d95136"}, + {file = "numcodecs-0.12.1.tar.gz", hash = "sha256:05d91a433733e7eef268d7e80ec226a0232da244289614a8f3826901aec1098e"}, ] [package.dependencies] -ipykernel = ">=6.14" -ipython = "*" -jupyter-client = ">=7.0.0" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -prompt-toolkit = ">=3.0.30" -pygments = "*" -pyzmq = ">=17" -traitlets = ">=5.4" +numpy = ">=1.7" [package.extras] -test = ["flaky", "pexpect", "pytest"] +docs = ["mock", "numpydoc", "sphinx (<7.0.0)", "sphinx-issues"] +msgpack = ["msgpack"] +test = ["coverage", "flake8", "pytest", "pytest-cov"] +test-extras = ["importlib-metadata"] +zfpy = ["zfpy (>=1.0.0)"] [[package]] -name = "jupyter-core" -version = "5.7.1" -description = "Jupyter core package. A base package on which Jupyter projects rely." +name = "numpy" +version = "2.0.0" +description = "Fundamental package for array computing in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "jupyter_core-5.7.1-py3-none-any.whl", hash = "sha256:c65c82126453a723a2804aa52409930434598fd9d35091d63dfb919d2b765bb7"}, - {file = "jupyter_core-5.7.1.tar.gz", hash = "sha256:de61a9d7fc71240f688b2fb5ab659fbb56979458dc66a71decd098e03c79e218"}, + {file = "numpy-2.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:04494f6ec467ccb5369d1808570ae55f6ed9b5809d7f035059000a37b8d7e86f"}, + {file = "numpy-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2635dbd200c2d6faf2ef9a0d04f0ecc6b13b3cad54f7c67c61155138835515d2"}, + {file = "numpy-2.0.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:0a43f0974d501842866cc83471bdb0116ba0dffdbaac33ec05e6afed5b615238"}, + {file = "numpy-2.0.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:8d83bb187fb647643bd56e1ae43f273c7f4dbcdf94550d7938cfc32566756514"}, + {file = "numpy-2.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79e843d186c8fb1b102bef3e2bc35ef81160ffef3194646a7fdd6a73c6b97196"}, + {file = "numpy-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d7696c615765091cc5093f76fd1fa069870304beaccfd58b5dcc69e55ef49c1"}, + {file = "numpy-2.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b4c76e3d4c56f145d41b7b6751255feefae92edbc9a61e1758a98204200f30fc"}, + {file = "numpy-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:acd3a644e4807e73b4e1867b769fbf1ce8c5d80e7caaef0d90dcdc640dfc9787"}, + {file = "numpy-2.0.0-cp310-cp310-win32.whl", hash = "sha256:cee6cc0584f71adefe2c908856ccc98702baf95ff80092e4ca46061538a2ba98"}, + {file = "numpy-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:ed08d2703b5972ec736451b818c2eb9da80d66c3e84aed1deeb0c345fefe461b"}, + {file = "numpy-2.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad0c86f3455fbd0de6c31a3056eb822fc939f81b1618f10ff3406971893b62a5"}, + {file = "numpy-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e7f387600d424f91576af20518334df3d97bc76a300a755f9a8d6e4f5cadd289"}, + {file = "numpy-2.0.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:34f003cb88b1ba38cb9a9a4a3161c1604973d7f9d5552c38bc2f04f829536609"}, + {file = "numpy-2.0.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:b6f6a8f45d0313db07d6d1d37bd0b112f887e1369758a5419c0370ba915b3871"}, + {file = "numpy-2.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f64641b42b2429f56ee08b4f427a4d2daf916ec59686061de751a55aafa22e4"}, + {file = "numpy-2.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7039a136017eaa92c1848152827e1424701532ca8e8967fe480fe1569dae581"}, + {file = "numpy-2.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:46e161722e0f619749d1cd892167039015b2c2817296104487cd03ed4a955995"}, + {file = "numpy-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0e50842b2295ba8414c8c1d9d957083d5dfe9e16828b37de883f51fc53c4016f"}, + {file = "numpy-2.0.0-cp311-cp311-win32.whl", hash = "sha256:2ce46fd0b8a0c947ae047d222f7136fc4d55538741373107574271bc00e20e8f"}, + {file = "numpy-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:fbd6acc766814ea6443628f4e6751d0da6593dae29c08c0b2606164db026970c"}, + {file = "numpy-2.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:354f373279768fa5a584bac997de6a6c9bc535c482592d7a813bb0c09be6c76f"}, + {file = "numpy-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4d2f62e55a4cd9c58c1d9a1c9edaedcd857a73cb6fda875bf79093f9d9086f85"}, + {file = "numpy-2.0.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:1e72728e7501a450288fc8e1f9ebc73d90cfd4671ebbd631f3e7857c39bd16f2"}, + {file = "numpy-2.0.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:84554fc53daa8f6abf8e8a66e076aff6ece62de68523d9f665f32d2fc50fd66e"}, + {file = "numpy-2.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c73aafd1afca80afecb22718f8700b40ac7cab927b8abab3c3e337d70e10e5a2"}, + {file = "numpy-2.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49d9f7d256fbc804391a7f72d4a617302b1afac1112fac19b6c6cec63fe7fe8a"}, + {file = "numpy-2.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0ec84b9ba0654f3b962802edc91424331f423dcf5d5f926676e0150789cb3d95"}, + {file = "numpy-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:feff59f27338135776f6d4e2ec7aeeac5d5f7a08a83e80869121ef8164b74af9"}, + {file = "numpy-2.0.0-cp312-cp312-win32.whl", hash = "sha256:c5a59996dc61835133b56a32ebe4ef3740ea5bc19b3983ac60cc32be5a665d54"}, + {file = "numpy-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:a356364941fb0593bb899a1076b92dfa2029f6f5b8ba88a14fd0984aaf76d0df"}, + {file = "numpy-2.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e61155fae27570692ad1d327e81c6cf27d535a5d7ef97648a17d922224b216de"}, + {file = "numpy-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4554eb96f0fd263041baf16cf0881b3f5dafae7a59b1049acb9540c4d57bc8cb"}, + {file = "numpy-2.0.0-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:903703372d46bce88b6920a0cd86c3ad82dae2dbef157b5fc01b70ea1cfc430f"}, + {file = "numpy-2.0.0-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:3e8e01233d57639b2e30966c63d36fcea099d17c53bf424d77f088b0f4babd86"}, + {file = "numpy-2.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cde1753efe513705a0c6d28f5884e22bdc30438bf0085c5c486cdaff40cd67a"}, + {file = "numpy-2.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:821eedb7165ead9eebdb569986968b541f9908979c2da8a4967ecac4439bae3d"}, + {file = "numpy-2.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a1712c015831da583b21c5bfe15e8684137097969c6d22e8316ba66b5baabe4"}, + {file = "numpy-2.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9c27f0946a3536403efb0e1c28def1ae6730a72cd0d5878db38824855e3afc44"}, + {file = "numpy-2.0.0-cp39-cp39-win32.whl", hash = "sha256:63b92c512d9dbcc37f9d81b123dec99fdb318ba38c8059afc78086fe73820275"}, + {file = "numpy-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:3f6bed7f840d44c08ebdb73b1825282b801799e325bcbdfa6bc5c370e5aecc65"}, + {file = "numpy-2.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9416a5c2e92ace094e9f0082c5fd473502c91651fb896bc17690d6fc475128d6"}, + {file = "numpy-2.0.0-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:17067d097ed036636fa79f6a869ac26df7db1ba22039d962422506640314933a"}, + {file = "numpy-2.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ecb5b0582cd125f67a629072fed6f83562d9dd04d7e03256c9829bdec027ad"}, + {file = "numpy-2.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cef04d068f5fb0518a77857953193b6bb94809a806bd0a14983a8f12ada060c9"}, + {file = "numpy-2.0.0.tar.gz", hash = "sha256:cf5d1c9e6837f8af9f92b6bd3e86d513cdc11f60fd62185cc49ec7d1aba34864"}, ] -[package.dependencies] -platformdirs = ">=2.5" -pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} -traitlets = ">=5.3" - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] -test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] - [[package]] -name = "jupyter-events" -version = "0.9.0" -description = "Jupyter Event System library" +name = "packaging" +version = "24.1" +description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_events-0.9.0-py3-none-any.whl", hash = "sha256:d853b3c10273ff9bc8bb8b30076d65e2c9685579db736873de6c2232dde148bf"}, - {file = "jupyter_events-0.9.0.tar.gz", hash = "sha256:81ad2e4bc710881ec274d31c6c50669d71bbaa5dd9d01e600b56faa85700d399"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] -[package.dependencies] -jsonschema = {version = ">=4.18.0", extras = ["format-nongpl"]} -python-json-logger = ">=2.0.4" -pyyaml = ">=5.3" -referencing = "*" -rfc3339-validator = "*" -rfc3986-validator = ">=0.1.1" -traitlets = ">=5.3" - -[package.extras] -cli = ["click", "rich"] -docs = ["jupyterlite-sphinx", "myst-parser", "pydata-sphinx-theme", "sphinxcontrib-spelling"] -test = ["click", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "pytest-console-scripts", "rich"] - [[package]] -name = "jupyter-lsp" +name = "pandas" version = "2.2.2" -description = "Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jupyter-lsp-2.2.2.tar.gz", hash = "sha256:256d24620542ae4bba04a50fc1f6ffe208093a07d8e697fea0a8d1b8ca1b7e5b"}, - {file = "jupyter_lsp-2.2.2-py3-none-any.whl", hash = "sha256:3b95229e4168355a8c91928057c1621ac3510ba98b2a925e82ebd77f078b1aa5"}, -] - -[package.dependencies] -importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} -jupyter-server = ">=1.1.2" - -[[package]] -name = "jupyter-server" -version = "2.12.5" -description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." +description = "Powerful data structures for data analysis, time series, and statistics" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "jupyter_server-2.12.5-py3-none-any.whl", hash = "sha256:184a0f82809a8522777cfb6b760ab6f4b1bb398664c5860a27cec696cb884923"}, - {file = "jupyter_server-2.12.5.tar.gz", hash = "sha256:0edb626c94baa22809be1323f9770cf1c00a952b17097592e40d03e6a3951689"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, ] [package.dependencies] -anyio = ">=3.1.0" -argon2-cffi = "*" -jinja2 = "*" -jupyter-client = ">=7.4.4" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -jupyter-events = ">=0.9.0" -jupyter-server-terminals = "*" -nbconvert = ">=6.4.4" -nbformat = ">=5.3.0" -overrides = "*" -packaging = "*" -prometheus-client = "*" -pywinpty = {version = "*", markers = "os_name == \"nt\""} -pyzmq = ">=24" -send2trash = ">=1.8.2" -terminado = ">=0.8.3" -tornado = ">=6.2.0" -traitlets = ">=5.6.0" -websocket-client = "*" - -[package.extras] -docs = ["ipykernel", "jinja2", "jupyter-client", "jupyter-server", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi (>=0.8.0)", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] -test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.4)", "pytest-timeout", "requests"] - -[[package]] -name = "jupyter-server-terminals" -version = "0.5.2" -description = "A Jupyter Server Extension Providing Terminals." -optional = false -python-versions = ">=3.8" -files = [ - {file = "jupyter_server_terminals-0.5.2-py3-none-any.whl", hash = "sha256:1b80c12765da979513c42c90215481bbc39bd8ae7c0350b4f85bc3eb58d0fa80"}, - {file = "jupyter_server_terminals-0.5.2.tar.gz", hash = "sha256:396b5ccc0881e550bf0ee7012c6ef1b53edbde69e67cab1d56e89711b46052e8"}, +numpy = [ + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, ] - -[package.dependencies] -pywinpty = {version = ">=2.0.3", markers = "os_name == \"nt\""} -terminado = ">=0.8.3" +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" [package.extras] -docs = ["jinja2", "jupyter-server", "mistune (<4.0)", "myst-parser", "nbformat", "packaging", "pydata-sphinx-theme", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"] -test = ["jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-jupyter[server] (>=0.5.3)", "pytest-timeout"] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] [[package]] -name = "jupyterlab" -version = "4.1.0" -description = "JupyterLab computational environment" +name = "platformdirs" +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "jupyterlab-4.1.0-py3-none-any.whl", hash = "sha256:5380e85fb4f11a227ed2db13103e513cfea274d1011f6210e62d611e92e0369d"}, - {file = "jupyterlab-4.1.0.tar.gz", hash = "sha256:92cdfd86c53e163fb9e91e14497901153536c5a889c9225dade270f6107a077f"}, + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, ] -[package.dependencies] -async-lru = ">=1.0.0" -httpx = ">=0.25.0" -importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} -ipykernel = "*" -jinja2 = ">=3.0.3" -jupyter-core = "*" -jupyter-lsp = ">=2.0.0" -jupyter-server = ">=2.4.0,<3" -jupyterlab-server = ">=2.19.0,<3" -notebook-shim = ">=0.2" -packaging = "*" -tomli = {version = "*", markers = "python_version < \"3.11\""} -tornado = ">=6.2.0" -traitlets = "*" - [package.extras] -dev = ["build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.1.15)"] -docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-jupyter", "sphinx (>=1.8,<7.3.0)", "sphinx-copybutton"] -docs-screenshots = ["altair (==5.2.0)", "ipython (==8.16.1)", "ipywidgets (==8.1.1)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.0.post6)", "matplotlib (==3.8.2)", "nbconvert (>=7.0.0)", "pandas (==2.2.0)", "scipy (==1.12.0)", "vega-datasets (==0.9.0)"] -test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "pytest-timeout", "pytest-tornasync", "requests", "requests-cache", "virtualenv"] - -[[package]] -name = "jupyterlab-pygments" -version = "0.3.0" -description = "Pygments theme using JupyterLab CSS variables" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780"}, - {file = "jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d"}, -] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] [[package]] -name = "jupyterlab-server" -version = "2.25.2" -description = "A set of server components for JupyterLab and JupyterLab like applications." +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" files = [ - {file = "jupyterlab_server-2.25.2-py3-none-any.whl", hash = "sha256:5b1798c9cc6a44f65c757de9f97fc06fc3d42535afbf47d2ace5e964ab447aaf"}, - {file = "jupyterlab_server-2.25.2.tar.gz", hash = "sha256:bd0ec7a99ebcedc8bcff939ef86e52c378e44c2707e053fcd81d046ce979ee63"}, + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] -[package.dependencies] -babel = ">=2.10" -importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} -jinja2 = ">=3.0.3" -json5 = ">=0.9.0" -jsonschema = ">=4.18.0" -jupyter-server = ">=1.21,<3" -packaging = ">=21.3" -requests = ">=2.31" - [package.extras] -docs = ["autodoc-traits", "jinja2 (<3.2.0)", "mistune (<4)", "myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-copybutton", "sphinxcontrib-openapi (>0.8)"] -openapi = ["openapi-core (>=0.18.0,<0.19.0)", "ruamel-yaml"] -test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-validator (>=0.6.0,<0.8.0)", "pytest (>=7.0)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter[server] (>=0.6.2)", "pytest-timeout", "requests-mock", "ruamel-yaml", "sphinxcontrib-spelling", "strict-rfc3339", "werkzeug"] - -[[package]] -name = "jupyterlab-widgets" -version = "3.0.10" -description = "Jupyter interactive widgets for JupyterLab" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jupyterlab_widgets-3.0.10-py3-none-any.whl", hash = "sha256:dd61f3ae7a5a7f80299e14585ce6cf3d6925a96c9103c978eda293197730cb64"}, - {file = "jupyterlab_widgets-3.0.10.tar.gz", hash = "sha256:04f2ac04976727e4f9d0fa91cdc2f1ab860f965e504c29dbd6a65c882c9d04c0"}, -] - -[[package]] -name = "linkml-runtime" -version = "1.7.0" -description = "Runtime environment for LinkML, the Linked open data modeling language" -optional = false -python-versions = ">=3.7.6,<4.0.0" -files = [ - {file = "linkml_runtime-1.7.0-py3-none-any.whl", hash = "sha256:ba35f9696146d5e6e1ac035fcbbd5d3f2d434d51c368590347a5785801346a9a"}, - {file = "linkml_runtime-1.7.0.tar.gz", hash = "sha256:49279407be8941a5ff1aff34aa6660f161cca3611044045835bc660246a57d92"}, -] - -[package.dependencies] -click = "*" -curies = ">=0.5.4" -deprecated = "*" -hbreader = "*" -json-flattener = ">=0.1.9" -jsonasobj2 = ">=1.0.4,<2.dev0" -jsonschema = ">=3.2.0" -prefixcommons = ">=0.1.12" -prefixmaps = ">=0.1.4" -pydantic = ">=1.10.2,<3.0.0" -pyyaml = "*" -rdflib = ">=6.0.0" -requests = "*" +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] [[package]] -name = "markdown-it-py" -version = "2.2.0" -description = "Python port of markdown-it. Markdown parsing, done right!" +name = "prefixcommons" +version = "0.1.12" +description = "A python API for working with ID prefixes" optional = false -python-versions = ">=3.7" +python-versions = ">=3.7,<4.0" files = [ - {file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"}, - {file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"}, -] - -[package.dependencies] -mdurl = ">=0.1,<1.0" - -[package.extras] -benchmarking = ["psutil", "pytest", "pytest-benchmark"] -code-style = ["pre-commit (>=3.0,<4.0)"] -compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] -linkify = ["linkify-it-py (>=1,<3)"] -plugins = ["mdit-py-plugins"] -profiling = ["gprof2dot"] -rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - -[[package]] -name = "markupsafe" -version = "2.1.5" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.7" -files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, -] - -[[package]] -name = "matplotlib-inline" -version = "0.1.6" -description = "Inline Matplotlib backend for Jupyter" -optional = false -python-versions = ">=3.5" -files = [ - {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, - {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, -] - -[package.dependencies] -traitlets = "*" - -[[package]] -name = "mdit-py-plugins" -version = "0.3.5" -description = "Collection of plugins for markdown-it-py" -optional = false -python-versions = ">=3.7" -files = [ - {file = "mdit-py-plugins-0.3.5.tar.gz", hash = "sha256:eee0adc7195e5827e17e02d2a258a2ba159944a0748f59c5099a4a27f78fcf6a"}, - {file = "mdit_py_plugins-0.3.5-py3-none-any.whl", hash = "sha256:ca9a0714ea59a24b2b044a1831f48d817dd0c817e84339f20e7889f392d77c4e"}, -] - -[package.dependencies] -markdown-it-py = ">=1.0.0,<3.0.0" - -[package.extras] -code-style = ["pre-commit"] -rtd = ["attrs", "myst-parser (>=0.16.1,<0.17.0)", "sphinx-book-theme (>=0.1.0,<0.2.0)"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - -[[package]] -name = "mdurl" -version = "0.1.2" -description = "Markdown URL utilities" -optional = false -python-versions = ">=3.7" -files = [ - {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, - {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, -] - -[[package]] -name = "mistune" -version = "3.0.2" -description = "A sane and fast Markdown parser with useful plugins and renderers" -optional = false -python-versions = ">=3.7" -files = [ - {file = "mistune-3.0.2-py3-none-any.whl", hash = "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205"}, - {file = "mistune-3.0.2.tar.gz", hash = "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8"}, -] - -[[package]] -name = "mypy" -version = "1.8.0" -description = "Optional static typing for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "mypy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3"}, - {file = "mypy-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4"}, - {file = "mypy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d"}, - {file = "mypy-1.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9"}, - {file = "mypy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410"}, - {file = "mypy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae"}, - {file = "mypy-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3"}, - {file = "mypy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817"}, - {file = "mypy-1.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d"}, - {file = "mypy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835"}, - {file = "mypy-1.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd"}, - {file = "mypy-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55"}, - {file = "mypy-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218"}, - {file = "mypy-1.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3"}, - {file = "mypy-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e"}, - {file = "mypy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6"}, - {file = "mypy-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66"}, - {file = "mypy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6"}, - {file = "mypy-1.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d"}, - {file = "mypy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02"}, - {file = "mypy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8"}, - {file = "mypy-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259"}, - {file = "mypy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b"}, - {file = "mypy-1.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592"}, - {file = "mypy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a"}, - {file = "mypy-1.8.0-py3-none-any.whl", hash = "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d"}, - {file = "mypy-1.8.0.tar.gz", hash = "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07"}, -] - -[package.dependencies] -mypy-extensions = ">=1.0.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=4.1.0" - -[package.extras] -dmypy = ["psutil (>=4.0)"] -install-types = ["pip"] -mypyc = ["setuptools (>=50)"] -reports = ["lxml"] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - -[[package]] -name = "myst-parser" -version = "0.18.1" -description = "An extended commonmark compliant parser, with bridges to docutils & sphinx." -optional = false -python-versions = ">=3.7" -files = [ - {file = "myst-parser-0.18.1.tar.gz", hash = "sha256:79317f4bb2c13053dd6e64f9da1ba1da6cd9c40c8a430c447a7b146a594c246d"}, - {file = "myst_parser-0.18.1-py3-none-any.whl", hash = "sha256:61b275b85d9f58aa327f370913ae1bec26ebad372cc99f3ab85c8ec3ee8d9fb8"}, -] - -[package.dependencies] -docutils = ">=0.15,<0.20" -jinja2 = "*" -markdown-it-py = ">=1.0.0,<3.0.0" -mdit-py-plugins = ">=0.3.1,<0.4.0" -pyyaml = "*" -sphinx = ">=4,<6" -typing-extensions = "*" - -[package.extras] -code-style = ["pre-commit (>=2.12,<3.0)"] -linkify = ["linkify-it-py (>=1.0,<2.0)"] -rtd = ["ipython", "sphinx-book-theme", "sphinx-design", "sphinxcontrib.mermaid (>=0.7.1,<0.8.0)", "sphinxext-opengraph (>=0.6.3,<0.7.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"] -testing = ["beautifulsoup4", "coverage[toml]", "pytest (>=6,<7)", "pytest-cov", "pytest-param-files (>=0.3.4,<0.4.0)", "pytest-regressions", "sphinx (<5.2)", "sphinx-pytest"] - -[[package]] -name = "nbclient" -version = "0.9.0" -description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "nbclient-0.9.0-py3-none-any.whl", hash = "sha256:a3a1ddfb34d4a9d17fc744d655962714a866639acd30130e9be84191cd97cd15"}, - {file = "nbclient-0.9.0.tar.gz", hash = "sha256:4b28c207877cf33ef3a9838cdc7a54c5ceff981194a82eac59d558f05487295e"}, -] - -[package.dependencies] -jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -nbformat = ">=5.1" -traitlets = ">=5.4" - -[package.extras] -dev = ["pre-commit"] -docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] -test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] - -[[package]] -name = "nbconvert" -version = "7.16.0" -description = "Converting Jupyter Notebooks" -optional = false -python-versions = ">=3.8" -files = [ - {file = "nbconvert-7.16.0-py3-none-any.whl", hash = "sha256:ad3dc865ea6e2768d31b7eb6c7ab3be014927216a5ece3ef276748dd809054c7"}, - {file = "nbconvert-7.16.0.tar.gz", hash = "sha256:813e6553796362489ae572e39ba1bff978536192fb518e10826b0e8cadf03ec8"}, -] - -[package.dependencies] -beautifulsoup4 = "*" -bleach = "!=5.0.0" -defusedxml = "*" -importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} -jinja2 = ">=3.0" -jupyter-core = ">=4.7" -jupyterlab-pygments = "*" -markupsafe = ">=2.0" -mistune = ">=2.0.3,<4" -nbclient = ">=0.5.0" -nbformat = ">=5.7" -packaging = "*" -pandocfilters = ">=1.4.1" -pygments = ">=2.4.1" -tinycss2 = "*" -traitlets = ">=5.1" - -[package.extras] -all = ["nbconvert[docs,qtpdf,serve,test,webpdf]"] -docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (==5.0.2)", "sphinxcontrib-spelling"] -qtpdf = ["nbconvert[qtpng]"] -qtpng = ["pyqtwebengine (>=5.15)"] -serve = ["tornado (>=6.1)"] -test = ["flaky", "ipykernel", "ipywidgets (>=7.5)", "pytest"] -webpdf = ["playwright"] - -[[package]] -name = "nbformat" -version = "5.9.2" -description = "The Jupyter Notebook format" -optional = false -python-versions = ">=3.8" -files = [ - {file = "nbformat-5.9.2-py3-none-any.whl", hash = "sha256:1c5172d786a41b82bcfd0c23f9e6b6f072e8fb49c39250219e4acfff1efe89e9"}, - {file = "nbformat-5.9.2.tar.gz", hash = "sha256:5f98b5ba1997dff175e77e0c17d5c10a96eaed2cbd1de3533d1fc35d5e111192"}, -] - -[package.dependencies] -fastjsonschema = "*" -jsonschema = ">=2.6" -jupyter-core = "*" -traitlets = ">=5.1" - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["pep440", "pre-commit", "pytest", "testpath"] - -[[package]] -name = "nest-asyncio" -version = "1.6.0" -description = "Patch asyncio to allow nested event loops" -optional = false -python-versions = ">=3.5" -files = [ - {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, - {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, -] - -[[package]] -name = "notebook" -version = "7.0.7" -description = "Jupyter Notebook - A web-based notebook environment for interactive computing" -optional = false -python-versions = ">=3.8" -files = [ - {file = "notebook-7.0.7-py3-none-any.whl", hash = "sha256:289b606d7e173f75a18beb1406ef411b43f97f7a9c55ba03efa3622905a62346"}, - {file = "notebook-7.0.7.tar.gz", hash = "sha256:3bcff00c17b3ac142ef5f436d50637d936b274cfa0b41f6ac0175363de9b4e09"}, -] - -[package.dependencies] -jupyter-server = ">=2.4.0,<3" -jupyterlab = ">=4.0.2,<5" -jupyterlab-server = ">=2.22.1,<3" -notebook-shim = ">=0.2,<0.3" -tornado = ">=6.2.0" - -[package.extras] -dev = ["hatch", "pre-commit"] -docs = ["myst-parser", "nbsphinx", "pydata-sphinx-theme", "sphinx (>=1.3.6)", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["importlib-resources (>=5.0)", "ipykernel", "jupyter-server[test] (>=2.4.0,<3)", "jupyterlab-server[test] (>=2.22.1,<3)", "nbval", "pytest (>=7.0)", "pytest-console-scripts", "pytest-timeout", "pytest-tornasync", "requests"] - -[[package]] -name = "notebook-shim" -version = "0.2.3" -description = "A shim layer for notebook traits and config" -optional = false -python-versions = ">=3.7" -files = [ - {file = "notebook_shim-0.2.3-py3-none-any.whl", hash = "sha256:a83496a43341c1674b093bfcebf0fe8e74cbe7eda5fd2bbc56f8e39e1486c0c7"}, - {file = "notebook_shim-0.2.3.tar.gz", hash = "sha256:f69388ac283ae008cd506dda10d0288b09a017d822d5e8c7129a152cbd3ce7e9"}, -] - -[package.dependencies] -jupyter-server = ">=1.8,<3" - -[package.extras] -test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync"] - -[[package]] -name = "nptyping" -version = "2.5.0" -description = "Type hints for NumPy." -optional = false -python-versions = ">=3.7" -files = [ - {file = "nptyping-2.5.0-py3-none-any.whl", hash = "sha256:764e51836faae33a7ae2e928af574cfb701355647accadcc89f2ad793630b7c8"}, - {file = "nptyping-2.5.0.tar.gz", hash = "sha256:e3d35b53af967e6fb407c3016ff9abae954d3a0568f7cc13a461084224e8e20a"}, -] - -[package.dependencies] -numpy = {version = ">=1.20.0,<2.0.0", markers = "python_version >= \"3.8\""} -typing-extensions = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.10\""} - -[package.extras] -build = ["invoke (>=1.6.0)", "pip-tools (>=6.5.0)"] -complete = ["pandas", "pandas-stubs-fork"] -dev = ["autoflake", "beartype (<0.10.0)", "beartype (>=0.10.0)", "black", "codecov (>=2.1.0)", "coverage", "feedparser", "invoke (>=1.6.0)", "isort", "mypy", "pandas", "pandas-stubs-fork", "pip-tools (>=6.5.0)", "pylint", "pyright", "setuptools", "typeguard", "wheel"] -pandas = ["pandas", "pandas-stubs-fork"] -qa = ["autoflake", "beartype (<0.10.0)", "beartype (>=0.10.0)", "black", "codecov (>=2.1.0)", "coverage", "feedparser", "isort", "mypy", "pylint", "pyright", "setuptools", "typeguard", "wheel"] - -[[package]] -name = "numcodecs" -version = "0.12.1" -description = "A Python package providing buffer compression and transformation codecs for use in data storage and communication applications." -optional = false -python-versions = ">=3.8" -files = [ - {file = "numcodecs-0.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d37f628fe92b3699e65831d5733feca74d2e33b50ef29118ffd41c13c677210e"}, - {file = "numcodecs-0.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:941b7446b68cf79f089bcfe92edaa3b154533dcbcd82474f994b28f2eedb1c60"}, - {file = "numcodecs-0.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e79bf9d1d37199ac00a60ff3adb64757523291d19d03116832e600cac391c51"}, - {file = "numcodecs-0.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:82d7107f80f9307235cb7e74719292d101c7ea1e393fe628817f0d635b7384f5"}, - {file = "numcodecs-0.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:eeaf42768910f1c6eebf6c1bb00160728e62c9343df9e2e315dc9fe12e3f6071"}, - {file = "numcodecs-0.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:135b2d47563f7b9dc5ee6ce3d1b81b0f1397f69309e909f1a35bb0f7c553d45e"}, - {file = "numcodecs-0.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a191a8e347ecd016e5c357f2bf41fbcb026f6ffe78fff50c77ab12e96701d155"}, - {file = "numcodecs-0.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:21d8267bd4313f4d16f5b6287731d4c8ebdab236038f29ad1b0e93c9b2ca64ee"}, - {file = "numcodecs-0.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2f84df6b8693206365a5b37c005bfa9d1be486122bde683a7b6446af4b75d862"}, - {file = "numcodecs-0.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:760627780a8b6afdb7f942f2a0ddaf4e31d3d7eea1d8498cf0fd3204a33c4618"}, - {file = "numcodecs-0.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c258bd1d3dfa75a9b708540d23b2da43d63607f9df76dfa0309a7597d1de3b73"}, - {file = "numcodecs-0.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:e04649ea504aff858dbe294631f098fbfd671baf58bfc04fc48d746554c05d67"}, - {file = "numcodecs-0.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:caf1a1e6678aab9c1e29d2109b299f7a467bd4d4c34235b1f0e082167846b88f"}, - {file = "numcodecs-0.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c17687b1fd1fef68af616bc83f896035d24e40e04e91e7e6dae56379eb59fe33"}, - {file = "numcodecs-0.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29dfb195f835a55c4d490fb097aac8c1bcb96c54cf1b037d9218492c95e9d8c5"}, - {file = "numcodecs-0.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:2f1ba2f4af3fd3ba65b1bcffb717fe65efe101a50a91c368f79f3101dbb1e243"}, - {file = "numcodecs-0.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2fbb12a6a1abe95926f25c65e283762d63a9bf9e43c0de2c6a1a798347dfcb40"}, - {file = "numcodecs-0.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f2207871868b2464dc11c513965fd99b958a9d7cde2629be7b2dc84fdaab013b"}, - {file = "numcodecs-0.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abff3554a6892a89aacf7b642a044e4535499edf07aeae2f2e6e8fc08c9ba07f"}, - {file = "numcodecs-0.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:ef964d4860d3e6b38df0633caf3e51dc850a6293fd8e93240473642681d95136"}, - {file = "numcodecs-0.12.1.tar.gz", hash = "sha256:05d91a433733e7eef268d7e80ec226a0232da244289614a8f3826901aec1098e"}, -] - -[package.dependencies] -numpy = ">=1.7" - -[package.extras] -docs = ["mock", "numpydoc", "sphinx (<7.0.0)", "sphinx-issues"] -msgpack = ["msgpack"] -test = ["coverage", "flake8", "pytest", "pytest-cov"] -test-extras = ["importlib-metadata"] -zfpy = ["zfpy (>=1.0.0)"] - -[[package]] -name = "numpy" -version = "1.26.4" -description = "Fundamental package for array computing in Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, - {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, - {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, - {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, - {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, - {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, - {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, - {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, - {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, - {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, - {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, - {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, - {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, - {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, - {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, - {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, - {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, - {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, - {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, - {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, - {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, - {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, - {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, - {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, - {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, - {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, - {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, - {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, - {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, - {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, - {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, - {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, - {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, - {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, - {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, - {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, -] - -[[package]] -name = "overrides" -version = "7.7.0" -description = "A decorator to automatically detect mismatch when overriding a method." -optional = false -python-versions = ">=3.6" -files = [ - {file = "overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49"}, - {file = "overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a"}, -] - -[[package]] -name = "packaging" -version = "23.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, -] - -[[package]] -name = "pandas" -version = "2.2.0" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pandas-2.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8108ee1712bb4fa2c16981fba7e68b3f6ea330277f5ca34fa8d557e986a11670"}, - {file = "pandas-2.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:736da9ad4033aeab51d067fc3bd69a0ba36f5a60f66a527b3d72e2030e63280a"}, - {file = "pandas-2.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38e0b4fc3ddceb56ec8a287313bc22abe17ab0eb184069f08fc6a9352a769b18"}, - {file = "pandas-2.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20404d2adefe92aed3b38da41d0847a143a09be982a31b85bc7dd565bdba0f4e"}, - {file = "pandas-2.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7ea3ee3f125032bfcade3a4cf85131ed064b4f8dd23e5ce6fa16473e48ebcaf5"}, - {file = "pandas-2.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9670b3ac00a387620489dfc1bca66db47a787f4e55911f1293063a78b108df1"}, - {file = "pandas-2.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:5a946f210383c7e6d16312d30b238fd508d80d927014f3b33fb5b15c2f895430"}, - {file = "pandas-2.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a1b438fa26b208005c997e78672f1aa8138f67002e833312e6230f3e57fa87d5"}, - {file = "pandas-2.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8ce2fbc8d9bf303ce54a476116165220a1fedf15985b09656b4b4275300e920b"}, - {file = "pandas-2.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2707514a7bec41a4ab81f2ccce8b382961a29fbe9492eab1305bb075b2b1ff4f"}, - {file = "pandas-2.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85793cbdc2d5bc32620dc8ffa715423f0c680dacacf55056ba13454a5be5de88"}, - {file = "pandas-2.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:cfd6c2491dc821b10c716ad6776e7ab311f7df5d16038d0b7458bc0b67dc10f3"}, - {file = "pandas-2.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a146b9dcacc3123aa2b399df1a284de5f46287a4ab4fbfc237eac98a92ebcb71"}, - {file = "pandas-2.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:fbc1b53c0e1fdf16388c33c3cca160f798d38aea2978004dd3f4d3dec56454c9"}, - {file = "pandas-2.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a41d06f308a024981dcaa6c41f2f2be46a6b186b902c94c2674e8cb5c42985bc"}, - {file = "pandas-2.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:159205c99d7a5ce89ecfc37cb08ed179de7783737cea403b295b5eda8e9c56d1"}, - {file = "pandas-2.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1e1f3861ea9132b32f2133788f3b14911b68102d562715d71bd0013bc45440"}, - {file = "pandas-2.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:761cb99b42a69005dec2b08854fb1d4888fdf7b05db23a8c5a099e4b886a2106"}, - {file = "pandas-2.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a20628faaf444da122b2a64b1e5360cde100ee6283ae8effa0d8745153809a2e"}, - {file = "pandas-2.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f5be5d03ea2073627e7111f61b9f1f0d9625dc3c4d8dda72cc827b0c58a1d042"}, - {file = "pandas-2.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:a626795722d893ed6aacb64d2401d017ddc8a2341b49e0384ab9bf7112bdec30"}, - {file = "pandas-2.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9f66419d4a41132eb7e9a73dcec9486cf5019f52d90dd35547af11bc58f8637d"}, - {file = "pandas-2.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:57abcaeda83fb80d447f28ab0cc7b32b13978f6f733875ebd1ed14f8fbc0f4ab"}, - {file = "pandas-2.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e60f1f7dba3c2d5ca159e18c46a34e7ca7247a73b5dd1a22b6d59707ed6b899a"}, - {file = "pandas-2.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb61dc8567b798b969bcc1fc964788f5a68214d333cade8319c7ab33e2b5d88a"}, - {file = "pandas-2.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:52826b5f4ed658fa2b729264d63f6732b8b29949c7fd234510d57c61dbeadfcd"}, - {file = "pandas-2.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bde2bc699dbd80d7bc7f9cab1e23a95c4375de615860ca089f34e7c64f4a8de7"}, - {file = "pandas-2.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:3de918a754bbf2da2381e8a3dcc45eede8cd7775b047b923f9006d5f876802ae"}, - {file = "pandas-2.2.0.tar.gz", hash = "sha256:30b83f7c3eb217fb4d1b494a57a2fda5444f17834f5df2de6b2ffff68dc3c8e2"}, -] - -[package.dependencies] -numpy = [ - {version = ">=1.22.4,<2", markers = "python_version < \"3.11\""}, - {version = ">=1.23.2,<2", markers = "python_version == \"3.11\""}, - {version = ">=1.26.0,<2", markers = "python_version >= \"3.12\""}, -] -python-dateutil = ">=2.8.2" -pytz = ">=2020.1" -tzdata = ">=2022.7" - -[package.extras] -all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] -aws = ["s3fs (>=2022.11.0)"] -clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] -compression = ["zstandard (>=0.19.0)"] -computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] -consortium-standard = ["dataframe-api-compat (>=0.1.7)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] -feather = ["pyarrow (>=10.0.1)"] -fss = ["fsspec (>=2022.11.0)"] -gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] -hdf5 = ["tables (>=3.8.0)"] -html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] -mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] -parquet = ["pyarrow (>=10.0.1)"] -performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] -plot = ["matplotlib (>=3.6.3)"] -postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] -spss = ["pyreadstat (>=1.2.0)"] -sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] -test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.9.2)"] - -[[package]] -name = "pandocfilters" -version = "1.5.1" -description = "Utilities for writing pandoc filters in python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc"}, - {file = "pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e"}, -] - -[[package]] -name = "parso" -version = "0.8.3" -description = "A Python Parser" -optional = false -python-versions = ">=3.6" -files = [ - {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, - {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, -] - -[package.extras] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] -testing = ["docopt", "pytest (<6.0.0)"] - -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - -[[package]] -name = "pexpect" -version = "4.9.0" -description = "Pexpect allows easy control of interactive console applications." -optional = false -python-versions = "*" -files = [ - {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, - {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, -] - -[package.dependencies] -ptyprocess = ">=0.5" - -[[package]] -name = "platformdirs" -version = "4.2.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, - {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, -] - -[package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] - -[[package]] -name = "pluggy" -version = "1.4.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, - {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "prefixcommons" -version = "0.1.12" -description = "A python API for working with ID prefixes" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "prefixcommons-0.1.12-py3-none-any.whl", hash = "sha256:16dbc0a1f775e003c724f19a694fcfa3174608f5c8b0e893d494cf8098ac7f8b"}, - {file = "prefixcommons-0.1.12.tar.gz", hash = "sha256:22c4e2d37b63487b3ab48f0495b70f14564cb346a15220f23919eb0c1851f69f"}, -] - -[package.dependencies] -click = ">=8.1.3,<9.0.0" -pytest-logging = ">=2015.11.4,<2016.0.0" -PyYAML = ">=6.0,<7.0" -requests = ">=2.28.1,<3.0.0" - -[[package]] -name = "prefixmaps" -version = "0.1.5" -description = "A python library for retrieving semantic prefix maps" -optional = false -python-versions = ">=3.7.6,<4.0.0" -files = [ - {file = "prefixmaps-0.1.5-py3-none-any.whl", hash = "sha256:afe679efa0fa62ae69939771956a76e2958505743b40755c8bae85732622b5b2"}, - {file = "prefixmaps-0.1.5.tar.gz", hash = "sha256:0073f69477f7e9e2359409c0e9d2f853c958600825d9ed859c4c6c71134010a1"}, -] - -[package.dependencies] -click = ">=8.1.3,<9.0.0" -greenlet = "2.0.1" -importlib-metadata = ">=1.0.0" -pyyaml = ">=5.3.1" -typing-extensions = ">=4.4.0,<5.0.0" - -[package.extras] -docs = ["Sphinx[docs] (>=5.3.0,<6.0.0)", "myst-parser[docs] (>=0.18.1,<0.19.0)", "sphinx-autodoc-typehints[docs] (>=1.19.4,<2.0.0)", "sphinx-click[docs] (>=4.3.0,<5.0.0)", "sphinx-rtd-theme[docs] (>=1.0.0,<2.0.0)"] -refresh = ["bioregistry[refresh] (>=0.8.0,<0.9.0)", "rdflib[refresh] (>=6.2.0,<7.0.0)", "requests[refresh] (>=2.28.1,<3.0.0)"] - -[[package]] -name = "prometheus-client" -version = "0.19.0" -description = "Python client for the Prometheus monitoring system." -optional = false -python-versions = ">=3.8" -files = [ - {file = "prometheus_client-0.19.0-py3-none-any.whl", hash = "sha256:c88b1e6ecf6b41cd8fb5731c7ae919bf66df6ec6fafa555cd6c0e16ca169ae92"}, - {file = "prometheus_client-0.19.0.tar.gz", hash = "sha256:4585b0d1223148c27a225b10dbec5ae9bc4c81a99a3fa80774fa6209935324e1"}, -] - -[package.extras] -twisted = ["twisted"] - -[[package]] -name = "prompt-toolkit" -version = "3.0.43" -description = "Library for building powerful interactive command lines in Python" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"}, - {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"}, -] - -[package.dependencies] -wcwidth = "*" - -[[package]] -name = "psutil" -version = "5.9.8" -description = "Cross-platform lib for process and system monitoring in Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "psutil-5.9.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8"}, - {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73"}, - {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7"}, - {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36"}, - {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d"}, - {file = "psutil-5.9.8-cp27-none-win32.whl", hash = "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e"}, - {file = "psutil-5.9.8-cp27-none-win_amd64.whl", hash = "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631"}, - {file = "psutil-5.9.8-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81"}, - {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421"}, - {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4"}, - {file = "psutil-5.9.8-cp36-cp36m-win32.whl", hash = "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee"}, - {file = "psutil-5.9.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2"}, - {file = "psutil-5.9.8-cp37-abi3-win32.whl", hash = "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0"}, - {file = "psutil-5.9.8-cp37-abi3-win_amd64.whl", hash = "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf"}, - {file = "psutil-5.9.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8"}, - {file = "psutil-5.9.8.tar.gz", hash = "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c"}, -] - -[package.extras] -test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] - -[[package]] -name = "ptyprocess" -version = "0.7.0" -description = "Run a subprocess in a pseudo terminal" -optional = false -python-versions = "*" -files = [ - {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, - {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, -] - -[[package]] -name = "pure-eval" -version = "0.2.2" -description = "Safely evaluate AST nodes without side effects" -optional = false -python-versions = "*" -files = [ - {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, - {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, -] - -[package.extras] -tests = ["pytest"] - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] - -[[package]] -name = "pycparser" -version = "2.21" -description = "C parser in Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, - {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, -] - -[[package]] -name = "pydantic" -version = "2.6.1" -description = "Data validation using Python type hints" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic-2.6.1-py3-none-any.whl", hash = "sha256:0b6a909df3192245cb736509a92ff69e4fef76116feffec68e93a567347bae6f"}, - {file = "pydantic-2.6.1.tar.gz", hash = "sha256:4fd5c182a2488dc63e6d32737ff19937888001e2a6d86e94b3f233104a5d1fa9"}, -] - -[package.dependencies] -annotated-types = ">=0.4.0" -pydantic-core = "2.16.2" -typing-extensions = ">=4.6.1" - -[package.extras] -email = ["email-validator (>=2.0.0)"] - -[[package]] -name = "pydantic-core" -version = "2.16.2" -description = "" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic_core-2.16.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3fab4e75b8c525a4776e7630b9ee48aea50107fea6ca9f593c98da3f4d11bf7c"}, - {file = "pydantic_core-2.16.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8bde5b48c65b8e807409e6f20baee5d2cd880e0fad00b1a811ebc43e39a00ab2"}, - {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2924b89b16420712e9bb8192396026a8fbd6d8726224f918353ac19c4c043d2a"}, - {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:16aa02e7a0f539098e215fc193c8926c897175d64c7926d00a36188917717a05"}, - {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:936a787f83db1f2115ee829dd615c4f684ee48ac4de5779ab4300994d8af325b"}, - {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:459d6be6134ce3b38e0ef76f8a672924460c455d45f1ad8fdade36796df1ddc8"}, - {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9ee4febb249c591d07b2d4dd36ebcad0ccd128962aaa1801508320896575ef"}, - {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:40a0bd0bed96dae5712dab2aba7d334a6c67cbcac2ddfca7dbcc4a8176445990"}, - {file = "pydantic_core-2.16.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:870dbfa94de9b8866b37b867a2cb37a60c401d9deb4a9ea392abf11a1f98037b"}, - {file = "pydantic_core-2.16.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:308974fdf98046db28440eb3377abba274808bf66262e042c412eb2adf852731"}, - {file = "pydantic_core-2.16.2-cp310-none-win32.whl", hash = "sha256:a477932664d9611d7a0816cc3c0eb1f8856f8a42435488280dfbf4395e141485"}, - {file = "pydantic_core-2.16.2-cp310-none-win_amd64.whl", hash = "sha256:8f9142a6ed83d90c94a3efd7af8873bf7cefed2d3d44387bf848888482e2d25f"}, - {file = "pydantic_core-2.16.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:406fac1d09edc613020ce9cf3f2ccf1a1b2f57ab00552b4c18e3d5276c67eb11"}, - {file = "pydantic_core-2.16.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ce232a6170dd6532096cadbf6185271e4e8c70fc9217ebe105923ac105da9978"}, - {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a90fec23b4b05a09ad988e7a4f4e081711a90eb2a55b9c984d8b74597599180f"}, - {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8aafeedb6597a163a9c9727d8a8bd363a93277701b7bfd2749fbefee2396469e"}, - {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9957433c3a1b67bdd4c63717eaf174ebb749510d5ea612cd4e83f2d9142f3fc8"}, - {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0d7a9165167269758145756db43a133608a531b1e5bb6a626b9ee24bc38a8f7"}, - {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dffaf740fe2e147fedcb6b561353a16243e654f7fe8e701b1b9db148242e1272"}, - {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8ed79883b4328b7f0bd142733d99c8e6b22703e908ec63d930b06be3a0e7113"}, - {file = "pydantic_core-2.16.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:cf903310a34e14651c9de056fcc12ce090560864d5a2bb0174b971685684e1d8"}, - {file = "pydantic_core-2.16.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:46b0d5520dbcafea9a8645a8164658777686c5c524d381d983317d29687cce97"}, - {file = "pydantic_core-2.16.2-cp311-none-win32.whl", hash = "sha256:70651ff6e663428cea902dac297066d5c6e5423fda345a4ca62430575364d62b"}, - {file = "pydantic_core-2.16.2-cp311-none-win_amd64.whl", hash = "sha256:98dc6f4f2095fc7ad277782a7c2c88296badcad92316b5a6e530930b1d475ebc"}, - {file = "pydantic_core-2.16.2-cp311-none-win_arm64.whl", hash = "sha256:ef6113cd31411eaf9b39fc5a8848e71c72656fd418882488598758b2c8c6dfa0"}, - {file = "pydantic_core-2.16.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:88646cae28eb1dd5cd1e09605680c2b043b64d7481cdad7f5003ebef401a3039"}, - {file = "pydantic_core-2.16.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7b883af50eaa6bb3299780651e5be921e88050ccf00e3e583b1e92020333304b"}, - {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bf26c2e2ea59d32807081ad51968133af3025c4ba5753e6a794683d2c91bf6e"}, - {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:99af961d72ac731aae2a1b55ccbdae0733d816f8bfb97b41909e143de735f522"}, - {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02906e7306cb8c5901a1feb61f9ab5e5c690dbbeaa04d84c1b9ae2a01ebe9379"}, - {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5362d099c244a2d2f9659fb3c9db7c735f0004765bbe06b99be69fbd87c3f15"}, - {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ac426704840877a285d03a445e162eb258924f014e2f074e209d9b4ff7bf380"}, - {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b94cbda27267423411c928208e89adddf2ea5dd5f74b9528513f0358bba019cb"}, - {file = "pydantic_core-2.16.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6db58c22ac6c81aeac33912fb1af0e930bc9774166cdd56eade913d5f2fff35e"}, - {file = "pydantic_core-2.16.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:396fdf88b1b503c9c59c84a08b6833ec0c3b5ad1a83230252a9e17b7dfb4cffc"}, - {file = "pydantic_core-2.16.2-cp312-none-win32.whl", hash = "sha256:7c31669e0c8cc68400ef0c730c3a1e11317ba76b892deeefaf52dcb41d56ed5d"}, - {file = "pydantic_core-2.16.2-cp312-none-win_amd64.whl", hash = "sha256:a3b7352b48fbc8b446b75f3069124e87f599d25afb8baa96a550256c031bb890"}, - {file = "pydantic_core-2.16.2-cp312-none-win_arm64.whl", hash = "sha256:a9e523474998fb33f7c1a4d55f5504c908d57add624599e095c20fa575b8d943"}, - {file = "pydantic_core-2.16.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:ae34418b6b389d601b31153b84dce480351a352e0bb763684a1b993d6be30f17"}, - {file = "pydantic_core-2.16.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:732bd062c9e5d9582a30e8751461c1917dd1ccbdd6cafb032f02c86b20d2e7ec"}, - {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b52776a2e3230f4854907a1e0946eec04d41b1fc64069ee774876bbe0eab55"}, - {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ef551c053692b1e39e3f7950ce2296536728871110e7d75c4e7753fb30ca87f4"}, - {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ebb892ed8599b23fa8f1799e13a12c87a97a6c9d0f497525ce9858564c4575a4"}, - {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa6c8c582036275997a733427b88031a32ffa5dfc3124dc25a730658c47a572f"}, - {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4ba0884a91f1aecce75202473ab138724aa4fb26d7707f2e1fa6c3e68c84fbf"}, - {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7924e54f7ce5d253d6160090ddc6df25ed2feea25bfb3339b424a9dd591688bc"}, - {file = "pydantic_core-2.16.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69a7b96b59322a81c2203be537957313b07dd333105b73db0b69212c7d867b4b"}, - {file = "pydantic_core-2.16.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7e6231aa5bdacda78e96ad7b07d0c312f34ba35d717115f4b4bff6cb87224f0f"}, - {file = "pydantic_core-2.16.2-cp38-none-win32.whl", hash = "sha256:41dac3b9fce187a25c6253ec79a3f9e2a7e761eb08690e90415069ea4a68ff7a"}, - {file = "pydantic_core-2.16.2-cp38-none-win_amd64.whl", hash = "sha256:f685dbc1fdadb1dcd5b5e51e0a378d4685a891b2ddaf8e2bba89bd3a7144e44a"}, - {file = "pydantic_core-2.16.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:55749f745ebf154c0d63d46c8c58594d8894b161928aa41adbb0709c1fe78b77"}, - {file = "pydantic_core-2.16.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b30b0dd58a4509c3bd7eefddf6338565c4905406aee0c6e4a5293841411a1286"}, - {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18de31781cdc7e7b28678df7c2d7882f9692ad060bc6ee3c94eb15a5d733f8f7"}, - {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5864b0242f74b9dd0b78fd39db1768bc3f00d1ffc14e596fd3e3f2ce43436a33"}, - {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8f9186ca45aee030dc8234118b9c0784ad91a0bb27fc4e7d9d6608a5e3d386c"}, - {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc6f6c9be0ab6da37bc77c2dda5f14b1d532d5dbef00311ee6e13357a418e646"}, - {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa057095f621dad24a1e906747179a69780ef45cc8f69e97463692adbcdae878"}, - {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ad84731a26bcfb299f9eab56c7932d46f9cad51c52768cace09e92a19e4cf55"}, - {file = "pydantic_core-2.16.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3b052c753c4babf2d1edc034c97851f867c87d6f3ea63a12e2700f159f5c41c3"}, - {file = "pydantic_core-2.16.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e0f686549e32ccdb02ae6f25eee40cc33900910085de6aa3790effd391ae10c2"}, - {file = "pydantic_core-2.16.2-cp39-none-win32.whl", hash = "sha256:7afb844041e707ac9ad9acad2188a90bffce2c770e6dc2318be0c9916aef1469"}, - {file = "pydantic_core-2.16.2-cp39-none-win_amd64.whl", hash = "sha256:9da90d393a8227d717c19f5397688a38635afec89f2e2d7af0df037f3249c39a"}, - {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5f60f920691a620b03082692c378661947d09415743e437a7478c309eb0e4f82"}, - {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:47924039e785a04d4a4fa49455e51b4eb3422d6eaacfde9fc9abf8fdef164e8a"}, - {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6294e76b0380bb7a61eb8a39273c40b20beb35e8c87ee101062834ced19c545"}, - {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe56851c3f1d6f5384b3051c536cc81b3a93a73faf931f404fef95217cf1e10d"}, - {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9d776d30cde7e541b8180103c3f294ef7c1862fd45d81738d156d00551005784"}, - {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:72f7919af5de5ecfaf1eba47bf9a5d8aa089a3340277276e5636d16ee97614d7"}, - {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:4bfcbde6e06c56b30668a0c872d75a7ef3025dc3c1823a13cf29a0e9b33f67e8"}, - {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ff7c97eb7a29aba230389a2661edf2e9e06ce616c7e35aa764879b6894a44b25"}, - {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:9b5f13857da99325dcabe1cc4e9e6a3d7b2e2c726248ba5dd4be3e8e4a0b6d0e"}, - {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a7e41e3ada4cca5f22b478c08e973c930e5e6c7ba3588fb8e35f2398cdcc1545"}, - {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60eb8ceaa40a41540b9acae6ae7c1f0a67d233c40dc4359c256ad2ad85bdf5e5"}, - {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7beec26729d496a12fd23cf8da9944ee338c8b8a17035a560b585c36fe81af20"}, - {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:22c5f022799f3cd6741e24f0443ead92ef42be93ffda0d29b2597208c94c3753"}, - {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:eca58e319f4fd6df004762419612122b2c7e7d95ffafc37e890252f869f3fb2a"}, - {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ed957db4c33bc99895f3a1672eca7e80e8cda8bd1e29a80536b4ec2153fa9804"}, - {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:459c0d338cc55d099798618f714b21b7ece17eb1a87879f2da20a3ff4c7628e2"}, - {file = "pydantic_core-2.16.2.tar.gz", hash = "sha256:0ba503850d8b8dcc18391f10de896ae51d37fe5fe43dbfb6a35c5c5cad271a06"}, -] - -[package.dependencies] -typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" - -[[package]] -name = "pygments" -version = "2.17.2" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, - {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, -] - -[package.extras] -plugins = ["importlib-metadata"] -windows-terminal = ["colorama (>=0.4.6)"] - -[[package]] -name = "pyparsing" -version = "3.1.1" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -optional = false -python-versions = ">=3.6.8" -files = [ - {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"}, - {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"}, -] - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - -[[package]] -name = "pytest" -version = "7.4.4" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} - -[package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-logging" -version = "2015.11.4" -description = "Configures logging and allows tweaking the log level with a py.test flag" -optional = false -python-versions = "*" -files = [ - {file = "pytest-logging-2015.11.4.tar.gz", hash = "sha256:cec5c85ecf18aab7b2ead5498a31b9f758680ef5a902b9054ab3f2bdbb77c896"}, -] - -[package.dependencies] -pytest = ">=2.8.1" - -[[package]] -name = "python-dateutil" -version = "2.8.2" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "python-json-logger" -version = "2.0.7" -description = "A python library adding a json log formatter" -optional = false -python-versions = ">=3.6" -files = [ - {file = "python-json-logger-2.0.7.tar.gz", hash = "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c"}, - {file = "python_json_logger-2.0.7-py3-none-any.whl", hash = "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd"}, -] - -[[package]] -name = "pytrie" -version = "0.4.0" -description = "A pure Python implementation of the trie data structure." -optional = false -python-versions = "*" -files = [ - {file = "PyTrie-0.4.0.tar.gz", hash = "sha256:8f4488f402d3465993fb6b6efa09866849ed8cda7903b50647b7d0342b805379"}, -] - -[package.dependencies] -sortedcontainers = "*" - -[[package]] -name = "pytz" -version = "2024.1" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, -] - -[[package]] -name = "pywin32" -version = "306" -description = "Python for Window Extensions" -optional = false -python-versions = "*" -files = [ - {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, - {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, - {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, - {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, - {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, - {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, - {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, - {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, - {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, - {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, - {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, - {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, - {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, - {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, -] - -[[package]] -name = "pywinpty" -version = "2.0.12" -description = "Pseudo terminal support for Windows from Python." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pywinpty-2.0.12-cp310-none-win_amd64.whl", hash = "sha256:21319cd1d7c8844fb2c970fb3a55a3db5543f112ff9cfcd623746b9c47501575"}, - {file = "pywinpty-2.0.12-cp311-none-win_amd64.whl", hash = "sha256:853985a8f48f4731a716653170cd735da36ffbdc79dcb4c7b7140bce11d8c722"}, - {file = "pywinpty-2.0.12-cp312-none-win_amd64.whl", hash = "sha256:1617b729999eb6713590e17665052b1a6ae0ad76ee31e60b444147c5b6a35dca"}, - {file = "pywinpty-2.0.12-cp38-none-win_amd64.whl", hash = "sha256:189380469ca143d06e19e19ff3fba0fcefe8b4a8cc942140a6b863aed7eebb2d"}, - {file = "pywinpty-2.0.12-cp39-none-win_amd64.whl", hash = "sha256:7520575b6546db23e693cbd865db2764097bd6d4ef5dc18c92555904cd62c3d4"}, - {file = "pywinpty-2.0.12.tar.gz", hash = "sha256:8197de460ae8ebb7f5d1701dfa1b5df45b157bb832e92acba316305e18ca00dd"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.1" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, -] - -[[package]] -name = "pyzmq" -version = "25.1.2" -description = "Python bindings for 0MQ" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pyzmq-25.1.2-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:e624c789359f1a16f83f35e2c705d07663ff2b4d4479bad35621178d8f0f6ea4"}, - {file = "pyzmq-25.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:49151b0efece79f6a79d41a461d78535356136ee70084a1c22532fc6383f4ad0"}, - {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9a5f194cf730f2b24d6af1f833c14c10f41023da46a7f736f48b6d35061e76e"}, - {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:faf79a302f834d9e8304fafdc11d0d042266667ac45209afa57e5efc998e3872"}, - {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f51a7b4ead28d3fca8dda53216314a553b0f7a91ee8fc46a72b402a78c3e43d"}, - {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:0ddd6d71d4ef17ba5a87becf7ddf01b371eaba553c603477679ae817a8d84d75"}, - {file = "pyzmq-25.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:246747b88917e4867e2367b005fc8eefbb4a54b7db363d6c92f89d69abfff4b6"}, - {file = "pyzmq-25.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:00c48ae2fd81e2a50c3485de1b9d5c7c57cd85dc8ec55683eac16846e57ac979"}, - {file = "pyzmq-25.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5a68d491fc20762b630e5db2191dd07ff89834086740f70e978bb2ef2668be08"}, - {file = "pyzmq-25.1.2-cp310-cp310-win32.whl", hash = "sha256:09dfe949e83087da88c4a76767df04b22304a682d6154de2c572625c62ad6886"}, - {file = "pyzmq-25.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:fa99973d2ed20417744fca0073390ad65ce225b546febb0580358e36aa90dba6"}, - {file = "pyzmq-25.1.2-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:82544e0e2d0c1811482d37eef297020a040c32e0687c1f6fc23a75b75db8062c"}, - {file = "pyzmq-25.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:01171fc48542348cd1a360a4b6c3e7d8f46cdcf53a8d40f84db6707a6768acc1"}, - {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc69c96735ab501419c432110016329bf0dea8898ce16fab97c6d9106dc0b348"}, - {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3e124e6b1dd3dfbeb695435dff0e383256655bb18082e094a8dd1f6293114642"}, - {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7598d2ba821caa37a0f9d54c25164a4fa351ce019d64d0b44b45540950458840"}, - {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d1299d7e964c13607efd148ca1f07dcbf27c3ab9e125d1d0ae1d580a1682399d"}, - {file = "pyzmq-25.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4e6f689880d5ad87918430957297c975203a082d9a036cc426648fcbedae769b"}, - {file = "pyzmq-25.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cc69949484171cc961e6ecd4a8911b9ce7a0d1f738fcae717177c231bf77437b"}, - {file = "pyzmq-25.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9880078f683466b7f567b8624bfc16cad65077be046b6e8abb53bed4eeb82dd3"}, - {file = "pyzmq-25.1.2-cp311-cp311-win32.whl", hash = "sha256:4e5837af3e5aaa99a091302df5ee001149baff06ad22b722d34e30df5f0d9097"}, - {file = "pyzmq-25.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:25c2dbb97d38b5ac9fd15586e048ec5eb1e38f3d47fe7d92167b0c77bb3584e9"}, - {file = "pyzmq-25.1.2-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:11e70516688190e9c2db14fcf93c04192b02d457b582a1f6190b154691b4c93a"}, - {file = "pyzmq-25.1.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:313c3794d650d1fccaaab2df942af9f2c01d6217c846177cfcbc693c7410839e"}, - {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b3cbba2f47062b85fe0ef9de5b987612140a9ba3a9c6d2543c6dec9f7c2ab27"}, - {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc31baa0c32a2ca660784d5af3b9487e13b61b3032cb01a115fce6588e1bed30"}, - {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02c9087b109070c5ab0b383079fa1b5f797f8d43e9a66c07a4b8b8bdecfd88ee"}, - {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:f8429b17cbb746c3e043cb986328da023657e79d5ed258b711c06a70c2ea7537"}, - {file = "pyzmq-25.1.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5074adeacede5f810b7ef39607ee59d94e948b4fd954495bdb072f8c54558181"}, - {file = "pyzmq-25.1.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7ae8f354b895cbd85212da245f1a5ad8159e7840e37d78b476bb4f4c3f32a9fe"}, - {file = "pyzmq-25.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b264bf2cc96b5bc43ce0e852be995e400376bd87ceb363822e2cb1964fcdc737"}, - {file = "pyzmq-25.1.2-cp312-cp312-win32.whl", hash = "sha256:02bbc1a87b76e04fd780b45e7f695471ae6de747769e540da909173d50ff8e2d"}, - {file = "pyzmq-25.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:ced111c2e81506abd1dc142e6cd7b68dd53747b3b7ae5edbea4578c5eeff96b7"}, - {file = "pyzmq-25.1.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:7b6d09a8962a91151f0976008eb7b29b433a560fde056ec7a3db9ec8f1075438"}, - {file = "pyzmq-25.1.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:967668420f36878a3c9ecb5ab33c9d0ff8d054f9c0233d995a6d25b0e95e1b6b"}, - {file = "pyzmq-25.1.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5edac3f57c7ddaacdb4d40f6ef2f9e299471fc38d112f4bc6d60ab9365445fb0"}, - {file = "pyzmq-25.1.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:0dabfb10ef897f3b7e101cacba1437bd3a5032ee667b7ead32bbcdd1a8422fe7"}, - {file = "pyzmq-25.1.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:2c6441e0398c2baacfe5ba30c937d274cfc2dc5b55e82e3749e333aabffde561"}, - {file = "pyzmq-25.1.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:16b726c1f6c2e7625706549f9dbe9b06004dfbec30dbed4bf50cbdfc73e5b32a"}, - {file = "pyzmq-25.1.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:a86c2dd76ef71a773e70551a07318b8e52379f58dafa7ae1e0a4be78efd1ff16"}, - {file = "pyzmq-25.1.2-cp36-cp36m-win32.whl", hash = "sha256:359f7f74b5d3c65dae137f33eb2bcfa7ad9ebefd1cab85c935f063f1dbb245cc"}, - {file = "pyzmq-25.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:55875492f820d0eb3417b51d96fea549cde77893ae3790fd25491c5754ea2f68"}, - {file = "pyzmq-25.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b8c8a419dfb02e91b453615c69568442e897aaf77561ee0064d789705ff37a92"}, - {file = "pyzmq-25.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8807c87fa893527ae8a524c15fc505d9950d5e856f03dae5921b5e9aa3b8783b"}, - {file = "pyzmq-25.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5e319ed7d6b8f5fad9b76daa0a68497bc6f129858ad956331a5835785761e003"}, - {file = "pyzmq-25.1.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3c53687dde4d9d473c587ae80cc328e5b102b517447456184b485587ebd18b62"}, - {file = "pyzmq-25.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9add2e5b33d2cd765ad96d5eb734a5e795a0755f7fc49aa04f76d7ddda73fd70"}, - {file = "pyzmq-25.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e690145a8c0c273c28d3b89d6fb32c45e0d9605b2293c10e650265bf5c11cfec"}, - {file = "pyzmq-25.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:00a06faa7165634f0cac1abb27e54d7a0b3b44eb9994530b8ec73cf52e15353b"}, - {file = "pyzmq-25.1.2-cp37-cp37m-win32.whl", hash = "sha256:0f97bc2f1f13cb16905a5f3e1fbdf100e712d841482b2237484360f8bc4cb3d7"}, - {file = "pyzmq-25.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6cc0020b74b2e410287e5942e1e10886ff81ac77789eb20bec13f7ae681f0fdd"}, - {file = "pyzmq-25.1.2-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:bef02cfcbded83473bdd86dd8d3729cd82b2e569b75844fb4ea08fee3c26ae41"}, - {file = "pyzmq-25.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e10a4b5a4b1192d74853cc71a5e9fd022594573926c2a3a4802020360aa719d8"}, - {file = "pyzmq-25.1.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8c5f80e578427d4695adac6fdf4370c14a2feafdc8cb35549c219b90652536ae"}, - {file = "pyzmq-25.1.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5dde6751e857910c1339890f3524de74007958557593b9e7e8c5f01cd919f8a7"}, - {file = "pyzmq-25.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea1608dd169da230a0ad602d5b1ebd39807ac96cae1845c3ceed39af08a5c6df"}, - {file = "pyzmq-25.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0f513130c4c361201da9bc69df25a086487250e16b5571ead521b31ff6b02220"}, - {file = "pyzmq-25.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:019744b99da30330798bb37df33549d59d380c78e516e3bab9c9b84f87a9592f"}, - {file = "pyzmq-25.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2e2713ef44be5d52dd8b8e2023d706bf66cb22072e97fc71b168e01d25192755"}, - {file = "pyzmq-25.1.2-cp38-cp38-win32.whl", hash = "sha256:07cd61a20a535524906595e09344505a9bd46f1da7a07e504b315d41cd42eb07"}, - {file = "pyzmq-25.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb7e49a17fb8c77d3119d41a4523e432eb0c6932187c37deb6fbb00cc3028088"}, - {file = "pyzmq-25.1.2-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:94504ff66f278ab4b7e03e4cba7e7e400cb73bfa9d3d71f58d8972a8dc67e7a6"}, - {file = "pyzmq-25.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6dd0d50bbf9dca1d0bdea219ae6b40f713a3fb477c06ca3714f208fd69e16fd8"}, - {file = "pyzmq-25.1.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:004ff469d21e86f0ef0369717351073e0e577428e514c47c8480770d5e24a565"}, - {file = "pyzmq-25.1.2-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c0b5ca88a8928147b7b1e2dfa09f3b6c256bc1135a1338536cbc9ea13d3b7add"}, - {file = "pyzmq-25.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c9a79f1d2495b167119d02be7448bfba57fad2a4207c4f68abc0bab4b92925b"}, - {file = "pyzmq-25.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:518efd91c3d8ac9f9b4f7dd0e2b7b8bf1a4fe82a308009016b07eaa48681af82"}, - {file = "pyzmq-25.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1ec23bd7b3a893ae676d0e54ad47d18064e6c5ae1fadc2f195143fb27373f7f6"}, - {file = "pyzmq-25.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db36c27baed588a5a8346b971477b718fdc66cf5b80cbfbd914b4d6d355e44e2"}, - {file = "pyzmq-25.1.2-cp39-cp39-win32.whl", hash = "sha256:39b1067f13aba39d794a24761e385e2eddc26295826530a8c7b6c6c341584289"}, - {file = "pyzmq-25.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:8e9f3fabc445d0ce320ea2c59a75fe3ea591fdbdeebec5db6de530dd4b09412e"}, - {file = "pyzmq-25.1.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a8c1d566344aee826b74e472e16edae0a02e2a044f14f7c24e123002dcff1c05"}, - {file = "pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:759cfd391a0996345ba94b6a5110fca9c557ad4166d86a6e81ea526c376a01e8"}, - {file = "pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c61e346ac34b74028ede1c6b4bcecf649d69b707b3ff9dc0fab453821b04d1e"}, - {file = "pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cb8fc1f8d69b411b8ec0b5f1ffbcaf14c1db95b6bccea21d83610987435f1a4"}, - {file = "pyzmq-25.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3c00c9b7d1ca8165c610437ca0c92e7b5607b2f9076f4eb4b095c85d6e680a1d"}, - {file = "pyzmq-25.1.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:df0c7a16ebb94452d2909b9a7b3337940e9a87a824c4fc1c7c36bb4404cb0cde"}, - {file = "pyzmq-25.1.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:45999e7f7ed5c390f2e87ece7f6c56bf979fb213550229e711e45ecc7d42ccb8"}, - {file = "pyzmq-25.1.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ac170e9e048b40c605358667aca3d94e98f604a18c44bdb4c102e67070f3ac9b"}, - {file = "pyzmq-25.1.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1b604734bec94f05f81b360a272fc824334267426ae9905ff32dc2be433ab96"}, - {file = "pyzmq-25.1.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:a793ac733e3d895d96f865f1806f160696422554e46d30105807fdc9841b9f7d"}, - {file = "pyzmq-25.1.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0806175f2ae5ad4b835ecd87f5f85583316b69f17e97786f7443baaf54b9bb98"}, - {file = "pyzmq-25.1.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ef12e259e7bc317c7597d4f6ef59b97b913e162d83b421dd0db3d6410f17a244"}, - {file = "pyzmq-25.1.2-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea253b368eb41116011add00f8d5726762320b1bda892f744c91997b65754d73"}, - {file = "pyzmq-25.1.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b9b1f2ad6498445a941d9a4fee096d387fee436e45cc660e72e768d3d8ee611"}, - {file = "pyzmq-25.1.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:8b14c75979ce932c53b79976a395cb2a8cd3aaf14aef75e8c2cb55a330b9b49d"}, - {file = "pyzmq-25.1.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:889370d5174a741a62566c003ee8ddba4b04c3f09a97b8000092b7ca83ec9c49"}, - {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a18fff090441a40ffda8a7f4f18f03dc56ae73f148f1832e109f9bffa85df15"}, - {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99a6b36f95c98839ad98f8c553d8507644c880cf1e0a57fe5e3a3f3969040882"}, - {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4345c9a27f4310afbb9c01750e9461ff33d6fb74cd2456b107525bbeebcb5be3"}, - {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3516e0b6224cf6e43e341d56da15fd33bdc37fa0c06af4f029f7d7dfceceabbc"}, - {file = "pyzmq-25.1.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:146b9b1f29ead41255387fb07be56dc29639262c0f7344f570eecdcd8d683314"}, - {file = "pyzmq-25.1.2.tar.gz", hash = "sha256:93f1aa311e8bb912e34f004cf186407a4e90eec4f0ecc0efd26056bf7eda0226"}, -] - -[package.dependencies] -cffi = {version = "*", markers = "implementation_name == \"pypy\""} - -[[package]] -name = "qtconsole" -version = "5.5.1" -description = "Jupyter Qt console" -optional = false -python-versions = ">= 3.8" -files = [ - {file = "qtconsole-5.5.1-py3-none-any.whl", hash = "sha256:8c75fa3e9b4ed884880ff7cea90a1b67451219279ec33deaee1d59e3df1a5d2b"}, - {file = "qtconsole-5.5.1.tar.gz", hash = "sha256:a0e806c6951db9490628e4df80caec9669b65149c7ba40f9bf033c025a5b56bc"}, -] - -[package.dependencies] -ipykernel = ">=4.1" -jupyter-client = ">=4.1" -jupyter-core = "*" -packaging = "*" -pygments = "*" -pyzmq = ">=17.1" -qtpy = ">=2.4.0" -traitlets = "<5.2.1 || >5.2.1,<5.2.2 || >5.2.2" - -[package.extras] -doc = ["Sphinx (>=1.3)"] -test = ["flaky", "pytest", "pytest-qt"] - -[[package]] -name = "qtpy" -version = "2.4.1" -description = "Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6)." -optional = false -python-versions = ">=3.7" -files = [ - {file = "QtPy-2.4.1-py3-none-any.whl", hash = "sha256:1c1d8c4fa2c884ae742b069151b0abe15b3f70491f3972698c683b8e38de839b"}, - {file = "QtPy-2.4.1.tar.gz", hash = "sha256:a5a15ffd519550a1361bdc56ffc07fda56a6af7292f17c7b395d4083af632987"}, -] - -[package.dependencies] -packaging = "*" - -[package.extras] -test = ["pytest (>=6,!=7.0.0,!=7.0.1)", "pytest-cov (>=3.0.0)", "pytest-qt"] - -[[package]] -name = "rdflib" -version = "7.0.0" -description = "RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information." -optional = false -python-versions = ">=3.8.1,<4.0.0" -files = [ - {file = "rdflib-7.0.0-py3-none-any.whl", hash = "sha256:0438920912a642c866a513de6fe8a0001bd86ef975057d6962c79ce4771687cd"}, - {file = "rdflib-7.0.0.tar.gz", hash = "sha256:9995eb8569428059b8c1affd26b25eac510d64f5043d9ce8c84e0d0036e995ae"}, -] - -[package.dependencies] -isodate = ">=0.6.0,<0.7.0" -pyparsing = ">=2.1.0,<4" - -[package.extras] -berkeleydb = ["berkeleydb (>=18.1.0,<19.0.0)"] -html = ["html5lib (>=1.0,<2.0)"] -lxml = ["lxml (>=4.3.0,<5.0.0)"] -networkx = ["networkx (>=2.0.0,<3.0.0)"] - -[[package]] -name = "referencing" -version = "0.33.0" -description = "JSON Referencing + Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "referencing-0.33.0-py3-none-any.whl", hash = "sha256:39240f2ecc770258f28b642dd47fd74bc8b02484de54e1882b74b35ebd779bd5"}, - {file = "referencing-0.33.0.tar.gz", hash = "sha256:c775fedf74bc0f9189c2a3be1c12fd03e8c23f4d371dce795df44e06c5b412f7"}, -] - -[package.dependencies] -attrs = ">=22.2.0" -rpds-py = ">=0.7.0" - -[[package]] -name = "requests" -version = "2.31.0" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.7" -files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "rfc3339-validator" -version = "0.1.4" -description = "A pure python RFC3339 validator" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa"}, - {file = "rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "rfc3986-validator" -version = "0.1.1" -description = "Pure python rfc3986 validator" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9"}, - {file = "rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055"}, -] - -[[package]] -name = "rpds-py" -version = "0.17.1" -description = "Python bindings to Rust's persistent data structures (rpds)" -optional = false -python-versions = ">=3.8" -files = [ - {file = "rpds_py-0.17.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:4128980a14ed805e1b91a7ed551250282a8ddf8201a4e9f8f5b7e6225f54170d"}, - {file = "rpds_py-0.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ff1dcb8e8bc2261a088821b2595ef031c91d499a0c1b031c152d43fe0a6ecec8"}, - {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d65e6b4f1443048eb7e833c2accb4fa7ee67cc7d54f31b4f0555b474758bee55"}, - {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a71169d505af63bb4d20d23a8fbd4c6ce272e7bce6cc31f617152aa784436f29"}, - {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:436474f17733c7dca0fbf096d36ae65277e8645039df12a0fa52445ca494729d"}, - {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:10162fe3f5f47c37ebf6d8ff5a2368508fe22007e3077bf25b9c7d803454d921"}, - {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:720215373a280f78a1814becb1312d4e4d1077b1202a56d2b0815e95ccb99ce9"}, - {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:70fcc6c2906cfa5c6a552ba7ae2ce64b6c32f437d8f3f8eea49925b278a61453"}, - {file = "rpds_py-0.17.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:91e5a8200e65aaac342a791272c564dffcf1281abd635d304d6c4e6b495f29dc"}, - {file = "rpds_py-0.17.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:99f567dae93e10be2daaa896e07513dd4bf9c2ecf0576e0533ac36ba3b1d5394"}, - {file = "rpds_py-0.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:24e4900a6643f87058a27320f81336d527ccfe503984528edde4bb660c8c8d59"}, - {file = "rpds_py-0.17.1-cp310-none-win32.whl", hash = "sha256:0bfb09bf41fe7c51413f563373e5f537eaa653d7adc4830399d4e9bdc199959d"}, - {file = "rpds_py-0.17.1-cp310-none-win_amd64.whl", hash = "sha256:20de7b7179e2031a04042e85dc463a93a82bc177eeba5ddd13ff746325558aa6"}, - {file = "rpds_py-0.17.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:65dcf105c1943cba45d19207ef51b8bc46d232a381e94dd38719d52d3980015b"}, - {file = "rpds_py-0.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:01f58a7306b64e0a4fe042047dd2b7d411ee82e54240284bab63e325762c1147"}, - {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:071bc28c589b86bc6351a339114fb7a029f5cddbaca34103aa573eba7b482382"}, - {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ae35e8e6801c5ab071b992cb2da958eee76340e6926ec693b5ff7d6381441745"}, - {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149c5cd24f729e3567b56e1795f74577aa3126c14c11e457bec1b1c90d212e38"}, - {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e796051f2070f47230c745d0a77a91088fbee2cc0502e9b796b9c6471983718c"}, - {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60e820ee1004327609b28db8307acc27f5f2e9a0b185b2064c5f23e815f248f8"}, - {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1957a2ab607f9added64478a6982742eb29f109d89d065fa44e01691a20fc20a"}, - {file = "rpds_py-0.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8587fd64c2a91c33cdc39d0cebdaf30e79491cc029a37fcd458ba863f8815383"}, - {file = "rpds_py-0.17.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4dc889a9d8a34758d0fcc9ac86adb97bab3fb7f0c4d29794357eb147536483fd"}, - {file = "rpds_py-0.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2953937f83820376b5979318840f3ee47477d94c17b940fe31d9458d79ae7eea"}, - {file = "rpds_py-0.17.1-cp311-none-win32.whl", hash = "sha256:1bfcad3109c1e5ba3cbe2f421614e70439f72897515a96c462ea657261b96518"}, - {file = "rpds_py-0.17.1-cp311-none-win_amd64.whl", hash = "sha256:99da0a4686ada4ed0f778120a0ea8d066de1a0a92ab0d13ae68492a437db78bf"}, - {file = "rpds_py-0.17.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:1dc29db3900cb1bb40353772417800f29c3d078dbc8024fd64655a04ee3c4bdf"}, - {file = "rpds_py-0.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:82ada4a8ed9e82e443fcef87e22a3eed3654dd3adf6e3b3a0deb70f03e86142a"}, - {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d36b2b59e8cc6e576f8f7b671e32f2ff43153f0ad6d0201250a7c07f25d570e"}, - {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3677fcca7fb728c86a78660c7fb1b07b69b281964673f486ae72860e13f512ad"}, - {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:516fb8c77805159e97a689e2f1c80655c7658f5af601c34ffdb916605598cda2"}, - {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df3b6f45ba4515632c5064e35ca7f31d51d13d1479673185ba8f9fefbbed58b9"}, - {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a967dd6afda7715d911c25a6ba1517975acd8d1092b2f326718725461a3d33f9"}, - {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dbbb95e6fc91ea3102505d111b327004d1c4ce98d56a4a02e82cd451f9f57140"}, - {file = "rpds_py-0.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:02866e060219514940342a1f84303a1ef7a1dad0ac311792fbbe19b521b489d2"}, - {file = "rpds_py-0.17.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2528ff96d09f12e638695f3a2e0c609c7b84c6df7c5ae9bfeb9252b6fa686253"}, - {file = "rpds_py-0.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bd345a13ce06e94c753dab52f8e71e5252aec1e4f8022d24d56decd31e1b9b23"}, - {file = "rpds_py-0.17.1-cp312-none-win32.whl", hash = "sha256:2a792b2e1d3038daa83fa474d559acfd6dc1e3650ee93b2662ddc17dbff20ad1"}, - {file = "rpds_py-0.17.1-cp312-none-win_amd64.whl", hash = "sha256:292f7344a3301802e7c25c53792fae7d1593cb0e50964e7bcdcc5cf533d634e3"}, - {file = "rpds_py-0.17.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:8ffe53e1d8ef2520ebcf0c9fec15bb721da59e8ef283b6ff3079613b1e30513d"}, - {file = "rpds_py-0.17.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4341bd7579611cf50e7b20bb8c2e23512a3dc79de987a1f411cb458ab670eb90"}, - {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f4eb548daf4836e3b2c662033bfbfc551db58d30fd8fe660314f86bf8510b93"}, - {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b686f25377f9c006acbac63f61614416a6317133ab7fafe5de5f7dc8a06d42eb"}, - {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e21b76075c01d65d0f0f34302b5a7457d95721d5e0667aea65e5bb3ab415c25"}, - {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b86b21b348f7e5485fae740d845c65a880f5d1eda1e063bc59bef92d1f7d0c55"}, - {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f175e95a197f6a4059b50757a3dca33b32b61691bdbd22c29e8a8d21d3914cae"}, - {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1701fc54460ae2e5efc1dd6350eafd7a760f516df8dbe51d4a1c79d69472fbd4"}, - {file = "rpds_py-0.17.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9051e3d2af8f55b42061603e29e744724cb5f65b128a491446cc029b3e2ea896"}, - {file = "rpds_py-0.17.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:7450dbd659fed6dd41d1a7d47ed767e893ba402af8ae664c157c255ec6067fde"}, - {file = "rpds_py-0.17.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5a024fa96d541fd7edaa0e9d904601c6445e95a729a2900c5aec6555fe921ed6"}, - {file = "rpds_py-0.17.1-cp38-none-win32.whl", hash = "sha256:da1ead63368c04a9bded7904757dfcae01eba0e0f9bc41d3d7f57ebf1c04015a"}, - {file = "rpds_py-0.17.1-cp38-none-win_amd64.whl", hash = "sha256:841320e1841bb53fada91c9725e766bb25009cfd4144e92298db296fb6c894fb"}, - {file = "rpds_py-0.17.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:f6c43b6f97209e370124baf2bf40bb1e8edc25311a158867eb1c3a5d449ebc7a"}, - {file = "rpds_py-0.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7d63ec01fe7c76c2dbb7e972fece45acbb8836e72682bde138e7e039906e2c"}, - {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81038ff87a4e04c22e1d81f947c6ac46f122e0c80460b9006e6517c4d842a6ec"}, - {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:810685321f4a304b2b55577c915bece4c4a06dfe38f6e62d9cc1d6ca8ee86b99"}, - {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:25f071737dae674ca8937a73d0f43f5a52e92c2d178330b4c0bb6ab05586ffa6"}, - {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa5bfb13f1e89151ade0eb812f7b0d7a4d643406caaad65ce1cbabe0a66d695f"}, - {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfe07308b311a8293a0d5ef4e61411c5c20f682db6b5e73de6c7c8824272c256"}, - {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a000133a90eea274a6f28adc3084643263b1e7c1a5a66eb0a0a7a36aa757ed74"}, - {file = "rpds_py-0.17.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d0e8a6434a3fbf77d11448c9c25b2f25244226cfbec1a5159947cac5b8c5fa4"}, - {file = "rpds_py-0.17.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:efa767c220d94aa4ac3a6dd3aeb986e9f229eaf5bce92d8b1b3018d06bed3772"}, - {file = "rpds_py-0.17.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:dbc56680ecf585a384fbd93cd42bc82668b77cb525343170a2d86dafaed2a84b"}, - {file = "rpds_py-0.17.1-cp39-none-win32.whl", hash = "sha256:270987bc22e7e5a962b1094953ae901395e8c1e1e83ad016c5cfcfff75a15a3f"}, - {file = "rpds_py-0.17.1-cp39-none-win_amd64.whl", hash = "sha256:2a7b2f2f56a16a6d62e55354dd329d929560442bd92e87397b7a9586a32e3e76"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a3264e3e858de4fc601741498215835ff324ff2482fd4e4af61b46512dd7fc83"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f2f3b28b40fddcb6c1f1f6c88c6f3769cd933fa493ceb79da45968a21dccc920"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9584f8f52010295a4a417221861df9bea4c72d9632562b6e59b3c7b87a1522b7"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c64602e8be701c6cfe42064b71c84ce62ce66ddc6422c15463fd8127db3d8066"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:060f412230d5f19fc8c8b75f315931b408d8ebf56aec33ef4168d1b9e54200b1"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9412abdf0ba70faa6e2ee6c0cc62a8defb772e78860cef419865917d86c7342"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9737bdaa0ad33d34c0efc718741abaafce62fadae72c8b251df9b0c823c63b22"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9f0e4dc0f17dcea4ab9d13ac5c666b6b5337042b4d8f27e01b70fae41dd65c57"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1db228102ab9d1ff4c64148c96320d0be7044fa28bd865a9ce628ce98da5973d"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:d8bbd8e56f3ba25a7d0cf980fc42b34028848a53a0e36c9918550e0280b9d0b6"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:be22ae34d68544df293152b7e50895ba70d2a833ad9566932d750d3625918b82"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bf046179d011e6114daf12a534d874958b039342b347348a78b7cdf0dd9d6041"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:1a746a6d49665058a5896000e8d9d2f1a6acba8a03b389c1e4c06e11e0b7f40d"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0b8bf5b8db49d8fd40f54772a1dcf262e8be0ad2ab0206b5a2ec109c176c0a4"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f7f4cb1f173385e8a39c29510dd11a78bf44e360fb75610594973f5ea141028b"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7fbd70cb8b54fe745301921b0816c08b6d917593429dfc437fd024b5ba713c58"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bdf1303df671179eaf2cb41e8515a07fc78d9d00f111eadbe3e14262f59c3d0"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fad059a4bd14c45776600d223ec194e77db6c20255578bb5bcdd7c18fd169361"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3664d126d3388a887db44c2e293f87d500c4184ec43d5d14d2d2babdb4c64cad"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:698ea95a60c8b16b58be9d854c9f993c639f5c214cf9ba782eca53a8789d6b19"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:c3d2010656999b63e628a3c694f23020322b4178c450dc478558a2b6ef3cb9bb"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:938eab7323a736533f015e6069a7d53ef2dcc841e4e533b782c2bfb9fb12d84b"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:1e626b365293a2142a62b9a614e1f8e331b28f3ca57b9f05ebbf4cf2a0f0bdc5"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:380e0df2e9d5d5d339803cfc6d183a5442ad7ab3c63c2a0982e8c824566c5ccc"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b760a56e080a826c2e5af09002c1a037382ed21d03134eb6294812dda268c811"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5576ee2f3a309d2bb403ec292d5958ce03953b0e57a11d224c1f134feaf8c40f"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3c3461ebb4c4f1bbc70b15d20b565759f97a5aaf13af811fcefc892e9197ba"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:637b802f3f069a64436d432117a7e58fab414b4e27a7e81049817ae94de45d8d"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffee088ea9b593cc6160518ba9bd319b5475e5f3e578e4552d63818773c6f56a"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3ac732390d529d8469b831949c78085b034bff67f584559340008d0f6041a049"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:93432e747fb07fa567ad9cc7aaadd6e29710e515aabf939dfbed8046041346c6"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:7b7d9ca34542099b4e185b3c2a2b2eda2e318a7dbde0b0d83357a6d4421b5296"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:0387ce69ba06e43df54e43968090f3626e231e4bc9150e4c3246947567695f68"}, - {file = "rpds_py-0.17.1.tar.gz", hash = "sha256:0210b2668f24c078307260bf88bdac9d6f1093635df5123789bfee4d8d7fc8e7"}, -] - -[[package]] -name = "send2trash" -version = "1.8.2" -description = "Send file to trash natively under Mac OS X, Windows and Linux" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -files = [ - {file = "Send2Trash-1.8.2-py3-none-any.whl", hash = "sha256:a384719d99c07ce1eefd6905d2decb6f8b7ed054025bb0e618919f945de4f679"}, - {file = "Send2Trash-1.8.2.tar.gz", hash = "sha256:c132d59fa44b9ca2b1699af5c86f57ce9f4c5eb56629d5d55fbb7a35f84e2312"}, -] - -[package.extras] -nativelib = ["pyobjc-framework-Cocoa", "pywin32"] -objc = ["pyobjc-framework-Cocoa"] -win32 = ["pywin32"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "sniffio" -version = "1.3.0" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, - {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, -] - -[[package]] -name = "snowballstemmer" -version = "2.2.0" -description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -optional = false -python-versions = "*" -files = [ - {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, - {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, -] - -[[package]] -name = "sortedcontainers" -version = "2.4.0" -description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" -optional = false -python-versions = "*" -files = [ - {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, - {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, + {file = "prefixcommons-0.1.12-py3-none-any.whl", hash = "sha256:16dbc0a1f775e003c724f19a694fcfa3174608f5c8b0e893d494cf8098ac7f8b"}, + {file = "prefixcommons-0.1.12.tar.gz", hash = "sha256:22c4e2d37b63487b3ab48f0495b70f14564cb346a15220f23919eb0c1851f69f"}, ] +[package.dependencies] +click = ">=8.1.3,<9.0.0" +pytest-logging = ">=2015.11.4,<2016.0.0" +PyYAML = ">=6.0,<7.0" +requests = ">=2.28.1,<3.0.0" + [[package]] -name = "soupsieve" -version = "2.5" -description = "A modern CSS selector implementation for Beautiful Soup." +name = "prefixmaps" +version = "0.2.4" +description = "A python library for retrieving semantic prefix maps" optional = false -python-versions = ">=3.8" +python-versions = "<4.0,>=3.8" files = [ - {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, - {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, + {file = "prefixmaps-0.2.4-py3-none-any.whl", hash = "sha256:89bf0e6fb08c276f754f9624c42adf2e87c64ee92a3dde1f7eff01f22d85b512"}, + {file = "prefixmaps-0.2.4.tar.gz", hash = "sha256:ae86a1b31189d0516d199756d5808f75f44b39e86546c356cc78c0fe8d2078af"}, ] +[package.dependencies] +curies = ">=0.5.3" +pyyaml = ">=5.3.1" + [[package]] -name = "sphinx" -version = "5.3.0" -description = "Python documentation generator" +name = "pydantic" +version = "2.8.2" +description = "Data validation using Python type hints" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "Sphinx-5.3.0.tar.gz", hash = "sha256:51026de0a9ff9fc13c05d74913ad66047e104f56a129ff73e174eb5c3ee794b5"}, - {file = "sphinx-5.3.0-py3-none-any.whl", hash = "sha256:060ca5c9f7ba57a08a1219e547b269fadf125ae25b06b9fa7f66768efb652d6d"}, + {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, + {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, ] [package.dependencies] -alabaster = ">=0.7,<0.8" -babel = ">=2.9" -colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.14,<0.20" -imagesize = ">=1.3" -importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} -Jinja2 = ">=3.0" -packaging = ">=21.0" -Pygments = ">=2.12" -requests = ">=2.5.0" -snowballstemmer = ">=2.0" -sphinxcontrib-applehelp = "*" -sphinxcontrib-devhelp = "*" -sphinxcontrib-htmlhelp = ">=2.0.0" -sphinxcontrib-jsmath = "*" -sphinxcontrib-qthelp = "*" -sphinxcontrib-serializinghtml = ">=1.1.5" -sphinxcontrib-websupport = {version = "*", optional = true, markers = "extra == \"docs\""} +annotated-types = ">=0.4.0" +pydantic-core = "2.20.1" +typing-extensions = [ + {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, + {version = ">=4.6.1", markers = "python_version < \"3.13\""}, +] [package.extras] -docs = ["sphinxcontrib-websupport"] -lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-bugbear", "flake8-comprehensions", "flake8-simplify", "isort", "mypy (>=0.981)", "sphinx-lint", "types-requests", "types-typed-ast"] -test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"] +email = ["email-validator (>=2.0.0)"] [[package]] -name = "sphinx-click" -version = "4.4.0" -description = "Sphinx extension that automatically documents click applications" +name = "pydantic-core" +version = "2.20.1" +description = "Core functionality for Pydantic validation and serialization" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "sphinx-click-4.4.0.tar.gz", hash = "sha256:cc67692bd28f482c7f01531c61b64e9d2f069bfcf3d24cbbb51d4a84a749fa48"}, - {file = "sphinx_click-4.4.0-py3-none-any.whl", hash = "sha256:2821c10a68fc9ee6ce7c92fad26540d8d8c8f45e6d7258f0e4fb7529ae8fab49"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, + {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, + {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, + {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, + {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, + {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, + {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, + {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, + {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, + {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, + {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, + {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, + {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, + {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, ] [package.dependencies] -click = ">=7.0" -docutils = "*" -sphinx = ">=2.0" +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] -name = "sphinx-rtd-theme" -version = "1.3.0" -description = "Read the Docs theme for Sphinx" +name = "pyparsing" +version = "3.1.2" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +python-versions = ">=3.6.8" files = [ - {file = "sphinx_rtd_theme-1.3.0-py2.py3-none-any.whl", hash = "sha256:46ddef89cc2416a81ecfbeaceab1881948c014b1b6e4450b815311a89fb977b0"}, - {file = "sphinx_rtd_theme-1.3.0.tar.gz", hash = "sha256:590b030c7abb9cf038ec053b95e5380b5c70d61591eb0b552063fbe7c41f0931"}, + {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, + {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, ] -[package.dependencies] -docutils = "<0.19" -sphinx = ">=1.6,<8" -sphinxcontrib-jquery = ">=4,<5" - [package.extras] -dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"] +diagrams = ["jinja2", "railroad-diagrams"] [[package]] -name = "sphinxcontrib-applehelp" -version = "1.0.8" -description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" +name = "pyproject-api" +version = "1.7.1" +description = "API to interact with the python pyproject.toml based projects" optional = false -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "sphinxcontrib_applehelp-1.0.8-py3-none-any.whl", hash = "sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4"}, - {file = "sphinxcontrib_applehelp-1.0.8.tar.gz", hash = "sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619"}, + {file = "pyproject_api-1.7.1-py3-none-any.whl", hash = "sha256:2dc1654062c2b27733d8fd4cdda672b22fe8741ef1dde8e3a998a9547b071eeb"}, + {file = "pyproject_api-1.7.1.tar.gz", hash = "sha256:7ebc6cd10710f89f4cf2a2731710a98abce37ebff19427116ff2174c9236a827"}, ] +[package.dependencies] +packaging = ">=24.1" +tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} + [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] +docs = ["furo (>=2024.5.6)", "sphinx-autodoc-typehints (>=2.2.1)"] +testing = ["covdefaults (>=2.3)", "pytest (>=8.2.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "setuptools (>=70.1)"] [[package]] -name = "sphinxcontrib-devhelp" -version = "1.0.6" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" +name = "pytest" +version = "8.2.2" +description = "pytest: simple powerful testing with Python" optional = false -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "sphinxcontrib_devhelp-1.0.6-py3-none-any.whl", hash = "sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f"}, - {file = "sphinxcontrib_devhelp-1.0.6.tar.gz", hash = "sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3"}, + {file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"}, + {file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"}, ] +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2.0" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] -name = "sphinxcontrib-htmlhelp" -version = "2.0.5" -description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +name = "pytest-logging" +version = "2015.11.4" +description = "Configures logging and allows tweaking the log level with a py.test flag" optional = false -python-versions = ">=3.9" +python-versions = "*" files = [ - {file = "sphinxcontrib_htmlhelp-2.0.5-py3-none-any.whl", hash = "sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04"}, - {file = "sphinxcontrib_htmlhelp-2.0.5.tar.gz", hash = "sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015"}, + {file = "pytest-logging-2015.11.4.tar.gz", hash = "sha256:cec5c85ecf18aab7b2ead5498a31b9f758680ef5a902b9054ab3f2bdbb77c896"}, ] -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -standalone = ["Sphinx (>=5)"] -test = ["html5lib", "pytest"] +[package.dependencies] +pytest = ">=2.8.1" [[package]] -name = "sphinxcontrib-jquery" -version = "4.1" -description = "Extension to include jQuery on newer Sphinx releases" +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" optional = false -python-versions = ">=2.7" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"}, - {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"}, + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, ] [package.dependencies] -Sphinx = ">=1.8" +six = ">=1.5" [[package]] -name = "sphinxcontrib-jsmath" -version = "1.0.1" -description = "A sphinx extension which renders display math in HTML via JavaScript" +name = "pytrie" +version = "0.4.0" +description = "A pure Python implementation of the trie data structure." optional = false -python-versions = ">=3.5" +python-versions = "*" files = [ - {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, - {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, + {file = "PyTrie-0.4.0.tar.gz", hash = "sha256:8f4488f402d3465993fb6b6efa09866849ed8cda7903b50647b7d0342b805379"}, ] -[package.extras] -test = ["flake8", "mypy", "pytest"] +[package.dependencies] +sortedcontainers = "*" [[package]] -name = "sphinxcontrib-qthelp" -version = "1.0.7" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" +name = "pytz" +version = "2024.1" +description = "World timezone definitions, modern and historical" optional = false -python-versions = ">=3.9" +python-versions = "*" files = [ - {file = "sphinxcontrib_qthelp-1.0.7-py3-none-any.whl", hash = "sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182"}, - {file = "sphinxcontrib_qthelp-1.0.7.tar.gz", hash = "sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6"}, + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, ] -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] - [[package]] -name = "sphinxcontrib-serializinghtml" -version = "1.1.10" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" optional = false -python-versions = ">=3.9" +python-versions = ">=3.6" files = [ - {file = "sphinxcontrib_serializinghtml-1.1.10-py3-none-any.whl", hash = "sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7"}, - {file = "sphinxcontrib_serializinghtml-1.1.10.tar.gz", hash = "sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] - [[package]] -name = "sphinxcontrib-websupport" -version = "1.2.7" -description = "sphinxcontrib-websupport provides a Python API to easily integrate Sphinx documentation into your Web application" +name = "rdflib" +version = "7.0.0" +description = "RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information." optional = false -python-versions = ">=3.9" +python-versions = ">=3.8.1,<4.0.0" files = [ - {file = "sphinxcontrib_websupport-1.2.7-py3-none-any.whl", hash = "sha256:2dc179d7f821ebd54f31f93c894ca52435ebc5364e4e4dfb0da834ac119d51fd"}, - {file = "sphinxcontrib_websupport-1.2.7.tar.gz", hash = "sha256:e322802ebfd5fe79368efd864aeb87b063566ae61911dccb2714e28a45ed7561"}, + {file = "rdflib-7.0.0-py3-none-any.whl", hash = "sha256:0438920912a642c866a513de6fe8a0001bd86ef975057d6962c79ce4771687cd"}, + {file = "rdflib-7.0.0.tar.gz", hash = "sha256:9995eb8569428059b8c1affd26b25eac510d64f5043d9ce8c84e0d0036e995ae"}, ] [package.dependencies] -jinja2 = "*" -Sphinx = ">=5" -sphinxcontrib-serializinghtml = "*" +isodate = ">=0.6.0,<0.7.0" +pyparsing = ">=2.1.0,<4" [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] -whoosh = ["sqlalchemy", "whoosh"] +berkeleydb = ["berkeleydb (>=18.1.0,<19.0.0)"] +html = ["html5lib (>=1.0,<2.0)"] +lxml = ["lxml (>=4.3.0,<5.0.0)"] +networkx = ["networkx (>=2.0.0,<3.0.0)"] [[package]] -name = "stack-data" -version = "0.6.3" -description = "Extract data from python stack frames and tracebacks for informative displays" +name = "referencing" +version = "0.35.1" +description = "JSON Referencing + Python" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, - {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, + {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, + {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, ] [package.dependencies] -asttokens = ">=2.1.0" -executing = ">=1.2.0" -pure-eval = "*" - -[package.extras] -tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" [[package]] -name = "terminado" -version = "0.18.0" -description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" files = [ - {file = "terminado-0.18.0-py3-none-any.whl", hash = "sha256:87b0d96642d0fe5f5abd7783857b9cab167f221a39ff98e3b9619a788a3c0f2e"}, - {file = "terminado-0.18.0.tar.gz", hash = "sha256:1ea08a89b835dd1b8c0c900d92848147cef2537243361b2e3f4dc15df9b6fded"}, + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, ] [package.dependencies] -ptyprocess = {version = "*", markers = "os_name != \"nt\""} -pywinpty = {version = ">=1.1.0", markers = "os_name == \"nt\""} -tornado = ">=6.1.0" +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" [package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"] -typing = ["mypy (>=1.6,<2.0)", "traitlets (>=5.11.1)"] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] -name = "tinycss2" -version = "1.2.1" -description = "A tiny CSS parser" +name = "rpds-py" +version = "0.18.1" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53"}, + {file = "rpds_py-0.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1"}, + {file = "rpds_py-0.18.1-cp310-none-win32.whl", hash = "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333"}, + {file = "rpds_py-0.18.1-cp310-none-win_amd64.whl", hash = "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a"}, + {file = "rpds_py-0.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8"}, + {file = "rpds_py-0.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88"}, + {file = "rpds_py-0.18.1-cp311-none-win32.whl", hash = "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb"}, + {file = "rpds_py-0.18.1-cp311-none-win_amd64.whl", hash = "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2"}, + {file = "rpds_py-0.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3"}, + {file = "rpds_py-0.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a"}, + {file = "rpds_py-0.18.1-cp312-none-win32.whl", hash = "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6"}, + {file = "rpds_py-0.18.1-cp312-none-win_amd64.whl", hash = "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72"}, + {file = "rpds_py-0.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74"}, + {file = "rpds_py-0.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc"}, + {file = "rpds_py-0.18.1-cp38-none-win32.whl", hash = "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9"}, + {file = "rpds_py-0.18.1-cp38-none-win_amd64.whl", hash = "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2"}, + {file = "rpds_py-0.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93"}, + {file = "rpds_py-0.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26"}, + {file = "rpds_py-0.18.1-cp39-none-win32.whl", hash = "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360"}, + {file = "rpds_py-0.18.1-cp39-none-win_amd64.whl", hash = "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e"}, + {file = "rpds_py-0.18.1.tar.gz", hash = "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f"}, +] + +[[package]] +name = "ruamel-yaml" +version = "0.18.6" +description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" optional = false python-versions = ">=3.7" files = [ - {file = "tinycss2-1.2.1-py3-none-any.whl", hash = "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847"}, - {file = "tinycss2-1.2.1.tar.gz", hash = "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627"}, + {file = "ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636"}, + {file = "ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b"}, ] [package.dependencies] -webencodings = ">=0.4" +"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""} [package.extras] -doc = ["sphinx", "sphinx_rtd_theme"] -test = ["flake8", "isort", "pytest"] +docs = ["mercurial (>5.7)", "ryd"] +jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] [[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" +name = "ruamel-yaml-clib" +version = "0.2.8" +description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" optional = false -python-versions = ">=3.7" +python-versions = ">=3.6" files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:d92f81886165cb14d7b067ef37e142256f1c6a90a65cd156b063a43da1708cfd"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:b5edda50e5e9e15e54a6a8a0070302b00c518a9d32accc2346ad6c984aacd279"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:7048c338b6c86627afb27faecf418768acb6331fc24cfa56c93e8c9780f815fa"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b"}, + {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3fcc54cb0c8b811ff66082de1680b4b14cf8a81dce0d4fbf665c2265a81e07a1"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:665f58bfd29b167039f714c6998178d27ccd83984084c286110ef26b230f259f"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:9eb5dee2772b0f704ca2e45b1713e4e5198c18f515b52743576d196348f374d3"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"}, + {file = "ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512"}, ] [[package]] -name = "tornado" -version = "6.4" -description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">= 3.8" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ - {file = "tornado-6.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0"}, - {file = "tornado-6.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f"}, - {file = "tornado-6.4-cp38-abi3-win32.whl", hash = "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052"}, - {file = "tornado-6.4-cp38-abi3-win_amd64.whl", hash = "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63"}, - {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"}, + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] [[package]] -name = "tox" -version = "3.28.0" -description = "tox is a generic virtualenv management and test command line tool" +name = "sortedcontainers" +version = "2.4.0" +description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = "*" files = [ - {file = "tox-3.28.0-py2.py3-none-any.whl", hash = "sha256:57b5ab7e8bb3074edc3c0c0b4b192a4f3799d3723b2c5b76f1fa9f2d40316eea"}, - {file = "tox-3.28.0.tar.gz", hash = "sha256:d0d28f3fe6d6d7195c27f8b054c3e99d5451952b54abdae673b71609a581f640"}, + {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, + {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, ] -[package.dependencies] -colorama = {version = ">=0.4.1", markers = "platform_system == \"Windows\""} -filelock = ">=3.0.0" -packaging = ">=14" -pluggy = ">=0.12.0" -py = ">=1.4.17" -six = ">=1.14.0" -tomli = {version = ">=2.0.1", markers = "python_version >= \"3.7\" and python_version < \"3.11\""} -virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2,<20.0.3 || >20.0.3,<20.0.4 || >20.0.4,<20.0.5 || >20.0.5,<20.0.6 || >20.0.6,<20.0.7 || >20.0.7" - -[package.extras] -docs = ["pygments-github-lexers (>=0.0.5)", "sphinx (>=2.0.0)", "sphinxcontrib-autoprogram (>=0.1.5)", "towncrier (>=18.5.0)"] -testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pathlib2 (>=2.3.3)", "psutil (>=5.6.1)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-randomly (>=1.0.0)"] - [[package]] -name = "traitlets" -version = "5.14.1" -description = "Traitlets Python configuration system" +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "traitlets-5.14.1-py3-none-any.whl", hash = "sha256:2e5a030e6eff91737c643231bfcf04a65b0132078dad75e4936700b213652e74"}, - {file = "traitlets-5.14.1.tar.gz", hash = "sha256:8585105b371a04b8316a43d5ce29c098575c2e477850b62b848b964f1444527e"}, + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] - [[package]] -name = "types-python-dateutil" -version = "2.8.19.20240106" -description = "Typing stubs for python-dateutil" +name = "tox" +version = "4.16.0" +description = "tox is a generic virtualenv management and test command line tool" optional = false python-versions = ">=3.8" files = [ - {file = "types-python-dateutil-2.8.19.20240106.tar.gz", hash = "sha256:1f8db221c3b98e6ca02ea83a58371b22c374f42ae5bbdf186db9c9a76581459f"}, - {file = "types_python_dateutil-2.8.19.20240106-py3-none-any.whl", hash = "sha256:efbbdc54590d0f16152fa103c9879c7d4a00e82078f6e2cf01769042165acaa2"}, + {file = "tox-4.16.0-py3-none-any.whl", hash = "sha256:61e101061b977b46cf00093d4319438055290ad0009f84497a07bf2d2d7a06d0"}, + {file = "tox-4.16.0.tar.gz", hash = "sha256:43499656f9949edb681c0f907f86fbfee98677af9919d8b11ae5ad77cb800748"}, ] +[package.dependencies] +cachetools = ">=5.3.3" +chardet = ">=5.2" +colorama = ">=0.4.6" +filelock = ">=3.15.4" +packaging = ">=24.1" +platformdirs = ">=4.2.2" +pluggy = ">=1.5" +pyproject-api = ">=1.7.1" +tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} +virtualenv = ">=20.26.3" + +[package.extras] +docs = ["furo (>=2024.5.6)", "sphinx (>=7.3.7)", "sphinx-argparse-cli (>=1.16)", "sphinx-autodoc-typehints (>=2.2.2)", "sphinx-copybutton (>=0.5.2)", "sphinx-inline-tabs (>=2023.4.21)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.11)"] +testing = ["build[virtualenv] (>=1.2.1)", "covdefaults (>=2.3)", "detect-test-pollution (>=1.2)", "devpi-process (>=1)", "diff-cover (>=9.1)", "distlib (>=0.3.8)", "flaky (>=3.8.1)", "hatch-vcs (>=0.4)", "hatchling (>=1.25)", "psutil (>=6)", "pytest (>=8.2.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-xdist (>=3.6.1)", "re-assert (>=1.1)", "setuptools (>=70.2)", "time-machine (>=2.14.2)", "wheel (>=0.43)"] + [[package]] name = "typing-extensions" -version = "4.9.0" +version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, - {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] name = "tzdata" -version = "2023.4" +version = "2024.1" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" files = [ - {file = "tzdata-2023.4-py2.py3-none-any.whl", hash = "sha256:aa3ace4329eeacda5b7beb7ea08ece826c28d761cda36e747cfbf97996d39bf3"}, - {file = "tzdata-2023.4.tar.gz", hash = "sha256:dd54c94f294765522c77399649b4fefd95522479a664a0cec87f41bebc6148c9"}, -] - -[[package]] -name = "uri-template" -version = "1.3.0" -description = "RFC 6570 URI Template Processor" -optional = false -python-versions = ">=3.7" -files = [ - {file = "uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7"}, - {file = "uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363"}, + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, ] -[package.extras] -dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake8-commas", "flake8-comprehensions", "flake8-continuation", "flake8-datetimez", "flake8-docstrings", "flake8-import-order", "flake8-literal", "flake8-modern-annotations", "flake8-noqa", "flake8-pyproject", "flake8-requirements", "flake8-typechecking-import", "flake8-use-fstring", "mypy", "pep8-naming", "types-PyYAML"] - [[package]] name = "urllib3" -version = "2.2.0" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.0-py3-none-any.whl", hash = "sha256:ce3711610ddce217e6d113a2732fafad960a03fd0318c91faa79481e35c11224"}, - {file = "urllib3-2.2.0.tar.gz", hash = "sha256:051d961ad0c62a94e50ecf1af379c3aba230c66c710493493560c0c223c49f20"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] @@ -3370,13 +1322,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.25.0" +version = "20.26.3" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.25.0-py3-none-any.whl", hash = "sha256:4238949c5ffe6876362d9c0180fc6c3a824a7b12b80604eeb8085f2ed7460de3"}, - {file = "virtualenv-20.25.0.tar.gz", hash = "sha256:bf51c0d9c7dd63ea8e44086fa1e4fb1093a31e963b86959257378aef020e1f1b"}, + {file = "virtualenv-20.26.3-py3-none-any.whl", hash = "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589"}, + {file = "virtualenv-20.26.3.tar.gz", hash = "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a"}, ] [package.dependencies] @@ -3385,73 +1337,9 @@ filelock = ">=3.12.2,<4" platformdirs = ">=3.9.1,<5" [package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] -[[package]] -name = "wcwidth" -version = "0.2.13" -description = "Measures the displayed width of unicode strings in a terminal" -optional = false -python-versions = "*" -files = [ - {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, - {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, -] - -[[package]] -name = "webcolors" -version = "1.13" -description = "A library for working with the color formats defined by HTML and CSS." -optional = false -python-versions = ">=3.7" -files = [ - {file = "webcolors-1.13-py3-none-any.whl", hash = "sha256:29bc7e8752c0a1bd4a1f03c14d6e6a72e93d82193738fa860cbff59d0fcc11bf"}, - {file = "webcolors-1.13.tar.gz", hash = "sha256:c225b674c83fa923be93d235330ce0300373d02885cef23238813b0d5668304a"}, -] - -[package.extras] -docs = ["furo", "sphinx", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-notfound-page", "sphinxext-opengraph"] -tests = ["pytest", "pytest-cov"] - -[[package]] -name = "webencodings" -version = "0.5.1" -description = "Character encoding aliases for legacy web content" -optional = false -python-versions = "*" -files = [ - {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, - {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, -] - -[[package]] -name = "websocket-client" -version = "1.7.0" -description = "WebSocket client for Python with low level API options" -optional = false -python-versions = ">=3.8" -files = [ - {file = "websocket-client-1.7.0.tar.gz", hash = "sha256:10e511ea3a8c744631d3bd77e61eb17ed09304c413ad42cf6ddfa4c7787e8fe6"}, - {file = "websocket_client-1.7.0-py3-none-any.whl", hash = "sha256:f4c3d22fec12a2461427a29957ff07d35098ee2d976d3ba244e688b8b4057588"}, -] - -[package.extras] -docs = ["Sphinx (>=6.0)", "sphinx-rtd-theme (>=1.1.0)"] -optional = ["python-socks", "wsaccel"] -test = ["websockets"] - -[[package]] -name = "widgetsnbextension" -version = "4.0.10" -description = "Jupyter interactive widgets for Jupyter Notebook" -optional = false -python-versions = ">=3.7" -files = [ - {file = "widgetsnbextension-4.0.10-py3-none-any.whl", hash = "sha256:d37c3724ec32d8c48400a435ecfa7d3e259995201fbefa37163124a9fcb393cc"}, - {file = "widgetsnbextension-4.0.10.tar.gz", hash = "sha256:64196c5ff3b9a9183a8e699a4227fb0b7002f252c814098e66c4d1cd0644688f"}, -] - [[package]] name = "wrapt" version = "1.16.0" @@ -3533,68 +1421,50 @@ files = [ [[package]] name = "xarray" -version = "2024.1.1" +version = "2024.6.0" description = "N-D labeled arrays and datasets in Python" optional = false python-versions = ">=3.9" files = [ - {file = "xarray-2024.1.1-py3-none-any.whl", hash = "sha256:0bec81303b088c8df4f075e1579c00cfd7e5069688e4434007f0b8d7df17fc1c"}, - {file = "xarray-2024.1.1.tar.gz", hash = "sha256:a1ba2d87a74892e213c9c83f4a462dbcdf68212320a4e31b34bd789ba7a64e35"}, + {file = "xarray-2024.6.0-py3-none-any.whl", hash = "sha256:721a7394e8ec3d592b2d8ebe21eed074ac077dc1bb1bd777ce00e41700b4866c"}, + {file = "xarray-2024.6.0.tar.gz", hash = "sha256:0b91e0bc4dc0296947947640fe31ec6e867ce258d2f7cbc10bedf4a6d68340c7"}, ] [package.dependencies] numpy = ">=1.23" -packaging = ">=22" -pandas = ">=1.5" +packaging = ">=23.1" +pandas = ">=2.0" [package.extras] accel = ["bottleneck", "flox", "numbagg", "opt-einsum", "scipy"] -complete = ["xarray[accel,io,parallel,viz]"] +complete = ["xarray[accel,dev,io,parallel,viz]"] +dev = ["hypothesis", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-env", "pytest-timeout", "pytest-xdist", "ruff", "xarray[complete]"] io = ["cftime", "fsspec", "h5netcdf", "netCDF4", "pooch", "pydap", "scipy", "zarr"] parallel = ["dask[complete]"] viz = ["matplotlib", "nc-time-axis", "seaborn"] [[package]] name = "zarr" -version = "2.16.1" +version = "2.18.2" description = "An implementation of chunked, compressed, N-dimensional arrays for Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "zarr-2.16.1-py3-none-any.whl", hash = "sha256:de4882433ccb5b42cc1ec9872b95e64ca3a13581424666b28ed265ad76c7056f"}, - {file = "zarr-2.16.1.tar.gz", hash = "sha256:4276cf4b4a653431042cd53ff2282bc4d292a6842411e88529964504fb073286"}, + {file = "zarr-2.18.2-py3-none-any.whl", hash = "sha256:a638754902f97efa99b406083fdc807a0e2ccf12a949117389d2a4ba9b05df38"}, + {file = "zarr-2.18.2.tar.gz", hash = "sha256:9bb393b8a0a38fb121dbb913b047d75db28de9890f6d644a217a73cf4ae74f47"}, ] [package.dependencies] asciitree = "*" -fasteners = "*" +fasteners = {version = "*", markers = "sys_platform != \"emscripten\""} numcodecs = ">=0.10.0" -numpy = ">=1.20,<1.21.0 || >1.21.0" +numpy = ">=1.23" [package.extras] -docs = ["numcodecs[msgpack]", "numpydoc", "pydata-sphinx-theme", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx-issues", "sphinx-rtd-theme"] +docs = ["numcodecs[msgpack]", "numpydoc", "pydata-sphinx-theme", "sphinx", "sphinx-automodapi", "sphinx-copybutton", "sphinx-design", "sphinx-issues"] jupyter = ["ipytree (>=0.2.2)", "ipywidgets (>=8.0.0)", "notebook"] -[[package]] -name = "zipp" -version = "3.17.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.8" -files = [ - {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, - {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] - -[extras] -docs = [] -jupyter = [] - [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "367b60c6639a725f4bd9a2ef837dbca12ee3a32cf0fe8a71f5684e5515981d93" +content-hash = "de26ee18efe0a5491f1818aceabe3b6f475c2f613279d5315fbd103e08e77b31" diff --git a/pyproject.toml b/pyproject.toml index a314337..509d60a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,49 +1,49 @@ [tool.poetry] name = "linkml-arrays" -version = "0.0.0" +version = "0.1.0" description = "linkml-arrays" -authors = ["Ryan Ly "] +authors = [ + "Ryan Ly ", + "Chris Mungall ", +] license = "BSD-3" readme = "README.md" [tool.poetry.dependencies] python = "^3.9" -linkml-runtime = ">=1.7.0" +linkml-runtime = ">=1.8.0" numpy = ">=1.24.3" h5py = ">=3.9.0" zarr = ">=2.16.1" -nptyping = ">=2.5.0" xarray = "^2024.1.1" -tox = "^3.25.1" # TODO move out of main deps +ruamel-yaml = "^0.18.6" [tool.poetry.dev-dependencies] -pytest = "^7.1.2" -sphinx = {version = "^5.3.0", extras = ["docs"]} -sphinx-rtd-theme = {version = "^1.0.0", extras = ["docs"]} -# sphinx-autodoc-typehints = {version = "^1.19.4", extras = ["docs"]} -sphinx-click = {version = "^4.3.0", extras = ["docs"]} -myst-parser = {version = "^0.18.1", extras = ["docs"]} -jupyter = {version = "*", extras = ["jupyter"]} - -[tool.poetry.scripts] -linkml-arrays = "linkml_arrays.cli:main" +pytest = "*" +tox = "*" +# sphinx = {version = "*", extras = ["docs"]} +# sphinx-rtd-theme = {version = "^1.0.0", extras = ["docs"]} +# # sphinx-autodoc-typehints = {version = "^1.19.4", extras = ["docs"]} +# sphinx-click = {version = "^4.3.0", extras = ["docs"]} +# myst-parser = {version = "*", extras = ["docs"]} +# jupyter = {version = "*", extras = ["jupyter"]} -[tool.poetry.extras] -docs = [ - "sphinx", - "sphinx-rtd-theme", - # "sphinx-autodoc-typehints", - "sphinx-click", - "myst-parser" -] -jupyter = [ - "jupyter" -] +# [tool.poetry.extras] +# docs = [ +# "sphinx", +# "sphinx-rtd-theme", +# "sphinx-autodoc-typehints", +# "sphinx-click", +# "myst-parser" +# ] +# jupyter = [ +# "jupyter" +# ] -[tool.poetry.group.dev.dependencies] -black = "^24.1.1" -pytest = "^7.1.2" -mypy = "^1.8.0" +# [tool.poetry.group.dev.dependencies] +# black = "^24.1.1" +# pytest = "^7.1.2" +# mypy = "^1.8.0" [tool.poetry-dynamic-versioning] enable = true @@ -52,7 +52,6 @@ style = "pep440" [tool.black] line-length = 100 -target-version = ["py38", "py39", "py310"] [tool.isort] profile = "black" diff --git a/src/linkml_arrays/cli.py b/src/linkml_arrays/cli.py deleted file mode 100644 index 04278f2..0000000 --- a/src/linkml_arrays/cli.py +++ /dev/null @@ -1,44 +0,0 @@ -"""Command line interface for linkml-arrays.""" - -import logging - -import click - -from linkml_arrays import __version__ -from linkml_arrays.main import demo - -__all__ = [ - "main", -] - -logger = logging.getLogger(__name__) - - -@click.group() -@click.option("-v", "--verbose", count=True) -@click.option("-q", "--quiet") -@click.version_option(__version__) -def main(verbose: int, quiet: bool): - """CLI for linkml-arrays. - - :param verbose: Verbosity while running. - :param quiet: Boolean to be quiet or verbose. - """ - if verbose >= 2: - logger.setLevel(level=logging.DEBUG) - elif verbose == 1: - logger.setLevel(level=logging.INFO) - else: - logger.setLevel(level=logging.WARNING) - if quiet: - logger.setLevel(level=logging.ERROR) - - -@main.command() -def run(): - """Run the linkml-arrays's demo command.""" - demo() - - -if __name__ == "__main__": - main() diff --git a/src/linkml_arrays/main.py b/src/linkml_arrays/main.py deleted file mode 100644 index 5a05fe2..0000000 --- a/src/linkml_arrays/main.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Main python file.""" - - -def demo(): - """Define API.""" - print("Hello, World!") - - -if __name__ == "__main__": - demo() From ca40bff6fdb3db4df8fde20f186b645d05deb56a Mon Sep 17 00:00:00 2001 From: rly Date: Sat, 6 Jul 2024 23:10:27 -0400 Subject: [PATCH 16/38] Remove demo test --- tests/demo_test.py | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 tests/demo_test.py diff --git a/tests/demo_test.py b/tests/demo_test.py deleted file mode 100644 index 1eaf64b..0000000 --- a/tests/demo_test.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Demo version test.""" - -import unittest - -from linkml_arrays import __version__ - - -class TestVersion(unittest.TestCase): - """Test version.""" - - def test_version_type(self): - """Demo test.""" - self.assertIsInstance(__version__, str) From 6aa88780c5b8b3fe688194cc3e4dd7d678562a08 Mon Sep 17 00:00:00 2001 From: Wouter-Michiel Vierdag Date: Sat, 27 Jul 2024 20:03:52 +0200 Subject: [PATCH 17/38] adjust for non ordered keys --- tests/test_dumpers/test_dumpers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_dumpers/test_dumpers.py b/tests/test_dumpers/test_dumpers.py index 3b83bd5..d0535d4 100644 --- a/tests/test_dumpers/test_dumpers.py +++ b/tests/test_dumpers/test_dumpers.py @@ -70,7 +70,9 @@ def test_yaml_dumper(): with open(expected_yaml_file) as f: expected = yaml.load(f) # load yaml into dictionary actual = yaml.load(ret) - assert actual == expected + assert expected.keys() == actual.keys() + for key in expected.keys(): + assert actual[key] == expected[key] def test_yaml_numpy_dumper(): From 1bbd018385c7d085a93522c59c59b93052b55c00 Mon Sep 17 00:00:00 2001 From: Wouter-Michiel Vierdag Date: Thu, 1 Aug 2024 11:28:45 +0200 Subject: [PATCH 18/38] add xarray loaders --- src/linkml_arrays/dumpers/xarray_dumpers.py | 130 ++++++++++++++++++++ src/linkml_arrays/loaders/xarray_loaders.py | 64 ++++++++++ 2 files changed, 194 insertions(+) create mode 100644 src/linkml_arrays/dumpers/xarray_dumpers.py create mode 100644 src/linkml_arrays/loaders/xarray_loaders.py diff --git a/src/linkml_arrays/dumpers/xarray_dumpers.py b/src/linkml_arrays/dumpers/xarray_dumpers.py new file mode 100644 index 0000000..61b3fbd --- /dev/null +++ b/src/linkml_arrays/dumpers/xarray_dumpers.py @@ -0,0 +1,130 @@ +"""Class for dumping a LinkML model to netcdf like using xarray and DataTree.""" + +from pathlib import Path + +import numpy as np +from xarray.core.datatree import DataTree + +"""Class for dumping a LinkML model to an netcdf like file.""" + +from pathlib import Path +from typing import Union + +import xarray as xr +import pandas as pd +from linkml_runtime import SchemaView +from linkml_runtime.dumpers.dumper_root import Dumper +from linkml_runtime.utils.yamlutils import YAMLRoot +from pydantic import BaseModel +from linkml_runtime import SchemaView + + +def _create_node(model, schemaview): + """Create datatree from temperature dataset""" + node_dict = {} + for k, v in vars(model).items(): + if isinstance(v, str): + # parts of the dataset with key and value both being string, e.g. name, latitude_in_deg + try: + node_dict["attrs"][k] = v + except KeyError: + node_dict["attrs"] = {k: v} + elif isinstance(v, BaseModel): + if len(var_dict := vars(v)) == 1: + # If values are length 1 we are dealing with coords like date + v = pd.to_datetime(v.values) + try: + node_dict["coords"][k] = v + except KeyError: + node_dict["coords"] = {k: {"data": v, "dims": k}} + else: + for key, value in var_dict.items(): + if key == "values": + if not isinstance(value[0], list): + try: + node_dict["coords"][k] = {"data": value, "dims": list(node_dict["coords"])[0]} + except KeyError: + node_dict["coords"] = {k: {"data": value, "dims": list(node_dict["coords"])[0]}} + else: + # Parse the temperature matrix + element_type = type(v).__name__ + dimensions_expressions = schemaview.induced_slot(key, element_type).array.dimensions + dims = [dim.alias for dim in dimensions_expressions] + array = np.array(value) + node_dict["dims"] = {dim: array.shape[i] for i, dim in enumerate(dims)} + node_dict["data_vars"] = {k: {"data": array, "dims": list(node_dict["dims"].keys())}} + else: + if isinstance(value, str): + # can't use timestamp here as it does not serialize, potentially add with 'data' dims as coord + try: + node_dict["attrs"][key] = value + except KeyError: + node_dict["attrs"] = {key: value} + else: + # conversion factor + node_dict["attrs"][key] = value + return xr.Dataset.from_dict(node_dict) + + + +def _iterate_element( + element: Union[YAMLRoot, BaseModel], schemaview: SchemaView, datatree = None +): + """Recursively iterate through the elements of a LinkML model and save them. + + Write toplevel Pydantic BaseModel objects as datasets, slots with the "array" element + as datasets, and other slots as attributes. + """ + # get the type of the element + element_type = type(element).__name__ + + for k, v in vars(element).items(): + if isinstance(v, BaseModel): + # create a subgroup and recurse + if "values" in v.__dir__(): + dims = ["y","x"] + data_dict = vars(v) + data_dict["data"] = np.array(data_dict.pop("values")) + data_dict["dims"] = [dims[i] for i in range(data_dict["data"].shape[0])] + dataarray = xr.DataArray.from_dict(d=data_dict) + datatree[k] = dataarray + else: + dataset = _create_node(v, schemaview) + datatree[k] = DataTree(data=dataset) + elif isinstance(v, str): + datatree.attrs["name"] = v + return datatree + + +class XarrayNetCDFDumper(Dumper): + """Dumper class for LinkML models to HDF5 files.""" + + # TODO is this the right method to overwrite? it does not dump a string + def dumps( + self, + element: Union[YAMLRoot, BaseModel], + schemaview: SchemaView, + output_file_path: Union[str, Path], + **kwargs, + ): + """Dump the element to an HDF5 file.""" + datatree = DataTree() + datatree = _iterate_element(element, schemaview, datatree) + datatree.to_netcdf(output_file_path, engine='h5netcdf') + + +class XarrayZarrDumper(Dumper): + """Dumper class for LinkML models to HDF5 files.""" + + # TODO is this the right method to overwrite? it does not dump a string + def dumps( + self, + element: Union[YAMLRoot, BaseModel], + schemaview: SchemaView, + output_file_path: Union[str, Path], + **kwargs, + ): + """Dump the element to an HDF5 file.""" + datatree = DataTree() + datatree = _iterate_element(element, schemaview, datatree) + datatree.to_zarr(output_file_path) diff --git a/src/linkml_arrays/loaders/xarray_loaders.py b/src/linkml_arrays/loaders/xarray_loaders.py new file mode 100644 index 0000000..fdd6e09 --- /dev/null +++ b/src/linkml_arrays/loaders/xarray_loaders.py @@ -0,0 +1,64 @@ +"""Class for loading a LinkML model from a Zarr directory store.""" + +from typing import Type, Union + +import zarr +from linkml_runtime import SchemaView +from linkml_runtime.linkml_model import ClassDefinition +from linkml_runtime.loaders.loader_root import Loader +from linkml_runtime.utils.yamlutils import YAMLRoot +from pydantic import BaseModel + + +def _iterate_element( + group: zarr.hierarchy.Group, element_type: ClassDefinition, schemaview: SchemaView +) -> dict: + """Recursively iterate through the elements of a LinkML model and load them into a dict. + + Datasets are read into memory. + """ + ret_dict = dict() + for k, v in group.attrs.items(): + ret_dict[k] = v + + for k, v in group.items(): + found_slot = schemaview.induced_slot( + k, element_type.name + ) # assumes the slot name has been written as the name which is OK for now. + if found_slot.array: + assert isinstance(v, zarr.Array) + v = v[()] # read all the values into memory # TODO support lazy loading + elif isinstance(v, zarr.hierarchy.Group): # it's a subgroup + found_slot_range = schemaview.get_class(found_slot.range) + v = _iterate_element(v, found_slot_range, schemaview) + # else: do not transform v + ret_dict[k] = v + + return ret_dict + + +class ZarrDirectoryStoreLoader(Loader): + """Class for loading a LinkML model from a Zarr directory store.""" + + def load_any(self, source: str, **kwargs): + """Create an instance of the target class from a Zarr directory store.""" + return self.load(source, **kwargs) + + def loads(self, source: str, **kwargs): + """Create an instance of the target class from a Zarr directory store.""" + return self.load(source, **kwargs) + + def load( + self, + source: str, + target_class: Type[Union[YAMLRoot, BaseModel]], + schemaview: SchemaView, + **kwargs, + ): + """Create an instance of the target class from a Zarr directory store.""" + element_type = schemaview.get_class(target_class.__name__) + z = zarr.open(source, mode="r") + element = _iterate_element(z, element_type, schemaview) + obj = target_class(**element) + + return obj From 0d68f95308b1af8334d8b5141298861e36b911fa Mon Sep 17 00:00:00 2001 From: Wouter-Michiel Vierdag Date: Thu, 1 Aug 2024 11:29:33 +0200 Subject: [PATCH 19/38] update dependency --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 509d60a..6d97b95 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,6 +16,7 @@ numpy = ">=1.24.3" h5py = ">=3.9.0" zarr = ">=2.16.1" xarray = "^2024.1.1" +h5netcdf = ">=1.3.0" ruamel-yaml = "^0.18.6" [tool.poetry.dev-dependencies] From 0858c1751ef4f516d9c7ef2ed3479dfb1a79d5a7 Mon Sep 17 00:00:00 2001 From: Wouter-Michiel Vierdag Date: Thu, 1 Aug 2024 11:29:59 +0200 Subject: [PATCH 20/38] update module imports --- src/linkml_arrays/dumpers/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/linkml_arrays/dumpers/__init__.py b/src/linkml_arrays/dumpers/__init__.py index 5011043..80959f9 100644 --- a/src/linkml_arrays/dumpers/__init__.py +++ b/src/linkml_arrays/dumpers/__init__.py @@ -1,15 +1,20 @@ """Dumper classes for linkml-arrays.""" from .hdf5_dumper import Hdf5Dumper +from .xarray_dumpers import XarrayNetCDFDumper, XarrayZarrDumper from .yaml_dumper import YamlDumper from .yaml_hdf5_dumper import YamlHdf5Dumper from .yaml_numpy_dumper import YamlNumpyDumper +from .yaml_xarray_dumper import YamlXarrayNetCDFDumper from .zarr_directory_store_dumper import ZarrDirectoryStoreDumper __all__ = [ "Hdf5Dumper", + "XarrayNetCDFDumper", + "XarrayZarrDumper", "YamlDumper", "YamlHdf5Dumper", "YamlNumpyDumper", "ZarrDirectoryStoreDumper", + "YamlXarrayNetCDFDumper", ] From d4369944921076b7e3a3e7b68bb9f5511bcf60e4 Mon Sep 17 00:00:00 2001 From: Wouter-Michiel Vierdag Date: Thu, 1 Aug 2024 11:30:21 +0200 Subject: [PATCH 21/38] add tests --- tests/test_dumpers/test_dumpers.py | 32 ++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/test_dumpers/test_dumpers.py b/tests/test_dumpers/test_dumpers.py index d0535d4..9523251 100644 --- a/tests/test_dumpers/test_dumpers.py +++ b/tests/test_dumpers/test_dumpers.py @@ -6,15 +6,18 @@ import h5py import numpy as np import zarr +from xarray.backends.api import open_datatree from linkml_runtime import SchemaView from ruamel.yaml import YAML from linkml_arrays.dumpers import ( Hdf5Dumper, + XarrayNetCDFDumper, YamlDumper, YamlHdf5Dumper, YamlNumpyDumper, ZarrDirectoryStoreDumper, + YamlXarrayNetCDFDumper ) from tests.array_classes_lol import ( Container, @@ -107,6 +110,35 @@ def test_yaml_hdf5_dumper(): assert actual == expected +def test_xarray_netcdf_dumper(tmp_path): + container = _create_container() + schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") + output_file_path = tmp_path / "my_container.nc" + XarrayNetCDFDumper().dumps(container, schemaview=schemaview, output_file_path=output_file_path) + + assert os.path.exists(output_file_path) + datatree = open_datatree(output_file_path, engine='h5netcdf') + + assert datatree.attrs['name'] == 'my_container' + np.testing.assert_array_equal(datatree["latitude_series"].data, [[1, 2], [3, 4]]) + np.testing.assert_array_equal(datatree["longitude_series"].data, [[5, 6], [7, 8]]) + assert list(datatree["temperature_dataset"].coords.keys()) == ['date', 'day_in_d'] + + dates = np.datetime_as_string(datatree["temperature_dataset"].coords["date"].values, unit="D") + np.testing.assert_array_equal( + dates, np.array(["2020-01-01", "2020-01-02"]) + ) + np.testing.assert_array_equal(datatree["temperature_dataset"]["day_in_d"].values, [0, 1]) + np.testing.assert_array_equal(datatree["temperature_dataset"]["temperatures_in_K"].values, + [[[0, 1], [2, 3]], [[4, 5], [6, 7]]]) + + assert datatree["temperature_dataset"].attrs["name"] == "my_temperature" + assert datatree["temperature_dataset"].attrs["conversion_factor"] == 1000 + # Check possibility of reference date being another coords with dims set to date. + assert datatree["temperature_dataset"].attrs["reference_date"] == "2020-01-01" + assert datatree["temperature_dataset"].attrs["latitude_in_deg"] == "my_latitude" + assert datatree["temperature_dataset"].attrs["longitude_in_deg"] == "my_longitude" + def test_hdf5_dumper(tmp_path): """Test Hdf5Dumper dumping to an HDF5 file.""" container = _create_container() From a23202d9fb12b53de58070a9d29c73506a40ec0c Mon Sep 17 00:00:00 2001 From: Wouter-Michiel Vierdag Date: Thu, 1 Aug 2024 15:20:22 +0200 Subject: [PATCH 22/38] add xarray zarr dumper test --- tests/test_dumpers/test_dumpers.py | 35 +++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/tests/test_dumpers/test_dumpers.py b/tests/test_dumpers/test_dumpers.py index 9523251..b853166 100644 --- a/tests/test_dumpers/test_dumpers.py +++ b/tests/test_dumpers/test_dumpers.py @@ -17,7 +17,7 @@ YamlHdf5Dumper, YamlNumpyDumper, ZarrDirectoryStoreDumper, - YamlXarrayNetCDFDumper + YamlXarrayNetCDFDumper, XarrayZarrDumper ) from tests.array_classes_lol import ( Container, @@ -110,6 +110,38 @@ def test_yaml_hdf5_dumper(): assert actual == expected +def test_xarray_zarr_dumper(tmp_path): + container = _create_container() + schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") + output_file_path = tmp_path / "my_container.zarr" + XarrayZarrDumper().dumps(container, schemaview=schemaview, output_file_path=output_file_path) + + assert os.path.exists(output_file_path) + root = zarr.group(store=output_file_path) + assert root.attrs["name"] == "my_container" + np.testing.assert_array_equal(root["latitude_series"][:], [[1, 2], [3, 4]]) + + np.testing.assert_array_equal(root["longitude_series"][:], [[5, 6], [7, 8]]) + assert set(root["temperature_dataset"]) == set(["date", "day_in_d", "temperatures_in_K"]) + + # Below reference date seems to be added automatically when using pd.to_datetime + np.testing.assert_array_equal( + root["temperature_dataset/date"][:], np.array([0, 1]) + ) + assert root["temperature_dataset/date"].attrs['units'] == "days since 2020-01-01 00:00:00" + np.testing.assert_array_equal(root["temperature_dataset/day_in_d"][:], [0, 1]) + np.testing.assert_array_equal( + root["temperature_dataset/temperatures_in_K"][:], + [[[0, 1], [2, 3]], [[4, 5], [6, 7]]], + ) + assert root["temperature_dataset"].attrs["name"] == "my_temperature" + assert root["temperature_dataset"].attrs["conversion_factor"] == 1000 + # Check possibility of reference date being another coords with dims set to date. + assert root["temperature_dataset"].attrs["reference_date"] == "2020-01-01" + assert root["temperature_dataset"].attrs["latitude_in_deg"] == "my_latitude" + assert root["temperature_dataset"].attrs["longitude_in_deg"] == "my_longitude" + + def test_xarray_netcdf_dumper(tmp_path): container = _create_container() schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") @@ -139,6 +171,7 @@ def test_xarray_netcdf_dumper(tmp_path): assert datatree["temperature_dataset"].attrs["latitude_in_deg"] == "my_latitude" assert datatree["temperature_dataset"].attrs["longitude_in_deg"] == "my_longitude" + def test_hdf5_dumper(tmp_path): """Test Hdf5Dumper dumping to an HDF5 file.""" container = _create_container() From 64f411bb3c36e46dd2608e7982ce8c43ac9da6cb Mon Sep 17 00:00:00 2001 From: Wouter-Michiel Vierdag Date: Thu, 1 Aug 2024 17:20:32 +0200 Subject: [PATCH 23/38] add xarray yaml netcdf dumper --- src/linkml_arrays/dumpers/__init__.py | 2 +- .../dumpers/yaml_xarray_dumpers.py | 36 +++++++++++++++++++ .../loaders/yaml_array_file_loader.py | 3 +- tests/input/container_yaml_xarray_netcdf.yaml | 34 ++++++++++++++++++ tests/test_dumpers/test_dumpers.py | 16 +++++++++ 5 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 src/linkml_arrays/dumpers/yaml_xarray_dumpers.py create mode 100644 tests/input/container_yaml_xarray_netcdf.yaml diff --git a/src/linkml_arrays/dumpers/__init__.py b/src/linkml_arrays/dumpers/__init__.py index 80959f9..be8f94b 100644 --- a/src/linkml_arrays/dumpers/__init__.py +++ b/src/linkml_arrays/dumpers/__init__.py @@ -5,7 +5,7 @@ from .yaml_dumper import YamlDumper from .yaml_hdf5_dumper import YamlHdf5Dumper from .yaml_numpy_dumper import YamlNumpyDumper -from .yaml_xarray_dumper import YamlXarrayNetCDFDumper +from .yaml_xarray_dumpers import YamlXarrayNetCDFDumper from .zarr_directory_store_dumper import ZarrDirectoryStoreDumper __all__ = [ diff --git a/src/linkml_arrays/dumpers/yaml_xarray_dumpers.py b/src/linkml_arrays/dumpers/yaml_xarray_dumpers.py new file mode 100644 index 0000000..b6c0328 --- /dev/null +++ b/src/linkml_arrays/dumpers/yaml_xarray_dumpers.py @@ -0,0 +1,36 @@ +"""Class for dumping a LinkML model to YAML with paths to NumPy files.""" + +from pathlib import Path +from typing import List, Union + +import numpy as np +import xarray as xr + +from .yaml_array_file_dumper import YamlArrayFileDumper + + +class YamlXarrayNetCDFDumper(YamlArrayFileDumper): + """Dumper class for LinkML models to YAML with paths to .nc file. + + Each array is written to an netcdf dataset at path "/data" in a new .nc file. + """ + + FILE_SUFFIX = ".nc" # used in parent class + FORMAT = "netcdf" + + @classmethod + def write_array( + cls, array: Union[List, np.ndarray], output_file_path_no_suffix: Union[str, Path] + ): + """Write an array to a NumPy file.""" + # TODO do not assume that there is only one by this name + # add suffix to the file name + if isinstance(output_file_path_no_suffix, str): + output_file_path_no_suffix = Path(output_file_path_no_suffix) + output_file_path = output_file_path_no_suffix.parent / ( + output_file_path_no_suffix.name + cls.FILE_SUFFIX + ) + + data_array = xr.DataArray(data=array) + data_array.to_netcdf(output_file_path, engine="h5netcdf") + return output_file_path \ No newline at end of file diff --git a/src/linkml_arrays/loaders/yaml_array_file_loader.py b/src/linkml_arrays/loaders/yaml_array_file_loader.py index d40b61d..b2e0fe4 100644 --- a/src/linkml_arrays/loaders/yaml_array_file_loader.py +++ b/src/linkml_arrays/loaders/yaml_array_file_loader.py @@ -10,6 +10,7 @@ from linkml_runtime.loaders.loader_root import Loader from linkml_runtime.utils.yamlutils import YAMLRoot from pydantic import BaseModel +from pathlib import Path def _iterate_element( @@ -39,7 +40,7 @@ def _iterate_element( raise ValueError( f"Array slot {k}, source {source}, format {format} has no file." ) - array_file_path = file + array_file_path = Path(file) with h5py.File(array_file_path, "r") as f: # read all the values into memory TODO: support lazy loading v = f["data"][()] diff --git a/tests/input/container_yaml_xarray_netcdf.yaml b/tests/input/container_yaml_xarray_netcdf.yaml new file mode 100644 index 0000000..735ccfa --- /dev/null +++ b/tests/input/container_yaml_xarray_netcdf.yaml @@ -0,0 +1,34 @@ +name: my_container +latitude_series: + name: my_latitude + values: + source: + - file: "./out/my_latitude.values.nc" + format: netcdf +longitude_series: + name: my_longitude + values: + source: + - file: "./out/my_longitude.values.nc" + format: netcdf +temperature_dataset: + date: + values: + source: + - file: "./out/my_temperature.date.values.nc" + format: netcdf + day_in_d: + reference_date: '2020-01-01' + values: + source: + - file: "./out/my_temperature.day_in_d.values.nc" + format: netcdf + latitude_in_deg: my_latitude + longitude_in_deg: my_longitude + name: my_temperature + temperatures_in_K: + conversion_factor: 1000.0 + values: + source: + - file: "./out/my_temperature.temperatures_in_K.values.nc" + format: netcdf diff --git a/tests/test_dumpers/test_dumpers.py b/tests/test_dumpers/test_dumpers.py index b853166..4a697ea 100644 --- a/tests/test_dumpers/test_dumpers.py +++ b/tests/test_dumpers/test_dumpers.py @@ -110,6 +110,22 @@ def test_yaml_hdf5_dumper(): assert actual == expected +def test_yaml_xarray_dumper(): + """Test YamlNumpyDumper dumping to a YAML file and HDF5 datasets in a directory.""" + container = _create_container() + + schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") + ret = YamlXarrayNetCDFDumper().dumps(container, schemaview=schemaview, output_dir="./out") + + # read and compare with the expected YAML file ignoring order of keys + expected_yaml_file = INPUT_DIR / "container_yaml_xarray_netcdf.yaml" + yaml = YAML(typ="safe") + with open(expected_yaml_file) as f: + expected = yaml.load(f) # load yaml into dictionary + actual = yaml.load(ret) + assert actual == expected + + def test_xarray_zarr_dumper(tmp_path): container = _create_container() schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") From 0fcadbb563b4157e69f04cb579b6260cfd795fec Mon Sep 17 00:00:00 2001 From: Wouter-Michiel Vierdag Date: Thu, 1 Aug 2024 18:12:58 +0200 Subject: [PATCH 24/38] add xarray input --- tests/input/my_container.nc | Bin 0 -> 16536 bytes tests/input/my_container_xarray.zarr/.zattrs | 3 + tests/input/my_container_xarray.zarr/.zgroup | 3 + .../input/my_container_xarray.zarr/.zmetadata | 161 ++++++++++++++++++ .../latitude_series/.zarray | 22 +++ .../latitude_series/.zattrs | 6 + .../latitude_series/0.0 | Bin 0 -> 48 bytes .../longitude_series/.zarray | 22 +++ .../longitude_series/.zattrs | 6 + .../longitude_series/0.0 | Bin 0 -> 48 bytes .../temperature_dataset/.zattrs | 7 + .../temperature_dataset/.zgroup | 3 + .../temperature_dataset/date/.zarray | 20 +++ .../temperature_dataset/date/.zattrs | 7 + .../temperature_dataset/date/0 | Bin 0 -> 32 bytes .../temperature_dataset/day_in_d/.zarray | 20 +++ .../temperature_dataset/day_in_d/.zattrs | 5 + .../temperature_dataset/day_in_d/0 | Bin 0 -> 24 bytes .../temperatures_in_K/.zarray | 24 +++ .../temperatures_in_K/.zattrs | 8 + .../temperatures_in_K/0.0.0 | Bin 0 -> 80 bytes 21 files changed, 317 insertions(+) create mode 100644 tests/input/my_container.nc create mode 100644 tests/input/my_container_xarray.zarr/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/.zgroup create mode 100644 tests/input/my_container_xarray.zarr/.zmetadata create mode 100644 tests/input/my_container_xarray.zarr/latitude_series/.zarray create mode 100644 tests/input/my_container_xarray.zarr/latitude_series/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/latitude_series/0.0 create mode 100644 tests/input/my_container_xarray.zarr/longitude_series/.zarray create mode 100644 tests/input/my_container_xarray.zarr/longitude_series/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/longitude_series/0.0 create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/.zgroup create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/date/.zarray create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/date/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/date/0 create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zarray create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/0 create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zarray create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/0.0.0 diff --git a/tests/input/my_container.nc b/tests/input/my_container.nc new file mode 100644 index 0000000000000000000000000000000000000000..cca7cdf273273cc37a880d8aa0f5cd3378edc52c GIT binary patch literal 16536 zcmeHOYiL|W6rP)Gw%c|!NgLZ(MQ>XlmBzSv6txd~+dNEdnwF-BR&=|~-n1*5-LQM3 z4Tvd-(kj}Z{wNA6fM{D~<^Onq02$6^isVaRbKW9uh>~V_3C4ZM(l#p9HTDOY<#YDpZY%s7#{INBmO9(F4Mu zv?9tw;A^F#h;WiltJ0%iX}WbAaw%|X_A-v`XJJyGzLcX4CY8mZxsP|~pE97qUW10KmtLs{sFbS~N7UjWDpe6dPFY!*u82OAtEMGf{WqgUaH%MbOEZc( z>S7veM8&)OpeNbe+?wi3B`Lj%#tvZ7E`n}KUlBGj#2po;dJ)yqxuLt8au(8e1Wlz{ zH*IO_>fW@qE8g9*p|edzcVTRp2h{4?u%!*^P|KsQ=-;t7m3Qfra5H|;(%SAOQ+<9W zpUP(3-2;J}$p#}?_a$!(r&6P+C`n4x_6M>qCD)f z#qzHjLN(M01(Lwg)%rG|c7 zY8(hc8%{(tp1$GaDa=WDIjTA#;ajTG+033|PEok8cV0X;Pfy}5UEwV9i5P>PD#Pi3 zvib6pgLBc^|BFuqatMMc$CO%d>?O_mo}Fd>>5V^Jr>C|C`kjz$181L*U(q{&I2cCw zPU2lH+j7}{KNk>%Of?o#g&1n0I)(fE92_R=8teA1A} zK9i%=bMHR8w%C?ShBGJ*k+9b0gv2qjF!1}xmM4ONoF6w1HP7XGU9AHj=zDkv+y5&4 zI8|^WrZVxQzh}y`4D(5uj1}IOD0#u)uc~Hkh35yOj+>rRD;zLVWcDz(;} z-|Of6OphKCJ@!p?-U8=LL>rKSHuxVGXl>+aGB>q&Z=xs2YL63@n%0A)cgVZ{i@O`o z{+R%!9=Mr0LE#$~(|9<9uMl%NGhd;eHM+%LxTh{28M^o7!lSzOzLxS#&*WT-QVFxm z9y!Md>lHjJg!!nD>7Eulhi>h|u4U_S^jgmAEGlyKlgArJO6*+CS+a`G*GZY98yDR@ z%{kNOFyI%b4+U?6Ge}C^v}W`;iKO&L(q+2kn1Q6rWLJ&RBlBEs(yuU*^yl4titd2!NLSogY_;5w3dg|ZitA|FARAe zmo%b4)lTAA=tqs2zKA0{g-CQvh;95;FOGv_D2{_$c=L&0G&NY#k$zNY_6zaF95W3C zUPyQ*8ki2>&-rx?Sf&5h=w#HV)2}~RJi7fJk6JjRD8=E_2y3UtKqeKyeLt0J1dNib zAh1kujZ~19x$GKAr2R}XAs&$_wSi9(ZQ!7=kIK~Vh=hH>HCVmbyW-oKWycPC+;!n2h2)>)1?+98F;hD#d#YFpj#$HN|2vIyWg~Y=sYP-zUVd@U zi8ru*!}_$969RvY5D_Z)<8_>H|8VV3D2R6;!@A=aqN&9KM-VBdR^l=mE~V7)-(No? S*XLc%_8bA Date: Mon, 5 Aug 2024 15:45:21 +0200 Subject: [PATCH 25/38] delete outdated .nc --- tests/input/my_container.nc | Bin 16536 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tests/input/my_container.nc diff --git a/tests/input/my_container.nc b/tests/input/my_container.nc deleted file mode 100644 index cca7cdf273273cc37a880d8aa0f5cd3378edc52c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16536 zcmeHOYiL|W6rP)Gw%c|!NgLZ(MQ>XlmBzSv6txd~+dNEdnwF-BR&=|~-n1*5-LQM3 z4Tvd-(kj}Z{wNA6fM{D~<^Onq02$6^isVaRbKW9uh>~V_3C4ZM(l#p9HTDOY<#YDpZY%s7#{INBmO9(F4Mu zv?9tw;A^F#h;WiltJ0%iX}WbAaw%|X_A-v`XJJyGzLcX4CY8mZxsP|~pE97qUW10KmtLs{sFbS~N7UjWDpe6dPFY!*u82OAtEMGf{WqgUaH%MbOEZc( z>S7veM8&)OpeNbe+?wi3B`Lj%#tvZ7E`n}KUlBGj#2po;dJ)yqxuLt8au(8e1Wlz{ zH*IO_>fW@qE8g9*p|edzcVTRp2h{4?u%!*^P|KsQ=-;t7m3Qfra5H|;(%SAOQ+<9W zpUP(3-2;J}$p#}?_a$!(r&6P+C`n4x_6M>qCD)f z#qzHjLN(M01(Lwg)%rG|c7 zY8(hc8%{(tp1$GaDa=WDIjTA#;ajTG+033|PEok8cV0X;Pfy}5UEwV9i5P>PD#Pi3 zvib6pgLBc^|BFuqatMMc$CO%d>?O_mo}Fd>>5V^Jr>C|C`kjz$181L*U(q{&I2cCw zPU2lH+j7}{KNk>%Of?o#g&1n0I)(fE92_R=8teA1A} zK9i%=bMHR8w%C?ShBGJ*k+9b0gv2qjF!1}xmM4ONoF6w1HP7XGU9AHj=zDkv+y5&4 zI8|^WrZVxQzh}y`4D(5uj1}IOD0#u)uc~Hkh35yOj+>rRD;zLVWcDz(;} z-|Of6OphKCJ@!p?-U8=LL>rKSHuxVGXl>+aGB>q&Z=xs2YL63@n%0A)cgVZ{i@O`o z{+R%!9=Mr0LE#$~(|9<9uMl%NGhd;eHM+%LxTh{28M^o7!lSzOzLxS#&*WT-QVFxm z9y!Md>lHjJg!!nD>7Eulhi>h|u4U_S^jgmAEGlyKlgArJO6*+CS+a`G*GZY98yDR@ z%{kNOFyI%b4+U?6Ge}C^v}W`;iKO&L(q+2kn1Q6rWLJ&RBlBEs(yuU*^yl4titd2!NLSogY_;5w3dg|ZitA|FARAe zmo%b4)lTAA=tqs2zKA0{g-CQvh;95;FOGv_D2{_$c=L&0G&NY#k$zNY_6zaF95W3C zUPyQ*8ki2>&-rx?Sf&5h=w#HV)2}~RJi7fJk6JjRD8=E_2y3UtKqeKyeLt0J1dNib zAh1kujZ~19x$GKAr2R}XAs&$_wSi9(ZQ!7=kIK~Vh=hH>HCVmbyW-oKWycPC+;!n2h2)>)1?+98F;hD#d#YFpj#$HN|2vIyWg~Y=sYP-zUVd@U zi8ru*!}_$969RvY5D_Z)<8_>H|8VV3D2R6;!@A=aqN&9KM-VBdR^l=mE~V7)-(No? S*XLc%_8bA Date: Mon, 5 Aug 2024 15:46:09 +0200 Subject: [PATCH 26/38] delete outdated .zarr --- tests/input/my_container_xarray.zarr/.zattrs | 3 - tests/input/my_container_xarray.zarr/.zgroup | 3 - .../input/my_container_xarray.zarr/.zmetadata | 161 ------------------ .../latitude_series/.zarray | 22 --- .../latitude_series/.zattrs | 6 - .../latitude_series/0.0 | Bin 48 -> 0 bytes .../longitude_series/.zarray | 22 --- .../longitude_series/.zattrs | 6 - .../longitude_series/0.0 | Bin 48 -> 0 bytes .../temperature_dataset/.zattrs | 7 - .../temperature_dataset/.zgroup | 3 - .../temperature_dataset/date/.zarray | 20 --- .../temperature_dataset/date/.zattrs | 7 - .../temperature_dataset/date/0 | Bin 32 -> 0 bytes .../temperature_dataset/day_in_d/.zarray | 20 --- .../temperature_dataset/day_in_d/.zattrs | 5 - .../temperature_dataset/day_in_d/0 | Bin 24 -> 0 bytes .../temperatures_in_K/.zarray | 24 --- .../temperatures_in_K/.zattrs | 8 - .../temperatures_in_K/0.0.0 | Bin 80 -> 0 bytes 20 files changed, 317 deletions(-) delete mode 100644 tests/input/my_container_xarray.zarr/.zattrs delete mode 100644 tests/input/my_container_xarray.zarr/.zgroup delete mode 100644 tests/input/my_container_xarray.zarr/.zmetadata delete mode 100644 tests/input/my_container_xarray.zarr/latitude_series/.zarray delete mode 100644 tests/input/my_container_xarray.zarr/latitude_series/.zattrs delete mode 100644 tests/input/my_container_xarray.zarr/latitude_series/0.0 delete mode 100644 tests/input/my_container_xarray.zarr/longitude_series/.zarray delete mode 100644 tests/input/my_container_xarray.zarr/longitude_series/.zattrs delete mode 100644 tests/input/my_container_xarray.zarr/longitude_series/0.0 delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/.zattrs delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/.zgroup delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/date/.zarray delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/date/.zattrs delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/date/0 delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zarray delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zattrs delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/0 delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zarray delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zattrs delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/0.0.0 diff --git a/tests/input/my_container_xarray.zarr/.zattrs b/tests/input/my_container_xarray.zarr/.zattrs deleted file mode 100644 index 060eade..0000000 --- a/tests/input/my_container_xarray.zarr/.zattrs +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "my_container" -} \ No newline at end of file diff --git a/tests/input/my_container_xarray.zarr/.zgroup b/tests/input/my_container_xarray.zarr/.zgroup deleted file mode 100644 index 3b7daf2..0000000 --- a/tests/input/my_container_xarray.zarr/.zgroup +++ /dev/null @@ -1,3 +0,0 @@ -{ - "zarr_format": 2 -} \ No newline at end of file diff --git a/tests/input/my_container_xarray.zarr/.zmetadata b/tests/input/my_container_xarray.zarr/.zmetadata deleted file mode 100644 index 9d30fbc..0000000 --- a/tests/input/my_container_xarray.zarr/.zmetadata +++ /dev/null @@ -1,161 +0,0 @@ -{ - "metadata": { - ".zattrs": { - "name": "my_container" - }, - ".zgroup": { - "zarr_format": 2 - }, - "latitude_series/.zarray": { - "chunks": [ - 2, - 2 - ], - "compressor": { - "blocksize": 0, - "clevel": 5, - "cname": "lz4", - "id": "blosc", - "shuffle": 1 - }, - "dtype": " Date: Mon, 5 Aug 2024 16:22:20 +0200 Subject: [PATCH 27/38] added name to data arrays --- src/linkml_arrays/dumpers/xarray_dumpers.py | 1 + tests/input/my_container.nc | Bin 0 -> 16536 bytes tests/input/my_container_xarray.zarr/.zattrs | 3 + tests/input/my_container_xarray.zarr/.zgroup | 3 + .../input/my_container_xarray.zarr/.zmetadata | 163 ++++++++++++++++++ .../latitude_series/.zarray | 22 +++ .../latitude_series/.zattrs | 7 + .../latitude_series/0.0 | Bin 0 -> 48 bytes .../longitude_series/.zarray | 22 +++ .../longitude_series/.zattrs | 7 + .../longitude_series/0.0 | Bin 0 -> 48 bytes .../temperature_dataset/.zattrs | 7 + .../temperature_dataset/.zgroup | 3 + .../temperature_dataset/date/.zarray | 20 +++ .../temperature_dataset/date/.zattrs | 7 + .../temperature_dataset/date/0 | Bin 0 -> 32 bytes .../temperature_dataset/day_in_d/.zarray | 20 +++ .../temperature_dataset/day_in_d/.zattrs | 5 + .../temperature_dataset/day_in_d/0 | Bin 0 -> 24 bytes .../temperatures_in_K/.zarray | 24 +++ .../temperatures_in_K/.zattrs | 8 + .../temperatures_in_K/0.0.0 | Bin 0 -> 80 bytes 22 files changed, 322 insertions(+) create mode 100644 tests/input/my_container.nc create mode 100644 tests/input/my_container_xarray.zarr/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/.zgroup create mode 100644 tests/input/my_container_xarray.zarr/.zmetadata create mode 100644 tests/input/my_container_xarray.zarr/latitude_series/.zarray create mode 100644 tests/input/my_container_xarray.zarr/latitude_series/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/latitude_series/0.0 create mode 100644 tests/input/my_container_xarray.zarr/longitude_series/.zarray create mode 100644 tests/input/my_container_xarray.zarr/longitude_series/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/longitude_series/0.0 create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/.zgroup create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/date/.zarray create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/date/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/date/0 create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zarray create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/0 create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zarray create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/0.0.0 diff --git a/src/linkml_arrays/dumpers/xarray_dumpers.py b/src/linkml_arrays/dumpers/xarray_dumpers.py index 61b3fbd..4ffe1f3 100644 --- a/src/linkml_arrays/dumpers/xarray_dumpers.py +++ b/src/linkml_arrays/dumpers/xarray_dumpers.py @@ -86,6 +86,7 @@ def _iterate_element( data_dict = vars(v) data_dict["data"] = np.array(data_dict.pop("values")) data_dict["dims"] = [dims[i] for i in range(data_dict["data"].shape[0])] + data_dict["attrs"] = {"name": v.name} dataarray = xr.DataArray.from_dict(d=data_dict) datatree[k] = dataarray else: diff --git a/tests/input/my_container.nc b/tests/input/my_container.nc new file mode 100644 index 0000000000000000000000000000000000000000..3ac46a1b2bdcf8f664065e4ecf6f0689e87eaa87 GIT binary patch literal 16536 zcmeHOS!i5U7(RD0NvG}DOl)oAg5J7TtZ}jwms)$&=ljpy-P_f3(xTHADY#fnMO8vS%FjXLo_07y{1U%I9s=Z+-mYzt)x+PsI#~Vv zK618BUsrFkiQ4IMQAAlta>^N0Go|VxYI+Ls#~q}zRJ~fJVk+;Bc<`TUS-L@JlvYG> zaQv)P93BqRVF}&(i%hkyK`c2A-G4g!?qy*@zdDt@ttOPkl9%7RR5$&k8!W3CVHVW{ zE~0-YW!*9q+_ds6-9V*mwIZfgj8m%m7-Axkh|Y*Q)T#1moc(vBMR2JP#-#&EEwzN& z8dK?%=MQ8CJG!zX*$jmzsOuChQIjUo^>Nr?OV>*E$fH7?*9mW1V9*rZkIwW>7^3_?&hEyUd>p<{$ z=eas&dNI%0&0KwU0ef$o5~}q4RBE3IrKvK*UHV$;>n)wV*RuAtD>*^Rq-!`E4^~ug zXw12O)*s7w>5^B>dZn{?is{sUT=Kw|(1dw{`OrwSskv$v^=<0kPU{xMVV13+FK`K3 zJqWf6a0D-4toTuA`OQDaP@3Q=tEFHa{}A&ZweYDH+q!$Yw{@pFyVG2Y<@z(l{{3$Z|E96s3M4Gr3F6c$S@Svz zg<>X~cYUv7s43n&$dQ9_(nQmkyXucQYiewqscU89*lN3S&xZGL$#m3MXLmOc$1 z`hc83sW(RQkCf8`g}m=(^Ij407-VqLo?A=?8Q~KCwwViN9;(Hh4f zB1PXqqo=BVxk7$O&o&dKMY6Hl7e0pwgb0KPgb0KPgb0KPgb0KPgb0KPgb0KP{J#;< z1jD?Ejkp6wz@mTmAl=hF*<9`hH#g=nrcJXDfQS)}fm8iG4lN*|YNPHoqhRO(unc=A zy6!vPbfs-`n~XSYx^l6h_4AzF(3PJxu=nXHp+m+D@uUfzjjp_DVfzp0*@knF$chSU zlc;bdhM5!wE%N+zPwAnsLuWXGtRx5?-QlLIAeOYeHHy;yTdX9IgA+{Ir<8lg;;kB6 z=lD&QYC9Jww8SSvd-VWWhFV%tnUdBnA==_MqTj%F!j6+pb#5&dM!lj>bT;K!N*R*K ziR|R=^olUvtZQ36yoM|~WMW#^+S1;VTs@o_Ttkno9W96&Ew5{DX>DyuHh;AHdz~@- z2@wbpINk{Sx!%;kVHq|lY`>FM_UV7nd;30QAxJ0vWj zJkBcQKgk%?-0Gb<|g!UO6(-*Y(AawhUUD>fCG`V71ozH zS;1hhYGQ3-B@uO8^qg9;bBIJsX$bdYFBt?_t0$P9Jj4EO(HUx@_&# zcE}y11xI)`==EVep-IB{Yv?;N?C7sQXdJI?v`r;5-y#cF!hvh>E|XBex{M6 zzhsxPv;*3cRk4%FEA&Uv#>Ng8;NV7!g`79)X9vUL?A>UL?A>UL?A>UL?A>UL?A@q7$U&LQqryQ4T zslh-K_#UCzPsA5o;*VcPw$;McWamHu0;lU5(dy?Re|>+W^9)xsIY$q%DO zgEnf6<+DCa=5v`wz$nQG0?P!`NIhv;$fglD=jAi5SVZR320lr&frG+4s#6CI1Na4n zXg3S1)VTU3eK}+HSM}oCF_!21YL(0ukysz_3|4P`uUA0>@IC^!kO*(|THKhTroJpT zSMPzh6THD~uF1W>kHj%_wNm`dq}tOcewnco4p&|HNFn(T@dEZ% literal 0 HcmV?d00001 diff --git a/tests/input/my_container_xarray.zarr/.zattrs b/tests/input/my_container_xarray.zarr/.zattrs new file mode 100644 index 0000000..060eade --- /dev/null +++ b/tests/input/my_container_xarray.zarr/.zattrs @@ -0,0 +1,3 @@ +{ + "name": "my_container" +} \ No newline at end of file diff --git a/tests/input/my_container_xarray.zarr/.zgroup b/tests/input/my_container_xarray.zarr/.zgroup new file mode 100644 index 0000000..3b7daf2 --- /dev/null +++ b/tests/input/my_container_xarray.zarr/.zgroup @@ -0,0 +1,3 @@ +{ + "zarr_format": 2 +} \ No newline at end of file diff --git a/tests/input/my_container_xarray.zarr/.zmetadata b/tests/input/my_container_xarray.zarr/.zmetadata new file mode 100644 index 0000000..57453e3 --- /dev/null +++ b/tests/input/my_container_xarray.zarr/.zmetadata @@ -0,0 +1,163 @@ +{ + "metadata": { + ".zattrs": { + "name": "my_container" + }, + ".zgroup": { + "zarr_format": 2 + }, + "latitude_series/.zarray": { + "chunks": [ + 2, + 2 + ], + "compressor": { + "blocksize": 0, + "clevel": 5, + "cname": "lz4", + "id": "blosc", + "shuffle": 1 + }, + "dtype": " Date: Tue, 6 Aug 2024 10:00:56 +0200 Subject: [PATCH 28/38] remove outdated data --- tests/input/my_container.nc | Bin 16536 -> 0 bytes tests/input/my_container_xarray.zarr/.zattrs | 3 - tests/input/my_container_xarray.zarr/.zgroup | 3 - .../input/my_container_xarray.zarr/.zmetadata | 163 ------------------ .../latitude_series/.zarray | 22 --- .../latitude_series/.zattrs | 7 - .../latitude_series/0.0 | Bin 48 -> 0 bytes .../longitude_series/.zarray | 22 --- .../longitude_series/.zattrs | 7 - .../longitude_series/0.0 | Bin 48 -> 0 bytes .../temperature_dataset/.zattrs | 7 - .../temperature_dataset/.zgroup | 3 - .../temperature_dataset/date/.zarray | 20 --- .../temperature_dataset/date/.zattrs | 7 - .../temperature_dataset/date/0 | Bin 32 -> 0 bytes .../temperature_dataset/day_in_d/.zarray | 20 --- .../temperature_dataset/day_in_d/.zattrs | 5 - .../temperature_dataset/day_in_d/0 | Bin 24 -> 0 bytes .../temperatures_in_K/.zarray | 24 --- .../temperatures_in_K/.zattrs | 8 - .../temperatures_in_K/0.0.0 | Bin 80 -> 0 bytes 21 files changed, 321 deletions(-) delete mode 100644 tests/input/my_container.nc delete mode 100644 tests/input/my_container_xarray.zarr/.zattrs delete mode 100644 tests/input/my_container_xarray.zarr/.zgroup delete mode 100644 tests/input/my_container_xarray.zarr/.zmetadata delete mode 100644 tests/input/my_container_xarray.zarr/latitude_series/.zarray delete mode 100644 tests/input/my_container_xarray.zarr/latitude_series/.zattrs delete mode 100644 tests/input/my_container_xarray.zarr/latitude_series/0.0 delete mode 100644 tests/input/my_container_xarray.zarr/longitude_series/.zarray delete mode 100644 tests/input/my_container_xarray.zarr/longitude_series/.zattrs delete mode 100644 tests/input/my_container_xarray.zarr/longitude_series/0.0 delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/.zattrs delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/.zgroup delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/date/.zarray delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/date/.zattrs delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/date/0 delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zarray delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zattrs delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/0 delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zarray delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zattrs delete mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/0.0.0 diff --git a/tests/input/my_container.nc b/tests/input/my_container.nc deleted file mode 100644 index 3ac46a1b2bdcf8f664065e4ecf6f0689e87eaa87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16536 zcmeHOS!i5U7(RD0NvG}DOl)oAg5J7TtZ}jwms)$&=ljpy-P_f3(xTHADY#fnMO8vS%FjXLo_07y{1U%I9s=Z+-mYzt)x+PsI#~Vv zK618BUsrFkiQ4IMQAAlta>^N0Go|VxYI+Ls#~q}zRJ~fJVk+;Bc<`TUS-L@JlvYG> zaQv)P93BqRVF}&(i%hkyK`c2A-G4g!?qy*@zdDt@ttOPkl9%7RR5$&k8!W3CVHVW{ zE~0-YW!*9q+_ds6-9V*mwIZfgj8m%m7-Axkh|Y*Q)T#1moc(vBMR2JP#-#&EEwzN& z8dK?%=MQ8CJG!zX*$jmzsOuChQIjUo^>Nr?OV>*E$fH7?*9mW1V9*rZkIwW>7^3_?&hEyUd>p<{$ z=eas&dNI%0&0KwU0ef$o5~}q4RBE3IrKvK*UHV$;>n)wV*RuAtD>*^Rq-!`E4^~ug zXw12O)*s7w>5^B>dZn{?is{sUT=Kw|(1dw{`OrwSskv$v^=<0kPU{xMVV13+FK`K3 zJqWf6a0D-4toTuA`OQDaP@3Q=tEFHa{}A&ZweYDH+q!$Yw{@pFyVG2Y<@z(l{{3$Z|E96s3M4Gr3F6c$S@Svz zg<>X~cYUv7s43n&$dQ9_(nQmkyXucQYiewqscU89*lN3S&xZGL$#m3MXLmOc$1 z`hc83sW(RQkCf8`g}m=(^Ij407-VqLo?A=?8Q~KCwwViN9;(Hh4f zB1PXqqo=BVxk7$O&o&dKMY6Hl7e0pwgb0KPgb0KPgb0KPgb0KPgb0KPgb0KP{J#;< z1jD?Ejkp6wz@mTmAl=hF*<9`hH#g=nrcJXDfQS)}fm8iG4lN*|YNPHoqhRO(unc=A zy6!vPbfs-`n~XSYx^l6h_4AzF(3PJxu=nXHp+m+D@uUfzjjp_DVfzp0*@knF$chSU zlc;bdhM5!wE%N+zPwAnsLuWXGtRx5?-QlLIAeOYeHHy;yTdX9IgA+{Ir<8lg;;kB6 z=lD&QYC9Jww8SSvd-VWWhFV%tnUdBnA==_MqTj%F!j6+pb#5&dM!lj>bT;K!N*R*K ziR|R=^olUvtZQ36yoM|~WMW#^+S1;VTs@o_Ttkno9W96&Ew5{DX>DyuHh;AHdz~@- z2@wbpINk{Sx!%;kVHq|lY`>FM_UV7nd;30QAxJ0vWj zJkBcQKgk%?-0Gb<|g!UO6(-*Y(AawhUUD>fCG`V71ozH zS;1hhYGQ3-B@uO8^qg9;bBIJsX$bdYFBt?_t0$P9Jj4EO(HUx@_&# zcE}y11xI)`==EVep-IB{Yv?;N?C7sQXdJI?v`r;5-y#cF!hvh>E|XBex{M6 zzhsxPv;*3cRk4%FEA&Uv#>Ng8;NV7!g`79)X9vUL?A>UL?A>UL?A>UL?A>UL?A@q7$U&LQqryQ4T zslh-K_#UCzPsA5o;*VcPw$;McWamHu0;lU5(dy?Re|>+W^9)xsIY$q%DO zgEnf6<+DCa=5v`wz$nQG0?P!`NIhv;$fglD=jAi5SVZR320lr&frG+4s#6CI1Na4n zXg3S1)VTU3eK}+HSM}oCF_!21YL(0ukysz_3|4P`uUA0>@IC^!kO*(|THKhTroJpT zSMPzh6THD~uF1W>kHj%_wNm`dq}tOcewnco4p&|HNFn(T@dEZ% diff --git a/tests/input/my_container_xarray.zarr/.zattrs b/tests/input/my_container_xarray.zarr/.zattrs deleted file mode 100644 index 060eade..0000000 --- a/tests/input/my_container_xarray.zarr/.zattrs +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "my_container" -} \ No newline at end of file diff --git a/tests/input/my_container_xarray.zarr/.zgroup b/tests/input/my_container_xarray.zarr/.zgroup deleted file mode 100644 index 3b7daf2..0000000 --- a/tests/input/my_container_xarray.zarr/.zgroup +++ /dev/null @@ -1,3 +0,0 @@ -{ - "zarr_format": 2 -} \ No newline at end of file diff --git a/tests/input/my_container_xarray.zarr/.zmetadata b/tests/input/my_container_xarray.zarr/.zmetadata deleted file mode 100644 index 57453e3..0000000 --- a/tests/input/my_container_xarray.zarr/.zmetadata +++ /dev/null @@ -1,163 +0,0 @@ -{ - "metadata": { - ".zattrs": { - "name": "my_container" - }, - ".zgroup": { - "zarr_format": 2 - }, - "latitude_series/.zarray": { - "chunks": [ - 2, - 2 - ], - "compressor": { - "blocksize": 0, - "clevel": 5, - "cname": "lz4", - "id": "blosc", - "shuffle": 1 - }, - "dtype": " Date: Tue, 6 Aug 2024 10:31:55 +0200 Subject: [PATCH 29/38] move refernce date to coords.attrs --- src/linkml_arrays/dumpers/xarray_dumpers.py | 5 +---- tests/test_dumpers/test_dumpers.py | 8 ++++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/linkml_arrays/dumpers/xarray_dumpers.py b/src/linkml_arrays/dumpers/xarray_dumpers.py index 4ffe1f3..51e5607 100644 --- a/src/linkml_arrays/dumpers/xarray_dumpers.py +++ b/src/linkml_arrays/dumpers/xarray_dumpers.py @@ -56,10 +56,7 @@ def _create_node(model, schemaview): else: if isinstance(value, str): # can't use timestamp here as it does not serialize, potentially add with 'data' dims as coord - try: - node_dict["attrs"][key] = value - except KeyError: - node_dict["attrs"] = {key: value} + node_dict["coords"][k].update({"attrs": {key: value}}) else: # conversion factor node_dict["attrs"][key] = value diff --git a/tests/test_dumpers/test_dumpers.py b/tests/test_dumpers/test_dumpers.py index 4a697ea..bca22da 100644 --- a/tests/test_dumpers/test_dumpers.py +++ b/tests/test_dumpers/test_dumpers.py @@ -129,7 +129,7 @@ def test_yaml_xarray_dumper(): def test_xarray_zarr_dumper(tmp_path): container = _create_container() schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") - output_file_path = tmp_path / "my_container.zarr" + output_file_path = INPUT_DIR / "my_container_xarray.zarr" XarrayZarrDumper().dumps(container, schemaview=schemaview, output_file_path=output_file_path) assert os.path.exists(output_file_path) @@ -145,6 +145,7 @@ def test_xarray_zarr_dumper(tmp_path): root["temperature_dataset/date"][:], np.array([0, 1]) ) assert root["temperature_dataset/date"].attrs['units'] == "days since 2020-01-01 00:00:00" + assert root["temperature_dataset/day_in_d"].attrs["reference_date"] == '2020-01-01' np.testing.assert_array_equal(root["temperature_dataset/day_in_d"][:], [0, 1]) np.testing.assert_array_equal( root["temperature_dataset/temperatures_in_K"][:], @@ -153,7 +154,6 @@ def test_xarray_zarr_dumper(tmp_path): assert root["temperature_dataset"].attrs["name"] == "my_temperature" assert root["temperature_dataset"].attrs["conversion_factor"] == 1000 # Check possibility of reference date being another coords with dims set to date. - assert root["temperature_dataset"].attrs["reference_date"] == "2020-01-01" assert root["temperature_dataset"].attrs["latitude_in_deg"] == "my_latitude" assert root["temperature_dataset"].attrs["longitude_in_deg"] == "my_longitude" @@ -161,7 +161,7 @@ def test_xarray_zarr_dumper(tmp_path): def test_xarray_netcdf_dumper(tmp_path): container = _create_container() schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") - output_file_path = tmp_path / "my_container.nc" + output_file_path = INPUT_DIR / "my_container.nc" XarrayNetCDFDumper().dumps(container, schemaview=schemaview, output_file_path=output_file_path) assert os.path.exists(output_file_path) @@ -177,13 +177,13 @@ def test_xarray_netcdf_dumper(tmp_path): dates, np.array(["2020-01-01", "2020-01-02"]) ) np.testing.assert_array_equal(datatree["temperature_dataset"]["day_in_d"].values, [0, 1]) + assert datatree["temperature_dataset"]["day_in_d"].attrs["reference_date"] == '2020-01-01' np.testing.assert_array_equal(datatree["temperature_dataset"]["temperatures_in_K"].values, [[[0, 1], [2, 3]], [[4, 5], [6, 7]]]) assert datatree["temperature_dataset"].attrs["name"] == "my_temperature" assert datatree["temperature_dataset"].attrs["conversion_factor"] == 1000 # Check possibility of reference date being another coords with dims set to date. - assert datatree["temperature_dataset"].attrs["reference_date"] == "2020-01-01" assert datatree["temperature_dataset"].attrs["latitude_in_deg"] == "my_latitude" assert datatree["temperature_dataset"].attrs["longitude_in_deg"] == "my_longitude" From f5ce0f9ffd6014e93d9de086cfd2e0ea2d6081cc Mon Sep 17 00:00:00 2001 From: Wouter-Michiel Vierdag Date: Tue, 6 Aug 2024 12:36:32 +0200 Subject: [PATCH 30/38] move conversion factor to array attributes --- src/linkml_arrays/dumpers/xarray_dumpers.py | 4 ++-- tests/test_dumpers/test_dumpers.py | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/linkml_arrays/dumpers/xarray_dumpers.py b/src/linkml_arrays/dumpers/xarray_dumpers.py index 51e5607..396bf90 100644 --- a/src/linkml_arrays/dumpers/xarray_dumpers.py +++ b/src/linkml_arrays/dumpers/xarray_dumpers.py @@ -52,14 +52,14 @@ def _create_node(model, schemaview): dims = [dim.alias for dim in dimensions_expressions] array = np.array(value) node_dict["dims"] = {dim: array.shape[i] for i, dim in enumerate(dims)} - node_dict["data_vars"] = {k: {"data": array, "dims": list(node_dict["dims"].keys())}} + node_dict["data_vars"][k].update({"data": array, "dims": list(node_dict["dims"].keys())}) else: if isinstance(value, str): # can't use timestamp here as it does not serialize, potentially add with 'data' dims as coord node_dict["coords"][k].update({"attrs": {key: value}}) else: # conversion factor - node_dict["attrs"][key] = value + node_dict["data_vars"] = {k: {"attrs": {key: value}}} return xr.Dataset.from_dict(node_dict) diff --git a/tests/test_dumpers/test_dumpers.py b/tests/test_dumpers/test_dumpers.py index bca22da..e651fad 100644 --- a/tests/test_dumpers/test_dumpers.py +++ b/tests/test_dumpers/test_dumpers.py @@ -110,7 +110,7 @@ def test_yaml_hdf5_dumper(): assert actual == expected -def test_yaml_xarray_dumper(): +def test_yaml_xarray_netcdf_dumper(): """Test YamlNumpyDumper dumping to a YAML file and HDF5 datasets in a directory.""" container = _create_container() @@ -129,7 +129,7 @@ def test_yaml_xarray_dumper(): def test_xarray_zarr_dumper(tmp_path): container = _create_container() schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") - output_file_path = INPUT_DIR / "my_container_xarray.zarr" + output_file_path = tmp_path / "my_container_xarray.zarr" XarrayZarrDumper().dumps(container, schemaview=schemaview, output_file_path=output_file_path) assert os.path.exists(output_file_path) @@ -151,8 +151,9 @@ def test_xarray_zarr_dumper(tmp_path): root["temperature_dataset/temperatures_in_K"][:], [[[0, 1], [2, 3]], [[4, 5], [6, 7]]], ) + assert root["temperature_dataset/temperatures_in_K"].attrs["conversion_factor"] == 1000 + assert root["temperature_dataset"].attrs["name"] == "my_temperature" - assert root["temperature_dataset"].attrs["conversion_factor"] == 1000 # Check possibility of reference date being another coords with dims set to date. assert root["temperature_dataset"].attrs["latitude_in_deg"] == "my_latitude" assert root["temperature_dataset"].attrs["longitude_in_deg"] == "my_longitude" @@ -161,7 +162,7 @@ def test_xarray_zarr_dumper(tmp_path): def test_xarray_netcdf_dumper(tmp_path): container = _create_container() schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") - output_file_path = INPUT_DIR / "my_container.nc" + output_file_path = tmp_path / "my_container.nc" XarrayNetCDFDumper().dumps(container, schemaview=schemaview, output_file_path=output_file_path) assert os.path.exists(output_file_path) @@ -180,9 +181,9 @@ def test_xarray_netcdf_dumper(tmp_path): assert datatree["temperature_dataset"]["day_in_d"].attrs["reference_date"] == '2020-01-01' np.testing.assert_array_equal(datatree["temperature_dataset"]["temperatures_in_K"].values, [[[0, 1], [2, 3]], [[4, 5], [6, 7]]]) + assert datatree["temperature_dataset"].data_vars["temperatures_in_K"].attrs["conversion_factor"] == 1000 assert datatree["temperature_dataset"].attrs["name"] == "my_temperature" - assert datatree["temperature_dataset"].attrs["conversion_factor"] == 1000 # Check possibility of reference date being another coords with dims set to date. assert datatree["temperature_dataset"].attrs["latitude_in_deg"] == "my_latitude" assert datatree["temperature_dataset"].attrs["longitude_in_deg"] == "my_longitude" From 0d213c350d6e10cf8bb43f37b0bea45217edf0c2 Mon Sep 17 00:00:00 2001 From: Wouter-Michiel Vierdag Date: Tue, 6 Aug 2024 12:37:07 +0200 Subject: [PATCH 31/38] add updated data --- tests/input/my_container.nc | Bin 0 -> 16536 bytes tests/input/my_container_xarray.zarr/.zattrs | 3 + tests/input/my_container_xarray.zarr/.zgroup | 3 + .../input/my_container_xarray.zarr/.zmetadata | 163 ++++++++++++++++++ .../latitude_series/.zarray | 22 +++ .../latitude_series/.zattrs | 7 + .../latitude_series/0.0 | Bin 0 -> 48 bytes .../longitude_series/.zarray | 22 +++ .../longitude_series/.zattrs | 7 + .../longitude_series/0.0 | Bin 0 -> 48 bytes .../temperature_dataset/.zattrs | 5 + .../temperature_dataset/.zgroup | 3 + .../temperature_dataset/date/.zarray | 20 +++ .../temperature_dataset/date/.zattrs | 7 + .../temperature_dataset/date/0 | Bin 0 -> 32 bytes .../temperature_dataset/day_in_d/.zarray | 20 +++ .../temperature_dataset/day_in_d/.zattrs | 6 + .../temperature_dataset/day_in_d/0 | Bin 0 -> 24 bytes .../temperatures_in_K/.zarray | 24 +++ .../temperatures_in_K/.zattrs | 9 + .../temperatures_in_K/0.0.0 | Bin 0 -> 80 bytes 21 files changed, 321 insertions(+) create mode 100644 tests/input/my_container.nc create mode 100644 tests/input/my_container_xarray.zarr/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/.zgroup create mode 100644 tests/input/my_container_xarray.zarr/.zmetadata create mode 100644 tests/input/my_container_xarray.zarr/latitude_series/.zarray create mode 100644 tests/input/my_container_xarray.zarr/latitude_series/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/latitude_series/0.0 create mode 100644 tests/input/my_container_xarray.zarr/longitude_series/.zarray create mode 100644 tests/input/my_container_xarray.zarr/longitude_series/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/longitude_series/0.0 create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/.zgroup create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/date/.zarray create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/date/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/date/0 create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zarray create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/0 create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zarray create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zattrs create mode 100644 tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/0.0.0 diff --git a/tests/input/my_container.nc b/tests/input/my_container.nc new file mode 100644 index 0000000000000000000000000000000000000000..f556600db109ecd15fd237cb4bae021bac585086 GIT binary patch literal 16536 zcmeHOU2GKB6~41xmIc9{9B_p?~4OZ>&(Z>Cd%& zFX-;sY3B?sDR^oKQd$n>s5I%3#{(2(}ByMhm zfA!Pb4{3yH^KK$>m8G}htUVmEr|tV`2Ov4BYnkf$xQX_38e0H++9(~>UOpU8p|rjv zc?Bm0*<-F^L< z`+Xa9gRE(n*oX@&E;y_hcY{JOmG^RGuT=2L>$Qq;>wj%|`cL2lJ%K)~AZ==^)1rZ0 zL;L95qB>~VYWfE*VW$VdRt1jW1&q}^2Ce-3;uJ;`Jms_$tW)nn{~<*{Qta*B*}Jzl z+ufVfQmmp0L5jQ^xMeQ@?@vu4ZB>~~YZ)!9Gsc*93Wc1Nf+Nq8`kXN?JJi^WpD;JblWWY;79-9nF=5xSwkR2}NZyQ}OdZ?D^ zZr~@%!6il`XYmt0LWSQF!>3NZ@uEM<+GeVlWLDJYqU#8O2!RNJ2!RNJ2!RNJ2!RNJ z2!RNJ2!RNJ|8E4?z_4J$M#_Ojz@oQ%7~OL_3*+MtyW>-y#&qQz20+w^jX}4%d>C9{ zglf!m&lUw^9)OkM)X|>r-Dq>AZR+Z%}`MZS99-CG=YTOVnn9{k- zm5(gx{3}*AaXT7Wak1K@tF{tjnG_3J?3IUpz+2%UcesXDNf>x|!Oc>EEN}niBu4vu zStWrSl3=QHO1a-%HptjIH%?jV{ai4irQaVt#T%p*Qd)6QN$YVjw57g{b%V7NewI`0E5UiQee342ZRF7*7t{8R_RjXq=CS<9HoENSYDd*% zWqW6PM@M_6?evikxnuMbArK*OqY=1xzmdSvG-+ts&{jj+3|(ia?eHBp+`n(`V4>dW zng0Ez(3W^ez*3pn41+B$4E=yP0;!222&+3XB=vdt@~wrrrzZ{M4vu$)BHFkev(|l z&*i<*d1D#yKqPa8_a#MMF!-xhYHs2s5q5g$dAZ`wAzbko(Y5}Awb$P7uGG?dv_Kyi zxg@e79=;>!u@!hV=8t1!=+<@fMmAh}?YaKygDiVE!@R$Z#EvNS8?%$2xy}e-^QZnyW z_#iyHT^C#$jT!aOdHhxvl((Hl(I`kbK#;DM8YP|MUAWO;7{}p(l_Ax)%S7m=(2Mk} zQJW`qcXPWtai7jUDS+{!m?qQ6`IgJSpH@(p35y@VjTedh{dG6K8fszj0P?2FFD$x$ z^_>;`bfBUr4?+?4|nQbY3{y+7zd&<$X7E4Zw@`x@;up4B`F9c<3 zFyDuvu>Z&o0;g0TeY{3omN1uLcii*yE`Je2mGg3gl}EV2Vgx;CQs=&bzDk|dgyJIP zqDIf{fA;UJ7yGbl7y3z)=!H<&E^*D~Uvi@~{#g?^0NHC0{X@uNeQwdn7JU;-kQ;G_ zgQ7ruRk1|Q^Ny@j%5aNTCUsBG}L`mbwxl@rR*852ssUpI$T|~U5ab& zQ=GMf=+WpYE*f1=W%jV2>bu8AW3fM~g;HvjT+F7AK9JhT>-QeH7FeGDh0h%2{DzJp biH}0(lzRCm?_}iq=AsLYBfws%C0u_3)fy@L literal 0 HcmV?d00001 diff --git a/tests/input/my_container_xarray.zarr/.zattrs b/tests/input/my_container_xarray.zarr/.zattrs new file mode 100644 index 0000000..060eade --- /dev/null +++ b/tests/input/my_container_xarray.zarr/.zattrs @@ -0,0 +1,3 @@ +{ + "name": "my_container" +} \ No newline at end of file diff --git a/tests/input/my_container_xarray.zarr/.zgroup b/tests/input/my_container_xarray.zarr/.zgroup new file mode 100644 index 0000000..3b7daf2 --- /dev/null +++ b/tests/input/my_container_xarray.zarr/.zgroup @@ -0,0 +1,3 @@ +{ + "zarr_format": 2 +} \ No newline at end of file diff --git a/tests/input/my_container_xarray.zarr/.zmetadata b/tests/input/my_container_xarray.zarr/.zmetadata new file mode 100644 index 0000000..57155c5 --- /dev/null +++ b/tests/input/my_container_xarray.zarr/.zmetadata @@ -0,0 +1,163 @@ +{ + "metadata": { + ".zattrs": { + "name": "my_container" + }, + ".zgroup": { + "zarr_format": 2 + }, + "latitude_series/.zarray": { + "chunks": [ + 2, + 2 + ], + "compressor": { + "blocksize": 0, + "clevel": 5, + "cname": "lz4", + "id": "blosc", + "shuffle": 1 + }, + "dtype": " Date: Tue, 6 Aug 2024 13:06:52 +0200 Subject: [PATCH 32/38] add yaml xarray zarr dumper --- src/linkml_arrays/dumpers/__init__.py | 3 +- .../dumpers/yaml_xarray_dumpers.py | 29 +++++++++++++++- tests/input/container_yaml_xarray_zarr.yaml | 34 +++++++++++++++++++ tests/test_dumpers/test_dumpers.py | 20 +++++++++-- 4 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 tests/input/container_yaml_xarray_zarr.yaml diff --git a/src/linkml_arrays/dumpers/__init__.py b/src/linkml_arrays/dumpers/__init__.py index be8f94b..0402927 100644 --- a/src/linkml_arrays/dumpers/__init__.py +++ b/src/linkml_arrays/dumpers/__init__.py @@ -5,7 +5,7 @@ from .yaml_dumper import YamlDumper from .yaml_hdf5_dumper import YamlHdf5Dumper from .yaml_numpy_dumper import YamlNumpyDumper -from .yaml_xarray_dumpers import YamlXarrayNetCDFDumper +from .yaml_xarray_dumpers import YamlXarrayNetCDFDumper, YamlXarrayZarrDumper from .zarr_directory_store_dumper import ZarrDirectoryStoreDumper __all__ = [ @@ -17,4 +17,5 @@ "YamlNumpyDumper", "ZarrDirectoryStoreDumper", "YamlXarrayNetCDFDumper", + "YamlXarrayZarrDumper", ] diff --git a/src/linkml_arrays/dumpers/yaml_xarray_dumpers.py b/src/linkml_arrays/dumpers/yaml_xarray_dumpers.py index b6c0328..5c81651 100644 --- a/src/linkml_arrays/dumpers/yaml_xarray_dumpers.py +++ b/src/linkml_arrays/dumpers/yaml_xarray_dumpers.py @@ -12,7 +12,7 @@ class YamlXarrayNetCDFDumper(YamlArrayFileDumper): """Dumper class for LinkML models to YAML with paths to .nc file. - Each array is written to an netcdf dataset at path "/data" in a new .nc file. + Each array is written to a netcdf dataset at path "/data" in a new .nc file. """ FILE_SUFFIX = ".nc" # used in parent class @@ -33,4 +33,31 @@ def write_array( data_array = xr.DataArray(data=array) data_array.to_netcdf(output_file_path, engine="h5netcdf") + return output_file_path + + +class YamlXarrayZarrDumper(YamlArrayFileDumper): + """Dumper class for LinkML models to YAML with paths to .zarr file. + + Each array is written to a zarr dataset at path "/data" in a new .zarr file. + """ + + FILE_SUFFIX = ".zarr" # used in parent class + FORMAT = "zarr" + + @classmethod + def write_array( + cls, array: Union[List, np.ndarray], output_file_path_no_suffix: Union[str, Path] + ): + """Write an array to a NumPy file.""" + # TODO do not assume that there is only one by this name + # add suffix to the file name + if isinstance(output_file_path_no_suffix, str): + output_file_path_no_suffix = Path(output_file_path_no_suffix) + output_file_path = output_file_path_no_suffix.parent / ( + output_file_path_no_suffix.name + cls.FILE_SUFFIX + ) + + data_array = xr.DataArray(data=array) + data_array.to_zarr(output_file_path) return output_file_path \ No newline at end of file diff --git a/tests/input/container_yaml_xarray_zarr.yaml b/tests/input/container_yaml_xarray_zarr.yaml new file mode 100644 index 0000000..3658193 --- /dev/null +++ b/tests/input/container_yaml_xarray_zarr.yaml @@ -0,0 +1,34 @@ +name: my_container +latitude_series: + name: my_latitude + values: + source: + - file: "./out/my_latitude.values.zarr" + format: zarr +longitude_series: + name: my_longitude + values: + source: + - file: "./out/my_longitude.values.zarr" + format: zarr +temperature_dataset: + date: + values: + source: + - file: "./out/my_temperature.date.values.zarr" + format: zarr + day_in_d: + reference_date: '2020-01-01' + values: + source: + - file: "./out/my_temperature.day_in_d.values.zarr" + format: zarr + latitude_in_deg: my_latitude + longitude_in_deg: my_longitude + name: my_temperature + temperatures_in_K: + conversion_factor: 1000.0 + values: + source: + - file: "./out/my_temperature.temperatures_in_K.values.zarr" + format: zarr diff --git a/tests/test_dumpers/test_dumpers.py b/tests/test_dumpers/test_dumpers.py index e651fad..aa9eca4 100644 --- a/tests/test_dumpers/test_dumpers.py +++ b/tests/test_dumpers/test_dumpers.py @@ -17,7 +17,7 @@ YamlHdf5Dumper, YamlNumpyDumper, ZarrDirectoryStoreDumper, - YamlXarrayNetCDFDumper, XarrayZarrDumper + YamlXarrayNetCDFDumper, XarrayZarrDumper, YamlXarrayZarrDumper ) from tests.array_classes_lol import ( Container, @@ -110,8 +110,24 @@ def test_yaml_hdf5_dumper(): assert actual == expected +def test_yaml_xarray_zarr_dumper(): + """Test YamlXarrayDumper dumping to a YAML file and zarr datasets in a directory.""" + container = _create_container() + + schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") + ret = YamlXarrayZarrDumper().dumps(container, schemaview=schemaview, output_dir="./out") + + # read and compare with the expected YAML file ignoring order of keys + expected_yaml_file = INPUT_DIR / "container_yaml_xarray_zarr.yaml" + yaml = YAML(typ="safe") + with open(expected_yaml_file) as f: + expected = yaml.load(f) # load yaml into dictionary + actual = yaml.load(ret) + assert actual == expected + + def test_yaml_xarray_netcdf_dumper(): - """Test YamlNumpyDumper dumping to a YAML file and HDF5 datasets in a directory.""" + """Test YamlXarrayNetCDFDumper dumping to a YAML file and netcdf datasets in a directory.""" container = _create_container() schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") From 06f527e99d7580a63e15d7feacde8405bb21ccae Mon Sep 17 00:00:00 2001 From: Wouter-Michiel Vierdag Date: Tue, 6 Aug 2024 15:05:53 +0200 Subject: [PATCH 33/38] don't use datetime --- src/linkml_arrays/dumpers/xarray_dumpers.py | 2 +- tests/input/my_container.nc | Bin 16536 -> 16552 bytes .../input/my_container_xarray.zarr/.zmetadata | 6 ++---- .../temperature_dataset/date/.zarray | 2 +- .../temperature_dataset/date/.zattrs | 4 +--- .../temperature_dataset/date/0 | Bin 32 -> 96 bytes tests/test_dumpers/test_dumpers.py | 7 +++---- 7 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/linkml_arrays/dumpers/xarray_dumpers.py b/src/linkml_arrays/dumpers/xarray_dumpers.py index 396bf90..08c6292 100644 --- a/src/linkml_arrays/dumpers/xarray_dumpers.py +++ b/src/linkml_arrays/dumpers/xarray_dumpers.py @@ -32,7 +32,7 @@ def _create_node(model, schemaview): elif isinstance(v, BaseModel): if len(var_dict := vars(v)) == 1: # If values are length 1 we are dealing with coords like date - v = pd.to_datetime(v.values) + v = v.values try: node_dict["coords"][k] = v except KeyError: diff --git a/tests/input/my_container.nc b/tests/input/my_container.nc index f556600db109ecd15fd237cb4bae021bac585086..100f811a26496326c81c37bb378b34ecec60bafb 100644 GIT binary patch delta 447 zcmbQy$he}Bae@Zpiiw)G{O!V<(va}P(nl=aI_>6@_cDcSUe7pP4qd_IP=!YD?4znbnaxg)alvF&yI!VaR+G2bX*sc~M`-#x zdw8=+gN$NiVFgh@z>$(z8K0RKpQ2<75wH(Ba}%VHLkPrYW^8bPh$~F)liE6YioJjc qOeI8|f#LIqV@rT8=VYAh=U}A41r&DBfXE2~DP%r4IDulIzy$#Af@yI8 delta 625 zcmZ3{$T*{sae@ZpjES1I{9j*gOhdvGOCPb!=lg6jc`sAQ=Jkxz<lF=zv zwb@$HoW+iZfsuhhfP;Ynh=9O>ft3R!!oA-7shCc(W}VEVW-13!y+IA4%owT~L|w0nx;8mnEtZK#b@D?MiOEmY1X&D?D;*~5 z*~#);vxTVqoX(^&F+g;)qWX76Z#k&$l*Gznh2qS-v7s@vT(#ULL)Pd9h02qV?AOHXW literal 32 XcmZQ#H0BUsU|;}Y1t5k2MkoUS4JiPC diff --git a/tests/test_dumpers/test_dumpers.py b/tests/test_dumpers/test_dumpers.py index aa9eca4..1195bf5 100644 --- a/tests/test_dumpers/test_dumpers.py +++ b/tests/test_dumpers/test_dumpers.py @@ -158,9 +158,9 @@ def test_xarray_zarr_dumper(tmp_path): # Below reference date seems to be added automatically when using pd.to_datetime np.testing.assert_array_equal( - root["temperature_dataset/date"][:], np.array([0, 1]) + root["temperature_dataset/date"][:], np.array(['2020-01-01', '2020-01-02']) ) - assert root["temperature_dataset/date"].attrs['units'] == "days since 2020-01-01 00:00:00" + assert root["temperature_dataset/day_in_d"].attrs["reference_date"] == '2020-01-01' np.testing.assert_array_equal(root["temperature_dataset/day_in_d"][:], [0, 1]) np.testing.assert_array_equal( @@ -189,9 +189,8 @@ def test_xarray_netcdf_dumper(tmp_path): np.testing.assert_array_equal(datatree["longitude_series"].data, [[5, 6], [7, 8]]) assert list(datatree["temperature_dataset"].coords.keys()) == ['date', 'day_in_d'] - dates = np.datetime_as_string(datatree["temperature_dataset"].coords["date"].values, unit="D") np.testing.assert_array_equal( - dates, np.array(["2020-01-01", "2020-01-02"]) + datatree["temperature_dataset"].coords["date"].values, np.array(["2020-01-01", "2020-01-02"]) ) np.testing.assert_array_equal(datatree["temperature_dataset"]["day_in_d"].values, [0, 1]) assert datatree["temperature_dataset"]["day_in_d"].attrs["reference_date"] == '2020-01-01' From b26372ed61191d072b605846b3fce5b442403305 Mon Sep 17 00:00:00 2001 From: Wouter-Michiel Vierdag Date: Tue, 6 Aug 2024 15:20:56 +0200 Subject: [PATCH 34/38] added xarray zarr loader --- src/linkml_arrays/loaders/__init__.py | 2 ++ src/linkml_arrays/loaders/xarray_loaders.py | 37 +++++++++++++++------ tests/test_loaders/test_loaders.py | 8 +++++ 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/linkml_arrays/loaders/__init__.py b/src/linkml_arrays/loaders/__init__.py index af71135..ae158cc 100644 --- a/src/linkml_arrays/loaders/__init__.py +++ b/src/linkml_arrays/loaders/__init__.py @@ -3,10 +3,12 @@ from .hdf5_loader import Hdf5Loader from .yaml_array_file_loader import YamlArrayFileLoader from .yaml_loader import YamlLoader +from .xarray_loaders import XarrayZarrLoader from .zarr_directory_store_loader import ZarrDirectoryStoreLoader __all__ = [ "Hdf5Loader", + "XarrayZarrLoader", "YamlArrayFileLoader", "YamlLoader", "ZarrDirectoryStoreLoader", diff --git a/src/linkml_arrays/loaders/xarray_loaders.py b/src/linkml_arrays/loaders/xarray_loaders.py index fdd6e09..4b236c0 100644 --- a/src/linkml_arrays/loaders/xarray_loaders.py +++ b/src/linkml_arrays/loaders/xarray_loaders.py @@ -2,7 +2,10 @@ from typing import Type, Union -import zarr +from pathlib import Path +from xarray.backends.api import open_datatree +import xarray as xr +from xarray.core.datatree import DataTree from linkml_runtime import SchemaView from linkml_runtime.linkml_model import ClassDefinition from linkml_runtime.loaders.loader_root import Loader @@ -11,7 +14,7 @@ def _iterate_element( - group: zarr.hierarchy.Group, element_type: ClassDefinition, schemaview: SchemaView + group: DataTree, element_type: ClassDefinition, schemaview: SchemaView ) -> dict: """Recursively iterate through the elements of a LinkML model and load them into a dict. @@ -25,20 +28,32 @@ def _iterate_element( found_slot = schemaview.induced_slot( k, element_type.name ) # assumes the slot name has been written as the name which is OK for now. - if found_slot.array: - assert isinstance(v, zarr.Array) - v = v[()] # read all the values into memory # TODO support lazy loading - elif isinstance(v, zarr.hierarchy.Group): # it's a subgroup + if isinstance(v, xr.DataArray): + if not v.coords: + value_dict = {key: v.attrs[key] for key in v.attrs} + value_dict.update({"values": v.values}) # read all the values into memory # TODO support lazy loading + else: + value_dict = {key: v.attrs[key] for key in v.attrs} + value_dict.update({"values": v.values}) # read all the values into memory # TODO support lazy loading + + + for coord in v.coords: + coordinate_array_dict = {key: value for key, value in v.coords[coord].attrs.items()} + coordinate_array_dict.update({"values": v.coords[coord].values}) + ret_dict[coord] = coordinate_array_dict + + ret_dict[k] = value_dict + + elif isinstance(v, DataTree): # it's a subgroup found_slot_range = schemaview.get_class(found_slot.range) v = _iterate_element(v, found_slot_range, schemaview) - # else: do not transform v - ret_dict[k] = v + ret_dict[k] = v return ret_dict -class ZarrDirectoryStoreLoader(Loader): - """Class for loading a LinkML model from a Zarr directory store.""" +class XarrayZarrLoader(Loader): + """Class for loading a LinkML model from a xarray Zarr directory store.""" def load_any(self, source: str, **kwargs): """Create an instance of the target class from a Zarr directory store.""" @@ -57,7 +72,7 @@ def load( ): """Create an instance of the target class from a Zarr directory store.""" element_type = schemaview.get_class(target_class.__name__) - z = zarr.open(source, mode="r") + z = open_datatree(Path(source), engine="zarr") element = _iterate_element(z, element_type, schemaview) obj = target_class(**element) diff --git a/tests/test_loaders/test_loaders.py b/tests/test_loaders/test_loaders.py index ca6e481..8935048 100644 --- a/tests/test_loaders/test_loaders.py +++ b/tests/test_loaders/test_loaders.py @@ -9,6 +9,7 @@ Hdf5Loader, YamlArrayFileLoader, YamlLoader, + XarrayZarrLoader, ZarrDirectoryStoreLoader, ) from tests.array_classes_lol import ( @@ -94,6 +95,13 @@ def test_hdf5_loader(): _check_container(container) +def test_xarray_zarr_loader(): + """Test loading of pydantic-style classes from xarray zarr datasets.""" + file_path = str(Path(__file__).parent.parent / "input" / "my_container_xarray.zarr") + schemaview = SchemaView(Path(__file__) / "../../input/temperature_schema.yaml") + container = XarrayZarrLoader().loads(file_path, target_class=Container, schemaview=schemaview) + _check_container(container) + def test_zarr_directory_store_loader(): """Test loading of pydantic-style classes from Zarr arrays.""" file_path = str(Path(__file__).parent.parent / "input" / "my_container.zarr") From ffb964573b3618e238215d8f86738bdcd6c6d2d3 Mon Sep 17 00:00:00 2001 From: Wouter-Michiel Vierdag Date: Tue, 6 Aug 2024 17:27:56 +0200 Subject: [PATCH 35/38] added xarray yaml loaders --- src/linkml_arrays/loaders/__init__.py | 3 +- src/linkml_arrays/loaders/xarray_loaders.py | 28 +++++++++++++++++ .../loaders/yaml_array_file_loader.py | 17 +++++++++++ tests/test_loaders/test_loaders.py | 30 +++++++++++++++++++ 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/linkml_arrays/loaders/__init__.py b/src/linkml_arrays/loaders/__init__.py index ae158cc..d86a0c5 100644 --- a/src/linkml_arrays/loaders/__init__.py +++ b/src/linkml_arrays/loaders/__init__.py @@ -3,11 +3,12 @@ from .hdf5_loader import Hdf5Loader from .yaml_array_file_loader import YamlArrayFileLoader from .yaml_loader import YamlLoader -from .xarray_loaders import XarrayZarrLoader +from .xarray_loaders import XarrayZarrLoader, XarrayNetCDFLoader from .zarr_directory_store_loader import ZarrDirectoryStoreLoader __all__ = [ "Hdf5Loader", + "XarrayNetCDFLoader", "XarrayZarrLoader", "YamlArrayFileLoader", "YamlLoader", diff --git a/src/linkml_arrays/loaders/xarray_loaders.py b/src/linkml_arrays/loaders/xarray_loaders.py index 4b236c0..f9a85a4 100644 --- a/src/linkml_arrays/loaders/xarray_loaders.py +++ b/src/linkml_arrays/loaders/xarray_loaders.py @@ -77,3 +77,31 @@ def load( obj = target_class(**element) return obj + + +class XarrayNetCDFLoader(Loader): + """Class for loading a LinkML model from a xarray netcdf store.""" + + def load_any(self, source: str, **kwargs): + """Create an instance of the target class from a netcdf store.""" + return self.load(source, **kwargs) + + def loads(self, source: str, **kwargs): + """Create an instance of the target class from a netcdf store.""" + return self.load(source, **kwargs) + + def load( + self, + source: str, + target_class: Type[Union[YAMLRoot, BaseModel]], + schemaview: SchemaView, + **kwargs, + ): + """Create an instance of the target class from a netcdf store.""" + element_type = schemaview.get_class(target_class.__name__) + # opening with this engine gives problems with permissions at least on windows. + z = open_datatree(Path(source), engine='h5netcdf') + element = _iterate_element(z, element_type, schemaview) + obj = target_class(**element) + + return obj diff --git a/src/linkml_arrays/loaders/yaml_array_file_loader.py b/src/linkml_arrays/loaders/yaml_array_file_loader.py index b2e0fe4..26c9d94 100644 --- a/src/linkml_arrays/loaders/yaml_array_file_loader.py +++ b/src/linkml_arrays/loaders/yaml_array_file_loader.py @@ -11,6 +11,20 @@ from linkml_runtime.utils.yamlutils import YAMLRoot from pydantic import BaseModel from pathlib import Path +import xarray as xr + +def _parse_xarray_dataset(source, k, format): + file_path = source.get("file", None) + if file_path is None: + raise ValueError( + f"Array slot {k}, source {source}, format {format} has no file." + ) + if format == "zarr": + data_set = xr.open_zarr(file_path) + else: + data_set = xr.open_dataset(file_path, engine='h5netcdf') + array_key = list(data_set.data_vars.keys())[0] + return data_set[array_key].values def _iterate_element( @@ -53,6 +67,9 @@ def _iterate_element( array_file_path = file # read all the values into memory TODO: support lazy loading v = np.load(array_file_path) + elif format in ["zarr", "netcdf"]: + v = _parse_xarray_dataset(source, k, format) + elif isinstance(v, dict): found_slot_range = schemaview.get_class(found_slot.range) v = _iterate_element(v, found_slot_range, schemaview) diff --git a/tests/test_loaders/test_loaders.py b/tests/test_loaders/test_loaders.py index 8935048..973efce 100644 --- a/tests/test_loaders/test_loaders.py +++ b/tests/test_loaders/test_loaders.py @@ -9,6 +9,7 @@ Hdf5Loader, YamlArrayFileLoader, YamlLoader, + XarrayNetCDFLoader, XarrayZarrLoader, ZarrDirectoryStoreLoader, ) @@ -87,6 +88,26 @@ def test_yaml_array_file_loader_hdf5(): _check_container(container) +def test_yaml_array_file_loader_xarray_zarr(): + """Test loading of pydantic-style classes from YAML + xarrays stored as .zarr.""" + read_yaml = hbread("container_yaml_xarray_zarr.yaml", base_path=str(Path(__file__) / "../../input")) + schemaview = SchemaView(Path(__file__) / "../../input/temperature_schema.yaml") + container = YamlArrayFileLoader().loads( + read_yaml, target_class=Container, schemaview=schemaview + ) + _check_container(container) + + +def test_yaml_array_file_loader_xarray_netcdf(): + """Test loading of pydantic-style classes from YAML + xarrays stored as .nc.""" + read_yaml = hbread("container_yaml_xarray_netcdf.yaml", base_path=str(Path(__file__) / "../../input")) + schemaview = SchemaView(Path(__file__) / "../../input/temperature_schema.yaml") + container = YamlArrayFileLoader().loads( + read_yaml, target_class=Container, schemaview=schemaview + ) + _check_container(container) + + def test_hdf5_loader(): """Test loading of pydantic-style classes from HDF5 datasets.""" file_path = str(Path(__file__).parent.parent / "input" / "my_container.h5") @@ -102,6 +123,15 @@ def test_xarray_zarr_loader(): container = XarrayZarrLoader().loads(file_path, target_class=Container, schemaview=schemaview) _check_container(container) + +def test_xarray_netcdf_loader(): + """Test loading of pydantic-style classes from xarray zarr datasets.""" + file_path = str(Path(__file__).parent.parent / "input" / "my_container_xarray.zarr") + schemaview = SchemaView(Path(__file__) / "../../input/temperature_schema.yaml") + container = XarrayNetCDFLoader().loads(file_path, target_class=Container, schemaview=schemaview) + _check_container(container) + + def test_zarr_directory_store_loader(): """Test loading of pydantic-style classes from Zarr arrays.""" file_path = str(Path(__file__).parent.parent / "input" / "my_container.zarr") From c0bdd6c4bf17bf7588206a3ae7f6362de5ea331d Mon Sep 17 00:00:00 2001 From: rly Date: Thu, 19 Sep 2024 10:37:40 -0700 Subject: [PATCH 36/38] Update dumpers to write relative to yaml, make loader/dumper tests independent --- poetry.lock | 30 +++- .../dumpers/yaml_array_file_dumper.py | 27 ++- .../ground_truth}/container_yaml.yaml | 0 .../ground_truth}/container_yaml_hdf5.yaml | 10 +- .../ground_truth}/container_yaml_numpy.yaml | 10 +- .../container_yaml_xarray_netcdf.yaml | 10 +- .../container_yaml_xarray_zarr.yaml | 10 +- .../ground_truth}/my_container.h5 | Bin .../ground_truth}/my_container.nc | Bin .../ground_truth}/my_container.zarr/.zattrs | 0 .../ground_truth}/my_container.zarr/.zgroup | 0 .../my_container.zarr/latitude_series/.zattrs | 0 .../my_container.zarr/latitude_series/.zgroup | 0 .../latitude_series/values/.zarray | 0 .../latitude_series/values/0.0 | Bin .../longitude_series/.zattrs | 0 .../longitude_series/.zgroup | 0 .../longitude_series/values/.zarray | 0 .../longitude_series/values/0.0 | Bin .../temperature_dataset/.zattrs | 0 .../temperature_dataset/.zgroup | 0 .../temperature_dataset/date/.zgroup | 0 .../temperature_dataset/date/values/.zarray | 0 .../temperature_dataset/date/values/0 | Bin .../temperature_dataset/day_in_d/.zattrs | 0 .../temperature_dataset/day_in_d/.zgroup | 0 .../day_in_d/values/.zarray | 0 .../temperature_dataset/day_in_d/values/0 | Bin .../temperatures_in_K/.zattrs | 0 .../temperatures_in_K/.zgroup | 0 .../temperatures_in_K/values/.zarray | 0 .../temperatures_in_K/values/0.0.0 | Bin .../my_container_xarray.zarr/.zattrs | 0 .../my_container_xarray.zarr/.zgroup | 0 .../my_container_xarray.zarr/.zmetadata | 0 .../latitude_series/.zarray | 0 .../latitude_series/.zattrs | 0 .../latitude_series/0.0 | Bin .../longitude_series/.zarray | 0 .../longitude_series/.zattrs | 0 .../longitude_series/0.0 | Bin .../temperature_dataset/.zattrs | 0 .../temperature_dataset/.zgroup | 0 .../temperature_dataset/date/.zarray | 0 .../temperature_dataset/date/.zattrs | 0 .../temperature_dataset/date/0 | Bin .../temperature_dataset/day_in_d/.zarray | 0 .../temperature_dataset/day_in_d/.zattrs | 0 .../temperature_dataset/day_in_d/0 | Bin .../temperatures_in_K/.zarray | 0 .../temperatures_in_K/.zattrs | 0 .../temperatures_in_K/0.0.0 | Bin .../ground_truth}/temperature_schema.yaml | 0 .../yaml_hdf5_h5s/my_latitude.values.h5 | Bin 0 -> 2080 bytes .../yaml_hdf5_h5s/my_longitude.values.h5 | Bin 0 -> 2080 bytes .../my_temperature.date.values.h5 | Bin 0 -> 6176 bytes .../my_temperature.day_in_d.values.h5 | Bin 0 -> 2064 bytes ...my_temperature.temperatures_in_K.values.h5 | Bin 0 -> 2112 bytes .../yaml_numpy_npys/my_latitude.values.npy | Bin 0 -> 160 bytes .../yaml_numpy_npys/my_longitude.values.npy | Bin 0 -> 160 bytes .../my_temperature.date.values.npy | Bin 0 -> 208 bytes .../my_temperature.day_in_d.values.npy | Bin 0 -> 144 bytes ...y_temperature.temperatures_in_K.values.npy | Bin 0 -> 192 bytes .../yaml_xarray_ncs/my_latitude.values.nc | Bin 0 -> 8294 bytes .../yaml_xarray_ncs/my_longitude.values.nc | Bin 0 -> 8294 bytes .../my_temperature.date.values.nc | Bin 0 -> 6176 bytes .../my_temperature.day_in_d.values.nc | Bin 0 -> 6160 bytes ...my_temperature.temperatures_in_K.values.nc | Bin 0 -> 8256 bytes .../my_latitude.values.zarr/.zattrs | 1 + .../my_latitude.values.zarr/.zgroup | 3 + .../my_latitude.values.zarr/.zmetadata | 37 ++++ .../__xarray_dataarray_variable__/.zarray | 22 +++ .../__xarray_dataarray_variable__/.zattrs | 6 + .../__xarray_dataarray_variable__/0.0 | Bin 0 -> 48 bytes .../my_longitude.values.zarr/.zattrs | 1 + .../my_longitude.values.zarr/.zgroup | 3 + .../my_longitude.values.zarr/.zmetadata | 37 ++++ .../__xarray_dataarray_variable__/.zarray | 22 +++ .../__xarray_dataarray_variable__/.zattrs | 6 + .../__xarray_dataarray_variable__/0.0 | Bin 0 -> 48 bytes .../my_temperature.date.values.zarr/.zattrs | 1 + .../my_temperature.date.values.zarr/.zgroup | 3 + .../.zmetadata | 34 ++++ .../__xarray_dataarray_variable__/.zarray | 20 +++ .../__xarray_dataarray_variable__/.zattrs | 5 + .../__xarray_dataarray_variable__/0 | Bin 0 -> 96 bytes .../.zattrs | 1 + .../.zgroup | 3 + .../.zmetadata | 34 ++++ .../__xarray_dataarray_variable__/.zarray | 20 +++ .../__xarray_dataarray_variable__/.zattrs | 5 + .../__xarray_dataarray_variable__/0 | Bin 0 -> 32 bytes .../.zattrs | 1 + .../.zgroup | 3 + .../.zmetadata | 40 +++++ .../__xarray_dataarray_variable__/.zarray | 24 +++ .../__xarray_dataarray_variable__/.zattrs | 7 + .../__xarray_dataarray_variable__/0.0.0 | Bin 0 -> 80 bytes tests/test_dumpers/test_dumpers.py | 87 +++++---- tests/test_loaders/input/container_yaml.yaml | 39 ++++ .../input/container_yaml_hdf5.yaml | 34 ++++ .../input/container_yaml_numpy.yaml | 34 ++++ .../input/container_yaml_xarray_netcdf.yaml | 34 ++++ .../input/container_yaml_xarray_zarr.yaml | 34 ++++ tests/test_loaders/input/my_container.h5 | Bin 0 -> 15656 bytes tests/test_loaders/input/my_container.nc | Bin 0 -> 16552 bytes .../input/my_container.zarr/.zattrs | 3 + .../input/my_container.zarr/.zgroup | 3 + .../my_container.zarr/latitude_series/.zattrs | 3 + .../my_container.zarr/latitude_series/.zgroup | 3 + .../latitude_series/values/.zarray | 22 +++ .../latitude_series/values/0.0 | Bin 0 -> 48 bytes .../longitude_series/.zattrs | 3 + .../longitude_series/.zgroup | 3 + .../longitude_series/values/.zarray | 22 +++ .../longitude_series/values/0.0 | Bin 0 -> 48 bytes .../temperature_dataset/.zattrs | 5 + .../temperature_dataset/.zgroup | 3 + .../temperature_dataset/date/.zgroup | 3 + .../temperature_dataset/date/values/.zarray | 20 +++ .../temperature_dataset/date/values/0 | Bin 0 -> 96 bytes .../temperature_dataset/day_in_d/.zattrs | 3 + .../temperature_dataset/day_in_d/.zgroup | 3 + .../day_in_d/values/.zarray | 20 +++ .../temperature_dataset/day_in_d/values/0 | Bin 0 -> 32 bytes .../temperatures_in_K/.zattrs | 3 + .../temperatures_in_K/.zgroup | 3 + .../temperatures_in_K/values/.zarray | 24 +++ .../temperatures_in_K/values/0.0.0 | Bin 0 -> 80 bytes .../input/my_container_xarray.zarr/.zattrs | 3 + .../input/my_container_xarray.zarr/.zgroup | 3 + .../input/my_container_xarray.zarr/.zmetadata | 161 +++++++++++++++++ .../latitude_series/.zarray | 22 +++ .../latitude_series/.zattrs | 7 + .../latitude_series/0.0 | Bin 0 -> 48 bytes .../longitude_series/.zarray | 22 +++ .../longitude_series/.zattrs | 7 + .../longitude_series/0.0 | Bin 0 -> 48 bytes .../temperature_dataset/.zattrs | 5 + .../temperature_dataset/.zgroup | 3 + .../temperature_dataset/date/.zarray | 20 +++ .../temperature_dataset/date/.zattrs | 5 + .../temperature_dataset/date/0 | Bin 0 -> 96 bytes .../temperature_dataset/day_in_d/.zarray | 20 +++ .../temperature_dataset/day_in_d/.zattrs | 6 + .../temperature_dataset/day_in_d/0 | Bin 0 -> 24 bytes .../temperatures_in_K/.zarray | 24 +++ .../temperatures_in_K/.zattrs | 9 + .../temperatures_in_K/0.0.0 | Bin 0 -> 80 bytes .../input/temperature_schema.yaml | 166 ++++++++++++++++++ .../input/yaml_hdf5_h5s/my_latitude.values.h5 | Bin 0 -> 2080 bytes .../yaml_hdf5_h5s/my_longitude.values.h5 | Bin 0 -> 2080 bytes .../my_temperature.date.values.h5 | Bin 0 -> 6176 bytes .../my_temperature.day_in_d.values.h5 | Bin 0 -> 2064 bytes ...my_temperature.temperatures_in_K.values.h5 | Bin 0 -> 2112 bytes .../yaml_numpy_npys/my_latitude.values.npy | Bin 0 -> 160 bytes .../yaml_numpy_npys/my_longitude.values.npy | Bin 0 -> 160 bytes .../my_temperature.date.values.npy | Bin 0 -> 208 bytes .../my_temperature.day_in_d.values.npy | Bin 0 -> 144 bytes ...y_temperature.temperatures_in_K.values.npy | Bin 0 -> 192 bytes .../yaml_xarray_ncs/my_latitude.values.nc | Bin 0 -> 8294 bytes .../yaml_xarray_ncs/my_longitude.values.nc | Bin 0 -> 8294 bytes .../my_temperature.date.values.nc | Bin 0 -> 6176 bytes .../my_temperature.day_in_d.values.nc | Bin 0 -> 6160 bytes ...my_temperature.temperatures_in_K.values.nc | Bin 0 -> 8256 bytes .../my_latitude.values.zarr/.zattrs | 1 + .../my_latitude.values.zarr/.zgroup | 3 + .../my_latitude.values.zarr/.zmetadata | 37 ++++ .../__xarray_dataarray_variable__/.zarray | 22 +++ .../__xarray_dataarray_variable__/.zattrs | 6 + .../__xarray_dataarray_variable__/0.0 | Bin 0 -> 48 bytes .../my_longitude.values.zarr/.zattrs | 1 + .../my_longitude.values.zarr/.zgroup | 3 + .../my_longitude.values.zarr/.zmetadata | 37 ++++ .../__xarray_dataarray_variable__/.zarray | 22 +++ .../__xarray_dataarray_variable__/.zattrs | 6 + .../__xarray_dataarray_variable__/0.0 | Bin 0 -> 48 bytes .../my_temperature.date.values.zarr/.zattrs | 1 + .../my_temperature.date.values.zarr/.zgroup | 3 + .../.zmetadata | 34 ++++ .../__xarray_dataarray_variable__/.zarray | 20 +++ .../__xarray_dataarray_variable__/.zattrs | 5 + .../__xarray_dataarray_variable__/0 | Bin 0 -> 96 bytes .../.zattrs | 1 + .../.zgroup | 3 + .../.zmetadata | 34 ++++ .../__xarray_dataarray_variable__/.zarray | 20 +++ .../__xarray_dataarray_variable__/.zattrs | 5 + .../__xarray_dataarray_variable__/0 | Bin 0 -> 32 bytes .../.zattrs | 1 + .../.zgroup | 3 + .../.zmetadata | 40 +++++ .../__xarray_dataarray_variable__/.zarray | 24 +++ .../__xarray_dataarray_variable__/.zattrs | 7 + .../__xarray_dataarray_variable__/0.0.0 | Bin 0 -> 80 bytes tests/test_loaders/test_loaders.py | 39 ++-- 196 files changed, 1615 insertions(+), 93 deletions(-) rename tests/{input => test_dumpers/ground_truth}/container_yaml.yaml (100%) rename tests/{input => test_dumpers/ground_truth}/container_yaml_hdf5.yaml (67%) rename tests/{input => test_dumpers/ground_truth}/container_yaml_numpy.yaml (66%) rename tests/{input => test_dumpers/ground_truth}/container_yaml_xarray_netcdf.yaml (67%) rename tests/{input => test_dumpers/ground_truth}/container_yaml_xarray_zarr.yaml (66%) rename tests/{input => test_dumpers/ground_truth}/my_container.h5 (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.nc (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/.zattrs (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/.zgroup (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/latitude_series/.zattrs (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/latitude_series/.zgroup (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/latitude_series/values/.zarray (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/latitude_series/values/0.0 (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/longitude_series/.zattrs (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/longitude_series/.zgroup (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/longitude_series/values/.zarray (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/longitude_series/values/0.0 (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/temperature_dataset/.zattrs (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/temperature_dataset/.zgroup (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/temperature_dataset/date/.zgroup (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/temperature_dataset/date/values/.zarray (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/temperature_dataset/date/values/0 (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/temperature_dataset/day_in_d/.zattrs (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/temperature_dataset/day_in_d/.zgroup (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/temperature_dataset/day_in_d/values/.zarray (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/temperature_dataset/day_in_d/values/0 (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/temperature_dataset/temperatures_in_K/.zattrs (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/temperature_dataset/temperatures_in_K/.zgroup (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/temperature_dataset/temperatures_in_K/values/.zarray (100%) rename tests/{input => test_dumpers/ground_truth}/my_container.zarr/temperature_dataset/temperatures_in_K/values/0.0.0 (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/.zattrs (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/.zgroup (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/.zmetadata (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/latitude_series/.zarray (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/latitude_series/.zattrs (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/latitude_series/0.0 (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/longitude_series/.zarray (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/longitude_series/.zattrs (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/longitude_series/0.0 (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/temperature_dataset/.zattrs (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/temperature_dataset/.zgroup (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/temperature_dataset/date/.zarray (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/temperature_dataset/date/.zattrs (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/temperature_dataset/date/0 (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/temperature_dataset/day_in_d/.zarray (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/temperature_dataset/day_in_d/.zattrs (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/temperature_dataset/day_in_d/0 (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zarray (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zattrs (100%) rename tests/{input => test_dumpers/ground_truth}/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/0.0.0 (100%) rename tests/{input => test_dumpers/ground_truth}/temperature_schema.yaml (100%) create mode 100644 tests/test_dumpers/ground_truth/yaml_hdf5_h5s/my_latitude.values.h5 create mode 100644 tests/test_dumpers/ground_truth/yaml_hdf5_h5s/my_longitude.values.h5 create mode 100644 tests/test_dumpers/ground_truth/yaml_hdf5_h5s/my_temperature.date.values.h5 create mode 100644 tests/test_dumpers/ground_truth/yaml_hdf5_h5s/my_temperature.day_in_d.values.h5 create mode 100644 tests/test_dumpers/ground_truth/yaml_hdf5_h5s/my_temperature.temperatures_in_K.values.h5 create mode 100644 tests/test_dumpers/ground_truth/yaml_numpy_npys/my_latitude.values.npy create mode 100644 tests/test_dumpers/ground_truth/yaml_numpy_npys/my_longitude.values.npy create mode 100644 tests/test_dumpers/ground_truth/yaml_numpy_npys/my_temperature.date.values.npy create mode 100644 tests/test_dumpers/ground_truth/yaml_numpy_npys/my_temperature.day_in_d.values.npy create mode 100644 tests/test_dumpers/ground_truth/yaml_numpy_npys/my_temperature.temperatures_in_K.values.npy create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_ncs/my_latitude.values.nc create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_ncs/my_longitude.values.nc create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_ncs/my_temperature.date.values.nc create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_ncs/my_temperature.day_in_d.values.nc create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_ncs/my_temperature.temperatures_in_K.values.nc create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_latitude.values.zarr/.zattrs create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_latitude.values.zarr/.zgroup create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_latitude.values.zarr/.zmetadata create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_latitude.values.zarr/__xarray_dataarray_variable__/.zarray create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_latitude.values.zarr/__xarray_dataarray_variable__/.zattrs create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_latitude.values.zarr/__xarray_dataarray_variable__/0.0 create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_longitude.values.zarr/.zattrs create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_longitude.values.zarr/.zgroup create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_longitude.values.zarr/.zmetadata create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_longitude.values.zarr/__xarray_dataarray_variable__/.zarray create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_longitude.values.zarr/__xarray_dataarray_variable__/.zattrs create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_longitude.values.zarr/__xarray_dataarray_variable__/0.0 create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.date.values.zarr/.zattrs create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.date.values.zarr/.zgroup create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.date.values.zarr/.zmetadata create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.date.values.zarr/__xarray_dataarray_variable__/.zarray create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.date.values.zarr/__xarray_dataarray_variable__/.zattrs create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.date.values.zarr/__xarray_dataarray_variable__/0 create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zattrs create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zgroup create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zmetadata create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/__xarray_dataarray_variable__/.zarray create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/__xarray_dataarray_variable__/.zattrs create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/__xarray_dataarray_variable__/0 create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.temperatures_in_K.values.zarr/.zattrs create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.temperatures_in_K.values.zarr/.zgroup create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.temperatures_in_K.values.zarr/.zmetadata create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.temperatures_in_K.values.zarr/__xarray_dataarray_variable__/.zarray create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.temperatures_in_K.values.zarr/__xarray_dataarray_variable__/.zattrs create mode 100644 tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.temperatures_in_K.values.zarr/__xarray_dataarray_variable__/0.0.0 create mode 100644 tests/test_loaders/input/container_yaml.yaml create mode 100644 tests/test_loaders/input/container_yaml_hdf5.yaml create mode 100644 tests/test_loaders/input/container_yaml_numpy.yaml create mode 100644 tests/test_loaders/input/container_yaml_xarray_netcdf.yaml create mode 100644 tests/test_loaders/input/container_yaml_xarray_zarr.yaml create mode 100644 tests/test_loaders/input/my_container.h5 create mode 100644 tests/test_loaders/input/my_container.nc create mode 100644 tests/test_loaders/input/my_container.zarr/.zattrs create mode 100644 tests/test_loaders/input/my_container.zarr/.zgroup create mode 100644 tests/test_loaders/input/my_container.zarr/latitude_series/.zattrs create mode 100644 tests/test_loaders/input/my_container.zarr/latitude_series/.zgroup create mode 100644 tests/test_loaders/input/my_container.zarr/latitude_series/values/.zarray create mode 100644 tests/test_loaders/input/my_container.zarr/latitude_series/values/0.0 create mode 100644 tests/test_loaders/input/my_container.zarr/longitude_series/.zattrs create mode 100644 tests/test_loaders/input/my_container.zarr/longitude_series/.zgroup create mode 100644 tests/test_loaders/input/my_container.zarr/longitude_series/values/.zarray create mode 100644 tests/test_loaders/input/my_container.zarr/longitude_series/values/0.0 create mode 100644 tests/test_loaders/input/my_container.zarr/temperature_dataset/.zattrs create mode 100644 tests/test_loaders/input/my_container.zarr/temperature_dataset/.zgroup create mode 100644 tests/test_loaders/input/my_container.zarr/temperature_dataset/date/.zgroup create mode 100644 tests/test_loaders/input/my_container.zarr/temperature_dataset/date/values/.zarray create mode 100644 tests/test_loaders/input/my_container.zarr/temperature_dataset/date/values/0 create mode 100644 tests/test_loaders/input/my_container.zarr/temperature_dataset/day_in_d/.zattrs create mode 100644 tests/test_loaders/input/my_container.zarr/temperature_dataset/day_in_d/.zgroup create mode 100644 tests/test_loaders/input/my_container.zarr/temperature_dataset/day_in_d/values/.zarray create mode 100644 tests/test_loaders/input/my_container.zarr/temperature_dataset/day_in_d/values/0 create mode 100644 tests/test_loaders/input/my_container.zarr/temperature_dataset/temperatures_in_K/.zattrs create mode 100644 tests/test_loaders/input/my_container.zarr/temperature_dataset/temperatures_in_K/.zgroup create mode 100644 tests/test_loaders/input/my_container.zarr/temperature_dataset/temperatures_in_K/values/.zarray create mode 100644 tests/test_loaders/input/my_container.zarr/temperature_dataset/temperatures_in_K/values/0.0.0 create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/.zattrs create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/.zgroup create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/.zmetadata create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/latitude_series/.zarray create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/latitude_series/.zattrs create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/latitude_series/0.0 create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/longitude_series/.zarray create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/longitude_series/.zattrs create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/longitude_series/0.0 create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/temperature_dataset/.zattrs create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/temperature_dataset/.zgroup create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/temperature_dataset/date/.zarray create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/temperature_dataset/date/.zattrs create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/temperature_dataset/date/0 create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zarray create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zattrs create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/temperature_dataset/day_in_d/0 create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zarray create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zattrs create mode 100644 tests/test_loaders/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/0.0.0 create mode 100644 tests/test_loaders/input/temperature_schema.yaml create mode 100644 tests/test_loaders/input/yaml_hdf5_h5s/my_latitude.values.h5 create mode 100644 tests/test_loaders/input/yaml_hdf5_h5s/my_longitude.values.h5 create mode 100644 tests/test_loaders/input/yaml_hdf5_h5s/my_temperature.date.values.h5 create mode 100644 tests/test_loaders/input/yaml_hdf5_h5s/my_temperature.day_in_d.values.h5 create mode 100644 tests/test_loaders/input/yaml_hdf5_h5s/my_temperature.temperatures_in_K.values.h5 create mode 100644 tests/test_loaders/input/yaml_numpy_npys/my_latitude.values.npy create mode 100644 tests/test_loaders/input/yaml_numpy_npys/my_longitude.values.npy create mode 100644 tests/test_loaders/input/yaml_numpy_npys/my_temperature.date.values.npy create mode 100644 tests/test_loaders/input/yaml_numpy_npys/my_temperature.day_in_d.values.npy create mode 100644 tests/test_loaders/input/yaml_numpy_npys/my_temperature.temperatures_in_K.values.npy create mode 100644 tests/test_loaders/input/yaml_xarray_ncs/my_latitude.values.nc create mode 100644 tests/test_loaders/input/yaml_xarray_ncs/my_longitude.values.nc create mode 100644 tests/test_loaders/input/yaml_xarray_ncs/my_temperature.date.values.nc create mode 100644 tests/test_loaders/input/yaml_xarray_ncs/my_temperature.day_in_d.values.nc create mode 100644 tests/test_loaders/input/yaml_xarray_ncs/my_temperature.temperatures_in_K.values.nc create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr/.zattrs create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr/.zgroup create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr/.zmetadata create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr/__xarray_dataarray_variable__/.zarray create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr/__xarray_dataarray_variable__/.zattrs create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr/__xarray_dataarray_variable__/0.0 create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_longitude.values.zarr/.zattrs create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_longitude.values.zarr/.zgroup create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_longitude.values.zarr/.zmetadata create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_longitude.values.zarr/__xarray_dataarray_variable__/.zarray create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_longitude.values.zarr/__xarray_dataarray_variable__/.zattrs create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_longitude.values.zarr/__xarray_dataarray_variable__/0.0 create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.date.values.zarr/.zattrs create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.date.values.zarr/.zgroup create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.date.values.zarr/.zmetadata create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.date.values.zarr/__xarray_dataarray_variable__/.zarray create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.date.values.zarr/__xarray_dataarray_variable__/.zattrs create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.date.values.zarr/__xarray_dataarray_variable__/0 create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zattrs create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zgroup create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zmetadata create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/__xarray_dataarray_variable__/.zarray create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/__xarray_dataarray_variable__/.zattrs create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/__xarray_dataarray_variable__/0 create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.temperatures_in_K.values.zarr/.zattrs create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.temperatures_in_K.values.zarr/.zgroup create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.temperatures_in_K.values.zarr/.zmetadata create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.temperatures_in_K.values.zarr/__xarray_dataarray_variable__/.zarray create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.temperatures_in_K.values.zarr/__xarray_dataarray_variable__/.zattrs create mode 100644 tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.temperatures_in_K.values.zarr/__xarray_dataarray_variable__/0.0.0 diff --git a/poetry.lock b/poetry.lock index e2eeef1..5e357ae 100644 --- a/poetry.lock +++ b/poetry.lock @@ -290,6 +290,24 @@ docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2. testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"] typing = ["typing-extensions (>=4.12.2)"] +[[package]] +name = "h5netcdf" +version = "1.3.0" +description = "netCDF4 via h5py" +optional = false +python-versions = ">=3.9" +files = [ + {file = "h5netcdf-1.3.0-py3-none-any.whl", hash = "sha256:f2df69dcd3665dc9c4d43eb6529dedd113b2508090d12ac973573305a8406465"}, + {file = "h5netcdf-1.3.0.tar.gz", hash = "sha256:a171c027daeb34b24c24a3b6304195b8eabbb6f10c748256ed3cfe19806383cf"}, +] + +[package.dependencies] +h5py = "*" +packaging = "*" + +[package.extras] +test = ["netCDF4", "pytest"] + [[package]] name = "h5py" version = "3.11.0" @@ -387,7 +405,7 @@ name = "isodate" version = "0.6.1" description = "An ISO 8601 date/time/duration parser and formatter" optional = false -python-versions = ">=3.8" +python-versions = "*" files = [ {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, @@ -727,18 +745,12 @@ files = [ curies = ">=0.5.3" pyyaml = ">=5.3.1" -[package.dependencies] -click = ">=8.1.3,<9.0.0" -pytest-logging = ">=2015.11.4,<2016.0.0" -PyYAML = ">=6.0,<7.0" -requests = ">=2.28.1,<3.0.0" - [[package]] name = "pydantic" version = "2.9.2" description = "Data validation using Python type hints" optional = false -python-versions = "<4.0,>=3.8" +python-versions = ">=3.8" files = [ {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, @@ -1536,4 +1548,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "0023555becb3abbfba198d28b8463cf51dc279c98c6d01bf8ac625a909e14eb6" +content-hash = "47cf503b7a309114705094f221fbd3e991ba6d4e593880bb3542bbdf9c3f5724" diff --git a/src/linkml_arrays/dumpers/yaml_array_file_dumper.py b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py index 18f9807..0b39199 100644 --- a/src/linkml_arrays/dumpers/yaml_array_file_dumper.py +++ b/src/linkml_arrays/dumpers/yaml_array_file_dumper.py @@ -61,19 +61,17 @@ def _iterate_element( else: output_file_name = f"{found_slot.name}" - # if output_dir is absolute, make it relative to current working directory - # and create the directory if it does not exist - if output_dir.is_absolute(): - output_dir = Path(os.path.relpath(output_dir, start=os.getcwd())) - output_dir.mkdir(exist_ok=True) - output_file_path_no_suffix = output_dir / output_file_name + output_file_path_no_suffix = (output_dir / output_file_name) # save the numpy array to file and write the file path to the dictionary output_file_path = write_array(v, output_file_path_no_suffix) + + # write the path to the array file relative to the output directory where the yaml is written + relative_output_file_path = os.path.relpath(output_file_path, start=output_dir) ret_dict[k] = { "source": [ { - "file": f"./{output_file_path}", + "file": f"{relative_output_file_path}", "format": format, } ] @@ -100,6 +98,21 @@ class YamlArrayFileDumper(Dumper, metaclass=ABCMeta): # FORMAT is a class attribute that must be set by subclasses + def dump( + self, + element: Union[YAMLRoot, BaseModel], + to_file: str, + schemaview: SchemaView, + **kwargs, + ): + """Dump the element to a YAML file with paths to array files.""" + output_dir = Path(to_file).parent + input = _iterate_element( + element, schemaview, Path(output_dir), self.write_array, self.FORMAT + ) + with open(to_file, "w") as f: + yaml.dump(input, f) + def dumps( self, element: Union[YAMLRoot, BaseModel], diff --git a/tests/input/container_yaml.yaml b/tests/test_dumpers/ground_truth/container_yaml.yaml similarity index 100% rename from tests/input/container_yaml.yaml rename to tests/test_dumpers/ground_truth/container_yaml.yaml diff --git a/tests/input/container_yaml_hdf5.yaml b/tests/test_dumpers/ground_truth/container_yaml_hdf5.yaml similarity index 67% rename from tests/input/container_yaml_hdf5.yaml rename to tests/test_dumpers/ground_truth/container_yaml_hdf5.yaml index b2e8d1a..a52de35 100644 --- a/tests/input/container_yaml_hdf5.yaml +++ b/tests/test_dumpers/ground_truth/container_yaml_hdf5.yaml @@ -3,25 +3,25 @@ latitude_series: name: my_latitude values: source: - - file: ./out/my_latitude.values.h5 + - file: my_latitude.values.h5 format: hdf5 longitude_series: name: my_longitude values: source: - - file: ./out/my_longitude.values.h5 + - file: my_longitude.values.h5 format: hdf5 temperature_dataset: date: values: source: - - file: ./out/my_temperature.date.values.h5 + - file: my_temperature.date.values.h5 format: hdf5 day_in_d: reference_date: '2020-01-01' values: source: - - file: ./out/my_temperature.day_in_d.values.h5 + - file: my_temperature.day_in_d.values.h5 format: hdf5 latitude_in_deg: my_latitude longitude_in_deg: my_longitude @@ -30,5 +30,5 @@ temperature_dataset: conversion_factor: 1000.0 values: source: - - file: ./out/my_temperature.temperatures_in_K.values.h5 + - file: my_temperature.temperatures_in_K.values.h5 format: hdf5 diff --git a/tests/input/container_yaml_numpy.yaml b/tests/test_dumpers/ground_truth/container_yaml_numpy.yaml similarity index 66% rename from tests/input/container_yaml_numpy.yaml rename to tests/test_dumpers/ground_truth/container_yaml_numpy.yaml index 1e8d765..d2d7bd1 100644 --- a/tests/input/container_yaml_numpy.yaml +++ b/tests/test_dumpers/ground_truth/container_yaml_numpy.yaml @@ -3,25 +3,25 @@ latitude_series: name: my_latitude values: source: - - file: "./out/my_latitude.values.npy" + - file: my_latitude.values.npy format: numpy longitude_series: name: my_longitude values: source: - - file: "./out/my_longitude.values.npy" + - file: my_longitude.values.npy format: numpy temperature_dataset: date: values: source: - - file: "./out/my_temperature.date.values.npy" + - file: my_temperature.date.values.npy format: numpy day_in_d: reference_date: '2020-01-01' values: source: - - file: "./out/my_temperature.day_in_d.values.npy" + - file: my_temperature.day_in_d.values.npy format: numpy latitude_in_deg: my_latitude longitude_in_deg: my_longitude @@ -30,5 +30,5 @@ temperature_dataset: conversion_factor: 1000.0 values: source: - - file: "./out/my_temperature.temperatures_in_K.values.npy" + - file: my_temperature.temperatures_in_K.values.npy format: numpy diff --git a/tests/input/container_yaml_xarray_netcdf.yaml b/tests/test_dumpers/ground_truth/container_yaml_xarray_netcdf.yaml similarity index 67% rename from tests/input/container_yaml_xarray_netcdf.yaml rename to tests/test_dumpers/ground_truth/container_yaml_xarray_netcdf.yaml index 735ccfa..da875ec 100644 --- a/tests/input/container_yaml_xarray_netcdf.yaml +++ b/tests/test_dumpers/ground_truth/container_yaml_xarray_netcdf.yaml @@ -3,25 +3,25 @@ latitude_series: name: my_latitude values: source: - - file: "./out/my_latitude.values.nc" + - file: my_latitude.values.nc format: netcdf longitude_series: name: my_longitude values: source: - - file: "./out/my_longitude.values.nc" + - file: my_longitude.values.nc format: netcdf temperature_dataset: date: values: source: - - file: "./out/my_temperature.date.values.nc" + - file: my_temperature.date.values.nc format: netcdf day_in_d: reference_date: '2020-01-01' values: source: - - file: "./out/my_temperature.day_in_d.values.nc" + - file: my_temperature.day_in_d.values.nc format: netcdf latitude_in_deg: my_latitude longitude_in_deg: my_longitude @@ -30,5 +30,5 @@ temperature_dataset: conversion_factor: 1000.0 values: source: - - file: "./out/my_temperature.temperatures_in_K.values.nc" + - file: my_temperature.temperatures_in_K.values.nc format: netcdf diff --git a/tests/input/container_yaml_xarray_zarr.yaml b/tests/test_dumpers/ground_truth/container_yaml_xarray_zarr.yaml similarity index 66% rename from tests/input/container_yaml_xarray_zarr.yaml rename to tests/test_dumpers/ground_truth/container_yaml_xarray_zarr.yaml index 3658193..de6a1da 100644 --- a/tests/input/container_yaml_xarray_zarr.yaml +++ b/tests/test_dumpers/ground_truth/container_yaml_xarray_zarr.yaml @@ -3,25 +3,25 @@ latitude_series: name: my_latitude values: source: - - file: "./out/my_latitude.values.zarr" + - file: my_latitude.values.zarr format: zarr longitude_series: name: my_longitude values: source: - - file: "./out/my_longitude.values.zarr" + - file: my_longitude.values.zarr format: zarr temperature_dataset: date: values: source: - - file: "./out/my_temperature.date.values.zarr" + - file: my_temperature.date.values.zarr format: zarr day_in_d: reference_date: '2020-01-01' values: source: - - file: "./out/my_temperature.day_in_d.values.zarr" + - file: my_temperature.day_in_d.values.zarr format: zarr latitude_in_deg: my_latitude longitude_in_deg: my_longitude @@ -30,5 +30,5 @@ temperature_dataset: conversion_factor: 1000.0 values: source: - - file: "./out/my_temperature.temperatures_in_K.values.zarr" + - file: my_temperature.temperatures_in_K.values.zarr format: zarr diff --git a/tests/input/my_container.h5 b/tests/test_dumpers/ground_truth/my_container.h5 similarity index 100% rename from tests/input/my_container.h5 rename to tests/test_dumpers/ground_truth/my_container.h5 diff --git a/tests/input/my_container.nc b/tests/test_dumpers/ground_truth/my_container.nc similarity index 100% rename from tests/input/my_container.nc rename to tests/test_dumpers/ground_truth/my_container.nc diff --git a/tests/input/my_container.zarr/.zattrs b/tests/test_dumpers/ground_truth/my_container.zarr/.zattrs similarity index 100% rename from tests/input/my_container.zarr/.zattrs rename to tests/test_dumpers/ground_truth/my_container.zarr/.zattrs diff --git a/tests/input/my_container.zarr/.zgroup b/tests/test_dumpers/ground_truth/my_container.zarr/.zgroup similarity index 100% rename from tests/input/my_container.zarr/.zgroup rename to tests/test_dumpers/ground_truth/my_container.zarr/.zgroup diff --git a/tests/input/my_container.zarr/latitude_series/.zattrs b/tests/test_dumpers/ground_truth/my_container.zarr/latitude_series/.zattrs similarity index 100% rename from tests/input/my_container.zarr/latitude_series/.zattrs rename to tests/test_dumpers/ground_truth/my_container.zarr/latitude_series/.zattrs diff --git a/tests/input/my_container.zarr/latitude_series/.zgroup b/tests/test_dumpers/ground_truth/my_container.zarr/latitude_series/.zgroup similarity index 100% rename from tests/input/my_container.zarr/latitude_series/.zgroup rename to tests/test_dumpers/ground_truth/my_container.zarr/latitude_series/.zgroup diff --git a/tests/input/my_container.zarr/latitude_series/values/.zarray b/tests/test_dumpers/ground_truth/my_container.zarr/latitude_series/values/.zarray similarity index 100% rename from tests/input/my_container.zarr/latitude_series/values/.zarray rename to tests/test_dumpers/ground_truth/my_container.zarr/latitude_series/values/.zarray diff --git a/tests/input/my_container.zarr/latitude_series/values/0.0 b/tests/test_dumpers/ground_truth/my_container.zarr/latitude_series/values/0.0 similarity index 100% rename from tests/input/my_container.zarr/latitude_series/values/0.0 rename to tests/test_dumpers/ground_truth/my_container.zarr/latitude_series/values/0.0 diff --git a/tests/input/my_container.zarr/longitude_series/.zattrs b/tests/test_dumpers/ground_truth/my_container.zarr/longitude_series/.zattrs similarity index 100% rename from tests/input/my_container.zarr/longitude_series/.zattrs rename to tests/test_dumpers/ground_truth/my_container.zarr/longitude_series/.zattrs diff --git a/tests/input/my_container.zarr/longitude_series/.zgroup b/tests/test_dumpers/ground_truth/my_container.zarr/longitude_series/.zgroup similarity index 100% rename from tests/input/my_container.zarr/longitude_series/.zgroup rename to tests/test_dumpers/ground_truth/my_container.zarr/longitude_series/.zgroup diff --git a/tests/input/my_container.zarr/longitude_series/values/.zarray b/tests/test_dumpers/ground_truth/my_container.zarr/longitude_series/values/.zarray similarity index 100% rename from tests/input/my_container.zarr/longitude_series/values/.zarray rename to tests/test_dumpers/ground_truth/my_container.zarr/longitude_series/values/.zarray diff --git a/tests/input/my_container.zarr/longitude_series/values/0.0 b/tests/test_dumpers/ground_truth/my_container.zarr/longitude_series/values/0.0 similarity index 100% rename from tests/input/my_container.zarr/longitude_series/values/0.0 rename to tests/test_dumpers/ground_truth/my_container.zarr/longitude_series/values/0.0 diff --git a/tests/input/my_container.zarr/temperature_dataset/.zattrs b/tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/.zattrs similarity index 100% rename from tests/input/my_container.zarr/temperature_dataset/.zattrs rename to tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/.zattrs diff --git a/tests/input/my_container.zarr/temperature_dataset/.zgroup b/tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/.zgroup similarity index 100% rename from tests/input/my_container.zarr/temperature_dataset/.zgroup rename to tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/.zgroup diff --git a/tests/input/my_container.zarr/temperature_dataset/date/.zgroup b/tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/date/.zgroup similarity index 100% rename from tests/input/my_container.zarr/temperature_dataset/date/.zgroup rename to tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/date/.zgroup diff --git a/tests/input/my_container.zarr/temperature_dataset/date/values/.zarray b/tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/date/values/.zarray similarity index 100% rename from tests/input/my_container.zarr/temperature_dataset/date/values/.zarray rename to tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/date/values/.zarray diff --git a/tests/input/my_container.zarr/temperature_dataset/date/values/0 b/tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/date/values/0 similarity index 100% rename from tests/input/my_container.zarr/temperature_dataset/date/values/0 rename to tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/date/values/0 diff --git a/tests/input/my_container.zarr/temperature_dataset/day_in_d/.zattrs b/tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/day_in_d/.zattrs similarity index 100% rename from tests/input/my_container.zarr/temperature_dataset/day_in_d/.zattrs rename to tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/day_in_d/.zattrs diff --git a/tests/input/my_container.zarr/temperature_dataset/day_in_d/.zgroup b/tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/day_in_d/.zgroup similarity index 100% rename from tests/input/my_container.zarr/temperature_dataset/day_in_d/.zgroup rename to tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/day_in_d/.zgroup diff --git a/tests/input/my_container.zarr/temperature_dataset/day_in_d/values/.zarray b/tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/day_in_d/values/.zarray similarity index 100% rename from tests/input/my_container.zarr/temperature_dataset/day_in_d/values/.zarray rename to tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/day_in_d/values/.zarray diff --git a/tests/input/my_container.zarr/temperature_dataset/day_in_d/values/0 b/tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/day_in_d/values/0 similarity index 100% rename from tests/input/my_container.zarr/temperature_dataset/day_in_d/values/0 rename to tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/day_in_d/values/0 diff --git a/tests/input/my_container.zarr/temperature_dataset/temperatures_in_K/.zattrs b/tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/temperatures_in_K/.zattrs similarity index 100% rename from tests/input/my_container.zarr/temperature_dataset/temperatures_in_K/.zattrs rename to tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/temperatures_in_K/.zattrs diff --git a/tests/input/my_container.zarr/temperature_dataset/temperatures_in_K/.zgroup b/tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/temperatures_in_K/.zgroup similarity index 100% rename from tests/input/my_container.zarr/temperature_dataset/temperatures_in_K/.zgroup rename to tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/temperatures_in_K/.zgroup diff --git a/tests/input/my_container.zarr/temperature_dataset/temperatures_in_K/values/.zarray b/tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/temperatures_in_K/values/.zarray similarity index 100% rename from tests/input/my_container.zarr/temperature_dataset/temperatures_in_K/values/.zarray rename to tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/temperatures_in_K/values/.zarray diff --git a/tests/input/my_container.zarr/temperature_dataset/temperatures_in_K/values/0.0.0 b/tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/temperatures_in_K/values/0.0.0 similarity index 100% rename from tests/input/my_container.zarr/temperature_dataset/temperatures_in_K/values/0.0.0 rename to tests/test_dumpers/ground_truth/my_container.zarr/temperature_dataset/temperatures_in_K/values/0.0.0 diff --git a/tests/input/my_container_xarray.zarr/.zattrs b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/.zattrs similarity index 100% rename from tests/input/my_container_xarray.zarr/.zattrs rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/.zattrs diff --git a/tests/input/my_container_xarray.zarr/.zgroup b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/.zgroup similarity index 100% rename from tests/input/my_container_xarray.zarr/.zgroup rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/.zgroup diff --git a/tests/input/my_container_xarray.zarr/.zmetadata b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/.zmetadata similarity index 100% rename from tests/input/my_container_xarray.zarr/.zmetadata rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/.zmetadata diff --git a/tests/input/my_container_xarray.zarr/latitude_series/.zarray b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/latitude_series/.zarray similarity index 100% rename from tests/input/my_container_xarray.zarr/latitude_series/.zarray rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/latitude_series/.zarray diff --git a/tests/input/my_container_xarray.zarr/latitude_series/.zattrs b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/latitude_series/.zattrs similarity index 100% rename from tests/input/my_container_xarray.zarr/latitude_series/.zattrs rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/latitude_series/.zattrs diff --git a/tests/input/my_container_xarray.zarr/latitude_series/0.0 b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/latitude_series/0.0 similarity index 100% rename from tests/input/my_container_xarray.zarr/latitude_series/0.0 rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/latitude_series/0.0 diff --git a/tests/input/my_container_xarray.zarr/longitude_series/.zarray b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/longitude_series/.zarray similarity index 100% rename from tests/input/my_container_xarray.zarr/longitude_series/.zarray rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/longitude_series/.zarray diff --git a/tests/input/my_container_xarray.zarr/longitude_series/.zattrs b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/longitude_series/.zattrs similarity index 100% rename from tests/input/my_container_xarray.zarr/longitude_series/.zattrs rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/longitude_series/.zattrs diff --git a/tests/input/my_container_xarray.zarr/longitude_series/0.0 b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/longitude_series/0.0 similarity index 100% rename from tests/input/my_container_xarray.zarr/longitude_series/0.0 rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/longitude_series/0.0 diff --git a/tests/input/my_container_xarray.zarr/temperature_dataset/.zattrs b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/.zattrs similarity index 100% rename from tests/input/my_container_xarray.zarr/temperature_dataset/.zattrs rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/.zattrs diff --git a/tests/input/my_container_xarray.zarr/temperature_dataset/.zgroup b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/.zgroup similarity index 100% rename from tests/input/my_container_xarray.zarr/temperature_dataset/.zgroup rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/.zgroup diff --git a/tests/input/my_container_xarray.zarr/temperature_dataset/date/.zarray b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/date/.zarray similarity index 100% rename from tests/input/my_container_xarray.zarr/temperature_dataset/date/.zarray rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/date/.zarray diff --git a/tests/input/my_container_xarray.zarr/temperature_dataset/date/.zattrs b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/date/.zattrs similarity index 100% rename from tests/input/my_container_xarray.zarr/temperature_dataset/date/.zattrs rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/date/.zattrs diff --git a/tests/input/my_container_xarray.zarr/temperature_dataset/date/0 b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/date/0 similarity index 100% rename from tests/input/my_container_xarray.zarr/temperature_dataset/date/0 rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/date/0 diff --git a/tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zarray b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/day_in_d/.zarray similarity index 100% rename from tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zarray rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/day_in_d/.zarray diff --git a/tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zattrs b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/day_in_d/.zattrs similarity index 100% rename from tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zattrs rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/day_in_d/.zattrs diff --git a/tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/0 b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/day_in_d/0 similarity index 100% rename from tests/input/my_container_xarray.zarr/temperature_dataset/day_in_d/0 rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/day_in_d/0 diff --git a/tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zarray b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zarray similarity index 100% rename from tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zarray rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zarray diff --git a/tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zattrs b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zattrs similarity index 100% rename from tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zattrs rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/.zattrs diff --git a/tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/0.0.0 b/tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/0.0.0 similarity index 100% rename from tests/input/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/0.0.0 rename to tests/test_dumpers/ground_truth/my_container_xarray.zarr/temperature_dataset/temperatures_in_K/0.0.0 diff --git a/tests/input/temperature_schema.yaml b/tests/test_dumpers/ground_truth/temperature_schema.yaml similarity index 100% rename from tests/input/temperature_schema.yaml rename to tests/test_dumpers/ground_truth/temperature_schema.yaml diff --git a/tests/test_dumpers/ground_truth/yaml_hdf5_h5s/my_latitude.values.h5 b/tests/test_dumpers/ground_truth/yaml_hdf5_h5s/my_latitude.values.h5 new file mode 100644 index 0000000000000000000000000000000000000000..a433f872b6c93a6f3737cfa4809bbea74f5e5c8d GIT binary patch literal 2080 zcmeD5aB<`1lHy_j0S*oZ76t(@6Gr@p0tF6;2#gPtPk=HQp>zk7Ucm%mFfxE31A_!q zTo7tLy1I}cS62q0N|^aD8mf)KfCa*WIs+y=N{^5b@Njhu0C_b6>R(tYJpoN;uwY0@ zEJ*~hVd>EWCP606$iNCQ3u+)Eg9g|nMka^=%z9ijGce_YR0=BCGeFX=1A_@SgUNqp zh=W*xq9A!DCWwI?(44}|2vyFY08t1hE8whwUzk7Ucm%mFfxE31A_!q zTo7tLy1I}cS62q0N|^aD8mf)KfCa*WIs+y=N{^5b@Njhu0C_b6>R(tYJpoN;uwY0@ zEJ*~hVd>EWCP606$iNCQ3u+)Eg9g|nMka^=%z9ijGce_YR0=BCGeFX=1A_@SgUNqp zh=W*xq9A!DCWwI?(44}|2vyFY08t1hE8whwU+agpj#zAL{+%jL?~!krDVbX*UyY+k%wFTgu5?r_74hs(Pwf|!^?Whr6Rn%2H2#HMVGkex z0-q4z4}YqMnQPeVnCsSbw3t=(OAD^lGMUHgWg!dwFzAPjM?_W!<%izk7Ucm%mFfxE31A_!q zTo7tLy1I}cS62q0N|^aD8mf)KfCa*WIs+y=N{^5b@Njhu0C_b6>R(tYJpoN;uwY0@ zEJ*~hVd>EWCP606$iNCQ3u+)EG$k`KLIhye!)Rt;`Uc5>@(U!bI)H6v1@b`ROiWB* zjT}&Om>HqU(DEGv!vwIt!A1o8`MZE}G%Oz~Fb_5tj=Ezk7Ucm%mFfxE31A_!q zTo7tLy1I}cS62q0N|^aD8mf)KfCa*WIs+y=N{^5b@Njhu0C_b6>R(tYJpoN;uwY0@ zEJ*~hVd>EWCP606$iNCQ3u+)Eg9X?mMrMcr%z9#JW?)VL=@eA3XMm(-2L=;v29y8H z5C^gXMM3gROiW-4IG{NPXdN`^J3th|$qYD)9*kf=e-}`WhB}5p0qSmg*ga~;Xb6mk b04+n{gFV!A2MEmpr3Ik02$Yt9(lQPJqOUS| literal 0 HcmV?d00001 diff --git a/tests/test_dumpers/ground_truth/yaml_numpy_npys/my_latitude.values.npy b/tests/test_dumpers/ground_truth/yaml_numpy_npys/my_latitude.values.npy new file mode 100644 index 0000000000000000000000000000000000000000..1a5f0c4a86e9418046dfc33302700515824bd2aa GIT binary patch literal 160 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= mXCxM+0{I$7ItoUbItsN4WCJb+F!*2(p&1+?GzXLxZ~y@7nH_cj literal 0 HcmV?d00001 diff --git a/tests/test_dumpers/ground_truth/yaml_numpy_npys/my_longitude.values.npy b/tests/test_dumpers/ground_truth/yaml_numpy_npys/my_longitude.values.npy new file mode 100644 index 0000000000000000000000000000000000000000..1de6b75bdf880c258355a00629003a49b971acaf GIT binary patch literal 160 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= lXCxM+0{I$7ItoUbItsN4WCJb+Fc5Ko&=OEu21+Y9007tW9M=E< literal 0 HcmV?d00001 diff --git a/tests/test_dumpers/ground_truth/yaml_numpy_npys/my_temperature.date.values.npy b/tests/test_dumpers/ground_truth/yaml_numpy_npys/my_temperature.date.values.npy new file mode 100644 index 0000000000000000000000000000000000000000..f1d35a8db7c03dd2251ddd560c603830d8cab2ac GIT binary patch literal 208 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1Z6KZInuA`uymS0p-l$aNvUzCyxl5k7RDNY57 v7iT0EqyqUGMmm~03bhL411=*51_lElhS9oEz9EoCX2axRG_o9w4Uz)@azP&! literal 0 HcmV?d00001 diff --git a/tests/test_dumpers/ground_truth/yaml_numpy_npys/my_temperature.day_in_d.values.npy b/tests/test_dumpers/ground_truth/yaml_numpy_npys/my_temperature.day_in_d.values.npy new file mode 100644 index 0000000000000000000000000000000000000000..aff3acec66c3825ca308545c202e929f5331d7c6 GIT binary patch literal 144 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlWC!@qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= aXCxM+0{I$7I+{8PwF(pfE(R!Igwg;Dof}~Q literal 0 HcmV?d00001 diff --git a/tests/test_dumpers/ground_truth/yaml_numpy_npys/my_temperature.temperatures_in_K.values.npy b/tests/test_dumpers/ground_truth/yaml_numpy_npys/my_temperature.temperatures_in_K.values.npy new file mode 100644 index 0000000000000000000000000000000000000000..de28bf8633b898cc80c36a0a023ce09c19db0aea GIT binary patch literal 192 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= tXCxM+0{I$7Itn19siRPktaptJ~-mVnYS4gjGQ9-IIG literal 0 HcmV?d00001 diff --git a/tests/test_dumpers/ground_truth/yaml_xarray_ncs/my_latitude.values.nc b/tests/test_dumpers/ground_truth/yaml_xarray_ncs/my_latitude.values.nc new file mode 100644 index 0000000000000000000000000000000000000000..83133793029c2e84f735a0dab0f5bcf404f3edd8 GIT binary patch literal 8294 zcmeHMPfrs;6o1oySz(bXC}1?Ko{W;Fg>o{4l5J~=r6m;6#KW?uRF_?HV zegi*&S5KN4PndY{Gic!M!Gnq1@V%KGAk`XULNsJvyYpt|y_xskZ{NH<%(Fr^-`8`Y z2Z%HcA`s_Y+3W{YHN=b@OZl?wbm8Sfb|Eyjd;3fE=(7{L!u7-9V42*ullO#xkxFcs zS{9*}DC&4?R`MQ~9ZG|tkfz>+gl;TJoJE2mT(Yc(cC%@3T8{18qPJl;J$t3*TGnV_ z$(4Kny>H`nGZ;3JCI}_eXFC-5SQiNwNk8*PW1`KI1 zw1xXbHIjrvA-+&pyAc%zJ_mNBmyxbs>SLG`EQ`q=wDNpBAh zNuVyRbz4m~L^(6Kij0;=gENxLn#Yx}d4K1@_Q{J*M*Hb$_9I0XjS~P=Uk`EI+tTL= z7Y2h^FNY86rP*jS9j|WtZi|ETQ{C*6N2E-4sR~n7{EI4_5t-DB9%22?d$rnhapb$_9CI2I)ss=uv`|ilSh8&`v9yFDns`_iyOm8!OWG|F6N8B- z<2UdVc=e=-@q~#7KZ6GD9!=zi@6GH0sn!@1qapL!oi{V@&Aj)1`{wOoo)xnBfxZiU zK&0ysh8XY4<{+S&DQ4tY%2#Bk2QL@0i`vBA?Ju?C&#rcv>xV+YGP!Lx@6&*hN;FO_ z3sXxJse0>n@*bBRNrRz~rrv2nH<~2Q!od(O+V(@I)pEA%s^dGNx9PMzXSMFy_IP09 z+!$g35Mt2nlN`qcQYP&VP!lX@Pd$G1frmb@%$V?<3GbvAl81&V!ZVk~xj6t6Msyh2 z#(g3>Ni7sYitSjE{&1qDO+P~hAti&gW2xugV~o ztCrThwuyhoY`DIa&71f>-A3DMHq6zIZ#J6#kx0IqgehqfciMY$?Zw|fcr=QeBmHfJ z35ow3;YXRyTY+$lu`7fL6RC*rS5Pk=3&Eb;9(b8{4K!vtJns@1|^2j zrK$aG{VZ`jeEjSHm^4KCjeK7rJqClArSW6gS)8jZ0gR%IvUda@vd4OyN}i{ILloul zG1V;R>Q1?A6>dpCWlfMV7;n&f?uCzDEavjL#azkC*}{wSxFvZ(^{4In*!wj}Zx0Vi zpf0WTT1_@YIWxJ6jFv}(Gm^`i$Ca>of9Ju@$%{@#`{`-+BSja95dc(Qk8s@IHWmmM z2E$k{y)5Kssx1QY@a0foT7MPN81?8gH>7H~7*LaJJYfI>hapb$_9 zC+L_6TwQ0P(#oOeW fRAMTToLH;Yrm>rvOps_}Yi25uN+psDo$BlF3vO`J literal 0 HcmV?d00001 diff --git a/tests/test_dumpers/ground_truth/yaml_xarray_ncs/my_temperature.date.values.nc b/tests/test_dumpers/ground_truth/yaml_xarray_ncs/my_temperature.date.values.nc new file mode 100644 index 0000000000000000000000000000000000000000..021a3a99c255ebf8c69e525677b6b5f0575d6f84 GIT binary patch literal 6176 zcmeHKPfrs;6o0!dxWNKd)PnKP>bW%A0!I>YyGUbc2}PnYW?ASq-9!r6E<{eA{Qw$2 zfX0I)UQG1j2k=W6J(_s-s_)Irqlno=FD524F!N^Sy?K9r^Jcd5WU0D1I&yIYs8|+c zAuqbz{7}W7lrubL{swnaXmhE$Y8JoT`PMmJKbzNue8yDESnWwVVuC>;!@|6gRpKzz zj<$X0zThF(p?M>#hH%;U9|dt79Qf@Z31n|Sh@)WhVd(oGl+p8-Fj|0&0Vl2UI4`jH zs;qX{_!aJ?)0d|oY>CiE*9}AZZbC~xYIkO<(RS3v`Md>3cBLG(vg8m|1OJ9`ods@v zq18gh1XhAYIEA!YTlN~QTC?G|+=aRaxefFgxkF-AV`14tA+hQPQeL&zjrunJ2X-$^ z-0Gr@`x*B7(N53a+)M1rk(?7J!E zu^HpefPO#p)|&3pZH|ERS1E(sdyGr?m!N;E-lDhaHC)e^{$0RSB>(8F^uuJJHl@dL z9BrABV{0kPgbf*tEkx3A;Pc6P-n=;VnxdmjrhNSSOukomdnh#AC7q;!GTLvrEAh^5 z7$;HK$N32a-4T3}0@x2@O33+2u{(!ZipOTYT$(94#csPZhuw0eM6BI|`I%C=Tyj?S z+VA8_-D(8>69jI#&APaN=mx;Tmk}Rk{>1X0H~&v1Spqcx literal 0 HcmV?d00001 diff --git a/tests/test_dumpers/ground_truth/yaml_xarray_ncs/my_temperature.day_in_d.values.nc b/tests/test_dumpers/ground_truth/yaml_xarray_ncs/my_temperature.day_in_d.values.nc new file mode 100644 index 0000000000000000000000000000000000000000..aef8e83a5900d58c26c93ea10b9745402dd23aa2 GIT binary patch literal 6160 zcmeHK&2AD=6h1RRoglSnwN&HJ=$a6q?ZO2~aTqKq1p>A4CuTY=gG?gOz_hU|*FJzg zfyRX`{?B*Moe9s@O6A%3r8v+q42VKf zO!@IE9LYt=;Wf**c`}98*Gf%2{r%3*&e8juenaR-^w5mmPSUsz8mY{P@LDufhgjS1 zIoSt7hSDtYwP?76D~|KT9S+??r|kx=oE^AB-`#oaInJjr=!MHzEkHzr$*8`ZC)49zt}r`C{ICRGj2KmrVKYF@D0?kt!5p5I1((tvSXsYg#a5{RmXzZtYMz^WEo zEfmb-O|Xchkd`VNcCA&Z*PNDBtlE&+#+*?a6IQk2hK)+XY85G4ZFc>UiI;2ky}&A! zP25kfKk^5Cb7wy=`-9+*h<7ey^2np7i_d#6B*O47gcB5&D#Z)O>IAaJIpSg)ge@*M z9XX7xJ{{WzS!ytch%6pKqFQNfVumOqUn#sPvKDp#WAGQ1sR?}KPQMPj?iN~#vA~n# zbp8ILn{{h#oh#w~4V^;bBi1MK3^328UACKc&9WVt=K{7Oh zjy9n_UQ!HMlqq=A@Zj^whVNdUdPCJwCsRNEe<$Bdy?-k_+$EpnfjZi$S&iXf&l?85 zH$whAZb(+hNeke>8&X3S^6Bmhb}1g4LN2qE$)>yQ&I(R*`3#Bn4hu_}TrQJs?6*Hi zOZ8L;oDc+VTlK1V5z*0R!Qh+aWJX2I5pb$_9Cy)5Kssx P1QY@afs=*+|L^||fu#Lx literal 0 HcmV?d00001 diff --git a/tests/test_dumpers/ground_truth/yaml_xarray_ncs/my_temperature.temperatures_in_K.values.nc b/tests/test_dumpers/ground_truth/yaml_xarray_ncs/my_temperature.temperatures_in_K.values.nc new file mode 100644 index 0000000000000000000000000000000000000000..873c77ce48f92743f8008d75569880e34657ce64 GIT binary patch literal 8256 zcmeHK%}-N75Z~9*`h+6oL#YPC({t0br6gVmCH;`b(i*C0g304yAK@kaO8X!X55$w2 zm=G@}#-o1#S1%krnt1W3;>imp9z1ZvncW>AXbsUcA!G;oW_M?1cjour&g?#$PG@_& zuXHmcU1wb^$eZ-omy|Tb2=z(6K#exMIGvvLgumY1T{`;P@m%Nn-Y#iI(;nyD9;Ts+ zKZH+>)S0jBRL$r-mmNxFS4d;q9<(`>%C3;cN9A1pDC%fkUSvR5O>@m^Hm!BDY`KyBgACA(=_3`CcGmrh6f17~#R8w@Iu}Q{8Q^#vIqC-zsH(9GEWmVT7Hs!nc`1>0s!kck zgE~2Fpqc=iw-^fmG8+8(!A@tX{8Xs~l0o=k@FE(<(z%&Tp_D5Y%u;G9pJ9Oo@EN2& zZdI6?$$&DqN&+XVJIhYXfPc%V*={PGHQ;^PwU$$_8H+2fQLDR$B0@i65XE7p7nRLw zClG#p4kiccG{T6)=|=e7_l<#0AiNIW98#wd#vOLL5q|P!^SwYgs%bY66U{4j2xW(p za+yVpN!WErNtWngiG4_FB5&L~&xhHbV5}>ETT#9U7~9*>2T%md8_016K_|#C4b;?F zALND5k$jNPmF_Th8Dy9*hT(_nX)+H|z9r7%Mnxb@qeuIgbdUBi3Fg)wZ530~x5#hG zcNA0LEkwh;a>1+FOg1x{DWo!{@ahr(i;H27Z`m%i{!ZlmL7I~4v|2lBTtgHEgR4;V zJQ^4wPIZMV!6WhE+s@gGj-u^pzBJBWbhKALHg%3HfE6UtLGNRO&LRLe&%j0lbfaA+VEHV~}hL_7r}yI+>Vda@r}mm(oHvE8mD>W{h1#H(J9iG_u7MTx}KBc3w_j5 yTp^$kPzWdl6aoqXg@8gpA)pXY2q**;0t$iuL*U1xv`-4IOCFSbNb->6BgtRexY3~i literal 0 HcmV?d00001 diff --git a/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_latitude.values.zarr/.zattrs b/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_latitude.values.zarr/.zattrs new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_latitude.values.zarr/.zattrs @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_latitude.values.zarr/.zgroup b/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_latitude.values.zarr/.zgroup new file mode 100644 index 0000000..3b7daf2 --- /dev/null +++ b/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_latitude.values.zarr/.zgroup @@ -0,0 +1,3 @@ +{ + "zarr_format": 2 +} \ No newline at end of file diff --git a/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_latitude.values.zarr/.zmetadata b/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_latitude.values.zarr/.zmetadata new file mode 100644 index 0000000..085537b --- /dev/null +++ b/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_latitude.values.zarr/.zmetadata @@ -0,0 +1,37 @@ +{ + "metadata": { + ".zattrs": {}, + ".zgroup": { + "zarr_format": 2 + }, + "__xarray_dataarray_variable__/.zarray": { + "chunks": [ + 2, + 2 + ], + "compressor": { + "blocksize": 0, + "clevel": 5, + "cname": "lz4", + "id": "blosc", + "shuffle": 1 + }, + "dtype": "v7s@vT(#ULL)Pd9h02qV?AOHXW literal 0 HcmV?d00001 diff --git a/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zattrs b/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zattrs new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zattrs @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zgroup b/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zgroup new file mode 100644 index 0000000..3b7daf2 --- /dev/null +++ b/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zgroup @@ -0,0 +1,3 @@ +{ + "zarr_format": 2 +} \ No newline at end of file diff --git a/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zmetadata b/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zmetadata new file mode 100644 index 0000000..572f002 --- /dev/null +++ b/tests/test_dumpers/ground_truth/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zmetadata @@ -0,0 +1,34 @@ +{ + "metadata": { + ".zattrs": {}, + ".zgroup": { + "zarr_format": 2 + }, + "__xarray_dataarray_variable__/.zarray": { + "chunks": [ + 2 + ], + "compressor": { + "blocksize": 0, + "clevel": 5, + "cname": "lz4", + "id": "blosc", + "shuffle": 1 + }, + "dtype": " Container: @@ -62,13 +62,14 @@ def _create_container() -> Container: def test_yaml_dumper(): """Test YamlDumper dumping to a YAML file.""" + # NOTE: YamlDumper dumps to a YAML string/stream, not a file container = _create_container() - schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") + schemaview = SchemaView(GROUND_TRUTH_DIR / "temperature_schema.yaml") ret = YamlDumper().dumps(container, schemaview=schemaview) # read and compare with the expected YAML file ignoring order of keys - expected_yaml_file = INPUT_DIR / "container_yaml.yaml" + expected_yaml_file = GROUND_TRUTH_DIR / "container_yaml.yaml" yaml = YAML(typ="safe") with open(expected_yaml_file) as f: expected = yaml.load(f) # load yaml into dictionary @@ -78,73 +79,81 @@ def test_yaml_dumper(): assert actual[key] == expected[key] -def test_yaml_numpy_dumper(): +def test_yaml_numpy_dumper(tmp_path): """Test YamlNumpyDumper dumping to a YAML file and NumPy .npy files in a directory.""" container = _create_container() - schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") - ret = YamlNumpyDumper().dumps(container, schemaview=schemaview, output_dir="./out") + output_yaml = tmp_path / "container_yaml_numpy.yaml" + schemaview = SchemaView(GROUND_TRUTH_DIR / "temperature_schema.yaml") + YamlNumpyDumper().dump(container, to_file=output_yaml, schemaview=schemaview) # read and compare with the expected YAML file ignoring order of keys - expected_yaml_file = INPUT_DIR / "container_yaml_numpy.yaml" + expected_yaml_file = GROUND_TRUTH_DIR / "container_yaml_numpy.yaml" yaml = YAML(typ="safe") - with open(expected_yaml_file) as f: - expected = yaml.load(f) # load yaml into dictionary - actual = yaml.load(ret) - assert actual == expected + with open(output_yaml) as f_actual: + with open(expected_yaml_file) as f_expected: + actual = yaml.load(f_actual) + expected = yaml.load(f_expected) + assert actual == expected -def test_yaml_hdf5_dumper(): +def test_yaml_hdf5_dumper(tmp_path): """Test YamlNumpyDumper dumping to a YAML file and HDF5 datasets in a directory.""" container = _create_container() - schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") - ret = YamlHdf5Dumper().dumps(container, schemaview=schemaview, output_dir="./out") + output_yaml = tmp_path / "container_yaml_hdf5.yaml" + schemaview = SchemaView(GROUND_TRUTH_DIR / "temperature_schema.yaml") + YamlHdf5Dumper().dump(container, to_file=output_yaml, schemaview=schemaview) # read and compare with the expected YAML file ignoring order of keys - expected_yaml_file = INPUT_DIR / "container_yaml_hdf5.yaml" + expected_yaml_file = GROUND_TRUTH_DIR / "container_yaml_hdf5.yaml" yaml = YAML(typ="safe") - with open(expected_yaml_file) as f: - expected = yaml.load(f) # load yaml into dictionary - actual = yaml.load(ret) - assert actual == expected + with open(output_yaml) as f_actual: + with open(expected_yaml_file) as f_expected: + actual = yaml.load(f_actual) + expected = yaml.load(f_expected) + assert actual == expected -def test_yaml_xarray_zarr_dumper(): +def test_yaml_xarray_zarr_dumper(tmp_path): """Test YamlXarrayDumper dumping to a YAML file and zarr datasets in a directory.""" container = _create_container() - schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") - ret = YamlXarrayZarrDumper().dumps(container, schemaview=schemaview, output_dir="./out") + output_yaml = tmp_path / "container_yaml_xarray_zarr.yaml" + schemaview = SchemaView(GROUND_TRUTH_DIR / "temperature_schema.yaml") + YamlXarrayZarrDumper().dump(container, to_file=output_yaml, schemaview=schemaview) # read and compare with the expected YAML file ignoring order of keys - expected_yaml_file = INPUT_DIR / "container_yaml_xarray_zarr.yaml" + expected_yaml_file = GROUND_TRUTH_DIR / "container_yaml_xarray_zarr.yaml" yaml = YAML(typ="safe") - with open(expected_yaml_file) as f: - expected = yaml.load(f) # load yaml into dictionary - actual = yaml.load(ret) - assert actual == expected + with open(output_yaml) as f_actual: + with open(expected_yaml_file) as f_expected: + actual = yaml.load(f_actual) + expected = yaml.load(f_expected) + assert actual == expected -def test_yaml_xarray_netcdf_dumper(): +def test_yaml_xarray_netcdf_dumper(tmp_path): """Test YamlXarrayNetCDFDumper dumping to a YAML file and netcdf datasets in a directory.""" container = _create_container() - schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") - ret = YamlXarrayNetCDFDumper().dumps(container, schemaview=schemaview, output_dir="./out") + output_yaml = tmp_path / "container_yaml_xarray_netcdf.yaml" + schemaview = SchemaView(GROUND_TRUTH_DIR / "temperature_schema.yaml") + YamlXarrayNetCDFDumper().dump(container, to_file=output_yaml, schemaview=schemaview) # read and compare with the expected YAML file ignoring order of keys - expected_yaml_file = INPUT_DIR / "container_yaml_xarray_netcdf.yaml" + expected_yaml_file = GROUND_TRUTH_DIR / "container_yaml_xarray_netcdf.yaml" yaml = YAML(typ="safe") - with open(expected_yaml_file) as f: - expected = yaml.load(f) # load yaml into dictionary - actual = yaml.load(ret) - assert actual == expected + with open(output_yaml) as f_actual: + with open(expected_yaml_file) as f_expected: + actual = yaml.load(f_actual) + expected = yaml.load(f_expected) + assert actual == expected def test_xarray_zarr_dumper(tmp_path): container = _create_container() - schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") + schemaview = SchemaView(GROUND_TRUTH_DIR / "temperature_schema.yaml") output_file_path = tmp_path / "my_container_xarray.zarr" XarrayZarrDumper().dumps(container, schemaview=schemaview, output_file_path=output_file_path) @@ -177,7 +186,7 @@ def test_xarray_zarr_dumper(tmp_path): def test_xarray_netcdf_dumper(tmp_path): container = _create_container() - schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") + schemaview = SchemaView(GROUND_TRUTH_DIR / "temperature_schema.yaml") output_file_path = tmp_path / "my_container.nc" XarrayNetCDFDumper().dumps(container, schemaview=schemaview, output_file_path=output_file_path) @@ -208,7 +217,7 @@ def test_hdf5_dumper(tmp_path): """Test Hdf5Dumper dumping to an HDF5 file.""" container = _create_container() - schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") + schemaview = SchemaView(GROUND_TRUTH_DIR / "temperature_schema.yaml") output_file_path = tmp_path / "my_container.h5" Hdf5Dumper().dumps(container, schemaview=schemaview, output_file_path=output_file_path) @@ -238,7 +247,7 @@ def test_zarr_directory_store_dumper(tmp_path): """Test ZarrDumper dumping to an HDF5 file.""" container = _create_container() - schemaview = SchemaView(INPUT_DIR / "temperature_schema.yaml") + schemaview = SchemaView(GROUND_TRUTH_DIR / "temperature_schema.yaml") output_file_path = tmp_path / "my_container.zarr" ZarrDirectoryStoreDumper().dumps( container, schemaview=schemaview, output_file_path=output_file_path diff --git a/tests/test_loaders/input/container_yaml.yaml b/tests/test_loaders/input/container_yaml.yaml new file mode 100644 index 0000000..8c1c32c --- /dev/null +++ b/tests/test_loaders/input/container_yaml.yaml @@ -0,0 +1,39 @@ +name: my_container +latitude_series: + name: my_latitude + values: + - - 1 + - 2 + - - 3 + - 4 +longitude_series: + name: my_longitude + values: + - - 5 + - 6 + - - 7 + - 8 +temperature_dataset: + name: my_temperature + latitude_in_deg: my_latitude + longitude_in_deg: my_longitude + temperatures_in_K: + conversion_factor: 1000 + values: + - - - 0 + - 1 + - - 2 + - 3 + - - - 4 + - 5 + - - 6 + - 7 + date: + values: + - "2020-01-01" + - "2020-01-02" + day_in_d: + values: + - 0 + - 1 + reference_date: "2020-01-01" diff --git a/tests/test_loaders/input/container_yaml_hdf5.yaml b/tests/test_loaders/input/container_yaml_hdf5.yaml new file mode 100644 index 0000000..cfe619e --- /dev/null +++ b/tests/test_loaders/input/container_yaml_hdf5.yaml @@ -0,0 +1,34 @@ +name: my_container +latitude_series: + name: my_latitude + values: + source: + - file: ./tests/test_loaders/input/yaml_hdf5_h5s/my_latitude.values.h5 + format: hdf5 +longitude_series: + name: my_longitude + values: + source: + - file: ./tests/test_loaders/input/yaml_hdf5_h5s/my_longitude.values.h5 + format: hdf5 +temperature_dataset: + date: + values: + source: + - file: ./tests/test_loaders/input/yaml_hdf5_h5s/my_temperature.date.values.h5 + format: hdf5 + day_in_d: + reference_date: '2020-01-01' + values: + source: + - file: ./tests/test_loaders/input/yaml_hdf5_h5s/my_temperature.day_in_d.values.h5 + format: hdf5 + latitude_in_deg: my_latitude + longitude_in_deg: my_longitude + name: my_temperature + temperatures_in_K: + conversion_factor: 1000.0 + values: + source: + - file: ./tests/test_loaders/input/yaml_hdf5_h5s/my_temperature.temperatures_in_K.values.h5 + format: hdf5 diff --git a/tests/test_loaders/input/container_yaml_numpy.yaml b/tests/test_loaders/input/container_yaml_numpy.yaml new file mode 100644 index 0000000..e4a26f0 --- /dev/null +++ b/tests/test_loaders/input/container_yaml_numpy.yaml @@ -0,0 +1,34 @@ +name: my_container +latitude_series: + name: my_latitude + values: + source: + - file: "./tests/test_loaders/input/yaml_numpy_npys/my_latitude.values.npy" + format: numpy +longitude_series: + name: my_longitude + values: + source: + - file: "./tests/test_loaders/input/yaml_numpy_npys/my_longitude.values.npy" + format: numpy +temperature_dataset: + date: + values: + source: + - file: "./tests/test_loaders/input/yaml_numpy_npys/my_temperature.date.values.npy" + format: numpy + day_in_d: + reference_date: '2020-01-01' + values: + source: + - file: "./tests/test_loaders/input/yaml_numpy_npys/my_temperature.day_in_d.values.npy" + format: numpy + latitude_in_deg: my_latitude + longitude_in_deg: my_longitude + name: my_temperature + temperatures_in_K: + conversion_factor: 1000.0 + values: + source: + - file: "./tests/test_loaders/input/yaml_numpy_npys/my_temperature.temperatures_in_K.values.npy" + format: numpy diff --git a/tests/test_loaders/input/container_yaml_xarray_netcdf.yaml b/tests/test_loaders/input/container_yaml_xarray_netcdf.yaml new file mode 100644 index 0000000..9be0753 --- /dev/null +++ b/tests/test_loaders/input/container_yaml_xarray_netcdf.yaml @@ -0,0 +1,34 @@ +name: my_container +latitude_series: + name: my_latitude + values: + source: + - file: "./tests/test_loaders/input/yaml_xarray_ncs/my_latitude.values.nc" + format: netcdf +longitude_series: + name: my_longitude + values: + source: + - file: "./tests/test_loaders/input/yaml_xarray_ncs/my_longitude.values.nc" + format: netcdf +temperature_dataset: + date: + values: + source: + - file: "./tests/test_loaders/input/yaml_xarray_ncs/my_temperature.date.values.nc" + format: netcdf + day_in_d: + reference_date: '2020-01-01' + values: + source: + - file: "./tests/test_loaders/input/yaml_xarray_ncs/my_temperature.day_in_d.values.nc" + format: netcdf + latitude_in_deg: my_latitude + longitude_in_deg: my_longitude + name: my_temperature + temperatures_in_K: + conversion_factor: 1000.0 + values: + source: + - file: "./tests/test_loaders/input/yaml_xarray_ncs/my_temperature.temperatures_in_K.values.nc" + format: netcdf diff --git a/tests/test_loaders/input/container_yaml_xarray_zarr.yaml b/tests/test_loaders/input/container_yaml_xarray_zarr.yaml new file mode 100644 index 0000000..6beb610 --- /dev/null +++ b/tests/test_loaders/input/container_yaml_xarray_zarr.yaml @@ -0,0 +1,34 @@ +name: my_container +latitude_series: + name: my_latitude + values: + source: + - file: "./tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr" + format: zarr +longitude_series: + name: my_longitude + values: + source: + - file: "./tests/test_loaders/input/yaml_xarray_zarrs/my_longitude.values.zarr" + format: zarr +temperature_dataset: + date: + values: + source: + - file: "./tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.date.values.zarr" + format: zarr + day_in_d: + reference_date: '2020-01-01' + values: + source: + - file: "./tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr" + format: zarr + latitude_in_deg: my_latitude + longitude_in_deg: my_longitude + name: my_temperature + temperatures_in_K: + conversion_factor: 1000.0 + values: + source: + - file: "./tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.temperatures_in_K.values.zarr" + format: zarr diff --git a/tests/test_loaders/input/my_container.h5 b/tests/test_loaders/input/my_container.h5 new file mode 100644 index 0000000000000000000000000000000000000000..1938a66e8fe890c8d6a13ddad67864f83628ddc1 GIT binary patch literal 15656 zcmeHO&ref95S~{At5z+>1OAHd*r>!xP*G#3QM8FhhV$JiY@3-q? z?WFEVR5Vwjxb?Amg**D_@5u2&z+N9CnEp=hZXDE_Fn&56tQ1P+!n8=6)=gClUP2&# z>q|$AzI{FZOviYUj|_1K8COJmb(r~CjQ@IncfT#Pe>`A5mI$rlcS7{7qrGX(3u?QT z$nT>3P;Ou*?Z%mNdOSe1LL@XZdGU1omBAJPPjEJIN_AOSDNHSvYeA_TR`dwbW%RSW z$#qD10+%zOYP^JA!#M$dlm2=r)*|^@`GJIJC_9uL%-$Ky!jJG6KzrnOSTVw8q+I+e z%Dz)E_CZYF1OQ<;>JV@UI0PI54grUNL%<>65O4@M1RMemfeuDM@|$*EB}I8-wa#Yh z{HAQ;P0}cwjm>kK{WUh*Iwz2#3Fzx*ef9jS&O#}LD6QmAbuPg(pT_$Ina>VhI3$r5 zjmw{IU1I|zKOpuvdOQ%Y^QTCMQ3n1aD7+8mm(}Y7le5=6UL_)Jol5>x{B8q&D|tBE zkHs$kI^RqBQHI-j@O_xFVfEX-1;K65BSQ3h7=r}>@sLRM)cY7+ByTCSN6ED$D&F*} zn5X551glL#Uynz=VyohtYvZ!ksCGb&{mPRRFl}D#0HeClgsAt|AFz(*FsG>aF^Bah zQ{V6S5osURx7a85x2egaCz-2r>&M2gR!l30VV}vFX*c#$3G*n~ z*iZRB<03m-ZV`Q!N=H$9U*+HEDD%3;7|GMwd5cEg@w~|sR>GOE5|*dTX-;)=Eo#3m z`;+GVi#`h!7vH{T88R2&y2f?()zGMYyKm*k_Iuwh{%_~w8vcL5_`f=Q_dcvtON-^g zOfXejG>7mM0{#AIJ-!Z~q2Zs_IY|Rj?o)1W{N|IPo=RltBKfetrII&`x_@+>&-&(u zlw(rA&edxNQL*Fqw)H(9gbhdG9#MIxA2{b*#3bY5@7z7^=;H5D@QT*w5EXyFz>h@Z z|BAo%`Sf?X0-_&H8@pX1dBB5%>j%E?{;5 literal 0 HcmV?d00001 diff --git a/tests/test_loaders/input/my_container.nc b/tests/test_loaders/input/my_container.nc new file mode 100644 index 0000000000000000000000000000000000000000..100f811a26496326c81c37bb378b34ecec60bafb GIT binary patch literal 16552 zcmeHOU2IfE6rQ`gT^72fTUwzYh6Pk0!m=#|RDxWxZ7sBHYfJdi#ARV`=_c*AZnuQK z05MS{8s$NQJ}I$L6OkC65H;~dkZ6d;7k?6hq7f1W5*{QW5zjX>XM6i|DNBkV+)2CV z&fl4tZ_b>1?>Xo0YpAU+nKWaPKnetePlV(p|6J4Q15=f7p6j>pg#&GFsBQHu+*^L6 z-Tr^ZGe@@f7U^!xb~v5n5eAyvH+~^g?pFFrI&0lj7pRl zG!rC`{2ip;3JhE}dzM_F5MePbAg1l6Rz(5Scsw525p(d0{u!$K1x3y7CIsFf!DMam> zb#?K!HO=uvTWobxod|Bh+OQAk6<@us4(!m&q<`kWz9ZcmroUu3W94GC_2E>y%gXeo zyEEafeYtR^J2zOhBbiMnw{}{QFsEwbbl!Tu|5hM;R`30-Mi@xk*$98}(cG;HVG`c? zG+kjRQ5+$|4l*5HMG}Byikf0kbInUK9fAlzruCtt+AF(#L6q7{0#ne>YltwYV3OAZ z&hoC#YM>e~}k_Sqq&LY_|{PU%uQDkIYJBk`Y`V-1ap`-<7BL0q@<&%uS^ zV;o95leu)RFJ&cqt!&!rou!VLY<+R@3qOJr&I!&#DV?TD+bL>V)3%=U7S-XDO{0I{ z;-ozYwmfhIFJR2)F=+p>OMMuP@nmhuSO>qt`Nu4BG>g`{`nuM-c&sj=W-*l(gjuAL zxn!@E1Mll5o^Adx>()G)Q)i4ZL<>3SO2$#HlKPy|JIDE}pLF~sv26ho2HgpQv?|tl zvF`3{DxFE@tX?^h5xUP|R5Zp2LDHnqY=vvmfA;@276fueBY$q)YF=7*=md@TWURSK z!iPPe#8Ao`BjvmL6Wh8oxnw$HWl;|yL*n&3qdTyKbNT1`Ea-D6id8r8*RI4ky!39RB!c6zlqM*$K zuri$3U;F&+HdltjYE7Elu(`5WoAooQyEa#T=U3S`hm>yDZiv@)>1gK4%@ddWf}Qox zMI*z6?<7kzHfk$q*-YSsEksmckF ze6F}fVr$;M!(#Vy!Gsq2dix0}AQhOU;o~D|>|{e*a1-_o)=v0w67g6|w!6p5=E$5) zJ<6#=6g|kU%73?SwkkQKh`!x!d{|{S4=H{3L6wy*K3yY3(;vtFwChiA{$gVj-H+*0|&od zi<6j4C~Hk0X-cc{AruPH zviQ?R-fFMd_=GCGpoj=ktI-3G@OH=#s^CZ2-w!_x@AvgnenX|$85E6z1O!&sZ<&HcjpxDTENC1a zz~wAsIt(H|PIa_8x+q$;D2kXfN@a?Stk>~>GH!|54CjjgI3%8bp6}4OL2;BPteU&O zE&?tBE&?tBE&?tBE&?tBE&?tBE&?tBE&_K10@BbU4U27;u&vvB$XkIcslf3=Jg@wO(f&ypoAcE-ldM_ZF~McfKF9|B>o`8ijfcH2>_b78PCMn5 z!A7Yx@$tvOTZsLN2r-o}M$)2rn-)M4{WAW@@WHB%6krqVoRz9zRqHqM3rAk^9#fTv r6%qfhZw^_RLg0~jl`1F1v7s@vT(#ULL)Pd9h02qV?AOHXW literal 0 HcmV?d00001 diff --git a/tests/test_loaders/input/my_container.zarr/temperature_dataset/day_in_d/.zattrs b/tests/test_loaders/input/my_container.zarr/temperature_dataset/day_in_d/.zattrs new file mode 100644 index 0000000..fc6cdcb --- /dev/null +++ b/tests/test_loaders/input/my_container.zarr/temperature_dataset/day_in_d/.zattrs @@ -0,0 +1,3 @@ +{ + "reference_date": "2020-01-01" +} \ No newline at end of file diff --git a/tests/test_loaders/input/my_container.zarr/temperature_dataset/day_in_d/.zgroup b/tests/test_loaders/input/my_container.zarr/temperature_dataset/day_in_d/.zgroup new file mode 100644 index 0000000..3b7daf2 --- /dev/null +++ b/tests/test_loaders/input/my_container.zarr/temperature_dataset/day_in_d/.zgroup @@ -0,0 +1,3 @@ +{ + "zarr_format": 2 +} \ No newline at end of file diff --git a/tests/test_loaders/input/my_container.zarr/temperature_dataset/day_in_d/values/.zarray b/tests/test_loaders/input/my_container.zarr/temperature_dataset/day_in_d/values/.zarray new file mode 100644 index 0000000..49bcc3c --- /dev/null +++ b/tests/test_loaders/input/my_container.zarr/temperature_dataset/day_in_d/values/.zarray @@ -0,0 +1,20 @@ +{ + "chunks": [ + 2 + ], + "compressor": { + "blocksize": 0, + "clevel": 5, + "cname": "lz4", + "id": "blosc", + "shuffle": 1 + }, + "dtype": "v7s@vT(#ULL)Pd9h02qV?AOHXW literal 0 HcmV?d00001 diff --git a/tests/test_loaders/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zarray b/tests/test_loaders/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zarray new file mode 100644 index 0000000..26011b4 --- /dev/null +++ b/tests/test_loaders/input/my_container_xarray.zarr/temperature_dataset/day_in_d/.zarray @@ -0,0 +1,20 @@ +{ + "chunks": [ + 2 + ], + "compressor": { + "blocksize": 0, + "clevel": 5, + "cname": "lz4", + "id": "blosc", + "shuffle": 1 + }, + "dtype": "zk7Ucm%mFfxE31A_!q zTo7tLy1I}cS62q0N|^aD8mf)KfCa*WIs+y=N{^5b@Njhu0C_b6>R(tYJpoN;uwY0@ zEJ*~hVd>EWCP606$iNCQ3u+)Eg9g|nMka^=%z9ijGce_YR0=BCGeFX=1A_@SgUNqp zh=W*xq9A!DCWwI?(44}|2vyFY08t1hE8whwUzk7Ucm%mFfxE31A_!q zTo7tLy1I}cS62q0N|^aD8mf)KfCa*WIs+y=N{^5b@Njhu0C_b6>R(tYJpoN;uwY0@ zEJ*~hVd>EWCP606$iNCQ3u+)Eg9g|nMka^=%z9ijGce_YR0=BCGeFX=1A_@SgUNqp zh=W*xq9A!DCWwI?(44}|2vyFY08t1hE8whwU+agpj#zAL{+%jL?~!krDVbX*UyY+k%wFTgu5?r_74hs(Pwf|!^?Whr6Rn%2H2#HMVGkex z0-q4z4}YqMnQPeVnCsSbw3t=(OAD^lGMUHgWg!dwFzAPjM?_W!<%izk7Ucm%mFfxE31A_!q zTo7tLy1I}cS62q0N|^aD8mf)KfCa*WIs+y=N{^5b@Njhu0C_b6>R(tYJpoN;uwY0@ zEJ*~hVd>EWCP606$iNCQ3u+)EG$k`KLIhye!)Rt;`Uc5>@(U!bI)H6v1@b`ROiWB* zjT}&Om>HqU(DEGv!vwIt!A1o8`MZE}G%Oz~Fb_5tj=Ezk7Ucm%mFfxE31A_!q zTo7tLy1I}cS62q0N|^aD8mf)KfCa*WIs+y=N{^5b@Njhu0C_b6>R(tYJpoN;uwY0@ zEJ*~hVd>EWCP606$iNCQ3u+)Eg9X?mMrMcr%z9#JW?)VL=@eA3XMm(-2L=;v29y8H z5C^gXMM3gROiW-4IG{NPXdN`^J3th|$qYD)9*kf=e-}`WhB}5p0qSmg*ga~;Xb6mk b04+n{gFV!A2MEmpr3Ik02$Yt9(lQPJqOUS| literal 0 HcmV?d00001 diff --git a/tests/test_loaders/input/yaml_numpy_npys/my_latitude.values.npy b/tests/test_loaders/input/yaml_numpy_npys/my_latitude.values.npy new file mode 100644 index 0000000000000000000000000000000000000000..1a5f0c4a86e9418046dfc33302700515824bd2aa GIT binary patch literal 160 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= mXCxM+0{I$7ItoUbItsN4WCJb+F!*2(p&1+?GzXLxZ~y@7nH_cj literal 0 HcmV?d00001 diff --git a/tests/test_loaders/input/yaml_numpy_npys/my_longitude.values.npy b/tests/test_loaders/input/yaml_numpy_npys/my_longitude.values.npy new file mode 100644 index 0000000000000000000000000000000000000000..1de6b75bdf880c258355a00629003a49b971acaf GIT binary patch literal 160 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= lXCxM+0{I$7ItoUbItsN4WCJb+Fc5Ko&=OEu21+Y9007tW9M=E< literal 0 HcmV?d00001 diff --git a/tests/test_loaders/input/yaml_numpy_npys/my_temperature.date.values.npy b/tests/test_loaders/input/yaml_numpy_npys/my_temperature.date.values.npy new file mode 100644 index 0000000000000000000000000000000000000000..f1d35a8db7c03dd2251ddd560c603830d8cab2ac GIT binary patch literal 208 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1Z6KZInuA`uymS0p-l$aNvUzCyxl5k7RDNY57 v7iT0EqyqUGMmm~03bhL411=*51_lElhS9oEz9EoCX2axRG_o9w4Uz)@azP&! literal 0 HcmV?d00001 diff --git a/tests/test_loaders/input/yaml_numpy_npys/my_temperature.day_in_d.values.npy b/tests/test_loaders/input/yaml_numpy_npys/my_temperature.day_in_d.values.npy new file mode 100644 index 0000000000000000000000000000000000000000..aff3acec66c3825ca308545c202e929f5331d7c6 GIT binary patch literal 144 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlWC!@qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= aXCxM+0{I$7I+{8PwF(pfE(R!Igwg;Dof}~Q literal 0 HcmV?d00001 diff --git a/tests/test_loaders/input/yaml_numpy_npys/my_temperature.temperatures_in_K.values.npy b/tests/test_loaders/input/yaml_numpy_npys/my_temperature.temperatures_in_K.values.npy new file mode 100644 index 0000000000000000000000000000000000000000..de28bf8633b898cc80c36a0a023ce09c19db0aea GIT binary patch literal 192 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= tXCxM+0{I$7Itn19siRPktaptJ~-mVnYS4gjGQ9-IIG literal 0 HcmV?d00001 diff --git a/tests/test_loaders/input/yaml_xarray_ncs/my_latitude.values.nc b/tests/test_loaders/input/yaml_xarray_ncs/my_latitude.values.nc new file mode 100644 index 0000000000000000000000000000000000000000..83133793029c2e84f735a0dab0f5bcf404f3edd8 GIT binary patch literal 8294 zcmeHMPfrs;6o1oySz(bXC}1?Ko{W;Fg>o{4l5J~=r6m;6#KW?uRF_?HV zegi*&S5KN4PndY{Gic!M!Gnq1@V%KGAk`XULNsJvyYpt|y_xskZ{NH<%(Fr^-`8`Y z2Z%HcA`s_Y+3W{YHN=b@OZl?wbm8Sfb|Eyjd;3fE=(7{L!u7-9V42*ullO#xkxFcs zS{9*}DC&4?R`MQ~9ZG|tkfz>+gl;TJoJE2mT(Yc(cC%@3T8{18qPJl;J$t3*TGnV_ z$(4Kny>H`nGZ;3JCI}_eXFC-5SQiNwNk8*PW1`KI1 zw1xXbHIjrvA-+&pyAc%zJ_mNBmyxbs>SLG`EQ`q=wDNpBAh zNuVyRbz4m~L^(6Kij0;=gENxLn#Yx}d4K1@_Q{J*M*Hb$_9I0XjS~P=Uk`EI+tTL= z7Y2h^FNY86rP*jS9j|WtZi|ETQ{C*6N2E-4sR~n7{EI4_5t-DB9%22?d$rnhapb$_9CI2I)ss=uv`|ilSh8&`v9yFDns`_iyOm8!OWG|F6N8B- z<2UdVc=e=-@q~#7KZ6GD9!=zi@6GH0sn!@1qapL!oi{V@&Aj)1`{wOoo)xnBfxZiU zK&0ysh8XY4<{+S&DQ4tY%2#Bk2QL@0i`vBA?Ju?C&#rcv>xV+YGP!Lx@6&*hN;FO_ z3sXxJse0>n@*bBRNrRz~rrv2nH<~2Q!od(O+V(@I)pEA%s^dGNx9PMzXSMFy_IP09 z+!$g35Mt2nlN`qcQYP&VP!lX@Pd$G1frmb@%$V?<3GbvAl81&V!ZVk~xj6t6Msyh2 z#(g3>Ni7sYitSjE{&1qDO+P~hAti&gW2xugV~o ztCrThwuyhoY`DIa&71f>-A3DMHq6zIZ#J6#kx0IqgehqfciMY$?Zw|fcr=QeBmHfJ z35ow3;YXRyTY+$lu`7fL6RC*rS5Pk=3&Eb;9(b8{4K!vtJns@1|^2j zrK$aG{VZ`jeEjSHm^4KCjeK7rJqClArSW6gS)8jZ0gR%IvUda@vd4OyN}i{ILloul zG1V;R>Q1?A6>dpCWlfMV7;n&f?uCzDEavjL#azkC*}{wSxFvZ(^{4In*!wj}Zx0Vi zpf0WTT1_@YIWxJ6jFv}(Gm^`i$Ca>of9Ju@$%{@#`{`-+BSja95dc(Qk8s@IHWmmM z2E$k{y)5Kssx1QY@a0foT7MPN81?8gH>7H~7*LaJJYfI>hapb$_9 zC+L_6TwQ0P(#oOeW fRAMTToLH;Yrm>rvOps_}Yi25uN+psDo$BlF3vO`J literal 0 HcmV?d00001 diff --git a/tests/test_loaders/input/yaml_xarray_ncs/my_temperature.date.values.nc b/tests/test_loaders/input/yaml_xarray_ncs/my_temperature.date.values.nc new file mode 100644 index 0000000000000000000000000000000000000000..021a3a99c255ebf8c69e525677b6b5f0575d6f84 GIT binary patch literal 6176 zcmeHKPfrs;6o0!dxWNKd)PnKP>bW%A0!I>YyGUbc2}PnYW?ASq-9!r6E<{eA{Qw$2 zfX0I)UQG1j2k=W6J(_s-s_)Irqlno=FD524F!N^Sy?K9r^Jcd5WU0D1I&yIYs8|+c zAuqbz{7}W7lrubL{swnaXmhE$Y8JoT`PMmJKbzNue8yDESnWwVVuC>;!@|6gRpKzz zj<$X0zThF(p?M>#hH%;U9|dt79Qf@Z31n|Sh@)WhVd(oGl+p8-Fj|0&0Vl2UI4`jH zs;qX{_!aJ?)0d|oY>CiE*9}AZZbC~xYIkO<(RS3v`Md>3cBLG(vg8m|1OJ9`ods@v zq18gh1XhAYIEA!YTlN~QTC?G|+=aRaxefFgxkF-AV`14tA+hQPQeL&zjrunJ2X-$^ z-0Gr@`x*B7(N53a+)M1rk(?7J!E zu^HpefPO#p)|&3pZH|ERS1E(sdyGr?m!N;E-lDhaHC)e^{$0RSB>(8F^uuJJHl@dL z9BrABV{0kPgbf*tEkx3A;Pc6P-n=;VnxdmjrhNSSOukomdnh#AC7q;!GTLvrEAh^5 z7$;HK$N32a-4T3}0@x2@O33+2u{(!ZipOTYT$(94#csPZhuw0eM6BI|`I%C=Tyj?S z+VA8_-D(8>69jI#&APaN=mx;Tmk}Rk{>1X0H~&v1Spqcx literal 0 HcmV?d00001 diff --git a/tests/test_loaders/input/yaml_xarray_ncs/my_temperature.day_in_d.values.nc b/tests/test_loaders/input/yaml_xarray_ncs/my_temperature.day_in_d.values.nc new file mode 100644 index 0000000000000000000000000000000000000000..aef8e83a5900d58c26c93ea10b9745402dd23aa2 GIT binary patch literal 6160 zcmeHK&2AD=6h1RRoglSnwN&HJ=$a6q?ZO2~aTqKq1p>A4CuTY=gG?gOz_hU|*FJzg zfyRX`{?B*Moe9s@O6A%3r8v+q42VKf zO!@IE9LYt=;Wf**c`}98*Gf%2{r%3*&e8juenaR-^w5mmPSUsz8mY{P@LDufhgjS1 zIoSt7hSDtYwP?76D~|KT9S+??r|kx=oE^AB-`#oaInJjr=!MHzEkHzr$*8`ZC)49zt}r`C{ICRGj2KmrVKYF@D0?kt!5p5I1((tvSXsYg#a5{RmXzZtYMz^WEo zEfmb-O|Xchkd`VNcCA&Z*PNDBtlE&+#+*?a6IQk2hK)+XY85G4ZFc>UiI;2ky}&A! zP25kfKk^5Cb7wy=`-9+*h<7ey^2np7i_d#6B*O47gcB5&D#Z)O>IAaJIpSg)ge@*M z9XX7xJ{{WzS!ytch%6pKqFQNfVumOqUn#sPvKDp#WAGQ1sR?}KPQMPj?iN~#vA~n# zbp8ILn{{h#oh#w~4V^;bBi1MK3^328UACKc&9WVt=K{7Oh zjy9n_UQ!HMlqq=A@Zj^whVNdUdPCJwCsRNEe<$Bdy?-k_+$EpnfjZi$S&iXf&l?85 zH$whAZb(+hNeke>8&X3S^6Bmhb}1g4LN2qE$)>yQ&I(R*`3#Bn4hu_}TrQJs?6*Hi zOZ8L;oDc+VTlK1V5z*0R!Qh+aWJX2I5pb$_9Cy)5Kssx P1QY@afs=*+|L^||fu#Lx literal 0 HcmV?d00001 diff --git a/tests/test_loaders/input/yaml_xarray_ncs/my_temperature.temperatures_in_K.values.nc b/tests/test_loaders/input/yaml_xarray_ncs/my_temperature.temperatures_in_K.values.nc new file mode 100644 index 0000000000000000000000000000000000000000..873c77ce48f92743f8008d75569880e34657ce64 GIT binary patch literal 8256 zcmeHK%}-N75Z~9*`h+6oL#YPC({t0br6gVmCH;`b(i*C0g304yAK@kaO8X!X55$w2 zm=G@}#-o1#S1%krnt1W3;>imp9z1ZvncW>AXbsUcA!G;oW_M?1cjour&g?#$PG@_& zuXHmcU1wb^$eZ-omy|Tb2=z(6K#exMIGvvLgumY1T{`;P@m%Nn-Y#iI(;nyD9;Ts+ zKZH+>)S0jBRL$r-mmNxFS4d;q9<(`>%C3;cN9A1pDC%fkUSvR5O>@m^Hm!BDY`KyBgACA(=_3`CcGmrh6f17~#R8w@Iu}Q{8Q^#vIqC-zsH(9GEWmVT7Hs!nc`1>0s!kck zgE~2Fpqc=iw-^fmG8+8(!A@tX{8Xs~l0o=k@FE(<(z%&Tp_D5Y%u;G9pJ9Oo@EN2& zZdI6?$$&DqN&+XVJIhYXfPc%V*={PGHQ;^PwU$$_8H+2fQLDR$B0@i65XE7p7nRLw zClG#p4kiccG{T6)=|=e7_l<#0AiNIW98#wd#vOLL5q|P!^SwYgs%bY66U{4j2xW(p za+yVpN!WErNtWngiG4_FB5&L~&xhHbV5}>ETT#9U7~9*>2T%md8_016K_|#C4b;?F zALND5k$jNPmF_Th8Dy9*hT(_nX)+H|z9r7%Mnxb@qeuIgbdUBi3Fg)wZ530~x5#hG zcNA0LEkwh;a>1+FOg1x{DWo!{@ahr(i;H27Z`m%i{!ZlmL7I~4v|2lBTtgHEgR4;V zJQ^4wPIZMV!6WhE+s@gGj-u^pzBJBWbhKALHg%3HfE6UtLGNRO&LRLe&%j0lbfaA+VEHV~}hL_7r}yI+>Vda@r}mm(oHvE8mD>W{h1#H(J9iG_u7MTx}KBc3w_j5 yTp^$kPzWdl6aoqXg@8gpA)pXY2q**;0t$iuL*U1xv`-4IOCFSbNb->6BgtRexY3~i literal 0 HcmV?d00001 diff --git a/tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr/.zattrs b/tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr/.zattrs new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr/.zattrs @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr/.zgroup b/tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr/.zgroup new file mode 100644 index 0000000..3b7daf2 --- /dev/null +++ b/tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr/.zgroup @@ -0,0 +1,3 @@ +{ + "zarr_format": 2 +} \ No newline at end of file diff --git a/tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr/.zmetadata b/tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr/.zmetadata new file mode 100644 index 0000000..085537b --- /dev/null +++ b/tests/test_loaders/input/yaml_xarray_zarrs/my_latitude.values.zarr/.zmetadata @@ -0,0 +1,37 @@ +{ + "metadata": { + ".zattrs": {}, + ".zgroup": { + "zarr_format": 2 + }, + "__xarray_dataarray_variable__/.zarray": { + "chunks": [ + 2, + 2 + ], + "compressor": { + "blocksize": 0, + "clevel": 5, + "cname": "lz4", + "id": "blosc", + "shuffle": 1 + }, + "dtype": "v7s@vT(#ULL)Pd9h02qV?AOHXW literal 0 HcmV?d00001 diff --git a/tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zattrs b/tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zattrs new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zattrs @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zgroup b/tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zgroup new file mode 100644 index 0000000..3b7daf2 --- /dev/null +++ b/tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zgroup @@ -0,0 +1,3 @@ +{ + "zarr_format": 2 +} \ No newline at end of file diff --git a/tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zmetadata b/tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zmetadata new file mode 100644 index 0000000..572f002 --- /dev/null +++ b/tests/test_loaders/input/yaml_xarray_zarrs/my_temperature.day_in_d.values.zarr/.zmetadata @@ -0,0 +1,34 @@ +{ + "metadata": { + ".zattrs": {}, + ".zgroup": { + "zarr_format": 2 + }, + "__xarray_dataarray_variable__/.zarray": { + "chunks": [ + 2 + ], + "compressor": { + "blocksize": 0, + "clevel": 5, + "cname": "lz4", + "id": "blosc", + "shuffle": 1 + }, + "dtype": " Date: Thu, 19 Sep 2024 10:46:39 -0700 Subject: [PATCH 37/38] Implement dump and raise error for dumps --- src/linkml_arrays/dumpers/hdf5_dumper.py | 10 ++++++---- src/linkml_arrays/dumpers/xarray_dumpers.py | 20 +++++++++++-------- .../dumpers/zarr_directory_store_dumper.py | 10 ++++++---- tests/test_dumpers/test_dumpers.py | 10 ++++------ 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/linkml_arrays/dumpers/hdf5_dumper.py b/src/linkml_arrays/dumpers/hdf5_dumper.py index eb50a03..538badb 100644 --- a/src/linkml_arrays/dumpers/hdf5_dumper.py +++ b/src/linkml_arrays/dumpers/hdf5_dumper.py @@ -39,14 +39,16 @@ def _iterate_element( class Hdf5Dumper(Dumper): """Dumper class for LinkML models to HDF5 files.""" - # TODO is this the right method to overwrite? it does not dump a string - def dumps( + def dump( self, element: Union[YAMLRoot, BaseModel], + to_file: str, schemaview: SchemaView, - output_file_path: Union[str, Path], **kwargs, ): """Dump the element to an HDF5 file.""" - with h5py.File(output_file_path, "w") as f: + with h5py.File(to_file, "w") as f: _iterate_element(element, schemaview, f) + + def dumps(self, element: Union[YAMLRoot, BaseModel], **kwargs): + raise NotImplementedError("This method is not sensible for this dumper.") diff --git a/src/linkml_arrays/dumpers/xarray_dumpers.py b/src/linkml_arrays/dumpers/xarray_dumpers.py index 08c6292..466bd6d 100644 --- a/src/linkml_arrays/dumpers/xarray_dumpers.py +++ b/src/linkml_arrays/dumpers/xarray_dumpers.py @@ -97,32 +97,36 @@ def _iterate_element( class XarrayNetCDFDumper(Dumper): """Dumper class for LinkML models to HDF5 files.""" - # TODO is this the right method to overwrite? it does not dump a string - def dumps( + def dump( self, element: Union[YAMLRoot, BaseModel], + to_file: str, schemaview: SchemaView, - output_file_path: Union[str, Path], **kwargs, ): """Dump the element to an HDF5 file.""" datatree = DataTree() datatree = _iterate_element(element, schemaview, datatree) - datatree.to_netcdf(output_file_path, engine='h5netcdf') + datatree.to_netcdf(to_file, engine='h5netcdf') + + def dumps(self, element: Union[YAMLRoot, BaseModel], **kwargs): + raise NotImplementedError("This method is not sensible for this dumper.") class XarrayZarrDumper(Dumper): """Dumper class for LinkML models to HDF5 files.""" - # TODO is this the right method to overwrite? it does not dump a string - def dumps( + def dump( self, element: Union[YAMLRoot, BaseModel], + to_file: str, schemaview: SchemaView, - output_file_path: Union[str, Path], **kwargs, ): """Dump the element to an HDF5 file.""" datatree = DataTree() datatree = _iterate_element(element, schemaview, datatree) - datatree.to_zarr(output_file_path) + datatree.to_zarr(to_file) + + def dumps(self, element: Union[YAMLRoot, BaseModel], **kwargs): + raise NotImplementedError("This method is not sensible for this dumper.") \ No newline at end of file diff --git a/src/linkml_arrays/dumpers/zarr_directory_store_dumper.py b/src/linkml_arrays/dumpers/zarr_directory_store_dumper.py index ca4e1d2..720e5f5 100644 --- a/src/linkml_arrays/dumpers/zarr_directory_store_dumper.py +++ b/src/linkml_arrays/dumpers/zarr_directory_store_dumper.py @@ -39,15 +39,17 @@ def _iterate_element( class ZarrDirectoryStoreDumper(Dumper): """Dumper class for LinkML models to Zarr directory stores.""" - # TODO is this the right method to overwrite? it does not dump a string - def dumps( + def dump( self, element: Union[YAMLRoot, BaseModel], + to_file: str, schemaview: SchemaView, - output_file_path: Union[str, Path], **kwargs, ): """Dump the element to a Zarr directory store.""" - store = zarr.DirectoryStore(output_file_path) + store = zarr.DirectoryStore(to_file) root = zarr.group(store=store, overwrite=True) _iterate_element(element, schemaview, root) + + def dumps(self, element: Union[YAMLRoot, BaseModel], **kwargs): + raise NotImplementedError("This method is not sensible for this dumper.") diff --git a/tests/test_dumpers/test_dumpers.py b/tests/test_dumpers/test_dumpers.py index 8221afd..7bfcfbb 100644 --- a/tests/test_dumpers/test_dumpers.py +++ b/tests/test_dumpers/test_dumpers.py @@ -155,7 +155,7 @@ def test_xarray_zarr_dumper(tmp_path): container = _create_container() schemaview = SchemaView(GROUND_TRUTH_DIR / "temperature_schema.yaml") output_file_path = tmp_path / "my_container_xarray.zarr" - XarrayZarrDumper().dumps(container, schemaview=schemaview, output_file_path=output_file_path) + XarrayZarrDumper().dump(container, to_file=output_file_path, schemaview=schemaview) assert os.path.exists(output_file_path) root = zarr.group(store=output_file_path) @@ -188,7 +188,7 @@ def test_xarray_netcdf_dumper(tmp_path): container = _create_container() schemaview = SchemaView(GROUND_TRUTH_DIR / "temperature_schema.yaml") output_file_path = tmp_path / "my_container.nc" - XarrayNetCDFDumper().dumps(container, schemaview=schemaview, output_file_path=output_file_path) + XarrayNetCDFDumper().dump(container, to_file=output_file_path, schemaview=schemaview) assert os.path.exists(output_file_path) datatree = open_datatree(output_file_path, engine='h5netcdf') @@ -219,7 +219,7 @@ def test_hdf5_dumper(tmp_path): schemaview = SchemaView(GROUND_TRUTH_DIR / "temperature_schema.yaml") output_file_path = tmp_path / "my_container.h5" - Hdf5Dumper().dumps(container, schemaview=schemaview, output_file_path=output_file_path) + Hdf5Dumper().dump(container, to_file=output_file_path, schemaview=schemaview) assert os.path.exists(output_file_path) with h5py.File(output_file_path, "r") as f: @@ -249,9 +249,7 @@ def test_zarr_directory_store_dumper(tmp_path): schemaview = SchemaView(GROUND_TRUTH_DIR / "temperature_schema.yaml") output_file_path = tmp_path / "my_container.zarr" - ZarrDirectoryStoreDumper().dumps( - container, schemaview=schemaview, output_file_path=output_file_path - ) + ZarrDirectoryStoreDumper().dump(container, to_file=output_file_path, schemaview=schemaview) assert os.path.exists(output_file_path) From 77a0feba8769ca5d79070efdca07f5a74452658f Mon Sep 17 00:00:00 2001 From: Wouter-Michiel Vierdag Date: Thu, 9 Jan 2025 14:29:12 +0100 Subject: [PATCH 38/38] adjust for deprecated data keyword argument --- src/linkml_arrays/dumpers/xarray_dumpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linkml_arrays/dumpers/xarray_dumpers.py b/src/linkml_arrays/dumpers/xarray_dumpers.py index 466bd6d..bddb206 100644 --- a/src/linkml_arrays/dumpers/xarray_dumpers.py +++ b/src/linkml_arrays/dumpers/xarray_dumpers.py @@ -88,7 +88,7 @@ def _iterate_element( datatree[k] = dataarray else: dataset = _create_node(v, schemaview) - datatree[k] = DataTree(data=dataset) + datatree[k] = DataTree(dataset) elif isinstance(v, str): datatree.attrs["name"] = v return datatree