otdf-python 0.3.3__py3-none-any.whl → 0.3.4__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.
@@ -10,7 +10,7 @@ class AuthHeaders:
10
10
  """
11
11
 
12
12
  auth_header: str
13
- dpop_header: str
13
+ dpop_header: str = ""
14
14
 
15
15
  def get_auth_header(self) -> str:
16
16
  """Returns the authorization header."""
@@ -19,3 +19,15 @@ class AuthHeaders:
19
19
  def get_dpop_header(self) -> str:
20
20
  """Returns the DPoP header."""
21
21
  return self.dpop_header
22
+
23
+ def to_dict(self) -> dict[str, str]:
24
+ """
25
+ Convert authentication headers to a dictionary for use with HTTP clients.
26
+
27
+ Returns:
28
+ Dictionary with 'Authorization' header and optionally 'DPoP' header
29
+ """
30
+ headers = {"Authorization": self.auth_header}
31
+ if self.dpop_header:
32
+ headers["DPoP"] = self.dpop_header
33
+ return headers
otdf_python/cli.py CHANGED
@@ -88,7 +88,7 @@ def load_client_credentials(creds_file_path: str) -> tuple[str, str]:
88
88
  "CRITICAL", f"Credentials file does not exist: {creds_file_path}"
89
89
  )
90
90
 
91
- with open(creds_path) as f:
91
+ with creds_path.open() as f:
92
92
  creds = json.load(f)
93
93
 
94
94
  client_id = creds.get("clientId")
@@ -223,13 +223,13 @@ def cmd_encrypt(args):
223
223
 
224
224
  try:
225
225
  # Read input file
226
- with open(input_path, "rb") as input_file:
226
+ with input_path.open("rb") as input_file:
227
227
  payload = input_file.read()
228
228
 
229
229
  # Determine output
230
230
  if args.output:
231
231
  output_path = Path(args.output)
232
- with open(output_path, "wb") as output_file:
232
+ with output_path.open("wb") as output_file:
233
233
  try:
234
234
  # Create appropriate config based on container type
235
235
  container_type = getattr(args, "container_type", "tdf")
@@ -247,7 +247,7 @@ def cmd_encrypt(args):
247
247
  logger.debug("Creating TDF")
248
248
  config = create_tdf_config(sdk, args)
249
249
  output_stream = BytesIO()
250
- manifest, size, _ = sdk.create_tdf(
250
+ _manifest, size, _ = sdk.create_tdf(
251
251
  BytesIO(payload), config, output_stream
252
252
  )
253
253
  output_file.write(output_stream.getvalue())
@@ -274,7 +274,7 @@ def cmd_encrypt(args):
274
274
  logger.debug("Creating TDF")
275
275
  config = create_tdf_config(sdk, args)
276
276
  output_stream = BytesIO()
277
- manifest, size, _ = sdk.create_tdf(
277
+ _manifest, size, _ = sdk.create_tdf(
278
278
  BytesIO(payload), config, output_stream
279
279
  )
280
280
  output_file.write(output_stream.getvalue())
@@ -296,13 +296,13 @@ def cmd_decrypt(args):
296
296
 
297
297
  try:
298
298
  # Read encrypted file
299
- with open(input_path, "rb") as input_file:
299
+ with input_path.open("rb") as input_file:
300
300
  encrypted_data = input_file.read()
301
301
 
302
302
  # Determine output
303
303
  if args.output:
304
304
  output_path = Path(args.output)
305
- with open(output_path, "wb") as output_file:
305
+ with output_path.open("wb") as output_file:
306
306
  try:
307
307
  # Try to determine if it's a NanoTDF or regular TDF
308
308
  # NanoTDFs have a specific header format, regular TDFs are ZIP files
@@ -359,7 +359,7 @@ def cmd_inspect(args):
359
359
 
360
360
  try:
361
361
  # Read encrypted file
362
- with open(input_path, "rb") as input_file:
362
+ with input_path.open("rb") as input_file:
363
363
  encrypted_data = input_file.read()
364
364
 
365
365
  if encrypted_data.startswith(b"PK"):
@@ -400,7 +400,7 @@ def cmd_inspect(args):
400
400
  except Exception as e:
401
401
  # If we can't inspect due to auth issues, show what we can
402
402
  logger.warning(f"Limited inspection due to: {e}")
403
- with open(input_path, "rb") as input_file:
403
+ with input_path.open("rb") as input_file:
404
404
  encrypted_data = input_file.read()
405
405
 
406
406
  file_type = "TDF" if encrypted_data.startswith(b"PK") else "NanoTDF"
otdf_python/header.py CHANGED
@@ -51,7 +51,7 @@ class Header:
51
51
  # MAGIC_NUMBER_AND_VERSION (3 bytes)
52
52
  offset += 3
53
53
  # ResourceLocator
54
- kas_locator, kas_size = ResourceLocator.from_bytes_with_size(buffer[offset:])
54
+ _kas_locator, kas_size = ResourceLocator.from_bytes_with_size(buffer[offset:])
55
55
  offset += kas_size
56
56
  # ECC mode (1 byte)
57
57
  ecc_mode = ECCMode(buffer[offset])
@@ -59,7 +59,7 @@ class Header:
59
59
  # Payload config (1 byte)
60
60
  offset += 1
61
61
  # PolicyInfo
62
- policy_info, policy_size = PolicyInfo.from_bytes_with_size(
62
+ _policy_info, policy_size = PolicyInfo.from_bytes_with_size(
63
63
  buffer[offset:], ecc_mode
64
64
  )
65
65
  offset += policy_size
@@ -9,6 +9,8 @@ import urllib3
9
9
  from otdf_python_proto.kas import kas_pb2
10
10
  from otdf_python_proto.kas.kas_pb2_connect import AccessServiceClient
11
11
 
12
+ from otdf_python.auth_headers import AuthHeaders
13
+
12
14
  from .sdk_exceptions import SDKException
13
15
 
14
16
 
@@ -69,7 +71,11 @@ class KASConnectRPCClient:
69
71
  Dictionary with authentication headers or None
70
72
  """
71
73
  if access_token:
72
- return {"Authorization": f"Bearer {access_token}"}
74
+ auth_headers = AuthHeaders(
75
+ auth_header=f"Bearer {access_token}",
76
+ dpop_header="", # Empty for now, ready for future DPoP support
77
+ )
78
+ return auth_headers.to_dict()
73
79
  return None
74
80
 
75
81
  def get_public_key(self, normalized_kas_url, kas_info, access_token=None):
otdf_python/nanotdf.py CHANGED
@@ -300,7 +300,7 @@ class NanoTDF:
300
300
  iv, ciphertext = self._encrypt_payload(payload, key)
301
301
 
302
302
  # Wrap key if needed
303
- wrapped_key, kas_public_key = self._wrap_key_if_needed(key, config)
303
+ wrapped_key, _kas_public_key = self._wrap_key_if_needed(key, config)
304
304
 
305
305
  # Compose the complete NanoTDF: [IV][CIPHERTEXT][WRAPPED_KEY][WRAPPED_KEY_LEN]
306
306
  if wrapped_key:
otdf_python/sdk.py CHANGED
@@ -6,42 +6,12 @@ from contextlib import AbstractContextManager
6
6
  from io import BytesIO
7
7
  from typing import Any, BinaryIO
8
8
 
9
- from otdf_python.config import NanoTDFConfig, TDFConfig
9
+ from otdf_python.config import KASInfo, NanoTDFConfig, TDFConfig
10
10
  from otdf_python.nanotdf import NanoTDF
11
11
  from otdf_python.sdk_exceptions import SDKException
12
12
  from otdf_python.tdf import TDF, TDFReader, TDFReaderConfig
13
13
 
14
14
 
15
- # Stubs for service client interfaces (to be implemented)
16
- class AttributesServiceClientInterface: ...
17
-
18
-
19
- class NamespaceServiceClientInterface: ...
20
-
21
-
22
- class SubjectMappingServiceClientInterface: ...
23
-
24
-
25
- class ResourceMappingServiceClientInterface: ...
26
-
27
-
28
- class AuthorizationServiceClientInterface: ...
29
-
30
-
31
- class KeyAccessServerRegistryServiceClientInterface: ...
32
-
33
-
34
- # Placeholder for ProtocolClient and Interceptor
35
- class ProtocolClient: ...
36
-
37
-
38
- class Interceptor: ... # Can be dict in Python implementation
39
-
40
-
41
- # Placeholder for TrustManager
42
- class TrustManager: ...
43
-
44
-
45
15
  class KAS(AbstractContextManager):
46
16
  """
47
17
  KAS (Key Access Service) interface to define methods related to key access and management.
@@ -71,7 +41,6 @@ class KAS(AbstractContextManager):
71
41
  token_source=None,
72
42
  sdk_ssl_verify=True,
73
43
  use_plaintext=False,
74
- auth_headers: dict | None = None,
75
44
  ):
76
45
  """
77
46
  Initialize the KAS client
@@ -81,7 +50,6 @@ class KAS(AbstractContextManager):
81
50
  token_source: Function that returns an authentication token
82
51
  sdk_ssl_verify: Whether to verify SSL certificates
83
52
  use_plaintext: Whether to use plaintext HTTP connections instead of HTTPS
84
- auth_headers: Dictionary of authentication headers to include in requests
85
53
  """
86
54
  from .kas_client import KASClient
87
55
 
@@ -94,7 +62,6 @@ class KAS(AbstractContextManager):
94
62
  # Store the parameters for potential use
95
63
  self._sdk_ssl_verify = sdk_ssl_verify
96
64
  self._use_plaintext = use_plaintext
97
- self._auth_headers = auth_headers
98
65
 
99
66
  def get_ec_public_key(self, kas_info: Any, curve: Any) -> Any:
100
67
  """
@@ -179,12 +146,14 @@ class KAS(AbstractContextManager):
179
146
 
180
147
  class SDK(AbstractContextManager):
181
148
  def new_tdf_config(
182
- self, attributes: list[str] | None = None, **kwargs
149
+ self,
150
+ attributes: list[str] | None = None,
151
+ kas_info_list: list[KASInfo] | None = None,
152
+ **kwargs,
183
153
  ) -> TDFConfig:
184
154
  """
185
155
  Create a TDFConfig with default kas_info_list from the SDK's platform_url.
186
156
  """
187
- from otdf_python.config import KASInfo
188
157
 
189
158
  if self.platform_url is None:
190
159
  raise SDKException("Cannot create TDFConfig: SDK platform_url is not set.")
@@ -232,10 +201,8 @@ class SDK(AbstractContextManager):
232
201
  # Use existing port with the determined scheme
233
202
  kas_url = f"{scheme}://{parsed_url.hostname}:{parsed_url.port}{parsed_url.path.rstrip('/')}/kas"
234
203
 
235
- kas_info = KASInfo(url=kas_url, default=True)
236
- # Accept user override for kas_info_list if provided
237
- kas_info_list = kwargs.pop("kas_info_list", None)
238
204
  if kas_info_list is None:
205
+ kas_info = KASInfo(url=kas_url, default=True)
239
206
  kas_info_list = [kas_info]
240
207
  return TDFConfig(
241
208
  kas_info_list=kas_info_list, attributes=attributes or [], **kwargs
@@ -251,30 +218,6 @@ class SDK(AbstractContextManager):
251
218
  The Services interface provides access to various platform service clients and KAS.
252
219
  """
253
220
 
254
- def attributes(self) -> AttributesServiceClientInterface:
255
- """Returns the attributes service client"""
256
- raise NotImplementedError
257
-
258
- def namespaces(self) -> NamespaceServiceClientInterface:
259
- """Returns the namespaces service client"""
260
- raise NotImplementedError
261
-
262
- def subject_mappings(self) -> SubjectMappingServiceClientInterface:
263
- """Returns the subject mappings service client"""
264
- raise NotImplementedError
265
-
266
- def resource_mappings(self) -> ResourceMappingServiceClientInterface:
267
- """Returns the resource mappings service client"""
268
- raise NotImplementedError
269
-
270
- def authorization(self) -> AuthorizationServiceClientInterface:
271
- """Returns the authorization service client"""
272
- raise NotImplementedError
273
-
274
- def kas_registry(self) -> KeyAccessServerRegistryServiceClientInterface:
275
- """Returns the KAS registry service client"""
276
- raise NotImplementedError
277
-
278
221
  def kas(self) -> KAS:
279
222
  """
280
223
  Returns the KAS client for key access operations.
@@ -292,9 +235,6 @@ class SDK(AbstractContextManager):
292
235
  def __init__(
293
236
  self,
294
237
  services: "SDK.Services",
295
- trust_manager: TrustManager | None = None,
296
- auth_interceptor: Interceptor | dict[str, str] | None = None,
297
- platform_services_client: ProtocolClient | None = None,
298
238
  platform_url: str | None = None,
299
239
  ssl_verify: bool = True,
300
240
  use_plaintext: bool = False,
@@ -304,17 +244,11 @@ class SDK(AbstractContextManager):
304
244
 
305
245
  Args:
306
246
  services: The services interface implementation
307
- trust_manager: Optional trust manager for SSL validation
308
- auth_interceptor: Optional auth interceptor for API requests
309
- platform_services_client: Optional client for platform services
310
247
  platform_url: Optional platform base URL
311
248
  ssl_verify: Whether to verify SSL certificates (default: True)
312
249
  use_plaintext: Whether to use HTTP instead of HTTPS (default: False)
313
250
  """
314
251
  self.services = services
315
- self.trust_manager = trust_manager
316
- self.auth_interceptor = auth_interceptor
317
- self.platform_services_client = platform_services_client
318
252
  self.platform_url = platform_url
319
253
  self.ssl_verify = ssl_verify
320
254
  self._use_plaintext = use_plaintext
@@ -332,18 +266,6 @@ class SDK(AbstractContextManager):
332
266
  """Returns the services interface"""
333
267
  return self.services
334
268
 
335
- def get_trust_manager(self) -> TrustManager | None:
336
- """Returns the trust manager if set"""
337
- return self.trust_manager
338
-
339
- def get_auth_interceptor(self) -> Interceptor | dict[str, str] | None:
340
- """Returns the auth interceptor if set"""
341
- return self.auth_interceptor
342
-
343
- def get_platform_services_client(self) -> ProtocolClient | None:
344
- """Returns the platform services client if set"""
345
- return self.platform_services_client
346
-
347
269
  def get_platform_url(self) -> str | None:
348
270
  """Returns the platform URL if set"""
349
271
  return self.platform_url
@@ -4,10 +4,9 @@ Provides methods to configure and build SDK instances.
4
4
  """
5
5
 
6
6
  import logging
7
- import os
8
7
  import ssl
9
8
  from dataclasses import dataclass
10
- from typing import Any
9
+ from pathlib import Path
11
10
 
12
11
  import httpx
13
12
 
@@ -77,9 +76,10 @@ class SDKBuilder:
77
76
  self.cert_paths = []
78
77
 
79
78
  # Find all .pem and .crt files in the directory
80
- for filename in os.listdir(certs_dir_path):
81
- if filename.endswith(".pem") or filename.endswith(".crt"):
82
- self.cert_paths.append(os.path.join(certs_dir_path, filename))
79
+ certs_path = Path(certs_dir_path)
80
+ for cert_file in certs_path.iterdir():
81
+ if cert_file.suffix in (".pem", ".crt"):
82
+ self.cert_paths.append(str(cert_file))
83
83
 
84
84
  # Create SSL context with these certificates
85
85
  if self.cert_paths:
@@ -343,32 +343,6 @@ class SDKBuilder:
343
343
  except Exception as e:
344
344
  raise AutoConfigureException(f"Error during token acquisition: {e!s}")
345
345
 
346
- def _create_auth_interceptor(self) -> Any:
347
- """
348
- Creates an authentication interceptor for API requests (httpx).
349
- Returns:
350
- Any: An auth interceptor object
351
- Raises:
352
- AutoConfigureException: If auth configuration fails
353
- """
354
- # For now, this is just a placeholder returning a dict with auth headers
355
- # In a real implementation, this would create a proper interceptor object
356
- # that injects auth headers into httpx requests
357
-
358
- token = None
359
-
360
- if self.auth_token:
361
- # Use provided token
362
- token = self.auth_token
363
- elif self.oauth_config:
364
- # Get token from OAuth
365
- token = self._get_token_from_client_credentials()
366
-
367
- if token:
368
- return {"Authorization": f"Bearer {token}"}
369
-
370
- return None
371
-
372
346
  def _create_services(self) -> SDK.Services:
373
347
  """
374
348
  Creates service client instances.
@@ -382,13 +356,11 @@ class SDKBuilder:
382
356
  # connecting to the platform endpoints
383
357
 
384
358
  ssl_verify = not self.insecure_skip_verify
385
- auth_interceptor = self._create_auth_interceptor()
386
359
 
387
360
  class ServicesImpl(SDK.Services):
388
361
  def __init__(self, builder_instance):
389
362
  self.closed = False
390
363
  self._ssl_verify = ssl_verify
391
- self._auth_headers = auth_interceptor if auth_interceptor else {}
392
364
  self._builder = builder_instance
393
365
 
394
366
  def kas(self) -> KAS:
@@ -432,16 +404,12 @@ class SDKBuilder:
432
404
  if not self.platform_endpoint:
433
405
  raise AutoConfigureException("Platform endpoint is not set")
434
406
 
435
- # Create the auth interceptor
436
- auth_interceptor = self._create_auth_interceptor()
437
-
438
407
  # Create services
439
408
  services = self._create_services()
440
409
 
441
410
  # Return the SDK instance, platform_url is set for new_tdf_config
442
411
  return SDK(
443
412
  services=services,
444
- auth_interceptor=auth_interceptor,
445
413
  platform_url=self.platform_endpoint,
446
414
  ssl_verify=not self.insecure_skip_verify,
447
415
  use_plaintext=getattr(self, "use_plaintext", False),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: otdf-python
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: Unofficial OpenTDF SDK for Python
5
5
  Author-email: b-long <b-long@users.noreply.github.com>
6
6
  License-File: LICENSE
@@ -114,8 +114,6 @@ decrypted_data = tdf_reader.payload
114
114
  with open("decrypted.txt", "wb") as f:
115
115
  f.write(decrypted_data)
116
116
 
117
- # Don't forget to close the SDK when done
118
- sdk.close()
119
117
  ```
120
118
 
121
119
  ## Project Structure
@@ -6,9 +6,9 @@ otdf_python/assertion_config.py,sha256=P2Pc1OxMk9Ln6bvp1ZI8j66Q7uoZoYB7oMB6WLG38
6
6
  otdf_python/asym_crypto.py,sha256=GzijIWYhWeazEwXYw-s8fRHVS7JLxDqHVcl7oRSOx_A,3008
7
7
  otdf_python/asym_decryption.py,sha256=eVfgfzFHMK4ni3g-u8fBe3sdF02eo_msZouo19UBlh4,1981
8
8
  otdf_python/asym_encryption.py,sha256=ex-S_PvBnWKSSvbocTjJ_p5VQjjeiThcc9bMRZqvifw,2932
9
- otdf_python/auth_headers.py,sha256=LFjfWiobNo9DNaPgcm-aJANzHZh7_u9oHTxnEzEq-Ro,562
9
+ otdf_python/auth_headers.py,sha256=a0TQD36QKXO1G4swume2wx3Sk9zQsSWEAQJnST2DlH0,966
10
10
  otdf_python/autoconfigure_utils.py,sha256=NiNtbapBoIO-6kM59HRvX3Kj_Z0IRMrTkFlXjwuNfPc,3236
11
- otdf_python/cli.py,sha256=oRPn002DB7Xvc0y4oPzIFt97OmvMOYHwR6pZXrdwvAo,19463
11
+ otdf_python/cli.py,sha256=XotWLHHEhxwIB9vnwkR2leEV0Q_hhcdceSvcWXyAMrE,19460
12
12
  otdf_python/collection_store.py,sha256=MH1RxlevRVFj5lBS_6DN3zz5ZgOhBjD0P7AYBLBqS0o,1004
13
13
  otdf_python/collection_store_impl.py,sha256=g3YeSwMeXr1BNmwmFr75fv9ptPjieC36Bhct-Jf1trw,613
14
14
  otdf_python/config.py,sha256=uGYVByTWl7pWcKRER41ef-ay5VevIbOyUAEd6BIArVg,2185
@@ -18,16 +18,16 @@ otdf_python/crypto_utils.py,sha256=KsNss9EC-wHs1nCiKivDnxJSMv0uxGlWLDcCowadcV8,2
18
18
  otdf_python/dpop.py,sha256=ssKXTGydJS--rBTCqX9Y8qy-c5Um4pIZPG3DZcj0rWU,2301
19
19
  otdf_python/ecc_mode.py,sha256=PUJJ6n0jk0IKKNVZ1_tWGPPujGR4fny4m5JBkUhPimo,1085
20
20
  otdf_python/eckeypair.py,sha256=4uZfdJaqSxW605FhU58Gko06mixSNoDOGBgVpP5VlSQ,2324
21
- otdf_python/header.py,sha256=YMmsBdiHM8rxLCtezIf_Cnrg2idoGpvq--WMxYqZ-no,5377
21
+ otdf_python/header.py,sha256=QGxqo5yfuJIFrEntLGoETYC8ihc9tszXc2IjtETCVmg,5379
22
22
  otdf_python/invalid_zip_exception.py,sha256=YEU20hM5_yE-RWJncPZobcqj4a90RAuahB54VjAS2SU,213
23
23
  otdf_python/kas_client.py,sha256=vjOP3o7ip2cWqfE4FB1sHWqXWWY-aXPI-PnaKsPPEF4,22464
24
- otdf_python/kas_connect_rpc_client.py,sha256=asxKKSQokUa9kgtU3s3yhKrx3Nug9bK696YFsNjz_vE,7645
24
+ otdf_python/kas_connect_rpc_client.py,sha256=LRhdFF6d8qz_BDFN4WMu0Kn-ZynvKMEWmuHYPj09A6Q,7862
25
25
  otdf_python/kas_info.py,sha256=STnyPo-Vu_rzVQRdQl8mUGPK8eZE2vY4oPkI-PqrZJM,687
26
26
  otdf_python/kas_key_cache.py,sha256=Ems2NyKC_3yh_xs8k4_n2gA3Jb-9nCeRRjIdz1LRC9I,1472
27
27
  otdf_python/key_type.py,sha256=cwhlh6DOFG5C8JlCxFqXYi0SJDlOLUkxceg7L8arFNk,816
28
28
  otdf_python/key_type_constants.py,sha256=ghridYdhFMLKDa_9Q5cplrl8DqdEgApd--20bJ-MBtA,1001
29
29
  otdf_python/manifest.py,sha256=Uv-Hvo9hOPLrSPTeKQpDvNeHzq7qSmJ5HYtkgGwVppE,6419
30
- otdf_python/nanotdf.py,sha256=s7kE5HhHOq1CEZW1gbkKMwMHh6eCNqd2Ln3SZGkfRTA,20213
30
+ otdf_python/nanotdf.py,sha256=zklLXXEbX5uHO11ebnI4pgo_bVp94I2deXKjN0tjExs,20214
31
31
  otdf_python/nanotdf_ecdsa_struct.py,sha256=nRScIJLeNcbxBBE9DlG15I7EXGTkH0ITib1ra-C1-uQ,4100
32
32
  otdf_python/nanotdf_type.py,sha256=40PyDd62iDwcfmS7rhUeQE2B0W6FYIeCpi5cDmMO7d4,819
33
33
  otdf_python/policy_binding_serializer.py,sha256=8d9MizhLTdy14ghdAvhXRBA8KzKt6Nf9kmmU9hoWhrQ,1169
@@ -35,8 +35,8 @@ otdf_python/policy_info.py,sha256=n9hgdQrTRqPO7O1R90EUtIyoWNlaABAF7mRfbjIzaX8,28
35
35
  otdf_python/policy_object.py,sha256=zzwHk6jhZwpiX2BWxTJ1kDl3cgFijQfQrKJP3OqI35Q,380
36
36
  otdf_python/policy_stub.py,sha256=BQn06Ye5MwCu9feJZFPmO_UTfhugtiQa539iBkSQwhQ,117
37
37
  otdf_python/resource_locator.py,sha256=zYN5yd9cGwN9SRQO2tUD1UXj2zkPl2apd-X4E1MrnDg,1879
38
- otdf_python/sdk.py,sha256=-JNrbk7Nr3IKsTX9BZp2OxPlCilaSbA8FmP7Zn_GWsU,17082
39
- otdf_python/sdk_builder.py,sha256=QEu9y5I8xLPBuR8O2AG7AWInqO7g4Q5-WGW0sIVsOmQ,15803
38
+ otdf_python/sdk.py,sha256=rihHwRwMzS1xu6eiJZ79Y2biDwPEZvqiQoFw97ma9-Q,14211
39
+ otdf_python/sdk_builder.py,sha256=jgswTxnAfKXDGqEOIQwEiE3S0Jh0w5HMtPxHwUFIu-U,14655
40
40
  otdf_python/sdk_exceptions.py,sha256=L_bYkkyF-hnEBFXfjT5C41i5lM-t8OJB5mU_1zYvfP8,479
41
41
  otdf_python/symmetric_and_payload_config.py,sha256=D_LArhk1gA5-tpUiaUZTTM90ZKdc3DCq1a6X8etCir8,992
42
42
  otdf_python/tdf.py,sha256=T4Wr7cc-QcQ607F4RfqWieTpQdaeOndGnLqx4Di9B_M,19648
@@ -131,7 +131,7 @@ otdf_python_proto/wellknownconfiguration/__init__.py,sha256=X3GeZJ1mG_N1MViryjkq
131
131
  otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2.py,sha256=g9xSm9TxX0IPMqiFCaridJvI2TrL8PrXVFPgu8tX9VM,3863
132
132
  otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2.pyi,sha256=Zw4vROvTgomnFqsalJrYda632ojXH0FVXSzTXxerybw,1490
133
133
  otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2_connect.py,sha256=i9rGG2mgQZfk6xGCp1ywu4QqKWSiwpuLoNKGUwl43t8,5346
134
- otdf_python-0.3.3.dist-info/METADATA,sha256=8NI8cmpOqLFh4QjizWUXIHiCCiWN5D1k11MhekFzAKQ,4279
135
- otdf_python-0.3.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
136
- otdf_python-0.3.3.dist-info/licenses/LICENSE,sha256=DPrPHdI6tfZcqk9kzQ37vh1Ftk7LJYdMrUtwKl7L3Pw,1074
137
- otdf_python-0.3.3.dist-info/RECORD,,
134
+ otdf_python-0.3.4.dist-info/METADATA,sha256=3mt22hjKkKrXHv1GFyqQUO1JQTKdvDe4CsazN6x5pYY,4225
135
+ otdf_python-0.3.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
136
+ otdf_python-0.3.4.dist-info/licenses/LICENSE,sha256=DPrPHdI6tfZcqk9kzQ37vh1Ftk7LJYdMrUtwKl7L3Pw,1074
137
+ otdf_python-0.3.4.dist-info/RECORD,,