Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Test

on:
pull_request:
push:
branches:
- main

permissions:
contents: read

jobs:
test:
name: Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
python-version:
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
steps:
- name: Check out repository
uses: actions/checkout@v6.0.2

- name: Set up uv and Python
uses: astral-sh/setup-uv@v10.0.1
with:
python-version: ${{ matrix.python-version }}

- name: Run tests
run: uv run --frozen -- python -W error -m unittest discover -s tests -v
87 changes: 86 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# sanka-sdk

Python SDK for the Sanka API.
Python SDK for Sanka's hosted API and local migration lifecycle.

This package is generated from Sanka's OpenAPI spec using Fern, then packaged locally for `uv` and PyPI.

## Install

Python 3.9 or newer is required. CI tests every minor from Python 3.9 through Python 3.14.

```bash
uv add sanka-sdk
```
Expand All @@ -20,6 +22,89 @@ response = client.public_auth.whoami()
print(response)
```

## Local migration

The hosted API client and local migration adapter are separate surfaces:

| Import | What runs | Authentication |
|---|---|---|
| `from sanka_sdk import SankaClient` | Sanka's hosted HTTP API | API token |
| `SankaMigrate` or `AsyncSankaMigrate` from `sanka_sdk.migrate` | A local `sanka-migrate` subprocess | None |

Install the migration runtime separately, then use the tokenless adapter:

```bash
uv tool install sanka-migrate
```

### Synchronous

```python
from sanka_sdk.migrate import SankaMigrate

migrate = SankaMigrate(cwd="./django-app")

scan = migrate.scan()
plan = migrate.plan(
to="fastapi",
generation="full",
strategy="native",
package_manager="uv",
)
applied = migrate.apply(plan_hash=plan.data["plan_hash"])
tested = migrate.test()
verified = migrate.verify()
```

### Asynchronous

Use `AsyncSankaMigrate` to run the same commands without blocking the event
loop. Cancelling an awaited command also terminates its local CLI process.

```python
import asyncio

from sanka_sdk.migrate import AsyncSankaMigrate


async def main() -> None:
migrate = AsyncSankaMigrate(cwd="./django-app")

await migrate.scan()
plan = await migrate.plan(to="fastapi", generation="full")
await migrate.apply(plan_hash=plan.data["plan_hash"])
await migrate.test()
await migrate.verify()


asyncio.run(main())
```

Each method maps directly to the local runtime:

| Python method | Runtime command | Purpose |
|---|---|---|
| `scan()` | `sanka-migrate scan ... --json` | Inspect the source and write the scan artifact |
| `plan()` | `sanka-migrate plan ... --json` | Create a reviewable plan and plan hash |
| `apply()` | `sanka-migrate apply ... --json` | Generate only from the supplied reviewed plan hash |
| `test()` | `sanka-migrate test ... --json` | Prepare the generated target environment and run its tests |
| `verify()` | `sanka-migrate verify ... --json` | Verify integrity and configured behavior |

Both adapters invoke an argument vector without a shell and never call Sanka's
hosted API. They forward only parameters you provide; defaults, validation,
framework detection, generated-target environments, and plan-hash safety remain
owned by `sanka-migrate`. Every call returns a typed `SankaMigrateResult` with
the `sanka-cli/v1` fields `data`, `artifacts`, `limitations`, and
`next_actions`.

Failures raise `SankaMigrateError`. Its `command`, `exit_code`, `parsed_error`,
and `stderr` attributes distinguish a migration failure (exit `1`), invalid
usage (exit `2`), a missing executable, and an invalid protocol response. The
public classes and methods include docstrings for IDE hover and `help()`.

See the [CLI execution model](https://github.com/sankaHQ/sanka/blob/main/docs/django-to-fastapi.md#cli-and-sdk-execution-model)
and [Sanka developer documentation](https://sanka.com/docs/developers/).

## Regenerate

```bash
Expand Down
Loading