Metadata-Version: 2.4
Name: imagineers-cards-sdk
Version: 0.1.0
Summary: Python SDK for Cards — create and manage projects, chain cards, and work items with a cards_pat token
Project-URL: Homepage, https://www.imagineers.cards
License-Expression: MIT
Keywords: cards,imagineers,project-management,sdk
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# imagineers-cards-sdk

The Python SDK for [Cards](https://www.imagineers.cards). Create and manage
projects, chain cards, and work items from any product — Cards becomes a database
you write to with a single API key. Zero runtime dependencies.

## Install

```bash
pip install imagineers-cards-sdk
```

## Authenticate

The SDK uses the same token the `cards` CLI stores at login. Mint one at
[imagineers.cards/cli-token](https://www.imagineers.cards/cli-token) — it starts
with `cards_pat_`. Keep it secret; it grants full read/write to your account.

```python
import os
from cards_sdk import CardsClient

cards = CardsClient(api_key=os.environ["CARDS_API_KEY"])
```

## Projects

```python
cards.projects.create("my-app", name="My App")
cards.projects.list()
cards.projects.get("my-app")
cards.projects.update("my-app", name="Renamed")
cards.projects.delete("my-app")
```

A project with subprojects cannot be deleted until its children are removed or
reparented — the API returns a `409` and the SDK raises a `CardsApiError`.

## Chain cards

The chain is the project's append-only log of decisions, observations,
invariants, questions, and artifacts.

```python
card = cards.chain.create(
    "my-app",
    title="We chose Postgres over SQLite for the write throughput",
    kind="decision",
    body="Alternatives considered…",
)

cards.chain.list("my-app", kind="decision", limit=20)
cards.chain.get("my-app", card.slug)
cards.chain.update("my-app", card.slug, status="published")
cards.chain.delete("my-app", card.slug)
```

## Work items

Work items are the ephemeral do-and-toss layer parallel to the chain.

```python
item = cards.work.create("my-app", title="Ship the import flow", labels=["feature"])

cards.work.list("my-app", status="todo")
cards.work.update("my-app", item.id, status="done")
cards.work.delete("my-app", item.id)
```

## Errors

Every non-2xx response raises a `CardsApiError` carrying the HTTP status and the
request that failed.

```python
from cards_sdk import CardsApiError

try:
    cards.projects.create("taken")
except CardsApiError as error:
    if error.status == 409:
        ...  # slug already exists
```

## Configuration

| Argument   | Default                                       | Notes                               |
| ---------- | --------------------------------------------- | ----------------------------------- |
| `api_key`  | _(required)_                                  | A `cards_pat_` token.               |
| `base_url` | `https://cards-api.krishnanandb.workers.dev`  | Point at a local or staging Worker. |
| `timeout`  | `30.0`                                         | Per-request timeout in seconds.     |

Returned values are frozen dataclasses (`Project`, `CreatedProject`,
`ProjectSummary`, `Card`, `WorkItem`). Requires Python 3.10+.
```

## Development

```bash
uv sync
uv run pytest            # unit tests
uv run ruff check        # lint
CARDS_API_KEY=… uv run pytest tests/smoke   # live round-trip against prod
```
