SDKs

Python SDK

Quickstart for the Lattix Python SDK — an async wrapper over the Rust core with Pydantic models for the public control-plane contract and local embedded-protection helpers.

The Python SDK is an async wrapper over the Rust SDK core. It exposes the same public control-plane contract as the Rust and Go SDKs, with Pydantic v2 models for request and response shapes, and it also ships local embedded-protection helpers for CID binding, artifact protection, and detached signatures. It is the right choice for data pipelines, notebooks, and orchestrated workloads.

This page is a conceptual quickstart. Full API reference — every public class, every field, every example — lives with the package itself on PyPI and in the lattixsdk.models module definitions.

Install

pip install lattix-sdk-python

The import package is lattixsdk. Official wheels bundle the matching native Rust library for the target platform, so a normal wheel install is sufficient; no separate native build is required for supported platforms.

Source / editable installs

Source installs are supported for local development and constrained environments. They require a separately built matching Rust core — see the Rust SDK documentation for how to produce a native library, then either set LATTIX_SDK_RUST_LIB to the compiled library path or stage the native library into the package before building.

Construct a client

The client is async and supports the async with pattern.

import asyncio
from lattixsdk import LattixClient


async def main() -> None:
    async with LattixClient(
        base_url="https://api.lattix.io",
        bearer_token="<your-token>",
    ) as client:
        bootstrap = await client.bootstrap()
        print(bootstrap.enforcement_model)


asyncio.run(main())

Constructor options

ArgumentPurpose
base_urlThe Lattix platform API base URL.
bearer_tokenPre-issued bearer token attached to every request.
timeout_secsHTTP request timeout in seconds.
headersAdditional headers attached to every request.
managed_symmetric_key_providersConfigure managed symmetric-key providers for local TDF / envelope helpers.
library_pathExplicit path to the native Rust library (overrides auto-discovery).
tenant_id / user_idPrivate-deployment options for trusted-header or test workflows; not required on the public api.lattix.io bearer path.

The client spawns a native Rust binding under the hood and dispatches each call to an executor, so the async API is safe to await from any asyncio event loop.

For public integrations, obtain the access token out of band via the published OAuth/OIDC issuer, then pass that token as bearer_token.

Make a call

All operations are async and return Pydantic models.

from lattixsdk import (
    ArtifactProfile,
    LattixClient,
    ProtectionOperation,
    ResourceDescriptor,
    SdkProtectionPlanRequest,
    WorkloadDescriptor,
)


async def protect(client: LattixClient) -> None:
    plan = await client.protection_plan(
        SdkProtectionPlanRequest(
            operation=ProtectionOperation.PROTECT,
            workload=WorkloadDescriptor(
                application="example-app",
                environment="prod",
                component="ingest",
            ),
            resource=ResourceDescriptor(
                kind="document",
                id="doc-123",
                mime_type="application/pdf",
            ),
            preferred_artifact_profile=ArtifactProfile.TDF,
            content_digest="sha256:...",
            content_size_bytes=1024,
            purpose="store",
            labels=["confidential"],
        )
    )

    if plan.decision.allow and plan.execution.protect_locally:
        # ... perform local protection using the indicated artifact profile
        ...

The response is a fully-typed Pydantic model. You can access fields directly (plan.execution.artifact_profile), serialize with model_dump(), or validate against the platform contract with model_validate_json().

Local helper surface

In addition to the HTTP control-plane calls, the current Python SDK exposes async local helper families for embedded enforcement:

  • prepare_local_protection(...) and generate_cid_binding(...)
  • TDF helpers for protect / access / rewrap plus attribute updates
  • Envelope helpers for protect / access / rewrap
  • Detached-signature helpers for sign / verify
  • managed_symmetric_key_providers= for managed local key flows

These helpers keep plaintext, protected bytes, and local key handling inside the Python process while the platform continues to provide policy, key guidance, registration, and evidence endpoints.

The eight core control-plane operations

Every method on LattixClient maps to a single /v1/sdk/* route.

await client.capabilities()                  # GET /v1/sdk/capabilities
await client.whoami()                        # GET /v1/sdk/whoami
await client.bootstrap()                     # GET /v1/sdk/bootstrap
await client.protection_plan(request)        # POST /v1/sdk/protection-plan
await client.policy_resolve(request)         # POST /v1/sdk/policy-resolve
await client.key_access_plan(request)        # POST /v1/sdk/key-access-plan
await client.artifact_register(request)      # POST /v1/sdk/artifact-register
await client.evidence(request)               # POST /v1/sdk/evidence

See Platform API → Endpoints for the shape of each request and response.

Models and enums

The lattixsdk package re-exports every request, response, and enum used by the contract. A typical import looks like:

from lattixsdk import (
    # Enums
    ArtifactProfile,
    AuthMode,
    EvidenceEventType,
    KeyAccessOperation,
    ProtectionOperation,
    # Descriptors
    ResourceDescriptor,
    WorkloadDescriptor,
    # Requests / responses
    SdkArtifactRegisterRequest, SdkArtifactRegisterResponse,
    SdkBootstrapResponse,
    SdkCapabilitiesResponse,
    SdkEvidenceIngestRequest, SdkEvidenceIngestResponse,
    SdkKeyAccessPlanRequest, SdkKeyAccessPlanResponse,
    SdkPolicyResolveRequest, SdkPolicyResolveResponse,
    SdkProtectionPlanRequest, SdkProtectionPlanResponse,
    # Caller + client
    CallerIdentityResponse,
    LattixClient,
    LattixBindingError,
)

Models are Pydantic v2 BaseModel subclasses. Fields that are Optional in the contract are Optional[...] in Python; enums use Python enum.Enum.

Errors

Errors surface as LattixBindingError (imported from lattixsdk). This is the single public exception for the SDK. Catch it around any SDK call:

from lattixsdk import LattixBindingError

try:
    plan = await client.protection_plan(request)
except LattixBindingError as exc:
    # exc.args contains a human-readable message describing the failure;
    # connection errors, serialization errors, and upstream responses
    # are all surfaced through this single type.
    ...

Lifecycle

  • async with LattixClient(...) as client: — preferred pattern; calls aclose() on exit.
  • client.close() — synchronous release of the native handle.
  • await client.aclose() — async release; equivalent to exiting the context manager.

Testing

Unit tests in the package use a fake binding, so they run without the native library:

pip install -e .[test]
pytest

Native smoke tests auto-skip if the Rust library is not present, and execute a real Rust-backed client against a local in-process HTTP server when it is.

Relationship to other pages