mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-07 14:58:23 +08:00
feat: 异步图片任务结果落对象存储
为异步生图任务增加 S3 兼容对象存储支持,任务结果不再把大图内联存进 Redis: - 新增可插拔接口 service.ImageStorage(Save -> url),适配别的厂商只需实现它 - S3 实现 S3ImageStorage(AWS S3 / R2 / 阿里云 OSS / MinIO),与备份共用 S3 客户端构造 - 新增 image_storage 配置(config.yaml + IMAGE_STORAGE_* 环境变量),默认关闭 - enabled 同时作为总开关:关闭或未配置对象存储时,异步生图接口返回 404 且不写 Redis,从根上避免几 MB 的 b64_json 结果撑爆 Redis - 完成时把图片上传对象存储并把结果改写为短链接(公开直链或 presigned), 上传失败则任务标记为失败 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SM1tf3CFVRzC7guuhBXvMd
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
e5e94d1eb1
commit
0eb6e21aaa
@@ -16,6 +16,31 @@ The aliases are `/images/generations/async`, `/images/edits/async`, and `/images
|
||||
|
||||
Only OpenAI and Grok groups are supported. Requests use the same JSON or multipart payload as the corresponding synchronous endpoint. Streaming image requests are rejected because a polled task returns one final JSON result.
|
||||
|
||||
## Enabling the feature (object storage)
|
||||
|
||||
Asynchronous image tasks are **disabled by default** and gated on object storage. When the switch is off — or the S3 credentials are incomplete — the async endpoints return `404` and never create a task or write to Redis. This is deliberate: without offloading, large `b64_json` results (several MB each, e.g. `gpt-image-1`) would accumulate in Redis and exhaust its memory.
|
||||
|
||||
Configure an S3-compatible object store (AWS S3, Cloudflare R2, Aliyun OSS, MinIO, …) in `config.yaml` (all keys also accept the `IMAGE_STORAGE_*` environment overrides):
|
||||
|
||||
```yaml
|
||||
image_storage:
|
||||
enabled: true
|
||||
endpoint: "https://<account_id>.r2.cloudflarestorage.com" # AWS 官方可留空
|
||||
region: "auto"
|
||||
bucket: "my-images"
|
||||
access_key_id: "..."
|
||||
secret_access_key: "..."
|
||||
prefix: "images/"
|
||||
force_path_style: false # MinIO/path-style buckets set true
|
||||
public_base_url: "" # set to return public_base_url/key直链; empty → presigned URL
|
||||
presign_expiry_hours: 24 # presigned link TTL when public_base_url is empty
|
||||
max_download_bytes: 33554432 # cap when re-hosting an upstream image URL (32MB)
|
||||
```
|
||||
|
||||
When a task completes, each generated image is uploaded to the bucket and the result is rewritten to a compact form: `data[].url` points at the stored object (a permanent `public_base_url/key` link, or a time-limited presigned URL) and `b64_json` is removed. Only this small JSON is stored in Redis. If an upload fails, the task is marked `failed` rather than persisting the raw base64.
|
||||
|
||||
To support a different vendor beyond the S3-compatible client, implement the `service.ImageStorage` interface (`Save(ctx, key, contentType, data) (url, error)`) and provide it in place of the S3 implementation.
|
||||
|
||||
## Submit a task
|
||||
|
||||
```bash
|
||||
@@ -67,7 +92,7 @@ While work is in progress:
|
||||
}
|
||||
```
|
||||
|
||||
On success, `result` is the unmodified JSON body from the synchronous image API, so URL and base64 response formats both remain supported:
|
||||
On success, `result` mirrors the synchronous image API body, except each image has been offloaded to object storage: `data[].url` points at the stored object and `b64_json` is stripped (so both URL and base64 upstream formats end up as compact stored links):
|
||||
|
||||
```json
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user