abyssale 1.0.0__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,15 @@
1
+ .venv/
2
+ venv/
3
+ __pycache__/
4
+ *.py[cod]
5
+ *.egg-info/
6
+ build/
7
+ dist/
8
+ .pytest_cache/
9
+ .mypy_cache/
10
+ .ruff_cache/
11
+ .coverage
12
+ htmlcov/
13
+ spec.stripped.json
14
+ .idea/
15
+ .DS_Store
@@ -0,0 +1,66 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ **Every release names the API version it was generated from.** The API is versioned by release date
8
+ (`vYYYY-MM-DD`) and one version is maintained at a time, so the pairing below tells you which
9
+ contract a given SDK release models. The SDK's own version is independent — regenerating against a
10
+ newer API version is a normal change, and whether it is a patch, minor or major depends on what the
11
+ API changed.
12
+
13
+ | SDK | API version | |
14
+ |---|---|---|
15
+ | 1.0.0 | `v2026-08-20` | [spec](https://api-reference.abyssale.com/api.yaml) |
16
+
17
+ ## [1.0.0] — 2026-08-20
18
+
19
+ _Generated from API version **`v2026-08-20`**._
20
+
21
+ First release. Covers **every operation in that spec** — 18 of them — plus two polling helpers over
22
+ its status endpoints. Response models are generated from its schemas.
23
+
24
+ ### Added
25
+
26
+ - `Abyssale` and `AsyncAbyssale`, over `httpx`. Both are context managers and both accept a
27
+ caller-supplied `httpx` client.
28
+ - All 18 endpoints: auth; design list/read/format read; sync and async generation; multipage PDF;
29
+ generation-request status; file read; fonts; projects list/create; export; dynamic image URL;
30
+ workspace templates, categories, duplication and duplication status.
31
+ - `wait_for_generation_request` and `wait_for_duplication_request` — exponential backoff with
32
+ jitter, a 30-minute default deadline, and a budget of three *consecutive* transient failures that
33
+ resets on any successful poll. Partial success resolves: a finalized request carrying both banners
34
+ and per-format errors is a result, not an exception. Only a request that finalized with no banners
35
+ at all and at least one error raises.
36
+ - Retries, following the spec's error contract: 5xx on idempotent methods only
37
+ (every POST bills credits, and a 504 does not mean the render did not happen); the full ladder for
38
+ a `429` carrying `Retry-After`; exactly one one-second probe for a bare `429`, because
39
+ `rate_limit_exceeded` conflates spent credits with the gateway's per-second ceiling;
40
+ `feature_not_in_plan` never retried, whatever headers the response carries — no window makes a
41
+ plan restriction clear.
42
+ - `max_retry_wait` (`$ABYSSALE_MAX_RETRY_WAIT_MS`, default 30s) — the longest single `Retry-After`
43
+ the SDK will sleep through on your behalf. The rate limiter can name a cool-off of ~1700s once a
44
+ quota is spent, and `max_retries` multiplies it, so honouring it blindly would turn one call into
45
+ 83 minutes of silence with no way to intervene. Past the bound the call fails immediately with
46
+ `AbyssaleRateLimitError`, `retry_after` carrying the server's figure so the decision is yours.
47
+ Applies to any server-named wait, including a 5xx that carries `Retry-After` and one absorbed by a
48
+ `wait_for_*` poll — a 30-minute deadline has room to sleep off a 28-minute cool-off in one go, and
49
+ the bound is what refuses it. The SDK's own backoff and the bare-`429` probe are unaffected. Pass
50
+ `math.inf` to wait however long the server asks.
51
+ - An exception hierarchy under `AbyssaleError`, built from the API's single error envelope — the
52
+ machine-readable `id` is always on the exception, and `errors` holds the per-field problems when
53
+ the failure was a payload problem.
54
+ - Pydantic response models generated from the spec, with the Alpha design-import surface stripped by
55
+ `scripts/fetch_spec.py`, since the spec marks that surface Alpha.
56
+ - Seven runnable examples in `examples/`, each exercising a documented operation end to end.
57
+
58
+ ### Notes
59
+
60
+ - **Request bodies are plain dicts.** The `elements` schema is an `anyOf` of ten deliberately
61
+ overlapping branches with no discriminator, and the API accepts unknown element names by design,
62
+ so bodies are passed through untouched rather than modelled.
63
+ - **Parsing never fails a successful response.** Unknown fields are kept, and a field the spec calls
64
+ required but the response omits does not raise — the spec is hand-maintained and the API is the
65
+ authority.
66
+ - Requires Python 3.10+.
abyssale-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Abyssale
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,171 @@
1
+ Metadata-Version: 2.5
2
+ Name: abyssale
3
+ Version: 1.0.0
4
+ Summary: Official Python SDK for the Abyssale API — image, video and PDF generation.
5
+ Project-URL: Homepage, https://www.abyssale.com
6
+ Project-URL: Documentation, https://developers.abyssale.com/sdks/python
7
+ Project-URL: API Reference, https://api-reference.abyssale.com
8
+ Project-URL: Repository, https://github.com/getabyssale/abyssale-python-sdk
9
+ Project-URL: Issues, https://github.com/getabyssale/abyssale-python-sdk/issues
10
+ Project-URL: Changelog, https://github.com/getabyssale/abyssale-python-sdk/blob/main/CHANGELOG.md
11
+ Author: Abyssale
12
+ License: MIT License
13
+
14
+ Copyright (c) 2025 Abyssale
15
+
16
+ Permission is hereby granted, free of charge, to any person obtaining a copy
17
+ of this software and associated documentation files (the "Software"), to deal
18
+ in the Software without restriction, including without limitation the rights
19
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20
+ copies of the Software, and to permit persons to whom the Software is
21
+ furnished to do so, subject to the following conditions:
22
+
23
+ The above copyright notice and this permission notice shall be included in all
24
+ copies or substantial portions of the Software.
25
+
26
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32
+ SOFTWARE.
33
+ License-File: LICENSE
34
+ Keywords: abyssale,api,banner,image-generation,pdf,sdk,video
35
+ Classifier: Development Status :: 5 - Production/Stable
36
+ Classifier: Intended Audience :: Developers
37
+ Classifier: License :: OSI Approved :: MIT License
38
+ Classifier: Programming Language :: Python :: 3
39
+ Classifier: Programming Language :: Python :: 3.10
40
+ Classifier: Programming Language :: Python :: 3.11
41
+ Classifier: Programming Language :: Python :: 3.12
42
+ Classifier: Programming Language :: Python :: 3.13
43
+ Classifier: Typing :: Typed
44
+ Requires-Python: >=3.10
45
+ Requires-Dist: httpx>=0.27
46
+ Requires-Dist: pydantic>=2.7
47
+ Provides-Extra: codegen
48
+ Requires-Dist: datamodel-code-generator>=0.25; extra == 'codegen'
49
+ Requires-Dist: pyyaml>=6; extra == 'codegen'
50
+ Provides-Extra: dev
51
+ Requires-Dist: anyio>=4; extra == 'dev'
52
+ Requires-Dist: build>=1.2; extra == 'dev'
53
+ Requires-Dist: mypy>=1.10; extra == 'dev'
54
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
55
+ Requires-Dist: pytest>=8; extra == 'dev'
56
+ Requires-Dist: respx>=0.21; extra == 'dev'
57
+ Requires-Dist: ruff>=0.5; extra == 'dev'
58
+ Requires-Dist: twine>=5; extra == 'dev'
59
+ Description-Content-Type: text/markdown
60
+
61
+ # Abyssale Python SDK
62
+
63
+ Official Python client for the [Abyssale API](https://developers.abyssale.com) — generate images,
64
+ videos, HTML5 banners and print-ready PDFs from your designs.
65
+
66
+ ## Install
67
+
68
+ ```bash
69
+ pip install abyssale
70
+ ```
71
+
72
+ Requires Python 3.10+. This release models API version **`v2026-08-20`** — see
73
+ [CHANGELOG.md](https://github.com/getabyssale/abyssale-python-sdk/blob/main/CHANGELOG.md) for the SDK-to-API version pairing, and `abyssale.__api_version__` to
74
+ read it at runtime.
75
+
76
+ ## Quick start
77
+
78
+ ```python
79
+ from abyssale import Abyssale
80
+
81
+ with Abyssale() as client: # reads ABYSSALE_API_KEY
82
+ design = client.get_design("64238d01-d402-474b-8c2d-fbc957e9d290")
83
+
84
+ banner = client.generate_image(design.id, {
85
+ "elements": {"title": {"payload": "Hello World"}},
86
+ "template_format_name": "facebook-post",
87
+ })
88
+ print(banner.file.cdn_url)
89
+ ```
90
+
91
+ Async is the same surface:
92
+
93
+ ```python
94
+ import asyncio
95
+ from abyssale import AsyncAbyssale
96
+
97
+ async def main():
98
+ async with AsyncAbyssale() as client:
99
+ accepted = await client.generate_multi_format_media(design_id, {
100
+ "elements": {"title": {"payload": "Summer Sale"}},
101
+ "template_format_names": ["facebook-feed", "instagram-post"],
102
+ })
103
+ result = await client.wait_for_generation_request(accepted.generation_request_id)
104
+ for banner in result.banners:
105
+ print(banner.file.cdn_url)
106
+
107
+ asyncio.run(main())
108
+ ```
109
+
110
+ ## Errors
111
+
112
+ Methods return the result and **raise** on failure. Branch on the API's machine-readable `id`, not
113
+ on the message:
114
+
115
+ ```python
116
+ from abyssale import AbyssaleAPIError, AbyssaleRateLimitError
117
+
118
+ try:
119
+ client.generate_image(design_id, {...})
120
+ except AbyssaleRateLimitError as err:
121
+ if err.id == "feature_not_in_plan":
122
+ ... # your plan excludes this design type
123
+ except AbyssaleAPIError as err:
124
+ print(err.status, err.id, err.message, err.errors)
125
+ ```
126
+
127
+ `err.errors` holds the per-field problems (`path`, `code`, `message`) when the request body was the
128
+ problem, and is `None` otherwise.
129
+
130
+ Transient failures are retried for you: 5xx on reads, and `429`s that carry a `Retry-After`. A `429`
131
+ without one gets a single one-second probe, because the status is shared by "out of credits"
132
+ (permanent) and the gateway's per-second ceiling (clears immediately). Writes are never retried on a
133
+ 5xx — a timed-out generation may still have been billed.
134
+
135
+ A `Retry-After` is only waited out up to `max_retry_wait` (30s by default). The rate limiter can name
136
+ a cool-off of half an hour once a quota is spent, and sleeping through that — times `max_retries` —
137
+ turns one call into an hour of silence. Past the bound the call fails immediately instead, with
138
+ `err.retry_after` carrying the server's figure so you can decide what to do with it. Pass
139
+ `max_retry_wait=math.inf` if you do want to wait however long the server asks.
140
+
141
+ ## Configuration
142
+
143
+ | Variable | Default | Purpose |
144
+ |---|---|---|
145
+ | `ABYSSALE_API_KEY` | — | Required, unless you pass `api_key=`. |
146
+ | `ABYSSALE_TIMEOUT_MS` | `30000` | Per-attempt request timeout. |
147
+ | `ABYSSALE_MAX_RETRIES` | `3` | `0` disables retries. |
148
+ | `ABYSSALE_MAX_RETRY_WAIT_MS` | `30000` | Longest `Retry-After` to wait out. `inf` to never give up. |
149
+
150
+ Every one can be overridden per client: `Abyssale(api_key=..., timeout=60, max_retries=0)`.
151
+
152
+ ## Examples
153
+
154
+ Runnable scripts are in [`examples/`](https://github.com/getabyssale/abyssale-python-sdk/blob/main/examples). Each one names its own command:
155
+
156
+ ```bash
157
+ ABYSSALE_API_KEY=your-key python examples/generate_image.py
158
+ ```
159
+
160
+ ## Contributing
161
+
162
+ See [AGENTS.md](https://github.com/getabyssale/abyssale-python-sdk/blob/main/AGENTS.md) for the architecture, how to regenerate the models from the OpenAPI spec,
163
+ and how to add an endpoint.
164
+
165
+ ## Links
166
+
167
+ - [Abyssale](https://www.abyssale.com) — the product this SDK talks to
168
+ - [Documentation](https://developers.abyssale.com/sdks/python)
169
+ - [API reference](https://api-reference.abyssale.com)
170
+ - [OpenAPI spec](https://api-reference.abyssale.com/api.yaml) — the contract this SDK is generated from
171
+ - [Source](https://github.com/getabyssale/abyssale-python-sdk)
@@ -0,0 +1,111 @@
1
+ # Abyssale Python SDK
2
+
3
+ Official Python client for the [Abyssale API](https://developers.abyssale.com) — generate images,
4
+ videos, HTML5 banners and print-ready PDFs from your designs.
5
+
6
+ ## Install
7
+
8
+ ```bash
9
+ pip install abyssale
10
+ ```
11
+
12
+ Requires Python 3.10+. This release models API version **`v2026-08-20`** — see
13
+ [CHANGELOG.md](https://github.com/getabyssale/abyssale-python-sdk/blob/main/CHANGELOG.md) for the SDK-to-API version pairing, and `abyssale.__api_version__` to
14
+ read it at runtime.
15
+
16
+ ## Quick start
17
+
18
+ ```python
19
+ from abyssale import Abyssale
20
+
21
+ with Abyssale() as client: # reads ABYSSALE_API_KEY
22
+ design = client.get_design("64238d01-d402-474b-8c2d-fbc957e9d290")
23
+
24
+ banner = client.generate_image(design.id, {
25
+ "elements": {"title": {"payload": "Hello World"}},
26
+ "template_format_name": "facebook-post",
27
+ })
28
+ print(banner.file.cdn_url)
29
+ ```
30
+
31
+ Async is the same surface:
32
+
33
+ ```python
34
+ import asyncio
35
+ from abyssale import AsyncAbyssale
36
+
37
+ async def main():
38
+ async with AsyncAbyssale() as client:
39
+ accepted = await client.generate_multi_format_media(design_id, {
40
+ "elements": {"title": {"payload": "Summer Sale"}},
41
+ "template_format_names": ["facebook-feed", "instagram-post"],
42
+ })
43
+ result = await client.wait_for_generation_request(accepted.generation_request_id)
44
+ for banner in result.banners:
45
+ print(banner.file.cdn_url)
46
+
47
+ asyncio.run(main())
48
+ ```
49
+
50
+ ## Errors
51
+
52
+ Methods return the result and **raise** on failure. Branch on the API's machine-readable `id`, not
53
+ on the message:
54
+
55
+ ```python
56
+ from abyssale import AbyssaleAPIError, AbyssaleRateLimitError
57
+
58
+ try:
59
+ client.generate_image(design_id, {...})
60
+ except AbyssaleRateLimitError as err:
61
+ if err.id == "feature_not_in_plan":
62
+ ... # your plan excludes this design type
63
+ except AbyssaleAPIError as err:
64
+ print(err.status, err.id, err.message, err.errors)
65
+ ```
66
+
67
+ `err.errors` holds the per-field problems (`path`, `code`, `message`) when the request body was the
68
+ problem, and is `None` otherwise.
69
+
70
+ Transient failures are retried for you: 5xx on reads, and `429`s that carry a `Retry-After`. A `429`
71
+ without one gets a single one-second probe, because the status is shared by "out of credits"
72
+ (permanent) and the gateway's per-second ceiling (clears immediately). Writes are never retried on a
73
+ 5xx — a timed-out generation may still have been billed.
74
+
75
+ A `Retry-After` is only waited out up to `max_retry_wait` (30s by default). The rate limiter can name
76
+ a cool-off of half an hour once a quota is spent, and sleeping through that — times `max_retries` —
77
+ turns one call into an hour of silence. Past the bound the call fails immediately instead, with
78
+ `err.retry_after` carrying the server's figure so you can decide what to do with it. Pass
79
+ `max_retry_wait=math.inf` if you do want to wait however long the server asks.
80
+
81
+ ## Configuration
82
+
83
+ | Variable | Default | Purpose |
84
+ |---|---|---|
85
+ | `ABYSSALE_API_KEY` | — | Required, unless you pass `api_key=`. |
86
+ | `ABYSSALE_TIMEOUT_MS` | `30000` | Per-attempt request timeout. |
87
+ | `ABYSSALE_MAX_RETRIES` | `3` | `0` disables retries. |
88
+ | `ABYSSALE_MAX_RETRY_WAIT_MS` | `30000` | Longest `Retry-After` to wait out. `inf` to never give up. |
89
+
90
+ Every one can be overridden per client: `Abyssale(api_key=..., timeout=60, max_retries=0)`.
91
+
92
+ ## Examples
93
+
94
+ Runnable scripts are in [`examples/`](https://github.com/getabyssale/abyssale-python-sdk/blob/main/examples). Each one names its own command:
95
+
96
+ ```bash
97
+ ABYSSALE_API_KEY=your-key python examples/generate_image.py
98
+ ```
99
+
100
+ ## Contributing
101
+
102
+ See [AGENTS.md](https://github.com/getabyssale/abyssale-python-sdk/blob/main/AGENTS.md) for the architecture, how to regenerate the models from the OpenAPI spec,
103
+ and how to add an endpoint.
104
+
105
+ ## Links
106
+
107
+ - [Abyssale](https://www.abyssale.com) — the product this SDK talks to
108
+ - [Documentation](https://developers.abyssale.com/sdks/python)
109
+ - [API reference](https://api-reference.abyssale.com)
110
+ - [OpenAPI spec](https://api-reference.abyssale.com/api.yaml) — the contract this SDK is generated from
111
+ - [Source](https://github.com/getabyssale/abyssale-python-sdk)
@@ -0,0 +1,87 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "abyssale"
7
+ version = "1.0.0"
8
+ description = "Official Python SDK for the Abyssale API — image, video and PDF generation."
9
+ readme = "README.md"
10
+ license = { file = "LICENSE" }
11
+ requires-python = ">=3.10"
12
+ authors = [{ name = "Abyssale" }]
13
+ keywords = ["abyssale", "banner", "image-generation", "video", "pdf", "api", "sdk"]
14
+ classifiers = [
15
+ "Development Status :: 5 - Production/Stable",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Typing :: Typed",
24
+ ]
25
+ dependencies = [
26
+ "httpx>=0.27",
27
+ "pydantic>=2.7",
28
+ ]
29
+
30
+ [project.urls]
31
+ Homepage = "https://www.abyssale.com"
32
+ Documentation = "https://developers.abyssale.com/sdks/python"
33
+ "API Reference" = "https://api-reference.abyssale.com"
34
+ Repository = "https://github.com/getabyssale/abyssale-python-sdk"
35
+ Issues = "https://github.com/getabyssale/abyssale-python-sdk/issues"
36
+ Changelog = "https://github.com/getabyssale/abyssale-python-sdk/blob/main/CHANGELOG.md"
37
+
38
+ [project.optional-dependencies]
39
+ dev = [
40
+ "pytest>=8",
41
+ "pytest-asyncio>=0.23",
42
+ "respx>=0.21",
43
+ "anyio>=4",
44
+ "mypy>=1.10",
45
+ "ruff>=0.5",
46
+ "build>=1.2",
47
+ "twine>=5",
48
+ ]
49
+ # Only needed to regenerate `src/abyssale/_generated.py` — not required to use or test the SDK.
50
+ codegen = [
51
+ "datamodel-code-generator>=0.25",
52
+ "PyYAML>=6",
53
+ ]
54
+
55
+ [tool.hatch.build.targets.wheel]
56
+ packages = ["src/abyssale"]
57
+
58
+ [tool.hatch.build.targets.sdist]
59
+ include = ["src/abyssale", "README.md", "LICENSE", "CHANGELOG.md"]
60
+
61
+ [tool.pytest.ini_options]
62
+ testpaths = ["tests"]
63
+ asyncio_mode = "auto"
64
+
65
+ [tool.ruff]
66
+ line-length = 120
67
+ target-version = "py310"
68
+ # The generated models are formatted by the code generator, not by us. Reformatting them here
69
+ # would make every regeneration produce a diff against itself.
70
+ extend-exclude = ["src/abyssale/_generated.py"]
71
+
72
+ [tool.ruff.lint]
73
+ select = ["E", "F", "I", "UP", "B"]
74
+
75
+ [tool.ruff.lint.per-file-ignores]
76
+ "src/abyssale/_generated.py" = ["ALL"]
77
+
78
+ [tool.mypy]
79
+ python_version = "3.10"
80
+ strict = true
81
+ files = ["src/abyssale"]
82
+
83
+ # The generated models are not hand-written and are excluded from strict typing, exactly as
84
+ # `generated.ts` is excluded from review in the Node SDK.
85
+ [[tool.mypy.overrides]]
86
+ module = "abyssale._generated"
87
+ ignore_errors = true
@@ -0,0 +1,102 @@
1
+ """Official Python SDK for the Abyssale API — image, video and PDF generation.
2
+
3
+ from abyssale import Abyssale
4
+
5
+ with Abyssale() as client: # reads ABYSSALE_API_KEY
6
+ design = client.get_design("64238d01-d402-474b-8c2d-fbc957e9d290")
7
+ banner = client.generate_image(design.id, {
8
+ "elements": {"title": {"payload": "Hello World"}},
9
+ "template_format_name": "facebook-post",
10
+ })
11
+ print(banner.file.cdn_url)
12
+
13
+ Async is the same surface: ``from abyssale import AsyncAbyssale``.
14
+
15
+ Errors raise. Every failure is an :class:`AbyssaleError`; a non-2xx is an :class:`AbyssaleAPIError`
16
+ carrying the API's machine-readable ``id``, which is what you branch on.
17
+
18
+ Docs: https://developers.abyssale.com/sdks/python
19
+ """
20
+
21
+ from ._async_client import AsyncAbyssale
22
+ from ._client import Abyssale
23
+ from ._errors import (
24
+ AbyssaleAPIError,
25
+ AbyssaleAuthError,
26
+ AbyssaleConfigError,
27
+ AbyssaleConnectionError,
28
+ AbyssaleError,
29
+ AbyssaleNotFoundError,
30
+ AbyssalePollingError,
31
+ AbyssaleRateLimitError,
32
+ )
33
+ from ._version import __api_version__, __version__
34
+ from .models import (
35
+ AuthResult,
36
+ Banner,
37
+ Design,
38
+ DesignAnimation,
39
+ DesignDetail,
40
+ DesignElement,
41
+ DesignFormat,
42
+ DesignFormatDetail,
43
+ DesignListItem,
44
+ DesignPage,
45
+ DesignPageElement,
46
+ DuplicatedDesign,
47
+ DuplicationRequest,
48
+ DuplicationRequestStatus,
49
+ DynamicImageResponse,
50
+ ErrorResponse,
51
+ ExportAccepted,
52
+ Font,
53
+ GenerationRequestAccepted,
54
+ GenerationRequestStatus,
55
+ Project,
56
+ ProjectSummary,
57
+ TextToImageProperties,
58
+ WorkspaceTemplate,
59
+ WorkspaceTemplateCategory,
60
+ )
61
+
62
+ __all__ = [
63
+ "Abyssale",
64
+ "AsyncAbyssale",
65
+ "__version__",
66
+ "__api_version__",
67
+ # Errors
68
+ "AbyssaleAPIError",
69
+ "AbyssaleAuthError",
70
+ "AbyssaleConfigError",
71
+ "AbyssaleConnectionError",
72
+ "AbyssaleError",
73
+ "AbyssaleNotFoundError",
74
+ "AbyssalePollingError",
75
+ "AbyssaleRateLimitError",
76
+ # Models
77
+ "AuthResult",
78
+ "Banner",
79
+ "Design",
80
+ "DesignAnimation",
81
+ "DesignDetail",
82
+ "DesignElement",
83
+ "DesignFormat",
84
+ "DesignFormatDetail",
85
+ "DesignListItem",
86
+ "DesignPage",
87
+ "DesignPageElement",
88
+ "DuplicatedDesign",
89
+ "DuplicationRequest",
90
+ "DuplicationRequestStatus",
91
+ "DynamicImageResponse",
92
+ "ErrorResponse",
93
+ "ExportAccepted",
94
+ "Font",
95
+ "GenerationRequestAccepted",
96
+ "GenerationRequestStatus",
97
+ "Project",
98
+ "ProjectSummary",
99
+ "TextToImageProperties",
100
+ "WorkspaceTemplate",
101
+ "WorkspaceTemplateCategory",
102
+ ]