feat(api): extract pure API clients for image generation and TTS

- Add bin/api/ package with generate_image() and synthesize_tts()
- Refactor bin/commands/image.py to call bin.api.image.generate_image
- Refactor bin/commands/voice.py to call bin.api.voice.synthesize_tts
- API layer is free of Click CLI dependencies, usable by external scripts
This commit is contained in:
Zhengshou Lai
2026-06-03 23:43:28 +08:00
parent ac605c2c17
commit 334ff647fc
6 changed files with 174 additions and 110 deletions
+8 -38
View File
@@ -1,13 +1,11 @@
"""Image utilities."""
import base64
import os
import subprocess
import urllib.request
from pathlib import Path
import click
from bin.api.image import _RATIO_MAP, generate_image
from bin.config import config
from bin.utils import handle_errors, run_command
@@ -187,15 +185,6 @@ def compress_images(files, target_mb, max_width, quality, suffix, dry_run):
click.echo(f"Compressed: {img_file} -> {output} ({size_mb:.2f} MB)")
_RATIO_MAP = {
"1:1": "1024x1024",
"4:3": "1024x768",
"3:4": "768x1024",
"16:9": "1280x720",
"9:16": "720x1280",
}
@image.command("generate")
@click.argument("prompt", required=False)
@click.option("-f", "--file", type=click.Path(exists=True), help="从文件读取 prompt")
@@ -207,8 +196,6 @@ _RATIO_MAP = {
@handle_errors
def generate_image_cmd(prompt, file, size, ratio, output, no_watermark, b64):
"""使用豆包/Seedream 模型生成图片。"""
from openai import OpenAI
if file:
prompt = Path(file).read_text(encoding="utf-8").strip()
elif not prompt:
@@ -222,30 +209,13 @@ def generate_image_cmd(prompt, file, size, ratio, output, no_watermark, b64):
if size and ratio:
click.echo("Warning: --size 和 --ratio 同时指定,--size 优先", err=True)
resolved_size = size or (ratio and _RATIO_MAP[ratio]) or "2K"
client = OpenAI(
base_url="https://ark.cn-beijing.volces.com/api/v3",
result = generate_image(
api_key=api_key,
)
resp = client.images.generate(
model="doubao-seedream-5-0-260128",
prompt=prompt,
size=resolved_size,
response_format="b64_json" if b64 else "url",
extra_body={"watermark": not no_watermark},
size=size,
ratio=ratio,
output=output,
watermark=not no_watermark,
b64=b64,
)
if b64:
image_bytes = base64.b64decode(resp.data[0].b64_json)
save_path = output or "generated_image.png"
Path(save_path).write_bytes(image_bytes)
click.echo(os.path.abspath(save_path))
else:
url = resp.data[0].url
if output:
urllib.request.urlretrieve(url, output)
click.echo(os.path.abspath(output))
else:
click.echo(url)
click.echo(result)