otdf-python 0.3.2__tar.gz → 0.3.4__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 (254) hide show
  1. {otdf_python-0.3.2 → otdf_python-0.3.4}/.github/check_entitlements.sh +0 -1
  2. {otdf_python-0.3.2 → otdf_python-0.3.4}/.github/workflows/build-python.yaml +0 -3
  3. {otdf_python-0.3.2 → otdf_python-0.3.4}/.pre-commit-config.yaml +1 -1
  4. otdf_python-0.3.4/.release-please-manifest.json +3 -0
  5. {otdf_python-0.3.2 → otdf_python-0.3.4}/CHANGELOG.md +18 -0
  6. {otdf_python-0.3.2 → otdf_python-0.3.4}/PKG-INFO +1 -5
  7. {otdf_python-0.3.2 → otdf_python-0.3.4}/README.md +0 -4
  8. otdf_python-0.3.4/docs/CONNECT_RPC.md +156 -0
  9. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/README.md +7 -7
  10. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/pyproject.toml +1 -1
  11. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/scripts/build_connect_proto.sh +1 -1
  12. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/scripts/generate_connect_proto.py +6 -6
  13. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/uv.lock +1 -1
  14. {otdf_python-0.3.2 → otdf_python-0.3.4}/pyproject.toml +2 -1
  15. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/auth_headers.py +13 -1
  16. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/cli.py +9 -9
  17. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/header.py +2 -2
  18. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/kas_connect_rpc_client.py +7 -1
  19. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/nanotdf.py +1 -1
  20. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/sdk.py +6 -84
  21. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/sdk_builder.py +5 -37
  22. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/integration/conftest.py +1 -1
  23. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/integration/otdfctl_only/test_otdfctl_generated_fixtures.py +2 -2
  24. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/integration/otdfctl_to_python/test_cli_comparison.py +2 -2
  25. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/integration/otdfctl_to_python/test_tdf_reader_integration.py +7 -7
  26. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/integration/test_cli_integration.py +4 -4
  27. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/integration/test_cli_tdf_validation.py +3 -3
  28. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/integration/test_pe_interaction.py +3 -3
  29. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/support_common.py +2 -2
  30. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_cli.py +5 -6
  31. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_crypto_utils.py +1 -1
  32. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_inner_classes.py +21 -0
  33. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_manifest_format.py +2 -2
  34. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_sdk.py +0 -3
  35. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_sdk_builder.py +5 -5
  36. otdf_python-0.3.4/tests/test_sdk_mock.py +31 -0
  37. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_sdk_tdf_integration.py +4 -4
  38. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_tdf.py +1 -1
  39. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_tdf_reader.py +2 -2
  40. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_url_normalization.py +0 -6
  41. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_validate_otdf_python.py +4 -4
  42. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_zip_reader.py +2 -1
  43. {otdf_python-0.3.2 → otdf_python-0.3.4}/uv.lock +21 -21
  44. otdf_python-0.3.2/.release-please-manifest.json +0 -3
  45. otdf_python-0.3.2/docs/CONNECT_RPC_MIGRATION.md +0 -283
  46. otdf_python-0.3.2/docs/PROTOBUF_SETUP.md +0 -135
  47. otdf_python-0.3.2/tests/test_sdk_mock.py +0 -58
  48. {otdf_python-0.3.2 → otdf_python-0.3.4}/.github/start_opentdf_docker.sh +0 -0
  49. {otdf_python-0.3.2 → otdf_python-0.3.4}/.github/workflows/platform-integration-test.yaml +0 -0
  50. {otdf_python-0.3.2 → otdf_python-0.3.4}/.github/workflows/release-please.yaml +0 -0
  51. {otdf_python-0.3.2 → otdf_python-0.3.4}/.github/workflows/test-suite.yaml +0 -0
  52. {otdf_python-0.3.2 → otdf_python-0.3.4}/.gitignore +0 -0
  53. {otdf_python-0.3.2 → otdf_python-0.3.4}/.release-please-config-develop.json +0 -0
  54. {otdf_python-0.3.2 → otdf_python-0.3.4}/.release-please-config.json +0 -0
  55. {otdf_python-0.3.2 → otdf_python-0.3.4}/.release-please-manifest-develop.json +0 -0
  56. {otdf_python-0.3.2 → otdf_python-0.3.4}/.vscode/extensions.json +0 -0
  57. {otdf_python-0.3.2 → otdf_python-0.3.4}/.vscode/settings.json +0 -0
  58. {otdf_python-0.3.2 → otdf_python-0.3.4}/LICENSE +0 -0
  59. {otdf_python-0.3.2 → otdf_python-0.3.4}/conftest.py +0 -0
  60. {otdf_python-0.3.2 → otdf_python-0.3.4}/docs/DEVELOPING.md +0 -0
  61. {otdf_python-0.3.2 → otdf_python-0.3.4}/docs/LEGACY_VERSION.md +0 -0
  62. {otdf_python-0.3.2 → otdf_python-0.3.4}/docs/RELEASES.md +0 -0
  63. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/buf.gen.yaml +0 -0
  64. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/buf.lock +0 -0
  65. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/buf.yaml +0 -0
  66. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/authorization/authorization.proto +0 -0
  67. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/authorization/v2/authorization.proto +0 -0
  68. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/common/common.proto +0 -0
  69. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/entity/entity.proto +0 -0
  70. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/entityresolution/entity_resolution.proto +0 -0
  71. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/entityresolution/v2/entity_resolution.proto +0 -0
  72. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/kas/kas.proto +0 -0
  73. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/logger/audit/test.proto +0 -0
  74. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/policy/actions/actions.proto +0 -0
  75. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/policy/attributes/attributes.proto +0 -0
  76. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/policy/kasregistry/key_access_server_registry.proto +0 -0
  77. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/policy/keymanagement/key_management.proto +0 -0
  78. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/policy/namespaces/namespaces.proto +0 -0
  79. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/policy/objects.proto +0 -0
  80. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/policy/registeredresources/registered_resources.proto +0 -0
  81. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/policy/resourcemapping/resource_mapping.proto +0 -0
  82. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/policy/selectors.proto +0 -0
  83. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/policy/subjectmapping/subject_mapping.proto +0 -0
  84. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/policy/unsafe/unsafe.proto +0 -0
  85. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/proto-files/wellknownconfiguration/wellknown_configuration.proto +0 -0
  86. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/scripts/setup_connect_rpc.py +0 -0
  87. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/__init__.py +0 -0
  88. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/authorization/__init__.py +0 -0
  89. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/authorization/authorization_pb2.py +0 -0
  90. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/authorization/authorization_pb2.pyi +0 -0
  91. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/authorization/authorization_pb2_connect.py +0 -0
  92. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/authorization/v2/authorization_pb2.py +0 -0
  93. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/authorization/v2/authorization_pb2.pyi +0 -0
  94. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/authorization/v2/authorization_pb2_connect.py +0 -0
  95. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/common/__init__.py +0 -0
  96. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/common/common_pb2.py +0 -0
  97. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/common/common_pb2.pyi +0 -0
  98. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/entity/__init__.py +0 -0
  99. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/entity/entity_pb2.py +0 -0
  100. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/entity/entity_pb2.pyi +0 -0
  101. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/entityresolution/__init__.py +0 -0
  102. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/entityresolution/entity_resolution_pb2.py +0 -0
  103. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/entityresolution/entity_resolution_pb2.pyi +0 -0
  104. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/entityresolution/entity_resolution_pb2_connect.py +0 -0
  105. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/entityresolution/v2/entity_resolution_pb2.py +0 -0
  106. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/entityresolution/v2/entity_resolution_pb2.pyi +0 -0
  107. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/entityresolution/v2/entity_resolution_pb2_connect.py +0 -0
  108. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/kas/__init__.py +0 -0
  109. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/kas/kas_pb2.py +0 -0
  110. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/kas/kas_pb2.pyi +0 -0
  111. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/kas/kas_pb2_connect.py +0 -0
  112. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/__init__.py +0 -0
  113. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/authorization/authorization_pb2_grpc.py +0 -0
  114. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/authorization/v2/authorization_pb2_grpc.py +0 -0
  115. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/common/common_pb2_grpc.py +0 -0
  116. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/entity/entity_pb2_grpc.py +0 -0
  117. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/entityresolution/entity_resolution_pb2_grpc.py +0 -0
  118. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/entityresolution/v2/entity_resolution_pb2_grpc.py +0 -0
  119. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/kas/kas_pb2_grpc.py +0 -0
  120. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/logger/audit/test_pb2_grpc.py +0 -0
  121. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/actions/actions_pb2_grpc.py +0 -0
  122. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/attributes/attributes_pb2_grpc.py +0 -0
  123. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/kasregistry/key_access_server_registry_pb2_grpc.py +0 -0
  124. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/keymanagement/key_management_pb2_grpc.py +0 -0
  125. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/namespaces/namespaces_pb2_grpc.py +0 -0
  126. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/objects_pb2_grpc.py +0 -0
  127. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/registeredresources/registered_resources_pb2_grpc.py +0 -0
  128. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/resourcemapping/resource_mapping_pb2_grpc.py +0 -0
  129. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/selectors_pb2_grpc.py +0 -0
  130. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/subjectmapping/subject_mapping_pb2_grpc.py +0 -0
  131. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/policy/unsafe/unsafe_pb2_grpc.py +0 -0
  132. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/legacy_grpc/wellknownconfiguration/wellknown_configuration_pb2_grpc.py +0 -0
  133. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/logger/__init__.py +0 -0
  134. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/logger/audit/test_pb2.py +0 -0
  135. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/logger/audit/test_pb2.pyi +0 -0
  136. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/__init__.py +0 -0
  137. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/actions/actions_pb2.py +0 -0
  138. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/actions/actions_pb2.pyi +0 -0
  139. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/actions/actions_pb2_connect.py +0 -0
  140. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/attributes/attributes_pb2.py +0 -0
  141. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/attributes/attributes_pb2.pyi +0 -0
  142. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/attributes/attributes_pb2_connect.py +0 -0
  143. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2.py +0 -0
  144. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2.pyi +0 -0
  145. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/kasregistry/key_access_server_registry_pb2_connect.py +0 -0
  146. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/keymanagement/key_management_pb2.py +0 -0
  147. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/keymanagement/key_management_pb2.pyi +0 -0
  148. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/keymanagement/key_management_pb2_connect.py +0 -0
  149. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/namespaces/namespaces_pb2.py +0 -0
  150. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/namespaces/namespaces_pb2.pyi +0 -0
  151. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/namespaces/namespaces_pb2_connect.py +0 -0
  152. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/objects_pb2.py +0 -0
  153. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/objects_pb2.pyi +0 -0
  154. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/registeredresources/registered_resources_pb2.py +0 -0
  155. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/registeredresources/registered_resources_pb2.pyi +0 -0
  156. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/registeredresources/registered_resources_pb2_connect.py +0 -0
  157. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/resourcemapping/resource_mapping_pb2.py +0 -0
  158. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/resourcemapping/resource_mapping_pb2.pyi +0 -0
  159. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/resourcemapping/resource_mapping_pb2_connect.py +0 -0
  160. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/selectors_pb2.py +0 -0
  161. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/selectors_pb2.pyi +0 -0
  162. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/subjectmapping/subject_mapping_pb2.py +0 -0
  163. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/subjectmapping/subject_mapping_pb2.pyi +0 -0
  164. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/subjectmapping/subject_mapping_pb2_connect.py +0 -0
  165. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/unsafe/unsafe_pb2.py +0 -0
  166. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/unsafe/unsafe_pb2.pyi +0 -0
  167. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/policy/unsafe/unsafe_pb2_connect.py +0 -0
  168. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/wellknownconfiguration/__init__.py +0 -0
  169. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2.py +0 -0
  170. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2.pyi +0 -0
  171. {otdf_python-0.3.2 → otdf_python-0.3.4}/otdf-python-proto/src/otdf_python_proto/wellknownconfiguration/wellknown_configuration_pb2_connect.py +0 -0
  172. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/__init__.py +0 -0
  173. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/__main__.py +0 -0
  174. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/address_normalizer.py +0 -0
  175. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/aesgcm.py +0 -0
  176. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/assertion_config.py +0 -0
  177. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/asym_crypto.py +0 -0
  178. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/asym_decryption.py +0 -0
  179. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/asym_encryption.py +0 -0
  180. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/autoconfigure_utils.py +0 -0
  181. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/collection_store.py +0 -0
  182. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/collection_store_impl.py +0 -0
  183. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/config.py +0 -0
  184. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/connect_client.py +0 -0
  185. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/constants.py +0 -0
  186. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/crypto_utils.py +0 -0
  187. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/dpop.py +0 -0
  188. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/ecc_mode.py +0 -0
  189. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/eckeypair.py +0 -0
  190. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/invalid_zip_exception.py +0 -0
  191. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/kas_client.py +0 -0
  192. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/kas_info.py +0 -0
  193. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/kas_key_cache.py +0 -0
  194. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/key_type.py +0 -0
  195. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/key_type_constants.py +0 -0
  196. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/manifest.py +0 -0
  197. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/nanotdf_ecdsa_struct.py +0 -0
  198. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/nanotdf_type.py +0 -0
  199. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/policy_binding_serializer.py +0 -0
  200. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/policy_info.py +0 -0
  201. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/policy_object.py +0 -0
  202. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/policy_stub.py +0 -0
  203. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/resource_locator.py +0 -0
  204. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/sdk_exceptions.py +0 -0
  205. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/symmetric_and_payload_config.py +0 -0
  206. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/tdf.py +0 -0
  207. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/tdf_reader.py +0 -0
  208. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/tdf_writer.py +0 -0
  209. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/token_source.py +0 -0
  210. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/version.py +0 -0
  211. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/zip_reader.py +0 -0
  212. {otdf_python-0.3.2 → otdf_python-0.3.4}/src/otdf_python/zip_writer.py +0 -0
  213. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/__init__.py +0 -0
  214. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/config_pydantic.py +0 -0
  215. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/integration/otdfctl_to_python/test_cli_decrypt.py +0 -0
  216. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/integration/otdfctl_to_python/test_cli_inspect.py +0 -0
  217. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/integration/python_only/test_kas_client_integration.py +0 -0
  218. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/integration/support_sdk.py +0 -0
  219. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/integration/test_data/empty_file.txt +0 -0
  220. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/integration/test_data/sample_binary.png +0 -0
  221. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/integration/test_data/sample_text.txt +0 -0
  222. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/integration/test_data/sample_with_attributes.txt +0 -0
  223. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/mock_crypto.py +0 -0
  224. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/server_logs.py +0 -0
  225. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/support_cli_args.py +0 -0
  226. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/support_otdfctl.py +0 -0
  227. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/support_otdfctl_args.py +0 -0
  228. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_address_normalizer.py +0 -0
  229. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_aesgcm.py +0 -0
  230. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_assertion_config.py +0 -0
  231. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_asym_encryption.py +0 -0
  232. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_autoconfigure_utils.py +0 -0
  233. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_collection_store.py +0 -0
  234. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_config.py +0 -0
  235. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_eckeypair.py +0 -0
  236. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_header.py +0 -0
  237. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_kas_client.py +0 -0
  238. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_kas_key_cache.py +0 -0
  239. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_kas_key_management.py +0 -0
  240. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_key_type.py +0 -0
  241. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_log_collection.py +0 -0
  242. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_manifest.py +0 -0
  243. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_nanotdf.py +0 -0
  244. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_nanotdf_ecdsa_struct.py +0 -0
  245. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_nanotdf_integration.py +0 -0
  246. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_nanotdf_type.py +0 -0
  247. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_policy_object.py +0 -0
  248. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_sdk_exceptions.py +0 -0
  249. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_tdf_key_management.py +0 -0
  250. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_tdf_writer.py +0 -0
  251. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_token_source.py +0 -0
  252. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_use_plaintext_flow.py +0 -0
  253. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_version.py +0 -0
  254. {otdf_python-0.3.2 → otdf_python-0.3.4}/tests/test_zip_writer.py +0 -0
@@ -17,7 +17,6 @@ echo ""
17
17
 
18
18
  get_token() {
19
19
  curl -k --location "$TOKEN_URL" \
20
- --header "X-VirtruPubKey;" \
21
20
  --header "Content-Type: application/x-www-form-urlencoded" \
22
21
  --data-urlencode "grant_type=client_credentials" \
23
22
  --data-urlencode "client_id=$OTDF_CLIENT" \
@@ -1,9 +1,6 @@
1
1
  # Build otdf-python wheel using uv and output the wheel path for downstream workflows
2
2
  name: "Build Python Wheel"
3
3
  on:
4
- push:
5
- branches:
6
- - chore/rewrite
7
4
  pull_request:
8
5
 
9
6
  jobs:
@@ -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.12.12
37
+ rev: v0.13.3
38
38
  hooks:
39
39
  # Run the linter.
40
40
  - id: ruff-check
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.3.4"
3
+ }
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.4](https://github.com/b-long/opentdf-python-sdk/compare/otdf-python-v0.3.3...otdf-python-v0.3.4) (2025-10-04)
4
+
5
+ ### Chores
6
+
7
+ * chore: remove placeholders ([#110](https://github.com/b-long/opentdf-python-sdk/issues/110))
8
+
9
+
10
+ ### Bug Fixes
11
+
12
+ * update ruff ([#108](https://github.com/b-long/opentdf-python-sdk/issues/108)) ([5e4c796](https://github.com/b-long/opentdf-python-sdk/commit/5e4c796a8c1fc10b206cd2769f7c8548903ad3c1))
13
+
14
+ ## [0.3.3](https://github.com/b-long/opentdf-python-sdk/compare/otdf-python-v0.3.2...otdf-python-v0.3.3) (2025-09-17)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * improve docs ([#106](https://github.com/b-long/opentdf-python-sdk/issues/106)) ([49aa4ae](https://github.com/b-long/opentdf-python-sdk/commit/49aa4aea5e576c20b3e26c852331de8b0469742f))
20
+
3
21
  ## [0.3.2](https://github.com/b-long/opentdf-python-sdk/compare/otdf-python-v0.3.1...otdf-python-v0.3.2) (2025-09-12)
4
22
 
5
23
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: otdf-python
3
- Version: 0.3.2
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
@@ -102,8 +102,6 @@ with open("encrypted.tdf", "wb") as f:
102
102
  ### Decrypt Data
103
103
 
104
104
  ```python
105
- from otdf_python.tdf import TDFReaderConfig
106
-
107
105
  # Read encrypted TDF file
108
106
  with open("encrypted.tdf", "rb") as f:
109
107
  encrypted_data = f.read()
@@ -116,8 +114,6 @@ decrypted_data = tdf_reader.payload
116
114
  with open("decrypted.txt", "wb") as f:
117
115
  f.write(decrypted_data)
118
116
 
119
- # Don't forget to close the SDK when done
120
- sdk.close()
121
117
  ```
122
118
 
123
119
  ## Project Structure
@@ -83,8 +83,6 @@ with open("encrypted.tdf", "wb") as f:
83
83
  ### Decrypt Data
84
84
 
85
85
  ```python
86
- from otdf_python.tdf import TDFReaderConfig
87
-
88
86
  # Read encrypted TDF file
89
87
  with open("encrypted.tdf", "rb") as f:
90
88
  encrypted_data = f.read()
@@ -97,8 +95,6 @@ decrypted_data = tdf_reader.payload
97
95
  with open("decrypted.txt", "wb") as f:
98
96
  f.write(decrypted_data)
99
97
 
100
- # Don't forget to close the SDK when done
101
- sdk.close()
102
98
  ```
103
99
 
104
100
  ## Project Structure
@@ -0,0 +1,156 @@
1
+ # Connect RPC in OpenTDF Python SDK
2
+
3
+ This document describes the Connect RPC implementation in the OpenTDF Python SDK, which provides a modern HTTP-friendly alternative to traditional gRPC.
4
+
5
+ ## Overview
6
+
7
+ Connect RPC is a protocol that brings the benefits of RPC to HTTP APIs. It's designed to be:
8
+ - **HTTP-compatible**: Works with standard HTTP infrastructure
9
+ - **Type-safe**: Generated from Protocol Buffer definitions
10
+ - **Efficient**: Binary protocol with JSON fallback
11
+ - **Simple**: Easy to debug and integrate
12
+
13
+ ## Architecture
14
+
15
+ The SDK uses a two-module structure for protocol buffer generation:
16
+
17
+ - **Main SDK**: `src/otdf_python/` - Core SDK functionality
18
+ - **Protocol Generation**: `otdf-python-proto/` - Generated Connect RPC and protobuf files
19
+
20
+ ### Generated Files
21
+
22
+ Connect RPC generates the following files in `otdf-python-proto/src/otdf_python_proto/`:
23
+
24
+ - `*_connect.py` - Connect RPC client implementations (recommended)
25
+ - `*_pb2.py` - Protocol buffer message definitions
26
+ - `legacy_grpc/*_pb2_grpc.py` - Traditional gRPC clients (backward compatibility)
27
+
28
+ ## Usage
29
+
30
+ ### Client Creation
31
+
32
+ Connect RPC clients are created using the generated `*_connect.py` modules:
33
+
34
+ ```python
35
+ from otdf_python_proto.kas import kas_connect
36
+ from otdf_python_proto.policy import policy_connect
37
+
38
+ # Create Connect RPC clients
39
+ kas_client = kas_connect.KeyAccessServiceClient(base_url="https://example.com")
40
+ policy_client = policy_connect.PolicyServiceClient(base_url="https://your-policy-endpoint")
41
+ ```
42
+
43
+ ### Authentication
44
+
45
+ Connect RPC clients support standard HTTP authentication:
46
+
47
+ ```python
48
+ import httpx
49
+
50
+ # Create authenticated HTTP client, assuming `token` holds your auth token
51
+ http_client = httpx.Client(
52
+ headers={"Authorization": f"Bearer {token}"}
53
+ )
54
+
55
+ # Use with Connect RPC client
56
+ kas_client = kas_connect.KeyAccessServiceClient(
57
+ base_url="https://example.com",
58
+ http_client=http_client
59
+ )
60
+ ```
61
+
62
+ ## Regenerating Connect RPC Files
63
+
64
+ To regenerate the Connect RPC and protobuf files:
65
+
66
+ ```bash
67
+ cd otdf-python-proto
68
+ uv run python scripts/generate_connect_proto.py
69
+ ```
70
+
71
+ ### Download Fresh Proto Files
72
+
73
+ To download the latest protocol definitions:
74
+
75
+ ```bash
76
+ cd otdf-python-proto
77
+ uv run python scripts/generate_connect_proto.py --download
78
+ ```
79
+
80
+ ### Requirements
81
+
82
+ - `buf` tool: `brew install bufbuild/buf/buf` (or see [official installation guide](https://buf.build/docs/installation))
83
+ - Python dependencies managed by `uv`
84
+
85
+ ## Benefits Over gRPC
86
+
87
+ 1. **HTTP Compatibility**: Works with load balancers, proxies, and other HTTP infrastructure
88
+ 2. **Debugging**: Easy to inspect with standard HTTP tools
89
+ 3. **Flexibility**: Supports both binary and JSON encoding
90
+ 4. **Simplicity**: No special HTTP/2 requirements
91
+
92
+ ## Migration from gRPC
93
+
94
+ If migrating from legacy gRPC clients:
95
+
96
+ 1. Replace `*_pb2_grpc.py` imports with `*_connect.py`
97
+ 2. Update client instantiation to use base URLs instead of channels
98
+ 3. Leverage HTTP client features for authentication and configuration
99
+
100
+ ## Testing
101
+
102
+ Connect RPC clients can be easily mocked and tested using standard HTTP testing tools:
103
+
104
+ ```python
105
+ import httpx
106
+ import respx
107
+ from otdf_python_proto.kas import kas_pb2, kas_connect
108
+
109
+ @respx.mock
110
+ def test_connect_rpc_client():
111
+ # 1. Create a sample protobuf response message
112
+ expected_response = kas_pb2.RewrapResponse(
113
+ entity_wrapped_key=b'some-unwrapped-key'
114
+ )
115
+
116
+ # 2. Mock the correct Connect RPC endpoint URL
117
+ respx.post("https://example.com/kas.AccessService/Rewrap").mock(
118
+ return_value=httpx.Response(
119
+ 200,
120
+ # 3. Return the serialized protobuf message as content
121
+ content=expected_response.SerializeToString(),
122
+ headers={'Content-Type': 'application/proto'}
123
+ )
124
+ )
125
+
126
+ client = kas_connect.KeyAccessServiceClient(base_url="https://example.com")
127
+ # Test client calls...
128
+ ```
129
+
130
+ ## Error Handling
131
+
132
+ Connect RPC provides structured error handling through standard HTTP status codes and error details:
133
+
134
+ ```python
135
+ from connectrpc import ConnectError
136
+
137
+ try:
138
+ # Assuming `kas_client` and `request` are defined as in previous examples
139
+ response = kas_client.rewrap(request)
140
+ except ConnectError as e:
141
+ print(f"Connect RPC error: {e.code} - {e.message}")
142
+ # Handle specific error types
143
+ ```
144
+
145
+ ## Performance Considerations
146
+
147
+ - Use connection pooling with `httpx.Client` for better performance
148
+ - Configure appropriate timeouts for your use case
149
+ - Consider using binary encoding for high-throughput scenarios
150
+
151
+ ## Additional Resources
152
+
153
+ For more information, see:
154
+ - [Connect RPC Documentation](https://connectrpc.com/docs/)
155
+ - [Connect Python Repository](https://github.com/connectrpc/connect-python)
156
+ - [OpenTDF Platform](https://github.com/opentdf/platform)
@@ -12,12 +12,12 @@ This project now supports **Connect RPC**, a modern HTTP-friendly alternative to
12
12
  - 🚀 **Simplified deployment** - No special gRPC infrastructure required
13
13
  - 📊 **Better observability** - Standard HTTP status codes and headers
14
14
 
15
- See [CONNECT_RPC_MIGRATION.md](../CONNECT_RPC_MIGRATION.md) for migration guide and examples.
15
+ See [CONNECT_RPC.md](../docs/CONNECT_RPC.md) for additional information.
16
16
 
17
17
  ## Structure
18
18
 
19
19
  - `proto-files/`: Contains the raw .proto files downloaded from the OpenTDF platform
20
- - `generated/`: Contains the generated Python protobuf and Connect RPC client files
20
+ - `src/otdf_python_proto/`: Contains the generated Python protobuf and Connect RPC client files
21
21
  - `scripts/`: Contains build scripts for generating protobuf and Connect RPC files
22
22
  - `buf.yaml`: Buf configuration for proto validation and management
23
23
  - `buf.gen.yaml`: Buf generation configuration for Connect RPC and protobuf
@@ -40,10 +40,10 @@ Or use the convenience script:
40
40
  ```
41
41
 
42
42
  This generates:
43
- - `generated/*_connect.py` - Connect RPC clients (preferred)
44
- - `generated/*_pb2.py` - Standard protobuf classes
45
- - `generated/*_pb2.pyi` - Type stubs for better IDE support
46
- - `generated/legacy_grpc/*_pb2_grpc.py` - Legacy gRPC clients (backward compatibility)
43
+ - `src/otdf_python_proto/**/*_connect.py` - Connect RPC clients (preferred)
44
+ - `src/otdf_python_proto/**/*_pb2.py` - Standard protobuf classes
45
+ - `src/otdf_python_proto/**/*_pb2.pyi` - Type stubs for better IDE support
46
+ - `src/otdf_python_proto/legacy_grpc/**/*_pb2_grpc.py` - Legacy gRPC clients (backward compatibility)
47
47
 
48
48
  ### Legacy gRPC Generation
49
49
 
@@ -158,7 +158,7 @@ response = client.GetPolicy(request)
158
158
 
159
159
  If you're migrating from traditional gRPC clients to Connect RPC:
160
160
 
161
- 1. Read the [Connect RPC Migration Guide](../CONNECT_RPC_MIGRATION.md)
161
+ 1. Read the [Connect RPC Migration Guide](../docs/CONNECT_RPC.md)
162
162
  2. Run the Connect RPC generation: `./scripts/build_connect_proto.sh` (or from the submodule: `cd otdf-python-proto && uv run python scripts/generate_connect_proto.py`)
163
163
  3. Update your client code to use `*_connect.py` modules
164
164
  4. Test with your authentication and deployment setup
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "otdf-python-proto"
3
- version = "0.3.2"
3
+ version = "0.3.4"
4
4
  description = "Generated protobuf files for OpenTDF Python SDK"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -87,7 +87,7 @@ if [[ $? -eq 0 ]]; then
87
87
  echo " python examples/connect_rpc_client_example.py"
88
88
  echo ""
89
89
  echo "For more information, see:"
90
- echo " - CONNECT_RPC_MIGRATION.md"
90
+ echo " - docs/CONNECT_RPC.md"
91
91
  echo " - https://connectrpc.com/docs/"
92
92
  else
93
93
  echo "✗ Connect RPC generation failed!"
@@ -96,10 +96,10 @@ def copy_opentdf_proto_files(proto_gen_dir: Path) -> bool:
96
96
  print(f" Copying {relative_path}...")
97
97
 
98
98
  # Copy the file content
99
- with open(proto_file) as src:
99
+ with proto_file.open() as src:
100
100
  content = src.read()
101
101
 
102
- with open(dest_path, "w") as dst:
102
+ with dest_path.open("w") as dst:
103
103
  dst.write(content)
104
104
 
105
105
  copied_files += 1
@@ -155,7 +155,7 @@ def run_buf_generate(proto_gen_dir: Path) -> bool:
155
155
 
156
156
  # Update buf.gen.yaml with the correct path
157
157
  buf_gen_path = proto_gen_dir / "buf.gen.yaml"
158
- with open(buf_gen_path) as f:
158
+ with buf_gen_path.open() as f:
159
159
  content = f.read()
160
160
 
161
161
  # Replace the local plugin path
@@ -163,7 +163,7 @@ def run_buf_generate(proto_gen_dir: Path) -> bool:
163
163
  "- local: protoc-gen-connect_python", f"- local: {connect_plugin_path}"
164
164
  )
165
165
 
166
- with open(buf_gen_path, "w") as f:
166
+ with buf_gen_path.open("w") as f:
167
167
  f.write(updated_content)
168
168
 
169
169
  # Run buf generate
@@ -221,7 +221,7 @@ def _fix_ignore_if_default_value(proto_files_dir):
221
221
  # Iterate all .proto files in the directory
222
222
  for proto_file in proto_files_dir.glob("**/*.proto"):
223
223
  try:
224
- with open(proto_file, "r") as file: # noqa: UP015
224
+ with proto_file.open("r") as file:
225
225
  content = file.read()
226
226
 
227
227
  # Replace the old enum value with the new one
@@ -230,7 +230,7 @@ def _fix_ignore_if_default_value(proto_files_dir):
230
230
  )
231
231
 
232
232
  # Write the updated content back to the file
233
- with open(proto_file, "w") as file:
233
+ with proto_file.open("w") as file:
234
234
  file.write(updated_content)
235
235
 
236
236
  print(f"Updated {proto_file.name} to use IGNORE_IF_ZERO_VALUE")
@@ -481,7 +481,7 @@ wheels = [
481
481
 
482
482
  [[package]]
483
483
  name = "otdf-python-proto"
484
- version = "0.3.2"
484
+ version = "0.3.4"
485
485
  source = { editable = "." }
486
486
  dependencies = [
487
487
  { name = "connect-python", extra = ["compiler"] },
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "otdf-python"
3
- version = "0.3.2"
3
+ version = "0.3.4"
4
4
  description = "Unofficial OpenTDF SDK for Python"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -73,6 +73,7 @@ lint.select = [
73
73
  "I",
74
74
  # Performance-related rules
75
75
  "PERF", # Ruff's performance rules
76
+ "PTH", # pathlib (path handling)
76
77
  # Additional useful rules
77
78
  "UP", # pyupgrade (modern Python features)
78
79
  "SIM", # flake8-simplify (simplifications)
@@ -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
@@ -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"
@@ -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):
@@ -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: