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
@@ -0,0 +1,313 @@
1
+ import copy
2
+ import logging
3
+ import collections
4
+ import pandas as pd
5
+ import numpy as np
6
+ from sdata.timestamp import TimeStamp
7
+ from sdata.deprecated.data import Data
8
+ from sdata.suuid import SUUID
9
+ from sdata.metadata import Metadata, Attribute
10
+ import sdata.contrib
11
+ import sdata.contrib.piexif
12
+ import sdata.contrib.piexif.helper
13
+ import json
14
+ import os
15
+ from io import BytesIO
16
+ import base64
17
+ import hashlib
18
+ try:
19
+ import PIL
20
+ except:
21
+ logging.warning("PIL is not available -> no image import")
22
+ PIL = None
23
+
24
+ class Image(Data):
25
+ """Image Object
26
+
27
+ .. warning::
28
+
29
+ highly experimental"""
30
+
31
+
32
+ def __init__(self, url, **kwargs):
33
+ """Image Object"""
34
+
35
+ # url = kwargs.get("url", "")
36
+ load = kwargs.get("load", False)
37
+ try:
38
+ name = os.path.basename(url)
39
+ except Exception as exp:
40
+ name = None
41
+ if "name" not in kwargs:
42
+ kwargs["name"] = name
43
+ Data.__init__(self, **kwargs)
44
+ self.url = url
45
+ self.img = None
46
+ if load is True:
47
+ self.load()
48
+
49
+ @classmethod
50
+ def _from_filepath(cls, filepath, **kwargs):
51
+ """read image from file
52
+
53
+ :param fielpath: image file path
54
+ :return: sdata.Image
55
+ """
56
+ project = kwargs.get("project")
57
+ suuid = SUUID.from_file(cls.__class__.__name__, filepath, ns_name=project)
58
+ kwargs["uuid"] = suuid.huuid
59
+ kwargs["url"] = filepath
60
+ data = cls(name=os.path.basename(filepath), **kwargs)
61
+ return data
62
+
63
+ @classmethod
64
+ def from_image(cls, name, img, **kwargs):
65
+ """read image from PIL.Image
66
+
67
+ """
68
+ project = kwargs.get("project", "")
69
+ parent = kwargs.get("parent", "")
70
+ class_name = "Image" #cls.__class__.__name__
71
+
72
+ sh = hashlib.sha3_256()
73
+ sh.update(img.tobytes())
74
+ suuid = SUUID.from_name(class_name=class_name, name=sh.hexdigest(), ns_name=project)
75
+ suuid.project = project
76
+ kwargs["parent"] = parent
77
+ kwargs["project"] = suuid.project
78
+ kwargs["sname"] = suuid.sname
79
+ kwargs["uuid"] = suuid.huuid
80
+ kwargs["suuid"] = suuid.idstr
81
+ kwargs["url"] = sdata.osname(name)
82
+ # name = os.path.basename(filepath)
83
+ data = cls(name=name, **kwargs)
84
+ data.img = img
85
+ return data
86
+
87
+
88
+ @classmethod
89
+ def from_bytes(cls, name, image_data, **kwargs):
90
+ """read image from file
91
+
92
+ """
93
+ project = kwargs.get("project")
94
+ class_name = "Image" #cls.__class__.__name__
95
+ suuid = SUUID.from_str(class_name, name, ns_name=project)
96
+ kwargs["sname"] = suuid.sname
97
+ kwargs["uuid"] = suuid.huuid
98
+ kwargs["suuid"] = suuid.idstr
99
+ kwargs["url"] = name
100
+ data = cls(name=name, **kwargs)
101
+ data.img = PIL.Image.open(BytesIO(image_data))
102
+ try:
103
+ d = None
104
+ if name.lower().endswith(".png"):
105
+ d = cls._get_png_metadata(image_data)
106
+ elif name.lower().endswith(("jpg", "jpeg")):
107
+ d = cls._get_jpg_metadata(image_data)
108
+ if d is not None:
109
+ data.metadata = data.metadata.from_json(d)
110
+ except:
111
+ pass
112
+ return data
113
+
114
+
115
+ @classmethod
116
+ def from_file(cls, filepath, **kwargs):
117
+ """read image from file
118
+
119
+ """
120
+ project = kwargs.get("project")
121
+ class_name = "Image" #cls.__class__.__name__
122
+ suuid = SUUID.from_file(class_name, filepath, ns_name=project)
123
+ kwargs["sname"] = suuid.sname
124
+ kwargs["uuid"] = suuid.huuid
125
+ kwargs["suuid"] = suuid.idstr
126
+ kwargs["url"] = filepath
127
+ name = os.path.basename(filepath)
128
+
129
+
130
+ if filepath.lower().endswith(".png"):
131
+ data = cls.from_png(filepath, **kwargs)
132
+ elif filepath.lower().endswith(("jpg", "jpeg")):
133
+ data = cls.from_jpg(filepath, **kwargs)
134
+ else:
135
+ data = cls(name=name, **kwargs)
136
+ return data
137
+
138
+ def get_sha3_256(self, filepath):
139
+ sh = hashlib.sha3_256()
140
+ with open(filepath, "rb") as fh:
141
+ sh.update(fh.read())
142
+ return sh.hexdigest()
143
+
144
+ def get_image_metadata(self):
145
+ """get metadata dict from pillow image"""
146
+ if self.img is None:
147
+ self.load()
148
+ return self.img.info
149
+
150
+ def load(self):
151
+ """store image data in sdata.Image.img"""
152
+ if PIL is None:
153
+ logging.warning("PIL is not available -> no image import")
154
+ return
155
+
156
+ if os.path.exists(self.url):
157
+ self.img = PIL.Image.open(self.url)
158
+ return self.img
159
+
160
+ def to_numpy(self):
161
+ """returns a NumPy array created from the color channels of the given Image object
162
+
163
+ array([[[192, 190, 187],
164
+ [193, 190, 187],
165
+ [193, 190, 185],
166
+ """
167
+ return np.array(self.img)
168
+
169
+ @classmethod
170
+ def from_png(cls, filepath, **kwargs):
171
+ """load png image and metadata
172
+
173
+ """
174
+ if PIL is None:
175
+ logging.warning("PIL is not available -> no image import")
176
+ return
177
+ data = cls._from_filepath(filepath, **kwargs)
178
+ data.load()
179
+ if "sdata" in data.img.info:
180
+ d = json.loads(data.img.info.get("sdata"))
181
+ data.metadata = data.metadata.from_json(d)
182
+ return data
183
+
184
+ @staticmethod
185
+ def _get_metadata(filepath, **kwargs):
186
+ """
187
+
188
+ """
189
+ if filepath.lower().endswith(".png"):
190
+ d = Image._get_png_metadata(filepath, **kwargs)
191
+ elif filepath.lower().endswith(".jpg"):
192
+ d = Image._get_png_metadata(filepath, **kwargs)
193
+ else:
194
+ d = {}
195
+ return d
196
+
197
+ @staticmethod
198
+ def _get_png_metadata(filepath, **kwargs):
199
+ """load metadata json dict from img.info
200
+ """
201
+ img = PIL.Image.open(filepath)
202
+ try:
203
+ d = json.loads(img.info.get("sdata"))
204
+ except Exception as exp:
205
+ d = {}
206
+ return d
207
+
208
+ @classmethod
209
+ def from_jpg(cls, filepath, **kwargs):
210
+ """load jpg image and metadata
211
+
212
+ """
213
+ if PIL is None:
214
+ logging.warning("PIL is not available -> no image import")
215
+ return
216
+ data = cls._from_filepath(filepath, **kwargs)
217
+ # data.load()
218
+ try:
219
+ d = cls._get_jpg_metadata(filepath)
220
+ if d is not None:
221
+ data.metadata = data.metadata.from_json(d)
222
+ except Exception as exp:
223
+ logging.debug(exp)
224
+ return data
225
+
226
+ @staticmethod
227
+ def _get_jpg_metadata(filepath):
228
+ """load metadata json dict from exif usercomment
229
+
230
+ """
231
+ exif_dict = sdata.contrib.piexif.load(filepath)
232
+ exif = exif_dict.get("Exif")
233
+ user_comment = exif.get(sdata.contrib.piexif.ExifIFD.UserComment)
234
+ d = None
235
+ if user_comment is not None:
236
+ json_string = sdata.contrib.piexif.helper.UserComment.load(user_comment)
237
+ d = json.loads(json_string)
238
+ return d
239
+
240
+ @property
241
+ def basename(self):
242
+ return os.path.basename(self.url)
243
+
244
+ def saveas(self, filepath, rename=True, random=True, **kwargs):
245
+ """save image
246
+
247
+ """
248
+ other = copy.deepcopy(self) # keep parent ...
249
+ if rename is True:
250
+ basename = os.path.basename(filepath)
251
+ other.rename(basename, random=random)
252
+ other.update_mtime()
253
+ other.save(filepath)
254
+ return other
255
+
256
+ def save(self, filepath, **kwargs):
257
+
258
+ if self.img is None:
259
+ self.load()
260
+
261
+ if filepath.endswith(".png"):
262
+ self._save_png(filepath)
263
+ elif filepath.lower().endswith(".jpg"):
264
+ self._save_jpg(filepath)
265
+ else:
266
+ logging.warning(f"metadata not supported for {filepath}")
267
+ self.img.save(filepath)
268
+
269
+ def _save_png(self, filepath):
270
+ """save png with metadata
271
+
272
+ """
273
+ if self.img is None:
274
+ self.load()
275
+
276
+ json_string = json.dumps(self.metadata.to_json())
277
+ metadaten = PIL.PngImagePlugin.PngInfo()
278
+ metadaten.add_text("sdata", json_string)
279
+
280
+ self.img.save(filepath, "PNG", pnginfo=metadaten)
281
+
282
+ def _save_jpg(self, filepath):
283
+ """save jpg with metadata
284
+
285
+ """
286
+ if self.img is None:
287
+ self.load()
288
+ json_string = json.dumps(self.metadata.to_json())
289
+ exif_dict = {"Exif": {sdata.contrib.piexif.ExifIFD.UserComment: sdata.contrib.piexif.helper.UserComment.dump(json_string)}}
290
+ exif_bytes = sdata.contrib.piexif.dump(exif_dict)
291
+ self.img.save(filepath, "jpeg", exif=exif_bytes)
292
+
293
+ def get_image_download_link(self, img, filename, text):
294
+
295
+ json_string = json.dumps(self.metadata.to_json())
296
+ buffered = BytesIO()
297
+
298
+ if filename.endswith(".png"):
299
+ metadaten = PIL.PngImagePlugin.PngInfo()
300
+ metadaten.add_text("sdata", json_string)
301
+ img.save(buffered, "PNG", pnginfo=metadaten)
302
+ elif filename.lower().endswith(".jpg"):
303
+ exif_dict = {"Exif": {
304
+ sdata.contrib.piexif.ExifIFD.UserComment: sdata.contrib.piexif.helper.UserComment.dump(json_string)}}
305
+ exif_bytes = sdata.contrib.piexif.dump(exif_dict)
306
+ img.save(buffered, format="JPEG", exif=exif_bytes)
307
+ else:
308
+ logging.warning(f"metadata not supported for {filepath}")
309
+ img.save(buffered)
310
+
311
+ img_str = base64.b64encode(buffered.getvalue()).decode()
312
+ href = f'<a href="data:file/txt;base64,{img_str}" download="{filename}">{text}</a>'
313
+ return href
@@ -0,0 +1,15 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # ["name", "default_value", "dtype", "unit", "description", "required"]
4
+
5
+ ks2specimen_default_attributes = [["rd", None, "float", "deg", "rolling direction", True],
6
+ ["t", None, "float", "mm", "thickness sheet", True],
7
+ ["r", None, "float", "mm", "bending radius sheet", True],
8
+ ["bi", None, "float", "mm", "inner width", True],
9
+ ["hi", None, "float", "mm", "inner height", True],
10
+ ["l", None, "float", "mm", "length", True],
11
+ ]
12
+
13
+ # ["name", "value", "dtype", "unit", "description", "required"]
14
+ ks2test_default_attributes = [["angle", None, "float", "deg", "loading angle", True],
15
+ ]
@@ -0,0 +1,8 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ lapshear_specimen_default_attributes = [
4
+ ["rd", None, "float", "deg", "rolling direction", True],
5
+ ["t", None, "float", "mm", "thickness sheet", True],
6
+ ["l", None, "float", "mm", "length", True],
7
+ ["w", None, "float", "mm", "width", True],
8
+ ]
@@ -0,0 +1,7 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # ["name", "default_value", "dtype", "unit", "description", "required"]
4
+ material_default_attributes = [
5
+ ["material_type", None, "str", "-", "Material type, e.g. alu|steel|plastic|wood|glas|foam|soil|...", True],
6
+ ["material_grade", "-", "str", "-", "Material grade, e.g. T4", False],
7
+ ]