Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/check_entitlements.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ echo ""

get_token() {
curl -k --location "$TOKEN_URL" \
--header "X-VirtruPubKey;" \
--header "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "client_id=$OTDF_CLIENT" \
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ repos:

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.12.12
rev: v0.13.1
hooks:
# Run the linter.
- id: ruff-check
Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,6 @@ decrypted_data = tdf_reader.payload
with open("decrypted.txt", "wb") as f:
f.write(decrypted_data)

# Don't forget to close the SDK when done
sdk.close()
```

## Project Structure
Expand Down
10 changes: 5 additions & 5 deletions otdf-python-proto/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ See [CONNECT_RPC.md](../docs/CONNECT_RPC.md) for additional information.
## Structure

- `proto-files/`: Contains the raw .proto files downloaded from the OpenTDF platform
- `generated/`: Contains the generated Python protobuf and Connect RPC client files
- `src/otdf_python_proto/`: Contains the generated Python protobuf and Connect RPC client files
- `scripts/`: Contains build scripts for generating protobuf and Connect RPC files
- `buf.yaml`: Buf configuration for proto validation and management
- `buf.gen.yaml`: Buf generation configuration for Connect RPC and protobuf
Expand All @@ -40,10 +40,10 @@ Or use the convenience script:
```

This generates:
- `generated/*_connect.py` - Connect RPC clients (preferred)
- `generated/*_pb2.py` - Standard protobuf classes
- `generated/*_pb2.pyi` - Type stubs for better IDE support
- `generated/legacy_grpc/*_pb2_grpc.py` - Legacy gRPC clients (backward compatibility)
- `src/otdf_python_proto/**/*_connect.py` - Connect RPC clients (preferred)
- `src/otdf_python_proto/**/*_pb2.py` - Standard protobuf classes
- `src/otdf_python_proto/**/*_pb2.pyi` - Type stubs for better IDE support
- `src/otdf_python_proto/legacy_grpc/**/*_pb2_grpc.py` - Legacy gRPC clients (backward compatibility)

### Legacy gRPC Generation

Expand Down
12 changes: 6 additions & 6 deletions otdf-python-proto/scripts/generate_connect_proto.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ def copy_opentdf_proto_files(proto_gen_dir: Path) -> bool:
print(f" Copying {relative_path}...")

# Copy the file content
with open(proto_file) as src:
with proto_file.open() as src:
content = src.read()

with open(dest_path, "w") as dst:
with dest_path.open("w") as dst:
dst.write(content)

copied_files += 1
Expand Down Expand Up @@ -155,15 +155,15 @@ def run_buf_generate(proto_gen_dir: Path) -> bool:

# Update buf.gen.yaml with the correct path
buf_gen_path = proto_gen_dir / "buf.gen.yaml"
with open(buf_gen_path) as f:
with buf_gen_path.open() as f:
content = f.read()

# Replace the local plugin path
updated_content = content.replace(
"- local: protoc-gen-connect_python", f"- local: {connect_plugin_path}"
)

with open(buf_gen_path, "w") as f:
with buf_gen_path.open("w") as f:
f.write(updated_content)

# Run buf generate
Expand Down Expand Up @@ -221,7 +221,7 @@ def _fix_ignore_if_default_value(proto_files_dir):
# Iterate all .proto files in the directory
for proto_file in proto_files_dir.glob("**/*.proto"):
try:
with open(proto_file, "r") as file: # noqa: UP015
with proto_file.open("r") as file:
content = file.read()

# Replace the old enum value with the new one
Expand All @@ -230,7 +230,7 @@ def _fix_ignore_if_default_value(proto_files_dir):
)

# Write the updated content back to the file
with open(proto_file, "w") as file:
with proto_file.open("w") as file:
file.write(updated_content)

print(f"Updated {proto_file.name} to use IGNORE_IF_ZERO_VALUE")
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ lint.select = [
"I",
# Performance-related rules
"PERF", # Ruff's performance rules
"PTH", # pathlib (path handling)
# Additional useful rules
"UP", # pyupgrade (modern Python features)
"SIM", # flake8-simplify (simplifications)
Expand Down
18 changes: 9 additions & 9 deletions src/otdf_python/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def load_client_credentials(creds_file_path: str) -> tuple[str, str]:
"CRITICAL", f"Credentials file does not exist: {creds_file_path}"
)

with open(creds_path) as f:
with creds_path.open() as f:
creds = json.load(f)

client_id = creds.get("clientId")
Expand Down Expand Up @@ -223,13 +223,13 @@ def cmd_encrypt(args):

try:
# Read input file
with open(input_path, "rb") as input_file:
with input_path.open("rb") as input_file:
payload = input_file.read()

# Determine output
if args.output:
output_path = Path(args.output)
with open(output_path, "wb") as output_file:
with output_path.open("wb") as output_file:
try:
# Create appropriate config based on container type
container_type = getattr(args, "container_type", "tdf")
Expand All @@ -247,7 +247,7 @@ def cmd_encrypt(args):
logger.debug("Creating TDF")
config = create_tdf_config(sdk, args)
output_stream = BytesIO()
manifest, size, _ = sdk.create_tdf(
_manifest, size, _ = sdk.create_tdf(
BytesIO(payload), config, output_stream
)
output_file.write(output_stream.getvalue())
Expand All @@ -274,7 +274,7 @@ def cmd_encrypt(args):
logger.debug("Creating TDF")
config = create_tdf_config(sdk, args)
output_stream = BytesIO()
manifest, size, _ = sdk.create_tdf(
_manifest, size, _ = sdk.create_tdf(
BytesIO(payload), config, output_stream
)
output_file.write(output_stream.getvalue())
Expand All @@ -296,13 +296,13 @@ def cmd_decrypt(args):

try:
# Read encrypted file
with open(input_path, "rb") as input_file:
with input_path.open("rb") as input_file:
encrypted_data = input_file.read()

# Determine output
if args.output:
output_path = Path(args.output)
with open(output_path, "wb") as output_file:
with output_path.open("wb") as output_file:
try:
# Try to determine if it's a NanoTDF or regular TDF
# NanoTDFs have a specific header format, regular TDFs are ZIP files
Expand Down Expand Up @@ -359,7 +359,7 @@ def cmd_inspect(args):

try:
# Read encrypted file
with open(input_path, "rb") as input_file:
with input_path.open("rb") as input_file:
encrypted_data = input_file.read()

if encrypted_data.startswith(b"PK"):
Expand Down Expand Up @@ -400,7 +400,7 @@ def cmd_inspect(args):
except Exception as e:
# If we can't inspect due to auth issues, show what we can
logger.warning(f"Limited inspection due to: {e}")
with open(input_path, "rb") as input_file:
with input_path.open("rb") as input_file:
encrypted_data = input_file.read()

file_type = "TDF" if encrypted_data.startswith(b"PK") else "NanoTDF"
Expand Down
4 changes: 2 additions & 2 deletions src/otdf_python/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,15 @@ def peek_length(buffer: bytes) -> int:
# MAGIC_NUMBER_AND_VERSION (3 bytes)
offset += 3
# ResourceLocator
kas_locator, kas_size = ResourceLocator.from_bytes_with_size(buffer[offset:])
_kas_locator, kas_size = ResourceLocator.from_bytes_with_size(buffer[offset:])
offset += kas_size
# ECC mode (1 byte)
ecc_mode = ECCMode(buffer[offset])
offset += 1
# Payload config (1 byte)
offset += 1
# PolicyInfo
policy_info, policy_size = PolicyInfo.from_bytes_with_size(
_policy_info, policy_size = PolicyInfo.from_bytes_with_size(
buffer[offset:], ecc_mode
)
offset += policy_size
Expand Down
2 changes: 1 addition & 1 deletion src/otdf_python/nanotdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ def create_nano_tdf(
iv, ciphertext = self._encrypt_payload(payload, key)

# Wrap key if needed
wrapped_key, kas_public_key = self._wrap_key_if_needed(key, config)
wrapped_key, _kas_public_key = self._wrap_key_if_needed(key, config)

# Compose the complete NanoTDF: [IV][CIPHERTEXT][WRAPPED_KEY][WRAPPED_KEY_LEN]
if wrapped_key:
Expand Down
9 changes: 5 additions & 4 deletions src/otdf_python/sdk_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
"""

import logging
import os
import ssl
from dataclasses import dataclass
from pathlib import Path
from typing import Any

import httpx
Expand Down Expand Up @@ -77,9 +77,10 @@ def ssl_context_from_directory(self, certs_dir_path: str) -> "SDKBuilder":
self.cert_paths = []

# Find all .pem and .crt files in the directory
for filename in os.listdir(certs_dir_path):
if filename.endswith(".pem") or filename.endswith(".crt"):
self.cert_paths.append(os.path.join(certs_dir_path, filename))
certs_path = Path(certs_dir_path)
for cert_file in certs_path.iterdir():
if cert_file.suffix in (".pem", ".crt"):
self.cert_paths.append(str(cert_file))

# Create SSL context with these certificates
if self.cert_paths:
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def temp_credentials_file():
with tempfile.TemporaryDirectory() as temp_dir:
creds_file = Path(temp_dir) / "creds.json"
creds_data = {"clientId": "opentdf", "clientSecret": "secret"}
with open(creds_file, "w") as f:
with creds_file.open("w") as f:
json.dump(creds_data, f)
yield creds_file

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def test_sample_file_contents(sample_input_files):
# Check text file has content
text_file = sample_input_files["text"]
assert text_file.exists(), f"Text file should exist: {text_file}"
with open(text_file) as f:
with text_file.open() as f:
content = f.read()
assert "Hello, World!" in content
assert len(content) > 0
Expand All @@ -66,7 +66,7 @@ def test_sample_file_contents(sample_input_files):
# Check attributes file has content
attr_file = sample_input_files["with_attributes"]
assert attr_file.exists(), f"Attributes file should exist: {attr_file}"
with open(attr_file) as f:
with attr_file.open() as f:
content = f.read()
assert "Classification: SECRET" in content

Expand Down
4 changes: 2 additions & 2 deletions tests/integration/otdfctl_to_python/test_cli_comparison.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def test_otdfctl_encrypt_python_decrypt(
# Create input file
input_file = temp_path / "input.txt"
input_content = "Hello, World! This is a test for otdfctl decrypt comparison."
with open(input_file, "w") as f:
with input_file.open("w") as f:
f.write(input_content)

# Define TDF file created by otdfctl
Expand Down Expand Up @@ -115,7 +115,7 @@ def test_otdfctl_encrypt_otdfctl_decrypt(collect_server_logs, temp_credentials_f
input_content = (
"Hello, World! This is a test for otdfctl roundtrip encryption/decryption."
)
with open(input_file, "w") as f:
with input_file.open("w") as f:
f.write(input_content)

# Define TDF file and decrypted output
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def test_read_otdfctl_created_tdf_structure(
# Create input file
input_file = temp_path / "input.txt"
input_content = "Hello, World! This is test data for TDFReader integration."
with open(input_file, "w") as f:
with input_file.open("w") as f:
f.write(input_content)

# Define output files
Expand All @@ -60,7 +60,7 @@ def test_read_otdfctl_created_tdf_structure(
assert otdfctl_output.stat().st_size > 0, "otdfctl created empty TDF file"

# Test that TDFReader can open and read the structure
with open(otdfctl_output, "rb") as f:
with otdfctl_output.open("rb") as f:
tdf_data = f.read()

# Initialize TDFReader
Expand Down Expand Up @@ -116,7 +116,7 @@ def test_read_otdfctl_tdf_with_attributes(
# Create input file
input_file = temp_path / "input.txt"
input_content = "This is input data for testing attributes."
with open(input_file, "w") as f:
with input_file.open("w") as f:
f.write(input_content)

# Define output file
Expand All @@ -143,7 +143,7 @@ def test_read_otdfctl_tdf_with_attributes(
assert otdfctl_output.exists(), "otdfctl did not create TDF file"

# Test that TDFReader can read the file with attributes
with open(otdfctl_output, "rb") as f:
with otdfctl_output.open("rb") as f:
tdf_data = f.read()

reader = TDFReader(io.BytesIO(tdf_data))
Expand Down Expand Up @@ -209,10 +209,10 @@ def test_read_multiple_otdfctl_files(
# Create input file
input_file = temp_path / f"{test_case['name']}.txt"
if isinstance(test_case["content"], bytes):
with open(input_file, "wb") as f:
with input_file.open("wb") as f:
f.write(test_case["content"])
else:
with open(input_file, "w") as f:
with input_file.open("w") as f:
f.write(test_case["content"])

# Define output file
Expand All @@ -235,7 +235,7 @@ def test_read_multiple_otdfctl_files(
)

# Test TDFReader on this file
with open(output_file, "rb") as f:
with output_file.open("rb") as f:
tdf_data = f.read()

reader = TDFReader(io.BytesIO(tdf_data))
Expand Down
8 changes: 4 additions & 4 deletions tests/integration/test_cli_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def test_cli_decrypt_otdfctl_tdf(
# Create input file
input_file = temp_path / "input.txt"
input_content = "Hello, World! This is a test for decryption."
with open(input_file, "w") as f:
with input_file.open("w") as f:
f.write(input_content)

# Define TDF file created by otdfctl
Expand Down Expand Up @@ -99,7 +99,7 @@ def test_otdfctl_decrypt_comparison(
# Create input file
input_file = temp_path / "input.txt"
input_content = "Hello, World! This is a test for otdfctl decrypt comparison."
with open(input_file, "w") as f:
with input_file.open("w") as f:
f.write(input_content)

# Define TDF file created by otdfctl
Expand Down Expand Up @@ -183,7 +183,7 @@ def test_otdfctl_encrypt_decrypt_roundtrip(collect_server_logs, temp_credentials
input_content = (
"Hello, World! This is a test for otdfctl roundtrip encryption/decryption."
)
with open(input_file, "w") as f:
with input_file.open("w") as f:
f.write(input_content)

# Define TDF file and decrypted output
Expand Down Expand Up @@ -258,7 +258,7 @@ def test_cli_encrypt_integration(
# Create input file
input_file = temp_path / "input.txt"
input_content = "Hello, World"
with open(input_file, "w") as f:
with input_file.open("w") as f:
f.write(input_content)

# Define output files
Expand Down
Loading
Loading