otdf-python 0.0.11__py3-none-any.whl → 0.0.12__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.
otdf_python/build.py CHANGED
@@ -149,6 +149,11 @@ mod.add_function('Slice_uint8_elem', retval('uint8_t'), [param('int64_t', 'handl
149
149
  mod.add_function('Slice_uint8_subslice', retval('int64_t'), [param('int64_t', 'handle'), param('int', 'st'), param('int', 'ed')])
150
150
  mod.add_function('Slice_uint8_set', None, [param('int64_t', 'handle'), param('int', 'idx'), param('uint8_t', 'value')])
151
151
  mod.add_function('Slice_uint8_append', None, [param('int64_t', 'handle'), param('uint8_t', 'value')])
152
+ mod.add_function('gotdf_python_TokenAuth_CTor', retval('int64_t'), [])
153
+ mod.add_function('gotdf_python_TokenAuth_AccessToken_Get', retval('char*'), [param('int64_t', 'handle')])
154
+ mod.add_function('gotdf_python_TokenAuth_AccessToken_Set', None, [param('int64_t', 'handle'), param('char*', 'val')])
155
+ mod.add_function('gotdf_python_TokenAuth_NpeClientId_Get', retval('char*'), [param('int64_t', 'handle')])
156
+ mod.add_function('gotdf_python_TokenAuth_NpeClientId_Set', None, [param('int64_t', 'handle'), param('char*', 'val')])
152
157
  mod.add_function('gotdf_python_DecryptionConfig_CTor', retval('int64_t'), [])
153
158
  mod.add_function('gotdf_python_DecryptionConfig_ClientId_Get', retval('char*'), [param('int64_t', 'handle')])
154
159
  mod.add_function('gotdf_python_DecryptionConfig_ClientId_Set', None, [param('int64_t', 'handle'), param('char*', 'val')])
@@ -173,18 +178,13 @@ mod.add_function('gotdf_python_EncryptionConfig_KasUrl_Get', retval('char*'), [p
173
178
  mod.add_function('gotdf_python_EncryptionConfig_KasUrl_Set', None, [param('int64_t', 'handle'), param('char*', 'val')])
174
179
  mod.add_function('gotdf_python_EncryptionConfig_DataAttributes_Get', retval('int64_t'), [param('int64_t', 'handle')])
175
180
  mod.add_function('gotdf_python_EncryptionConfig_DataAttributes_Set', None, [param('int64_t', 'handle'), param('int64_t', 'val')])
176
- mod.add_function('gotdf_python_TokenAuth_CTor', retval('int64_t'), [])
177
- mod.add_function('gotdf_python_TokenAuth_AccessToken_Get', retval('char*'), [param('int64_t', 'handle')])
178
- mod.add_function('gotdf_python_TokenAuth_AccessToken_Set', None, [param('int64_t', 'handle'), param('char*', 'val')])
179
- mod.add_function('gotdf_python_TokenAuth_NpeClientId_Get', retval('char*'), [param('int64_t', 'handle')])
180
- mod.add_function('gotdf_python_TokenAuth_NpeClientId_Set', None, [param('int64_t', 'handle'), param('char*', 'val')])
181
+ add_checked_string_function(mod, 'gotdf_python_DecryptFile', retval('char*'), [param('char*', 'inputFilePath'), param('char*', 'outputFilePath'), param('int64_t', 'config')])
181
182
  add_checked_string_function(mod, 'gotdf_python_DecryptFilePE', retval('char*'), [param('char*', 'inputFilePath'), param('char*', 'outputFilePath'), param('int64_t', 'config'), param('int64_t', 'token')])
182
183
  add_checked_string_function(mod, 'gotdf_python_DecryptStringPE', retval('char*'), [param('char*', 'inputText'), param('int64_t', 'config'), param('int64_t', 'token')])
183
184
  add_checked_string_function(mod, 'gotdf_python_EncryptFile', retval('char*'), [param('char*', 'inputFilePath'), param('char*', 'outputFilePath'), param('int64_t', 'config')])
184
185
  add_checked_string_function(mod, 'gotdf_python_EncryptFilePE', retval('char*'), [param('char*', 'inputFilePath'), param('char*', 'outputFilePath'), param('int64_t', 'config'), param('int64_t', 'token')])
185
186
  add_checked_string_function(mod, 'gotdf_python_EncryptString', retval('char*'), [param('char*', 'inputText'), param('int64_t', 'config')])
186
187
  add_checked_string_function(mod, 'gotdf_python_Hello', retval('char*'), [])
187
- add_checked_string_function(mod, 'gotdf_python_DecryptFile', retval('char*'), [param('char*', 'inputFilePath'), param('char*', 'outputFilePath'), param('int64_t', 'config')])
188
188
 
189
189
  mod.generate(open('gotdf_python.c', 'w'))
190
190
 
@@ -44,6 +44,73 @@ os.chdir(cwd)
44
44
 
45
45
  # ---- Structs ---
46
46
 
47
+ # Python type for struct gotdf_python.TokenAuth
48
+ class TokenAuth(go.GoClass):
49
+ """"""
50
+ def __init__(self, *args, **kwargs):
51
+ """
52
+ handle=A Go-side object is always initialized with an explicit handle=arg
53
+ otherwise parameters can be unnamed in order of field names or named fields
54
+ in which case a new Go object is constructed first
55
+ """
56
+ if len(kwargs) == 1 and 'handle' in kwargs:
57
+ self.handle = kwargs['handle']
58
+ _gotdf_python.IncRef(self.handle)
59
+ elif len(args) == 1 and isinstance(args[0], go.GoClass):
60
+ self.handle = args[0].handle
61
+ _gotdf_python.IncRef(self.handle)
62
+ else:
63
+ self.handle = _gotdf_python.gotdf_python_TokenAuth_CTor()
64
+ _gotdf_python.IncRef(self.handle)
65
+ if 0 < len(args):
66
+ self.AccessToken = args[0]
67
+ if "AccessToken" in kwargs:
68
+ self.AccessToken = kwargs["AccessToken"]
69
+ if 1 < len(args):
70
+ self.NpeClientId = args[1]
71
+ if "NpeClientId" in kwargs:
72
+ self.NpeClientId = kwargs["NpeClientId"]
73
+ def __del__(self):
74
+ _gotdf_python.DecRef(self.handle)
75
+ def __str__(self):
76
+ pr = [(p, getattr(self, p)) for p in dir(self) if not p.startswith('__')]
77
+ sv = 'gotdf_python.TokenAuth{'
78
+ first = True
79
+ for v in pr:
80
+ if callable(v[1]):
81
+ continue
82
+ if first:
83
+ first = False
84
+ else:
85
+ sv += ', '
86
+ sv += v[0] + '=' + str(v[1])
87
+ return sv + '}'
88
+ def __repr__(self):
89
+ pr = [(p, getattr(self, p)) for p in dir(self) if not p.startswith('__')]
90
+ sv = 'gotdf_python.TokenAuth ( '
91
+ for v in pr:
92
+ if not callable(v[1]):
93
+ sv += v[0] + '=' + str(v[1]) + ', '
94
+ return sv + ')'
95
+ @property
96
+ def AccessToken(self):
97
+ return _gotdf_python.gotdf_python_TokenAuth_AccessToken_Get(self.handle)
98
+ @AccessToken.setter
99
+ def AccessToken(self, value):
100
+ if isinstance(value, go.GoClass):
101
+ _gotdf_python.gotdf_python_TokenAuth_AccessToken_Set(self.handle, value.handle)
102
+ else:
103
+ _gotdf_python.gotdf_python_TokenAuth_AccessToken_Set(self.handle, value)
104
+ @property
105
+ def NpeClientId(self):
106
+ return _gotdf_python.gotdf_python_TokenAuth_NpeClientId_Get(self.handle)
107
+ @NpeClientId.setter
108
+ def NpeClientId(self, value):
109
+ if isinstance(value, go.GoClass):
110
+ _gotdf_python.gotdf_python_TokenAuth_NpeClientId_Set(self.handle, value.handle)
111
+ else:
112
+ _gotdf_python.gotdf_python_TokenAuth_NpeClientId_Set(self.handle, value)
113
+
47
114
  # Python type for struct gotdf_python.DecryptionConfig
48
115
  class DecryptionConfig(go.GoClass):
49
116
  """"""
@@ -269,73 +336,6 @@ class EncryptionConfig(go.GoClass):
269
336
  else:
270
337
  raise TypeError("supplied argument type {t} is not a go.GoClass".format(t=type(value)))
271
338
 
272
- # Python type for struct gotdf_python.TokenAuth
273
- class TokenAuth(go.GoClass):
274
- """"""
275
- def __init__(self, *args, **kwargs):
276
- """
277
- handle=A Go-side object is always initialized with an explicit handle=arg
278
- otherwise parameters can be unnamed in order of field names or named fields
279
- in which case a new Go object is constructed first
280
- """
281
- if len(kwargs) == 1 and 'handle' in kwargs:
282
- self.handle = kwargs['handle']
283
- _gotdf_python.IncRef(self.handle)
284
- elif len(args) == 1 and isinstance(args[0], go.GoClass):
285
- self.handle = args[0].handle
286
- _gotdf_python.IncRef(self.handle)
287
- else:
288
- self.handle = _gotdf_python.gotdf_python_TokenAuth_CTor()
289
- _gotdf_python.IncRef(self.handle)
290
- if 0 < len(args):
291
- self.AccessToken = args[0]
292
- if "AccessToken" in kwargs:
293
- self.AccessToken = kwargs["AccessToken"]
294
- if 1 < len(args):
295
- self.NpeClientId = args[1]
296
- if "NpeClientId" in kwargs:
297
- self.NpeClientId = kwargs["NpeClientId"]
298
- def __del__(self):
299
- _gotdf_python.DecRef(self.handle)
300
- def __str__(self):
301
- pr = [(p, getattr(self, p)) for p in dir(self) if not p.startswith('__')]
302
- sv = 'gotdf_python.TokenAuth{'
303
- first = True
304
- for v in pr:
305
- if callable(v[1]):
306
- continue
307
- if first:
308
- first = False
309
- else:
310
- sv += ', '
311
- sv += v[0] + '=' + str(v[1])
312
- return sv + '}'
313
- def __repr__(self):
314
- pr = [(p, getattr(self, p)) for p in dir(self) if not p.startswith('__')]
315
- sv = 'gotdf_python.TokenAuth ( '
316
- for v in pr:
317
- if not callable(v[1]):
318
- sv += v[0] + '=' + str(v[1]) + ', '
319
- return sv + ')'
320
- @property
321
- def AccessToken(self):
322
- return _gotdf_python.gotdf_python_TokenAuth_AccessToken_Get(self.handle)
323
- @AccessToken.setter
324
- def AccessToken(self, value):
325
- if isinstance(value, go.GoClass):
326
- _gotdf_python.gotdf_python_TokenAuth_AccessToken_Set(self.handle, value.handle)
327
- else:
328
- _gotdf_python.gotdf_python_TokenAuth_AccessToken_Set(self.handle, value)
329
- @property
330
- def NpeClientId(self):
331
- return _gotdf_python.gotdf_python_TokenAuth_NpeClientId_Get(self.handle)
332
- @NpeClientId.setter
333
- def NpeClientId(self, value):
334
- if isinstance(value, go.GoClass):
335
- _gotdf_python.gotdf_python_TokenAuth_NpeClientId_Set(self.handle, value.handle)
336
- else:
337
- _gotdf_python.gotdf_python_TokenAuth_NpeClientId_Set(self.handle, value)
338
-
339
339
 
340
340
  # ---- Slices ---
341
341
 
@@ -347,6 +347,9 @@ class TokenAuth(go.GoClass):
347
347
 
348
348
 
349
349
  # ---- Functions ---
350
+ def DecryptFile(inputFilePath, outputFilePath, config):
351
+ """DecryptFile(str inputFilePath, str outputFilePath, object config) str, str"""
352
+ return _gotdf_python.gotdf_python_DecryptFile(inputFilePath, outputFilePath, config.handle)
350
353
  def DecryptFilePE(inputFilePath, outputFilePath, config, token):
351
354
  """DecryptFilePE(str inputFilePath, str outputFilePath, object config, object token) str, str"""
352
355
  return _gotdf_python.gotdf_python_DecryptFilePE(inputFilePath, outputFilePath, config.handle, token.handle)
@@ -376,8 +379,5 @@ def Hello():
376
379
  conventional & useful function like GetVersion()
377
380
  """
378
381
  return _gotdf_python.gotdf_python_Hello()
379
- def DecryptFile(inputFilePath, outputFilePath, config):
380
- """DecryptFile(str inputFilePath, str outputFilePath, object config) str, str"""
381
- return _gotdf_python.gotdf_python_DecryptFile(inputFilePath, outputFilePath, config.handle)
382
382
 
383
383
 
@@ -0,0 +1,149 @@
1
+ Metadata-Version: 2.1
2
+ Name: otdf_python
3
+ Version: 0.0.12
4
+ Home-page: https://github.com/b-long/opentdf-python-sdk
5
+ Author-email: b-long@users.noreply.github.com
6
+ Description-Content-Type: text/markdown
7
+ License-File: LICENSE
8
+
9
+ # opentdf-python-sdk
10
+
11
+ Unofficial OpenTDF SDK for Python
12
+
13
+ [![Tests](https://github.com/b-long/opentdf-python-sdk/workflows/PyPIBuild/badge.svg)](https://github.com/b-long/opentdf-python-sdk/actions?query=workflow%3APyPIBuild)
14
+
15
+ This project is powered by gopy, which generates (and compiles) a CPython extension module from a go package. The `gopy`
16
+ tool unlocks performance, flexibility, and excellent Developer Experience to Python end-users. Read more about
17
+ [`gopy` on Github](https://github.com/go-python/gopy).
18
+
19
+ ## Adding features
20
+
21
+ If you wish to expand the functionality of `otdf-python`:
22
+
23
+ 1. Create a fork/branch
24
+ 1. Add new capabilities (e.g. in `main.go`)
25
+ 1. Add a test (e.g. in `otdf_python_test.go`)
26
+ 1. Commit your changes, push, and open a Pull Request via
27
+ the Github project: https://github.com/b-long/opentdf-python-sdk
28
+
29
+ ## Installation
30
+
31
+ Install from the [Python Package Index (PyPI)](https://pypi.org):
32
+
33
+ ```bash
34
+ # Install the latest from pypi.org
35
+ pip install otdf_python
36
+
37
+ # Install a pinned version
38
+ pip install otdf-python==0.0.9
39
+
40
+ # Install a pinned version, from test.pypi.org
41
+ pip install -i https://test.pypi.org/simple/ otdf-python==0.0.9
42
+ ```
43
+
44
+ ## Usage
45
+
46
+ Simple usage examples are given below. In addition, we recommend you also:
47
+
48
+ 1. See the contents of [`main.go` on Github](https://github.com/b-long/opentdf-python-sdk/blob/main/main.go). ✨ Note that all Upper-case functions are available in Python.
49
+ 1. See the contents of [`validate_otdf_python.py` on Github](https://github.com/b-long/opentdf-python-sdk/blob/main/validate_otdf_python.py).
50
+
51
+ ### Example: Configuration
52
+
53
+ Creating a helper function may simplify the usage of `otdf-python`.
54
+
55
+ For example:
56
+
57
+ ```python
58
+ def get_encrypt_config(data_attributes: list | None = None):
59
+ """
60
+ The config object returned here can only be used for encryption.
61
+
62
+ While 'otdf_python.gotdf_python' internally can use golang interfaces,
63
+ to normalize config objects, that pattern causes a panic
64
+ when used from Python.
65
+
66
+ """
67
+ print("Preparing 'EncryptionConfig' object")
68
+ from otdf_python.gotdf_python import EncryptionConfig
69
+ from otdf_python.go import Slice_string
70
+
71
+ if isinstance(data_attributes, list):
72
+ # Create config using the attributes from the caller
73
+ da = Slice_string(data_attributes)
74
+ config: EncryptionConfig = EncryptionConfig(
75
+ ClientId="opentdf-sdk",
76
+ ClientSecret="secret",
77
+ PlatformEndpoint=platformEndpoint,
78
+ TokenEndpoint="http://localhost:8888/auth/realms/opentdf/protocol/openid-connect/token",
79
+ KasUrl=f"http://{platformEndpoint}/kas",
80
+ # FIXME: Be careful with binding the 'DataAttributes' field on this struct.
81
+ #
82
+ # In golang, this is initialized as []string , but passing
83
+ # DataAttributes=None, or DataAttributes=[] from Python will fail.
84
+ DataAttributes=da,
85
+ )
86
+ else:
87
+ # Create config without attributes
88
+ config: EncryptionConfig = EncryptionConfig(
89
+ ClientId=testing_credentials.TDF_NPE_CLIENT,
90
+ ClientSecret=testing_credentials.TDF_NPE_CLIENT_SECRET,
91
+ PlatformEndpoint=testing_credentials.PLATFORM_ENDPOINT,
92
+ TokenEndpoint=testing_credentials.OIDC_AUTH_URL,
93
+ KasUrl=testing_credentials.KAS_URL,
94
+ )
95
+
96
+ # NOTE: Structs from golang can be printed, like below
97
+ # print(config)
98
+ print("Returning 'EncryptionConfig'")
99
+
100
+ return config
101
+ ```
102
+
103
+
104
+ ### Example: Encrypt a string
105
+
106
+ ```python
107
+ from otdf_python.gotdf_python import EncryptString
108
+
109
+ # Depends on the 'get_encrypt_config()' given
110
+ # in the README above
111
+ config: EncryptionConfig = get_encrypt_config()
112
+
113
+ tdf_manifest_json = EncryptString(inputText="Hello from Python", config=config)
114
+ ```
115
+
116
+ ### Example: Encrypt a file
117
+
118
+ ```python
119
+ from otdf_python.gotdf_python import EncryptFile
120
+ from otdf_python.go import Slice_string
121
+
122
+ # Depends on the 'get_encrypt_config()' given
123
+ # in the README above
124
+ config: EncryptionConfig = get_encrypt_config()
125
+
126
+ with tempfile.TemporaryDirectory() as tmpDir:
127
+ print("Created temporary directory", tmpDir)
128
+
129
+ da = Slice_string(["https://example.com/attr/attr1/value/value1", "https://example.com/attr/attr1/value/value2"])
130
+
131
+ encrypted_file = Path(tmpDir) / "some-file.tdf"
132
+
133
+ if encrypted_file.exists():
134
+ encrypted_file.unlink()
135
+
136
+ if encrypted_file.exists():
137
+ raise ValueError(
138
+ "The output path should not exist before calling 'EncryptFile()'."
139
+ )
140
+
141
+ outputFilePath = EncryptFile(
142
+ inputFilePath=str(SOME_PLAINTEXT_FILE),
143
+ outputFilePath=str(encrypted_file),
144
+ config=config,
145
+ )
146
+
147
+ print(f"The output file was written to destination path: {outputFilePath}")
148
+
149
+ ```
@@ -0,0 +1,10 @@
1
+ otdf_python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ otdf_python/_gotdf_python.cpython-311-darwin.so,sha256=WaiZ__LO-HDPQBKuWhBNR3gFvNbvzhwapCGDGnC86Mg,15204536
3
+ otdf_python/build.py,sha256=n992UQdwhJukysD1zgty1LrOnNTPEGAAG9MOWGlaJqs,16756
4
+ otdf_python/go.py,sha256=7kz0kwEbEJZp9ZJIvdcUryZmhahLRb5RrkhGBN2BDBY,49317
5
+ otdf_python/gotdf_python.py,sha256=1-Agpw4XFW01MudVbpiuf59ZRKSzvARXv-ojOlbeKsE,13880
6
+ otdf_python-0.0.12.dist-info/LICENSE,sha256=51wzGxR-Rns8XaiGmDLq2OqPN3qWMpoQKV-fERpVzyM,1063
7
+ otdf_python-0.0.12.dist-info/METADATA,sha256=udqnlCw0jdvLs_aDGRWPfBjCn4HXYxeAocYh3wv0NYA,4964
8
+ otdf_python-0.0.12.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
9
+ otdf_python-0.0.12.dist-info/top_level.txt,sha256=A2vK95iTIxdu4pm8kDZlvHorBKCvSN5dvlMdFbIVXrA,12
10
+ otdf_python-0.0.12.dist-info/RECORD,,
@@ -1,82 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: otdf_python
3
- Version: 0.0.11
4
- Home-page: https://github.com/b-long/opentdf-python-sdk
5
- Author-email: b-long@users.noreply.github.com
6
- Description-Content-Type: text/markdown
7
- License-File: LICENSE
8
-
9
- # opentdf-python-sdk
10
-
11
- Unofficial OpenTDF SDK for Python
12
-
13
- [![Tests](https://github.com/b-long/opentdf-python-sdk/workflows/PyPIBuild/badge.svg)](https://github.com/b-long/opentdf-python-sdk/actions?query=workflow%3APyPIBuild)
14
-
15
-
16
- ## Installation
17
-
18
- Install from PyPI.org:
19
-
20
- ```bash
21
- pip install otdf_python
22
- ```
23
-
24
- ## Usage
25
-
26
- Simple usage examples are given below. In addition, see the content of `validate_otdf_python.py` .
27
-
28
- ### Example: Encrypt a string
29
-
30
- ```python
31
- from otdf_python.gotdf_python import EncryptString
32
-
33
- config: EncryptionConfig = _get_configuration()
34
-
35
- tdf_manifest_json = EncryptString(inputText="Hello from Python", config=config)
36
-
37
- ```
38
-
39
- ### Example: Encrypt a file
40
-
41
- ```python
42
- from otdf_python.gotdf_python import EncryptFile
43
- from otdf_python.go import Slice_string
44
-
45
- with tempfile.TemporaryDirectory() as tmpDir:
46
- print("Created temporary directory", tmpDir)
47
-
48
- da = Slice_string(["https://example.com/attr/attr1/value/value1", "https://example.com/attr/attr1/value/value2"])
49
-
50
- config: EncryptionConfig = EncryptionConfig(
51
- ClientId="opentdf-sdk",
52
- ClientSecret="secret",
53
- PlatformEndpoint=platformEndpoint,
54
- TokenEndpoint="http://localhost:8888/auth/realms/opentdf/protocol/openid-connect/token",
55
- KasUrl=f"http://{platformEndpoint}/kas",
56
- # FIXME: Be careful with binding the 'DataAttributes' field on this struct.
57
- #
58
- # In golang, this is initialized as []string , but passing
59
- # DataAttributes=None, or DataAttributes=[] from Python will fail.
60
- # DataAttributes=...
61
- DataAttributes=da,
62
- )
63
-
64
- encrypted_file = Path(tmpDir) / "some-file.tdf"
65
-
66
- if encrypted_file.exists():
67
- encrypted_file.unlink()
68
-
69
- if encrypted_file.exists():
70
- raise ValueError(
71
- "The output path should not exist before calling 'EncryptFile()'."
72
- )
73
-
74
- outputFilePath = EncryptFile(
75
- inputFilePath=str(SOME_PLAINTEXT_FILE),
76
- outputFilePath=str(encrypted_file),
77
- config=config,
78
- )
79
-
80
- print(f"The output file was written to destination path: {outputFilePath}")
81
-
82
- ```
@@ -1,10 +0,0 @@
1
- otdf_python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- otdf_python/_gotdf_python.cpython-311-darwin.so,sha256=fI0Up2Nk3hgxXpp2CD_u5nQvBztk3tbPUB_DoIYfO9E,15112432
3
- otdf_python/build.py,sha256=WwdUm0ey-MV1OuYjVcp12cKprHkHzGiupk4GphbhP9U,16756
4
- otdf_python/go.py,sha256=7kz0kwEbEJZp9ZJIvdcUryZmhahLRb5RrkhGBN2BDBY,49317
5
- otdf_python/gotdf_python.py,sha256=UtT6rqs7pEM7KiXEVApKBAP_Xx1s1_6mifL6_TVqN_g,13880
6
- otdf_python-0.0.11.dist-info/LICENSE,sha256=51wzGxR-Rns8XaiGmDLq2OqPN3qWMpoQKV-fERpVzyM,1063
7
- otdf_python-0.0.11.dist-info/METADATA,sha256=X7-5_6L_HpBWhGSyVI-v3ujgsOBDtgEqPu4GKMwie78,2316
8
- otdf_python-0.0.11.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
9
- otdf_python-0.0.11.dist-info/top_level.txt,sha256=A2vK95iTIxdu4pm8kDZlvHorBKCvSN5dvlMdFbIVXrA,12
10
- otdf_python-0.0.11.dist-info/RECORD,,