Metadata-Version: 2.4
Name: elasti
Version: 0.1.0
Summary: Official Python SDK for the Elasti platform (encrypted vector database)
License: Proprietary
Project-URL: Homepage, https://elasti.com
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.31
Provides-Extra: text
Requires-Dist: sentence-transformers>=3.0; extra == "text"
Requires-Dist: numpy>=1.26; extra == "text"
Provides-Extra: demo
Requires-Dist: sentence-transformers>=3.0; extra == "demo"
Requires-Dist: numpy>=1.26; extra == "demo"

# elasti (Python SDK)

Official Python SDK for the Elasti platform. `client.vectors` is the
end-to-end **encrypted vector database**: embeddings are encrypted
**on-device** with a secret key that never leaves your machine, similarity
search runs **homomorphically** server-side, and scores decrypt locally.
The server only ever sees ciphertext — your data, your queries, and your
results stay unreadable to everyone but you.

## Install

```bash
pip install elasti            # SDK
pip install "elasti[demo]"    # + sentence-transformers for the example
```

The SDK binds the native bridge via ctypes. Point it at the library if it
is not in a standard location:

```bash
export ELASTI_BRIDGE_LIB=/path/to/libelastibridge.so
```

## Quick start

An API key from the [dashboard](https://elasti.com) is the only credential
you need. Bring your own embeddings — any model, any pipeline:

```python
import os
from elasti import Elasti

client = Elasti(api_key=os.environ["ELASTI_API_KEY"])

index = client.vectors.index("default")   # first run generates keys locally

encrypted = index.encrypt_embeddings(vectors)   # local, secret-key encryption
index.upload(encrypted)                          # only ciphertext leaves

for r in index.search(query_vector, top_k=5):
    print(r.id, r.score)
```

- The **first** `index()` call generates your full key set on this machine
  (~30s) and uploads only the public evaluation keys (~1 GB, one time, via
  presigned URLs). The secret key is written to `~/.elasti/` and is never
  transmitted anywhere.
- `encrypt_embeddings(vectors)` seals each embedding locally
  (~34 KB of ciphertext per vector).
- `upload(encrypted)` stages the ciphertext and returns insertion-order ids;
  map ids to your own records however you like.
- `search(embedding)` encrypts the query locally, scores every stored vector
  blindly server-side, and decrypts the scoreboard back on this machine.
  Scores are inner products (cosine similarity if your embeddings are
  normalized).
- `sync()` blocks until recent uploads are packed and searchable; `search()`
  calls it automatically when needed.

## Multiple indexes

Your account has one key set and any number of named indexes. Extra indexes
are cheap — they share your keys and only add their own storage — and every
search is scoped to one index:

```python
notes  = client.vectors.index("notes")
photos = client.vectors.index("photos")
```

Index names: lowercase alphanumerics, dash, underscore, max 64 chars.

## Key backup and portability

The secret key is the only way to decrypt an index — back it up:

```python
index.save_key("~/backups/elasti.key")   # export to a file
raw = index.export_key()                  # or raw bytes for a vault/KMS

# on a new machine, open your data with the exported key:
index = client.vectors.index("default", key_file="~/backups/elasti.key")
index = client.vectors.index("default", key=raw)
```

If a different key already exists locally, `index()` refuses to overwrite it.

## Example

`examples/encrypted_search.py` stores passages from *1984*, *Fahrenheit
451*, *Brave New World*, and other novels about surveillance — encrypted,
in a database that for once actually can't read them — then answers
semantic queries over them end to end:

```bash
ELASTI_API_KEY=elasti_sk_... python examples/encrypted_search.py
```

## Security model

- The secret key is generated on your machine and never leaves it.
- Encrypted embeddings (~34 KB/vector) and queries (~34 KB) are ciphertext
  end to end.
- The server computes inner products blindly and returns encrypted
  scoreboards; ranking happens after local decryption.
- Rate limits apply per API key during the developer preview; requests
  return `Retry-After` and the SDK backs off automatically.
