Metadata-Version: 2.4
Name: dakera
Version: 0.2.0
Summary: Python SDK for Dakera - AI memory platform
Author: Dakera Team
License: MIT
Project-URL: Homepage, https://dakera.ai
Project-URL: Documentation, https://dakera.ai/docs/python
Project-URL: Repository, https://github.com/dakera-ai/dakera-py
Project-URL: Issues, https://github.com/dakera-ai/dakera-py/issues
Keywords: vector,database,embedding,similarity,search,ai,ml,memory,dakera
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Database
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Typing :: Typed
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28.0
Requires-Dist: typing-extensions>=4.0.0; python_version < "3.10"
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: responses>=0.23.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: types-requests>=2.28.0; extra == "dev"
Provides-Extra: async
Requires-Dist: aiohttp>=3.8.0; extra == "async"
Dynamic: license-file

# Dakera Python SDK

[![CI](https://github.com/dakera-ai/dakera-py/actions/workflows/ci.yml/badge.svg)](https://github.com/dakera-ai/dakera-py/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/dakera)](https://pypi.org/project/dakera/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Python](https://img.shields.io/pypi/pyversions/dakera)](https://pypi.org/project/dakera/)

Official Python client for [Dakera](https://github.com/dakera/dakera) - a high-performance vector database.

## Installation

```bash
pip install dakera
```

For async support:
```bash
pip install dakera[async]
```

## Quick Start

```python
from dakera import DakeraClient

# Connect to Dakera
client = DakeraClient("http://localhost:3000")

# Upsert vectors
client.upsert("my-namespace", vectors=[
    {"id": "vec1", "values": [0.1, 0.2, 0.3], "metadata": {"label": "a"}},
    {"id": "vec2", "values": [0.4, 0.5, 0.6], "metadata": {"label": "b"}},
])

# Query similar vectors
results = client.query(
    "my-namespace",
    vector=[0.1, 0.2, 0.3],
    top_k=10,
)

for result in results.results:
    print(f"{result.id}: {result.score}")
```

## Features

- **Vector Operations**: Upsert, query, delete, fetch vectors
- **Full-Text Search**: Index documents and perform BM25 search
- **Hybrid Search**: Combine vector and text search with configurable weights
- **Namespace Management**: Create, list, delete namespaces
- **Metadata Filtering**: Filter queries by metadata fields
- **Type Hints**: Full type annotation support
- **Context Manager**: Automatic connection cleanup

## Usage Examples

### Vector Operations

```python
from dakera import DakeraClient, Vector

client = DakeraClient("http://localhost:3000")

# Using dataclass
vectors = [
    Vector(id="vec1", values=[0.1, 0.2, 0.3], metadata={"category": "A"}),
    Vector(id="vec2", values=[0.4, 0.5, 0.6], metadata={"category": "B"}),
]
client.upsert("my-namespace", vectors)

# Using dictionaries
client.upsert("my-namespace", vectors=[
    {"id": "vec3", "values": [0.7, 0.8, 0.9]},
])

# Query with metadata filter
results = client.query(
    "my-namespace",
    vector=[0.1, 0.2, 0.3],
    top_k=5,
    filter={"category": {"$eq": "A"}},
    include_metadata=True,
)

# Batch query
batch_results = client.batch_query("my-namespace", queries=[
    {"vector": [0.1, 0.2, 0.3], "top_k": 5},
    {"vector": [0.4, 0.5, 0.6], "top_k": 3},
])

# Delete vectors
client.delete("my-namespace", ids=["vec1", "vec2"])
client.delete("my-namespace", filter={"category": {"$eq": "obsolete"}})
```

### Full-Text Search

```python
# Index documents
client.index_documents("my-namespace", documents=[
    {"id": "doc1", "content": "Machine learning is transforming industries"},
    {"id": "doc2", "content": "Vector databases enable semantic search"},
])

# Search
results = client.fulltext_search(
    "my-namespace",
    query="machine learning",
    top_k=10,
)

for result in results:
    print(f"{result.id}: {result.score}")
```

### Hybrid Search

```python
# Combine vector and text search
results = client.hybrid_search(
    "my-namespace",
    vector=[0.1, 0.2, 0.3],  # Embedding of query
    query="machine learning",  # Text query
    top_k=10,
    alpha=0.7,  # 0 = pure vector, 1 = pure text
)

for result in results:
    print(f"{result.id}: score={result.score}, vector={result.vector_score}, text={result.text_score}")
```

### Namespace Management

```python
# Create namespace with specific configuration
client.create_namespace(
    "embeddings",
    dimensions=384,
    index_type="hnsw",
)

# List all namespaces
namespaces = client.list_namespaces()
for ns in namespaces:
    print(f"{ns.name}: {ns.vector_count} vectors")

# Get namespace info
info = client.get_namespace("embeddings")
print(f"Dimensions: {info.dimensions}, Index: {info.index_type}")

# Delete namespace
client.delete_namespace("old-namespace")
```

### Metadata Filtering

Dakera supports rich metadata filtering:

```python
# Equality
filter = {"status": {"$eq": "active"}}

# Comparison
filter = {"price": {"$gt": 100, "$lt": 500}}

# In list
filter = {"category": {"$in": ["electronics", "books"]}}

# Logical operators
filter = {
    "$and": [
        {"status": {"$eq": "active"}},
        {"price": {"$lt": 1000}},
    ]
}

results = client.query(
    "products",
    vector=query_embedding,
    filter=filter,
    top_k=20,
)
```

### Error Handling

```python
from dakera import (
    DakeraClient,
    NotFoundError,
    ValidationError,
    RateLimitError,
)

client = DakeraClient("http://localhost:3000")

try:
    results = client.query("nonexistent", vector=[0.1, 0.2])
except NotFoundError as e:
    print(f"Namespace not found: {e}")
except ValidationError as e:
    print(f"Invalid request: {e}")
except RateLimitError as e:
    print(f"Rate limited, retry after {e.retry_after} seconds")
```

### Context Manager

```python
with DakeraClient("http://localhost:3000") as client:
    client.upsert("my-namespace", vectors=[...])
    results = client.query("my-namespace", vector=[...])
# Connection automatically closed
```

### Authentication

```python
# With API key
client = DakeraClient(
    "http://localhost:3000",
    api_key="your-api-key",
)

# With custom headers
client = DakeraClient(
    "http://localhost:3000",
    headers={"X-Custom-Header": "value"},
)
```

## Configuration

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `base_url` | str | required | Dakera server URL |
| `api_key` | str | None | API key for authentication |
| `timeout` | float | 30.0 | Request timeout in seconds |
| `max_retries` | int | 3 | Max retries for failed requests |
| `headers` | dict | None | Additional HTTP headers |

## API Reference

### DakeraClient

#### Vector Operations
- `upsert(namespace, vectors)` - Insert or update vectors
- `query(namespace, vector, top_k, filter, ...)` - Query similar vectors
- `delete(namespace, ids, filter, delete_all)` - Delete vectors
- `fetch(namespace, ids)` - Fetch vectors by ID
- `batch_query(namespace, queries)` - Execute multiple queries

#### Full-Text Operations
- `index_documents(namespace, documents)` - Index documents
- `fulltext_search(namespace, query, top_k, filter)` - Text search
- `hybrid_search(namespace, vector, query, alpha, ...)` - Hybrid search

#### Namespace Operations
- `list_namespaces()` - List all namespaces
- `get_namespace(namespace)` - Get namespace info
- `create_namespace(namespace, dimensions, index_type)` - Create namespace
- `delete_namespace(namespace)` - Delete namespace

#### Admin Operations
- `health()` - Check server health
- `get_index_stats(namespace)` - Get index statistics
- `compact(namespace)` - Trigger compaction
- `flush(namespace)` - Flush pending writes

## Development

```bash
# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Type checking
mypy src/dakera

# Linting
ruff check src/
```

## Related Repositories

| Repository | Description |
|------------|-------------|
| [dakera](https://github.com/dakera-ai/dakera) | Core vector database engine (Rust) |
| [dakera-js](https://github.com/dakera-ai/dakera-js) | TypeScript/JavaScript SDK |
| [dakera-go](https://github.com/dakera-ai/dakera-go) | Go SDK |
| [dakera-rs](https://github.com/dakera-ai/dakera-rs) | Rust SDK |
| [dakera-cli](https://github.com/dakera-ai/dakera-cli) | Command-line interface |
| [dakera-mcp](https://github.com/dakera-ai/dakera-mcp) | MCP Server for AI agent memory |
| [dakera-dashboard](https://github.com/dakera-ai/dakera-dashboard) | Admin dashboard (Leptos/WASM) |
| [dakera-docs](https://github.com/dakera-ai/dakera-docs) | Documentation |
| [dakera-deploy](https://github.com/dakera-ai/dakera-deploy) | Deployment configs and Docker Compose |
| [dakera-cortex](https://github.com/dakera-ai/dakera-cortex) | Flagship demo with AI agents |

## License

MIT License - see [LICENSE](LICENSE) for details.
