kainguru-sdk 0.1.4.dev0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,22 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+
9
+ # Virtualenv
10
+ .venv/
11
+ venv/
12
+
13
+ # Tooling caches
14
+ .pytest_cache/
15
+ .mypy_cache/
16
+ .ruff_cache/
17
+ .coverage
18
+ htmlcov/
19
+
20
+ # OS
21
+ .DS_Store
22
+ Thumbs.db
@@ -0,0 +1,72 @@
1
+ # Maintaining kainguru-sdk
2
+
3
+ Internal notes for building, testing, and publishing the Python SDK.
4
+
5
+ ## Layout
6
+
7
+ ```
8
+ kainguru-sdk-python/
9
+ pyproject.toml # PEP 621 metadata, hatchling build backend
10
+ Makefile # generate / lint / typecheck / test / build
11
+ src/kainguru/
12
+ __init__.py # public exports
13
+ _config.py # KainguruConfig: api key + base URL resolution
14
+ _environment.py # Environment enum + base-URL map
15
+ _transport.py # httpx wrappers, auth, retry, error mapping, unwrap
16
+ _errors.py # exception hierarchy
17
+ _polling.py # sync + async await_completion engines
18
+ models.py # GENERATED (datamodel-code-generator), pydantic v2
19
+ client.py # KainguruClient (sync)
20
+ async_client.py # AsyncKainguruClient
21
+ resources/ # ExecutionsResource / FineTuningResource (+ async)
22
+ py.typed # PEP 561 marker
23
+ tests/
24
+ resources/openapi.json # pinned spec snapshot
25
+ ```
26
+
27
+ ## Setup
28
+
29
+ ```bash
30
+ python -m venv .venv && source .venv/bin/activate
31
+ make install # pip install -e ".[dev]"
32
+ ```
33
+
34
+ ## Local workflow
35
+
36
+ ```bash
37
+ make generate # regenerate src/kainguru/models.py from the pinned spec
38
+ make lint # ruff check
39
+ make typecheck # mypy (strict)
40
+ make test # pytest (sync + async via pytest-asyncio)
41
+ make build # wheel + sdist into dist/
42
+ ```
43
+
44
+ ## Model-drift check (CI)
45
+
46
+ `src/kainguru/models.py` is committed. CI runs `make generate` and
47
+ `git diff --exit-code src/kainguru/models.py` to detect drift against
48
+ `tests/resources/openapi.json`. Update the pinned spec and regenerate when the
49
+ backend contract changes.
50
+
51
+ > Note: `datamodel-code-generator` emits PEP 604 (`X | None`) syntax, so the
52
+ > package floor is **Python 3.10** (`requires-python = ">=3.10"`).
53
+
54
+ ## httpx base URL gotcha
55
+
56
+ httpx resolves request paths against `base_url` per RFC 3986, so the base URL
57
+ **must end with `/`** or the `/api` context path is dropped. `KainguruConfig`
58
+ normalizes this; request paths are written without a leading slash
59
+ (`"v1/executions"`).
60
+
61
+ ## Publishing
62
+
63
+ - PyPI name: `kainguru-sdk`; import name: `kainguru`.
64
+ - Automated via GitHub Actions on tag push; see
65
+ `.github/workflows/kainguru-sdk-python-publish.yml` and the step-by-step guide in
66
+ `.claude/plans/kainguru-pypi-publish-steps.md`.
67
+
68
+ ```bash
69
+ # Manual publish (fallback)
70
+ make build
71
+ python -m twine upload dist/*
72
+ ```
@@ -0,0 +1,28 @@
1
+ .PHONY: install generate lint typecheck test build all
2
+
3
+ install:
4
+ python -m pip install -e ".[dev]"
5
+
6
+ # Regenerate pydantic models from the pinned OpenAPI spec.
7
+ generate:
8
+ datamodel-codegen \
9
+ --input tests/resources/openapi.json \
10
+ --input-file-type openapi \
11
+ --output src/kainguru/models.py \
12
+ --output-model-type pydantic_v2.BaseModel \
13
+ --target-python-version 3.10 \
14
+ --disable-timestamp
15
+
16
+ lint:
17
+ ruff check src tests
18
+
19
+ typecheck:
20
+ mypy
21
+
22
+ test:
23
+ pytest
24
+
25
+ build:
26
+ python -m build
27
+
28
+ all: generate lint typecheck test build
@@ -0,0 +1,251 @@
1
+ Metadata-Version: 2.4
2
+ Name: kainguru-sdk
3
+ Version: 0.1.4.dev0
4
+ Summary: Python SDK for the Kainguru ML platform — run models and fine-tune them.
5
+ Project-URL: Homepage, https://kainguru.com
6
+ Project-URL: Repository, https://github.com/kainguru/kainguru
7
+ Author: Kainguru
8
+ License: MIT
9
+ Keywords: fine-tuning,kainguru,machine-learning,ml,sdk
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Typing :: Typed
17
+ Requires-Python: >=3.10
18
+ Requires-Dist: httpx>=0.27
19
+ Requires-Dist: pydantic>=2.5
20
+ Provides-Extra: dev
21
+ Requires-Dist: build>=1.2; extra == 'dev'
22
+ Requires-Dist: datamodel-code-generator>=0.25; extra == 'dev'
23
+ Requires-Dist: mypy>=1.11; extra == 'dev'
24
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
25
+ Requires-Dist: pytest>=8.0; extra == 'dev'
26
+ Requires-Dist: respx>=0.21; extra == 'dev'
27
+ Requires-Dist: ruff>=0.6; extra == 'dev'
28
+ Description-Content-Type: text/markdown
29
+
30
+ # kainguru-sdk
31
+
32
+ Python SDK for the [Kainguru](https://kainguru.com) ML platform — run models and
33
+ fine-tune them from any Python application.
34
+
35
+ - Python 3.10+
36
+ - **Sync and async** clients with an identical surface (`KainguruClient`, `AsyncKainguruClient`)
37
+ - Typed pydantic v2 models
38
+ - Built-in polling with configurable timeout and backoff
39
+ - Automatic retry on 429 / 5xx with exponential backoff (honors `Retry-After`)
40
+
41
+ Covers `/v1/executions` and `/v1/fine-tuning`.
42
+
43
+ ---
44
+
45
+ ## Installation
46
+
47
+ ```bash
48
+ pip install kainguru-sdk
49
+ ```
50
+
51
+ Import name is `kainguru`:
52
+
53
+ ```python
54
+ from kainguru import KainguruClient
55
+ ```
56
+
57
+ ---
58
+
59
+ ## Authentication
60
+
61
+ You must pass **both** an API key and the base URL explicitly. The API key is issued
62
+ from the Kainguru Dashboard (it begins with `kg_`); the base URL is the full host
63
+ including the `/api` context path:
64
+
65
+ ```python
66
+ from kainguru import KainguruClient
67
+
68
+ client = KainguruClient(
69
+ api_key="kg_your_api_key",
70
+ base_url="https://your-host/api",
71
+ )
72
+ ```
73
+
74
+ Both fields are required. If either is missing or blank, the constructor raises
75
+ `KainguruConfigError` (fail fast). There are no defaults, environment presets, or
76
+ environment-variable fallbacks.
77
+
78
+ `KainguruClient` is a context manager — use `with` to close the HTTP pool automatically.
79
+
80
+ ---
81
+
82
+ ## Quick start (sync)
83
+
84
+ ```python
85
+ from kainguru import KainguruClient
86
+
87
+ with KainguruClient(
88
+ api_key="kg_your_api_key",
89
+ base_url="https://your-host/api",
90
+ ) as client:
91
+ submitted = client.executions.execute(
92
+ "my-mlflow-id",
93
+ {"prompt": "hello world"},
94
+ output_format="json",
95
+ )
96
+
97
+ done = client.executions.await_completion(submitted.id)
98
+
99
+ print(done.status) # ModelStatus.COMPLETED / FAILED
100
+ print(done.execution.output) # model output
101
+ ```
102
+
103
+ `ml_flow_id` (first positional arg) is the model's **MLflow id** — the identifier the
104
+ Dashboard shows for the model.
105
+
106
+ ## Quick start (async)
107
+
108
+ ```python
109
+ import asyncio
110
+ from kainguru import AsyncKainguruClient
111
+
112
+
113
+ async def main():
114
+ async with AsyncKainguruClient(
115
+ api_key="kg_your_api_key", base_url="https://your-host/api"
116
+ ) as client:
117
+ submitted = await client.executions.execute(
118
+ "my-mlflow-id", {"prompt": "hello world"}, output_format="json"
119
+ )
120
+ done = await client.executions.await_completion(submitted.id)
121
+ print(done.status)
122
+
123
+
124
+ asyncio.run(main())
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Executions API
130
+
131
+ ```python
132
+ exec = client.executions
133
+
134
+ # Run a model (returns immediately, typically PENDING)
135
+ pending = exec.execute(ml_flow_id, input, output_format=None, exec_id=None)
136
+
137
+ # Poll the current status once
138
+ current = exec.get(id)
139
+
140
+ # Block until COMPLETED or FAILED (default: 2 s interval, 5 min timeout)
141
+ done = exec.await_completion(id)
142
+
143
+ # Block with custom poll options
144
+ done = exec.await_completion(id, poll_interval=1.0, timeout=60.0)
145
+ ```
146
+
147
+ **Terminal statuses:** `COMPLETED`, `FAILED`. `REGISTERED` is treated as non-terminal.
148
+ A `FAILED` job *returns* from `await_completion` — inspect `dto.status`; it is not raised.
149
+
150
+ ---
151
+
152
+ ## Fine-Tuning API
153
+
154
+ ```python
155
+ ft = client.fine_tuning
156
+
157
+ # Start fine-tuning
158
+ pending = ft.execute(model_id, "my-fine-tuned-variant", input)
159
+
160
+ # Get status / poll until done
161
+ current = ft.get_status(id)
162
+ done = ft.await_completion(id)
163
+ ```
164
+
165
+ (The async client exposes the same methods with `await`.)
166
+
167
+ ---
168
+
169
+ ## Polling options
170
+
171
+ ```python
172
+ client.executions.await_completion(
173
+ id,
174
+ poll_interval=2.0, # base interval between polls in s (default 2.0)
175
+ timeout=300.0, # total wall-clock timeout in s (default 300.0)
176
+ backoff=1.5, # multiply interval each attempt (default 1.0 = fixed)
177
+ max_interval=30.0, # cap on interval after backoff (default 30.0)
178
+ )
179
+ ```
180
+
181
+ On timeout, `await_completion` raises `KainguruTimeoutError`, which carries the last DTO
182
+ seen via `err.last_dto`.
183
+
184
+ ---
185
+
186
+ ## Configuration
187
+
188
+ ```python
189
+ client = KainguruClient(
190
+ api_key="kg_...", # required, explicit key
191
+ base_url="https://your-host/api", # required, full host incl. /api context path
192
+ timeout=30.0, # per-request timeout in s
193
+ max_retries=3, # retries on 429 / 5xx / network
194
+ )
195
+ ```
196
+
197
+ Both `api_key` and `base_url` are required and must be passed explicitly — there are no
198
+ defaults or environment-variable fallbacks. The base URL must be the full host including
199
+ the dashboard's `/api` context path.
200
+
201
+ Every method also accepts a per-request `api_key=` to override the client key for one call.
202
+
203
+ ---
204
+
205
+ ## Error handling
206
+
207
+ All errors extend `KainguruError`.
208
+
209
+ | Error | When |
210
+ |---|---|
211
+ | `KainguruConfigError` | Missing/invalid configuration (e.g. no API key) |
212
+ | `KainguruAPIError` | Non-2xx HTTP response, or `success=false` in the body. Has `status_code`, `body`, `api_code` |
213
+ | `KainguruAuthError` | 401 / 403 (subclass of `KainguruAPIError`) |
214
+ | `KainguruNotFoundError` | 404 (subclass of `KainguruAPIError`) |
215
+ | `KainguruRateLimitError` | 429 (subclass of `KainguruAPIError`); exposes `retry_after` |
216
+ | `KainguruTimeoutError` | `await_completion` exceeded `timeout`; carries `last_dto` |
217
+ | `KainguruConnectionError` | Network / transport failure; chained via `from` |
218
+
219
+ ```python
220
+ from kainguru import (
221
+ KainguruAPIError,
222
+ KainguruNotFoundError,
223
+ KainguruTimeoutError,
224
+ )
225
+
226
+ try:
227
+ result = client.executions.await_completion(id)
228
+ if result.status.value == "FAILED":
229
+ ... # FAILED is returned, not raised — inspect the result
230
+ except KainguruNotFoundError as e:
231
+ print("not found:", e.status_code)
232
+ except KainguruAPIError as e:
233
+ print(f"HTTP {e.status_code}: {e.body}")
234
+ except KainguruTimeoutError as e:
235
+ print("timed out; last:", e.last_dto)
236
+ ```
237
+
238
+ The SDK automatically retries `429` and `5xx` responses up to 3 times with exponential
239
+ backoff (base 1 s, doubling per attempt); `Retry-After` headers are respected.
240
+
241
+ ---
242
+
243
+ ## Limitations (v0.1.0)
244
+
245
+ - Cancel endpoints are not exposed yet (they require JWT/Keycloak auth, not an API key).
246
+ - `input` parameters are untyped (`dict[str, Any]`).
247
+ - `output_format` is a free `str`; allowed values are not yet enumerated by the backend.
248
+
249
+ ---
250
+
251
+ > Building or publishing the SDK yourself? See **[MAINTAINERS.md](MAINTAINERS.md)**.
@@ -0,0 +1,222 @@
1
+ # kainguru-sdk
2
+
3
+ Python SDK for the [Kainguru](https://kainguru.com) ML platform — run models and
4
+ fine-tune them from any Python application.
5
+
6
+ - Python 3.10+
7
+ - **Sync and async** clients with an identical surface (`KainguruClient`, `AsyncKainguruClient`)
8
+ - Typed pydantic v2 models
9
+ - Built-in polling with configurable timeout and backoff
10
+ - Automatic retry on 429 / 5xx with exponential backoff (honors `Retry-After`)
11
+
12
+ Covers `/v1/executions` and `/v1/fine-tuning`.
13
+
14
+ ---
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ pip install kainguru-sdk
20
+ ```
21
+
22
+ Import name is `kainguru`:
23
+
24
+ ```python
25
+ from kainguru import KainguruClient
26
+ ```
27
+
28
+ ---
29
+
30
+ ## Authentication
31
+
32
+ You must pass **both** an API key and the base URL explicitly. The API key is issued
33
+ from the Kainguru Dashboard (it begins with `kg_`); the base URL is the full host
34
+ including the `/api` context path:
35
+
36
+ ```python
37
+ from kainguru import KainguruClient
38
+
39
+ client = KainguruClient(
40
+ api_key="kg_your_api_key",
41
+ base_url="https://your-host/api",
42
+ )
43
+ ```
44
+
45
+ Both fields are required. If either is missing or blank, the constructor raises
46
+ `KainguruConfigError` (fail fast). There are no defaults, environment presets, or
47
+ environment-variable fallbacks.
48
+
49
+ `KainguruClient` is a context manager — use `with` to close the HTTP pool automatically.
50
+
51
+ ---
52
+
53
+ ## Quick start (sync)
54
+
55
+ ```python
56
+ from kainguru import KainguruClient
57
+
58
+ with KainguruClient(
59
+ api_key="kg_your_api_key",
60
+ base_url="https://your-host/api",
61
+ ) as client:
62
+ submitted = client.executions.execute(
63
+ "my-mlflow-id",
64
+ {"prompt": "hello world"},
65
+ output_format="json",
66
+ )
67
+
68
+ done = client.executions.await_completion(submitted.id)
69
+
70
+ print(done.status) # ModelStatus.COMPLETED / FAILED
71
+ print(done.execution.output) # model output
72
+ ```
73
+
74
+ `ml_flow_id` (first positional arg) is the model's **MLflow id** — the identifier the
75
+ Dashboard shows for the model.
76
+
77
+ ## Quick start (async)
78
+
79
+ ```python
80
+ import asyncio
81
+ from kainguru import AsyncKainguruClient
82
+
83
+
84
+ async def main():
85
+ async with AsyncKainguruClient(
86
+ api_key="kg_your_api_key", base_url="https://your-host/api"
87
+ ) as client:
88
+ submitted = await client.executions.execute(
89
+ "my-mlflow-id", {"prompt": "hello world"}, output_format="json"
90
+ )
91
+ done = await client.executions.await_completion(submitted.id)
92
+ print(done.status)
93
+
94
+
95
+ asyncio.run(main())
96
+ ```
97
+
98
+ ---
99
+
100
+ ## Executions API
101
+
102
+ ```python
103
+ exec = client.executions
104
+
105
+ # Run a model (returns immediately, typically PENDING)
106
+ pending = exec.execute(ml_flow_id, input, output_format=None, exec_id=None)
107
+
108
+ # Poll the current status once
109
+ current = exec.get(id)
110
+
111
+ # Block until COMPLETED or FAILED (default: 2 s interval, 5 min timeout)
112
+ done = exec.await_completion(id)
113
+
114
+ # Block with custom poll options
115
+ done = exec.await_completion(id, poll_interval=1.0, timeout=60.0)
116
+ ```
117
+
118
+ **Terminal statuses:** `COMPLETED`, `FAILED`. `REGISTERED` is treated as non-terminal.
119
+ A `FAILED` job *returns* from `await_completion` — inspect `dto.status`; it is not raised.
120
+
121
+ ---
122
+
123
+ ## Fine-Tuning API
124
+
125
+ ```python
126
+ ft = client.fine_tuning
127
+
128
+ # Start fine-tuning
129
+ pending = ft.execute(model_id, "my-fine-tuned-variant", input)
130
+
131
+ # Get status / poll until done
132
+ current = ft.get_status(id)
133
+ done = ft.await_completion(id)
134
+ ```
135
+
136
+ (The async client exposes the same methods with `await`.)
137
+
138
+ ---
139
+
140
+ ## Polling options
141
+
142
+ ```python
143
+ client.executions.await_completion(
144
+ id,
145
+ poll_interval=2.0, # base interval between polls in s (default 2.0)
146
+ timeout=300.0, # total wall-clock timeout in s (default 300.0)
147
+ backoff=1.5, # multiply interval each attempt (default 1.0 = fixed)
148
+ max_interval=30.0, # cap on interval after backoff (default 30.0)
149
+ )
150
+ ```
151
+
152
+ On timeout, `await_completion` raises `KainguruTimeoutError`, which carries the last DTO
153
+ seen via `err.last_dto`.
154
+
155
+ ---
156
+
157
+ ## Configuration
158
+
159
+ ```python
160
+ client = KainguruClient(
161
+ api_key="kg_...", # required, explicit key
162
+ base_url="https://your-host/api", # required, full host incl. /api context path
163
+ timeout=30.0, # per-request timeout in s
164
+ max_retries=3, # retries on 429 / 5xx / network
165
+ )
166
+ ```
167
+
168
+ Both `api_key` and `base_url` are required and must be passed explicitly — there are no
169
+ defaults or environment-variable fallbacks. The base URL must be the full host including
170
+ the dashboard's `/api` context path.
171
+
172
+ Every method also accepts a per-request `api_key=` to override the client key for one call.
173
+
174
+ ---
175
+
176
+ ## Error handling
177
+
178
+ All errors extend `KainguruError`.
179
+
180
+ | Error | When |
181
+ |---|---|
182
+ | `KainguruConfigError` | Missing/invalid configuration (e.g. no API key) |
183
+ | `KainguruAPIError` | Non-2xx HTTP response, or `success=false` in the body. Has `status_code`, `body`, `api_code` |
184
+ | `KainguruAuthError` | 401 / 403 (subclass of `KainguruAPIError`) |
185
+ | `KainguruNotFoundError` | 404 (subclass of `KainguruAPIError`) |
186
+ | `KainguruRateLimitError` | 429 (subclass of `KainguruAPIError`); exposes `retry_after` |
187
+ | `KainguruTimeoutError` | `await_completion` exceeded `timeout`; carries `last_dto` |
188
+ | `KainguruConnectionError` | Network / transport failure; chained via `from` |
189
+
190
+ ```python
191
+ from kainguru import (
192
+ KainguruAPIError,
193
+ KainguruNotFoundError,
194
+ KainguruTimeoutError,
195
+ )
196
+
197
+ try:
198
+ result = client.executions.await_completion(id)
199
+ if result.status.value == "FAILED":
200
+ ... # FAILED is returned, not raised — inspect the result
201
+ except KainguruNotFoundError as e:
202
+ print("not found:", e.status_code)
203
+ except KainguruAPIError as e:
204
+ print(f"HTTP {e.status_code}: {e.body}")
205
+ except KainguruTimeoutError as e:
206
+ print("timed out; last:", e.last_dto)
207
+ ```
208
+
209
+ The SDK automatically retries `429` and `5xx` responses up to 3 times with exponential
210
+ backoff (base 1 s, doubling per attempt); `Retry-After` headers are respected.
211
+
212
+ ---
213
+
214
+ ## Limitations (v0.1.0)
215
+
216
+ - Cancel endpoints are not exposed yet (they require JWT/Keycloak auth, not an API key).
217
+ - `input` parameters are untyped (`dict[str, Any]`).
218
+ - `output_format` is a free `str`; allowed values are not yet enumerated by the backend.
219
+
220
+ ---
221
+
222
+ > Building or publishing the SDK yourself? See **[MAINTAINERS.md](MAINTAINERS.md)**.
@@ -0,0 +1,65 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "kainguru-sdk"
7
+ version = "0.1.4.dev0"
8
+ description = "Python SDK for the Kainguru ML platform — run models and fine-tune them."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "Kainguru" }]
13
+ keywords = ["kainguru", "ml", "machine-learning", "sdk", "fine-tuning"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.10",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Operating System :: OS Independent",
21
+ "Typing :: Typed",
22
+ ]
23
+ dependencies = [
24
+ "httpx>=0.27",
25
+ "pydantic>=2.5",
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://kainguru.com"
30
+ Repository = "https://github.com/kainguru/kainguru"
31
+
32
+ [project.optional-dependencies]
33
+ dev = [
34
+ "pytest>=8.0",
35
+ "pytest-asyncio>=0.23",
36
+ "respx>=0.21",
37
+ "ruff>=0.6",
38
+ "mypy>=1.11",
39
+ "build>=1.2",
40
+ "datamodel-code-generator>=0.25",
41
+ ]
42
+
43
+ [tool.hatch.build.targets.wheel]
44
+ packages = ["src/kainguru"]
45
+
46
+ [tool.pytest.ini_options]
47
+ asyncio_mode = "auto"
48
+ testpaths = ["tests"]
49
+
50
+ [tool.ruff]
51
+ line-length = 100
52
+ src = ["src", "tests"]
53
+
54
+ [tool.ruff.lint]
55
+ select = ["E", "F", "I", "UP", "B"]
56
+
57
+ [tool.mypy]
58
+ python_version = "3.10"
59
+ strict = true
60
+ files = ["src/kainguru"]
61
+ # models.py is generated by datamodel-code-generator; its output (e.g. constr(...)
62
+ # constraint types) isn't static-type clean, so it's excluded from mypy checking.
63
+ [[tool.mypy.overrides]]
64
+ module = "kainguru.models"
65
+ ignore_errors = true
@@ -0,0 +1,48 @@
1
+ """Kainguru Python SDK — run models and fine-tune them on the Kainguru ML platform."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ._config import KainguruConfig
6
+ from ._errors import (
7
+ KainguruAPIError,
8
+ KainguruAuthError,
9
+ KainguruConfigError,
10
+ KainguruConnectionError,
11
+ KainguruError,
12
+ KainguruNotFoundError,
13
+ KainguruRateLimitError,
14
+ KainguruTimeoutError,
15
+ )
16
+ from .async_client import AsyncKainguruClient
17
+ from .client import KainguruClient
18
+ from .models import (
19
+ ApplicationDto,
20
+ ExecutionResultDto,
21
+ ModelExecResponseDto,
22
+ ModelFineTunedDetailDto,
23
+ ModelStatus,
24
+ )
25
+
26
+ __version__ = "0.1.0"
27
+
28
+ __all__ = [
29
+ "__version__",
30
+ "KainguruClient",
31
+ "AsyncKainguruClient",
32
+ "KainguruConfig",
33
+ # Errors
34
+ "KainguruError",
35
+ "KainguruConfigError",
36
+ "KainguruAPIError",
37
+ "KainguruAuthError",
38
+ "KainguruNotFoundError",
39
+ "KainguruRateLimitError",
40
+ "KainguruTimeoutError",
41
+ "KainguruConnectionError",
42
+ # Models
43
+ "ModelStatus",
44
+ "ModelExecResponseDto",
45
+ "ModelFineTunedDetailDto",
46
+ "ApplicationDto",
47
+ "ExecutionResultDto",
48
+ ]