合并分支
* Merge branch 'main' into feature/modal-cluster-gemini * FIX 修复带图片模态推理接口 * PERF 优化Gemini Prompt词 * Merge remote-tracking branch 'origin/main' into feature/modal-cluster-gemini * ADD 增加网格图片创建接口 ADD gemini推理打点增加商品封面模态 PERF gemini打点结果相邻时间线同商品合并 * Merge branch 'main' into feature/modal-cluster-gemini * FIX 429重试机制 * FIX 修复Gemini推理函数入参 * Merge branch 'main' into feature/modal-cluster-gemini * PERF gemini修改参数类型 ADD 增加批量删除Gemini文件接口 * PERF gemini修改prompt * Merge branch 'feature/modal-cluster' into feature/modal-cluster-gemini * PERF gemini修改prompt * 录制HLS时 结果复制到S3挂载点增加一个fallback处理 * Merge branch 'feature/modal-cluster' into feature/modal-cluster-gemini * PERF gemini修改prompt * PERF gemini增加图像模态 * PERF gemini增加图像模态 * fix : TikHub的Logger换为Loguru * fix : 修复直播切分视频接口 * Merge branch 'feature/modal-cluster' into feature/modal-cluster-gemini * PERF tikhub接口增加随机延迟 * Merge remote-tracking branch 'origin/feature/modal-cluster' into feature/modal-cluster * 合并分支 * fix : hls录制缓存读写问题 * FIX 修改冲突 * ADD 增加获取直播间指定商品数量接口 * Merge branch 'feature/modal-cluster' into feature/modal-cluster-gemini * PERF 修改tikhub到aws * fix : 增加s3分片上传接口 * PERF Gemini推理直接从参数列表获取商品列表 ADD Tikhub增加获取置顶|讲解中商品接口 * PERF Gemini推理直接从参数获取商品列表 * Merge branch 'feature/modal-cluster' into feature/modal-cluster-gemini * fix 处理jpg图片的codec_name应为mjpg * Merge branch 'feature/modal-cluster' into feature/modal-cluster-gemini * PERF 优化返回值 * fix 获取媒体metadata的类型报错,modal client升级到1.0.2 * Merge branch 'feature/modal-cluster' into feature/modal-cluster-gemini * PERF 风控后爬虫直接退出避免cookie失效 PERF 分离tikhub api, 使用更低的保持时间以更换IP FIX 修复Dict键不存在报错的bug * fix 一些webhook相关的bug,添加了更详细的接口说明 * 更新直播录制为可跳转时间的hls流接口,用于替代掉腾讯VOD+火山云拉流转推,片段保证每片开头为关键帧,时间精度准确到毫秒级 * ADD 增加直播间商品增量缓存触发器 * Merge branch 'feature/modal-cluster' into feature/modal-cluster-gemini * PERF 调整gemini prompt * - KVCache类改为可拓展,基于环境变量设置KV space - test 环境配置与CF测试环境对齐 * FIX 修复Gemini推理视频切条的问题 PERF 优化视频切条函数性能 * ADD 基本完成gemini视频推理API * ADD 添加内联的tikhub * 对齐预发环境 --------- Merge request URL: https://g-ldyi2063.coding.net/p/dev/d/modalDeploy/git/merge/4794 Co-authored-by: 康宇佳,shuohigh@gmail.com
This commit is contained in:
@@ -14,7 +14,7 @@ from starlette.responses import JSONResponse
|
||||
|
||||
from BowongModalFunctions.config import WorkerConfig
|
||||
from BowongModalFunctions.models.web_model import SentryTransactionInfo, GeminiResultResponse, GeminiRequest, \
|
||||
ModalTaskResponse
|
||||
ModalTaskResponse, MakeGridGeminiRequest
|
||||
from BowongModalFunctions.utils.ModalUtils import ModalUtils
|
||||
|
||||
config = WorkerConfig()
|
||||
@@ -25,7 +25,6 @@ router = APIRouter(prefix="/google", tags=["Google"])
|
||||
class GoogleAPIKeyHeaders(BaseModel):
|
||||
x_google_api_key: Optional[str] = Field(description="Google API Key")
|
||||
|
||||
|
||||
class BundleHeaders(BaseModel):
|
||||
x_google_api_key: Optional[str] = Field(description="Google API Key")
|
||||
x_trace_id: str = Field(description="Sentry Transaction ID", default=None)
|
||||
@@ -102,7 +101,6 @@ async def delete_file(filename: str, headers: Annotated[GoogleAPIKeyHeaders, Hea
|
||||
response.raise_for_status()
|
||||
return JSONResponse(content=response.json(), status_code=response.status_code)
|
||||
|
||||
|
||||
@router.delete('/delete_all', summary="删除所有已上传的文件/第一页")
|
||||
async def delete_all(headers: Annotated[GoogleAPIKeyHeaders, Header()]):
|
||||
google_api_key = headers.x_google_api_key or os.environ.get("GOOGLE_API_KEY")
|
||||
@@ -122,7 +120,6 @@ async def delete_all(headers: Annotated[GoogleAPIKeyHeaders, Header()]):
|
||||
return JSONResponse(content={"msg": f"删除文件{filename}失败"}, status_code=resp.status_code)
|
||||
return JSONResponse(content=response.json(), status_code=response.status_code)
|
||||
|
||||
|
||||
@router.get('/list', summary="列出已上传的文件")
|
||||
async def list_files(headers: Annotated[GoogleAPIKeyHeaders, Header()]):
|
||||
google_api_key = headers.x_google_api_key or os.environ.get("GOOGLE_API_KEY")
|
||||
@@ -135,6 +132,16 @@ async def list_files(headers: Annotated[GoogleAPIKeyHeaders, Header()]):
|
||||
return JSONResponse(content={}, status_code=response.status_code)
|
||||
return JSONResponse(content=response.json() if len(response.text) > 0 else "", status_code=response.status_code)
|
||||
|
||||
@router.post("/make_grid_gemini", summary="将输入图拼为网格上传到Gemini网盘")
|
||||
async def make_grid_gemini_upload(data: MakeGridGeminiRequest, headers: Annotated[BundleHeaders, Header()]):
|
||||
google_api_key = headers.x_google_api_key or os.environ.get("GOOGLE_API_KEY")
|
||||
if not google_api_key:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Missing Google API Key")
|
||||
fn = modal.Function.from_name(config.modal_app_name,"make_image_grid_upload", environment_name=config.modal_environment)
|
||||
image_grid_uri = await fn.remote.aio(data.pic_info_list, data.image_size, data.text_height, data.font_size, data.padding, data.separator, google_api_key,
|
||||
SentryTransactionInfo(x_trace_id=sentry_sdk.get_traceparent(), x_baggage=sentry_sdk.get_baggage())
|
||||
if headers.x_trace_id is None else SentryTransactionInfo(x_trace_id=headers.x_trace_id, x_baggage=headers.x_baggage))
|
||||
return JSONResponse(content={"uri":image_grid_uri}, status_code=200)
|
||||
|
||||
@router.post('/inference_gemini', summary="使用Gemini推理hls视频流指定时间段的打点情况")
|
||||
async def inference_gemini(
|
||||
@@ -144,13 +151,10 @@ async def inference_gemini(
|
||||
google_api_key = headers.x_google_api_key or os.environ.get("GOOGLE_API_KEY")
|
||||
if not google_api_key:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Missing Google API Key")
|
||||
fn = modal.Function.from_name(config.modal_app_name, "video_hls_slice_inference",
|
||||
environment_name=config.modal_environment)
|
||||
fn_call = fn.spawn(data.media_hls_url, google_api_key, data.product_list, data.start_time, data.end_time,
|
||||
SentryTransactionInfo(x_trace_id=sentry_sdk.get_traceparent(),
|
||||
x_baggage=sentry_sdk.get_baggage())
|
||||
if headers.x_trace_id is None else SentryTransactionInfo(x_trace_id=headers.x_trace_id,
|
||||
x_baggage=headers.x_baggage))
|
||||
fn = modal.Function.from_name(config.modal_app_name,"video_hls_slice_inference", environment_name=config.modal_environment)
|
||||
fn_call = fn.spawn(data.media_hls_url, google_api_key, data.product_cover_grid_uri_list, data.product_list, data.start_time, data.end_time,
|
||||
SentryTransactionInfo(x_trace_id=sentry_sdk.get_traceparent(), x_baggage=sentry_sdk.get_baggage())
|
||||
if headers.x_trace_id is None else SentryTransactionInfo(x_trace_id=headers.x_trace_id, x_baggage=headers.x_baggage))
|
||||
return ModalTaskResponse(success=True, taskId=fn_call.object_id)
|
||||
|
||||
|
||||
@@ -162,11 +166,10 @@ async def gemini_status(task_id: str, response: Response) -> GeminiResultRespons
|
||||
response.headers["x-baggage"] = task_info.transaction.x_baggage
|
||||
try:
|
||||
return GeminiResultResponse(taskId=task_id, status=task_info.status, code=cast(int, task_info.error_code.value),
|
||||
error=task_info.error_reason,
|
||||
result=json.dumps(task_info.results, ensure_ascii=False)
|
||||
error=task_info.error_reason, result=json.dumps(task_info.results, ensure_ascii=False)
|
||||
if task_info.results is not None else "")
|
||||
except Exception as e:
|
||||
logger.exception(f"获取Gemini状态发生错误 {e}")
|
||||
return GeminiResultResponse(taskId=task_id, status=task_info.status, code=cast(int, task_info.error_code.value),
|
||||
error=task_info.error_reason + f"获取Gemini状态发生错误 {e}"
|
||||
if task_info.error_reason else f"获取Gemini状态发生错误 {e}", result="")
|
||||
if task_info.error_reason else f"获取Gemini状态发生错误 {e}", result="")
|
||||
Reference in New Issue
Block a user