TectraTectra
Python SDK

Python SDK

The Tectra Python SDK signs and watermarks images entirely on your machine. Only cryptographic hashes are sent to our servers - your image bytes never leave your infrastructure.

Looking for JavaScript/TypeScript? See the TypeScript SDK

TypeScript SDK

Privacy-first design

The SDK decrypts your Ed25519 private key locally using a Fernet key that never leaves your machine. Images are watermarked and signed on your hardware. Only SHA-256 hashes and metadata are posted to Tectra for blockchain registration.

Installation

bash
pip install tectravision-sdk

Requires Python 3.10+. Dependencies: requests, PyNaCl, cryptography, Pillow, invisible-watermark.

Initialization

Create a client with your API key, signing key ID, and Fernet key. Get these from the dashboard.

python
from tectravision_sdk import TectraClient

client = TectraClient(
    api_key="iai_live_abc123...",          # From dashboard → API Keys
    signing_key_id="your-key-uuid",        # From dashboard → Signing Keys
    api_url="https://tectra.vision",       # Default
    fernet_key="your-fernet-key",         # From dashboard → Signing Keys
    # Or set TECTRA_FERNET_KEY env variable
)

# The Fernet key is used to decrypt your private signing key locally.
# It never leaves your machine.

client.sign()

Sign an image. Returns a result dict with the record ID, output path, and certificate.

python
# Sign from file path
result = client.sign("photo.jpg")

# Sign from bytes
with open("photo.jpg", "rb") as f:
    result = client.sign(f.read(), filename="photo.jpg")

# Sign with origin type and metadata
result = client.sign(
    "generated.png",
    origin_type="ai_generated_image",
    metadata={
        "model": "my-model-v2",
        "seed": 42,
    }
)

# Result dict:
{
    "record_id": "uuid",
    "output_path": "photo_signed.jpg",    # Watermarked output file
    "sha256": "abc123...",
    "perceptual_hash": "def456...",
    "signature_hex": "ghi789...",
    "blockchain_status": "pending",
    "certificate": {
        "record_id": "uuid",
        "sha256": "abc123...",
        "org_name": "Acme AI Inc.",
        "timestamp": "2025-01-15T12:34:56Z",
    }
}

client.sign_batch()

Sign multiple images in a single call. Returns a list of result dicts, one per image.

python
results = client.sign_batch([
    "photo1.jpg",
    "photo2.png",
    "photo3.webp",
])

for r in results:
    print(f"{r['output_path']} → {r['record_id']}")

# With shared metadata for all images
results = client.sign_batch(
    ["img_001.jpg", "img_002.jpg", "img_003.jpg"],
    origin_type="ai_generated_image",
    metadata={"model": "my-model-v2", "batch": "20250601"},
)

# With per-image options
results = client.sign_batch([
    {"path": "camera_01.jpg", "origin_type": "camera_capture"},
    {"path": "render_02.png", "origin_type": "ai_generated_image", "metadata": {"seed": 42}},
])

client.verify()

Verify any image - calls the public API endpoint. No API key required for verification.

python
result = client.verify("suspect.jpg")

print(f"Authentic: {result['authentic']}")
print(f"Confidence: {result['confidence']:.0%}")

if result['signer']:
    print(f"Signed by: {result['signer']['org_name']}")
    print(f"Origin: {result['signer']['org_type']}")

for check, data in result['checks'].items():
    status = "✓" if data['passed'] else "✗"
    print(f"  {status} {check}: {data['details']}")

client.sign_video()

Sign a video by extracting and watermarking key frames. Returns a record per frame.

python
result = client.sign_video(
    "footage.mp4",
    keyframe_fps=1,         # Sign 1 frame per second
    output_path="footage_signed.mp4",
)

print(f"Frames signed: {result['frame_count']}")
print(f"Parent record: {result['record_id']}")
for frame in result['frames']:
    print(f"  Frame {frame['index']}: {frame['record_id']}")

Video frame records are linked to a parent record. Verification of the parent verifies all frames.

client.watch()

Watch a directory and auto-sign new files as they appear. Runs indefinitely.

python
def on_signed(path: str, result: dict):
    print(f"Auto-signed: {path}")
    print(f"  Record: {result['record_id']}")

# Blocking - runs until interrupted
client.watch(
    directory="/camera/output/",
    callback=on_signed,
    extensions=[".jpg", ".png", ".mp4"],
    recursive=False,
)

# Non-blocking with threading
import threading
t = threading.Thread(
    target=client.watch,
    args=("/camera/output/",),
    kwargs={"callback": on_signed},
    daemon=True,
)
t.start()

Environment Variables

VariableDescription
TECTRA_API_KEYYour iai_ API key
TECTRA_SIGNING_KEY_IDUUID of your signing key
TECTRA_FERNET_KEYFernet key for local private key decryption
TECTRA_API_URLAPI base URL (default: https://tectra.vision)

Next: Docker Agent

Zero-code drop-in for camera and media pipelines.

Docker Agent

See Also