feat: store async generated images as WebP

This commit is contained in:
vasily committed 2026-10-16 16:34:02 +08:00
1 parent a07c178fda
commit dc0f2080f3
6 files changed
+404 -18

No files matched your search

+6 -2
View File
@@ -51,7 +51,7 @@ curl -X POST http://127.0.0.1:8000/v1/generate \
-F 'images=@capture.jpg;type=image/jpeg' -F 'images=@style.png;type=image/png'
```
Polling mode accepts the same multipart fields with `?async_mode=true`. It returns a `job_id`; poll the returned URL with `client_id` as a query parameter and the same `x-client-secret` header. Jobs and their results are stored in SQLite so they survive a client disconnect. Jobs still processing when the proxy process restarts are marked failed because the in-process worker cannot resume safely.
Polling mode accepts the same multipart fields with `?async_mode=true`. It returns a `job_id`; poll the returned URL with `client_id` as a query parameter and the same `x-client-secret` header. Job state and compact result metadata are stored in SQLite; generated images are converted to WebP (quality 90 by default) and stored as private files under `OUTPUT_DIR` (default `./data/generated`). Downloaded async results use `image/webp`, so save them with a `.webp` extension or convert them locally to JPEG/PNG if the next step requires it. Output files are automatically deleted after 24 hours (checked at startup and every five minutes); job, timing, and cost records remain. Once a job completes or fails, its uploaded prompt/image request payload is removed from SQLite. Jobs still processing when the proxy process restarts are marked failed because the in-process worker cannot resume safely.
The built-in `nano-banana` alias defaults to Gemini 2.5 Flash Image. Set `GOOGLE_MODEL_NANO_BANANA` and `OPENROUTER_MODEL_NANO_BANANA` to provider model IDs you have confirmed are available for your account. Other model IDs are passed through (with `google/` prefix normalization for the native provider).
@@ -61,6 +61,9 @@ The built-in `nano-banana` alias defaults to Gemini 2.5 Flash Image. Set `GOOGLE
| --- | --- | --- |
| `ADMIN_SECRET` | required | Protects administration endpoints. Use a long random value. |
| `DB_PATH` | `./data/proxy.db` | SQLite database location. |
| `OUTPUT_DIR` | `./data/generated` | Private directory for generated output images. Back it up with the database. |
| `OUTPUT_WEBP_QUALITY` | `90` | WebP quality used for stored async outputs (1–100). |
| `OUTPUT_RETENTION_SECONDS` | `86400` | Lifetime of generated image files; cleanup runs every five minutes. |
| `MAX_UPLOAD_BYTES` | `52428800` | Aggregate raw image upload limit. |
| `MAX_IMAGES` | `8` | Maximum reference image count. |
| `MAX_IMAGE_PIXELS` | `25000000` | Maximum width × height for each uploaded image. |
@@ -76,7 +79,8 @@ Only one Uvicorn worker is supported for this initial implementation. SQLite WAL
See the copyable endpoint guide in [`docs/API.md`](docs/API.md).
- `POST /v1/generate` — multipart `client_id`, `prompt`, `model`, optional `provider`, JSON `params`, repeated `images`; optional `?async_mode=true`.
- `GET /v1/jobs/{job_id}?client_id=...` — job status/result, tenant-scoped.
- `GET /v1/jobs/{job_id}?client_id=...&include_result=false` — small, tenant-scoped job status and image download links.
- `GET /v1/jobs/{job_id}/images/{index}?token=...` — raw image download using a short-lived signed link (or use client-secret authentication).
- `GET /api/admin/state` — client and redacted key state (`x-admin-secret`).
- `POST /api/admin/client` — create/update a client (`x-admin-secret`).
- `POST /api/keys` and `DELETE /api/keys/{id}` — manage keys with `auth-secret` (admin or owning client secret).