otdf-python 0.4.0__tar.gz → 0.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. {otdf_python-0.4.0 → otdf_python-0.4.1}/.pre-commit-config.yaml +1 -1
  2. otdf_python-0.4.1/.release-please-manifest.json +3 -0
  3. {otdf_python-0.4.0 → otdf_python-0.4.1}/.vscode/extensions.json +1 -1
  4. {otdf_python-0.4.0 → otdf_python-0.4.1}/CHANGELOG.md +7 -0
  5. {otdf_python-0.4.0 → otdf_python-0.4.1}/PKG-INFO +1 -1
  6. {otdf_python-0.4.0 → otdf_python-0.4.1}/conftest.py +4 -6
  7. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/pyproject.toml +1 -1
  8. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/scripts/generate_connect_proto.py +2 -4
  9. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/uv.lock +1 -1
  10. {otdf_python-0.4.0 → otdf_python-0.4.1}/pyproject.toml +29 -23
  11. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/__init__.py +1 -2
  12. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/__main__.py +1 -2
  13. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/address_normalizer.py +8 -10
  14. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/aesgcm.py +8 -0
  15. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/assertion_config.py +21 -0
  16. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/asym_crypto.py +18 -22
  17. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/auth_headers.py +7 -6
  18. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/autoconfigure_utils.py +22 -6
  19. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/cli.py +5 -5
  20. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/collection_store.py +13 -0
  21. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/collection_store_impl.py +5 -0
  22. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/config.py +13 -0
  23. otdf_python-0.4.1/src/otdf_python/connect_client.py +1 -0
  24. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/constants.py +2 -0
  25. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/crypto_utils.py +4 -0
  26. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/dpop.py +3 -5
  27. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/ecc_constants.py +12 -14
  28. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/ecc_mode.py +7 -2
  29. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/ecdh.py +24 -25
  30. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/eckeypair.py +5 -0
  31. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/header.py +5 -0
  32. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/invalid_zip_exception.py +6 -2
  33. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/kas_client.py +48 -55
  34. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/kas_connect_rpc_client.py +16 -19
  35. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/kas_info.py +4 -3
  36. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/kas_key_cache.py +10 -9
  37. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/key_type.py +4 -0
  38. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/key_type_constants.py +4 -11
  39. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/manifest.py +24 -0
  40. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/nanotdf.py +34 -24
  41. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/nanotdf_ecdsa_struct.py +5 -9
  42. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/nanotdf_type.py +12 -0
  43. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/policy_binding_serializer.py +6 -4
  44. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/policy_info.py +6 -0
  45. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/policy_object.py +8 -0
  46. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/policy_stub.py +2 -0
  47. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/resource_locator.py +22 -13
  48. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/sdk.py +49 -57
  49. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/sdk_builder.py +58 -41
  50. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/sdk_exceptions.py +11 -1
  51. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/symmetric_and_payload_config.py +6 -0
  52. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/tdf.py +47 -10
  53. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/tdf_reader.py +10 -13
  54. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/tdf_writer.py +5 -0
  55. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/token_source.py +4 -3
  56. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/version.py +5 -0
  57. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/zip_reader.py +10 -2
  58. {otdf_python-0.4.0 → otdf_python-0.4.1}/src/otdf_python/zip_writer.py +11 -0
  59. otdf_python-0.4.1/tests/__init__.py +1 -0
  60. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/config_pydantic.py +2 -5
  61. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/conftest.py +1 -3
  62. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/otdfctl_only/test_otdfctl_generated_fixtures.py +0 -2
  63. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/otdfctl_to_python/test_cli_comparison.py +1 -5
  64. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/otdfctl_to_python/test_cli_decrypt.py +4 -13
  65. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/otdfctl_to_python/test_cli_inspect.py +3 -10
  66. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/otdfctl_to_python/test_nanotdf_cli_comparison.py +3 -8
  67. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/otdfctl_to_python/test_python_nanotdf_only.py +2 -3
  68. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/otdfctl_to_python/test_tdf_reader_integration.py +1 -6
  69. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/python_only/test_kas_client_integration.py +1 -3
  70. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/support_sdk.py +1 -2
  71. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/test_cli_integration.py +4 -16
  72. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/test_cli_tdf_validation.py +4 -11
  73. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/test_pe_interaction.py +2 -4
  74. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/server_logs.py +6 -8
  75. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/support_cli_args.py +3 -9
  76. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/support_common.py +1 -2
  77. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/support_otdfctl.py +3 -5
  78. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/support_otdfctl_args.py +5 -9
  79. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_address_normalizer.py +1 -3
  80. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_cli.py +1 -3
  81. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_ecdh.py +1 -3
  82. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_kas_client.py +17 -3
  83. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_kas_key_cache.py +6 -3
  84. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_kas_key_management.py +2 -0
  85. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_key_type.py +8 -0
  86. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_log_collection.py +1 -2
  87. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_manifest.py +2 -0
  88. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_manifest_format.py +1 -4
  89. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_nanotdf.py +6 -0
  90. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_nanotdf_ecdh.py +1 -3
  91. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_nanotdf_ecdsa_struct.py +1 -3
  92. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_nanotdf_integration.py +3 -0
  93. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_nanotdf_type.py +9 -0
  94. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_policy_object.py +7 -0
  95. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_sdk.py +16 -3
  96. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_sdk_builder.py +1 -3
  97. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_sdk_exceptions.py +6 -0
  98. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_sdk_mock.py +13 -0
  99. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_sdk_tdf_integration.py +1 -3
  100. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_tdf.py +4 -0
  101. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_tdf_key_management.py +2 -0
  102. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_tdf_reader.py +1 -3
  103. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_tdf_writer.py +8 -0
  104. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_token_source.py +3 -3
  105. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_url_normalization.py +2 -2
  106. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_use_plaintext_flow.py +1 -6
  107. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_validate_otdf_python.py +6 -3
  108. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_version.py +8 -0
  109. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_zip_reader.py +7 -0
  110. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_zip_writer.py +6 -0
  111. {otdf_python-0.4.0 → otdf_python-0.4.1}/uv.lock +1 -1
  112. otdf_python-0.4.0/.release-please-manifest.json +0 -3
  113. otdf_python-0.4.0/src/otdf_python/connect_client.py +0 -0
  114. otdf_python-0.4.0/tests/__init__.py +0 -1
  115. {otdf_python-0.4.0 → otdf_python-0.4.1}/.github/check_entitlements.sh +0 -0
  116. {otdf_python-0.4.0 → otdf_python-0.4.1}/.github/start_opentdf_docker.sh +0 -0
  117. {otdf_python-0.4.0 → otdf_python-0.4.1}/.github/workflows/build-python.yaml +0 -0
  118. {otdf_python-0.4.0 → otdf_python-0.4.1}/.github/workflows/platform-integration-test.yaml +0 -0
  119. {otdf_python-0.4.0 → otdf_python-0.4.1}/.github/workflows/release-please.yaml +0 -0
  120. {otdf_python-0.4.0 → otdf_python-0.4.1}/.github/workflows/test-suite.yaml +0 -0
  121. {otdf_python-0.4.0 → otdf_python-0.4.1}/.gitignore +0 -0
  122. {otdf_python-0.4.0 → otdf_python-0.4.1}/.release-please-config-develop.json +0 -0
  123. {otdf_python-0.4.0 → otdf_python-0.4.1}/.release-please-config.json +0 -0
  124. {otdf_python-0.4.0 → otdf_python-0.4.1}/.release-please-manifest-develop.json +0 -0
  125. {otdf_python-0.4.0 → otdf_python-0.4.1}/.vscode/settings.json +0 -0
  126. {otdf_python-0.4.0 → otdf_python-0.4.1}/LICENSE +0 -0
  127. {otdf_python-0.4.0 → otdf_python-0.4.1}/README.md +0 -0
  128. {otdf_python-0.4.0 → otdf_python-0.4.1}/docs/CONNECT_RPC.md +0 -0
  129. {otdf_python-0.4.0 → otdf_python-0.4.1}/docs/DEVELOPING.md +0 -0
  130. {otdf_python-0.4.0 → otdf_python-0.4.1}/docs/LEGACY_VERSION.md +0 -0
  131. {otdf_python-0.4.0 → otdf_python-0.4.1}/docs/RELEASES.md +0 -0
  132. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/README.md +0 -0
  133. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/buf.gen.yaml +0 -0
  134. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/buf.lock +0 -0
  135. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/buf.yaml +0 -0
  136. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/authorization/authorization.proto +0 -0
  137. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/authorization/v2/authorization.proto +0 -0
  138. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/common/common.proto +0 -0
  139. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/entity/entity.proto +0 -0
  140. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/entityresolution/entity_resolution.proto +0 -0
  141. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/entityresolution/v2/entity_resolution.proto +0 -0
  142. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/kas/kas.proto +0 -0
  143. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/logger/audit/test.proto +0 -0
  144. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/policy/actions/actions.proto +0 -0
  145. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/policy/attributes/attributes.proto +0 -0
  146. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/policy/kasregistry/key_access_server_registry.proto +0 -0
  147. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/policy/keymanagement/key_management.proto +0 -0
  148. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/policy/namespaces/namespaces.proto +0 -0
  149. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/policy/objects.proto +0 -0
  150. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/policy/registeredresources/registered_resources.proto +0 -0
  151. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/policy/resourcemapping/resource_mapping.proto +0 -0
  152. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/policy/selectors.proto +0 -0
  153. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/policy/subjectmapping/subject_mapping.proto +0 -0
  154. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/policy/unsafe/unsafe.proto +0 -0
  155. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/proto-files/wellknownconfiguration/wellknown_configuration.proto +0 -0
  156. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/scripts/build_connect_proto.sh +0 -0
  157. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/scripts/setup_connect_rpc.py +0 -0
  158. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/__init__.py +0 -0
  159. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/authorization/__init__.py +0 -0
  160. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/authorization/authorization_pb2.py +0 -0
  161. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/authorization/authorization_pb2.pyi +0 -0
  162. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/authorization/authorization_pb2_connect.py +0 -0
  163. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/authorization/v2/authorization_pb2.py +0 -0
  164. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/authorization/v2/authorization_pb2.pyi +0 -0
  165. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/authorization/v2/authorization_pb2_connect.py +0 -0
  166. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/common/__init__.py +0 -0
  167. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/common/common_pb2.py +0 -0
  168. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/common/common_pb2.pyi +0 -0
  169. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/entity/__init__.py +0 -0
  170. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/entity/entity_pb2.py +0 -0
  171. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/entity/entity_pb2.pyi +0 -0
  172. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/entityresolution/__init__.py +0 -0
  173. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/entityresolution/entity_resolution_pb2.py +0 -0
  174. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/entityresolution/entity_resolution_pb2.pyi +0 -0
  175. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/entityresolution/entity_resolution_pb2_connect.py +0 -0
  176. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/entityresolution/v2/entity_resolution_pb2.py +0 -0
  177. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/entityresolution/v2/entity_resolution_pb2.pyi +0 -0
  178. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/entityresolution/v2/entity_resolution_pb2_connect.py +0 -0
  179. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/kas/__init__.py +0 -0
  180. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/kas/kas_pb2.py +0 -0
  181. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/kas/kas_pb2.pyi +0 -0
  182. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/kas/kas_pb2_connect.py +0 -0
  183. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/__init__.py +0 -0
  184. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/authorization/authorization_pb2_grpc.py +0 -0
  185. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/authorization/v2/authorization_pb2_grpc.py +0 -0
  186. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/common/common_pb2_grpc.py +0 -0
  187. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/entity/entity_pb2_grpc.py +0 -0
  188. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/entityresolution/entity_resolution_pb2_grpc.py +0 -0
  189. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/entityresolution/v2/entity_resolution_pb2_grpc.py +0 -0
  190. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/kas/kas_pb2_grpc.py +0 -0
  191. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/logger/audit/test_pb2_grpc.py +0 -0
  192. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/actions/actions_pb2_grpc.py +0 -0
  193. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/attributes/attributes_pb2_grpc.py +0 -0
  194. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/kasregistry/key_access_server_registry_pb2_grpc.py +0 -0
  195. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/keymanagement/key_management_pb2_grpc.py +0 -0
  196. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/namespaces/namespaces_pb2_grpc.py +0 -0
  197. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/objects_pb2_grpc.py +0 -0
  198. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/registeredresources/registered_resources_pb2_grpc.py +0 -0
  199. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/resourcemapping/resource_mapping_pb2_grpc.py +0 -0
  200. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/selectors_pb2_grpc.py +0 -0
  201. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/subjectmapping/subject_mapping_pb2_grpc.py +0 -0
  202. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/unsafe/unsafe_pb2_grpc.py +0 -0
  203. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/wellknownconfiguration/wellknown_configuration_pb2_grpc.py +0 -0
  204. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/logger/__init__.py +0 -0
  205. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/logger/audit/test_pb2.py +0 -0
  206. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/logger/audit/test_pb2.pyi +0 -0
  207. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/__init__.py +0 -0
  208. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/actions/actions_pb2.py +0 -0
  209. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/actions/actions_pb2.pyi +0 -0
  210. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/actions/actions_pb2_connect.py +0 -0
  211. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/attributes/attributes_pb2.py +0 -0
  212. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/attributes/attributes_pb2.pyi +0 -0
  213. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/attributes/attributes_pb2_connect.py +0 -0
  214. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2.py +0 -0
  215. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2.pyi +0 -0
  216. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2_connect.py +0 -0
  217. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/keymanagement/key_management_pb2.py +0 -0
  218. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/keymanagement/key_management_pb2.pyi +0 -0
  219. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/keymanagement/key_management_pb2_connect.py +0 -0
  220. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/namespaces/namespaces_pb2.py +0 -0
  221. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/namespaces/namespaces_pb2.pyi +0 -0
  222. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/namespaces/namespaces_pb2_connect.py +0 -0
  223. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/objects_pb2.py +0 -0
  224. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/objects_pb2.pyi +0 -0
  225. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/registeredresources/registered_resources_pb2.py +0 -0
  226. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/registeredresources/registered_resources_pb2.pyi +0 -0
  227. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/registeredresources/registered_resources_pb2_connect.py +0 -0
  228. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/resourcemapping/resource_mapping_pb2.py +0 -0
  229. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/resourcemapping/resource_mapping_pb2.pyi +0 -0
  230. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/resourcemapping/resource_mapping_pb2_connect.py +0 -0
  231. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/selectors_pb2.py +0 -0
  232. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/selectors_pb2.pyi +0 -0
  233. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/subjectmapping/subject_mapping_pb2.py +0 -0
  234. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/subjectmapping/subject_mapping_pb2.pyi +0 -0
  235. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/subjectmapping/subject_mapping_pb2_connect.py +0 -0
  236. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/unsafe/unsafe_pb2.py +0 -0
  237. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/unsafe/unsafe_pb2.pyi +0 -0
  238. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/policy/unsafe/unsafe_pb2_connect.py +0 -0
  239. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/wellknownconfiguration/__init__.py +0 -0
  240. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2.py +0 -0
  241. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2.pyi +0 -0
  242. {otdf_python-0.4.0 → otdf_python-0.4.1}/otdf-python-proto/src/otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2_connect.py +0 -0
  243. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/test_data/empty_file.txt +0 -0
  244. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/test_data/sample_binary.png +0 -0
  245. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/test_data/sample_text.txt +0 -0
  246. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/integration/test_data/sample_with_attributes.txt +0 -0
  247. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/mock_crypto.py +0 -0
  248. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_aesgcm.py +0 -0
  249. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_assertion_config.py +0 -0
  250. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_asym_encryption.py +0 -0
  251. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_autoconfigure_utils.py +0 -0
  252. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_collection_store.py +0 -0
  253. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_config.py +0 -0
  254. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_crypto_utils.py +0 -0
  255. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_eckeypair.py +0 -0
  256. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_header.py +0 -0
  257. {otdf_python-0.4.0 → otdf_python-0.4.1}/tests/test_inner_classes.py +0 -0
@@ -34,7 +34,7 @@ repos:
34
34
 
35
35
  - repo: https://github.com/astral-sh/ruff-pre-commit
36
36
  # Ruff version.
37
- rev: v0.14.5
37
+ rev: v0.14.8
38
38
  hooks:
39
39
  # Run the linter.
40
40
  - id: ruff-check
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.4.1"
3
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "recommendations": [
3
- "golang.go"
3
+ "charliermarsh.ruff"
4
4
  ]
5
5
  }
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.1](https://github.com/b-long/opentdf-python-sdk/compare/otdf-python-v0.4.0...otdf-python-v0.4.1) (2025-12-09)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * preserve exception chain ([#119](https://github.com/b-long/opentdf-python-sdk/issues/119)) ([09984b8](https://github.com/b-long/opentdf-python-sdk/commit/09984b843b369a6d2c76dc8a81d6315f195ea773))
9
+
3
10
  ## [0.4.0](https://github.com/b-long/opentdf-python-sdk/compare/otdf-python-v0.3.5...otdf-python-v0.4.0) (2025-11-20)
4
11
 
5
12
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: otdf-python
3
- Version: 0.4.0
3
+ Version: 0.4.1
4
4
  Summary: Unofficial OpenTDF SDK for Python
5
5
  Project-URL: Homepage, https://github.com/b-long/opentdf-python-sdk
6
6
  Project-URL: Repository, https://github.com/b-long/opentdf-python-sdk
@@ -1,5 +1,4 @@
1
- """
2
- Pytest configuration and fixtures for the OpenTDF Python SDK tests.
1
+ """Pytest configuration and fixtures for the OpenTDF Python SDK tests.
3
2
 
4
3
  This module contains pytest hooks and fixtures that will be automatically
5
4
  loaded by pytest when running tests.
@@ -14,13 +13,13 @@ from tests.server_logs import log_server_logs_on_failure
14
13
 
15
14
  @pytest.fixture(scope="session")
16
15
  def project_root(request) -> Path:
16
+ """Get project root directory."""
17
17
  return request.config.rootpath # Project root
18
18
 
19
19
 
20
20
  @pytest.hookimpl(tryfirst=True, hookwrapper=True)
21
21
  def pytest_runtest_makereport(item, call):
22
- """
23
- Hook that runs after each test phase (setup, call, teardown).
22
+ """Collect server logs when test fails after each test phase.
24
23
 
25
24
  This hook automatically collects server logs when a test fails.
26
25
  """
@@ -53,8 +52,7 @@ def pytest_runtest_makereport(item, call):
53
52
 
54
53
  @pytest.fixture
55
54
  def collect_server_logs():
56
- """
57
- Fixture that provides a function to manually collect server logs.
55
+ """Fixture that provides a function to manually collect server logs.
58
56
 
59
57
  Usage:
60
58
  def test_something(collect_server_logs):
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "otdf-python-proto"
3
- version = "0.4.0"
3
+ version = "0.4.1"
4
4
  description = "Generated protobuf files for OpenTDF Python SDK"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- """
3
- Enhanced script to generate Python Connect RPC clients from .proto definitions.
2
+ """Enhanced script to generate Python Connect RPC clients from .proto definitions.
4
3
 
5
4
  This script:
6
5
  1. Downloads the latest proto files from OpenTDF platform
@@ -200,8 +199,7 @@ def create_init_files(generated_dir: Path) -> None:
200
199
 
201
200
 
202
201
  def _fix_ignore_if_default_value(proto_files_dir):
203
- """
204
- TODO: Fix buf validation: Updated the proto files to use the correct enum value:
202
+ """TODO: Fix buf validation: Updated the proto files to use the correct enum value:
205
203
 
206
204
  Changed IGNORE_IF_DEFAULT_VALUE → IGNORE_IF_ZERO_VALUE in:
207
205
  attributes.proto
@@ -601,7 +601,7 @@ wheels = [
601
601
 
602
602
  [[package]]
603
603
  name = "otdf-python-proto"
604
- version = "0.4.0"
604
+ version = "0.4.1"
605
605
  source = { editable = "." }
606
606
  dependencies = [
607
607
  { name = "connect-python", extra = ["compiler"] },
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "otdf-python"
3
- version = "0.4.0"
3
+ version = "0.4.1"
4
4
  description = "Unofficial OpenTDF SDK for Python"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -72,6 +72,7 @@ norecursedirs = ["otdf-python-proto"]
72
72
 
73
73
  [tool.ruff]
74
74
  line-length = 88
75
+ target-version = "py310"
75
76
 
76
77
  # See https://docs.astral.sh/ruff/rules/
77
78
  # for rule information.
@@ -80,28 +81,33 @@ lint.ignore = [
80
81
  "E501",
81
82
  ]
82
83
  lint.select = [
83
- # pycodestyle checks.
84
- "E",
85
- "W",
86
- # pyflakes checks.
87
- "F",
88
- # flake8-bugbear checks.
89
- "B0",
90
- # flake8-comprehensions checks.
91
- "C4",
92
- # McCabe complexity
93
- "C90",
94
- # isort
95
- "I",
96
- # Performance-related rules
97
- "PERF", # Ruff's performance rules
98
- "PTH", # pathlib (path handling)
99
- # Additional useful rules
100
- "UP", # pyupgrade (modern Python features)
101
- "SIM", # flake8-simplify (simplifications)
102
- "RUF", # Ruff-specific rules
103
- "FURB", # refurb (FURB)
104
- "PT018", # flake8-pytest-style (pytest style)
84
+ "B", # flake8-bugbear
85
+ "C4", # flake8-comprehensions
86
+ "C90", # McCabe complexity
87
+ "D", # pydocstyle
88
+ "DOC", # pydoclint
89
+ "E", # pycodestyle errors
90
+ "F", # pyflakes
91
+ "FURB", # refurb
92
+ "I", # isort
93
+ "PERF", # performance
94
+ "PT018", # pytest style
95
+ "PTH", # pathlib
96
+ "Q", # flake8-quotes
97
+ "RUF", # ruff-specific
98
+ "SIM", # flake8-simplify
99
+ "UP", # pyupgrade
100
+ "W", # pycodestyle warnings
105
101
  ]
106
102
  # Ignore generated files
107
103
  extend-exclude = ["otdf-python-proto/src/"]
104
+
105
+ [tool.ruff.lint.per-file-ignores]
106
+ "tests/**" = ["D100", "D101", "D102", "D103", "D107", "D400", "D401", "D415"]
107
+ "otdf-python-proto/**" = ["D"] # Ignore all D (docstring) rules for generated proto files
108
+
109
+ # TODO: Remaining work - 4 buckets to fix (140 errors remaining):
110
+ # Bucket #1: D102 (missing method docstrings) - 98 errors
111
+ # Bucket #2: D105 (missing magic method docstrings) - 23 errors
112
+ # Bucket #3: D205 (blank line formatting), D103, D417, D104 - 19 errors
113
+ "src/**" = ["D102", "D105", "D205"]
@@ -1,5 +1,4 @@
1
- """
2
- OpenTDF Python SDK
1
+ """OpenTDF Python SDK.
3
2
 
4
3
  A Python implementation of the OpenTDF SDK for working with Trusted Data Format (TDF) files.
5
4
  Provides both programmatic APIs and command-line interface for encryption and decryption.
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- """
3
- Main entry point for running otdf_python as a module.
2
+ """Main entry point for running otdf_python as a module.
4
3
 
5
4
  This allows the package to be run with `python -m otdf_python` and properly
6
5
  handles the CLI interface without import conflicts.
@@ -1,6 +1,4 @@
1
- """
2
- Address normalization utilities for OpenTDF.
3
- """
1
+ """Address normalization utilities for OpenTDF."""
4
2
 
5
3
  import logging
6
4
  import re
@@ -12,8 +10,7 @@ logger = logging.getLogger(__name__)
12
10
 
13
11
 
14
12
  def normalize_address(url_string: str, use_plaintext: bool) -> str:
15
- """
16
- Normalize a URL address to ensure it has the correct scheme and port.
13
+ """Normalize a URL address to ensure it has the correct scheme and port.
17
14
 
18
15
  Args:
19
16
  url_string: The URL string to normalize
@@ -24,6 +21,7 @@ def normalize_address(url_string: str, use_plaintext: bool) -> str:
24
21
 
25
22
  Raises:
26
23
  SDKException: If there's an error parsing or creating the URL
24
+
27
25
  """
28
26
  scheme = "http" if use_plaintext else "https"
29
27
 
@@ -34,8 +32,8 @@ def normalize_address(url_string: str, use_plaintext: bool) -> str:
34
32
  port_str = host_port_pattern.group(2)
35
33
  try:
36
34
  port = int(port_str)
37
- except ValueError:
38
- raise SDKException(f"Invalid port in URL [{url_string}]")
35
+ except ValueError as err:
36
+ raise SDKException(f"Invalid port in URL [{url_string}]") from err
39
37
 
40
38
  normalized_url = f"{scheme}://{host}:{port}"
41
39
  logger.debug(f"normalized url [{url_string}] to [{normalized_url}]")
@@ -66,8 +64,8 @@ def normalize_address(url_string: str, use_plaintext: bool) -> str:
66
64
  _, port_str = parsed_url.netloc.split(":", 1)
67
65
  try:
68
66
  port = int(port_str)
69
- except ValueError:
70
- raise SDKException(f"Invalid port in URL [{url_string}]")
67
+ except ValueError as err:
68
+ raise SDKException(f"Invalid port in URL [{url_string}]") from err
71
69
 
72
70
  # If no port was found or extracted, use the default
73
71
  if port is None:
@@ -81,4 +79,4 @@ def normalize_address(url_string: str, use_plaintext: bool) -> str:
81
79
  except Exception as e:
82
80
  if isinstance(e, SDKException):
83
81
  raise e
84
- raise SDKException(f"Error normalizing URL [{url_string}]", e)
82
+ raise SDKException(f"Error normalizing URL [{url_string}]: {e}") from e
@@ -1,13 +1,18 @@
1
+ """AES-GCM encryption and decryption functionality."""
2
+
1
3
  import os
2
4
 
3
5
  from cryptography.hazmat.primitives.ciphers.aead import AESGCM
4
6
 
5
7
 
6
8
  class AesGcm:
9
+ """AES-GCM encryption and decryption operations."""
10
+
7
11
  GCM_NONCE_LENGTH = 12
8
12
  GCM_TAG_LENGTH = 16
9
13
 
10
14
  def __init__(self, key: bytes):
15
+ """Initialize AES-GCM cipher with key."""
11
16
  if not key or len(key) not in (16, 24, 32):
12
17
  raise ValueError("Invalid key size for GCM encryption")
13
18
  self.key = key
@@ -17,7 +22,10 @@ class AesGcm:
17
22
  return self.key
18
23
 
19
24
  class Encrypted:
25
+ """Encrypted data with initialization vector and ciphertext."""
26
+
20
27
  def __init__(self, iv: bytes, ciphertext: bytes):
28
+ """Initialize encrypted data."""
21
29
  self.iv = iv
22
30
  self.ciphertext = ciphertext
23
31
 
@@ -1,8 +1,12 @@
1
+ """Assertion configuration for TDF."""
2
+
1
3
  from enum import Enum, auto
2
4
  from typing import Any
3
5
 
4
6
 
5
7
  class Type(Enum):
8
+ """Assertion type enumeration."""
9
+
6
10
  HANDLING_ASSERTION = "handling"
7
11
  BASE_ASSERTION = "base"
8
12
 
@@ -11,6 +15,8 @@ class Type(Enum):
11
15
 
12
16
 
13
17
  class Scope(Enum):
18
+ """Assertion scope enumeration."""
19
+
14
20
  TRUSTED_DATA_OBJ = "tdo"
15
21
  PAYLOAD = "payload"
16
22
 
@@ -19,12 +25,16 @@ class Scope(Enum):
19
25
 
20
26
 
21
27
  class AssertionKeyAlg(Enum):
28
+ """Assertion key algorithm enumeration."""
29
+
22
30
  RS256 = auto()
23
31
  HS256 = auto()
24
32
  NOT_DEFINED = auto()
25
33
 
26
34
 
27
35
  class AppliesToState(Enum):
36
+ """Assertion applies-to state enumeration."""
37
+
28
38
  ENCRYPTED = "encrypted"
29
39
  UNENCRYPTED = "unencrypted"
30
40
 
@@ -33,6 +43,8 @@ class AppliesToState(Enum):
33
43
 
34
44
 
35
45
  class BindingMethod(Enum):
46
+ """Assertion binding method enumeration."""
47
+
36
48
  JWS = "jws"
37
49
 
38
50
  def __str__(self):
@@ -40,7 +52,10 @@ class BindingMethod(Enum):
40
52
 
41
53
 
42
54
  class AssertionKey:
55
+ """Assertion signing key configuration."""
56
+
43
57
  def __init__(self, alg: AssertionKeyAlg, key: Any):
58
+ """Initialize assertion key."""
44
59
  self.alg = alg
45
60
  self.key = key
46
61
 
@@ -49,7 +64,10 @@ class AssertionKey:
49
64
 
50
65
 
51
66
  class Statement:
67
+ """Assertion statement with format, schema, and value."""
68
+
52
69
  def __init__(self, format: str, schema: str, value: str):
70
+ """Initialize assertion statement."""
53
71
  self.format = format
54
72
  self.schema = schema
55
73
  self.value = value
@@ -67,6 +85,8 @@ class Statement:
67
85
 
68
86
 
69
87
  class AssertionConfig:
88
+ """TDF assertion configuration."""
89
+
70
90
  def __init__(
71
91
  self,
72
92
  id: str,
@@ -76,6 +96,7 @@ class AssertionConfig:
76
96
  statement: Statement,
77
97
  signing_key: AssertionKey | None = None,
78
98
  ):
99
+ """Initialize assertion configuration."""
79
100
  self.id = id
80
101
  self.type = type
81
102
  self.scope = scope
@@ -1,6 +1,4 @@
1
- """
2
- Asymmetric encryption and decryption utilities for RSA keys in PEM format.
3
- """
1
+ """Asymmetric encryption and decryption utilities for RSA keys in PEM format."""
4
2
 
5
3
  import base64
6
4
  import re
@@ -14,8 +12,7 @@ from .sdk_exceptions import SDKException
14
12
 
15
13
 
16
14
  class AsymDecryption:
17
- """
18
- Provides functionality for asymmetric decryption using an RSA private key.
15
+ """Provides functionality for asymmetric decryption using an RSA private key.
19
16
 
20
17
  Supports both PEM string and key object initialization for flexibility.
21
18
  """
@@ -25,8 +22,7 @@ class AsymDecryption:
25
22
  PRIVATE_KEY_FOOTER = "-----END PRIVATE KEY-----"
26
23
 
27
24
  def __init__(self, private_key_pem: str | None = None, private_key_obj=None):
28
- """
29
- Initialize with either a PEM string or a key object.
25
+ """Initialize with either a PEM string or a key object.
30
26
 
31
27
  Args:
32
28
  private_key_pem: Private key in PEM format (with or without headers)
@@ -34,6 +30,7 @@ class AsymDecryption:
34
30
 
35
31
  Raises:
36
32
  SDKException: If key loading fails
33
+
37
34
  """
38
35
  if private_key_obj is not None:
39
36
  self.private_key = private_key_obj
@@ -60,13 +57,12 @@ class AsymDecryption:
60
57
  decoded, password=None, backend=default_backend()
61
58
  )
62
59
  except Exception as e:
63
- raise SDKException(f"Failed to load private key: {e}")
60
+ raise SDKException(f"Failed to load private key: {e}") from e
64
61
  else:
65
62
  self.private_key = None
66
63
 
67
64
  def decrypt(self, data: bytes) -> bytes:
68
- """
69
- Decrypt data using RSA OAEP with SHA-1.
65
+ """Decrypt data using RSA OAEP with SHA-1.
70
66
 
71
67
  Args:
72
68
  data: Encrypted bytes to decrypt
@@ -76,6 +72,7 @@ class AsymDecryption:
76
72
 
77
73
  Raises:
78
74
  SDKException: If decryption fails or key is not set
75
+
79
76
  """
80
77
  if self.private_key is None:
81
78
  raise SDKException("Failed to decrypt, private key is empty")
@@ -89,12 +86,11 @@ class AsymDecryption:
89
86
  ),
90
87
  )
91
88
  except Exception as e:
92
- raise SDKException(f"Error performing decryption: {e}")
89
+ raise SDKException(f"Error performing decryption: {e}") from e
93
90
 
94
91
 
95
92
  class AsymEncryption:
96
- """
97
- Provides functionality for asymmetric encryption using an RSA public key or certificate in PEM format.
93
+ """Provides functionality for asymmetric encryption using an RSA public key or certificate in PEM format.
98
94
 
99
95
  Supports PEM public keys, X.509 certificates, and pre-loaded key objects.
100
96
  Also handles base64-encoded keys without PEM headers.
@@ -105,8 +101,7 @@ class AsymEncryption:
105
101
  CIPHER_TRANSFORM = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding"
106
102
 
107
103
  def __init__(self, public_key_pem: str | None = None, public_key_obj=None):
108
- """
109
- Initialize with either a PEM string or a key object.
104
+ """Initialize with either a PEM string or a key object.
110
105
 
111
106
  Args:
112
107
  public_key_pem: Public key in PEM format, X.509 certificate, or base64 string
@@ -114,6 +109,7 @@ class AsymEncryption:
114
109
 
115
110
  Raises:
116
111
  SDKException: If key loading fails or key is not RSA
112
+
117
113
  """
118
114
  if public_key_obj is not None:
119
115
  self.public_key = public_key_obj
@@ -141,7 +137,7 @@ class AsymEncryption:
141
137
  decoded, backend=default_backend()
142
138
  )
143
139
  except Exception as e:
144
- raise SDKException(f"Failed to load public key: {e}")
140
+ raise SDKException(f"Failed to load public key: {e}") from e
145
141
  else:
146
142
  self.public_key = None
147
143
 
@@ -152,8 +148,7 @@ class AsymEncryption:
152
148
  raise SDKException("Not an RSA PEM formatted public key")
153
149
 
154
150
  def encrypt(self, data: bytes) -> bytes:
155
- """
156
- Encrypt data using RSA OAEP with SHA-1.
151
+ """Encrypt data using RSA OAEP with SHA-1.
157
152
 
158
153
  Args:
159
154
  data: Plaintext bytes to encrypt
@@ -163,6 +158,7 @@ class AsymEncryption:
163
158
 
164
159
  Raises:
165
160
  SDKException: If encryption fails or key is not set
161
+
166
162
  """
167
163
  if self.public_key is None:
168
164
  raise SDKException("Failed to encrypt, public key is empty")
@@ -176,17 +172,17 @@ class AsymEncryption:
176
172
  ),
177
173
  )
178
174
  except Exception as e:
179
- raise SDKException(f"Error performing encryption: {e}")
175
+ raise SDKException(f"Error performing encryption: {e}") from e
180
176
 
181
177
  def public_key_in_pem_format(self) -> str:
182
- """
183
- Export the public key to PEM format.
178
+ """Export the public key to PEM format.
184
179
 
185
180
  Returns:
186
181
  Public key as PEM-encoded string
187
182
 
188
183
  Raises:
189
184
  SDKException: If export fails
185
+
190
186
  """
191
187
  try:
192
188
  pem = self.public_key.public_bytes(
@@ -195,4 +191,4 @@ class AsymEncryption:
195
191
  )
196
192
  return pem.decode()
197
193
  except Exception as e:
198
- raise SDKException(f"Error exporting public key to PEM: {e}")
194
+ raise SDKException(f"Error exporting public key to PEM: {e}") from e
@@ -1,10 +1,11 @@
1
+ """Authentication header management."""
2
+
1
3
  from dataclasses import dataclass
2
4
 
3
5
 
4
6
  @dataclass
5
7
  class AuthHeaders:
6
- """
7
- Represents authentication headers used in token-based authorization.
8
+ """Represents authentication headers used in token-based authorization.
8
9
  This class holds authorization and DPoP (Demonstrating Proof of Possession) headers
9
10
  that are used in token-based API requests.
10
11
  """
@@ -13,19 +14,19 @@ class AuthHeaders:
13
14
  dpop_header: str = ""
14
15
 
15
16
  def get_auth_header(self) -> str:
16
- """Returns the authorization header."""
17
+ """Get the authorization header."""
17
18
  return self.auth_header
18
19
 
19
20
  def get_dpop_header(self) -> str:
20
- """Returns the DPoP header."""
21
+ """Get the DPoP header."""
21
22
  return self.dpop_header
22
23
 
23
24
  def to_dict(self) -> dict[str, str]:
24
- """
25
- Convert authentication headers to a dictionary for use with HTTP clients.
25
+ """Convert authentication headers to a dictionary for use with HTTP clients.
26
26
 
27
27
  Returns:
28
28
  Dictionary with 'Authorization' header and optionally 'DPoP' header
29
+
29
30
  """
30
31
  headers = {"Authorization": self.auth_header}
31
32
  if self.dpop_header:
@@ -1,3 +1,5 @@
1
+ """Utilities for automatic SDK configuration."""
2
+
1
3
  import re
2
4
  import urllib.parse
3
5
  from dataclasses import dataclass
@@ -6,6 +8,8 @@ from typing import Any
6
8
 
7
9
  # RuleType constants
8
10
  class RuleType:
11
+ """Rule type constants for attribute hierarchy."""
12
+
9
13
  HIERARCHY = "hierarchy"
10
14
  ALL_OF = "allOf"
11
15
  ANY_OF = "anyOf"
@@ -15,6 +19,8 @@ class RuleType:
15
19
 
16
20
  @dataclass(frozen=True)
17
21
  class KeySplitStep:
22
+ """Key split step information."""
23
+
18
24
  kas: str
19
25
  splitID: str
20
26
 
@@ -31,21 +37,26 @@ class KeySplitStep:
31
37
 
32
38
 
33
39
  class AutoConfigureException(Exception):
40
+ """Exception for auto-configuration errors."""
41
+
34
42
  pass
35
43
 
36
44
 
37
45
  class AttributeNameFQN:
46
+ """Fully qualified attribute name."""
47
+
38
48
  def __init__(self, url: str):
49
+ """Initialize attribute name from URL."""
39
50
  pattern = re.compile(r"^(https?://[\w./-]+)/attr/([^/\s]*)$")
40
51
  matcher = pattern.match(url)
41
52
  if not matcher or not matcher.group(1) or not matcher.group(2):
42
53
  raise AutoConfigureException("invalid type: attribute regex fail")
43
54
  try:
44
55
  urllib.parse.unquote(matcher.group(2))
45
- except Exception:
56
+ except Exception as err:
46
57
  raise AutoConfigureException(
47
58
  f"invalid type: error in attribute name [{matcher.group(2)}]"
48
- )
59
+ ) from err
49
60
  self.url = url
50
61
  self.key = url.lower()
51
62
 
@@ -76,12 +87,15 @@ class AttributeNameFQN:
76
87
  raise AutoConfigureException("invalid attribute")
77
88
  try:
78
89
  return urllib.parse.unquote(matcher.group(1))
79
- except Exception:
80
- raise AutoConfigureException("invalid type")
90
+ except Exception as err:
91
+ raise AutoConfigureException("invalid type") from err
81
92
 
82
93
 
83
94
  class AttributeValueFQN:
95
+ """Fully qualified attribute value."""
96
+
84
97
  def __init__(self, url: str):
98
+ """Initialize attribute value from URL."""
85
99
  pattern = re.compile(r"^(https?://[\w./-]+)/attr/(\S*)/value/(\S*)$")
86
100
  matcher = pattern.match(url)
87
101
  if (
@@ -96,8 +110,10 @@ class AttributeValueFQN:
96
110
  try:
97
111
  urllib.parse.unquote(matcher.group(2))
98
112
  urllib.parse.unquote(matcher.group(3))
99
- except Exception:
100
- raise AutoConfigureException("invalid type: error in attribute or value")
113
+ except Exception as err:
114
+ raise AutoConfigureException(
115
+ "invalid type: error in attribute or value"
116
+ ) from err
101
117
  self.url = url
102
118
  self.key = url.lower()
103
119
 
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- """
3
- OpenTDF Python CLI
2
+ """OpenTDF Python CLI.
4
3
 
5
4
  A command-line interface for encrypting and decrypting files using OpenTDF.
6
5
  Provides encrypt, decrypt, and inspect commands similar to the otdfctl CLI.
@@ -36,6 +35,7 @@ class CLIError(Exception):
36
35
  """Custom exception for CLI errors."""
37
36
 
38
37
  def __init__(self, level: str, message: str, cause: Exception | None = None):
38
+ """Initialize CLI error."""
39
39
  self.level = level
40
40
  self.message = message
41
41
  self.cause = cause
@@ -105,11 +105,11 @@ def load_client_credentials(creds_file_path: str) -> tuple[str, str]:
105
105
  except json.JSONDecodeError as e:
106
106
  raise CLIError(
107
107
  "CRITICAL", f"Invalid JSON in credentials file {creds_file_path}: {e}"
108
- )
108
+ ) from e
109
109
  except Exception as e:
110
110
  raise CLIError(
111
111
  "CRITICAL", f"Error reading credentials file {creds_file_path}: {e}"
112
- )
112
+ ) from e
113
113
 
114
114
 
115
115
  def build_sdk(args) -> SDK:
@@ -525,7 +525,7 @@ Where creds.json contains:
525
525
 
526
526
 
527
527
  def main():
528
- """Main CLI entry point."""
528
+ """Execute the CLI entry point."""
529
529
  parser = create_parser()
530
530
  args = parser.parse_args()
531
531