imazeo 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.
- imazeo-1.0.0/.gitignore +16 -0
- imazeo-1.0.0/CHANGELOG.md +34 -0
- imazeo-1.0.0/GUIDE.md +141 -0
- imazeo-1.0.0/LICENSE +21 -0
- imazeo-1.0.0/PKG-INFO +210 -0
- imazeo-1.0.0/README.md +183 -0
- imazeo-1.0.0/examples/qr.py +44 -0
- imazeo-1.0.0/examples/upload_transform.py +54 -0
- imazeo-1.0.0/openapi/backend.json +6348 -0
- imazeo-1.0.0/openapi/contract-meta.json +12 -0
- imazeo-1.0.0/pyproject.toml +69 -0
- imazeo-1.0.0/src/imazeo/__init__.py +75 -0
- imazeo-1.0.0/src/imazeo/_http.py +437 -0
- imazeo-1.0.0/src/imazeo/client.py +86 -0
- imazeo-1.0.0/src/imazeo/errors.py +89 -0
- imazeo-1.0.0/src/imazeo/resources/__init__.py +17 -0
- imazeo-1.0.0/src/imazeo/resources/barcodes.py +30 -0
- imazeo-1.0.0/src/imazeo/resources/context.py +17 -0
- imazeo-1.0.0/src/imazeo/resources/images.py +86 -0
- imazeo-1.0.0/src/imazeo/resources/pdf.py +163 -0
- imazeo-1.0.0/src/imazeo/resources/qr.py +30 -0
- imazeo-1.0.0/src/imazeo/resources/transforms.py +91 -0
- imazeo-1.0.0/src/imazeo/types.py +266 -0
- imazeo-1.0.0/src/imazeo/version.py +14 -0
- imazeo-1.0.0/tests/test_client.py +290 -0
- imazeo-1.0.0/tests/test_media_contract.py +21 -0
imazeo-1.0.0/.gitignore
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Initial official Python SDK (`imazeo`)
|
|
8
|
+
- Resources: `context`, `images`, `transforms`, `qr`, `barcodes`, `pdf`
|
|
9
|
+
- Typed errors mapped from Imazeo API envelopes
|
|
10
|
+
- API version allowlist (`v1`) separate from SDK SemVer
|
|
11
|
+
- Multipart uploads with required `X-Upload-Length`
|
|
12
|
+
- Binary response helpers for images/PDF/QR/barcode
|
|
13
|
+
- Image list `q` filename-prefix filter
|
|
14
|
+
- Transform download `If-None-Match` → HTTP 304 as `BinaryResult.not_modified`
|
|
15
|
+
- Default HTTP transport refuses redirects so `X-API-Key` stays on the configured origin
|
|
16
|
+
- Reviewed API-key-only OpenAPI snapshot bundled as `openapi/backend.json`
|
|
17
|
+
- Native CI verification and independent SemVer/tag checks
|
|
18
|
+
|
|
19
|
+
### Media contract
|
|
20
|
+
|
|
21
|
+
- Barcode: required `type` and `content`; optional `format` (`png`/`svg`) and `includeText`
|
|
22
|
+
- PDF merge uses repeated multipart `file` parts in order
|
|
23
|
+
- Integer model types for barcode scale and image hue where applicable
|
|
24
|
+
|
|
25
|
+
### Deferred (API-key routes exist; not in SDK_BEHAVIOR §1)
|
|
26
|
+
|
|
27
|
+
- Tool artifacts CRUD/download
|
|
28
|
+
- Project outputs list
|
|
29
|
+
|
|
30
|
+
### API compatibility
|
|
31
|
+
|
|
32
|
+
- Default API: `v1`
|
|
33
|
+
- Supported API versions: `v1`
|
|
34
|
+
- Default base URL: `https://api.imazeo.com`
|
imazeo-1.0.0/GUIDE.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Imazeo Python integration guide
|
|
2
|
+
|
|
3
|
+
## 1. Prepare a server integration
|
|
4
|
+
|
|
5
|
+
Install the package:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install imazeo
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Package: [`imazeo`](https://pypi.org/project/imazeo/) on PyPI.
|
|
12
|
+
Source: [manishbalodia/imazeo-python](https://github.com/manishbalodia/imazeo-python).
|
|
13
|
+
Use the package README for runtime details.
|
|
14
|
+
|
|
15
|
+
Create a Customer account, complete required verification, create a project and
|
|
16
|
+
issue a project key. Set IMAZEO_API_KEY in protected server configuration and
|
|
17
|
+
IMAZEO_API_ORIGIN to the supplied API origin (no /v1 suffix; production default
|
|
18
|
+
`https://api.imazeo.com`). Use HTTPS outside loopback development. A key can
|
|
19
|
+
resolve its project through GET /v1/api-key/context; that response has projectId
|
|
20
|
+
and keyId, not plan limits or the secret key.
|
|
21
|
+
|
|
22
|
+
The Main site's documentation paths, served by your configured Main origin, are:
|
|
23
|
+
/docs/getting-started/, /docs/authentication/ and /docs/projects/.
|
|
24
|
+
These paths are site-relative; this guide does not assume a live production domain.
|
|
25
|
+
|
|
26
|
+
## 2. Generate a QR code and render a delivery note
|
|
27
|
+
|
|
28
|
+
The following example uses the `imazeo` package. Obtain the original two-page synthetic
|
|
29
|
+
delivery-note.pdf from the Main site's /examples/assets/delivery-note.pdf and put it
|
|
30
|
+
in the working directory. The event URL is fictional. Run only against your configured
|
|
31
|
+
API deployment with the required entitlements and credits.
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
import os
|
|
35
|
+
import base64
|
|
36
|
+
from pathlib import Path
|
|
37
|
+
from imazeo import Imazeo, PdfMultiPageResult
|
|
38
|
+
|
|
39
|
+
# Context manager closes the underlying HTTP client.
|
|
40
|
+
with Imazeo(api_key=os.environ['IMAZEO_API_KEY'],
|
|
41
|
+
base_url=os.environ['IMAZEO_API_ORIGIN']) as client:
|
|
42
|
+
qr = client.qr.generate({
|
|
43
|
+
'content': 'https://example.com/events/studio-open-day',
|
|
44
|
+
'format': 'svg', 'size': 384,
|
|
45
|
+
})
|
|
46
|
+
Path('event-check-in.svg').write_bytes(qr.data)
|
|
47
|
+
result = client.pdf.render(Path('delivery-note.pdf').read_bytes(), {
|
|
48
|
+
'pages': '1,2', 'format': 'png',
|
|
49
|
+
})
|
|
50
|
+
if isinstance(result, PdfMultiPageResult):
|
|
51
|
+
for page in result.pages:
|
|
52
|
+
Path(f"delivery-page-{page['pageNumber']}.png").write_bytes(
|
|
53
|
+
base64.b64decode(page['data'], validate=True))
|
|
54
|
+
else:
|
|
55
|
+
Path('delivery-page.png').write_bytes(result.data)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
All six SDK default transports refuse HTTP redirects so project credentials stay
|
|
59
|
+
on the configured API origin. The examples also set safe redirect policies where
|
|
60
|
+
custom client hooks are used. Custom fetch functions, Java HttpClient instances,
|
|
61
|
+
.NET HttpClient/message handlers and Python/PHP handlers must preserve this rule.
|
|
62
|
+
Never forward project credentials to a redirected host.
|
|
63
|
+
|
|
64
|
+
QR success is binary SVG. A one-page PDF render returns binary image bytes; multiple
|
|
65
|
+
selected pages return base64 page data. This SDK's render result is:
|
|
66
|
+
BinaryResult or PdfMultiPageResult. Decode base64 exactly once; use each page's contentType if you
|
|
67
|
+
change the selected format. The example uses PNG and .png filenames deliberately.
|
|
68
|
+
|
|
69
|
+
## 3. Upload and transform images
|
|
70
|
+
|
|
71
|
+
Use the image upload method with file bytes and explicit filename/content type
|
|
72
|
+
as documented in the README. It sends multipart field file and the exact
|
|
73
|
+
X-Upload-Length file byte count. Filenames are metadata, not paths or resource IDs.
|
|
74
|
+
Keep the returned image ID, then create a transform with imageId and transform.
|
|
75
|
+
REST uses _id; use the native ID accessor shown in the README.
|
|
76
|
+
|
|
77
|
+
CACHE and PERSIST retain derivatives according to their mode rules. EPHEMERAL
|
|
78
|
+
only returns immediate bytes. All transform success bodies are binary. Image
|
|
79
|
+
originals preserve original metadata; generated derivatives strip metadata.
|
|
80
|
+
The HTTP guides are /docs/images/, /docs/transforms/ and /docs/quickstart/.
|
|
81
|
+
|
|
82
|
+
## 4. Choose PDF and code inputs
|
|
83
|
+
|
|
84
|
+
PDF info returns parsed JSON and costs one credit. Render costs one per selected
|
|
85
|
+
page; merge costs two; extract costs one. Page numbers are one-based. Select
|
|
86
|
+
pages, a complete rangeStart/rangeEnd pair, or render-only all=true; do not combine
|
|
87
|
+
selectors. Render defaults to page 1; extract requires an explicit selection.
|
|
88
|
+
Merge upload order determines document order. Encrypted/invalid PDFs are rejected.
|
|
89
|
+
|
|
90
|
+
QR and barcode generation each cost one credit and return PNG or SVG. Barcode
|
|
91
|
+
content must be a string, including numeric identifiers with leading zeros.
|
|
92
|
+
Send numbers and booleans as native values, and omit unused optional fields instead
|
|
93
|
+
of null. A barcode renderer does not assign registered retail identifiers; QR
|
|
94
|
+
generation does not provide dynamic redirect hosting.
|
|
95
|
+
Detailed guides: /docs/pdf/, /docs/qr/, /docs/barcodes/ and /docs/workflows/.
|
|
96
|
+
|
|
97
|
+
## 5. Handle pagination, downloads and errors
|
|
98
|
+
|
|
99
|
+
Image/transform lists return a Page wrapper with items and page/limit/total/pages.
|
|
100
|
+
Pagination is explicit; clients do not silently fetch all pages. Only image lists
|
|
101
|
+
accept q as a filename-prefix filter; transformation lists accept page and limit.
|
|
102
|
+
This is not unrestricted full-text search.
|
|
103
|
+
Binary results contain bytes, content type, headers and request ID. Derivative
|
|
104
|
+
downloads support conditional ETags. A not-modified result has no new bytes:
|
|
105
|
+
retain your cached file instead of replacing it with an empty body.
|
|
106
|
+
|
|
107
|
+
SDK errors expose status, code, request ID and details using native language names
|
|
108
|
+
listed in the README. Network errors do not guarantee an HTTP status. Log only
|
|
109
|
+
sanitized diagnostics; never log a key, source media or base64 PDF pages. Fix
|
|
110
|
+
validation/authentication/entitlement failures. For temporary 429 or busy responses,
|
|
111
|
+
use bounded backoff only when replay is safe and honor Retry-After if supplied.
|
|
112
|
+
No general idempotency-key mechanism is promised. A timed-out mutation may already
|
|
113
|
+
have completed; reconcile known IDs/state before repeating it. SDKs do not
|
|
114
|
+
automatically retry mutations.
|
|
115
|
+
See /docs/errors/ and /docs/troubleshooting/.
|
|
116
|
+
|
|
117
|
+
## 6. Retain outputs and operate in production
|
|
118
|
+
|
|
119
|
+
PDF/code output is transient unless you retain the bytes or separately save a
|
|
120
|
+
private artifact through HTTP. Saved artifacts, unified output inventory, usage,
|
|
121
|
+
account/project/key management and Admin APIs are outside the SDK's core media
|
|
122
|
+
scope. Use Customer Bearer authentication for management, not a project key.
|
|
123
|
+
Do not combine Bearer and X-API-Key in one request.
|
|
124
|
+
|
|
125
|
+
There is no public CDN or customer signed-delivery URL in this contract. Deliver
|
|
126
|
+
bytes through your own authorized server. Never bundle a project key into browser,
|
|
127
|
+
mobile or end-user applications. Your server must enforce its own per-user access.
|
|
128
|
+
|
|
129
|
+
Bound source sizes, output bytes, page counts and concurrency: these SDKs buffer
|
|
130
|
+
media and base64 pages require extra memory. Default client timeouts are 30 seconds
|
|
131
|
+
for light operations, 60 seconds for images and 120 seconds for PDFs; they do not
|
|
132
|
+
extend backend worker deadlines. Check assigned account limits, not just public
|
|
133
|
+
pricing templates. Cache hits still consume output bandwidth; an authenticated
|
|
134
|
+
derivative 304 consumes no output bandwidth. Deletion refunds storage, not past
|
|
135
|
+
credits/bandwidth. Expiry and physical cleanup are separate.
|
|
136
|
+
|
|
137
|
+
Production and reference paths: /docs/outputs/, /docs/limits/, /docs/security/,
|
|
138
|
+
/docs/production/ and /docs/api-reference/. The developer OpenAPI download is
|
|
139
|
+
/openapi/imazeo-developer.json. It is a curated development snapshot and excludes
|
|
140
|
+
Admin/account operations and the known defective unified Outputs list; use
|
|
141
|
+
resource-specific lists to enumerate inventory.
|
imazeo-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Imazeo
|
|
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.
|
imazeo-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: imazeo
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Official Imazeo Python SDK for server-side image, transform, PDF, QR, and barcode APIs
|
|
5
|
+
Project-URL: Homepage, https://pypi.org/project/imazeo/
|
|
6
|
+
Project-URL: Documentation, https://github.com/manishbalodia/imazeo-python#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/manishbalodia/imazeo-python
|
|
8
|
+
Project-URL: Issues, https://github.com/manishbalodia/imazeo-python/issues
|
|
9
|
+
Author: Imazeo
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: barcode,images,imazeo,pdf,qr,sdk,transforms
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
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
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# imazeo
|
|
29
|
+
|
|
30
|
+
Official **server-side** Python SDK for Imazeo.
|
|
31
|
+
|
|
32
|
+
| | |
|
|
33
|
+
| -------------- | ------------------------------- |
|
|
34
|
+
| Package | `imazeo` |
|
|
35
|
+
| SDK version | `1.0.0` |
|
|
36
|
+
| Default API | `v1` |
|
|
37
|
+
| Supported APIs | `v1` |
|
|
38
|
+
| Runtime | Python **3.10+** (sync `httpx`) |
|
|
39
|
+
| Registry | [PyPI](https://pypi.org/project/imazeo/) |
|
|
40
|
+
| Source | [GitHub](https://github.com/manishbalodia/imazeo-python) |
|
|
41
|
+
|
|
42
|
+
> **Security:** Secret API keys (`X-API-Key`) are for trusted servers only.
|
|
43
|
+
> Do **not** ship this client with a secret key in browsers or client apps.
|
|
44
|
+
|
|
45
|
+
Integration contract and learning path: [GUIDE.md](GUIDE.md).
|
|
46
|
+
|
|
47
|
+
## Install
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install imazeo
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Requires Python 3.10+. Create a project API key in the Imazeo customer portal.
|
|
54
|
+
Default API origin is `https://api.imazeo.com` (override with `base_url` when needed).
|
|
55
|
+
|
|
56
|
+
## Learning path
|
|
57
|
+
|
|
58
|
+
Read the self-contained [integration guide](GUIDE.md) for project/key setup,
|
|
59
|
+
language examples, PDF response types, pagination, output retention, troubleshooting
|
|
60
|
+
and production practices.
|
|
61
|
+
|
|
62
|
+
The default HTTP client refuses redirects so credentials stay on the configured
|
|
63
|
+
API origin.
|
|
64
|
+
|
|
65
|
+
## Quick start
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from pathlib import Path
|
|
69
|
+
from imazeo import Imazeo
|
|
70
|
+
import os
|
|
71
|
+
|
|
72
|
+
client = Imazeo(
|
|
73
|
+
api_key=os.environ["IMAZEO_API_KEY"],
|
|
74
|
+
base_url=os.environ["IMAZEO_API_ORIGIN"], # supplied API origin
|
|
75
|
+
# project_id="…", # optional; otherwise resolved via /v1/api-key/context
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
qr = client.qr.generate({
|
|
79
|
+
"content": "https://imazeo.com",
|
|
80
|
+
"format": "png",
|
|
81
|
+
"size": 256,
|
|
82
|
+
})
|
|
83
|
+
Path("qr.png").write_bytes(qr.data)
|
|
84
|
+
client.close()
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Or use as a context manager:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
with Imazeo(api_key=os.environ["IMAZEO_API_KEY"]) as client:
|
|
91
|
+
ctx = client.context.get()
|
|
92
|
+
print(ctx["projectId"], ctx["keyId"])
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Authentication
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
Imazeo(api_key=os.environ["IMAZEO_API_KEY"])
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Sends `X-API-Key` only. Never send `Authorization` together with an API key
|
|
102
|
+
(backend rejects that combination).
|
|
103
|
+
|
|
104
|
+
## Resources
|
|
105
|
+
|
|
106
|
+
| Resource | Methods |
|
|
107
|
+
| ------------------- | -------------------------------------------------------------------------------- |
|
|
108
|
+
| `client.context` | `get()` → project/key IDs |
|
|
109
|
+
| `client.images` | `upload`, `list` (`page`/`limit`/`q`), `get`, `delete`, `download` |
|
|
110
|
+
| `client.transforms` | `create`, `list`, `get`, `download` (`if_none_match` → `not_modified`), `delete` |
|
|
111
|
+
| `client.qr` | `generate` |
|
|
112
|
+
| `client.barcodes` | `generate` |
|
|
113
|
+
| `client.pdf` | `info`, `render`, `merge`, `extract` |
|
|
114
|
+
|
|
115
|
+
### Upload + transform
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
image = client.images.upload(
|
|
119
|
+
photo_bytes,
|
|
120
|
+
filename="photo.jpg",
|
|
121
|
+
content_type="image/jpeg",
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
out = client.transforms.create({
|
|
125
|
+
"imageId": image["_id"],
|
|
126
|
+
"mode": "EPHEMERAL",
|
|
127
|
+
"transform": {"width": 1200, "format": "webp", "quality": 85},
|
|
128
|
+
})
|
|
129
|
+
# out.data → bytes
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Remote URL transform
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
out = client.transforms.create({
|
|
136
|
+
"url": "https://example.com/image.jpg",
|
|
137
|
+
"transform": {"width": 640, "format": "jpeg"},
|
|
138
|
+
})
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### PDF
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
info = client.pdf.info(pdf_bytes)
|
|
145
|
+
page = client.pdf.render(pdf_bytes, {"pages": "1", "format": "png"})
|
|
146
|
+
merged = client.pdf.merge([pdf_a, pdf_b])
|
|
147
|
+
extracted = client.pdf.extract(pdf_bytes, {"pages": "1,2"})
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Errors
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
from imazeo import ImazeoError, RateLimitError
|
|
154
|
+
|
|
155
|
+
try:
|
|
156
|
+
client.images.get(image_id)
|
|
157
|
+
except RateLimitError as error:
|
|
158
|
+
print(error.code, error.request_id)
|
|
159
|
+
except ImazeoError as error:
|
|
160
|
+
print(error.status, error.code, error.message)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Configuration
|
|
164
|
+
|
|
165
|
+
| Option | Default | Notes |
|
|
166
|
+
| ------------- | ------------------------ | -------------------------------------- |
|
|
167
|
+
| `api_key` | required | Secret key |
|
|
168
|
+
| `project_id` | from context | Path project |
|
|
169
|
+
| `base_url` | `https://api.imazeo.com` | Origin only; `/v1` stripped if present |
|
|
170
|
+
| `api_version` | `v1` | Allowlisted |
|
|
171
|
+
| `timeout_ms` | `60000` | PDF uses 120s; QR/barcode 30s |
|
|
172
|
+
| `app_name` | — | Appended to User-Agent |
|
|
173
|
+
| `transport` | — | Optional `httpx.BaseTransport` (tests) |
|
|
174
|
+
|
|
175
|
+
## API version vs package version
|
|
176
|
+
|
|
177
|
+
- **API** path version: `v1` (configured via `api_version`)
|
|
178
|
+
- **SDK** SemVer: `1.0.0`
|
|
179
|
+
|
|
180
|
+
`Imazeo.api_compatibility()` reports supported API versions.
|
|
181
|
+
|
|
182
|
+
## Not included
|
|
183
|
+
|
|
184
|
+
Portal JWT APIs (projects CRUD, API-key management, usage, plans, tickets, auth),
|
|
185
|
+
admin APIs, tool-artifacts, outputs, and browser secret-key usage.
|
|
186
|
+
|
|
187
|
+
## Development
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
pip install -e ".[dev]"
|
|
191
|
+
pytest
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## License
|
|
195
|
+
|
|
196
|
+
MIT
|
|
197
|
+
|
|
198
|
+
## Media contract update — 2026-10-02
|
|
199
|
+
|
|
200
|
+
Barcode generation requires `type` and string `content`; optional `format` is
|
|
201
|
+
`png` or `svg` (default `png`), and `includeText` is a boolean (default `true`).
|
|
202
|
+
The old `data`, `output` and `includetext` fields are removed before release.
|
|
203
|
+
PDF merge sends repeated `file` parts in order. Omit optional fields for defaults;
|
|
204
|
+
JSON numbers/booleans are not coerced and top-level optional nulls are rejected.
|
|
205
|
+
Barcode scale and image hue are integers. Methods retain language-specific names.
|
|
206
|
+
The reviewed API-key-only contract is bundled in `openapi/backend.json`.
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
client.barcodes.generate({'type': 'code128', 'content': 'IMAZEO-2026', 'format': 'svg', 'includeText': False})
|
|
210
|
+
```
|
imazeo-1.0.0/README.md
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# imazeo
|
|
2
|
+
|
|
3
|
+
Official **server-side** Python SDK for Imazeo.
|
|
4
|
+
|
|
5
|
+
| | |
|
|
6
|
+
| -------------- | ------------------------------- |
|
|
7
|
+
| Package | `imazeo` |
|
|
8
|
+
| SDK version | `1.0.0` |
|
|
9
|
+
| Default API | `v1` |
|
|
10
|
+
| Supported APIs | `v1` |
|
|
11
|
+
| Runtime | Python **3.10+** (sync `httpx`) |
|
|
12
|
+
| Registry | [PyPI](https://pypi.org/project/imazeo/) |
|
|
13
|
+
| Source | [GitHub](https://github.com/manishbalodia/imazeo-python) |
|
|
14
|
+
|
|
15
|
+
> **Security:** Secret API keys (`X-API-Key`) are for trusted servers only.
|
|
16
|
+
> Do **not** ship this client with a secret key in browsers or client apps.
|
|
17
|
+
|
|
18
|
+
Integration contract and learning path: [GUIDE.md](GUIDE.md).
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install imazeo
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Requires Python 3.10+. Create a project API key in the Imazeo customer portal.
|
|
27
|
+
Default API origin is `https://api.imazeo.com` (override with `base_url` when needed).
|
|
28
|
+
|
|
29
|
+
## Learning path
|
|
30
|
+
|
|
31
|
+
Read the self-contained [integration guide](GUIDE.md) for project/key setup,
|
|
32
|
+
language examples, PDF response types, pagination, output retention, troubleshooting
|
|
33
|
+
and production practices.
|
|
34
|
+
|
|
35
|
+
The default HTTP client refuses redirects so credentials stay on the configured
|
|
36
|
+
API origin.
|
|
37
|
+
|
|
38
|
+
## Quick start
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from pathlib import Path
|
|
42
|
+
from imazeo import Imazeo
|
|
43
|
+
import os
|
|
44
|
+
|
|
45
|
+
client = Imazeo(
|
|
46
|
+
api_key=os.environ["IMAZEO_API_KEY"],
|
|
47
|
+
base_url=os.environ["IMAZEO_API_ORIGIN"], # supplied API origin
|
|
48
|
+
# project_id="…", # optional; otherwise resolved via /v1/api-key/context
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
qr = client.qr.generate({
|
|
52
|
+
"content": "https://imazeo.com",
|
|
53
|
+
"format": "png",
|
|
54
|
+
"size": 256,
|
|
55
|
+
})
|
|
56
|
+
Path("qr.png").write_bytes(qr.data)
|
|
57
|
+
client.close()
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Or use as a context manager:
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
with Imazeo(api_key=os.environ["IMAZEO_API_KEY"]) as client:
|
|
64
|
+
ctx = client.context.get()
|
|
65
|
+
print(ctx["projectId"], ctx["keyId"])
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Authentication
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
Imazeo(api_key=os.environ["IMAZEO_API_KEY"])
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Sends `X-API-Key` only. Never send `Authorization` together with an API key
|
|
75
|
+
(backend rejects that combination).
|
|
76
|
+
|
|
77
|
+
## Resources
|
|
78
|
+
|
|
79
|
+
| Resource | Methods |
|
|
80
|
+
| ------------------- | -------------------------------------------------------------------------------- |
|
|
81
|
+
| `client.context` | `get()` → project/key IDs |
|
|
82
|
+
| `client.images` | `upload`, `list` (`page`/`limit`/`q`), `get`, `delete`, `download` |
|
|
83
|
+
| `client.transforms` | `create`, `list`, `get`, `download` (`if_none_match` → `not_modified`), `delete` |
|
|
84
|
+
| `client.qr` | `generate` |
|
|
85
|
+
| `client.barcodes` | `generate` |
|
|
86
|
+
| `client.pdf` | `info`, `render`, `merge`, `extract` |
|
|
87
|
+
|
|
88
|
+
### Upload + transform
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
image = client.images.upload(
|
|
92
|
+
photo_bytes,
|
|
93
|
+
filename="photo.jpg",
|
|
94
|
+
content_type="image/jpeg",
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
out = client.transforms.create({
|
|
98
|
+
"imageId": image["_id"],
|
|
99
|
+
"mode": "EPHEMERAL",
|
|
100
|
+
"transform": {"width": 1200, "format": "webp", "quality": 85},
|
|
101
|
+
})
|
|
102
|
+
# out.data → bytes
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Remote URL transform
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
out = client.transforms.create({
|
|
109
|
+
"url": "https://example.com/image.jpg",
|
|
110
|
+
"transform": {"width": 640, "format": "jpeg"},
|
|
111
|
+
})
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### PDF
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
info = client.pdf.info(pdf_bytes)
|
|
118
|
+
page = client.pdf.render(pdf_bytes, {"pages": "1", "format": "png"})
|
|
119
|
+
merged = client.pdf.merge([pdf_a, pdf_b])
|
|
120
|
+
extracted = client.pdf.extract(pdf_bytes, {"pages": "1,2"})
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Errors
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
from imazeo import ImazeoError, RateLimitError
|
|
127
|
+
|
|
128
|
+
try:
|
|
129
|
+
client.images.get(image_id)
|
|
130
|
+
except RateLimitError as error:
|
|
131
|
+
print(error.code, error.request_id)
|
|
132
|
+
except ImazeoError as error:
|
|
133
|
+
print(error.status, error.code, error.message)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Configuration
|
|
137
|
+
|
|
138
|
+
| Option | Default | Notes |
|
|
139
|
+
| ------------- | ------------------------ | -------------------------------------- |
|
|
140
|
+
| `api_key` | required | Secret key |
|
|
141
|
+
| `project_id` | from context | Path project |
|
|
142
|
+
| `base_url` | `https://api.imazeo.com` | Origin only; `/v1` stripped if present |
|
|
143
|
+
| `api_version` | `v1` | Allowlisted |
|
|
144
|
+
| `timeout_ms` | `60000` | PDF uses 120s; QR/barcode 30s |
|
|
145
|
+
| `app_name` | — | Appended to User-Agent |
|
|
146
|
+
| `transport` | — | Optional `httpx.BaseTransport` (tests) |
|
|
147
|
+
|
|
148
|
+
## API version vs package version
|
|
149
|
+
|
|
150
|
+
- **API** path version: `v1` (configured via `api_version`)
|
|
151
|
+
- **SDK** SemVer: `1.0.0`
|
|
152
|
+
|
|
153
|
+
`Imazeo.api_compatibility()` reports supported API versions.
|
|
154
|
+
|
|
155
|
+
## Not included
|
|
156
|
+
|
|
157
|
+
Portal JWT APIs (projects CRUD, API-key management, usage, plans, tickets, auth),
|
|
158
|
+
admin APIs, tool-artifacts, outputs, and browser secret-key usage.
|
|
159
|
+
|
|
160
|
+
## Development
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
pip install -e ".[dev]"
|
|
164
|
+
pytest
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## License
|
|
168
|
+
|
|
169
|
+
MIT
|
|
170
|
+
|
|
171
|
+
## Media contract update — 2026-10-02
|
|
172
|
+
|
|
173
|
+
Barcode generation requires `type` and string `content`; optional `format` is
|
|
174
|
+
`png` or `svg` (default `png`), and `includeText` is a boolean (default `true`).
|
|
175
|
+
The old `data`, `output` and `includetext` fields are removed before release.
|
|
176
|
+
PDF merge sends repeated `file` parts in order. Omit optional fields for defaults;
|
|
177
|
+
JSON numbers/booleans are not coerced and top-level optional nulls are rejected.
|
|
178
|
+
Barcode scale and image hue are integers. Methods retain language-specific names.
|
|
179
|
+
The reviewed API-key-only contract is bundled in `openapi/backend.json`.
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
client.barcodes.generate({'type': 'code128', 'content': 'IMAZEO-2026', 'format': 'svg', 'includeText': False})
|
|
183
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Minimal server-side QR example.
|
|
2
|
+
|
|
3
|
+
Requires: IMAZEO_API_KEY, optional IMAZEO_BASE_URL, IMAZEO_PROJECT_ID
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
from imazeo import Imazeo
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def main() -> None:
|
|
16
|
+
api_key = os.environ.get("IMAZEO_API_KEY")
|
|
17
|
+
if not api_key:
|
|
18
|
+
raise SystemExit("Set IMAZEO_API_KEY")
|
|
19
|
+
|
|
20
|
+
with Imazeo(
|
|
21
|
+
api_key=api_key,
|
|
22
|
+
base_url=os.environ.get("IMAZEO_BASE_URL", "http://localhost:3001"),
|
|
23
|
+
project_id=os.environ.get("IMAZEO_PROJECT_ID"),
|
|
24
|
+
) as client:
|
|
25
|
+
ctx = client.context.get()
|
|
26
|
+
print("project", ctx["projectId"], "env", ctx["environment"])
|
|
27
|
+
|
|
28
|
+
qr = client.qr.generate(
|
|
29
|
+
{
|
|
30
|
+
"content": "https://imazeo.com",
|
|
31
|
+
"size": 256,
|
|
32
|
+
"format": "png",
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
Path("qr.png").write_bytes(qr.data)
|
|
36
|
+
print("wrote qr.png", qr.content_type)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
if __name__ == "__main__":
|
|
40
|
+
try:
|
|
41
|
+
main()
|
|
42
|
+
except Exception as error: # noqa: BLE001 — example script
|
|
43
|
+
print(error, file=sys.stderr)
|
|
44
|
+
raise SystemExit(1) from error
|