Files
AiDA_Python/app/api/api_generate_image.py

473 lines
20 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import json
import logging
import httpx
import requests
from fastapi import APIRouter, BackgroundTasks, HTTPException
from app.core.config import settings
from app.schemas.generate_image import GenerateImageModel, GenerateProductImageModel, GenerateSingleLogoImageModel, GenerateRelightImageModel, GenerateMultiViewModel, BatchGenerateProductImageModel, BatchGenerateRelightImageModel, AgentTollGenerateImageModel, Flux2ToProductImgModel, GenerateSloganImageModel, GenerateImageFlux2KleinModel
from app.schemas.pose_transform import BatchPoseTransformModel
from app.schemas.response_template import ResponseModel
from app.service.generate_batch_image.service import start_product_batch_generate, start_relight_batch_generate, start_pose_transform_batch_generate
from app.service.generate_image.service_agent_tool_generate_image import AgentToolGenerateImage
from app.service.generate_image.service_generate_image import GenerateImage, infer_cancel as generate_image_infer_cancel
from app.service.generate_image.service_generate_multi_view import GenerateMultiView, infer_cancel as generate_multi_view_cancel
from app.service.generate_image.service_generate_product_image import GenerateProductImage, infer_cancel as generate_product_image_cancel
from app.service.generate_image.service_generate_relight_image import GenerateRelightImage, infer_cancel as generate_relight_image_cancel
from app.service.generate_image.service_generate_single_logo import GenerateSingleLogoImage, infer_cancel as generate_single_logo_cancel
router = APIRouter()
logger = logging.getLogger()
'''generate image'''
# flux2 klein
@router.post("/generate_image_flux2_klein")
async def generate_image_flux2_klein(request_item: GenerateImageFlux2KleinModel):
"""
创建一个具有以下参数的请求体:
- **bucket_name**: OSS桶名 (必填)
- **object_name**: OSS对象名文件路径(必填)
- **width**: 图片宽度默认1024像素 (非必填,1024)
- **height**: 图片高度默认1024像素 (非必填,默认1024)
- **prompt**: 文本提示词,用于模型推理等场景 (非必填,默认"")
- **steps**: 推理步数,控制模型生成过程的迭代次数 (非必填,默认4)
- **guidance**: 引导系数,调节提示词对生成结果的影响程度 (非必填,默认 4.0 )
### 示例参数:
```
{
"bucket_name": "aida-users",
"object_name": "89/moodboard/5fdc698c-cb9b-4b36-afa9ce4-1-89.png",
"prompt": "a single item of sketch of dress, 4k, white background"
}
```
### 输出示例:
```
{
"code": 200,
"msg": "OK!",
"data": {
"output_path": "aida-users/89/moodboard/5fdc698c-cb9b-4b36-afa9ce4-1-89.png"
}
}
```
"""
try:
logger.info(f"generate_image_flux2_gen_img request: {json.dumps(request_item.model_dump(), indent=4)}")
async with httpx.AsyncClient(timeout=120) as client:
resp = await client.post(
f"http://{settings.FLUX2_GEN_IMG_MODEL_URL}/predict",
json=request_item.model_dump(),
)
result = resp.json()
logger.info(f"generate_image_flux2_gen_img response: {json.dumps(result, indent=4)}")
return ResponseModel(data=result)
except Exception as e:
logger.warning(f"generate_image_flux2_gen_img Run Exception @@@@@@:{e}")
raise HTTPException(status_code=404, detail=str(e))
# sdxl
@router.post("/generate_image")
def generate_image(request_item: GenerateImageModel, background_tasks: BackgroundTasks):
"""
创建一个具有以下参数的请求体:
- **tasks_id**: 任务id 用于取消生成任务和获取生成结果
- **prompt**: 想要生成图片的描述词
- **image_url**: 图生图的输入minio或S3 url 地址
- **mode**: 生成模式img2img或者txt2img
- **category**: 生成图片的类别sketch print 等等
- **gender**: 生成sketch专用服装类别
- **version**: 使用模型版本 fast 或者 high
示例参数:
1. txt 2 img
{
"tasks_id": "bd2cf809-24bc-49a6-91c9-193c6272a52e-2-89",
"prompt": "a single item of sketch of dress, 4k, white background",
"image_url": "",
"mode": "txt2img",
"category": "sketch",
"gender": "Female",
"version": "fast"
}
2. img 2 img
{
"tasks_id": "b861d4fa-5ae3-4a30-9c7a-7ba6bb9aa37b-1-89",
"prompt": "a single item of sketch of dress, 4k, white background",
"image_url": "aida-collection-element/89/Sketchboard/548da3a2-834f-49a7-b52c-e729c5ab5062.png",
"mode": "img2img",
"category": "sketch",
"gender": "Female",
"version": "fast"
}
"""
try:
logger.info(f"generate_image request item is : @@@@@@:{json.dumps(request_item.dict(), indent=4)}")
service = GenerateImage(request_item)
background_tasks.add_task(service.get_result)
except Exception as e:
logger.warning(f"generate_image Run Exception @@@@@@:{e}")
raise HTTPException(status_code=404, detail=str(e))
return ResponseModel()
@router.get("/generate_cancel/{tasks_id}")
def generate_image(tasks_id: str):
try:
logger.info(f"generate_cancel request item is : @@@@@@:{tasks_id}")
data = generate_image_infer_cancel(tasks_id)
logger.info(f"generate_cancel response @@@@@@:{data}")
except Exception as e:
logger.warning(f"generate_cancel Run Exception @@@@@@:{e}")
raise HTTPException(status_code=404, detail=str(e))
return ResponseModel(data=data['data'])
'''multi view 停用'''
# @router.post("/generate_multi_view")
# def generate_multi_view(request_item: GenerateMultiViewModel, background_tasks: BackgroundTasks):
# """
# 创建一个具有以下参数的请求体:
# - **tasks_id**: 任务id 用于取消生成任务和获取生成结果
# - **image_url**: 前视角图的输入minio或S3 url 地址
#
# 示例参数:
# {
# "tasks_id": "123-89",
# "image_url": "aida-collection-element/87/Printboard/842c09cf-7297-42d9-9e6e-9c17d4a13cb5.jpg"
# }
# """
# try:
# logger.info(f"generate_multi_view request item is : @@@@@@:{json.dumps(request_item.dict(),indent=4)}")
# service = GenerateMultiView(request_item)
# background_tasks.add_task(service.get_result)
# except Exception as e:
# logger.warning(f"generate_multi_view Run Exception @@@@@@:{e}")
# raise HTTPException(status_code=404, detail=str(e))
# return ResponseModel()
# @router.get("/generate_multi_view_cancel/{tasks_id}")
# def generate_multi_view(tasks_id: str):
# try:
# logger.info(f"generate_cancel request item is : @@@@@@:{tasks_id}")
# data = generate_multi_view_cancel(tasks_id)
# logger.info(f"generate_cancel response @@@@@@:{data}")
# except Exception as e:
# logger.warning(f"generate_cancel Run Exception @@@@@@:{e}")
# raise HTTPException(status_code=404, detail=str(e))
# return ResponseModel(data=data['data'])
'''single logo'''
@router.post("/generate_single_logo")
def generate_single_logo(request_item: GenerateSingleLogoImageModel, background_tasks: BackgroundTasks):
"""
创建一个具有以下参数的请求体:
- **tasks_id**: 任务id 用于取消生成任务和获取生成结果
- **prompt**: 想要生成图片的描述词
- **seed**: 固定的prompt和固定的seed 每次的生成结果都是一样的
示例参数:
{
"tasks_id": "123-89",
"prompt": "an apple",
"seed": "2"
}
"""
try:
logger.info(f"generate_single_logo request item is : @@@@@@:{json.dumps(request_item.dict(), indent=4)}")
service = GenerateSingleLogoImage(request_item)
background_tasks.add_task(service.get_result)
except Exception as e:
logger.warning(f"generate_single_logo Run Exception @@@@@@:{e}")
raise HTTPException(status_code=404, detail=str(e))
return ResponseModel()
@router.get("/generate_single_logo_cancel/{tasks_id}")
def generate_single_logo_image(tasks_id: str):
try:
logger.info(f"generate_single_logo_cancel request item is : @@@@@@:{tasks_id}")
data = generate_single_logo_cancel(tasks_id)
logger.info(f"generate_single_logo_cancel response @@@@@@:{data}")
except Exception as e:
logger.warning(f"generate_single_logo_cancel Run Exception @@@@@@:{e}")
raise HTTPException(status_code=404, detail=str(e))
return ResponseModel(data=data['data'])
"""slogan """
@router.post("/generate_slogan")
async def generate_slogan(request_data: GenerateSloganImageModel):
"""
### 请求体示例:
```json
{
"num_point": 16,
"image_url": "aida-slogan/6886785f-0aac-4052-b6fd-7ae20a841d8d.png",
"prompt": "123",
"tasks_id": "string-89"
}
```
"""
try:
logger.info(f"generate_slogan request item is : @@@@@@:{json.dumps(request_data.dict(), indent=4)}")
data = requests.post(f"http://{settings.A6000_SERVICE_HOST}:10020/api/slogan", json=request_data.dict())
logger.info(f"generate_slogan response @@@@@@:{json.dumps(json.loads(data.content), indent=4)}")
return ResponseModel(data=json.loads(data.content))
except Exception as e:
logger.warning(f"generate_slogan Run Exception @@@@@@:{e}")
"""product image flux2.0"""
# @router.post("/img_to_product")
# async def img_to_product(request_data: Flux2ToProductImgModel):
# """
# 创建一个具有以下参数的请求体:
# - **tasks_id**: 任务id 用于取消生成任务和获取生成结果
# - **prompt**: 想要生成图片的描述词
# - **image_path**: 被生成图片的S3或minio url地址
# - **infer_step**: 推理步数
#
# ### 请求体示例:
# ```json
# point
# {
# "prompt": "Create realistic studio photo with real people model standing and wearing this garment, in white studio, Keep original model if present, or generate appropriate model, Standing pose, facing camera.",
# "image_path":"aida-results/result_38151e0a-f83b-11f0-89f6-0242ac130002.png",
# "infer_step":4,
# "tasks_id":"123456-123"
# }
# ```
# """
# try:
# logger.info(f"img_to_product request item is : @@@@@@:{json.dumps(request_data.dict(), indent=4)}")
# data = requests.post(f"http://{settings.A6000_SERVICE_HOST}:10090/api/v1/to_product", json=request_data.dict())
# logger.info(f"img_to_product response @@@@@@:{json.dumps(json.loads(data.content), indent=4)}")
# return ResponseModel(data=json.loads(data.content))
# except Exception as e:
# logger.warning(f"img_to_product Run Exception @@@@@@:{e}")
'''product image'''
@router.post("/generate_product_image")
def generate_product_image(request_item: GenerateProductImageModel, background_tasks: BackgroundTasks):
"""
创建一个具有以下参数的请求体:
- **tasks_id**: 任务id 用于取消生成任务和获取生成结果
- **prompt**: 想要生成图片的描述词
- **image_url**: 被生成图片的S3或minio url地址
- **image_strength**: 生成强度,越低越接近原图
- **product_type**: 输入single item 还是 overall item
示例参数:
{
"tasks_id": "123-89",
"prompt": "the best quality, masterpiece. detailed, high-res, simple background, studio photography, extremely detailed, updo, detailed face, face, close-up, HDR, UHD, 8K realistic, Highly detailed, simple background, Studio lighting",
"image_url": "aida-results/result_00097282-ebb2-11ee-a822-b48351119060.png",
"image_strength": 0.8,
"product_type": "overall"
}
"""
try:
logger.info(f"generate_product_image request item is : @@@@@@:{json.dumps(request_item.dict(), indent=4)}")
service = GenerateProductImage(request_item)
background_tasks.add_task(service.get_result)
except Exception as e:
logger.warning(f"generate_product_image Run Exception @@@@@@:{e}")
raise HTTPException(status_code=404, detail=str(e))
return ResponseModel()
@router.get("/generate_product_image_cancel_cancel/{tasks_id}")
def generate_product_image(tasks_id: str):
try:
logger.info(f"generate_product_image_cancel_cancel request item is : @@@@@@:{tasks_id}")
data = generate_product_image_cancel(tasks_id)
logger.info(f"generate_product_image_cancel_cancel response @@@@@@:{data}")
except Exception as e:
logger.warning(f"generate_product_image_cancel_cancel Run Exception @@@@@@:{e}")
raise HTTPException(status_code=404, detail=str(e))
return ResponseModel(data=data['data'])
'''relight image 停用'''
# @router.post("/generate_relight_image")
# def generate_relight_image(request_item: GenerateRelightImageModel, background_tasks: BackgroundTasks):
# """
# 创建一个具有以下参数的请求体:
# - **tasks_id**: 任务id 用于取消生成任务和获取生成结果
# - **prompt**: 想要生成图片的描述词
# - **image_url**: 被生成图片的S3或minio url地址
# - **direction**: 光源方向 Right Light Left Light Top Light Bottom Light
# - **product_type**: 输入single item 还是 overall item
#
#
# 示例参数:
# {
# "tasks_id": "123-89",
# "prompt": "beautiful woman, detailed face, sunshine, outdoor, warm atmosphere",
# "image_url": "aida-results/result_0000b606-1902-11ef-9424-0242ac180002.png",
# "direction": "Right Light",
# "product_type": "overall"
# }
# """
# try:
# logger.info(f"generate_relight_image request item is : @@@@@@:{json.dumps(request_item.dict(),indent=4)}")
# service = GenerateRelightImage(request_item)
# background_tasks.add_task(service.get_result)
# except Exception as e:
# logger.warning(f"generate_relight_image Run Exception @@@@@@:{e}")
# raise HTTPException(status_code=404, detail=str(e))
# return ResponseModel()
#
#
# @router.get("/generate_relight_image_cancel_cancel/{tasks_id}")
# def generate_relight_image(tasks_id: str):
# try:
# logger.info(f"generate_relight_image_cancel_cancel request item is : @@@@@@:{tasks_id}")
# data = generate_relight_image_cancel(tasks_id)
# logger.info(f"generate_relight_image_cancel_cancel response @@@@@@:{data}")
# except Exception as e:
# logger.warning(f"generate_relight_image_cancel_cancel Run Exception @@@@@@:{e}")
# raise HTTPException(status_code=404, detail=str(e))
# return ResponseModel(data=data['data'])
"""batch generate img 停用"""
# @router.post("/batch_generate_product_image")
# async def batch_generate_product(request_batch_item: BatchGenerateProductImageModel):
# """
# 创建一个具有以下参数的请求体:
# - **tasks_id**: 任务id 用于获取生成结果
# - **prompt**: 想要生成图片的描述词
# - **image_url**: 被生成图片的S3或minio url地址
# - **image_strength**: 生成强度,越低越接近原图
# - **product_type**: 输入single item 还是 overall item
# - **batch_size**: 批生成数量
#
#
# 示例参数:
# {
# "tasks_id": "123-89",
# "prompt": "the best quality, masterpiece. detailed, high-res, simple background, studio photography, extremely detailed, updo, detailed face, face, close-up, HDR, UHD, 8K realistic, Highly detailed, simple background, Studio lighting",
# "image_url": "aida-results/result_00097282-ebb2-11ee-a822-b48351119060.png",
# "image_strength": 0.8,
# "product_type": "overall",
# "batch_size": 1
# }
# """
# return await start_product_batch_generate(request_batch_item)
#
#
# @router.post("/batch_generate_relight_image")
# async def batch_generate_relight(request_batch_item: BatchGenerateRelightImageModel):
# """
# 创建一个具有以下参数的请求体:
# - **tasks_id**: 任务id 用于获取生成结果
# - **prompt**: 想要生成图片的描述词
# - **image_url**: 被生成图片的S3或minio url地址
# - **direction**: 光源方向 Right Light Left Light Top Light Bottom Light
# - **product_type**: 输入single item 还是 overall item
# - **batch_size**: 批生成数量
#
#
# 示例参数:
# {
# "tasks_id": "123-89",
# "prompt": "beautiful woman, detailed face, sunshine, outdoor, warm atmosphere",
# "image_url": "aida-results/result_0000b606-1902-11ef-9424-0242ac180002.png",
# "direction": "Right Light",
# "product_type": "overall",
# "batch_size": 1
# }
# """
# return await start_relight_batch_generate(request_batch_item)
# @router.post("/batch_generate_pose_transform_image")
# async def batch_generate_pose_transform(request_batch_item: BatchPoseTransformModel):
# """
# 创建一个具有以下参数的请求体:
# - **tasks_id**: 任务id 用于取消生成任务和获取生成结果
# - **image_url**: 被生成图片的S3或minio url地址
# - **pose_id**: 1
# - **batch_size**: 批生成数量
#
#
# 示例参数:
# {
# "tasks_id": "123-89",
# "image_url": "aida-results/result_0000b606-1902-11ef-9424-0242ac180002.png",
# "pose_id": "1",
# "batch_size": 1
# }
# """
# return await start_pose_transform_batch_generate(request_batch_item)
#
#
# """agent tool"""
#
#
# @router.post("/agent_tool_generate_image")
# def agent_tool_generate_image(request_item: AgentTollGenerateImageModel):
# """
# 创建一个具有以下参数的请求体:
# - **prompt**: 想要生成图片的描述词
# - **category**: 生成图片的类别sketch print 等等
# - **gender**: 生成sketch专用服装类别
# - **version**: 使用模型版本 fast 或者 high
# - **size**: 生成数量
# - **version**: 使用模型版本 fast 或者 high
#
#
# 示例参数:
# {
# "prompt": "a single item of sketch of Wabi-sabi, skirt, tiered, 4k, white background",
# "category": "sketch",
# "gender": "male",
# "size":2,
# "version":"high"
# }
# """
# try:
# logger.info(f"agent_tool_generate_image request item is : @@@@@@:{request_item.dict()}")
# request_data = request_item.dict()
# service = AgentToolGenerateImage(request_data['version'])
# image_url_list, clothing_category_list = service.get_result(
# prompt=request_data['prompt'],
# size=request_data['size'],
# version=request_data['version'],
# category=request_data['category'],
# gender=request_data['gender']
# )
# data = {
# "image_url_list": image_url_list,
# "clothing_category_list": clothing_category_list
# }
# logger.info(f"agent_tool_generate_image response item is : @@@@@@:{data}")
# except Exception as e:
# logger.warning(f"agent_tool_generate_image Run Exception @@@@@@:{e}")
# raise HTTPException(status_code=404, detail=str(e))
# return ResponseModel(data=data)