taco-eo 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. taco_eo-0.3.0/.gitignore +34 -0
  2. taco_eo-0.3.0/CHANGELOG.md +98 -0
  3. taco_eo-0.3.0/LICENSE +21 -0
  4. taco_eo-0.3.0/PKG-INFO +75 -0
  5. taco_eo-0.3.0/README.md +32 -0
  6. taco_eo-0.3.0/examples/change_detection.py +78 -0
  7. taco_eo-0.3.0/examples/geospatial.py +61 -0
  8. taco_eo-0.3.0/examples/minimal.py +17 -0
  9. taco_eo-0.3.0/examples/numpy_minimal.py +48 -0
  10. taco_eo-0.3.0/examples/oceantaco_istac.py +321 -0
  11. taco_eo-0.3.0/examples/partitioned.py +34 -0
  12. taco_eo-0.3.0/examples/sequence.py +49 -0
  13. taco_eo-0.3.0/examples/stac_segmentation.py +209 -0
  14. taco_eo-0.3.0/examples/time_series.py +65 -0
  15. taco_eo-0.3.0/pyproject.toml +99 -0
  16. taco_eo-0.3.0/taco/__init__.py +40 -0
  17. taco_eo-0.3.0/taco/_graph.py +129 -0
  18. taco_eo-0.3.0/taco/_parquet.py +15 -0
  19. taco_eo-0.3.0/taco/_publish.py +97 -0
  20. taco_eo-0.3.0/taco/_repr.py +303 -0
  21. taco_eo-0.3.0/taco/_source.py +52 -0
  22. taco_eo-0.3.0/taco/_view.py +148 -0
  23. taco_eo-0.3.0/taco/contract/__init__.py +23 -0
  24. taco_eo-0.3.0/taco/contract/collection.py +410 -0
  25. taco_eo-0.3.0/taco/contract/contract.py +650 -0
  26. taco_eo-0.3.0/taco/contract/naming.py +215 -0
  27. taco_eo-0.3.0/taco/contract/sample.py +151 -0
  28. taco_eo-0.3.0/taco/contract/structure.py +130 -0
  29. taco_eo-0.3.0/taco/contract/types.py +279 -0
  30. taco_eo-0.3.0/taco/cozip.py +9 -0
  31. taco_eo-0.3.0/taco/dataset.py +88 -0
  32. taco_eo-0.3.0/taco/errors.py +37 -0
  33. taco_eo-0.3.0/taco/metadata/__init__.py +3 -0
  34. taco_eo-0.3.0/taco/metadata/_base.py +68 -0
  35. taco_eo-0.3.0/taco/metadata/asset.py +59 -0
  36. taco_eo-0.3.0/taco/metadata/collection.py +70 -0
  37. taco_eo-0.3.0/taco/metadata/derived.py +244 -0
  38. taco_eo-0.3.0/taco/metadata/folder.py +15 -0
  39. taco_eo-0.3.0/taco/metadata/sample.py +5 -0
  40. taco_eo-0.3.0/taco/metadata/spatiotemporal.py +207 -0
  41. taco_eo-0.3.0/taco/metadata/split.py +12 -0
  42. taco_eo-0.3.0/taco/py.typed +0 -0
  43. taco_eo-0.3.0/taco/reader/__init__.py +194 -0
  44. taco_eo-0.3.0/taco/reader/engine.py +67 -0
  45. taco_eo-0.3.0/taco/schema.py +287 -0
  46. taco_eo-0.3.0/taco/tacocat.py +157 -0
  47. taco_eo-0.3.0/taco/validate.py +517 -0
  48. taco_eo-0.3.0/taco/writer/__init__.py +73 -0
  49. taco_eo-0.3.0/taco/writer/archive.py +367 -0
  50. taco_eo-0.3.0/taco/writer/core.py +186 -0
  51. taco_eo-0.3.0/taco/writer/folder.py +211 -0
  52. taco_eo-0.3.0/taco/writer/metadata_tables.py +233 -0
  53. taco_eo-0.3.0/taco/writer/progress.py +46 -0
  54. taco_eo-0.3.0/taco/writer/staging.py +44 -0
  55. taco_eo-0.3.0/tests/__init__.py +0 -0
  56. taco_eo-0.3.0/tests/conftest.py +125 -0
  57. taco_eo-0.3.0/tests/datasets.py +538 -0
  58. taco_eo-0.3.0/tests/test_collection.py +171 -0
  59. taco_eo-0.3.0/tests/test_contract.py +220 -0
  60. taco_eo-0.3.0/tests/test_examples.py +41 -0
  61. taco_eo-0.3.0/tests/test_metadata.py +407 -0
  62. taco_eo-0.3.0/tests/test_parquet.py +16 -0
  63. taco_eo-0.3.0/tests/test_progress.py +64 -0
  64. taco_eo-0.3.0/tests/test_publish.py +88 -0
  65. taco_eo-0.3.0/tests/test_reader.py +268 -0
  66. taco_eo-0.3.0/tests/test_tacocat.py +141 -0
  67. taco_eo-0.3.0/tests/test_types.py +137 -0
  68. taco_eo-0.3.0/tests/test_validate.py +145 -0
  69. taco_eo-0.3.0/tests/test_writer.py +489 -0
  70. taco_eo-0.3.0/tests/test_writer_cases.py +219 -0
@@ -0,0 +1,34 @@
1
+
2
+ .DS_Store
3
+
4
+ spec/main.md
5
+
6
+ demo.zip
7
+ minimal.zip
8
+ /numpy-demo.zip
9
+ /change-detection/
10
+ /image-sequence.zip
11
+ /time-series.zip
12
+ /geospatial.zip
13
+ /partitioned_*.zip
14
+ /.tacocat/
15
+ .vscode/
16
+
17
+ .pytest_cache/
18
+ .coverage
19
+ __pycache__/
20
+ *.pyc
21
+ build/
22
+ *.egg-info/
23
+ python/.venv/
24
+ python/dist/
25
+ python/uv.lock
26
+ /julia/Manifest.toml
27
+
28
+ *.dylib
29
+
30
+ *.o
31
+
32
+ create-julia-skeleton.sh
33
+ _site/
34
+ numpy_demo.zip
@@ -0,0 +1,98 @@
1
+ # Changelog
2
+
3
+ All notable changes to `taco` are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
+
6
+ ## Unreleased
7
+
8
+ ### Changed
9
+
10
+ - Python, R, and Julia now share `open_dataset()` and `read()`. An open dataset
11
+ exposes its sources, collection, and contract in each language.
12
+ - STAC once again represents regular raster chunks with `tensor_shape` and a
13
+ six-value GDAL `geotransform`; it no longer stores a WKB footprint on every
14
+ sample. ISTAC is now a distinct irregular-geometry model instead of an alias
15
+ of STAC. Both retain centroid-based collection summaries, and metadata levels
16
+ must choose one of the two profiles.
17
+ - The reader keeps one DuckDB connection per thread.
18
+ - Collection and nested sample values are validated before writing.
19
+ - Python checks now cover formatting, strict typing, warnings and branch
20
+ coverage.
21
+ - The writer internals now follow the build flow explicitly (`core`, `archive`,
22
+ `folder`, `metadata_tables`, and `staging`) and use descriptive class and
23
+ method names. STAC/ISTAC definitions moved to `metadata.spatiotemporal`,
24
+ while `metadata.sample` remains a compatible import facade.
25
+
26
+ ### Removed
27
+
28
+ - The unused `staging_dir` writer option and `writer.ARCHIVE_SUFFIX` constant.
29
+
30
+ ## 0.2.0 - 2026-09-04
31
+
32
+ ### Changed
33
+
34
+ - The package is laid out as subpackages: `taco.contract` for the contract
35
+ vocabulary, `taco.writer` for the two writers and `taco.reader` for metadata
36
+ access, with `tacocat` and `validate` beside them. The top level exports ten
37
+ names, down from thirty-eight; everything else is imported from the
38
+ subpackage that owns it.
39
+ - `COLLECTION.json` records only the fields the caller declares. Nothing is
40
+ inferred from field names, so the writer no longer guesses an extent from
41
+ `stac:centroid` or `time_start`, and `_extent.py`, `auto_extent`,
42
+ `ExtentSpec`, `compute_extent` and `wkb_bounds` are gone. STAC is not part
43
+ of the core. A TACOCAT still merges the extents its partitions declare,
44
+ which TACO specification 7.5 requires.
45
+ - Archives are written as `.zip`. cozip specification 14.5 makes the profile
46
+ byte in the byte-0 index the only authoritative signal, and the extension
47
+ carries no meaning. Outputs are extensionless or end in `.zip`; any other
48
+ suffix is rejected.
49
+ - Reading a dataset is the `cozip` DuckDB extension's job. `open_dataset`,
50
+ `TacoDataset` and `vsi_subfile` are gone from the top-level API;
51
+ `taco.reader` forwards to the extension and builds no VSI paths itself. The
52
+ old Python mapping covered four URL schemes and the C++ one covers seven,
53
+ so the two had already drifted.
54
+ - The ZIP writer now delegates layout planning and serialization to cozip's
55
+ native TACO ABI through `cozip._taco.plan()` / `write()` instead of driving
56
+ the low-level entry API itself. Archive names, priority ordering, padding
57
+ placement and post-write verification are enforced in C. Local source and
58
+ output paths may contain Unicode.
59
+ - `Contract`, `Collection` and the writers raise `taco.errors.*`
60
+ exceptions (`ContractError`, `SampleError`, `CollectionError`,
61
+ `WriterError`, ...). They still subclass `ValueError` / `RuntimeError`.
62
+ - Metadata levels without fields may be omitted from `Contract(metadata=...)`
63
+ and from `Sample(metadata=...)`.
64
+ - `internal:relative_path` is written in `collection.parquet` too (the sample
65
+ index), matching the normative text of spec section 7.2.
66
+ - Lossy value conversions (floats into integer fields, bytes into strings,
67
+ ISO strings into timestamps) are rejected at `add()` time.
68
+
69
+ ### Added
70
+
71
+ - `taco:structure = null` datasets (one file per sample) in every container.
72
+ - Inline `bytes` assets, materialized into the staging directory on `add()`.
73
+ - `FolderWriter` / `open_folder()` for FOLDER mode with `append=True` and
74
+ optional hard links.
75
+ - Partitioned builds (`partition_size`, `partition_by`) producing
76
+ `<stem>_partNNNN.zip` / `<stem>_<value>.zip` plus a `.tacocat` directory;
77
+ `consolidate()` to build a TACOCAT from existing archives.
78
+ - An internal metadata view for ZIP, FOLDER and TACOCAT, used by
79
+ `consolidate` and `validate`.
80
+ - `validate()` for structural and contract checks across all three containers.
81
+ - Type specification parser supporting `timestamp[unit, tz]`, `list<...>`,
82
+ `struct<...>`, `map<...>`, `decimal128(p, s)`, `fixed_size_list<...>`.
83
+ - `parse_size()` and file-name sanitizing for partitioned builds.
84
+
85
+ ### Fixed
86
+
87
+ - `overwrite=False` uses an atomic no-replace publication step, so a file
88
+ created by another process during the build is left untouched.
89
+
90
+ ### Removed
91
+
92
+ - Direct use of `cozip.profile()` and the entry-based `cozip_plan` /
93
+ `cozip_finalize` calls.
94
+
95
+ ## 0.1.0 - 2026-09-02
96
+
97
+ - First prototype: `Contract`, `Asset`, `Sample`, `Collection`, staged
98
+ `TacoWriter` producing profile-2 `.tacozip` archives.
taco_eo-0.3.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Asterisk Laboratories Co-operative Limited
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
taco_eo-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,75 @@
1
+ Metadata-Version: 2.5
2
+ Name: taco-eo
3
+ Version: 0.3.0
4
+ Summary: Read and write TACO datasets in Python.
5
+ Project-URL: Homepage, https://asterisk.coop/taco
6
+ Project-URL: Specification, https://asterisk.coop/taco/spec
7
+ Project-URL: Repository, https://github.com/asterisk-labs/taco
8
+ Project-URL: Issues, https://github.com/asterisk-labs/taco/issues
9
+ Author-email: Cesar Aybar <cesar@asterisk.coop>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: cloud-optimized,cozip,earth-observation,geospatial,machine-learning,parquet,taco
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
+ Classifier: Topic :: Scientific/Engineering :: GIS
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.10
25
+ Requires-Dist: cozip>=2026.9.4
26
+ Requires-Dist: duckdb>=1.5.5
27
+ Requires-Dist: numpy>=1.24
28
+ Requires-Dist: pyarrow>=14
29
+ Requires-Dist: pydantic>=2.8
30
+ Provides-Extra: dev
31
+ Requires-Dist: mypy>=1.8; extra == 'dev'
32
+ Requires-Dist: pytest-cov>=5; extra == 'dev'
33
+ Requires-Dist: pytest>=8; extra == 'dev'
34
+ Requires-Dist: ruff>=0.5; extra == 'dev'
35
+ Provides-Extra: geoenrich
36
+ Requires-Dist: earthengine-api>=1; extra == 'geoenrich'
37
+ Provides-Extra: progress
38
+ Requires-Dist: tqdm>=4.66; extra == 'progress'
39
+ Provides-Extra: test
40
+ Requires-Dist: pytest-cov>=5; extra == 'test'
41
+ Requires-Dist: pytest>=8; extra == 'test'
42
+ Description-Content-Type: text/markdown
43
+
44
+ # taco
45
+
46
+ Read and write TACO datasets in Python.
47
+
48
+ ```bash
49
+ pip install taco-eo
50
+ python examples/minimal.py
51
+ ```
52
+
53
+ ```python
54
+ import taco
55
+
56
+ samples = taco.read("dataset.zip")
57
+ parts = taco.read(["part-0.zip", "part-1.zip"])
58
+ ```
59
+
60
+ ## Examples
61
+
62
+ Every example is self-contained, uses synthetic data, and writes its output in
63
+ the current directory.
64
+
65
+ | Example | What it demonstrates |
66
+ | --- | --- |
67
+ | [`minimal.py`](examples/minimal.py) | Smallest possible single-file dataset |
68
+ | [`numpy_minimal.py`](examples/numpy_minimal.py) | NumPy image and mask assets with a train/test split |
69
+ | [`change_detection.py`](examples/change_detection.py) | Metadata on `before/` and `after/` folders |
70
+ | [`sequence.py`](examples/sequence.py) | Variable-length asset sequences |
71
+ | [`time_series.py`](examples/time_series.py) | Per-observation time and cloud metadata |
72
+ | [`geospatial.py`](examples/geospatial.py) | Compact STAC metadata and derived MajorTOM cells |
73
+ | [`stac_segmentation.py`](examples/stac_segmentation.py) | Rich STAC metadata for regular raster chips, labels, bands, scaling, and statistics |
74
+ | [`oceantaco_istac.py`](examples/oceantaco_istac.py) | OceanTACO-inspired ISTAC metadata for irregular SWOT swaths and Argo collocations |
75
+ | [`partitioned.py`](examples/partitioned.py) | ZIP partitions and their TACOCAT catalog |
@@ -0,0 +1,32 @@
1
+ # taco
2
+
3
+ Read and write TACO datasets in Python.
4
+
5
+ ```bash
6
+ pip install taco-eo
7
+ python examples/minimal.py
8
+ ```
9
+
10
+ ```python
11
+ import taco
12
+
13
+ samples = taco.read("dataset.zip")
14
+ parts = taco.read(["part-0.zip", "part-1.zip"])
15
+ ```
16
+
17
+ ## Examples
18
+
19
+ Every example is self-contained, uses synthetic data, and writes its output in
20
+ the current directory.
21
+
22
+ | Example | What it demonstrates |
23
+ | --- | --- |
24
+ | [`minimal.py`](examples/minimal.py) | Smallest possible single-file dataset |
25
+ | [`numpy_minimal.py`](examples/numpy_minimal.py) | NumPy image and mask assets with a train/test split |
26
+ | [`change_detection.py`](examples/change_detection.py) | Metadata on `before/` and `after/` folders |
27
+ | [`sequence.py`](examples/sequence.py) | Variable-length asset sequences |
28
+ | [`time_series.py`](examples/time_series.py) | Per-observation time and cloud metadata |
29
+ | [`geospatial.py`](examples/geospatial.py) | Compact STAC metadata and derived MajorTOM cells |
30
+ | [`stac_segmentation.py`](examples/stac_segmentation.py) | Rich STAC metadata for regular raster chips, labels, bands, scaling, and statistics |
31
+ | [`oceantaco_istac.py`](examples/oceantaco_istac.py) | OceanTACO-inspired ISTAC metadata for irregular SWOT swaths and Argo collocations |
32
+ | [`partitioned.py`](examples/partitioned.py) | ZIP partitions and their TACOCAT catalog |
@@ -0,0 +1,78 @@
1
+ import io
2
+
3
+ import numpy as np
4
+ from pydantic import BaseModel
5
+
6
+ import taco
7
+
8
+
9
+ class Acquisition(BaseModel):
10
+ year: int
11
+
12
+
13
+ def encode(array: np.ndarray) -> bytes:
14
+ buffer = io.BytesIO()
15
+ np.save(buffer, array)
16
+ return buffer.getvalue()
17
+
18
+
19
+ raster = taco.metadata.asset.Raster
20
+ contract = taco.Contract(
21
+ structure=[
22
+ "before/B02.npy",
23
+ "before/B03.npy",
24
+ "after/B02.npy",
25
+ "after/B03.npy",
26
+ "change.npy",
27
+ ],
28
+ metadata=taco.MetadataSchema(
29
+ taco.Level("sample", ml=taco.metadata.sample.Split),
30
+ taco.Level("children", acquisition=Acquisition | None, raster=raster | None),
31
+ taco.Level("children/before", raster=raster),
32
+ taco.Level("children/after", raster=raster),
33
+ ),
34
+ )
35
+ collection = taco.Collection(
36
+ contract=contract,
37
+ id="change-detection",
38
+ dataset_version="1.0.0",
39
+ description="Paired observations and their change mask",
40
+ licenses=["MIT"],
41
+ providers=["Asterisk Labs"],
42
+ tasks=["change-detection"],
43
+ )
44
+
45
+ before = np.arange(2 * 16 * 16, dtype=np.uint16).reshape(2, 16, 16)
46
+ after = before.copy()
47
+ after[:, 5:11, 7:13] += 100
48
+ paths = {
49
+ "before/B02.npy": before[0],
50
+ "before/B03.npy": before[1],
51
+ "after/B02.npy": after[0],
52
+ "after/B03.npy": after[1],
53
+ "change.npy": np.any(before != after, axis=0),
54
+ }
55
+ assets = [
56
+ taco.Asset(
57
+ encode(array),
58
+ path=path,
59
+ metadata=taco.Metadata(raster=raster(resolution=10, num_bands=1, data_type=str(array.dtype))),
60
+ )
61
+ for path, array in paths.items()
62
+ ]
63
+ sample = taco.Sample(
64
+ assets=assets,
65
+ metadata=taco.Metadata(ml=taco.metadata.sample.Split(split="train")),
66
+ folders=[
67
+ taco.Folder("before", metadata=taco.Metadata(acquisition=Acquisition(year=2020))),
68
+ taco.Folder("after", metadata=taco.Metadata(acquisition=Acquisition(year=2024))),
69
+ ],
70
+ )
71
+
72
+ with taco.open_writer(collection, "change-detection", overwrite=True) as writer:
73
+ writer.add(sample)
74
+ writer.run()
75
+
76
+ dataset = taco.open_dataset("change-detection")
77
+ assert taco.read(dataset).num_rows == 1
78
+ assert taco.validate("change-detection").ok
@@ -0,0 +1,61 @@
1
+ import struct
2
+ from datetime import datetime, timezone
3
+
4
+ import taco
5
+
6
+
7
+ def point(longitude: float, latitude: float) -> bytes:
8
+ return struct.pack("<BIdd", 1, 1, longitude, latitude)
9
+
10
+
11
+ contract = taco.Contract(
12
+ structure=["image.bin"],
13
+ metadata=taco.MetadataSchema(
14
+ taco.Level(
15
+ "sample",
16
+ stac=taco.metadata.sample.STAC,
17
+ majortom=taco.metadata.sample.MajorTOM(
18
+ dist_km=100,
19
+ latitude_range=(-20, 0),
20
+ longitude_range=(-90, -60),
21
+ ),
22
+ ),
23
+ taco.Level("children", raster=taco.metadata.asset.Raster),
24
+ ),
25
+ )
26
+ collection = taco.Collection(
27
+ contract=contract,
28
+ id="peru-sites",
29
+ dataset_version="1.0.0",
30
+ description="Small geospatial dataset with derived MajorTOM cells",
31
+ licenses=["MIT"],
32
+ providers=["Asterisk Labs"],
33
+ tasks=["classification"],
34
+ )
35
+
36
+ sites = [(-77.04, -12.05), (-71.97, -13.53), (-80.63, -5.19)]
37
+ with taco.open_writer(collection, "geospatial.zip", overwrite=True) as writer:
38
+ for index, (longitude, latitude) in enumerate(sites):
39
+ location = point(longitude, latitude)
40
+ stac = taco.metadata.sample.STAC(
41
+ crs="EPSG:4326",
42
+ tensor_shape=(1, 8, 8),
43
+ geotransform=(longitude - 0.05, 0.0125, 0, latitude + 0.05, 0, -0.0125),
44
+ centroid=location,
45
+ time_start=datetime(2024, 1, index + 1, tzinfo=timezone.utc),
46
+ )
47
+ asset = taco.Asset(
48
+ bytes([index + 1]) * 64,
49
+ path="image.bin",
50
+ metadata=taco.Metadata(raster=taco.metadata.asset.Raster(resolution=10, num_bands=1, data_type="uint8")),
51
+ )
52
+ writer.add(taco.Sample(assets=asset, metadata=taco.Metadata(stac=stac)))
53
+ writer.run()
54
+
55
+ dataset = taco.open_dataset("geospatial.zip")
56
+ table = taco.read(dataset)
57
+ assert table.num_rows == 3
58
+ assert "majortom:code" in table.column_names
59
+ assert dataset.collection.extent is not None
60
+ assert dataset.collection.extent.spatial == (-80.63, -13.53, -71.97, -5.19)
61
+ assert taco.validate("geospatial.zip").ok
@@ -0,0 +1,17 @@
1
+ import taco
2
+
3
+ collection = taco.Collection(
4
+ contract=taco.Contract(structure=None),
5
+ id="minimal",
6
+ dataset_version="1.0.0",
7
+ description="Minimal TACO dataset",
8
+ licenses=["MIT"],
9
+ providers=["me"],
10
+ tasks=["other"],
11
+ )
12
+ with taco.open_writer(collection, "minimal.zip", overwrite=True) as writer:
13
+ writer.add(taco.Sample(assets=b"hello"))
14
+ writer.run()
15
+
16
+ dataset = taco.open_dataset("minimal.zip")
17
+ assert taco.read(dataset).num_rows == 1
@@ -0,0 +1,48 @@
1
+ import io
2
+
3
+ import numpy as np
4
+ from pydantic import BaseModel
5
+
6
+ import taco
7
+
8
+
9
+ class ML(BaseModel):
10
+ split: str
11
+
12
+
13
+ def encode(array: np.ndarray) -> bytes:
14
+ buffer = io.BytesIO()
15
+ np.save(buffer, array)
16
+ return buffer.getvalue()
17
+
18
+
19
+ contract = taco.Contract(
20
+ structure=["image.npy", "mask.npy"],
21
+ metadata=taco.MetadataSchema(taco.Level("sample", ml=ML)),
22
+ )
23
+ collection = taco.Collection(
24
+ contract=contract,
25
+ id="numpy-demo",
26
+ dataset_version="1.0.0",
27
+ description="Small NumPy dataset",
28
+ licenses=["MIT"],
29
+ providers=["me"],
30
+ tasks=["segmentation"],
31
+ )
32
+ with taco.open_writer(collection, "numpy-demo.zip", overwrite=True) as writer:
33
+ for index in range(10):
34
+ image = np.random.default_rng(index).random((3, 32, 32), dtype=np.float32)
35
+ writer.add(
36
+ taco.Sample(
37
+ metadata=taco.Metadata(ml=ML(split="train" if index < 8 else "test")),
38
+ assets=[
39
+ taco.Asset(encode(image), path="image.npy"),
40
+ taco.Asset(encode(image[0] > 0.5), path="mask.npy"),
41
+ ],
42
+ )
43
+ )
44
+ writer.run()
45
+
46
+ dataset = taco.open_dataset("numpy-demo.zip")
47
+ assert taco.read(dataset).num_rows == 10
48
+ assert taco.validate("numpy-demo.zip").ok