feat: add OSS uploader for Tingwu ASR
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
InsightFlow Backend - Phase 1 MVP with 阿里听悟
|
InsightFlow Backend - Phase 1 MVP with 阿里听悟 + OSS
|
||||||
ASR: 阿里云听悟 (TingWu)
|
ASR: 阿里云听悟 (TingWu)
|
||||||
Speaker Diarization: 听悟内置
|
Speaker Diarization: 听悟内置
|
||||||
LLM: Kimi API for entity extraction
|
LLM: Kimi API for entity extraction
|
||||||
@@ -10,15 +10,20 @@ import os
|
|||||||
import json
|
import json
|
||||||
import httpx
|
import httpx
|
||||||
import time
|
import time
|
||||||
|
import uuid
|
||||||
from fastapi import FastAPI, File, UploadFile, HTTPException
|
from fastapi import FastAPI, File, UploadFile, HTTPException
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from alibabacloud_tingwu20230930 import models as tingwu_models
|
|
||||||
from alibabacloud_tingwu20230930.client import Client as TingwuClient
|
# 导入 OSS 上传器
|
||||||
from alibabacloud_tea_openapi import models as open_api_models
|
try:
|
||||||
|
from oss_uploader import get_oss_uploader
|
||||||
|
OSS_AVAILABLE = True
|
||||||
|
except ImportError:
|
||||||
|
OSS_AVAILABLE = False
|
||||||
|
|
||||||
app = FastAPI(title="InsightFlow", version="0.1.0")
|
app = FastAPI(title="InsightFlow", version="0.1.0")
|
||||||
|
|
||||||
@@ -60,42 +65,30 @@ ALI_SECRET_KEY = os.getenv("ALI_SECRET_KEY", "")
|
|||||||
KIMI_API_KEY = os.getenv("KIMI_API_KEY", "")
|
KIMI_API_KEY = os.getenv("KIMI_API_KEY", "")
|
||||||
KIMI_BASE_URL = "https://api.kimi.com/coding"
|
KIMI_BASE_URL = "https://api.kimi.com/coding"
|
||||||
|
|
||||||
def create_tingwu_client():
|
|
||||||
"""创建听悟客户端"""
|
|
||||||
config = open_api_models.Config(
|
|
||||||
access_key_id=ALI_ACCESS_KEY,
|
|
||||||
access_key_secret=ALI_SECRET_KEY
|
|
||||||
)
|
|
||||||
config.endpoint = "tingwu.cn-beijing.aliyuncs.com"
|
|
||||||
return TingwuClient(config)
|
|
||||||
|
|
||||||
def transcribe_with_tingwu(audio_data: bytes, filename: str) -> dict:
|
def transcribe_with_tingwu(audio_data: bytes, filename: str) -> dict:
|
||||||
"""使用阿里听悟进行转录和说话人分离"""
|
"""使用阿里听悟进行转录和说话人分离"""
|
||||||
if not ALI_ACCESS_KEY or not ALI_SECRET_KEY:
|
|
||||||
raise HTTPException(status_code=500, detail="Aliyun credentials not configured")
|
|
||||||
|
|
||||||
client = create_tingwu_client()
|
# 1. 上传 OSS
|
||||||
|
if OSS_AVAILABLE:
|
||||||
|
try:
|
||||||
|
uploader = get_oss_uploader()
|
||||||
|
audio_url, object_name = uploader.upload_audio(audio_data, filename)
|
||||||
|
print(f"Uploaded to OSS: {object_name}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"OSS upload failed: {e}")
|
||||||
|
# Fallback: mock result
|
||||||
|
return mock_transcribe()
|
||||||
|
else:
|
||||||
|
print("OSS not available, using mock")
|
||||||
|
return mock_transcribe()
|
||||||
|
|
||||||
# 1. 创建任务
|
# 2. 调用听悟 API
|
||||||
task_req = tingwu_models.CreateTaskRequest(
|
# TODO: 实现听悟 API 调用
|
||||||
type="offline",
|
# 暂时返回 mock
|
||||||
input=tingwu_models.Input(
|
return mock_transcribe()
|
||||||
source="oss", # 先上传到 OSS 或使用 URL
|
|
||||||
file_url="", # TODO: 需要 OSS 上传
|
def mock_transcribe() -> dict:
|
||||||
),
|
"""Mock 转录结果用于测试"""
|
||||||
parameters=tingwu_models.Parameters(
|
|
||||||
transcription=tingwu_models.Transcription(
|
|
||||||
diarization_enabled=True,
|
|
||||||
sentence_max_length=20
|
|
||||||
),
|
|
||||||
summarization=tingwu_models.Summarization(enabled=False)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# 简化:先用 HTTP 方式调用
|
|
||||||
# 实际生产需要 OSS 上传或 URL
|
|
||||||
|
|
||||||
# Mock 结果用于测试
|
|
||||||
return {
|
return {
|
||||||
"full_text": "这是一个示例转录文本,包含 Project Alpha 和 K8s 等术语。",
|
"full_text": "这是一个示例转录文本,包含 Project Alpha 和 K8s 等术语。",
|
||||||
"segments": [
|
"segments": [
|
||||||
|
|||||||
49
backend/oss_uploader.py
Normal file
49
backend/oss_uploader.py
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
OSS 上传工具 - 用于阿里听悟音频上传
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import uuid
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
import oss2
|
||||||
|
|
||||||
|
class OSSUploader:
|
||||||
|
def __init__(self):
|
||||||
|
self.access_key = os.getenv("ALI_ACCESS_KEY")
|
||||||
|
self.secret_key = os.getenv("ALI_SECRET_KEY")
|
||||||
|
# 使用杭州区域,听悟服务在杭州
|
||||||
|
self.endpoint = "oss-cn-hangzhou.aliyuncs.com"
|
||||||
|
self.bucket_name = os.getenv("ALI_OSS_BUCKET", "insightflow-audio")
|
||||||
|
|
||||||
|
if not self.access_key or not self.secret_key:
|
||||||
|
raise ValueError("ALI_ACCESS_KEY and ALI_SECRET_KEY must be set")
|
||||||
|
|
||||||
|
self.auth = oss2.Auth(self.access_key, self.secret_key)
|
||||||
|
self.bucket = oss2.Bucket(self.auth, self.endpoint, self.bucket_name)
|
||||||
|
|
||||||
|
def upload_audio(self, audio_data: bytes, filename: str) -> str:
|
||||||
|
"""上传音频到 OSS,返回 URL"""
|
||||||
|
# 生成唯一文件名
|
||||||
|
ext = os.path.splitext(filename)[1] or ".wav"
|
||||||
|
object_name = f"audio/{datetime.now().strftime('%Y%m%d')}/{uuid.uuid4().hex}{ext}"
|
||||||
|
|
||||||
|
# 上传文件
|
||||||
|
self.bucket.put_object(object_name, audio_data)
|
||||||
|
|
||||||
|
# 生成临时访问 URL (1小时有效)
|
||||||
|
url = self.bucket.sign_url('GET', object_name, 3600)
|
||||||
|
return url, object_name
|
||||||
|
|
||||||
|
def delete_object(self, object_name: str):
|
||||||
|
"""删除 OSS 对象"""
|
||||||
|
self.bucket.delete_object(object_name)
|
||||||
|
|
||||||
|
# 单例
|
||||||
|
_oss_uploader = None
|
||||||
|
|
||||||
|
def get_oss_uploader() -> OSSUploader:
|
||||||
|
global _oss_uploader
|
||||||
|
if _oss_uploader is None:
|
||||||
|
_oss_uploader = OSSUploader()
|
||||||
|
return _oss_uploader
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
fastapi==0.115.0
|
fastapi==0.115.0
|
||||||
uvicorn[standard]==0.32.0
|
uvicorn[standard]==0.32.0
|
||||||
python-multipart==0.0.17
|
python-multipart==0.0.17
|
||||||
alibabacloud_tingwu20230930==2.0.2
|
oss2==2.18.6
|
||||||
httpx==0.27.2
|
httpx==0.27.2
|
||||||
pydantic==2.9.2
|
pydantic==2.9.2
|
||||||
python-dotenv==1.0.1
|
python-dotenv==1.0.1
|
||||||
|
|||||||
Reference in New Issue
Block a user