Metadata-Version: 2.4
Name: rafikidb
Version: 0.1.0
Summary: Typed Python client for RafikiDB - data, auth, realtime, storage, env vars, secrets, webhooks, edge functions and payments.
Author: RafikiDB
License: MIT
Keywords: baas,backend,database,rafikidb,realtime
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Provides-Extra: realtime
Requires-Dist: websockets>=12.0; extra == 'realtime'
Provides-Extra: test
Requires-Dist: pytest>=8.0; extra == 'test'
Description-Content-Type: text/markdown

# rafikidb

Typed Python client for [RafikiDB](https://rafikidb.com) - data, auth,
realtime, storage, environment variables, secrets, webhooks, edge functions
and payments.

- **Zero required dependencies** (stdlib HTTP)
- Optional `websockets` for the WebSocket realtime transport
- Same envelope and error model as the REST API
- Python 3.10+

## Install

```bash
pip install rafikidb            # core
pip install rafikidb[realtime]  # with WebSocket realtime
```

## Quick start

```python
from rafikidb import create_client

db = create_client(
    project_id="5c73dab0-...",
    api_key="raf_live_...",
    base_url="https://api.rafikidb.com/api/v1",  # optional
)
```

Every call returns an `Envelope`:

```python
rows = db.from_("profiles").select("id, nationality").eq("nationality", "Tanzania").limit(25).execute()
rows.success      # True
rows.data         # list of dicts
rows.message      # "Request was successful"
```

Failures raise `RafikiDBError` with `message`, `status`, `code` and `errors`.

## Data

```python
# Filters: eq, neq, gt, gte, lt, lte, like, ilike, is_null, is_not_null, in_
db.from_("profiles").eq("nationality", "Tanzania").is_not_null("user_id")

# Ordering and pagination
db.from_("profiles").order("created_at", ascending=False).limit(50).offset(100)

# Keyset pagination (O(1) per page on large tables)
db.from_("logs").select("id").limit(100).cursor(last_id)

# Joins (column-based, no SQL)
from rafikidb import JoinSpec
rows = (
    db.from_("messages")
    .select("id as message_id, message, users.full_name as full_name")
    .join(JoinSpec(table="users", from_column="user_id", to_column="id"))
    .limit(20)
).execute()
# rows.data[i]["full_name"]

# Row operations
db.from_("profiles").get(record_id)
db.from_("profiles").single()
db.from_("profiles").head()              # {"count": n}
db.from_("profiles").insert({...})       # single or list
db.from_("profiles").update({...}).eq("id", record_id)
db.from_("profiles").delete().eq("id", record_id)
```

## Auth

```python
session = db.auth.signup(
    email="user@example.com", password="strong-pass1",
    full_name="Asha Mwinyi", phone="+255712345678",
)
session = db.auth.login(email="user@example.com", password="strong-pass1")

# The session is stored on the client and sent with every request,
# so RLS sees the logged-in user.
db.client.access_token     # the project-user JWT

db.auth.sign_out()

# OTP
db.auth.otp_request("+255712345678")
db.auth.otp_verify(phone="+255712345678", code="123456", full_name="Asha Mwinyi")

# Password reset
db.auth.reset_password("user@example.com")
db.auth.confirm_reset_password(email="user@example.com", code="123456", new_password="brand-new-pass1")
```

## Realtime

```python
def on_event(event):
    print(event.type, event.table, event.record)

sub = db.realtime.subscribe("messages", on_event, events=["INSERT", "DELETE"])

# Stop listening (or sub.wait() to block)
sub.close()
```

Default transport: WebSocket when `websockets` is installed, SSE otherwise.

```python
db.realtime.subscribe("messages", on_event, transport="sse")
db.realtime.subscribe("messages", on_event, transport="websocket")
```

## Storage / env / secrets / webhooks / functions / payments

```python
db.storage.create_bucket(name="Avatars", slug="avatars", is_public=True)
db.storage.signed_upload_url(bucket_id=..., object_name="user-1.png")

db.env.set("STRIPE_KEY", "sk_test_123", environment="production")
db.env.bulk_set("development", {"DEBUG": "true"})

db.secrets.set(key="API_SECRET", value="s3cr3t")
db.secrets.reveal(secret_id)

db.webhooks.create(name="order.created", url="https://myapp.com/hooks/orders", events=["order.created"])
db.webhooks.list_deliveries(webhook_id)

db.functions.create(name="hello", runtime="javascript", code="...")
db.functions.deploy(fn_id)
db.functions.invoke(fn_id, body='{"name":"Asha"}')

db.payments.stk_push(phone="+255712345678", amount=5000, description="Order #123")
db.payments.snippe_status(reference)
db.payments.list_transactions()
```

## Development

```bash
pip install -e ".[test]"
python -m unittest discover -s tests -q
```