cubic-sdk 0.3.2__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,21 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+ - run: pip install -e ".[dev]"
21
+ - run: pytest -q
@@ -0,0 +1,69 @@
1
+ # Publishes to PyPI via trusted publishing (OIDC) — no API token stored anywhere.
2
+ # Triggered by pushing a version tag (git tag -a vX.Y.Z && git push --follow-tags).
3
+ #
4
+ # One-time setup on pypi.org before the first run:
5
+ # Account → Publishing → "Add a new pending publisher":
6
+ # project: cubic-sdk
7
+ # owner: cubic-zone
8
+ # repository: cubic-python
9
+ # workflow: publish.yml
10
+ # environment: pypi
11
+
12
+ name: Publish to PyPI
13
+
14
+ on:
15
+ push:
16
+ tags: ["v*"]
17
+
18
+ jobs:
19
+ test:
20
+ runs-on: ubuntu-latest
21
+ strategy:
22
+ fail-fast: false
23
+ matrix:
24
+ python-version: ["3.10", "3.13"]
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+ - uses: actions/setup-python@v5
28
+ with:
29
+ python-version: ${{ matrix.python-version }}
30
+ - run: pip install -e ".[dev]"
31
+ - run: pytest -q
32
+
33
+ build:
34
+ needs: test
35
+ runs-on: ubuntu-latest
36
+ steps:
37
+ - uses: actions/checkout@v4
38
+ - uses: actions/setup-python@v5
39
+ with:
40
+ python-version: "3.12"
41
+ - name: Check tag matches package version
42
+ run: |
43
+ PKG_VERSION=$(python -c "exec(open('src/cubic/_version.py').read()); print(__version__)")
44
+ TAG_VERSION="${GITHUB_REF_NAME#v}"
45
+ if [ "$PKG_VERSION" != "$TAG_VERSION" ]; then
46
+ echo "Tag $GITHUB_REF_NAME does not match package version $PKG_VERSION" >&2
47
+ exit 1
48
+ fi
49
+ - run: pip install build
50
+ - run: python -m build
51
+ - uses: actions/upload-artifact@v4
52
+ with:
53
+ name: dist
54
+ path: dist/
55
+
56
+ publish:
57
+ needs: build
58
+ runs-on: ubuntu-latest
59
+ environment:
60
+ name: pypi
61
+ url: https://pypi.org/project/cubic-sdk/
62
+ permissions:
63
+ id-token: write # OIDC token for PyPI trusted publishing
64
+ steps:
65
+ - uses: actions/download-artifact@v4
66
+ with:
67
+ name: dist
68
+ path: dist/
69
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,18 @@
1
+ # Environments
2
+ .venv/
3
+ venv/
4
+
5
+ # Build artifacts
6
+ dist/
7
+ build/
8
+ *.egg-info/
9
+
10
+ # Caches
11
+ __pycache__/
12
+ *.py[cod]
13
+ .pytest_cache/
14
+ .mypy_cache/
15
+ .ruff_cache/
16
+
17
+ # OS
18
+ .DS_Store
@@ -0,0 +1,43 @@
1
+ # Changelog
2
+
3
+ ## 0.3.2 (2026-07-12)
4
+
5
+ - First PyPI release: `pip install cubic-sdk`.
6
+ - Repository moved to the `cubic-zone` GitHub organization; project URLs
7
+ updated. CI and trusted-publishing workflows added. No code changes.
8
+
9
+ ## 0.3.1 (2026-07-12)
10
+
11
+ - The default `base_url` is now the hosted API (`https://api.cubic.zone`)
12
+ instead of the local dev server. Local development now requires an explicit
13
+ `base_url="http://localhost:8010"` or `CUBIC_BASE_URL`.
14
+
15
+ ## 0.3.0 (2026-07-11)
16
+
17
+ - `client.models` resource: `list()` (public catalog, cached in-process for
18
+ 1h, `provider=` filter, `force_refresh=`) and `retrieve(model_name)`
19
+ (client-side lookup with `provider=` disambiguation and did-you-mean
20
+ suggestions via `ModelNotFoundError`).
21
+ - PyPI packaging prep: `py.typed` marker (PEP 561), trove classifiers,
22
+ project URLs, changelog.
23
+
24
+ ## 0.2.0 (2026-07-10)
25
+
26
+ - `AsyncCubic`: the full client surface as coroutines, sharing retry and
27
+ parsing logic with the sync client.
28
+ - `completions.wait(request_id)` and the `result.wait()` shortcut: poll for a
29
+ queued run's persisted record with backoff; raises `CompletionError` for
30
+ error records and `WaitTimeoutError` on deadline.
31
+ - `cubic.webhooks`: `verify()` / `verify_signature()` / `parse()` for signed
32
+ callback deliveries (`X-Maxwell-Signature`, HMAC-SHA256 over the raw body),
33
+ plus `derive_project_secret()` for self-hosted deployments.
34
+
35
+ ## 0.1.0 (2026-07-09)
36
+
37
+ - Initial release: `Cubic` client with `completions.create` /
38
+ `completions.retrieve` and `cubes.retrieve`.
39
+ - Unified cube/polycube execution: one `create()` call for both kinds, typed
40
+ `CompletionResult` / `PolycubeResult` with a common `result.content`.
41
+ - Typed exception hierarchy incl. pipeline errors surfaced from HTTP 200
42
+ bodies (`MissingVariableError`, `ProviderError`, `CubeNotFoundError`…).
43
+ - Automatic idempotent retries via auto-generated `client_request_id`.
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.4
2
+ Name: cubic-sdk
3
+ Version: 0.3.2
4
+ Summary: Official Python SDK for Cubic — run your Cubes and Polycubes from any application.
5
+ Project-URL: Homepage, https://cubic.zone
6
+ Project-URL: Documentation, https://cubic.zone/docs
7
+ Project-URL: Repository, https://github.com/cubic-zone/cubic-python
8
+ Project-URL: Changelog, https://github.com/cubic-zone/cubic-python/blob/main/CHANGELOG.md
9
+ Author: Cubic
10
+ License: MIT
11
+ Keywords: cubic,llm,prompts,sdk
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.10
23
+ Requires-Dist: httpx>=0.27
24
+ Requires-Dist: pydantic>=2.7
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
27
+ Requires-Dist: pytest>=8; extra == 'dev'
28
+ Description-Content-Type: text/markdown
29
+
30
+ # Cubic Python SDK
31
+
32
+ Run your Cubes and Polycubes from any Python application with a single API key.
33
+
34
+ ```bash
35
+ pip install cubic-sdk # installs the `cubic` import package
36
+ ```
37
+
38
+ ## Quickstart
39
+
40
+ ```python
41
+ from cubic import Cubic
42
+
43
+ client = Cubic(api_key="mxk_...") # or set CUBIC_API_KEY
44
+
45
+ result = client.completions.create(
46
+ cube_id="cbe_a1B2c3D4e5F6g7",
47
+ variables={"customer_name": "Ada", "issue": "billing"},
48
+ )
49
+ print(result.content)
50
+ ```
51
+
52
+ `cube_id` accepts any public Cube ID — plain cubes and Polycubes share one ID
53
+ space (`cbe_…`, with legacy `prmt…`/`poly…` IDs still valid). You never need to
54
+ know which kind an ID is: the same call runs either, and `result.content` is
55
+ the delivered output for both.
56
+
57
+ ## Running a completion
58
+
59
+ ```python
60
+ result = client.completions.create(
61
+ cube_id="cbe_a1B2c3D4e5F6g7",
62
+ variables={"customer_name": "Ada"},
63
+
64
+ # plain cubes only:
65
+ version=5, # pin a version (default: latest)
66
+ parameters={"temperature": 0.7}, # merged over the cube's parameters
67
+ models=[{"provider": "anthropic", "model_name": "claude-sonnet-4-5"}],
68
+ history=[{"role": "user", "content": "hi"}],
69
+
70
+ # both kinds:
71
+ test_mode=True, # no provider spend, no credit debit
72
+ metadata={"trace": "abc"},
73
+ )
74
+
75
+ result.content # str | dict — the winning completion (or final node output)
76
+ result.kind # "cube" | "polycube"
77
+ result.metrics # tokens, cost, credits_charged, latency, cache hits
78
+ result.request_id # keep this for retrieval / support
79
+ result.is_partial # cube delivered content but some fallbacks failed
80
+ result.segments # polycube only: per-node outputs, metrics, errors
81
+ ```
82
+
83
+ ## Async client
84
+
85
+ `AsyncCubic` has the identical surface with awaitable methods:
86
+
87
+ ```python
88
+ from cubic import AsyncCubic
89
+
90
+ async with AsyncCubic(api_key="mxk_...") as client:
91
+ result = await client.completions.create(cube_id="cbe_...", variables={...})
92
+ ```
93
+
94
+ ## Async execution (callbacks)
95
+
96
+ If the cube defines a callback URL — or you pass `callback_url=` — the run is
97
+ queued and delivered to your endpoint when done:
98
+
99
+ ```python
100
+ job = client.completions.create(cube_id="cbe_...", variables={...},
101
+ callback_url="https://you.example/hook")
102
+ job.is_queued # True
103
+ job.request_id # correlate with the X-Maxwell-Request-Id callback header
104
+
105
+ record = job.wait(timeout=120) # poll until persisted
106
+ record = client.completions.wait(job.request_id) # same, by id
107
+ record = client.completions.retrieve(job.request_id) # single poll
108
+ ```
109
+
110
+ `wait()` backs off from 0.5s to 4s between polls (fix it with
111
+ `poll_interval=`), raises `CompletionError` if the run finished with status
112
+ `error`, and `WaitTimeoutError` if nothing was persisted in time (the run
113
+ itself is unaffected). With `AsyncCubic`, `await job.wait()`.
114
+
115
+ ## Verifying callback deliveries
116
+
117
+ Every delivery is signed. Verify and parse it in one step — always against the
118
+ **raw request body bytes**:
119
+
120
+ ```python
121
+ from cubic import webhooks
122
+
123
+ @app.post("/hook") # any framework
124
+ async def hook(request):
125
+ result = webhooks.verify(await request.body(), request.headers,
126
+ secret=CUBIC_SIGNING_SECRET)
127
+ if result.status == "success":
128
+ handle(result.content) # CompletionResult | PolycubeResult
129
+ ```
130
+
131
+ A bad or missing `X-Maxwell-Signature` raises `WebhookSignatureError`. Unlike
132
+ `create()`, an error-status delivery is returned (not raised) — it's an event
133
+ you inspect. Retried deliveries reuse the same body and signature and carry an
134
+ incrementing `X-Maxwell-Delivery-Attempt` header; deduplicate on
135
+ `result.request_id` if your handler isn't idempotent.
136
+
137
+ ## Reading a cube's definition
138
+
139
+ ```python
140
+ cube = client.cubes.retrieve("cbe_a1B2c3D4e5F6g7") # latest
141
+ cube = client.cubes.retrieve("cbe_a1B2c3D4e5F6g7", version=5)
142
+
143
+ cube.system_instructions # the cube's system prompt
144
+ cube.user_prompt # the user prompt template
145
+ cube.variables # input schema — handy for pre-flight checks
146
+ cube.models # the model stack (provider, model, rank, role)
147
+ ```
148
+
149
+ Definitions are owner-only: marketplace cubes you subscribe to can be *run*
150
+ but not read, and polycube definitions are not yet available on this endpoint.
151
+
152
+ ## The model catalog
153
+
154
+ ```python
155
+ models = client.models.list() # cached in-process for 1h
156
+ anthropic = client.models.list(provider="anthropic")
157
+
158
+ m = client.models.retrieve("claude-3-5-haiku") # ModelNotFoundError suggests
159
+ m.context_window, m.input_per_1k, m.supports_tools # close matches on typos
160
+ ```
161
+
162
+ Useful for validating `models=` overrides before a run, populating model
163
+ pickers, and estimating cost. Lookups are explicit — the SDK never
164
+ auto-validates overrides against the cache; the server stays authoritative.
165
+
166
+ ## Error handling
167
+
168
+ The SDK never returns a silent failure: pipeline errors that the API reports
169
+ inside an HTTP 200 are raised as typed exceptions too.
170
+
171
+ ```python
172
+ from cubic import (
173
+ AuthenticationError, # bad/expired API key
174
+ CubeNotFoundError, # unknown ID, or not yours
175
+ MissingVariableError, # e.missing variable_name
176
+ InvalidRequestError, # bad parameters / polycube-inapplicable fields
177
+ InsufficientCreditsError, # e.required / e.balance / e.topup_allowed
178
+ RateLimitError, # capacity (auto-retried first)
179
+ ProviderError, # all model attempts failed; see e.attempt_errors
180
+ CompletionTimeoutError, # server-side execution deadline exceeded
181
+ )
182
+
183
+ try:
184
+ result = client.completions.create(cube_id="cbe_...", variables={...})
185
+ except MissingVariableError as e:
186
+ print(f"Provide the '{e.variable_name}' variable")
187
+ except InsufficientCreditsError as e:
188
+ print(f"Need {e.required} credits, have {e.balance}")
189
+ ```
190
+
191
+ Every exception carries `.error_code`, `.status_code`, `.request_id` (quote it
192
+ in support requests), and — for pipeline failures — `.result` with the full
193
+ parsed response.
194
+
195
+ ## Retries and idempotency
196
+
197
+ Connection failures and capacity 429s are retried automatically with
198
+ exponential backoff (`max_retries=2` by default). For plain cubes the SDK
199
+ attaches a `client_request_id` idempotency key to every run, so retries can
200
+ never double-charge or double-execute; ambiguous failures (timeouts, 5xx) are
201
+ retried only when that key is present. Pass your own `client_request_id` to
202
+ make retries idempotent across process restarts too.
203
+
204
+ ## Configuration
205
+
206
+ ```python
207
+ client = Cubic(
208
+ api_key="mxk_...", # or CUBIC_API_KEY
209
+ base_url="http://localhost:8010", # or CUBIC_BASE_URL (default: https://api.cubic.zone)
210
+ timeout=120.0,
211
+ max_retries=3,
212
+ )
213
+ ```
@@ -0,0 +1,184 @@
1
+ # Cubic Python SDK
2
+
3
+ Run your Cubes and Polycubes from any Python application with a single API key.
4
+
5
+ ```bash
6
+ pip install cubic-sdk # installs the `cubic` import package
7
+ ```
8
+
9
+ ## Quickstart
10
+
11
+ ```python
12
+ from cubic import Cubic
13
+
14
+ client = Cubic(api_key="mxk_...") # or set CUBIC_API_KEY
15
+
16
+ result = client.completions.create(
17
+ cube_id="cbe_a1B2c3D4e5F6g7",
18
+ variables={"customer_name": "Ada", "issue": "billing"},
19
+ )
20
+ print(result.content)
21
+ ```
22
+
23
+ `cube_id` accepts any public Cube ID — plain cubes and Polycubes share one ID
24
+ space (`cbe_…`, with legacy `prmt…`/`poly…` IDs still valid). You never need to
25
+ know which kind an ID is: the same call runs either, and `result.content` is
26
+ the delivered output for both.
27
+
28
+ ## Running a completion
29
+
30
+ ```python
31
+ result = client.completions.create(
32
+ cube_id="cbe_a1B2c3D4e5F6g7",
33
+ variables={"customer_name": "Ada"},
34
+
35
+ # plain cubes only:
36
+ version=5, # pin a version (default: latest)
37
+ parameters={"temperature": 0.7}, # merged over the cube's parameters
38
+ models=[{"provider": "anthropic", "model_name": "claude-sonnet-4-5"}],
39
+ history=[{"role": "user", "content": "hi"}],
40
+
41
+ # both kinds:
42
+ test_mode=True, # no provider spend, no credit debit
43
+ metadata={"trace": "abc"},
44
+ )
45
+
46
+ result.content # str | dict — the winning completion (or final node output)
47
+ result.kind # "cube" | "polycube"
48
+ result.metrics # tokens, cost, credits_charged, latency, cache hits
49
+ result.request_id # keep this for retrieval / support
50
+ result.is_partial # cube delivered content but some fallbacks failed
51
+ result.segments # polycube only: per-node outputs, metrics, errors
52
+ ```
53
+
54
+ ## Async client
55
+
56
+ `AsyncCubic` has the identical surface with awaitable methods:
57
+
58
+ ```python
59
+ from cubic import AsyncCubic
60
+
61
+ async with AsyncCubic(api_key="mxk_...") as client:
62
+ result = await client.completions.create(cube_id="cbe_...", variables={...})
63
+ ```
64
+
65
+ ## Async execution (callbacks)
66
+
67
+ If the cube defines a callback URL — or you pass `callback_url=` — the run is
68
+ queued and delivered to your endpoint when done:
69
+
70
+ ```python
71
+ job = client.completions.create(cube_id="cbe_...", variables={...},
72
+ callback_url="https://you.example/hook")
73
+ job.is_queued # True
74
+ job.request_id # correlate with the X-Maxwell-Request-Id callback header
75
+
76
+ record = job.wait(timeout=120) # poll until persisted
77
+ record = client.completions.wait(job.request_id) # same, by id
78
+ record = client.completions.retrieve(job.request_id) # single poll
79
+ ```
80
+
81
+ `wait()` backs off from 0.5s to 4s between polls (fix it with
82
+ `poll_interval=`), raises `CompletionError` if the run finished with status
83
+ `error`, and `WaitTimeoutError` if nothing was persisted in time (the run
84
+ itself is unaffected). With `AsyncCubic`, `await job.wait()`.
85
+
86
+ ## Verifying callback deliveries
87
+
88
+ Every delivery is signed. Verify and parse it in one step — always against the
89
+ **raw request body bytes**:
90
+
91
+ ```python
92
+ from cubic import webhooks
93
+
94
+ @app.post("/hook") # any framework
95
+ async def hook(request):
96
+ result = webhooks.verify(await request.body(), request.headers,
97
+ secret=CUBIC_SIGNING_SECRET)
98
+ if result.status == "success":
99
+ handle(result.content) # CompletionResult | PolycubeResult
100
+ ```
101
+
102
+ A bad or missing `X-Maxwell-Signature` raises `WebhookSignatureError`. Unlike
103
+ `create()`, an error-status delivery is returned (not raised) — it's an event
104
+ you inspect. Retried deliveries reuse the same body and signature and carry an
105
+ incrementing `X-Maxwell-Delivery-Attempt` header; deduplicate on
106
+ `result.request_id` if your handler isn't idempotent.
107
+
108
+ ## Reading a cube's definition
109
+
110
+ ```python
111
+ cube = client.cubes.retrieve("cbe_a1B2c3D4e5F6g7") # latest
112
+ cube = client.cubes.retrieve("cbe_a1B2c3D4e5F6g7", version=5)
113
+
114
+ cube.system_instructions # the cube's system prompt
115
+ cube.user_prompt # the user prompt template
116
+ cube.variables # input schema — handy for pre-flight checks
117
+ cube.models # the model stack (provider, model, rank, role)
118
+ ```
119
+
120
+ Definitions are owner-only: marketplace cubes you subscribe to can be *run*
121
+ but not read, and polycube definitions are not yet available on this endpoint.
122
+
123
+ ## The model catalog
124
+
125
+ ```python
126
+ models = client.models.list() # cached in-process for 1h
127
+ anthropic = client.models.list(provider="anthropic")
128
+
129
+ m = client.models.retrieve("claude-3-5-haiku") # ModelNotFoundError suggests
130
+ m.context_window, m.input_per_1k, m.supports_tools # close matches on typos
131
+ ```
132
+
133
+ Useful for validating `models=` overrides before a run, populating model
134
+ pickers, and estimating cost. Lookups are explicit — the SDK never
135
+ auto-validates overrides against the cache; the server stays authoritative.
136
+
137
+ ## Error handling
138
+
139
+ The SDK never returns a silent failure: pipeline errors that the API reports
140
+ inside an HTTP 200 are raised as typed exceptions too.
141
+
142
+ ```python
143
+ from cubic import (
144
+ AuthenticationError, # bad/expired API key
145
+ CubeNotFoundError, # unknown ID, or not yours
146
+ MissingVariableError, # e.missing variable_name
147
+ InvalidRequestError, # bad parameters / polycube-inapplicable fields
148
+ InsufficientCreditsError, # e.required / e.balance / e.topup_allowed
149
+ RateLimitError, # capacity (auto-retried first)
150
+ ProviderError, # all model attempts failed; see e.attempt_errors
151
+ CompletionTimeoutError, # server-side execution deadline exceeded
152
+ )
153
+
154
+ try:
155
+ result = client.completions.create(cube_id="cbe_...", variables={...})
156
+ except MissingVariableError as e:
157
+ print(f"Provide the '{e.variable_name}' variable")
158
+ except InsufficientCreditsError as e:
159
+ print(f"Need {e.required} credits, have {e.balance}")
160
+ ```
161
+
162
+ Every exception carries `.error_code`, `.status_code`, `.request_id` (quote it
163
+ in support requests), and — for pipeline failures — `.result` with the full
164
+ parsed response.
165
+
166
+ ## Retries and idempotency
167
+
168
+ Connection failures and capacity 429s are retried automatically with
169
+ exponential backoff (`max_retries=2` by default). For plain cubes the SDK
170
+ attaches a `client_request_id` idempotency key to every run, so retries can
171
+ never double-charge or double-execute; ambiguous failures (timeouts, 5xx) are
172
+ retried only when that key is present. Pass your own `client_request_id` to
173
+ make retries idempotent across process restarts too.
174
+
175
+ ## Configuration
176
+
177
+ ```python
178
+ client = Cubic(
179
+ api_key="mxk_...", # or CUBIC_API_KEY
180
+ base_url="http://localhost:8010", # or CUBIC_BASE_URL (default: https://api.cubic.zone)
181
+ timeout=120.0,
182
+ max_retries=3,
183
+ )
184
+ ```
@@ -0,0 +1,47 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ # PyPI distribution name ("cubic" is taken by an unrelated bioimaging package);
7
+ # the import package remains `cubic`.
8
+ name = "cubic-sdk"
9
+ version = "0.3.2"
10
+ description = "Official Python SDK for Cubic — run your Cubes and Polycubes from any application."
11
+ readme = "README.md"
12
+ requires-python = ">=3.10"
13
+ license = { text = "MIT" }
14
+ authors = [{ name = "Cubic" }]
15
+ dependencies = [
16
+ "httpx>=0.27",
17
+ "pydantic>=2.7",
18
+ ]
19
+ keywords = ["cubic", "llm", "prompts", "sdk"]
20
+ classifiers = [
21
+ "Development Status :: 4 - Beta",
22
+ "Intended Audience :: Developers",
23
+ "License :: OSI Approved :: MIT License",
24
+ "Operating System :: OS Independent",
25
+ "Programming Language :: Python :: 3",
26
+ "Programming Language :: Python :: 3.10",
27
+ "Programming Language :: Python :: 3.11",
28
+ "Programming Language :: Python :: 3.12",
29
+ "Programming Language :: Python :: 3.13",
30
+ "Typing :: Typed",
31
+ ]
32
+
33
+ [project.urls]
34
+ Homepage = "https://cubic.zone"
35
+ Documentation = "https://cubic.zone/docs"
36
+ Repository = "https://github.com/cubic-zone/cubic-python"
37
+ Changelog = "https://github.com/cubic-zone/cubic-python/blob/main/CHANGELOG.md"
38
+
39
+ [project.optional-dependencies]
40
+ dev = ["pytest>=8", "pytest-asyncio>=0.23"]
41
+
42
+ [tool.hatch.build.targets.wheel]
43
+ packages = ["src/cubic"]
44
+
45
+ [tool.pytest.ini_options]
46
+ testpaths = ["tests"]
47
+ asyncio_mode = "auto"
@@ -0,0 +1,91 @@
1
+ """Cubic Python SDK.
2
+
3
+ Quickstart::
4
+
5
+ from cubic import Cubic
6
+
7
+ client = Cubic(api_key="mxk_...")
8
+ result = client.completions.create(
9
+ cube_id="cbe_a1B2c3D4e5F6g7",
10
+ variables={"customer_name": "Ada"},
11
+ )
12
+ print(result.content)
13
+ """
14
+
15
+ from . import webhooks
16
+ from ._async_client import AsyncCubic
17
+ from ._client import Cubic
18
+ from ._exceptions import (
19
+ APIConnectionError,
20
+ APITimeoutError,
21
+ AuthenticationError,
22
+ CompletionError,
23
+ CompletionNotFoundError,
24
+ CompletionTimeoutError,
25
+ CubeNotFoundError,
26
+ CubicError,
27
+ InsufficientCreditsError,
28
+ InternalServerError,
29
+ InvalidRequestError,
30
+ MissingVariableError,
31
+ ModelNotFoundError,
32
+ NotFoundError,
33
+ PermissionDeniedError,
34
+ ProviderError,
35
+ RateLimitError,
36
+ VersionNotFoundError,
37
+ WaitTimeoutError,
38
+ WebhookSignatureError,
39
+ )
40
+ from ._version import __version__
41
+ from .types import (
42
+ AttemptError,
43
+ CompletionRecord,
44
+ CompletionResult,
45
+ Cube,
46
+ CubeModel,
47
+ Metrics,
48
+ Model,
49
+ PolycubeResult,
50
+ Segment,
51
+ SingleCompletion,
52
+ )
53
+
54
+ __all__ = [
55
+ "Cubic",
56
+ "AsyncCubic",
57
+ "webhooks",
58
+ "__version__",
59
+ # exceptions
60
+ "CubicError",
61
+ "APIConnectionError",
62
+ "APITimeoutError",
63
+ "AuthenticationError",
64
+ "PermissionDeniedError",
65
+ "NotFoundError",
66
+ "ModelNotFoundError",
67
+ "CubeNotFoundError",
68
+ "VersionNotFoundError",
69
+ "CompletionNotFoundError",
70
+ "InvalidRequestError",
71
+ "InsufficientCreditsError",
72
+ "RateLimitError",
73
+ "CompletionTimeoutError",
74
+ "InternalServerError",
75
+ "CompletionError",
76
+ "MissingVariableError",
77
+ "ProviderError",
78
+ "WaitTimeoutError",
79
+ "WebhookSignatureError",
80
+ # types
81
+ "AttemptError",
82
+ "Metrics",
83
+ "SingleCompletion",
84
+ "CompletionResult",
85
+ "PolycubeResult",
86
+ "Segment",
87
+ "CompletionRecord",
88
+ "Cube",
89
+ "CubeModel",
90
+ "Model",
91
+ ]