Metadata-Version: 2.4
Name: ankhdb
Version: 2.0.2
Summary: The official Python SDK for AnkhDB - Real-time Multi-tenant BaaS.
Author-email: KemetSoft <yusufsameh347@gmail.com>
Project-URL: Homepage, https://github.com/ankhdb/ankhdb-python
Project-URL: Bug Tracker, https://github.com/ankhdb/ankhdb-python/issues
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28.0
Dynamic: license-file

# ankhdb

[![PyPI version](https://img.shields.io/pypi/v/ankhdb.svg)](https://pypi.org/project/ankhdb/)

The official Python SDK for **AnkhDB** — a self-hosted, multi-tenant Backend-as-a-Service with Auth, Database, Storage, and Edge Functions.

## Installation

```bash
pip install ankhdb
```

## Quick Start

```python
from ankhdb import AnkhDB

db = AnkhDB("YOUR_PROJECT_ID", "YOUR_API_KEY")
# Self-hosted: AnkhDB("proj_...", "ankh_sec_...", server_url="http://localhost:5000")
```

---

## Error Handling

All errors raise typed exceptions derived from `AnkhDBError`:

```python
from ankhdb import AuthError, NotFoundError, RateLimitError

try:
    db.login("user@example.com", "wrong")
except AuthError as e:
    print("Bad credentials", e.status)
except RateLimitError:
    print("Slow down!")
```

| Class | HTTP Status |
|---|---|
| `AnkhDBError` | base (all errors) |
| `ValidationError` | 400 |
| `AuthError` | 401 |
| `PermissionError` | 403 |
| `NotFoundError` | 404 |
| `RateLimitError` | 429 |
| `ServerError` | 5xx |

---

## Authentication

```python
db.register("user@example.com", "password")
db.login("user@example.com", "password")
session = db.get_session()
db.logout()
```

---

## Database — Query Builder

`db.from_collection(name)` returns a **chainable `AnkhQuery`**:

```python
posts = db.from_collection("posts")

# Basic CRUD
doc  = posts.insert({"title": "Hello", "views": 0})
all  = posts.select()
one  = posts.get(doc["id"])
posts.update(doc["id"], {"views": 1})
posts.delete(doc["id"])

# Filters
popular = (db.from_collection("posts")
             .gt("views", 100)
             .eq("status", "published")
             .select())

# Pagination
page2 = db.from_collection("posts").limit(10).offset(10).select()

# Join (embed related collection)
with_comments = (db.from_collection("posts")
                   .join("comments", "postId")   # embed where comments.postId == post.id
                   .select())

# Realtime subscription (blocking)
def on_event(event):
    print(event["event"], event["data"])  # INSERT / UPDATE / DELETE

db.from_collection("posts").subscribe(on_event)
```

---

## Storage

```python
uploaded = db.storage_upload("/path/to/image.png")
print(uploaded["url"])

files = db.storage_list()
db.storage_delete(uploaded["id"])
```

---

## Edge Functions

```python
res = db.invoke_function("greet", {"name": "Alice"})
print(res["result"])
```

---

## License

MIT © KemetSoft
