Metadata-Version: 2.4
Name: restack_ai
Version: 0.0.121
Summary: Restack AI library
Author-email: Restack Team <service@restack.io>
Requires-Python: >=3.10
Requires-Dist: aiohttp<4,>=3.11.10
Requires-Dist: asyncio<4,>=3.4.3
Requires-Dist: msgspec<0.22,>=0.20.0
Requires-Dist: pydantic<3,>=2.10.6
Requires-Dist: python-dotenv<2,>=1.0.1
Requires-Dist: temporalio==1.18.1
Requires-Dist: typing-extensions>=4.12.2
Requires-Dist: websockets<15,>=13.1
Description-Content-Type: text/markdown

# Restack AI libraries

This is the Python Restack AI libraries.

## Installation

You can install the Restack AI libraries using pip:

### Using pip

```bash
pip install restack_ai
```

### Using Poetry

```bash
poetry add restack_ai
```

### Using uv

```bash
uv add restack_ai
```

## Prerequisites

- Python 3.8 or higher
- Poetry (for dependency management)

## Usage

To use the libraries in your project, you can import it like this:

```python
from restack_ai import Restack
```

## Initialize the Restack client

```python
client = Restack()
```

## Hide sensitive fields from the workflow UI

Wrap any value with `Sensitive` to opt it into selective field encryption.
Only the marked fields are encrypted on the wire, so the engine UI keeps
showing useful debug context (email, ids, timestamps) while sensitive
values render as opaque ciphertext.

### Engine-managed key (recommended)

When the engine is configured with `RESTACK_ENGINE_PAYLOAD_KEY` and
`RESTACK_API_BEARER_TOKEN` (see the engine readme), the SDK auto-fetches
the key during `connect()` and wires up the codec for you. Consumer
services don't need any new env:

```python
from pydantic import BaseModel
from restack_ai import Restack, Sensitive


class SignupInput(BaseModel):
    email: str
    password: Sensitive[str]


client = Restack()  # engine config from RESTACK_ENGINE_* envs

# Caller side:
await client.schedule_workflow(
    workflow_name="UserSignupWorkflow",
    workflow_id=workflow_id,
    workflow_input=SignupInput(
        email=email,
        password=Sensitive(value=password),
    ).model_dump(),
)


# Workflow side: receive the typed input, unwrap when you need plaintext.
@workflow.defn
class UserSignupWorkflow:
    @workflow.run
    async def run(self, payload: SignupInput) -> None:
        raw_password = payload.password.unwrap()
        ...
```

The SDK passes its `api_key` as the bearer token when fetching the key.
Engines that don't expose the key endpoint (older versions, or with the
env unset) cause the SDK to silently fall back to no encryption — no
deployment breakage.

In the engine UI the `password` field renders as
`{"__restack_encrypted__": "v1", "alg": "AES-256-GCM", "iv": "...", "ct": "..."}`
instead of plaintext.

`create_aes_gcm_encryption` (used internally) requires the optional
`cryptography` package — install it on every service that runs as a
Restack worker so it can decrypt: `pip install cryptography`.

### Consumer-managed key (advanced)

To keep the key entirely out of the engine — e.g. each consumer service
manages its own key in a KMS — pass a codec explicitly. This overrides
the engine auto-wire:

```python
import os
from restack_ai import (
    Restack,
    SensitiveFieldsCodec,
    create_aes_gcm_encryption,
)
from restack_ai.restack import CloudConnectionOptions

key = os.urandom(32)  # load from your secrets store in real code
codec = SensitiveFieldsCodec(create_aes_gcm_encryption(key))

client = Restack(
    CloudConnectionOptions(
        engine_id=..., api_key=...,
        payload_codecs=[codec],
    ),
)
```

For non-AES backends (KMS, HSM, envelope encryption) provide your own
implementation of `SensitiveEncryption` and pass it to
`SensitiveFieldsCodec`.

## Documentation

For detailed usage instructions, please visit our examples repository at [https://github.com/restackio/examples-python](https://github.com/restackio/examples-python).

## Development

If you want to contribute to the libraries development:

### Clone the repository and navigate to the `engine/libraries/python` directory.

### Install Poetry/uv if you haven't already: [https://python-poetry.org/docs/#installation](https://python-poetry.org/docs/#installation) or use pip

### Activate the virtual environment:

If using uv:

```bash
uv venv && source .venv/bin/activate
```

If using poetry:

```bash
poetry env use 3.12 && poetry shell
```

If using pip:

```bash
python -m venv .venv && source .venv/bin/activate
```

### Install the project dependencies:

If using uv:

```bash
uv sync
```

If using Poetry:

```bash
poetry install
```

If using pip:

```bash
pip install -e .
```
