Metadata-Version: 2.4
Name: k9o
Version: 1.0.0
Summary: Kilimanjaro platform SDK — createClient + data DSL + projects + gate + migrations + functions + policies + audit + orgs + me + org + studio (workflows/dashboards) + compute.llms + realtime subscriptions + kibo (ZK vault) + barbican (Keep L2 guardrail) + KError. Full TS-surface parity. Python idiomatic (snake_case; raise KError; async for streams).
Author-email: Kilimanjaro <engineering@kilimanjaro.dev>
License: Apache-2.0
Project-URL: homepage, https://kilimanjaro.dev
Project-URL: repository, https://github.com/k9o-dev/sdk-python
Keywords: kilimanjaro,k9o,sdk,platform
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: httpx>=0.27.0
Requires-Dist: typing_extensions>=4.0; python_version < "3.11"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: respx>=0.21; extra == "dev"
Dynamic: license-file

# k9o — Kilimanjaro platform SDK (Python)

Idiomatic Python SDK. Snake_case methods; raise `KError` on error; data DSL via `client.from_("collection").select()`; typed envelope with meta accessor sugar.

## Status

v0.1.0 — first-pass idiomatic ship (P3 wave 1; reshape from prior `k9o_gate` OpenAPI codegen).

Surfaces shipped:

- `create_client(...)` factory + baseUrl validation per ch13 §7
- `KError(Exception)` with `kerror_from_wire` rehydration
- `Envelope` + typed `Meta` accessor (`MetaCursor` / `MetaSubscription` / `MetaIdempotency` / `MetaWarning` / `MetaTiming` / `MetaContext`) per ch01 §1 + ch13 §5
- URL grammar v2.5.68 (`validate_base_url` / `validate_slug` / `project_path` / `org_path` / `platform_path`)
- Data-plane DSL: `client.from_(collection)` with chainable filter builder (`.eq` / `.neq` / `.gt` / `.gte` / `.lt` / `.lte` / `.in_` / `.not_in` / `.like` / `.ilike` / `.is_` / `.filter`) + `.limit` / `.cursor` / `.count` + terminal verbs (`.select().execute()` / `.insert()` / `.update().eq("id", ...).execute()` / `.delete().eq("id", ...).execute()`)
- `client.projects.{list,create,get,update}`
- `client.ai.embed(input, model=None)` (platform embeddings; requires project_slug)
- `client.gate.{sign_up,sign_in,sign_out,whoami,refresh_token,verify_session,hosted}` (project-scoped auth)
- `client.storage.{create_bucket,get_bucket,list_buckets,update_bucket,delete_bucket}` and `client.storage.from_(bucket).{upload,create_signed_url,list,remove}` (buckets and objects; `_async` twins; requires project_slug; `expires_in` is required, 1..604800)
- Sync (`request`) + async (`request_async`) HTTP via httpx

## Install

```bash
pip install k9o
```

(Pre-launch: install from monorepo source via `pip install -e packages/python`.)

## Quick start

```python
import os
from k9o import create_client, KError

k9o = create_client(
    base_url="https://acme.api.k9o.io",
    api_key=os.environ["K9O_API_KEY"],
    org_slug="acme",
    project_slug="member-portal",
)

try:
    response = k9o.from_("posts").select().limit(10).execute()
    for row in response.data:
        print(row)
    if response.meta.cursor:
        print("next cursor:", response.meta.cursor.next)

    session = k9o.gate.sign_in(email="user@example.com", password="…")
    print("signed in:", session.data["user"]["id"])
except KError as e:
    print(f"[{e.code}] {e.message}: {e.recommendation}")
    raise
```

## Idiomatic shape (per ch13)

| Aspect | This SDK |
|---|---|
| Package name | `k9o` (PyPI) |
| Method casing | `snake_case` |
| Constants | `SCREAMING_SNAKE_CASE` |
| KError delivery | `raise KError` (catch with `except KError as e:`) |
| Data DSL entry | `client.from_("collection")` (`from` is a Python keyword; `from_` is the idiomatic mapping) |
| Filter chain | `.eq()` / `.gt()` / `.in_()` / `.is_()` (`_` suffix on Python reserved-keyword names) |
| Terminal verb | `.execute()` (explicit; async parallel `.execute_async()`) |
| Meta accessor | `response.meta.cursor.next`, `response.meta.timing.total_ms`, `response.meta.context.request_id` (snake_case attrs translated from camelCase wire) |
| Wire format | Always camelCase JSON (ch01 §3.3 invariant) — translated at boundary |
| Runtime | Python 3.10+ |
| HTTP library | httpx (sync + async; modern) |

## License

UNLICENSED — internal to Kilimanjaro.
