SDKs

Python SDK

Quickstart for the Lattix Python SDK — an async wrapper over the Rust core with Pydantic models, for data pipelines, notebooks, and orchestrated workloads.

The Python SDK is an async wrapper over the Rust SDK core. It exposes the same eight operations as the Rust and Go SDKs, with Pydantic v2 models for request and response shapes, and 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>",
        tenant_id="<your-tenant>",
        user_id="<your-user>",
    ) 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.
client_id / client_secretSDK client credentials; the SDK exchanges them for a short-lived token on first use.
tenant_idTenant identity for this client. Required in client-credentials mode.
user_idUser/principal identity (used in trusted-headers deployments).
timeout_secsHTTP request timeout in seconds.
token_exchange_pathOverride the default session-exchange endpoint path.
requested_scopesRequested scopes during session exchange.
headersAdditional headers attached to every request.
library_pathExplicit path to the native Rust library (overrides auto-discovery).

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.

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().

The eight 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.exchange_session()              # POST /v1/sdk/session (client-credentials mode only)
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,
    SdkSessionExchangeResponse,
    # 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