Metadata-Version: 2.4
Name: lattix-sdk-python
Version: 0.1.1
Summary: Async Python bindings for the Rust-based Lattix SDK core
Author: Lattix
License-Expression: LicenseRef-Lattix-Proprietary-SDK
Project-URL: Homepage, https://lattix.io/
Project-URL: Documentation, https://lattix.io/docs
Project-URL: Repository, https://github.com/LATTIX-IO/sdk-python
Keywords: lattix,sdk,rust,bindings,zero-trust
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pydantic>=2
Provides-Extra: test
Requires-Dist: pytest>=8; extra == "test"
Requires-Dist: anyio>=4; extra == "test"
Provides-Extra: quality
Requires-Dist: ruff>=0.6; extra == "quality"
Requires-Dist: bandit[toml]>=1.7; extra == "quality"
Requires-Dist: pip-audit>=2.7; extra == "quality"
Dynamic: license-file

# Lattix Python SDK

Async Python bindings for the Rust-based Lattix SDK core.

The public Lattix docs at `https://lattix.io/docs` intentionally stay focused on platform concepts and tenant/operator guidance. Per-language SDK reference material is distributed with each SDK package, so this README is part of the supported Python reference surface.

## Overview

This package targets the `lattix-platform-api` SDK control-plane contract and exposes async methods for the metadata-only zero-trust flows:

- `capabilities()`
- `whoami()`
- `bootstrap()`
- `protection_plan(...)`
- `policy_resolve(...)`
- `key_access_plan(...)`
- `artifact_register(...)`
- `evidence(...)`
- `prepare_local_protection(...)`
- `generate_cid_binding(...)`

Python stays thin: the Rust core owns HTTP, auth header shaping, platform contract behavior, and the local helper workflow sequencing.

`capabilities()` and `bootstrap()` surface the live `auth_configuration` metadata published by `lattix-platform-api`, including the direct bearer/OIDC mode, proof-of-possession mode, issuer/audience, and readiness flags.

`generate_cid_binding(...)` is the smallest local helper. It computes the SHA-256 digest/raw CID in-process, drives the metadata-only planning calls, and returns a portable `LocalArtifactBinding` that captures tenant/workload/resource linkage plus the resolved binding targets and binding hash.

## What ships in this repo

- `lattixsdk.client.LattixClient` — async wrapper over the native Rust binding
- `lattixsdk.binding.RustBinding` — low-level ctypes bridge to the Rust SDK core
- `lattixsdk.models` — Pydantic models mirroring the `/v1/sdk/*` control-plane contract
- `examples/example.ipynb` — notebook example using the current bootstrap flow

## Installation

### Official wheel install

Supported wheels bundle the matching native `sdk-rust` shared library for the
target platform, so a normal wheel install is enough:

```bash
pip install lattix-sdk-python
```

The import package remains `lattixsdk`.

### Source and editable installs

Source installs remain supported for local development and constrained
environments, but they require a separately built matching `sdk-rust` native
library.

Build `sdk-rust` first:

```bash
cd ../sdk-rust
cargo build --release
```

Then either:

- set `LATTIX_SDK_RUST_LIB` to the compiled library path; or
- stage the native library into this package before building a wheel with
    `python tools/stage_native_library.py`.

The canonical C ABI lives in `sdk-rust/include/lattix_sdk.h`; this package intentionally does not maintain a second handwritten header.

## Quickstart

```python
import asyncio
from lattixsdk import LattixClient
from lattixsdk.models import (
    ArtifactProfile,
    LocalProtectionRequest,
    ResourceDescriptor,
    WorkloadDescriptor,
)


async def main() -> None:
    async with LattixClient(
        base_url="https://api.lattix.io",
        bearer_token="replace-me",
        tenant_id="tenant-a",
        user_id="user-a",
    ) as client:
        bootstrap = await client.bootstrap()
        print(bootstrap.enforcement_model)

        binding = await client.generate_cid_binding(
            b"hello world",
            LocalProtectionRequest(
                workload=WorkloadDescriptor(application="example-app"),
                resource=ResourceDescriptor(kind="document"),
                preferred_artifact_profile=ArtifactProfile.ENVELOPE,
                purpose="store",
                labels=["confidential"],
                attributes={"region": "us"},
            ),
        )

        print(binding.raw_cid)
        print(binding.binding_hash)


asyncio.run(main())
```

Use `generate_cid_binding(...)` when you need deterministic CID lineage and policy/tenant binding metadata without yet creating an encrypted artifact.

Managed symmetric-key providers are configured through `managed_symmetric_key_providers=` and now have first-class typed support for both in-memory fixtures and command-backed helpers.

```python
from lattixsdk import LattixClient
from lattixsdk.models import CommandManagedKeyProviderConfig

client = LattixClient(
    base_url="https://api.lattix.io",
    managed_symmetric_key_providers=[
        CommandManagedKeyProviderConfig.from_command(
            name="command-kms",
            command="provider.py",
            args=["--stdio"],
            env={"LATTIX_PROFILE": "dev"},
        )
    ],
)
```

Use the command-backed variant when key lookup or unwrap authorization must stay inside an external helper process instead of embedding that provider logic directly in Python.

## Design notes

- The SDK is aligned to the embedded-enforcement model: applications protect data locally and only send metadata to the platform.
- The async API is implemented by running the native Rust calls in an executor, so callers can integrate it cleanly into async Python services.
- Pydantic models live under `lattixsdk.models` and mirror the platform-api SDK contract.
- The authoritative machine-readable `/v1/sdk/*` contract lives in `lattix-platform-api/openapi/sdk-control-plane.yaml`; this package mirrors that surface and does not ship a separate divergent OpenAPI source of truth.

## Testing

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

```bash
pip install -e .[test]
pytest
```

Native smoke tests are included as well. They auto-skip if the Rust library has not been built yet, and they run a real Rust-backed client against a local in-process HTTP server when the native artifact is present, including CID-binding coverage for the local helper layer.

## Local quality gate

Run the local quality gate before committing when you want automated fixes,
security scans, tests, package builds, wheel-install smoke coverage, and cleanup
in one step:

```bash
./precommit.sh
```

On Windows:

```powershell
./precommit.ps1
```

The gate applies automated fixes first, then runs linting, SAST, secret
scanning, tests, package builds, and an installed-wheel smoke test in a
temporary virtual environment.

To wire the same checks into local Git commits and pushes:

```bash
./install-hooks.sh
```

or:

```powershell
./install-hooks.ps1
```

The installed `pre-commit` hook runs a faster version of the gate; the
installed `pre-push` hook runs the full gate.

## Release process

Maintainer release notes live in `RELEASING.md`. The publish workflow supports a
TestPyPI rehearsal path through trusted publishing before the first real PyPI
publish.

## License

Distributed under the proprietary Lattix SDK License in `LICENSE`.
