sdata 1.5.0__py3-none-any.whl

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 (98) hide show
  1. sdata/__init__.py +140 -0
  2. sdata/base.py +684 -0
  3. sdata/contrib/__init__.py +0 -0
  4. sdata/contrib/piexif/__init__.py +12 -0
  5. sdata/contrib/piexif/_common.py +94 -0
  6. sdata/contrib/piexif/_dump.py +346 -0
  7. sdata/contrib/piexif/_exceptions.py +2 -0
  8. sdata/contrib/piexif/_exif.py +638 -0
  9. sdata/contrib/piexif/_insert.py +60 -0
  10. sdata/contrib/piexif/_load.py +270 -0
  11. sdata/contrib/piexif/_remove.py +56 -0
  12. sdata/contrib/piexif/_transplant.py +45 -0
  13. sdata/contrib/piexif/_webp.py +240 -0
  14. sdata/contrib/piexif/helper.py +66 -0
  15. sdata/contrib/ranger/__init__.py +8 -0
  16. sdata/contrib/ranger/collections/__init__.py +0 -0
  17. sdata/contrib/ranger/collections/rangebucketmap.py +346 -0
  18. sdata/contrib/ranger/collections/rangemap.py +396 -0
  19. sdata/contrib/ranger/collections/rangeset.py +483 -0
  20. sdata/contrib/ranger/range/__init__.py +0 -0
  21. sdata/contrib/ranger/range/cut.py +285 -0
  22. sdata/contrib/ranger/range/range.py +644 -0
  23. sdata/contrib/sobol_seq.py +394 -0
  24. sdata/contrib/sortedcontainers/LICENSE +13 -0
  25. sdata/contrib/sortedcontainers/__init__.py +74 -0
  26. sdata/contrib/sortedcontainers/sorteddict.py +789 -0
  27. sdata/contrib/sortedcontainers/sortedlist.py +2646 -0
  28. sdata/contrib/sortedcontainers/sortedset.py +733 -0
  29. sdata/contrib/sqlitedict.py +598 -0
  30. sdata/contrib/timeflake/__init__.py +40 -0
  31. sdata/contrib/timeflake/flake.py +69 -0
  32. sdata/contrib/timeflake/utils.py +47 -0
  33. sdata/deprecated/__init__.py +10 -0
  34. sdata/deprecated/data.py +1503 -0
  35. sdata/did/__init__.py +129 -0
  36. sdata/did/_http.py +67 -0
  37. sdata/did/base58btc.py +49 -0
  38. sdata/did/did_github.py +152 -0
  39. sdata/did/did_peer4.py +155 -0
  40. sdata/did/did_web.py +222 -0
  41. sdata/did/diddoc.py +75 -0
  42. sdata/did/ed25519.py +225 -0
  43. sdata/did/eddsa.py +107 -0
  44. sdata/did/errors.py +40 -0
  45. sdata/did/issue_vc.py +193 -0
  46. sdata/did/jose.py +126 -0
  47. sdata/did/keys.py +104 -0
  48. sdata/did/utils_didkey.py +161 -0
  49. sdata/did/verify_vp.py +158 -0
  50. sdata/doe.py +101 -0
  51. sdata/dtypes.py +510 -0
  52. sdata/experiments/__init__.py +331 -0
  53. sdata/experiments/blob0.py +131 -0
  54. sdata/experiments/file.py +42 -0
  55. sdata/experiments/filegroup.py +144 -0
  56. sdata/experiments/image_old.py +313 -0
  57. sdata/experiments/ks2.py +15 -0
  58. sdata/experiments/lapshear.py +8 -0
  59. sdata/experiments/material.py +7 -0
  60. sdata/experiments/parameters_deprecated.py +394 -0
  61. sdata/experiments/workbook.py +226 -0
  62. sdata/format.py +125 -0
  63. sdata/imagemeta.py +533 -0
  64. sdata/interactive.py +118 -0
  65. sdata/iolib/__init__.py +51 -0
  66. sdata/iolib/hashtree.py +264 -0
  67. sdata/iolib/json1sqlitestore.py +554 -0
  68. sdata/iolib/jsonsqlitestore.py +704 -0
  69. sdata/iolib/pud.py +242 -0
  70. sdata/iolib/reader.py +262 -0
  71. sdata/iolib/writer.py +419 -0
  72. sdata/metadata.py +882 -0
  73. sdata/parameter.py +414 -0
  74. sdata/schema.py +273 -0
  75. sdata/sclass/__init__.py +111 -0
  76. sdata/sclass/bfo_classes.py +362 -0
  77. sdata/sclass/blob.py +362 -0
  78. sdata/sclass/content.py +87 -0
  79. sdata/sclass/dataframe.py +1251 -0
  80. sdata/sclass/dataframegroup.py +187 -0
  81. sdata/sclass/dependency_graph.py +85 -0
  82. sdata/sclass/filereference.py +124 -0
  83. sdata/sclass/image.py +218 -0
  84. sdata/sclass/lazy_namespace.py +155 -0
  85. sdata/sclass/process.py +383 -0
  86. sdata/sclass/process_graph.py +221 -0
  87. sdata/sclass/zipfile.py +135 -0
  88. sdata/semantic.py +346 -0
  89. sdata/suuid.py +136 -0
  90. sdata/timestamp.py +336 -0
  91. sdata/tools.py +14 -0
  92. sdata/units.py +602 -0
  93. sdata/vocab.py +149 -0
  94. sdata-1.5.0.dist-info/METADATA +264 -0
  95. sdata-1.5.0.dist-info/RECORD +98 -0
  96. sdata-1.5.0.dist-info/WHEEL +5 -0
  97. sdata-1.5.0.dist-info/licenses/LICENSE-MIT +21 -0
  98. sdata-1.5.0.dist-info/top_level.txt +1 -0
sdata/vocab.py ADDED
@@ -0,0 +1,149 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Vokabular & JSON-LD-``@context`` für die semantische Metadaten-Schicht.
3
+
4
+ Reine-Python-Tabellen (keine Abhängigkeit): Namespace-Präfixe, ein
5
+ ``@context``-Builder, das XSD-Typ-Mapping (aus :mod:`sdata.dtypes`) und die
6
+ Auflösung von BFO-Topologieklassen sowie von Attribut-``ontology``-Annotationen.
7
+
8
+ Designentscheidungen (siehe Projektplan):
9
+
10
+ * **Identität**: ``@id`` eines Objekts ist seine DID ``did:suuid:<sname>:sdata``.
11
+ * **``ontology`` = immer ``@type``/Klasse** des Werts (z.B. ``bfo:Quality``); das
12
+ Subjekt→Wert-**Prädikat** kommt NICHT aus ``ontology``, sondern ist
13
+ ``sdata:<name>`` (bzw. ein gemappter schema.org/qudt-Term).
14
+ """
15
+ import re
16
+
17
+ import sdata.dtypes as dtypes
18
+
19
+ __all__ = [
20
+ "SDATA_NS", "NAMESPACES", "CONTEXT_TERMS", "CONTEXT_URL", "BFO_IRIS",
21
+ "build_context", "xsd_for_dtype", "expand_curie", "bfo_iri",
22
+ "safe_term", "predicate_for", "type_iri",
23
+ ]
24
+
25
+ #: Namespace-IRI des sdata-Vokabulars (auflösbar via GitHub Pages des Repos).
26
+ SDATA_NS = "https://lepy.github.io/sdata/ns#"
27
+ #: gehostetes JSON-LD-@context (statische Datei ``ns/context.jsonld`` im Repo-Root,
28
+ #: von GitHub Pages unter dieser URL ausgeliefert).
29
+ CONTEXT_URL = "https://lepy.github.io/sdata/ns/context.jsonld"
30
+
31
+ NAMESPACES = {
32
+ "sdata": SDATA_NS,
33
+ "schema": "https://schema.org/",
34
+ "dcterms": "http://purl.org/dc/terms/",
35
+ "dcat": "http://www.w3.org/ns/dcat#",
36
+ "prov": "http://www.w3.org/ns/prov#",
37
+ "qudt": "http://qudt.org/schema/qudt/",
38
+ "unit": "http://qudt.org/vocab/unit/",
39
+ "xsd": "http://www.w3.org/2001/XMLSchema#",
40
+ "bfo": "http://purl.obolibrary.org/obo/",
41
+ "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
42
+ "csvw": "http://www.w3.org/ns/csvw#",
43
+ "did": "https://www.w3.org/ns/did#",
44
+ }
45
+
46
+ #: JSON-LD-Term-Definitionen (ergänzen die Präfixe im ``@context``).
47
+ CONTEXT_TERMS = {
48
+ "name": "schema:name",
49
+ "description": "schema:description",
50
+ "generatedAtTime": {"@id": "prov:generatedAtTime", "@type": "xsd:dateTime"},
51
+ "wasDerivedFrom": {"@id": "prov:wasDerivedFrom", "@type": "@id"},
52
+ "isPartOf": {"@id": "dcterms:isPartOf", "@type": "@id"},
53
+ "identifier": "dcterms:identifier",
54
+ "topologyClass": {"@id": "sdata:topologyClass", "@type": "@id"},
55
+ "value": "qudt:value",
56
+ "unitRef": {"@id": "qudt:unit", "@type": "@id"},
57
+ "symbol": "qudt:symbol",
58
+ "label": "rdfs:label",
59
+ # Formelzeichen der Größe (RFC 0016); "symbol" bleibt das Einheiten-Symbol
60
+ "quantitySymbol": "sdata:quantitySymbol",
61
+ "required": {"@id": "sdata:required", "@type": "xsd:boolean"},
62
+ # tabellarische Spalten (CSVW)
63
+ "columns": {"@id": "csvw:column", "@container": "@list"},
64
+ "datatype": {"@id": "csvw:datatype", "@type": "@id"},
65
+ # Klasse der Spaltenwerte (``ontology`` der Spalte; wie ``rdfType`` im Data Package)
66
+ "rdfType": {"@id": "sdata:rdfType", "@type": "@id"},
67
+ }
68
+
69
+ #: BFO-2.0-Klassenname -> OBO-CURIE (für ``_sdata_topology_class``).
70
+ BFO_IRIS = {
71
+ "Entity": "bfo:BFO_0000001",
72
+ "Continuant": "bfo:BFO_0000002",
73
+ "Occurrent": "bfo:BFO_0000003",
74
+ "IndependentContinuant": "bfo:BFO_0000004",
75
+ "SpatialRegion": "bfo:BFO_0000006",
76
+ "Process": "bfo:BFO_0000015",
77
+ "Disposition": "bfo:BFO_0000016",
78
+ "RealizableEntity": "bfo:BFO_0000017",
79
+ "Quality": "bfo:BFO_0000019",
80
+ "SpecificallyDependentContinuant": "bfo:BFO_0000020",
81
+ "Role": "bfo:BFO_0000023",
82
+ "Site": "bfo:BFO_0000029",
83
+ "GenericallyDependentContinuant": "bfo:BFO_0000031",
84
+ "Function": "bfo:BFO_0000034",
85
+ "MaterialEntity": "bfo:BFO_0000040",
86
+ "ImmaterialEntity": "bfo:BFO_0000141",
87
+ "RelationalQuality": "bfo:BFO_0000145",
88
+ }
89
+
90
+
91
+ def build_context(mode="inline", extra=None):
92
+ """Liefere das JSON-LD-``@context`` (``inline`` = vollständige Term-Map) oder
93
+ – bei ``mode="url"`` – die gehostete Context-URL.
94
+
95
+ :param mode: ``"inline"`` (default) oder ``"url"``
96
+ :param extra: optionale zusätzliche Term-Definitionen
97
+ """
98
+ if mode == "url":
99
+ return CONTEXT_URL
100
+ ctx = dict(NAMESPACES)
101
+ ctx.update(CONTEXT_TERMS)
102
+ if extra:
103
+ ctx.update(extra)
104
+ return ctx
105
+
106
+
107
+ def xsd_for_dtype(dtype):
108
+ """XSD-Typ-CURIE für einen sdata-dtype (String oder Klasse)."""
109
+ return dtypes.XSD.get(dtypes.resolve(dtype) or "str", "xsd:string")
110
+
111
+
112
+ def expand_curie(curie):
113
+ """Expandiere eine CURIE (``schema:name``) zur vollen IRI; IRIs/Unbekanntes
114
+ werden unverändert zurückgegeben."""
115
+ if not isinstance(curie, str) or ":" not in curie:
116
+ return curie
117
+ prefix, _, local = curie.partition(":")
118
+ if curie.startswith("http://") or curie.startswith("https://"):
119
+ return curie
120
+ base = NAMESPACES.get(prefix)
121
+ return base + local if base else curie
122
+
123
+
124
+ def bfo_iri(topology_class):
125
+ """Mappe einen Topologieklassen-String (``"sdata.sclass:IndependentContinuant"``)
126
+ auf die BFO-CURIE oder ``None``, falls unbekannt/leer."""
127
+ if not topology_class:
128
+ return None
129
+ local = str(topology_class).rsplit(":", 1)[-1]
130
+ return BFO_IRIS.get(local)
131
+
132
+
133
+ def safe_term(name):
134
+ """Normalisiere einen Attributnamen zu einem CURIE-tauglichen lokalen Teil."""
135
+ local = re.sub(r"[^0-9A-Za-z_]", "_", str(name)).strip("_")
136
+ return local or "attribute"
137
+
138
+
139
+ def predicate_for(attr_name):
140
+ """Subjekt→Wert-Prädikat für ein User-Attribut: Default ``sdata:<safe_name>``."""
141
+ return "sdata:" + safe_term(attr_name)
142
+
143
+
144
+ def type_iri(ontology):
145
+ """``@type``/Klasse eines Werts aus dem ``ontology``-Feld (CURIE/IRI) oder
146
+ ``None``. (``ontology`` ist per Projektentscheidung stets eine Klasse.)"""
147
+ if not ontology:
148
+ return None
149
+ return str(ontology)
@@ -0,0 +1,264 @@
1
+ Metadata-Version: 2.4
2
+ Name: sdata
3
+ Version: 1.5.0
4
+ Summary: a structured data format
5
+ Author-email: Ingolf Lepenies <lepy@tuta.io>
6
+ Maintainer-email: Ingolf Lepenies <lepy@tuta.io>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/lepy/sdata
9
+ Project-URL: Documentation, https://lepy.github.io/sdata/
10
+ Keywords: open data
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Natural Language :: English
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3.9
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 :: Implementation :: CPython
21
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE-MIT
25
+ Requires-Dist: numpy
26
+ Requires-Dist: pandas
27
+ Requires-Dist: suuid>=0.2.0
28
+ Provides-Extra: did
29
+ Provides-Extra: http
30
+ Requires-Dist: requests; extra == "http"
31
+ Provides-Extra: excel
32
+ Requires-Dist: openpyxl; extra == "excel"
33
+ Requires-Dist: xlsxwriter; extra == "excel"
34
+ Requires-Dist: tabulate; extra == "excel"
35
+ Provides-Extra: hdf
36
+ Requires-Dist: h5py; extra == "hdf"
37
+ Provides-Extra: sql
38
+ Requires-Dist: sqlalchemy; extra == "sql"
39
+ Provides-Extra: parquet
40
+ Requires-Dist: pyarrow; extra == "parquet"
41
+ Provides-Extra: blob
42
+ Requires-Dist: fsspec; extra == "blob"
43
+ Provides-Extra: units
44
+ Requires-Dist: pint; extra == "units"
45
+ Provides-Extra: rdf
46
+ Requires-Dist: rdflib; extra == "rdf"
47
+ Provides-Extra: schema
48
+ Requires-Dist: jsonschema; extra == "schema"
49
+ Dynamic: license-file
50
+
51
+
52
+ [![PyPI](https://img.shields.io/pypi/v/sdata.svg?style=flat-square)](https://pypi.python.org/pypi/sdata/)
53
+ [![Python versions](https://img.shields.io/pypi/pyversions/sdata.svg?style=flat-square)](https://pypi.python.org/pypi/sdata/)
54
+ [![Docs](https://img.shields.io/badge/docs-mkdocs--material-blue?style=flat-square)](https://lepy.github.io/sdata/)
55
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4311323.svg)](https://doi.org/10.5281/zenodo.4311323)
56
+
57
+ # Structured data format (sdata)
58
+
59
+ ## Design goals & status
60
+
61
+ sdata is an open, self-describing data format for open-science projects. The
62
+ table below is an honest status of the original design goals (triaged in
63
+ [RFC 0008](docs/rfc/0008-bestandsaufnahme-roadmap.md)) — **implemented**,
64
+ **partial**, on the **roadmap**, or an explicit **non-goal**.
65
+
66
+ | Goal | Status | Notes |
67
+ |------|--------|-------|
68
+ | Open, self-describing data | **implemented** | metadata embedded in every format |
69
+ | Platform independent, simple object model | **implemented** | pure Python / numpy / pandas |
70
+ | Standard metadata formats (key/value, JSON-LD, …) | **implemented** | `Metadata`, QUDT/BFO/PROV/CSVW/DID/VC |
71
+ | Physical units + conversion | **implemented** | `sdata.units` (RFC 0006) |
72
+ | Standard dataset formats — HDF5, CSV, Parquet, Arrow, Data Package | **implemented** | HDF5 via `sdata[hdf]` |
73
+ | (De-)serialization of data + metadata | **implemented** | lossless round-trips |
74
+ | Data format versions | **implemented** | `_sdata_format_version` + migration (RFC 0010) |
75
+ | Project standards (e.g. tensile test) | **partial** | schema templates (`MetadataSchema`/`TableSchema`) |
76
+ | Series | **partial** | as a one-column table |
77
+ | Hierarchical structure / nested groups | **partial** | `DataFrameGroup` (flat) + `parent`/`project` relations |
78
+ | Transparent compression | **partial** | Parquet-internal (zstd); zlib is a **non-goal** for the store (speed) |
79
+ | Standard dataset formats — **netCDF** | **roadmap** | not implemented |
80
+ | Dataset types — **datacubes** | **roadmap** | not implemented |
81
+ | Optional encryption (gpg, …) | **non-goal** | encrypt blobs/filesystem out of band |
82
+ | posix-path syntax, change management, tensor-library interop, SWMR | **non-goal** | not planned; revisit on demand |
83
+
84
+ Machine-readable metadata is the backbone (see below); the optional semantic
85
+ backends degrade gracefully to pure Python.
86
+
87
+ ## Quickstart
88
+
89
+ ```python
90
+ import pandas as pd
91
+ from sdata.sclass.dataframe import DataFrame
92
+
93
+ df = pd.DataFrame({"force": [1.0, 2.0, 3.0]})
94
+ data = DataFrame(df=df, name="specimen_01", description="a tension test")
95
+ data.metadata.add("max_force", 12.5, unit="kN", dtype="float",
96
+ description="max force", ontology="bfo:Quality")
97
+
98
+ print(data.metadata.df[["value", "unit", "dtype", "ontology"]])
99
+ ```
100
+
101
+ ```
102
+ value unit dtype ontology
103
+ key
104
+ _sdata_name specimen_01 - str
105
+ _sdata_sname DataFrame__specimen_01__3003... - str
106
+ ...
107
+ max_force 12.5 kN float bfo:Quality
108
+ ```
109
+
110
+ Every object has a deterministic, content-addressable identity (`SUUID`), a set
111
+ of reserved `_sdata_*` attributes (name, sname, suuid, class, ctime, parent,
112
+ project, topology class) and freely extensible, fully-described user attributes.
113
+
114
+ ## Machine-readable metadata (JSON-LD / Linked Data)
115
+
116
+ The metadata is the backbone of the data description: it lives next to every
117
+ data blob and fully qualifies the data — units (QUDT/UCUM), ontology classes
118
+ (BFO), provenance (PROV/DCAT), tabular columns (CSVW) and identity (DID).
119
+
120
+ ```python
121
+ # self-describing JSON-LD (qudt:Quantity units, BFO @type, did:suuid @id, csvw columns)
122
+ doc = data.to_jsonld()
123
+
124
+ # RDF/Turtle (uses rdflib if installed, otherwise returns the JSON-LD)
125
+ print(data.to_turtle())
126
+
127
+ # write the data + a sidecar <sname>.meta.jsonld right next to it
128
+ data.to_json("specimen_01.sjson", sidecar=True)
129
+
130
+ # validate / auto-complete against a schema template
131
+ from sdata.schema import MetadataSchema, AttrSpec
132
+ schema = MetadataSchema("TensileTest", [
133
+ AttrSpec("max_force", dtype="float", unit="kN", required=True, ontology="bfo:Quality"),
134
+ ])
135
+ report = data.metadata.validate(schema) # ValidationReport (truthy if ok)
136
+
137
+ # sign the metadata as a W3C Verifiable Credential (pure-Python Ed25519)
138
+ from sdata.did import keys, pub_from_priv_jwk
139
+ priv = keys.gen_ed25519_jwk()
140
+ vc = data.metadata.to_verifiable_credential("did:example:issuer", priv)
141
+ subject = data.metadata.from_verifiable_credential(vc, pub_from_priv_jwk(priv))
142
+
143
+ # interactive: attribute autocomplete + rich Jupyter display
144
+ data.metadata.a.max_force # -> Attribute; tab-completion in Jupyter
145
+ data.metadata # -> _repr_html_ table
146
+ ```
147
+
148
+ Resulting JSON-LD for `max_force` (excerpt):
149
+
150
+ ```json
151
+ {
152
+ "@id": "did:suuid:DataFrame__specimen_01__3003...:sdata",
153
+ "@type": ["sdata:DataFrame", "bfo:BFO_0000004"],
154
+ "name": "specimen_01",
155
+ "sdata:max_force": {
156
+ "@type": ["qudt:Quantity", "bfo:Quality"],
157
+ "value": {"@value": 12.5, "@type": "xsd:double"},
158
+ "unitRef": "unit:KiloN", "symbol": "kN"
159
+ },
160
+ "columns": [{"name": "force", "datatype": "xsd:double"}]
161
+ }
162
+ ```
163
+
164
+ The optional semantic backends degrade gracefully to pure Python (no hard
165
+ dependency): `pip install "sdata[rdf]"` (rdflib), `sdata[units]` (pint),
166
+ `sdata[schema]` (jsonschema). Core install needs only `numpy`, `pandas`, `suuid`.
167
+
168
+ ## Tabular data (`DataFrame`)
169
+
170
+ `DataFrame` wraps a pandas frame plus per-column metadata and serializes to many
171
+ formats — Parquet, Arrow/Feather, CSV, dict/JSON, JSON-LD, a Frictionless **Data
172
+ Package** and **HDF5** — with the qualifying metadata embedded or written as a
173
+ sidecar.
174
+
175
+ ```python
176
+ import pandas as pd
177
+ from sdata.sclass.dataframe import DataFrame
178
+
179
+ sdf = DataFrame(df=pd.DataFrame({"weight": [10, 20], "height": [1.5, 1.6]}),
180
+ name="specimen_01", description="a tension test")
181
+
182
+ # per-column annotations (only the fields you pass are changed)
183
+ sdf.set_column("weight", unit="kg", label="Gewicht", ontology="bfo:Quality")
184
+ sdf.col["height"].unit = "m" # mutate the column Attribute in place
185
+ sdf.column_units # {'weight': 'kg', 'height': 'm'}
186
+
187
+ # serialize (optional <sname>.meta.jsonld sidecar; bytes/str without a path)
188
+ sdf.to_parquet(path="out", sidecar=True) # out/<sname>.spq + sidecar
189
+ sdf.to_csv(path="out") # data-only CSV (pure pandas)
190
+ sdf.to_feather(path="out") # Arrow IPC + native per-column field metadata
191
+ sdf.to_datapackage(path="out") # Frictionless Data Package (.zip)
192
+ sdf.to_hdf(path="out") # HDF5 via h5py, one dataset/column (sdata[hdf])
193
+ DataFrame.from_parquet("out/specimen_01.spq")
194
+
195
+ # validate the table against a schema (missing/dtype/unit/extra columns)
196
+ from sdata.schema import TableSchema, AttrSpec
197
+ schema = TableSchema("TensileTable", [
198
+ AttrSpec("weight", dtype="int", unit="kg", required=True),
199
+ ])
200
+ report = sdf.validate_table(schema) # ValidationReport (truthy if ok)
201
+ ```
202
+
203
+ Arrow/Feather/Parquet need `pip install "sdata[parquet]"`, HDF5 `sdata[hdf]`; CSV,
204
+ dict, JSON-LD and the (CSV) Data Package work with the core install. See the
205
+ [Tabular data docs](https://lepy.github.io/sdata/usage/dataframe/)
206
+ ([`docs/usage/dataframe.md`](docs/usage/dataframe.md)) for the full reference.
207
+
208
+ ## Howto
209
+
210
+
211
+ * [Das sdata-Format - slides](https://lepy.github.io/sdata/ipynb/Das_sdata_Format.slides.html#)
212
+ * https://deepwiki.com/lepy/sdata
213
+
214
+ ## Demo App
215
+
216
+ * [test the demo app with editor](https://share.streamlit.io/lepy/sdata_streamlit/main/sdata_editor.py)
217
+
218
+ Try to paste some Excel-Data in the forms ...
219
+
220
+
221
+ ## Metadata
222
+
223
+ ### Attributes
224
+
225
+ * name
226
+ * value
227
+ * dtype
228
+ * unit
229
+ * description
230
+ * label
231
+ * required
232
+ * ontology (CURIE/IRI of the value's class, e.g. `bfo:Quality`)
233
+
234
+ ### dtypes for attributes
235
+
236
+ Every attribute value is coerced to a declared dtype (single source:
237
+ `sdata.dtypes`), each with a lossless JSON-LD / XSD mapping:
238
+
239
+ * `int`, `float`, `str`, `bool`
240
+ * `list` (list of strings), `floatlist` (typed list of floats)
241
+ * `timestamp` (ISO-8601 with timezone, stdlib `zoneinfo`)
242
+ * `date`, `time`, `duration` (ISO-8601 / `datetime` types)
243
+ * `decimal` (exact decimal), `complex` (complex number)
244
+ * `bytes` (base64 in JSON), `json` (dict/list), `uri`
245
+ * `langstring` (language-tagged string, `rdf:langString`, e.g. `"Hallo@de"`)
246
+
247
+ Coercion is **lenient** by default (invalid values are logged and left unchanged).
248
+ Pass `strict=True` (e.g. `metadata.add(..., strict=True)`) to raise `DtypeError`
249
+ instead. See the [conventions](https://lepy.github.io/sdata/conventions/) for the
250
+ error policy.
251
+
252
+ ## paper
253
+
254
+ * [Das sdata-Format](https://zenodo.org/record/4311323#.X89yo9-YXys)
255
+ * Ingolf Lepenies. (2020). Das sdata-Format (Version 0.8.4). http://doi.org/10.5281/zenodo.4311323
256
+ * [slides](https://lepy.github.io/sdata/ipynb/Das_sdata_Format.slides.html#),
257
+ [html](https://lepy.github.io/sdata/paper/2020/Das_sdata-Format.html),
258
+ [pdf](https://lepy.github.io/sdata/paper/2020/Das_sdata-Format.pdf)
259
+ [temperaturmessung-001.json](https://lepy.github.io/sdata/paper/2020/temperaturmessung-001.json)
260
+ [temperaturmessung-001.xlsx](https://lepy.github.io/sdata/paper/2020/temperaturmessung-001.xlsx)
261
+
262
+ * [sdata](https://doi.org/10.5281/zenodo.4311396)
263
+ * Ingolf Lepenies. (2020, December 8). sdata - a structured data format (Version 0.8.4). Zenodo. http://doi.org/10.5281/zenodo.4311397
264
+
@@ -0,0 +1,98 @@
1
+ sdata/__init__.py,sha256=-dI783pOCXydCJVS71HU9EDfZExf1jWK38qahVm7Erg,4716
2
+ sdata/base.py,sha256=5R6CWnuthahksvR6biLKrFq2YzfggbCCtn80wv5J4es,24399
3
+ sdata/doe.py,sha256=0F87fwsl8OqDkAXd907-MamiK85WhH8B0XgaSBHmMZw,3131
4
+ sdata/dtypes.py,sha256=dvg0XsbZ4dB0iwzNSeq5tahGc29zLT2XDYI_p35DnaY,17952
5
+ sdata/format.py,sha256=oyWvesvSVqMoYub8p0SUUd-3pfzj0H4TNbUMEpB7v1M,4779
6
+ sdata/imagemeta.py,sha256=Qd7sylMjM6KZyaRkt3_NGCTFIuRXf9b-bwm5vOfUvMY,20874
7
+ sdata/interactive.py,sha256=e5QqE2MkVZE7X-9d20NiT2yjfD672HU2pCi5J3w2kDI,4273
8
+ sdata/metadata.py,sha256=dRN6-8ZLDqLMKnx6AADjKrCQVSxMQMAHMhZaHOpzZa4,29467
9
+ sdata/parameter.py,sha256=XdF9Nmi4WwMkwmTFGGn7jhc12kHPkiac_GSQf6vyd_0,13652
10
+ sdata/schema.py,sha256=M1CSm6C2X3Rvw8LlNCRuY8z-L61uZwhSc2UQOTs8RAU,10933
11
+ sdata/semantic.py,sha256=aC7seRkomXD__np-m_YItVQ3WmbvB7bdAErYDIE78Do,12706
12
+ sdata/suuid.py,sha256=TJftRPguUgyu4XTSXiaIgW4F3Dj33nmjcTNhh90baVY,5549
13
+ sdata/timestamp.py,sha256=6tP_Phl9fwbjxIVdFJ2QhYqux6Zw76n1x6azRZ14Pv0,10279
14
+ sdata/tools.py,sha256=dhvllyLdk27qQ789iCVt0-n61tJ4RxRG29w5FXEoPqk,337
15
+ sdata/units.py,sha256=7NGg_wsa_qCEORMPr371R7vBrWYBLa33vPWQewUZde4,24925
16
+ sdata/vocab.py,sha256=9KcnKVMRfPK5USuVw2F2ABrnztwiT2Ic4Q95tIaS9dw,5780
17
+ sdata/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ sdata/contrib/sobol_seq.py,sha256=MRId2aaG66UOjYcs6Yt4EV1Xndu1t4ASJpTf_I38hhI,12870
19
+ sdata/contrib/sqlitedict.py,sha256=FA1hLZfOyWcjdjQgunyFk0pvxN8-JACol7COFdD_Rwg,22903
20
+ sdata/contrib/piexif/__init__.py,sha256=rezSWjJWI9hsUDIt49f04x8ziNeZianluuD2Cq64uDk,231
21
+ sdata/contrib/piexif/_common.py,sha256=PNDCYnbeJNA8Zae-YDtFdzqLFOQ35v9Mv2GaAr9w9Bc,2590
22
+ sdata/contrib/piexif/_dump.py,sha256=zozYuWiRPYKObyZmoaa4eXZYfuK7yU0LHziW2pXDG2c,12749
23
+ sdata/contrib/piexif/_exceptions.py,sha256=17AbJRsaB0m519TAOmT2pgOzp75quibOCk0WBoDO06s,50
24
+ sdata/contrib/piexif/_exif.py,sha256=N9NjeoYNSlBV37RbVLHOwX_OGiJq14RUpJI3kcvLKIQ,29812
25
+ sdata/contrib/piexif/_insert.py,sha256=2tSkjFjJDwGNRycBptvQeS8Rl0Z5DrdgkGEeR7lXs2E,1868
26
+ sdata/contrib/piexif/_load.py,sha256=jKIrEWD1yjhF47gsAvRDyTCKbiVf5JkSjxuLNqwuXyU,12230
27
+ sdata/contrib/piexif/_remove.py,sha256=s7JtaEdpNl_1S9gZKVvNg4ItHE4sEhm4lFooYliP_wc,1535
28
+ sdata/contrib/piexif/_transplant.py,sha256=Z4KytfkdYqhIpVCBg4rIPClfZP35HKhwYym3uSphn7Q,1225
29
+ sdata/contrib/piexif/_webp.py,sha256=gAq26vEdS2LaKgsR2219lSsDQzH4mqikemI0zuNkAao,7889
30
+ sdata/contrib/piexif/helper.py,sha256=dAil29ji-kEPb3y7QPtUEOUOqBoah9B2rSmltepBksI,2460
31
+ sdata/contrib/ranger/__init__.py,sha256=7HB21tTtNqzCRCe_diignOfOJXRFBijTbQwcGXhkHJY,323
32
+ sdata/contrib/ranger/collections/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
+ sdata/contrib/ranger/collections/rangebucketmap.py,sha256=su_qeRz-g025JtxPe6IPBEHJbF-VDR3e9guk2xB0jhw,16305
34
+ sdata/contrib/ranger/collections/rangemap.py,sha256=C2TaT4Tt4Z3jaPKxDDRatbt8UyGP_fC4wps3d1U8zzs,16239
35
+ sdata/contrib/ranger/collections/rangeset.py,sha256=3FG8ylCQt6ezcOoDrm_qxFzoDRgYy-kz4aUQWAqJuO8,20556
36
+ sdata/contrib/ranger/range/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
+ sdata/contrib/ranger/range/cut.py,sha256=DE_SlzlFcmr8WSUcM1AwgPx3hwdSCBKhhvv-syI3qXA,8833
38
+ sdata/contrib/ranger/range/range.py,sha256=_sRyZCEF7KdjMDZ3tuYAye30YC6uzzQgBuGR_ljx9JY,19804
39
+ sdata/contrib/sortedcontainers/LICENSE,sha256=HbfK5_zmRS4uYI5AGg-VPgEz5MLXXbafuK6FHSCG9bY,557
40
+ sdata/contrib/sortedcontainers/__init__.py,sha256=KNPfSbw7lLIaInY6zANDaD9c-pTfxQ0HaEpIfk46qOQ,2131
41
+ sdata/contrib/sortedcontainers/sorteddict.py,sha256=yGLHZOwcSqYe3Ed2iZcMpQH5RH_ypG_rbexj-45_nL0,22154
42
+ sdata/contrib/sortedcontainers/sortedlist.py,sha256=rwA1dM8ce09eb2DMjLOfHoikhCx_Rfk5nuE_NSsfr3I,76331
43
+ sdata/contrib/sortedcontainers/sortedset.py,sha256=5RI2CUJGMm1ig3-dhbOrzDl8aPqDePkoJPQoq0ROS7M,19825
44
+ sdata/contrib/timeflake/__init__.py,sha256=cWKQH48zZwXNW2x-UqljzLJxgu7JvPrEg8o1NGU_qiI,1283
45
+ sdata/contrib/timeflake/flake.py,sha256=OSNCEVo3Vo57PBOzkJa9iHKajU_walmEicyUptPFKCo,1735
46
+ sdata/contrib/timeflake/utils.py,sha256=AdyaF91dLt8mJDwANz2m3a0GSebhggCxgmA2SdN2IA0,1044
47
+ sdata/deprecated/__init__.py,sha256=ask8WL4L0Zf4U6iseEwb9k_ffhl9fi5dqBgRJ4bqjbY,336
48
+ sdata/deprecated/data.py,sha256=dI3Ae9Y01dqfmyepUTxHJc9pedjHzjR5nrZNACoNCz8,50953
49
+ sdata/did/__init__.py,sha256=zjWI5D3HFLft1btrzWSE3PIBvpwH9vHxfyLKQ4CHrEY,6217
50
+ sdata/did/_http.py,sha256=cHObbRCJsAeratlpIF8Ctz2Z3itGTyxBehS8LMgZ_sE,2510
51
+ sdata/did/base58btc.py,sha256=0KcHYQI9Kotp9qaEhdiyw3WycuKqN284mlR0tHpfqnY,1566
52
+ sdata/did/did_github.py,sha256=JG-ktgZQRVl9L8vy38ndRhnrqxDTV7jWvmUOJy1YTJQ,5155
53
+ sdata/did/did_peer4.py,sha256=9CZxQl-zX2JVt45eg4qCTtyKe2X4kCc4mPvltHNBTu8,5721
54
+ sdata/did/did_web.py,sha256=Z-MkbU4uuzff42ABMQG0e4Gi1HrL_rXQBHcRuytXsro,8190
55
+ sdata/did/diddoc.py,sha256=8yFWKe3sBxRZKti4663R8z1lpoB88DRQPjyavJxnTk8,2451
56
+ sdata/did/ed25519.py,sha256=j9gfF8qViEGq01UoBp9vqNTGB0ugShHUp-hVrOgCM6M,6924
57
+ sdata/did/eddsa.py,sha256=MfAmhU-LT_5LWqpq3tgUa8TtAKWvjwxFVru3zGy8Lr0,3638
58
+ sdata/did/errors.py,sha256=RHx7MRqq0KgBX34JBhfbGv4saRMsI5inQQj_D3C00zI,1388
59
+ sdata/did/issue_vc.py,sha256=HS3KV0ydOWDRY4H4-xIZfbyDh75fMPQLQhwDssWsoUo,6781
60
+ sdata/did/jose.py,sha256=KRk8-0MCsx37di2hg0B1nU24D2Q4vt9Zq9BBt0pFad8,4903
61
+ sdata/did/keys.py,sha256=zm6BFFte4EIECg6Z9scLbfmbz5JjcdnsHtcDNv6YV6Q,3520
62
+ sdata/did/utils_didkey.py,sha256=wJm_5QjHeT6muNlAgSM17P-_DWMaXBBxA8ujGE7_fq4,6318
63
+ sdata/did/verify_vp.py,sha256=8ihY4urrajjPVJvlQ3vHgvc39OO0tWrEf5VvHpVKxOM,5667
64
+ sdata/experiments/__init__.py,sha256=enImO0mzemJwTzz9tgkJ0jLtys3Lkr9RAKa4Eshph14,13342
65
+ sdata/experiments/blob0.py,sha256=2aeHR-4o7x_W4cPz6-B9H9ynRsy9mVB1QY9fOb1HBeE,3639
66
+ sdata/experiments/file.py,sha256=rdeP3AF5-9eKtLebA3e0bESloo6_Hlc0nHAVWnbD_18,856
67
+ sdata/experiments/filegroup.py,sha256=QcXks1u6gNmja6dZq3Q-pa3aI1k0cYxeF-DuJVoqqAM,5109
68
+ sdata/experiments/image_old.py,sha256=xz3tyH_WCnbmYZXq1diwBnYEN3aJoSEhEiYdK4HSaRQ,9597
69
+ sdata/experiments/ks2.py,sha256=AsVJNfrsiICefYfYdBHB3GfnoW7gy1CyAy-kZsgfVSQ,834
70
+ sdata/experiments/lapshear.py,sha256=iBdKQve7_UMKUDcsMs4HSr4J1OA3tWGnVZ43Oz-MzYA,281
71
+ sdata/experiments/material.py,sha256=qV2-mGqPT_LKCk2lcnVUC1Yhqy_O0dhRd8sSZLNMdeU,318
72
+ sdata/experiments/parameters_deprecated.py,sha256=TNAGGxLyZp1bf8SFjUZd3V986x036j8Sib3dzXGf3I4,13631
73
+ sdata/experiments/workbook.py,sha256=aWM9_Y9jeCdApEoMcE1t5vGN4iT41zKCxTOkWjaQFxo,6933
74
+ sdata/iolib/__init__.py,sha256=x_V0Vqx2yZeFOWyM1fWT4B_Wyb6a8wmP4IYw3WikpX4,1383
75
+ sdata/iolib/hashtree.py,sha256=nF7OJiIGofggOmc7WUVU4lhLmX07xqzhI6z7N26qWmo,8989
76
+ sdata/iolib/json1sqlitestore.py,sha256=yLVbPDvFa849EhXyC3AmwxwMUsconUw11J58UNDWgBg,23360
77
+ sdata/iolib/jsonsqlitestore.py,sha256=iQ1rCC6sNujHO2OJ5C-SpZlJ3enj7pXVd7xc0ezgev0,22600
78
+ sdata/iolib/pud.py,sha256=EKPmkKbOq2ukTq1S0Lh5VW53oxRSCumCA9fGhpGYMGc,9565
79
+ sdata/iolib/reader.py,sha256=u_1HrjOKJv2ckV-8SBRHfjEa2pq8l9xfnRueZQ7UlhE,10759
80
+ sdata/iolib/writer.py,sha256=NHBU6dweQZrkf46gqH_rtVwurhcHgqu8dN2Twjidmto,17369
81
+ sdata/sclass/__init__.py,sha256=A3cwPakW0wCTGUZYA6cu5kE60XXEIJXcsqxKM_M2aO8,3716
82
+ sdata/sclass/bfo_classes.py,sha256=bggtMF05598KA5vomlNkSxHL433Cpe87CUZUOEu0NAc,16775
83
+ sdata/sclass/blob.py,sha256=eQSSPWcGGNoII2XpU_Fv0WKIwVZLRCweUaSSOBScCKk,15082
84
+ sdata/sclass/content.py,sha256=ShMbTTfzApUG5nkvATsEaJNXIS0cG6jbflkyfuJ95QE,3290
85
+ sdata/sclass/dataframe.py,sha256=U3VAlBswqXvq9jz2R3lZdR4ZBLTFx2l8buhlKLKclHk,57525
86
+ sdata/sclass/dataframegroup.py,sha256=Tc5_E-CGINlWXgZqWUFQ7Z53_VpgCjT7KFjnYFp3IYM,8728
87
+ sdata/sclass/dependency_graph.py,sha256=_nPq_65WkDoazG2cLoF3IivRCfZivtShJ9e-Ws9lxnE,3097
88
+ sdata/sclass/filereference.py,sha256=Gh5k6cYNSS3qcCG8-iyOk1Go1FcKNdGElgEFwrMfLBs,4485
89
+ sdata/sclass/image.py,sha256=J3h4LLHswAoQa2cI6jUjaKHnS17Jl1rNJ_tV5MkDNyc,9453
90
+ sdata/sclass/lazy_namespace.py,sha256=s-u1jJW7gVkd2SlSNTLD7xVbIMOcAmXfXWclY6Rjl6Y,6193
91
+ sdata/sclass/process.py,sha256=baelESWEeuRGHy2bAWOumIRhmxkRp1IxYQYJqN2eYJA,14801
92
+ sdata/sclass/process_graph.py,sha256=d4lIyLesJK83bgQ--JbatxjB0IVz3PJG0-5LK1ATnIs,8532
93
+ sdata/sclass/zipfile.py,sha256=Rbmnbc7bPmTex7VedUunqsAsfY81ixuJZQ-LIJxgeAk,5064
94
+ sdata-1.5.0.dist-info/licenses/LICENSE-MIT,sha256=5U6rYVFnGH6sgX_ZHqovb03c5sjFG0SxcUhCeBIz74s,1066
95
+ sdata-1.5.0.dist-info/METADATA,sha256=3dZt-z0Mk2Z7hnPpc__kQv59N5LB8nTwB83jtYW5KCQ,11204
96
+ sdata-1.5.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
97
+ sdata-1.5.0.dist-info/top_level.txt,sha256=5HOjejfoO5ta_hkVFnEhX0T0L7YrtdcfhUu9FesNWfk,6
98
+ sdata-1.5.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017-2020 lepy
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.
@@ -0,0 +1 @@
1
+ sdata