otdf-python 0.1.9__py3-none-any.whl → 0.3.1__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 (144) hide show
  1. otdf_python/__init__.py +25 -0
  2. otdf_python/__main__.py +12 -0
  3. otdf_python/address_normalizer.py +84 -0
  4. otdf_python/aesgcm.py +55 -0
  5. otdf_python/assertion_config.py +84 -0
  6. otdf_python/asym_crypto.py +85 -0
  7. otdf_python/asym_decryption.py +53 -0
  8. otdf_python/asym_encryption.py +75 -0
  9. otdf_python/auth_headers.py +21 -0
  10. otdf_python/autoconfigure_utils.py +113 -0
  11. otdf_python/cli.py +570 -0
  12. otdf_python/collection_store.py +41 -0
  13. otdf_python/collection_store_impl.py +22 -0
  14. otdf_python/config.py +69 -0
  15. otdf_python/connect_client.py +0 -0
  16. otdf_python/constants.py +1 -0
  17. otdf_python/crypto_utils.py +78 -0
  18. otdf_python/dpop.py +81 -0
  19. otdf_python/ecc_mode.py +32 -0
  20. otdf_python/eckeypair.py +75 -0
  21. otdf_python/header.py +143 -0
  22. otdf_python/invalid_zip_exception.py +8 -0
  23. otdf_python/kas_client.py +603 -0
  24. otdf_python/kas_connect_rpc_client.py +207 -0
  25. otdf_python/kas_info.py +25 -0
  26. otdf_python/kas_key_cache.py +52 -0
  27. otdf_python/key_type.py +31 -0
  28. otdf_python/key_type_constants.py +43 -0
  29. otdf_python/manifest.py +215 -0
  30. otdf_python/nanotdf.py +553 -0
  31. otdf_python/nanotdf_ecdsa_struct.py +132 -0
  32. otdf_python/nanotdf_type.py +43 -0
  33. otdf_python/policy_binding_serializer.py +39 -0
  34. otdf_python/policy_info.py +78 -0
  35. otdf_python/policy_object.py +22 -0
  36. otdf_python/policy_stub.py +2 -0
  37. otdf_python/resource_locator.py +44 -0
  38. otdf_python/sdk.py +528 -0
  39. otdf_python/sdk_builder.py +448 -0
  40. otdf_python/sdk_exceptions.py +16 -0
  41. otdf_python/symmetric_and_payload_config.py +30 -0
  42. otdf_python/tdf.py +479 -0
  43. otdf_python/tdf_reader.py +153 -0
  44. otdf_python/tdf_writer.py +23 -0
  45. otdf_python/token_source.py +34 -0
  46. otdf_python/version.py +57 -0
  47. otdf_python/zip_reader.py +47 -0
  48. otdf_python/zip_writer.py +70 -0
  49. otdf_python-0.3.1.dist-info/METADATA +231 -0
  50. otdf_python-0.3.1.dist-info/RECORD +137 -0
  51. {otdf_python-0.1.9.dist-info → otdf_python-0.3.1.dist-info}/WHEEL +1 -2
  52. {otdf_python-0.1.9.dist-info → otdf_python-0.3.1.dist-info/licenses}/LICENSE +1 -1
  53. otdf_python_proto/__init__.py +37 -0
  54. otdf_python_proto/authorization/__init__.py +1 -0
  55. otdf_python_proto/authorization/authorization_pb2.py +80 -0
  56. otdf_python_proto/authorization/authorization_pb2.pyi +161 -0
  57. otdf_python_proto/authorization/authorization_pb2_connect.py +191 -0
  58. otdf_python_proto/authorization/v2/authorization_pb2.py +105 -0
  59. otdf_python_proto/authorization/v2/authorization_pb2.pyi +134 -0
  60. otdf_python_proto/authorization/v2/authorization_pb2_connect.py +233 -0
  61. otdf_python_proto/common/__init__.py +1 -0
  62. otdf_python_proto/common/common_pb2.py +52 -0
  63. otdf_python_proto/common/common_pb2.pyi +61 -0
  64. otdf_python_proto/entity/__init__.py +1 -0
  65. otdf_python_proto/entity/entity_pb2.py +47 -0
  66. otdf_python_proto/entity/entity_pb2.pyi +50 -0
  67. otdf_python_proto/entityresolution/__init__.py +1 -0
  68. otdf_python_proto/entityresolution/entity_resolution_pb2.py +57 -0
  69. otdf_python_proto/entityresolution/entity_resolution_pb2.pyi +55 -0
  70. otdf_python_proto/entityresolution/entity_resolution_pb2_connect.py +149 -0
  71. otdf_python_proto/entityresolution/v2/entity_resolution_pb2.py +55 -0
  72. otdf_python_proto/entityresolution/v2/entity_resolution_pb2.pyi +55 -0
  73. otdf_python_proto/entityresolution/v2/entity_resolution_pb2_connect.py +149 -0
  74. otdf_python_proto/kas/__init__.py +9 -0
  75. otdf_python_proto/kas/kas_pb2.py +103 -0
  76. otdf_python_proto/kas/kas_pb2.pyi +170 -0
  77. otdf_python_proto/kas/kas_pb2_connect.py +192 -0
  78. otdf_python_proto/legacy_grpc/__init__.py +1 -0
  79. otdf_python_proto/legacy_grpc/authorization/authorization_pb2_grpc.py +163 -0
  80. otdf_python_proto/legacy_grpc/authorization/v2/authorization_pb2_grpc.py +206 -0
  81. otdf_python_proto/legacy_grpc/common/common_pb2_grpc.py +4 -0
  82. otdf_python_proto/legacy_grpc/entity/entity_pb2_grpc.py +4 -0
  83. otdf_python_proto/legacy_grpc/entityresolution/entity_resolution_pb2_grpc.py +122 -0
  84. otdf_python_proto/legacy_grpc/entityresolution/v2/entity_resolution_pb2_grpc.py +120 -0
  85. otdf_python_proto/legacy_grpc/kas/kas_pb2_grpc.py +172 -0
  86. otdf_python_proto/legacy_grpc/logger/audit/test_pb2_grpc.py +4 -0
  87. otdf_python_proto/legacy_grpc/policy/actions/actions_pb2_grpc.py +249 -0
  88. otdf_python_proto/legacy_grpc/policy/attributes/attributes_pb2_grpc.py +873 -0
  89. otdf_python_proto/legacy_grpc/policy/kasregistry/key_access_server_registry_pb2_grpc.py +602 -0
  90. otdf_python_proto/legacy_grpc/policy/keymanagement/key_management_pb2_grpc.py +251 -0
  91. otdf_python_proto/legacy_grpc/policy/namespaces/namespaces_pb2_grpc.py +427 -0
  92. otdf_python_proto/legacy_grpc/policy/objects_pb2_grpc.py +4 -0
  93. otdf_python_proto/legacy_grpc/policy/registeredresources/registered_resources_pb2_grpc.py +524 -0
  94. otdf_python_proto/legacy_grpc/policy/resourcemapping/resource_mapping_pb2_grpc.py +516 -0
  95. otdf_python_proto/legacy_grpc/policy/selectors_pb2_grpc.py +4 -0
  96. otdf_python_proto/legacy_grpc/policy/subjectmapping/subject_mapping_pb2_grpc.py +551 -0
  97. otdf_python_proto/legacy_grpc/policy/unsafe/unsafe_pb2_grpc.py +485 -0
  98. otdf_python_proto/legacy_grpc/wellknownconfiguration/wellknown_configuration_pb2_grpc.py +77 -0
  99. otdf_python_proto/logger/__init__.py +1 -0
  100. otdf_python_proto/logger/audit/test_pb2.py +43 -0
  101. otdf_python_proto/logger/audit/test_pb2.pyi +45 -0
  102. otdf_python_proto/policy/__init__.py +1 -0
  103. otdf_python_proto/policy/actions/actions_pb2.py +75 -0
  104. otdf_python_proto/policy/actions/actions_pb2.pyi +87 -0
  105. otdf_python_proto/policy/actions/actions_pb2_connect.py +275 -0
  106. otdf_python_proto/policy/attributes/attributes_pb2.py +234 -0
  107. otdf_python_proto/policy/attributes/attributes_pb2.pyi +328 -0
  108. otdf_python_proto/policy/attributes/attributes_pb2_connect.py +863 -0
  109. otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2.py +266 -0
  110. otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2.pyi +450 -0
  111. otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2_connect.py +611 -0
  112. otdf_python_proto/policy/keymanagement/key_management_pb2.py +79 -0
  113. otdf_python_proto/policy/keymanagement/key_management_pb2.pyi +87 -0
  114. otdf_python_proto/policy/keymanagement/key_management_pb2_connect.py +275 -0
  115. otdf_python_proto/policy/namespaces/namespaces_pb2.py +117 -0
  116. otdf_python_proto/policy/namespaces/namespaces_pb2.pyi +147 -0
  117. otdf_python_proto/policy/namespaces/namespaces_pb2_connect.py +443 -0
  118. otdf_python_proto/policy/objects_pb2.py +150 -0
  119. otdf_python_proto/policy/objects_pb2.pyi +464 -0
  120. otdf_python_proto/policy/registeredresources/registered_resources_pb2.py +139 -0
  121. otdf_python_proto/policy/registeredresources/registered_resources_pb2.pyi +196 -0
  122. otdf_python_proto/policy/registeredresources/registered_resources_pb2_connect.py +527 -0
  123. otdf_python_proto/policy/resourcemapping/resource_mapping_pb2.py +139 -0
  124. otdf_python_proto/policy/resourcemapping/resource_mapping_pb2.pyi +194 -0
  125. otdf_python_proto/policy/resourcemapping/resource_mapping_pb2_connect.py +527 -0
  126. otdf_python_proto/policy/selectors_pb2.py +57 -0
  127. otdf_python_proto/policy/selectors_pb2.pyi +90 -0
  128. otdf_python_proto/policy/subjectmapping/subject_mapping_pb2.py +127 -0
  129. otdf_python_proto/policy/subjectmapping/subject_mapping_pb2.pyi +189 -0
  130. otdf_python_proto/policy/subjectmapping/subject_mapping_pb2_connect.py +569 -0
  131. otdf_python_proto/policy/unsafe/unsafe_pb2.py +113 -0
  132. otdf_python_proto/policy/unsafe/unsafe_pb2.pyi +145 -0
  133. otdf_python_proto/policy/unsafe/unsafe_pb2_connect.py +485 -0
  134. otdf_python_proto/wellknownconfiguration/__init__.py +1 -0
  135. otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2.py +51 -0
  136. otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2.pyi +32 -0
  137. otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2_connect.py +107 -0
  138. otdf_python/_gotdf_python.cpython-312-darwin.so +0 -0
  139. otdf_python/build.py +0 -190
  140. otdf_python/go.py +0 -1478
  141. otdf_python/gotdf_python.py +0 -383
  142. otdf_python-0.1.9.dist-info/METADATA +0 -149
  143. otdf_python-0.1.9.dist-info/RECORD +0 -10
  144. otdf_python-0.1.9.dist-info/top_level.txt +0 -1
otdf_python/version.py ADDED
@@ -0,0 +1,57 @@
1
+ import re
2
+ from functools import total_ordering
3
+
4
+
5
+ @total_ordering
6
+ class Version:
7
+ SEMVER_PATTERN = re.compile(
8
+ r"^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?P<prereleaseAndMetadata>\D.*)?$"
9
+ )
10
+
11
+ def __init__(
12
+ self,
13
+ semver_or_major,
14
+ minor=None,
15
+ patch=None,
16
+ prerelease_and_metadata: str | None = None,
17
+ ):
18
+ if minor is None and patch is None:
19
+ # Parse from string
20
+ m = self.SEMVER_PATTERN.match(semver_or_major)
21
+ if not m:
22
+ raise ValueError(f"Invalid version format: {semver_or_major}")
23
+ self.major = int(m.group("major"))
24
+ self.minor = int(m.group("minor"))
25
+ self.patch = int(m.group("patch"))
26
+ self.prerelease_and_metadata = m.group("prereleaseAndMetadata")
27
+ else:
28
+ self.major = int(semver_or_major)
29
+ self.minor = int(minor)
30
+ self.patch = int(patch)
31
+ self.prerelease_and_metadata = prerelease_and_metadata
32
+
33
+ def __str__(self):
34
+ return f"Version{{major={self.major}, minor={self.minor}, patch={self.patch}, prereleaseAndMetadata='{self.prerelease_and_metadata}'}}"
35
+
36
+ def __eq__(self, other):
37
+ if not isinstance(other, Version):
38
+ return False
39
+ return (self.major, self.minor, self.patch) == (
40
+ other.major,
41
+ other.minor,
42
+ other.patch,
43
+ )
44
+
45
+ def __lt__(self, other):
46
+ if not isinstance(other, Version):
47
+ return NotImplemented
48
+ if self.major != other.major:
49
+ return self.major < other.major
50
+ if self.minor != other.minor:
51
+ return self.minor < other.minor
52
+ if self.patch != other.patch:
53
+ return self.patch < other.patch
54
+ return False
55
+
56
+ def __hash__(self):
57
+ return hash((self.major, self.minor, self.patch))
@@ -0,0 +1,47 @@
1
+ import io
2
+ import zipfile
3
+
4
+ from otdf_python.invalid_zip_exception import InvalidZipException
5
+
6
+
7
+ class ZipReader:
8
+ class Entry:
9
+ def __init__(self, zipfile_obj, zipinfo):
10
+ self._zipfile = zipfile_obj
11
+ self._zipinfo = zipinfo
12
+
13
+ def get_name(self) -> str:
14
+ return self._zipinfo.filename
15
+
16
+ def get_data(self) -> bytes:
17
+ try:
18
+ return self._zipfile.read(self._zipinfo)
19
+ except Exception as e:
20
+ raise InvalidZipException(f"Error reading entry data: {e}")
21
+
22
+ def __init__(self, in_stream: io.BytesIO | bytes | None = None):
23
+ try:
24
+ if isinstance(in_stream, bytes):
25
+ in_stream = io.BytesIO(in_stream)
26
+ self.in_stream = in_stream or io.BytesIO()
27
+ self.zipfile = zipfile.ZipFile(self.in_stream, mode="r")
28
+ self.entries = [
29
+ self.Entry(self.zipfile, zi) for zi in self.zipfile.infolist()
30
+ ]
31
+ except zipfile.BadZipFile as e:
32
+ raise InvalidZipException(f"Invalid ZIP file: {e}")
33
+
34
+ def get_entries(self) -> list:
35
+ return self.entries
36
+
37
+ def namelist(self) -> list[str]:
38
+ return self.zipfile.namelist()
39
+
40
+ def extract(self, name: str, path: str | None = None) -> str:
41
+ return self.zipfile.extract(name, path)
42
+
43
+ def read(self, name: str) -> bytes:
44
+ return self.zipfile.read(name)
45
+
46
+ def close(self):
47
+ self.zipfile.close()
@@ -0,0 +1,70 @@
1
+ import io
2
+ import zipfile
3
+ import zlib
4
+
5
+
6
+ class FileInfo:
7
+ def __init__(self, name: str, crc: int, size: int, offset: int):
8
+ self.name = name
9
+ self.crc = crc
10
+ self.size = size
11
+ self.offset = offset
12
+
13
+
14
+ class ZipWriter:
15
+ def __init__(self, out_stream: io.BytesIO | None = None):
16
+ self.out_stream = out_stream or io.BytesIO()
17
+ self.zipfile = zipfile.ZipFile(
18
+ self.out_stream, mode="w", compression=zipfile.ZIP_STORED
19
+ )
20
+ self._file_infos: list[FileInfo] = []
21
+ self._offsets: dict[str, int] = {}
22
+
23
+ def stream(self, name: str):
24
+ # Returns a writable file-like object for the given name, tracks offset
25
+ offset = self.out_stream.tell()
26
+ self._offsets[name] = offset
27
+ return _TrackingWriter(self, name, offset)
28
+
29
+ def data(self, name: str, content: bytes):
30
+ offset = self.out_stream.tell()
31
+ crc = zlib.crc32(content)
32
+ self.zipfile.writestr(name, content)
33
+ self._file_infos.append(FileInfo(name, crc, len(content), offset))
34
+
35
+ def finish(self) -> int:
36
+ self.zipfile.close()
37
+ return self.out_stream.tell()
38
+
39
+ def getvalue(self) -> bytes:
40
+ self.zipfile.close()
41
+ return self.out_stream.getvalue()
42
+
43
+ def get_file_infos(self) -> list[FileInfo]:
44
+ return self._file_infos
45
+
46
+
47
+ class _TrackingWriter(io.RawIOBase):
48
+ def __init__(self, zip_writer: ZipWriter, name: str, offset: int):
49
+ self._zip_writer = zip_writer
50
+ self._name = name
51
+ self._offset = offset
52
+ self._buffer = io.BytesIO()
53
+ self._closed = False
54
+
55
+ def write(self, b):
56
+ return self._buffer.write(b)
57
+
58
+ def close(self):
59
+ if not self._closed:
60
+ data = self._buffer.getvalue()
61
+ crc = zlib.crc32(data)
62
+ self._zip_writer.zipfile.writestr(self._name, data)
63
+ self._zip_writer._file_infos.append(
64
+ FileInfo(self._name, crc, len(data), self._offset)
65
+ )
66
+ self._closed = True
67
+ super().close()
68
+
69
+ def writable(self):
70
+ return True
@@ -0,0 +1,231 @@
1
+ Metadata-Version: 2.4
2
+ Name: otdf-python
3
+ Version: 0.3.1
4
+ Summary: Unofficial OpenTDF SDK for Python
5
+ Author-email: b-long <b-long@users.noreply.github.com>
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.10
8
+ Requires-Dist: connect-python[compiler]>=0.4.2
9
+ Requires-Dist: cryptography>=45.0.4
10
+ Requires-Dist: grpcio-status>=1.74.0
11
+ Requires-Dist: grpcio-tools>=1.74.0
12
+ Requires-Dist: grpcio>=1.74.0
13
+ Requires-Dist: httpx>=0.28.1
14
+ Requires-Dist: protobuf>=6.31.1
15
+ Requires-Dist: protoc-gen-openapiv2>=0.0.1
16
+ Requires-Dist: pyjwt>=2.10.1
17
+ Requires-Dist: typing-extensions>=4.14.1
18
+ Description-Content-Type: text/markdown
19
+
20
+ # OpenTDF Python SDK
21
+
22
+ Unofficial OpenTDF SDK for Python
23
+
24
+
25
+ ## Features
26
+
27
+ - **TDF Encryption/Decryption**: Create and decrypt TDF files with policy-based access control
28
+ - **Flexible Configuration**: Support for various authentication methods and platform endpoints
29
+ - **Comprehensive Testing**: Full test suite with unit and integration tests
30
+
31
+ ## Legacy Version
32
+
33
+ A legacy version (0.2.x) of this project is available for users who need the previous implementation. For more information, see [LEGACY_VERSION.md](docs/LEGACY_VERSION.md) or visit the [legacy branch on GitHub](https://github.com/b-long/opentdf-python-sdk/tree/0.2.x).
34
+
35
+ ## Prerequisites
36
+
37
+ This project uses [uv](https://docs.astral.sh/uv/) for dependency management and task running.
38
+
39
+ ### Installing uv
40
+
41
+ Install `uv` using one of the following methods:
42
+
43
+ **macOS/Linux:**
44
+ ```bash
45
+ curl -LsSf https://astral.sh/uv/install.sh | sh
46
+ ```
47
+
48
+ **Windows:**
49
+ ```powershell
50
+ powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
51
+ ```
52
+
53
+ **Using Homebrew (macOS):**
54
+ ```bash
55
+ brew install uv
56
+ ```
57
+
58
+ For more installation options, see the [uv installation guide](https://docs.astral.sh/uv/getting-started/installation/).
59
+
60
+ ## Development Setup
61
+
62
+ 1. Clone the repository:
63
+ ```bash
64
+ git clone <repository-url>
65
+ cd opentdf-python-sdk
66
+ ```
67
+
68
+ 2. Install dependencies:
69
+ ```bash
70
+ uv sync
71
+ ```
72
+
73
+ ## Running Tests
74
+
75
+ Run the full test suite:
76
+ ```bash
77
+ uv run pytest tests/
78
+ ```
79
+
80
+ Run specific test files:
81
+ ```bash
82
+ uv run pytest tests/test_sdk.py
83
+ ```
84
+
85
+ Run tests with verbose output:
86
+ ```bash
87
+ uv run pytest tests/ -v
88
+ ```
89
+
90
+ Run integration tests only:
91
+ ```bash
92
+ uv run pytest tests/ -m integration
93
+ ```
94
+
95
+ ## Installation
96
+
97
+ Install from PyPI:
98
+ ```bash
99
+ pip install otdf-python
100
+ ```
101
+
102
+
103
+ ## Protobuf & Connect RPC Generation
104
+
105
+ This project uses a dedicated submodule, `otdf-python-proto/`, for generating Python protobuf files and Connect RPC clients from OpenTDF platform proto definitions.
106
+
107
+ ### Regenerating Protobuf & Connect RPC Files
108
+
109
+ From the submodule:
110
+ ```bash
111
+ cd otdf-python-proto
112
+ uv run python scripts/generate_connect_proto.py
113
+ ```
114
+
115
+ See [`otdf-python-proto/README.md`](otdf-python-proto/README.md) and [`PROTOBUF_SETUP.md`](PROTOBUF_SETUP.md) for details.
116
+
117
+ ## Quick Start
118
+
119
+ ### Basic Configuration
120
+
121
+ ```python
122
+ from otdf_python.sdk_builder import SDKBuilder
123
+
124
+ # Create and configure SDK using builder pattern
125
+ builder = SDKBuilder()
126
+ builder.set_platform_endpoint("https://platform.example.com")
127
+ builder.client_secret("your-client-id", "your-client-secret")
128
+
129
+ # Build the SDK instance
130
+ sdk = builder.build()
131
+ ```
132
+
133
+ ### Advanced Configuration
134
+
135
+ ```python
136
+ from otdf_python.sdk_builder import SDKBuilder
137
+
138
+ # Create SDK with additional configuration options
139
+ builder = SDKBuilder()
140
+ builder.set_platform_endpoint("https://platform.example.com")
141
+ builder.set_issuer_endpoint("https://auth.example.com")
142
+ builder.client_secret("your-client-id", "your-client-secret")
143
+
144
+ # Examples, for local development
145
+
146
+ # Use HTTP instead of HTTPS
147
+ builder.use_insecure_plaintext_connection(True)
148
+
149
+ # Or
150
+ # Skip TLS verification
151
+ builder.use_insecure_skip_verify(True)
152
+
153
+ # Build the SDK instance
154
+ sdk = builder.build()
155
+ ```
156
+
157
+ ### Encrypt Data
158
+
159
+ ```python
160
+ from io import BytesIO
161
+
162
+ # Create TDF configuration with attributes
163
+ config = sdk.new_tdf_config(attributes=["https://example.com/attr/classification/value/public"])
164
+
165
+ # Encrypt data to TDF format
166
+ input_data = b"Hello, World!"
167
+ output_stream = BytesIO()
168
+ manifest, size, _ = sdk.create_tdf(BytesIO(input_data), config, output_stream)
169
+ encrypted_data = output_stream.getvalue()
170
+
171
+ # Save encrypted data to file
172
+ with open("encrypted.tdf", "wb") as f:
173
+ f.write(encrypted_data)
174
+ ```
175
+
176
+ ### Decrypt Data
177
+
178
+ ```python
179
+ from otdf_python.tdf import TDFReaderConfig
180
+
181
+ # Read encrypted TDF file
182
+ with open("encrypted.tdf", "rb") as f:
183
+ encrypted_data = f.read()
184
+
185
+ # Decrypt TDF
186
+ reader_config = TDFReaderConfig()
187
+ tdf_reader = sdk.load_tdf(encrypted_data, reader_config)
188
+ decrypted_data = tdf_reader.payload
189
+
190
+ # Save decrypted data
191
+ with open("decrypted.txt", "wb") as f:
192
+ f.write(decrypted_data)
193
+
194
+ # Don't forget to close the SDK when done
195
+ sdk.close()
196
+ ```
197
+
198
+ ## Project Structure
199
+
200
+ ```
201
+ src/otdf_python/
202
+ ├── sdk.py # Main SDK interface
203
+ ├── config.py # Configuration management
204
+ ├── tdf.py # TDF format handling
205
+ ├── nanotdf.py # NanoTDF format handling
206
+ ├── crypto_utils.py # Cryptographic utilities
207
+ ├── kas_client.py # Key Access Service client
208
+ └── ... # Additional modules
209
+ tests/
210
+ └── ... # Various tests
211
+
212
+ ## Contributing
213
+
214
+ 1. Fork the repository
215
+ 2. Create a feature branch: `git checkout -b feature-name`
216
+ 3. Make your changes
217
+ 4. Run tests: `uv run pytest tests/`
218
+ 5. Commit your changes: `git commit -am 'Add feature'`
219
+ 6. Push to the branch: `git push origin feature-name`
220
+ 7. Submit a pull request
221
+
222
+ ### Release Process
223
+
224
+ For maintainers and contributors working on releases:
225
+ - See [RELEASES.md](RELEASES.md) for comprehensive release documentation
226
+ - Feature branch alpha releases available for testing changes before merge
227
+ - Automated releases via Release Please on the main branch
228
+
229
+ ## License
230
+
231
+ This project is licensed under the MIT License - see the LICENSE file for details.
@@ -0,0 +1,137 @@
1
+ otdf_python/__init__.py,sha256=oTB1bue61KAwDNJ1ITtvIv7YqF3fgXtpha1WztQnvHE,542
2
+ otdf_python/__main__.py,sha256=V9cmvhX9Ht2wpPOHGrw_onBogStJnuWTx9eyiezEDsQ,276
3
+ otdf_python/address_normalizer.py,sha256=pv7RoG4Dwac6so7NK1zCsVZBNFCcQK3cj_4iW6FPnRw,2815
4
+ otdf_python/aesgcm.py,sha256=KhMabIUYxxp1gUwdwNLiwD-SvmJPqW2PunbgeguMEh8,1666
5
+ otdf_python/assertion_config.py,sha256=P2Pc1OxMk9Ln6bvp1ZI8j66Q7uoZoYB7oMB6WLG38Y8,1763
6
+ otdf_python/asym_crypto.py,sha256=GzijIWYhWeazEwXYw-s8fRHVS7JLxDqHVcl7oRSOx_A,3008
7
+ otdf_python/asym_decryption.py,sha256=eVfgfzFHMK4ni3g-u8fBe3sdF02eo_msZouo19UBlh4,1981
8
+ otdf_python/asym_encryption.py,sha256=ex-S_PvBnWKSSvbocTjJ_p5VQjjeiThcc9bMRZqvifw,2932
9
+ otdf_python/auth_headers.py,sha256=LFjfWiobNo9DNaPgcm-aJANzHZh7_u9oHTxnEzEq-Ro,562
10
+ otdf_python/autoconfigure_utils.py,sha256=NiNtbapBoIO-6kM59HRvX3Kj_Z0IRMrTkFlXjwuNfPc,3236
11
+ otdf_python/cli.py,sha256=GoDmar7E4TG_kMTTa121TFL2aQGksrF_rQ4j9dPhuxQ,19838
12
+ otdf_python/collection_store.py,sha256=MH1RxlevRVFj5lBS_6DN3zz5ZgOhBjD0P7AYBLBqS0o,1004
13
+ otdf_python/collection_store_impl.py,sha256=g3YeSwMeXr1BNmwmFr75fv9ptPjieC36Bhct-Jf1trw,613
14
+ otdf_python/config.py,sha256=uGYVByTWl7pWcKRER41ef-ay5VevIbOyUAEd6BIArVg,2185
15
+ otdf_python/connect_client.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ otdf_python/constants.py,sha256=SFGjrzB1GK4CkSZgNlEUIAZMY37MelTxgc8ajXIAhoc,53
17
+ otdf_python/crypto_utils.py,sha256=KsNss9EC-wHs1nCiKivDnxJSMv0uxGlWLDcCowadcV8,2837
18
+ otdf_python/dpop.py,sha256=ssKXTGydJS--rBTCqX9Y8qy-c5Um4pIZPG3DZcj0rWU,2301
19
+ otdf_python/ecc_mode.py,sha256=PUJJ6n0jk0IKKNVZ1_tWGPPujGR4fny4m5JBkUhPimo,1085
20
+ otdf_python/eckeypair.py,sha256=4uZfdJaqSxW605FhU58Gko06mixSNoDOGBgVpP5VlSQ,2324
21
+ otdf_python/header.py,sha256=YMmsBdiHM8rxLCtezIf_Cnrg2idoGpvq--WMxYqZ-no,5377
22
+ otdf_python/invalid_zip_exception.py,sha256=YEU20hM5_yE-RWJncPZobcqj4a90RAuahB54VjAS2SU,213
23
+ otdf_python/kas_client.py,sha256=vjOP3o7ip2cWqfE4FB1sHWqXWWY-aXPI-PnaKsPPEF4,22464
24
+ otdf_python/kas_connect_rpc_client.py,sha256=asxKKSQokUa9kgtU3s3yhKrx3Nug9bK696YFsNjz_vE,7645
25
+ otdf_python/kas_info.py,sha256=STnyPo-Vu_rzVQRdQl8mUGPK8eZE2vY4oPkI-PqrZJM,687
26
+ otdf_python/kas_key_cache.py,sha256=Ems2NyKC_3yh_xs8k4_n2gA3Jb-9nCeRRjIdz1LRC9I,1472
27
+ otdf_python/key_type.py,sha256=cwhlh6DOFG5C8JlCxFqXYi0SJDlOLUkxceg7L8arFNk,816
28
+ otdf_python/key_type_constants.py,sha256=ghridYdhFMLKDa_9Q5cplrl8DqdEgApd--20bJ-MBtA,1001
29
+ otdf_python/manifest.py,sha256=Uv-Hvo9hOPLrSPTeKQpDvNeHzq7qSmJ5HYtkgGwVppE,6419
30
+ otdf_python/nanotdf.py,sha256=s7kE5HhHOq1CEZW1gbkKMwMHh6eCNqd2Ln3SZGkfRTA,20213
31
+ otdf_python/nanotdf_ecdsa_struct.py,sha256=nRScIJLeNcbxBBE9DlG15I7EXGTkH0ITib1ra-C1-uQ,4100
32
+ otdf_python/nanotdf_type.py,sha256=40PyDd62iDwcfmS7rhUeQE2B0W6FYIeCpi5cDmMO7d4,819
33
+ otdf_python/policy_binding_serializer.py,sha256=8d9MizhLTdy14ghdAvhXRBA8KzKt6Nf9kmmU9hoWhrQ,1169
34
+ otdf_python/policy_info.py,sha256=n9hgdQrTRqPO7O1R90EUtIyoWNlaABAF7mRfbjIzaX8,2861
35
+ otdf_python/policy_object.py,sha256=zzwHk6jhZwpiX2BWxTJ1kDl3cgFijQfQrKJP3OqI35Q,380
36
+ otdf_python/policy_stub.py,sha256=BQn06Ye5MwCu9feJZFPmO_UTfhugtiQa539iBkSQwhQ,117
37
+ otdf_python/resource_locator.py,sha256=zYN5yd9cGwN9SRQO2tUD1UXj2zkPl2apd-X4E1MrnDg,1879
38
+ otdf_python/sdk.py,sha256=u-mYUv615AMxlh3yGaMADAwqmS2uEsIDBkZ9jUzmutI,17507
39
+ otdf_python/sdk_builder.py,sha256=QEu9y5I8xLPBuR8O2AG7AWInqO7g4Q5-WGW0sIVsOmQ,15803
40
+ otdf_python/sdk_exceptions.py,sha256=L_bYkkyF-hnEBFXfjT5C41i5lM-t8OJB5mU_1zYvfP8,479
41
+ otdf_python/symmetric_and_payload_config.py,sha256=D_LArhk1gA5-tpUiaUZTTM90ZKdc3DCq1a6X8etCir8,992
42
+ otdf_python/tdf.py,sha256=T4Wr7cc-QcQ607F4RfqWieTpQdaeOndGnLqx4Di9B_M,19648
43
+ otdf_python/tdf_reader.py,sha256=XQ3CuIXSOVRuBMYv2YIYlyaY-tHQA85HHHqNBoXNH9o,5267
44
+ otdf_python/tdf_writer.py,sha256=DVEGEl8pyBm1JK2K-9BJKmT2TqvQXokPkthAQMwgCkk,645
45
+ otdf_python/token_source.py,sha256=tfHWcIpPQ3FR45DUDiKz6q_vBaHH_HNifnnIpDVbMD8,923
46
+ otdf_python/version.py,sha256=-MUAI4rKLCv3eGkVtEhBzqpyZOT7hZDWdzqJhfnS_BQ,1906
47
+ otdf_python/zip_reader.py,sha256=GuE4hMDJfeFx6UtCUeFLmsZCJiK4RFNyyzlERA8T6Uw,1470
48
+ otdf_python/zip_writer.py,sha256=UizpXBvqnl7v1mQvIr-vBIF50NwGFU0YWI-I4Y1XNW0,2091
49
+ otdf_python_proto/__init__.py,sha256=2MVQMcsELGYF8NyXU8OFFQdXM1_WTKpdA9MUqiMazE8,931
50
+ otdf_python_proto/authorization/__init__.py,sha256=hDpCNPxPswsfkcrCiv3Y78nqAQ_FxE9uDrYqeIqKipg,42
51
+ otdf_python_proto/authorization/authorization_pb2.py,sha256=VxRCF1popd01Po0uC-H3Uz85Z6y39ICuzwjFuRWkDoE,9085
52
+ otdf_python_proto/authorization/authorization_pb2.pyi,sha256=43mV-jbbgxjvzuKkJE-tcLg4JrqtqoQwB5WT9k4j3Ew,8927
53
+ otdf_python_proto/authorization/authorization_pb2_connect.py,sha256=PrbEg9mUSMA6Bwh5pCtwkIHEQ-phcd1vW0uIizBwqis,10162
54
+ otdf_python_proto/authorization/v2/authorization_pb2.py,sha256=pz5GE1cBmcyWHCG3ba46_We-ywY7dx2oxZwHgvtJJtA,12998
55
+ otdf_python_proto/authorization/v2/authorization_pb2.pyi,sha256=0azk9XIOxBU5u0b8_PnHnfaGM13tQPBgN4i42oRSI2Q,7497
56
+ otdf_python_proto/authorization/v2/authorization_pb2_connect.py,sha256=UdsbFiFW2_yDIKsUlhgM4mUWzZaZ8J8rfxqVwWFjMYY,13129
57
+ otdf_python_proto/common/__init__.py,sha256=cJlVANj7I0xoLUerst-2su60AFtywyrFHPOIKIzS65Q,35
58
+ otdf_python_proto/common/common_pb2.py,sha256=F2Ap8Lf-LJGnk_-BsrAfoidYtkkTsc24OvZgikBigDs,3599
59
+ otdf_python_proto/common/common_pb2.pyi,sha256=iitFFATcqvxfhdgAGlPFmYeyHeLSyBKKzvSNgm8kioM,2860
60
+ otdf_python_proto/entity/__init__.py,sha256=Q5bx_n1hD8DQR8f78iflJzw90RJZLeIj--Q6YaHqJ_4,35
61
+ otdf_python_proto/entity/entity_pb2.py,sha256=LpdkNpqn-L808SfYI6JWATfmud_9oYRpHbnX02qXQB8,3178
62
+ otdf_python_proto/entity/entity_pb2.pyi,sha256=vkQau-BYeQvGV_Sr0YqqPDgiLuecErOey_Dn0zpHTN4,2423
63
+ otdf_python_proto/entityresolution/__init__.py,sha256=YAlVbWPddWxz9U5ldGLwFxs1VvvM9x7c8_JalKwXa4U,45
64
+ otdf_python_proto/entityresolution/entity_resolution_pb2.py,sha256=XrPNnZ7GvHE0w0iHharpSte30l_DjhDlNE__mJigWTg,5032
65
+ otdf_python_proto/entityresolution/entity_resolution_pb2.pyi,sha256=Yn8snkOsfkYPb4CngTMJcTe75RdOJUT_Yo4rk-mMTaM,3001
66
+ otdf_python_proto/entityresolution/entity_resolution_pb2_connect.py,sha256=7NFAV7cx27R8b__2eM0MAiwPaT8E3TEmm-QrhauW3nE,7972
67
+ otdf_python_proto/entityresolution/v2/entity_resolution_pb2.py,sha256=G_CHQ76xCYAV6hfY1-tbncOCu7FqtdLH2FzOwO0vlvM,4680
68
+ otdf_python_proto/entityresolution/v2/entity_resolution_pb2.pyi,sha256=wRcDT1bcKvyjMgPi8-MrQYLUDEaWjy2MY0YbsxF3Gjo,2942
69
+ otdf_python_proto/entityresolution/v2/entity_resolution_pb2_connect.py,sha256=mnj_IuaBr_AjAGtvIc4QZzcHgG2UuYFnbA7cEH-f8RQ,8178
70
+ otdf_python_proto/kas/__init__.py,sha256=8gcnDu9Hr7l0iJa3tVUjZruOjnewelau1Vt124Ln1n4,226
71
+ otdf_python_proto/kas/kas_pb2.py,sha256=FuWeaQYjICzKFmovm1sqdAPCcDn-tariNUs4CHHNUV8,11431
72
+ otdf_python_proto/kas/kas_pb2.pyi,sha256=w-S-AoFOZn3jn39iLyLFW4Sw4bKxr0GA8OSVF-SnR-s,8594
73
+ otdf_python_proto/kas/kas_pb2_connect.py,sha256=kFOs0mwynx-lutAqNp5m3HvEQyVCCAjHtj4JcJ8Q-Yo,8664
74
+ otdf_python_proto/legacy_grpc/__init__.py,sha256=zpWWFl-aIfDdJqBnMFk6lDSzsKfZ4pjkp2LYxGE1S9c,40
75
+ otdf_python_proto/legacy_grpc/authorization/authorization_pb2_grpc.py,sha256=Xn_jbL7EyOKolHp_0wxOqN3Eqm0eWjb4meB6X8xJPM0,6922
76
+ otdf_python_proto/legacy_grpc/authorization/v2/authorization_pb2_grpc.py,sha256=i6SlVNT3uRfKr11hIZGGwPmmCZag-28kUzJjj8h_Zy0,9109
77
+ otdf_python_proto/legacy_grpc/common/common_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
78
+ otdf_python_proto/legacy_grpc/entity/entity_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
79
+ otdf_python_proto/legacy_grpc/entityresolution/entity_resolution_pb2_grpc.py,sha256=uU_nscm2_PmQ1lk1Y4e1Nzj1Vcp8ReYxe7l93JXCSiw,5261
80
+ otdf_python_proto/legacy_grpc/entityresolution/v2/entity_resolution_pb2_grpc.py,sha256=HqYKJ3j5sJv8EAzdtZAfmrB1Fi4Xtrv-v3wud0JdieQ,5422
81
+ otdf_python_proto/legacy_grpc/kas/kas_pb2_grpc.py,sha256=zZpTeIk_EKPv1ds4kzo4L_otI0PDwpzO1o7qTqrOVTk,6422
82
+ otdf_python_proto/legacy_grpc/logger/audit/test_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
83
+ otdf_python_proto/legacy_grpc/policy/objects_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
84
+ otdf_python_proto/legacy_grpc/policy/selectors_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
85
+ otdf_python_proto/legacy_grpc/policy/actions/actions_pb2_grpc.py,sha256=cwsrUzJrypSl4NaImV9FzM8TIy8u8kpj-r_M1beI8_8,10380
86
+ otdf_python_proto/legacy_grpc/policy/attributes/attributes_pb2_grpc.py,sha256=1c1v8No6eqkgYGuoU6im5OVQbcdW9MV4m36pAQhABEQ,40356
87
+ otdf_python_proto/legacy_grpc/policy/kasregistry/key_access_server_registry_pb2_grpc.py,sha256=ZNncnAVLfGe_oY8hK6MzZDD1ReiKJ-hgyuHpYalI1lo,28509
88
+ otdf_python_proto/legacy_grpc/policy/keymanagement/key_management_pb2_grpc.py,sha256=LynB9ChgzqaLUw1NGVk0ONdRIeEA7WT44-yv64sxMg0,11526
89
+ otdf_python_proto/legacy_grpc/policy/namespaces/namespaces_pb2_grpc.py,sha256=SPdWNt23Kty6z0NIIDvfBq7ACedGQAaQzBlqQ8gFwr4,19665
90
+ otdf_python_proto/legacy_grpc/policy/registeredresources/registered_resources_pb2_grpc.py,sha256=Bz6kkWw_exluCLkn8JqQ5drDS_Cu_v0ostNQJ_7yVCI,26156
91
+ otdf_python_proto/legacy_grpc/policy/resourcemapping/resource_mapping_pb2_grpc.py,sha256=AZhmHCiR9yILQHR30sH1norFwy4oSU4TtnbjpCQQmuw,24868
92
+ otdf_python_proto/legacy_grpc/policy/subjectmapping/subject_mapping_pb2_grpc.py,sha256=GZgqhIieGaXqVVuMpD17JjmSsqyc3PzBXry514gvbP0,26820
93
+ otdf_python_proto/legacy_grpc/policy/unsafe/unsafe_pb2_grpc.py,sha256=OE4D6SySpinZAkaVlUIkqqYImDUQSbWFA6HZu7to-0I,21295
94
+ otdf_python_proto/legacy_grpc/wellknownconfiguration/wellknown_configuration_pb2_grpc.py,sha256=dCFsCFxcDzT9RZ2M09pX-zu4qZazu_1UGSNJjS7JhzU,3348
95
+ otdf_python_proto/logger/__init__.py,sha256=gMDNk1OB1THsKqwevYeQERG-DCJ-PspkYdo9jnqLyas,35
96
+ otdf_python_proto/logger/audit/test_pb2.py,sha256=FbhQNp-ENPvhFlYtGqPaq9aaFLxXn_NaxOO0PJzvFzI,3028
97
+ otdf_python_proto/logger/audit/test_pb2.pyi,sha256=uqHbuyrpKspEObm4F3edJthw2IZSdojaoBalXEQgA1U,2346
98
+ otdf_python_proto/policy/__init__.py,sha256=yrbwH5e3KjoqN4PSnFcOfC4xV9YuvzPa8OxDlGoOfkk,35
99
+ otdf_python_proto/policy/objects_pb2.py,sha256=4izyxIYyD_9q6Bj3hff5cfjgvYIGW6ewZpsQ_MZE26E,22589
100
+ otdf_python_proto/policy/objects_pb2.pyi,sha256=nuK89_2Z1R6I1xE0EokL2lUdEIEuzVFne0IqykpC7uI,24523
101
+ otdf_python_proto/policy/selectors_pb2.py,sha256=uqgIS0DtfOYDqzJ6WNq9D9aLa-RnTpN9a5o7YGMF7xM,5301
102
+ otdf_python_proto/policy/selectors_pb2.pyi,sha256=FdC8ZLkgBBspwdjA1JlaeSgPo3R2qUIDws-9vNRXAUs,5162
103
+ otdf_python_proto/policy/actions/actions_pb2.py,sha256=QRcrBnuu1iDWjVQLl0dWHCwuOwnLguzn4w9f2201xjM,8858
104
+ otdf_python_proto/policy/actions/actions_pb2.pyi,sha256=ZBgv2xtG4PW7vXUJkzbfvMPaKUmztVw6_FG5iN0Ph-I,4298
105
+ otdf_python_proto/policy/actions/actions_pb2_connect.py,sha256=u6M1o9T8lWtkLSp2sMG7mQwxNPMixK2VxZ3IVVyfAAM,14472
106
+ otdf_python_proto/policy/attributes/attributes_pb2.py,sha256=wnK1qsuOVOePneFfDGtBDxiyvP9S8XA48mMTexybYBE,33029
107
+ otdf_python_proto/policy/attributes/attributes_pb2.pyi,sha256=lpxvoxiRhSn1LEupx1fOcBc6pOdWcrTXAx_boHvGFZY,16259
108
+ otdf_python_proto/policy/attributes/attributes_pb2_connect.py,sha256=M57-dw9vfiDJuwmCxLHlZhBxrXXPULbyyiopykh_xkU,56796
109
+ otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2.py,sha256=5RRqC6MsfBM9TEmPedRZYKMjdVWptMXXTUolUU4FPXI,45921
110
+ otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2.pyi,sha256=hpIgoFXZtY6HsjfHPi_Ybxm0CddK_AYy8YTlfdzR1Jk,24030
111
+ otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2_connect.py,sha256=R2hkmB9X_Utg3C5fIWSGcTYZB9X3dJVy8gGaxkq6RFE,40328
112
+ otdf_python_proto/policy/keymanagement/key_management_pb2.py,sha256=MVAJKkR_B2nqN9jqWg7JLWByKFFfoi4unj1hbToByCE,8129
113
+ otdf_python_proto/policy/keymanagement/key_management_pb2.pyi,sha256=9HoPHqEKIO8jhx9TpkwFJWSHiInpkq04LiNPUCYeDU4,4381
114
+ otdf_python_proto/policy/keymanagement/key_management_pb2_connect.py,sha256=_ghDKFEFCaofp2j4U9mQ8RgizFHAN2XSJQsSHRBH_Zg,16662
115
+ otdf_python_proto/policy/namespaces/namespaces_pb2.py,sha256=NTdUbii-WF0VNiVvM29ZmAni7W4dgmNkOGq2ytP31pk,15222
116
+ otdf_python_proto/policy/namespaces/namespaces_pb2.pyi,sha256=plOpaSBszfi7p71XKZvTg1e1nJUhvoz1wrcYDX9cByQ,7148
117
+ otdf_python_proto/policy/namespaces/namespaces_pb2_connect.py,sha256=mXn8N0hmguejlkbL-IwwSYl-nXGdrfGPLQ0XMEKCXLM,27828
118
+ otdf_python_proto/policy/registeredresources/registered_resources_pb2.py,sha256=5pb4vm0SEOG-U8FORKa9Z1Fe2tbgcWEEJworZE_LS00,23112
119
+ otdf_python_proto/policy/registeredresources/registered_resources_pb2.pyi,sha256=MsFkcXQbdvu7JQGeS-HYFHB7V3yWtpAPEmhoARjDvMI,10132
120
+ otdf_python_proto/policy/registeredresources/registered_resources_pb2_connect.py,sha256=KI17dRxTVL71j_qHlwEs1MZPVtayt-Ay5xwZgfmizq0,38350
121
+ otdf_python_proto/policy/resourcemapping/resource_mapping_pb2.py,sha256=vnMJu2jEr3NHH5aUx5hquQAyHlUwtgh2lL9YdXil2bs,21745
122
+ otdf_python_proto/policy/resourcemapping/resource_mapping_pb2.pyi,sha256=B4I6nj1bHNI8VZImfuBeXJ6S_-tovN0DbwfncTujUw4,10380
123
+ otdf_python_proto/policy/resourcemapping/resource_mapping_pb2_connect.py,sha256=wuqKoDgpdGr0mo_JQ_MO2vshdXLDKVs1x_-9Ou4SchU,36062
124
+ otdf_python_proto/policy/subjectmapping/subject_mapping_pb2.py,sha256=iNZp_sHDLXtSUdMNayWHJyZl0050Ag5v-naq0r2FmUM,18093
125
+ otdf_python_proto/policy/subjectmapping/subject_mapping_pb2.pyi,sha256=kPkRm8xw3KiEu9LiUmKCbouHVryeEFWyk19Eo6L6rus,10903
126
+ otdf_python_proto/policy/subjectmapping/subject_mapping_pb2_connect.py,sha256=tn9Ib6TPWoYKQ7B-RKL2cliSPAC6DYLatXO6Ao2Ys7I,38548
127
+ otdf_python_proto/policy/unsafe/unsafe_pb2.py,sha256=j8J3FGM6nL6VDJvZUdrq6MAQ0GvHCDRH1q3-Djw5NfE,14936
128
+ otdf_python_proto/policy/unsafe/unsafe_pb2.pyi,sha256=Pu72GtZTZWdD_L9SqqyeV8SQu9VXdVEEAGECrzHFmWs,5879
129
+ otdf_python_proto/policy/unsafe/unsafe_pb2_connect.py,sha256=OqKigFTTVPKQkL4TOMLqnEUKBc2zUp8qSSOk2TKP6U8,29839
130
+ otdf_python_proto/wellknownconfiguration/__init__.py,sha256=X3GeZJ1mG_N1MViryjkqUU099f2qzR6bnoDQXGWhKpc,51
131
+ otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2.py,sha256=g9xSm9TxX0IPMqiFCaridJvI2TrL8PrXVFPgu8tX9VM,3863
132
+ otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2.pyi,sha256=Zw4vROvTgomnFqsalJrYda632ojXH0FVXSzTXxerybw,1490
133
+ otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2_connect.py,sha256=i9rGG2mgQZfk6xGCp1ywu4QqKWSiwpuLoNKGUwl43t8,5346
134
+ otdf_python-0.3.1.dist-info/METADATA,sha256=c_xz4PSK5R_IPZCa2jHFxYzZ6DkYAsMA5l2N2nya4gc,5822
135
+ otdf_python-0.3.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
136
+ otdf_python-0.3.1.dist-info/licenses/LICENSE,sha256=DPrPHdI6tfZcqk9kzQ37vh1Ftk7LJYdMrUtwKl7L3Pw,1074
137
+ otdf_python-0.3.1.dist-info/RECORD,,
@@ -1,5 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
-
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 b-long
3
+ Copyright (c) 2024 to present b-long
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,37 @@
1
+ """OpenTDF Python Protocol Buffers Package.
2
+
3
+ This package contains generated Python code from OpenTDF protocol buffer definitions.
4
+ It includes modules for authorization, common types, entities, policy management,
5
+ and other OpenTDF services.
6
+ """
7
+ from importlib import metadata
8
+
9
+ try:
10
+ __version__ = metadata.version("otdf-python-proto")
11
+ except metadata.PackageNotFoundError:
12
+ # package is not installed, e.g., in development
13
+ __version__ = "0.0.0"
14
+
15
+ # Import submodules to make them available
16
+ from . import authorization
17
+ from . import common
18
+ from . import entity
19
+ from . import entityresolution
20
+ from . import kas
21
+ from . import legacy_grpc
22
+ from . import logger
23
+ from . import policy
24
+ from . import wellknownconfiguration
25
+
26
+ # Export main module categories
27
+ __all__ = [
28
+ "authorization",
29
+ "common",
30
+ "entity",
31
+ "entityresolution",
32
+ "kas",
33
+ "legacy_grpc",
34
+ "logger",
35
+ "policy",
36
+ "wellknownconfiguration",
37
+ ]
@@ -0,0 +1 @@
1
+ """authorization protobuf definitions."""