fix: streamline gemini flow and add e2e test

This commit is contained in:
2026-03-08 23:58:17 +08:00
parent 82284ce3fb
commit 2ab27eb914
3 changed files with 151 additions and 8 deletions

View File

@@ -0,0 +1,144 @@
import asyncio
import os
from datetime import datetime
from pathlib import Path
import httpx
from dotenv import load_dotenv
from PIL import Image, ImageDraw
from services.service_gemini import GeminiExtractV2Service
from services.service_tuhui_upload import upload_to_tuhui
load_dotenv()
BASE_DIR = Path(__file__).resolve().parents[1] / "tmp_e2e_pipeline"
BASE_DIR.mkdir(parents=True, exist_ok=True)
TUHUI_WEB_BASE = os.getenv("TUHUI_WEB_BASE_URL", "https://tuhui.cloud").rstrip("/")
TUHUI_DIRECT_BASE = os.getenv("TUHUI_DIRECT_BASE_URL", "http://1.12.50.92:8002").rstrip("/")
TUHUI_API_BASES = [f"{TUHUI_DIRECT_BASE}/api", f"{TUHUI_WEB_BASE}/api"]
TUHUI_PHONE = os.getenv("TUHUI_PHONE", "17520145271")
TUHUI_PASSWORD = os.getenv("TUHUI_PASSWORD", "zuowei1216")
def build_test_input() -> Path:
ts = datetime.now().strftime("%Y%m%d_%H%M%S")
path = BASE_DIR / f"input_{ts}.png"
img = Image.new("RGBA", (768, 768), (228, 244, 249, 255))
draw = ImageDraw.Draw(img)
draw.rounded_rectangle((40, 40, 728, 728), radius=48, fill=(33, 114, 147, 255))
draw.ellipse((120, 120, 340, 340), fill=(96, 214, 255, 255))
draw.rectangle((390, 160, 640, 460), fill=(11, 54, 72, 255))
draw.text((110, 540), "TW Gemini E2E Test", fill=(255, 255, 255, 255))
img.save(path)
return path
async def login_tuhui(client: httpx.AsyncClient) -> tuple[str, str]:
last_error = None
for api_base in TUHUI_API_BASES:
try:
resp = await client.post(
f"{api_base}/auth/login",
json={"phone": TUHUI_PHONE, "password": TUHUI_PASSWORD},
timeout=30.0,
)
resp.raise_for_status()
data = resp.json()
return data["access_token"], api_base
except Exception as e:
last_error = e
raise last_error or RuntimeError("图绘登录失败")
async def create_order_and_pay(client: httpx.AsyncClient, api_base: str, token: str, work_id: int) -> dict:
headers = {"Authorization": f"Bearer {token}"}
order_resp = await client.post(
f"{api_base}/orders/create",
headers=headers,
json={"work_id": work_id, "payment_method": "balance"},
timeout=30.0,
)
order_resp.raise_for_status()
order = order_resp.json()
pay_resp = await client.post(
f"{api_base}/orders/pay/{order['id']}",
headers=headers,
timeout=30.0,
)
pay_resp.raise_for_status()
payment = pay_resp.json()
return {"order": order, "payment": payment}
async def download_work(client: httpx.AsyncClient, api_base: str, token: str, work_id: int) -> Path:
headers = {"Authorization": f"Bearer {token}"}
resp = await client.get(
f"{api_base}/works/{work_id}/download",
headers=headers,
timeout=60.0,
)
resp.raise_for_status()
filename = resp.headers.get("content-disposition", "").split("filename=")[-1].strip('"') or f"work_{work_id}.bin"
dest = BASE_DIR / filename
dest.write_bytes(resp.content)
return dest
async def main():
print("== 构建测试图 ==")
input_path = build_test_input()
output_path = BASE_DIR / f"gemini_{input_path.stem}.png"
print(f"输入图: {input_path}")
print("== Gemini 处理 ==")
gemini = GeminiExtractV2Service()
success, message, data = await gemini.extract_pattern(
str(input_path),
str(output_path),
custom_prompt="根据原图生成一张更完整、更干净的科技风背景素材图,保持主体布局清晰。",
aspect_ratio="1:1",
)
print({"success": success, "message": message, "data": data})
if not success:
raise RuntimeError(f"Gemini 处理失败: {message}")
print("== 上传图绘 ==")
title = f"E2E测试图_{datetime.now().strftime('%m%d_%H%M%S')}"
upload_result = await upload_to_tuhui(
image_path=str(output_path),
title=title,
description="自动化端到端测试图0元下载校验。",
price=0,
category="设计素材",
tags="E2E测试,自动化",
designer_name="自动化测试",
)
print(upload_result.as_dict())
if not upload_result.success:
raise RuntimeError(f"图绘上传失败: {upload_result.message}")
print("== 登录图绘并创建0元订单 ==")
async with httpx.AsyncClient(follow_redirects=True) as client:
token, api_base = await login_tuhui(client)
pay_info = await create_order_and_pay(client, api_base, token, upload_result.work_id)
print(pay_info)
print("== 下载作品 ==")
downloaded = await download_work(client, api_base, token, upload_result.work_id)
print({"downloaded_file": str(downloaded), "size": downloaded.stat().st_size})
print("== 测试完成 ==")
print(
{
"work_id": upload_result.work_id,
"detail_url": upload_result.download_url,
"processed_output": str(output_path),
}
)
if __name__ == "__main__":
asyncio.run(main())