shon98's picture
Update app.py
05f8512 verified
import os
import logging
import time
import json
from fastapi import FastAPI, Request
from fastapi.responses import StreamingResponse
from phonikud import Phonikud, phonemize # ื™ื™ื‘ื•ื ืจืฉืžื™ ืžื”ืกืคืจื™ื™ื”
from google import genai
from google.genai import types
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
app = FastAPI()
# ื˜ืขื™ื ืช ื”ืžื•ื“ืœ (ื”ืงื•ื‘ืฅ ื—ื™ื™ื‘ ืœื”ื™ื•ืช ื‘ืชื™ืงื™ื™ื” ื”ืจืืฉื™ืช ืฉืœ ื”-Space)
MODEL_PATH = "./phonikud-1.0.int8.onnx"
pk = Phonikud(MODEL_PATH) if os.path.exists(MODEL_PATH) else None
client = genai.Client(api_key=os.getenv("GEMINI_API_KEY"))
@app.post("/v1/chat/completions")
async def chat_proxy(request: Request):
try:
body = await request.json()
messages = body.get("messages", [])
# ื‘ื ื™ื™ืช ื”ื”ืงืฉืจ ืœื“ื ื™ืืœ
system_instruction = ""
contents = []
for msg in messages:
if msg["role"] == "system":
system_instruction = msg["content"]
else:
role = "user" if msg["role"] == "user" else "model"
contents.append(types.Content(role=role, parts=[types.Part(text=msg["content"])]))
# 1. ืงื‘ืœืช ืชืฉื•ื‘ื” ืž-Gemini
response = client.models.generate_content(
model='gemini-2.5-flash',
contents=contents,
config=types.GenerateContentConfig(system_instruction=system_instruction)
)
original_text = response.text or ""
logger.info(f"Gemini: {original_text}")
# 2. ื”ืคื™ื›ื” ืœืคื•ื ืžื•ืช IPA (ื”ืฉื™ื˜ื” ืžื”ืžืืžืจ)
final_output = original_text
if pk and original_text:
try:
# ื”ื•ืกืคืช ื ื™ืงื•ื“
vocalized = pk.add_diacritics(original_text)
# ื”ืžืจื” ืœืคื•ื ืžื•ืช IPA
ipa = phonemize(vocalized)
# ืขื˜ื™ืคื” ืœืงืจื˜ืกื™ื” (ื ื™ืงื•ื™ ืชื•ื•ื™ื ืžื‘ื ื™ื™ื ื‘ืžื™ื“ืช ื”ืฆื•ืจืš)
final_output = f"<<{ipa.replace('|', '')}>>"
logger.info(f"IPA for Cartesia: {final_output}")
except Exception as e:
logger.error(f"Phonemization failed: {e}")
# 3. ื”ื–ืจืžื” ื‘ืคื•ืจืžื˜ ืฉื•ื•ืืคื™ ืžื‘ื™ื ื”
def generate_vapi_stream():
chat_id = f"chatcmpl-{int(time.time())}"
chunk = {
"id": chat_id,
"object": "chat.completion.chunk",
"choices": [{
"index": 0,
"delta": {"role": "assistant", "content": final_output},
"finish_reason": "stop"
}]
}
yield f"data: {json.dumps(chunk)}\n\n"
yield "data: [DONE]\n\n"
return StreamingResponse(generate_vapi_stream(), media_type="text/event-stream")
except Exception as e:
logger.error(f"Error: {str(e)}")
return {"error": str(e)}, 500
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=7860)