ChandimaPrabath commited on
Commit
c620425
·
verified ·
1 Parent(s): 043f279

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -0
app.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException, Response
2
+ from pydantic import BaseModel
3
+ import requests
4
+ import base64
5
+ import os
6
+
7
+ app = FastAPI(title="OpenAI‑Compatible TTS Adapter")
8
+
9
+ class OpenAITTSRequest(BaseModel):
10
+ model: str # e.g. "tts-1"
11
+ input: str # the text prompt
12
+ voice: str = "tara" # optional voice parameter
13
+ format: str = "wav" # "wav" or "mp3"
14
+
15
+ @app.post(
16
+ "/v1/audio/speech",
17
+ summary="Generate speech",
18
+ response_class=Response, # raw bytes
19
+ )
20
+ def tts_speech(req: OpenAITTSRequest):
21
+ # Load your Chutes token
22
+ chutes_token = os.getenv("CHUTES_API_TOKEN")
23
+ if not chutes_token:
24
+ raise HTTPException(status_code=500, detail="Chutes API token not configured")
25
+
26
+ # Call Chutes TTS
27
+ resp = requests.post(
28
+ "https://chutes-orpheus-tts.chutes.ai/speak",
29
+ headers={
30
+ "Authorization": f"Bearer {chutes_token}",
31
+ "Content-Type": "application/json"
32
+ },
33
+ json={"voice": req.voice, "prompt": req.input},
34
+ timeout=30
35
+ )
36
+
37
+ if resp.status_code != 200:
38
+ raise HTTPException(
39
+ status_code=502,
40
+ detail=f"Chutes TTS error: {resp.status_code} {resp.text}"
41
+ )
42
+
43
+ # If Chutes returns JSON-wrapped base64, extract and decode
44
+ content_type = f"audio/{req.format}"
45
+ try:
46
+ segments = resp.json()
47
+ for seg in segments:
48
+ if seg.get("type") == "audio" and seg.get("data"):
49
+ # data:audio/wav;base64,AAAA...
50
+ prefix, b64 = seg["data"].split(",", 1)
51
+ audio_bytes = base64.b64decode(b64)
52
+ return Response(content=audio_bytes, media_type=content_type)
53
+ except ValueError:
54
+ # Not JSON — assume raw bytes
55
+ return Response(content=resp.content, media_type=content_type)
56
+
57
+ raise HTTPException(status_code=502, detail="No audio in Chutes response")
58
+
59
+ @app.get("/healthz")
60
+ def health_check():
61
+ return {"status": "ok"}