sdata 0.25.6__tar.gz → 1.6.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 (223) hide show
  1. sdata-1.6.0/MANIFEST.in +2 -0
  2. sdata-1.6.0/PKG-INFO +263 -0
  3. sdata-1.6.0/README.md +214 -0
  4. sdata-1.6.0/pyproject.toml +92 -0
  5. sdata-1.6.0/sdata/__init__.py +140 -0
  6. sdata-1.6.0/sdata/base.py +708 -0
  7. sdata-1.6.0/sdata/deprecated/__init__.py +10 -0
  8. {sdata-0.25.6/sdata → sdata-1.6.0/sdata/deprecated}/data.py +80 -21
  9. sdata-1.6.0/sdata/did/__init__.py +129 -0
  10. sdata-1.6.0/sdata/did/_http.py +67 -0
  11. sdata-1.6.0/sdata/did/base58btc.py +49 -0
  12. sdata-1.6.0/sdata/did/did_github.py +152 -0
  13. sdata-1.6.0/sdata/did/did_peer4.py +155 -0
  14. sdata-1.6.0/sdata/did/did_web.py +222 -0
  15. sdata-1.6.0/sdata/did/diddoc.py +75 -0
  16. sdata-1.6.0/sdata/did/ed25519.py +225 -0
  17. sdata-1.6.0/sdata/did/eddsa.py +107 -0
  18. sdata-1.6.0/sdata/did/errors.py +40 -0
  19. sdata-1.6.0/sdata/did/issue_vc.py +193 -0
  20. sdata-1.6.0/sdata/did/jose.py +126 -0
  21. sdata-1.6.0/sdata/did/keys.py +104 -0
  22. sdata-1.6.0/sdata/did/utils_didkey.py +161 -0
  23. sdata-1.6.0/sdata/did/verify_vp.py +158 -0
  24. {sdata-0.25.6 → sdata-1.6.0}/sdata/doe.py +65 -7
  25. sdata-1.6.0/sdata/dtypes.py +510 -0
  26. {sdata-0.25.6 → sdata-1.6.0}/sdata/experiments/__init__.py +5 -1
  27. sdata-1.6.0/sdata/experiments/filegroup.py +144 -0
  28. {sdata-0.25.6/sdata → sdata-1.6.0/sdata/experiments}/workbook.py +1 -1
  29. sdata-1.6.0/sdata/format.py +125 -0
  30. sdata-1.6.0/sdata/imagemeta.py +618 -0
  31. sdata-1.6.0/sdata/interactive.py +118 -0
  32. {sdata-0.25.6 → sdata-1.6.0}/sdata/iolib/hashtree.py +1 -1
  33. sdata-1.6.0/sdata/iolib/json1sqlitestore.py +554 -0
  34. {sdata-0.25.6 → sdata-1.6.0}/sdata/iolib/jsonsqlitestore.py +17 -4
  35. {sdata-0.25.6 → sdata-1.6.0}/sdata/iolib/pud.py +3 -3
  36. sdata-1.6.0/sdata/iolib/reader.py +262 -0
  37. sdata-1.6.0/sdata/iolib/writer.py +419 -0
  38. {sdata-0.25.6 → sdata-1.6.0}/sdata/metadata.py +257 -96
  39. {sdata-0.25.6 → sdata-1.6.0}/sdata/parameter.py +4 -1
  40. sdata-1.6.0/sdata/schema.py +273 -0
  41. sdata-1.6.0/sdata/sclass/__init__.py +111 -0
  42. sdata-1.6.0/sdata/sclass/bfo_classes.py +362 -0
  43. sdata-1.6.0/sdata/sclass/blob.py +417 -0
  44. sdata-1.6.0/sdata/sclass/content.py +100 -0
  45. sdata-1.6.0/sdata/sclass/dataframe.py +1262 -0
  46. sdata-1.6.0/sdata/sclass/dataframegroup.py +187 -0
  47. sdata-1.6.0/sdata/sclass/dependency_graph.py +85 -0
  48. sdata-1.6.0/sdata/sclass/filereference.py +124 -0
  49. sdata-1.6.0/sdata/sclass/image.py +218 -0
  50. sdata-1.6.0/sdata/sclass/lazy_namespace.py +155 -0
  51. sdata-1.6.0/sdata/sclass/lca.py +490 -0
  52. sdata-1.6.0/sdata/sclass/process.py +383 -0
  53. sdata-1.6.0/sdata/sclass/process_graph.py +221 -0
  54. sdata-1.6.0/sdata/sclass/zipfile.py +135 -0
  55. sdata-1.6.0/sdata/semantic.py +346 -0
  56. sdata-1.6.0/sdata/suuid.py +136 -0
  57. {sdata-0.25.6 → sdata-1.6.0}/sdata/timestamp.py +14 -10
  58. sdata-1.6.0/sdata/units.py +642 -0
  59. sdata-1.6.0/sdata/vocab.py +149 -0
  60. sdata-1.6.0/sdata.egg-info/PKG-INFO +263 -0
  61. sdata-1.6.0/sdata.egg-info/SOURCES.txt +148 -0
  62. sdata-1.6.0/sdata.egg-info/requires.txt +34 -0
  63. {sdata-0.25.6 → sdata-1.6.0}/sdata.egg-info/top_level.txt +0 -1
  64. {sdata-0.25.6 → sdata-1.6.0}/setup.cfg +0 -3
  65. sdata-1.6.0/tests/test_attribute_symbol.py +137 -0
  66. sdata-1.6.0/tests/test_base.py +211 -0
  67. sdata-1.6.0/tests/test_base_coverage.py +142 -0
  68. sdata-1.6.0/tests/test_base_from_dict_subclass.py +52 -0
  69. {sdata-0.25.6 → sdata-1.6.0}/tests/test_blob.py +0 -1
  70. sdata-1.6.0/tests/test_csv_sidecar_ontology.py +33 -0
  71. {sdata-0.25.6 → sdata-1.6.0}/tests/test_data.py +33 -8
  72. sdata-1.6.0/tests/test_data_deprecation.py +50 -0
  73. sdata-1.6.0/tests/test_did.py +383 -0
  74. sdata-1.6.0/tests/test_did_coverage.py +352 -0
  75. sdata-1.6.0/tests/test_doe_coverage.py +98 -0
  76. sdata-1.6.0/tests/test_dtypes.py +520 -0
  77. sdata-1.6.0/tests/test_eddsa.py +124 -0
  78. sdata-1.6.0/tests/test_format_versioning.py +171 -0
  79. sdata-1.6.0/tests/test_http_backend.py +88 -0
  80. sdata-1.6.0/tests/test_image.py +142 -0
  81. sdata-1.6.0/tests/test_imagemeta.py +435 -0
  82. sdata-1.6.0/tests/test_interactive.py +60 -0
  83. {sdata-0.25.6 → sdata-1.6.0}/tests/test_io.py +3 -0
  84. {sdata-0.25.6 → sdata-1.6.0}/tests/test_metadata.py +19 -1
  85. sdata-1.6.0/tests/test_metadata_coverage.py +249 -0
  86. sdata-1.6.0/tests/test_metadata_sorteddict.py +51 -0
  87. sdata-1.6.0/tests/test_parameter_coverage.py +171 -0
  88. sdata-1.6.0/tests/test_schema.py +146 -0
  89. sdata-1.6.0/tests/test_sclass_blob_coverage.py +120 -0
  90. sdata-1.6.0/tests/test_sclass_blob_errors.py +195 -0
  91. sdata-1.6.0/tests/test_sclass_blob_hardening.py +51 -0
  92. sdata-1.6.0/tests/test_sclass_blob_io.py +55 -0
  93. sdata-1.6.0/tests/test_sclass_dataframe_as_blob.py +76 -0
  94. sdata-1.6.0/tests/test_sclass_dataframe_column_dtype.py +84 -0
  95. sdata-1.6.0/tests/test_sclass_dataframe_columns.py +101 -0
  96. sdata-1.6.0/tests/test_sclass_dataframe_correctness.py +126 -0
  97. sdata-1.6.0/tests/test_sclass_dataframe_coverage.py +86 -0
  98. sdata-1.6.0/tests/test_sclass_dataframe_datapackage.py +105 -0
  99. sdata-1.6.0/tests/test_sclass_dataframe_field_metadata.py +64 -0
  100. sdata-1.6.0/tests/test_sclass_dataframe_hdf.py +146 -0
  101. sdata-1.6.0/tests/test_sclass_dataframe_integrity.py +104 -0
  102. sdata-1.6.0/tests/test_sclass_dataframe_interop.py +167 -0
  103. sdata-1.6.0/tests/test_sclass_dataframe_parquet_filename.py +49 -0
  104. sdata-1.6.0/tests/test_sclass_dataframe_tableschema.py +112 -0
  105. sdata-1.6.0/tests/test_sclass_dataframe_units.py +224 -0
  106. sdata-1.6.0/tests/test_sclass_dataframegroup_coverage.py +110 -0
  107. sdata-1.6.0/tests/test_sclass_filereference_blob.py +34 -0
  108. sdata-1.6.0/tests/test_sclass_filereference_coverage.py +32 -0
  109. sdata-1.6.0/tests/test_sclass_lazy_namespace_coverage.py +91 -0
  110. sdata-1.6.0/tests/test_sclass_lca.py +375 -0
  111. sdata-1.6.0/tests/test_sclass_misc_coverage.py +56 -0
  112. sdata-1.6.0/tests/test_sclass_zipfile_coverage.py +59 -0
  113. sdata-1.6.0/tests/test_sdata_init_coverage.py +30 -0
  114. sdata-1.6.0/tests/test_semantic_columns.py +60 -0
  115. sdata-1.6.0/tests/test_semantic_jsonld.py +110 -0
  116. sdata-1.6.0/tests/test_semantic_rdf.py +49 -0
  117. sdata-1.6.0/tests/test_semantic_vc.py +53 -0
  118. sdata-1.6.0/tests/test_sidecar_wiring.py +42 -0
  119. sdata-1.6.0/tests/test_suuid.py +24 -0
  120. sdata-1.6.0/tests/test_suuid_class.py +121 -0
  121. {sdata-0.25.6 → sdata-1.6.0}/tests/test_table.py +2 -0
  122. {sdata-0.25.6 → sdata-1.6.0}/tests/test_testprogram.py +1 -2
  123. sdata-1.6.0/tests/test_timestamp.py +63 -0
  124. sdata-1.6.0/tests/test_timestamp_coverage.py +70 -0
  125. sdata-1.6.0/tests/test_unit_system_persistence.py +102 -0
  126. sdata-1.6.0/tests/test_units.py +50 -0
  127. sdata-1.6.0/tests/test_units_angle.py +95 -0
  128. sdata-1.6.0/tests/test_units_convert.py +186 -0
  129. sdata-1.6.0/tests/test_units_electrical.py +118 -0
  130. sdata-1.6.0/tests/test_units_frequency.py +64 -0
  131. sdata-1.6.0/tests/test_units_pint_interop.py +148 -0
  132. sdata-1.6.0/tests/test_units_qudt_coverage.py +54 -0
  133. sdata-1.6.0/tests/test_vocab.py +65 -0
  134. sdata-0.25.6/MANIFEST.in +0 -6
  135. sdata-0.25.6/PKG-INFO +0 -151
  136. sdata-0.25.6/README.md +0 -101
  137. sdata-0.25.6/pyproject.toml +0 -3
  138. sdata-0.25.6/sdata/__init__.py +0 -65
  139. sdata-0.25.6/sdata/base.py +0 -155
  140. sdata-0.25.6/sdata/contrib/attrdict/__init__.py +0 -10
  141. sdata-0.25.6/sdata/contrib/attrdict/default.py +0 -133
  142. sdata-0.25.6/sdata/contrib/attrdict/dictionary.py +0 -60
  143. sdata-0.25.6/sdata/contrib/attrdict/mapping.py +0 -100
  144. sdata-0.25.6/sdata/contrib/attrdict/merge.py +0 -47
  145. sdata-0.25.6/sdata/contrib/attrdict/mixins.py +0 -213
  146. sdata-0.25.6/sdata/contrib/piexif/__init__.py +0 -12
  147. sdata-0.25.6/sdata/contrib/piexif/_common.py +0 -94
  148. sdata-0.25.6/sdata/contrib/piexif/_dump.py +0 -346
  149. sdata-0.25.6/sdata/contrib/piexif/_exceptions.py +0 -2
  150. sdata-0.25.6/sdata/contrib/piexif/_exif.py +0 -638
  151. sdata-0.25.6/sdata/contrib/piexif/_insert.py +0 -60
  152. sdata-0.25.6/sdata/contrib/piexif/_load.py +0 -270
  153. sdata-0.25.6/sdata/contrib/piexif/_remove.py +0 -56
  154. sdata-0.25.6/sdata/contrib/piexif/_transplant.py +0 -45
  155. sdata-0.25.6/sdata/contrib/piexif/_webp.py +0 -240
  156. sdata-0.25.6/sdata/contrib/piexif/helper.py +0 -66
  157. sdata-0.25.6/sdata/contrib/ranger/__init__.py +0 -8
  158. sdata-0.25.6/sdata/contrib/ranger/collections/__init__.py +0 -0
  159. sdata-0.25.6/sdata/contrib/ranger/collections/rangebucketmap.py +0 -342
  160. sdata-0.25.6/sdata/contrib/ranger/collections/rangemap.py +0 -396
  161. sdata-0.25.6/sdata/contrib/ranger/collections/rangeset.py +0 -483
  162. sdata-0.25.6/sdata/contrib/ranger/range/__init__.py +0 -0
  163. sdata-0.25.6/sdata/contrib/ranger/range/cut.py +0 -285
  164. sdata-0.25.6/sdata/contrib/ranger/range/range.py +0 -644
  165. sdata-0.25.6/sdata/contrib/semver.py +0 -1259
  166. sdata-0.25.6/sdata/contrib/simple_graph_db/LICENSE +0 -20
  167. sdata-0.25.6/sdata/contrib/simple_graph_db/__init__.py +0 -603
  168. sdata-0.25.6/sdata/contrib/simple_graph_db/database.py +0 -234
  169. sdata-0.25.6/sdata/contrib/simple_graph_db/schema.sql +0 -17
  170. sdata-0.25.6/sdata/contrib/sortedcontainers/LICENSE +0 -13
  171. sdata-0.25.6/sdata/contrib/sortedcontainers/__init__.py +0 -74
  172. sdata-0.25.6/sdata/contrib/sortedcontainers/sorteddict.py +0 -789
  173. sdata-0.25.6/sdata/contrib/sortedcontainers/sortedlist.py +0 -2646
  174. sdata-0.25.6/sdata/contrib/sortedcontainers/sortedset.py +0 -733
  175. sdata-0.25.6/sdata/contrib/sqlitedict.py +0 -598
  176. sdata-0.25.6/sdata/contrib/timeflake/__init__.py +0 -40
  177. sdata-0.25.6/sdata/contrib/timeflake/flake.py +0 -69
  178. sdata-0.25.6/sdata/contrib/timeflake/utils.py +0 -47
  179. sdata-0.25.6/sdata/image.py +0 -312
  180. sdata-0.25.6/sdata/iolib/db.py +0 -86
  181. sdata-0.25.6/sdata/iolib/hdf.py +0 -95
  182. sdata-0.25.6/sdata/iolib/isomme.py +0 -410
  183. sdata-0.25.6/sdata/iolib/json1sqlitestore.py +0 -596
  184. sdata-0.25.6/sdata/iolib/owncloudfs.py +0 -105
  185. sdata-0.25.6/sdata/iolib/pgp.py +0 -80
  186. sdata-0.25.6/sdata/iolib/simple_signature.py +0 -446
  187. sdata-0.25.6/sdata/iolib/vault.py +0 -475
  188. sdata-0.25.6/sdata/node.py +0 -145
  189. sdata-0.25.6/sdata/suuid.py +0 -287
  190. sdata-0.25.6/sdata.egg-info/PKG-INFO +0 -151
  191. sdata-0.25.6/sdata.egg-info/SOURCES.txt +0 -107
  192. sdata-0.25.6/sdata.egg-info/requires.txt +0 -9
  193. sdata-0.25.6/setup.py +0 -54
  194. sdata-0.25.6/tests/__init__.py +0 -0
  195. sdata-0.25.6/tests/iolib/__init__.py +0 -0
  196. sdata-0.25.6/tests/iolib/pud/__init__.py +0 -0
  197. sdata-0.25.6/tests/iolib/pud/test_pud.py +0 -18
  198. sdata-0.25.6/tests/iolib/test_hasttree.py +0 -67
  199. sdata-0.25.6/tests/iolib/test_hdf.py +0 -59
  200. sdata-0.25.6/tests/iolib/test_jsonsqlitestore.py +0 -156
  201. sdata-0.25.6/tests/test_image.py +0 -28
  202. sdata-0.25.6/tests/test_suuid.py +0 -45
  203. sdata-0.25.6/tests/test_timeflake.py +0 -124
  204. sdata-0.25.6/tests/test_timestamp.py +0 -106
  205. sdata-0.25.6/tests/test_vault.py +0 -146
  206. sdata-0.25.6/tests/test_workbook.py +0 -43
  207. {sdata-0.25.6 → sdata-1.6.0}/LICENSE-MIT +0 -0
  208. {sdata-0.25.6 → sdata-1.6.0}/sdata/contrib/__init__.py +0 -0
  209. {sdata-0.25.6 → sdata-1.6.0}/sdata/contrib/sobol_seq.py +0 -0
  210. /sdata-0.25.6/sdata/blob.py → /sdata-1.6.0/sdata/experiments/blob0.py +0 -0
  211. {sdata-0.25.6/sdata → sdata-1.6.0/sdata/experiments}/file.py +0 -0
  212. {sdata-0.25.6 → sdata-1.6.0}/sdata/experiments/ks2.py +0 -0
  213. {sdata-0.25.6 → sdata-1.6.0}/sdata/experiments/lapshear.py +0 -0
  214. {sdata-0.25.6 → sdata-1.6.0}/sdata/experiments/material.py +0 -0
  215. {sdata-0.25.6/sdata → sdata-1.6.0/sdata/experiments}/parameters_deprecated.py +0 -0
  216. {sdata-0.25.6 → sdata-1.6.0}/sdata/iolib/__init__.py +0 -0
  217. {sdata-0.25.6 → sdata-1.6.0}/sdata/tools.py +0 -0
  218. {sdata-0.25.6 → sdata-1.6.0}/sdata.egg-info/dependency_links.txt +0 -0
  219. {sdata-0.25.6 → sdata-1.6.0}/tests/test_attribute.py +0 -0
  220. {sdata-0.25.6 → sdata-1.6.0}/tests/test_ks2.py +0 -0
  221. {sdata-0.25.6 → sdata-1.6.0}/tests/test_parameter.py +0 -0
  222. {sdata-0.25.6 → sdata-1.6.0}/tests/test_sqlite.py +0 -0
  223. {sdata-0.25.6 → sdata-1.6.0}/tests/test_tools.py +0 -0
@@ -0,0 +1,2 @@
1
+ include LICENSE-MIT
2
+ include README.md
sdata-1.6.0/PKG-INFO ADDED
@@ -0,0 +1,263 @@
1
+ Metadata-Version: 2.4
2
+ Name: sdata
3
+ Version: 1.6.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-Expression: 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: Natural Language :: English
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: Implementation :: CPython
20
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE-MIT
24
+ Requires-Dist: numpy
25
+ Requires-Dist: pandas
26
+ Requires-Dist: suuid>=0.2.0
27
+ Provides-Extra: did
28
+ Provides-Extra: http
29
+ Requires-Dist: requests; extra == "http"
30
+ Provides-Extra: excel
31
+ Requires-Dist: openpyxl; extra == "excel"
32
+ Requires-Dist: xlsxwriter; extra == "excel"
33
+ Requires-Dist: tabulate; extra == "excel"
34
+ Provides-Extra: hdf
35
+ Requires-Dist: h5py; extra == "hdf"
36
+ Provides-Extra: sql
37
+ Requires-Dist: sqlalchemy; extra == "sql"
38
+ Provides-Extra: parquet
39
+ Requires-Dist: pyarrow; extra == "parquet"
40
+ Provides-Extra: blob
41
+ Requires-Dist: fsspec; extra == "blob"
42
+ Provides-Extra: units
43
+ Requires-Dist: pint; extra == "units"
44
+ Provides-Extra: rdf
45
+ Requires-Dist: rdflib; extra == "rdf"
46
+ Provides-Extra: schema
47
+ Requires-Dist: jsonschema; extra == "schema"
48
+ Dynamic: license-file
49
+
50
+
51
+ [![PyPI](https://img.shields.io/pypi/v/sdata.svg?style=flat-square)](https://pypi.python.org/pypi/sdata/)
52
+ [![Python versions](https://img.shields.io/pypi/pyversions/sdata.svg?style=flat-square)](https://pypi.python.org/pypi/sdata/)
53
+ [![Docs](https://img.shields.io/badge/docs-mkdocs--material-blue?style=flat-square)](https://lepy.github.io/sdata/)
54
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4311323.svg)](https://doi.org/10.5281/zenodo.4311323)
55
+
56
+ # Structured data format (sdata)
57
+
58
+ ## Design goals & status
59
+
60
+ sdata is an open, self-describing data format for open-science projects. The
61
+ table below is an honest status of the original design goals (triaged in
62
+ [RFC 0008](docs/rfc/0008-bestandsaufnahme-roadmap.md)) — **implemented**,
63
+ **partial**, on the **roadmap**, or an explicit **non-goal**.
64
+
65
+ | Goal | Status | Notes |
66
+ |------|--------|-------|
67
+ | Open, self-describing data | **implemented** | metadata embedded in every format |
68
+ | Platform independent, simple object model | **implemented** | pure Python / numpy / pandas |
69
+ | Standard metadata formats (key/value, JSON-LD, …) | **implemented** | `Metadata`, QUDT/BFO/PROV/CSVW/DID/VC |
70
+ | Physical units + conversion | **implemented** | `sdata.units` (RFC 0006) |
71
+ | Standard dataset formats — HDF5, CSV, Parquet, Arrow, Data Package | **implemented** | HDF5 via `sdata[hdf]` |
72
+ | (De-)serialization of data + metadata | **implemented** | lossless round-trips |
73
+ | Data format versions | **implemented** | `_sdata_format_version` + migration (RFC 0010) |
74
+ | Project standards (e.g. tensile test) | **partial** | schema templates (`MetadataSchema`/`TableSchema`) |
75
+ | Series | **partial** | as a one-column table |
76
+ | Hierarchical structure / nested groups | **partial** | `DataFrameGroup` (flat) + `parent`/`project` relations |
77
+ | Transparent compression | **partial** | Parquet-internal (zstd); zlib is a **non-goal** for the store (speed) |
78
+ | Standard dataset formats — **netCDF** | **roadmap** | not implemented |
79
+ | Dataset types — **datacubes** | **roadmap** | not implemented |
80
+ | Optional encryption (gpg, …) | **non-goal** | encrypt blobs/filesystem out of band |
81
+ | posix-path syntax, change management, tensor-library interop, SWMR | **non-goal** | not planned; revisit on demand |
82
+
83
+ Machine-readable metadata is the backbone (see below); the optional semantic
84
+ backends degrade gracefully to pure Python.
85
+
86
+ ## Quickstart
87
+
88
+ ```python
89
+ import pandas as pd
90
+ from sdata.sclass.dataframe import DataFrame
91
+
92
+ df = pd.DataFrame({"force": [1.0, 2.0, 3.0]})
93
+ data = DataFrame(df=df, name="specimen_01", description="a tension test")
94
+ data.metadata.add("max_force", 12.5, unit="kN", dtype="float",
95
+ description="max force", ontology="bfo:Quality")
96
+
97
+ print(data.metadata.df[["value", "unit", "dtype", "ontology"]])
98
+ ```
99
+
100
+ ```
101
+ value unit dtype ontology
102
+ key
103
+ _sdata_name specimen_01 - str
104
+ _sdata_sname DataFrame__specimen_01__3003... - str
105
+ ...
106
+ max_force 12.5 kN float bfo:Quality
107
+ ```
108
+
109
+ Every object has a deterministic, content-addressable identity (`SUUID`), a set
110
+ of reserved `_sdata_*` attributes (name, sname, suuid, class, ctime, parent,
111
+ project, topology class) and freely extensible, fully-described user attributes.
112
+
113
+ ## Machine-readable metadata (JSON-LD / Linked Data)
114
+
115
+ The metadata is the backbone of the data description: it lives next to every
116
+ data blob and fully qualifies the data — units (QUDT/UCUM), ontology classes
117
+ (BFO), provenance (PROV/DCAT), tabular columns (CSVW) and identity (DID).
118
+
119
+ ```python
120
+ # self-describing JSON-LD (qudt:Quantity units, BFO @type, did:suuid @id, csvw columns)
121
+ doc = data.to_jsonld()
122
+
123
+ # RDF/Turtle (uses rdflib if installed, otherwise returns the JSON-LD)
124
+ print(data.to_turtle())
125
+
126
+ # write the data + a sidecar <sname>.meta.jsonld right next to it
127
+ data.to_json("specimen_01.sjson", sidecar=True)
128
+
129
+ # validate / auto-complete against a schema template
130
+ from sdata.schema import MetadataSchema, AttrSpec
131
+ schema = MetadataSchema("TensileTest", [
132
+ AttrSpec("max_force", dtype="float", unit="kN", required=True, ontology="bfo:Quality"),
133
+ ])
134
+ report = data.metadata.validate(schema) # ValidationReport (truthy if ok)
135
+
136
+ # sign the metadata as a W3C Verifiable Credential (pure-Python Ed25519)
137
+ from sdata.did import keys, pub_from_priv_jwk
138
+ priv = keys.gen_ed25519_jwk()
139
+ vc = data.metadata.to_verifiable_credential("did:example:issuer", priv)
140
+ subject = data.metadata.from_verifiable_credential(vc, pub_from_priv_jwk(priv))
141
+
142
+ # interactive: attribute autocomplete + rich Jupyter display
143
+ data.metadata.a.max_force # -> Attribute; tab-completion in Jupyter
144
+ data.metadata # -> _repr_html_ table
145
+ ```
146
+
147
+ Resulting JSON-LD for `max_force` (excerpt):
148
+
149
+ ```json
150
+ {
151
+ "@id": "did:suuid:DataFrame__specimen_01__3003...:sdata",
152
+ "@type": ["sdata:DataFrame", "bfo:BFO_0000004"],
153
+ "name": "specimen_01",
154
+ "sdata:max_force": {
155
+ "@type": ["qudt:Quantity", "bfo:Quality"],
156
+ "value": {"@value": 12.5, "@type": "xsd:double"},
157
+ "unitRef": "unit:KiloN", "symbol": "kN"
158
+ },
159
+ "columns": [{"name": "force", "datatype": "xsd:double"}]
160
+ }
161
+ ```
162
+
163
+ The optional semantic backends degrade gracefully to pure Python (no hard
164
+ dependency): `pip install "sdata[rdf]"` (rdflib), `sdata[units]` (pint),
165
+ `sdata[schema]` (jsonschema). Core install needs only `numpy`, `pandas`, `suuid`.
166
+
167
+ ## Tabular data (`DataFrame`)
168
+
169
+ `DataFrame` wraps a pandas frame plus per-column metadata and serializes to many
170
+ formats — Parquet, Arrow/Feather, CSV, dict/JSON, JSON-LD, a Frictionless **Data
171
+ Package** and **HDF5** — with the qualifying metadata embedded or written as a
172
+ sidecar.
173
+
174
+ ```python
175
+ import pandas as pd
176
+ from sdata.sclass.dataframe import DataFrame
177
+
178
+ sdf = DataFrame(df=pd.DataFrame({"weight": [10, 20], "height": [1.5, 1.6]}),
179
+ name="specimen_01", description="a tension test")
180
+
181
+ # per-column annotations (only the fields you pass are changed)
182
+ sdf.set_column("weight", unit="kg", label="Gewicht", ontology="bfo:Quality")
183
+ sdf.col["height"].unit = "m" # mutate the column Attribute in place
184
+ sdf.column_units # {'weight': 'kg', 'height': 'm'}
185
+
186
+ # serialize (optional <sname>.meta.jsonld sidecar; bytes/str without a path)
187
+ sdf.to_parquet(path="out", sidecar=True) # out/<sname>.spq + sidecar
188
+ sdf.to_csv(path="out") # data-only CSV (pure pandas)
189
+ sdf.to_feather(path="out") # Arrow IPC + native per-column field metadata
190
+ sdf.to_datapackage(path="out") # Frictionless Data Package (.zip)
191
+ sdf.to_hdf(path="out") # HDF5 via h5py, one dataset/column (sdata[hdf])
192
+ DataFrame.from_parquet("out/specimen_01.spq")
193
+
194
+ # validate the table against a schema (missing/dtype/unit/extra columns)
195
+ from sdata.schema import TableSchema, AttrSpec
196
+ schema = TableSchema("TensileTable", [
197
+ AttrSpec("weight", dtype="int", unit="kg", required=True),
198
+ ])
199
+ report = sdf.validate_table(schema) # ValidationReport (truthy if ok)
200
+ ```
201
+
202
+ Arrow/Feather/Parquet need `pip install "sdata[parquet]"`, HDF5 `sdata[hdf]`; CSV,
203
+ dict, JSON-LD and the (CSV) Data Package work with the core install. See the
204
+ [Tabular data docs](https://lepy.github.io/sdata/usage/dataframe/)
205
+ ([`docs/usage/dataframe.md`](docs/usage/dataframe.md)) for the full reference.
206
+
207
+ ## Howto
208
+
209
+
210
+ * [Das sdata-Format - slides](https://lepy.github.io/sdata/ipynb/Das_sdata_Format.slides.html#)
211
+ * https://deepwiki.com/lepy/sdata
212
+
213
+ ## Demo App
214
+
215
+ * [test the demo app with editor](https://share.streamlit.io/lepy/sdata_streamlit/main/sdata_editor.py)
216
+
217
+ Try to paste some Excel-Data in the forms ...
218
+
219
+
220
+ ## Metadata
221
+
222
+ ### Attributes
223
+
224
+ * name
225
+ * value
226
+ * dtype
227
+ * unit
228
+ * description
229
+ * label
230
+ * required
231
+ * ontology (CURIE/IRI of the value's class, e.g. `bfo:Quality`)
232
+
233
+ ### dtypes for attributes
234
+
235
+ Every attribute value is coerced to a declared dtype (single source:
236
+ `sdata.dtypes`), each with a lossless JSON-LD / XSD mapping:
237
+
238
+ * `int`, `float`, `str`, `bool`
239
+ * `list` (list of strings), `floatlist` (typed list of floats)
240
+ * `timestamp` (ISO-8601 with timezone, stdlib `zoneinfo`)
241
+ * `date`, `time`, `duration` (ISO-8601 / `datetime` types)
242
+ * `decimal` (exact decimal), `complex` (complex number)
243
+ * `bytes` (base64 in JSON), `json` (dict/list), `uri`
244
+ * `langstring` (language-tagged string, `rdf:langString`, e.g. `"Hallo@de"`)
245
+
246
+ Coercion is **lenient** by default (invalid values are logged and left unchanged).
247
+ Pass `strict=True` (e.g. `metadata.add(..., strict=True)`) to raise `DtypeError`
248
+ instead. See the [conventions](https://lepy.github.io/sdata/conventions/) for the
249
+ error policy.
250
+
251
+ ## paper
252
+
253
+ * [Das sdata-Format](https://zenodo.org/record/4311323#.X89yo9-YXys)
254
+ * Ingolf Lepenies. (2020). Das sdata-Format (Version 0.8.4). http://doi.org/10.5281/zenodo.4311323
255
+ * [slides](https://lepy.github.io/sdata/ipynb/Das_sdata_Format.slides.html#),
256
+ [html](https://lepy.github.io/sdata/paper/2020/Das_sdata-Format.html),
257
+ [pdf](https://lepy.github.io/sdata/paper/2020/Das_sdata-Format.pdf)
258
+ [temperaturmessung-001.json](https://lepy.github.io/sdata/paper/2020/temperaturmessung-001.json)
259
+ [temperaturmessung-001.xlsx](https://lepy.github.io/sdata/paper/2020/temperaturmessung-001.xlsx)
260
+
261
+ * [sdata](https://doi.org/10.5281/zenodo.4311396)
262
+ * Ingolf Lepenies. (2020, December 8). sdata - a structured data format (Version 0.8.4). Zenodo. http://doi.org/10.5281/zenodo.4311397
263
+
sdata-1.6.0/README.md ADDED
@@ -0,0 +1,214 @@
1
+
2
+ [![PyPI](https://img.shields.io/pypi/v/sdata.svg?style=flat-square)](https://pypi.python.org/pypi/sdata/)
3
+ [![Python versions](https://img.shields.io/pypi/pyversions/sdata.svg?style=flat-square)](https://pypi.python.org/pypi/sdata/)
4
+ [![Docs](https://img.shields.io/badge/docs-mkdocs--material-blue?style=flat-square)](https://lepy.github.io/sdata/)
5
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4311323.svg)](https://doi.org/10.5281/zenodo.4311323)
6
+
7
+ # Structured data format (sdata)
8
+
9
+ ## Design goals & status
10
+
11
+ sdata is an open, self-describing data format for open-science projects. The
12
+ table below is an honest status of the original design goals (triaged in
13
+ [RFC 0008](docs/rfc/0008-bestandsaufnahme-roadmap.md)) — **implemented**,
14
+ **partial**, on the **roadmap**, or an explicit **non-goal**.
15
+
16
+ | Goal | Status | Notes |
17
+ |------|--------|-------|
18
+ | Open, self-describing data | **implemented** | metadata embedded in every format |
19
+ | Platform independent, simple object model | **implemented** | pure Python / numpy / pandas |
20
+ | Standard metadata formats (key/value, JSON-LD, …) | **implemented** | `Metadata`, QUDT/BFO/PROV/CSVW/DID/VC |
21
+ | Physical units + conversion | **implemented** | `sdata.units` (RFC 0006) |
22
+ | Standard dataset formats — HDF5, CSV, Parquet, Arrow, Data Package | **implemented** | HDF5 via `sdata[hdf]` |
23
+ | (De-)serialization of data + metadata | **implemented** | lossless round-trips |
24
+ | Data format versions | **implemented** | `_sdata_format_version` + migration (RFC 0010) |
25
+ | Project standards (e.g. tensile test) | **partial** | schema templates (`MetadataSchema`/`TableSchema`) |
26
+ | Series | **partial** | as a one-column table |
27
+ | Hierarchical structure / nested groups | **partial** | `DataFrameGroup` (flat) + `parent`/`project` relations |
28
+ | Transparent compression | **partial** | Parquet-internal (zstd); zlib is a **non-goal** for the store (speed) |
29
+ | Standard dataset formats — **netCDF** | **roadmap** | not implemented |
30
+ | Dataset types — **datacubes** | **roadmap** | not implemented |
31
+ | Optional encryption (gpg, …) | **non-goal** | encrypt blobs/filesystem out of band |
32
+ | posix-path syntax, change management, tensor-library interop, SWMR | **non-goal** | not planned; revisit on demand |
33
+
34
+ Machine-readable metadata is the backbone (see below); the optional semantic
35
+ backends degrade gracefully to pure Python.
36
+
37
+ ## Quickstart
38
+
39
+ ```python
40
+ import pandas as pd
41
+ from sdata.sclass.dataframe import DataFrame
42
+
43
+ df = pd.DataFrame({"force": [1.0, 2.0, 3.0]})
44
+ data = DataFrame(df=df, name="specimen_01", description="a tension test")
45
+ data.metadata.add("max_force", 12.5, unit="kN", dtype="float",
46
+ description="max force", ontology="bfo:Quality")
47
+
48
+ print(data.metadata.df[["value", "unit", "dtype", "ontology"]])
49
+ ```
50
+
51
+ ```
52
+ value unit dtype ontology
53
+ key
54
+ _sdata_name specimen_01 - str
55
+ _sdata_sname DataFrame__specimen_01__3003... - str
56
+ ...
57
+ max_force 12.5 kN float bfo:Quality
58
+ ```
59
+
60
+ Every object has a deterministic, content-addressable identity (`SUUID`), a set
61
+ of reserved `_sdata_*` attributes (name, sname, suuid, class, ctime, parent,
62
+ project, topology class) and freely extensible, fully-described user attributes.
63
+
64
+ ## Machine-readable metadata (JSON-LD / Linked Data)
65
+
66
+ The metadata is the backbone of the data description: it lives next to every
67
+ data blob and fully qualifies the data — units (QUDT/UCUM), ontology classes
68
+ (BFO), provenance (PROV/DCAT), tabular columns (CSVW) and identity (DID).
69
+
70
+ ```python
71
+ # self-describing JSON-LD (qudt:Quantity units, BFO @type, did:suuid @id, csvw columns)
72
+ doc = data.to_jsonld()
73
+
74
+ # RDF/Turtle (uses rdflib if installed, otherwise returns the JSON-LD)
75
+ print(data.to_turtle())
76
+
77
+ # write the data + a sidecar <sname>.meta.jsonld right next to it
78
+ data.to_json("specimen_01.sjson", sidecar=True)
79
+
80
+ # validate / auto-complete against a schema template
81
+ from sdata.schema import MetadataSchema, AttrSpec
82
+ schema = MetadataSchema("TensileTest", [
83
+ AttrSpec("max_force", dtype="float", unit="kN", required=True, ontology="bfo:Quality"),
84
+ ])
85
+ report = data.metadata.validate(schema) # ValidationReport (truthy if ok)
86
+
87
+ # sign the metadata as a W3C Verifiable Credential (pure-Python Ed25519)
88
+ from sdata.did import keys, pub_from_priv_jwk
89
+ priv = keys.gen_ed25519_jwk()
90
+ vc = data.metadata.to_verifiable_credential("did:example:issuer", priv)
91
+ subject = data.metadata.from_verifiable_credential(vc, pub_from_priv_jwk(priv))
92
+
93
+ # interactive: attribute autocomplete + rich Jupyter display
94
+ data.metadata.a.max_force # -> Attribute; tab-completion in Jupyter
95
+ data.metadata # -> _repr_html_ table
96
+ ```
97
+
98
+ Resulting JSON-LD for `max_force` (excerpt):
99
+
100
+ ```json
101
+ {
102
+ "@id": "did:suuid:DataFrame__specimen_01__3003...:sdata",
103
+ "@type": ["sdata:DataFrame", "bfo:BFO_0000004"],
104
+ "name": "specimen_01",
105
+ "sdata:max_force": {
106
+ "@type": ["qudt:Quantity", "bfo:Quality"],
107
+ "value": {"@value": 12.5, "@type": "xsd:double"},
108
+ "unitRef": "unit:KiloN", "symbol": "kN"
109
+ },
110
+ "columns": [{"name": "force", "datatype": "xsd:double"}]
111
+ }
112
+ ```
113
+
114
+ The optional semantic backends degrade gracefully to pure Python (no hard
115
+ dependency): `pip install "sdata[rdf]"` (rdflib), `sdata[units]` (pint),
116
+ `sdata[schema]` (jsonschema). Core install needs only `numpy`, `pandas`, `suuid`.
117
+
118
+ ## Tabular data (`DataFrame`)
119
+
120
+ `DataFrame` wraps a pandas frame plus per-column metadata and serializes to many
121
+ formats — Parquet, Arrow/Feather, CSV, dict/JSON, JSON-LD, a Frictionless **Data
122
+ Package** and **HDF5** — with the qualifying metadata embedded or written as a
123
+ sidecar.
124
+
125
+ ```python
126
+ import pandas as pd
127
+ from sdata.sclass.dataframe import DataFrame
128
+
129
+ sdf = DataFrame(df=pd.DataFrame({"weight": [10, 20], "height": [1.5, 1.6]}),
130
+ name="specimen_01", description="a tension test")
131
+
132
+ # per-column annotations (only the fields you pass are changed)
133
+ sdf.set_column("weight", unit="kg", label="Gewicht", ontology="bfo:Quality")
134
+ sdf.col["height"].unit = "m" # mutate the column Attribute in place
135
+ sdf.column_units # {'weight': 'kg', 'height': 'm'}
136
+
137
+ # serialize (optional <sname>.meta.jsonld sidecar; bytes/str without a path)
138
+ sdf.to_parquet(path="out", sidecar=True) # out/<sname>.spq + sidecar
139
+ sdf.to_csv(path="out") # data-only CSV (pure pandas)
140
+ sdf.to_feather(path="out") # Arrow IPC + native per-column field metadata
141
+ sdf.to_datapackage(path="out") # Frictionless Data Package (.zip)
142
+ sdf.to_hdf(path="out") # HDF5 via h5py, one dataset/column (sdata[hdf])
143
+ DataFrame.from_parquet("out/specimen_01.spq")
144
+
145
+ # validate the table against a schema (missing/dtype/unit/extra columns)
146
+ from sdata.schema import TableSchema, AttrSpec
147
+ schema = TableSchema("TensileTable", [
148
+ AttrSpec("weight", dtype="int", unit="kg", required=True),
149
+ ])
150
+ report = sdf.validate_table(schema) # ValidationReport (truthy if ok)
151
+ ```
152
+
153
+ Arrow/Feather/Parquet need `pip install "sdata[parquet]"`, HDF5 `sdata[hdf]`; CSV,
154
+ dict, JSON-LD and the (CSV) Data Package work with the core install. See the
155
+ [Tabular data docs](https://lepy.github.io/sdata/usage/dataframe/)
156
+ ([`docs/usage/dataframe.md`](docs/usage/dataframe.md)) for the full reference.
157
+
158
+ ## Howto
159
+
160
+
161
+ * [Das sdata-Format - slides](https://lepy.github.io/sdata/ipynb/Das_sdata_Format.slides.html#)
162
+ * https://deepwiki.com/lepy/sdata
163
+
164
+ ## Demo App
165
+
166
+ * [test the demo app with editor](https://share.streamlit.io/lepy/sdata_streamlit/main/sdata_editor.py)
167
+
168
+ Try to paste some Excel-Data in the forms ...
169
+
170
+
171
+ ## Metadata
172
+
173
+ ### Attributes
174
+
175
+ * name
176
+ * value
177
+ * dtype
178
+ * unit
179
+ * description
180
+ * label
181
+ * required
182
+ * ontology (CURIE/IRI of the value's class, e.g. `bfo:Quality`)
183
+
184
+ ### dtypes for attributes
185
+
186
+ Every attribute value is coerced to a declared dtype (single source:
187
+ `sdata.dtypes`), each with a lossless JSON-LD / XSD mapping:
188
+
189
+ * `int`, `float`, `str`, `bool`
190
+ * `list` (list of strings), `floatlist` (typed list of floats)
191
+ * `timestamp` (ISO-8601 with timezone, stdlib `zoneinfo`)
192
+ * `date`, `time`, `duration` (ISO-8601 / `datetime` types)
193
+ * `decimal` (exact decimal), `complex` (complex number)
194
+ * `bytes` (base64 in JSON), `json` (dict/list), `uri`
195
+ * `langstring` (language-tagged string, `rdf:langString`, e.g. `"Hallo@de"`)
196
+
197
+ Coercion is **lenient** by default (invalid values are logged and left unchanged).
198
+ Pass `strict=True` (e.g. `metadata.add(..., strict=True)`) to raise `DtypeError`
199
+ instead. See the [conventions](https://lepy.github.io/sdata/conventions/) for the
200
+ error policy.
201
+
202
+ ## paper
203
+
204
+ * [Das sdata-Format](https://zenodo.org/record/4311323#.X89yo9-YXys)
205
+ * Ingolf Lepenies. (2020). Das sdata-Format (Version 0.8.4). http://doi.org/10.5281/zenodo.4311323
206
+ * [slides](https://lepy.github.io/sdata/ipynb/Das_sdata_Format.slides.html#),
207
+ [html](https://lepy.github.io/sdata/paper/2020/Das_sdata-Format.html),
208
+ [pdf](https://lepy.github.io/sdata/paper/2020/Das_sdata-Format.pdf)
209
+ [temperaturmessung-001.json](https://lepy.github.io/sdata/paper/2020/temperaturmessung-001.json)
210
+ [temperaturmessung-001.xlsx](https://lepy.github.io/sdata/paper/2020/temperaturmessung-001.xlsx)
211
+
212
+ * [sdata](https://doi.org/10.5281/zenodo.4311396)
213
+ * Ingolf Lepenies. (2020, December 8). sdata - a structured data format (Version 0.8.4). Zenodo. http://doi.org/10.5281/zenodo.4311397
214
+
@@ -0,0 +1,92 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77.0.0", "wheel"] # >=77: PEP-639-Lizenzfelder
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sdata"
7
+ dynamic = ["version"] # Single Source: sdata/__init__.py:__version__
8
+ description = "a structured data format"
9
+ readme = "README.md"
10
+ license = "MIT" # SPDX (PEP 639); RFC 0008 A7 / RFC 0013
11
+ # Nur die eigene Lizenz: das einzige vendored Modul (sdata/contrib/sobol_seq.py,
12
+ # MIT) trägt seinen Lizenztext im Dateikopf. Kein Muster ohne Treffer — setuptools
13
+ # warnt sonst und lehnt solche Builds ab 2027-02-18 ab.
14
+ license-files = ["LICENSE-MIT"]
15
+ requires-python = ">=3.9"
16
+ authors = [{ name = "Ingolf Lepenies", email = "lepy@tuta.io" }]
17
+ maintainers = [{ name = "Ingolf Lepenies", email = "lepy@tuta.io" }]
18
+ keywords = ["open data"]
19
+ # Schlanker Kern: nur numpy/pandas (Datenmodell) und suuid. Zeitzonen über das
20
+ # stdlib-Modul zoneinfo (Python >= 3.9).
21
+ dependencies = ["numpy", "pandas", "suuid>=0.2.0"]
22
+ classifiers = [
23
+ "Development Status :: 3 - Alpha",
24
+ "Intended Audience :: Developers",
25
+ "Natural Language :: English",
26
+ "Operating System :: OS Independent",
27
+ "Programming Language :: Python :: 3.9",
28
+ "Programming Language :: Python :: 3.10",
29
+ "Programming Language :: Python :: 3.11",
30
+ "Programming Language :: Python :: 3.12",
31
+ "Programming Language :: Python :: Implementation :: CPython",
32
+ "Programming Language :: Python :: Implementation :: PyPy",
33
+ ]
34
+
35
+ [project.urls]
36
+ Homepage = "https://github.com/lepy/sdata"
37
+ Documentation = "https://lepy.github.io/sdata/"
38
+
39
+ [project.optional-dependencies]
40
+ # sdata.did ist abhängigkeitsfrei (Ed25519 + base58btc als pure Python);
41
+ # das Extra bleibt als no-op erhalten, damit 'pip install sdata[did]' weiter geht.
42
+ did = []
43
+ http = ["requests"] # sonst urllib-Fallback (stdlib)
44
+ excel = ["openpyxl", "xlsxwriter", "tabulate"]
45
+ hdf = ["h5py"] # sdata.sclass.DataFrame (natives HDF5, RFC 0002)
46
+ sql = ["sqlalchemy"]
47
+ parquet = ["pyarrow"] # sdata.sclass.DataFrame (Parquet)
48
+ blob = ["fsspec"] # sdata.sclass.Blob (URI-Content: file/S3/Zip)
49
+ units = ["pint"] # sonst kuratierte QUDT/UCUM-Tabelle
50
+ rdf = ["rdflib"] # sonst JSON-LD (= gültiges RDF)
51
+ schema = ["jsonschema"] # sonst native MetadataSchema-Prüfung
52
+
53
+ [tool.setuptools.dynamic]
54
+ version = { attr = "sdata.__version__" }
55
+
56
+ [tool.setuptools.packages.find]
57
+ include = ["sdata*"]
58
+
59
+ [tool.pytest.ini_options]
60
+ # Nur die eigene Testsuite kollektieren; vendored contrib-Tests (z. B.
61
+ # sdata/contrib/ecdsa/test_*.py) bewusst ausschliessen.
62
+ testpaths = ["tests"]
63
+
64
+ [tool.coverage.run]
65
+ source = ["sdata"]
66
+ omit = [
67
+ # Vendored Third-Party-Libs (nicht Teil der eigenen Coverage)
68
+ "sdata/contrib/*",
69
+ # Test-/Hilfsdateien
70
+ "*/tests/*",
71
+ "sdata/test/*",
72
+ # Deprecated / experimentell / WIP / Netzwerk — bewusst ausgeblendet
73
+ "sdata/deprecated/*", # Data (ersetzt durch sdata.sclass.dataframe.DataFrame)
74
+ "sdata/experiments/*",
75
+ "*_old.py",
76
+ "*_deprecated.py",
77
+ "sdata/sclass/bfo_classes.py",
78
+ "sdata/sclass/process.py",
79
+ "sdata/sclass/process_graph.py",
80
+ "sdata/sclass/image.py", # Image(Blob); optionales Pillow-Backend (nicht als CI-Dep deklariert)
81
+ ]
82
+
83
+ [tool.coverage.report]
84
+ show_missing = true
85
+ exclude_also = [
86
+ "pragma: no cover",
87
+ "if __name__ == .__main__.:",
88
+ "raise NotImplementedError",
89
+ "if TYPE_CHECKING:",
90
+ "@(abc\\.)?abstractmethod",
91
+ "\\.\\.\\.",
92
+ ]