updated skeleton with true data

This commit is contained in:
2025-12-09 08:40:18 +01:00
parent 61e6644158
commit 8cd91b6f22
27 changed files with 1193 additions and 14 deletions

View File

@ -1 +1,11 @@
FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.gateway.txt .
RUN pip install -r requirements.gateway.txt
COPY . .
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /usr/local /usr/local
COPY . .
CMD ["python","main.py"]

7
gateway/api/health.py Normal file
View File

@ -0,0 +1,7 @@
from fastapi import APIRouter
router = APIRouter()
@router.get("/")
async def health():
return {"status": "ok"}

View File

@ -0,0 +1,19 @@
from fastapi import APIRouter, Response
from pydantic import BaseModel
from core.queue_client import push_job, await_result
router = APIRouter()
class SpeechRequest(BaseModel):
model: str
input: str
voice: str = "auto"
format: str = "wav"
voice_sample_url: str | None = None
voice_sample_base64: str | None = None
@router.post("/speech")
async def speech(req: SpeechRequest):
job_id = push_job(req.dict())
audio_bytes, mime = await_result(job_id)
return Response(content=audio_bytes, media_type=mime)

21
gateway/api/voices.py Normal file
View File

@ -0,0 +1,21 @@
from fastapi import APIRouter
import json
from pathlib import Path
router = APIRouter()
REG = Path("voices/registry.json")
@router.post("/register")
async def register(data: dict):
reg = {}
if REG.exists():
reg = json.loads(REG.read_text())
reg[data["name"]] = data
REG.write_text(json.dumps(reg, indent=2))
return {"status": "ok", "voices": list(reg.keys())}
@router.get("/list")
async def list_voices():
if not REG.exists():
return []
return json.loads(REG.read_text())

1
gateway/core/cache.py Normal file
View File

@ -0,0 +1 @@
# optional cache placeholder

1
gateway/core/config.py Normal file
View File

@ -0,0 +1 @@
REDIS_HOST='redis'

View File

@ -0,0 +1 @@
# logging config placeholder

1
gateway/core/models.py Normal file
View File

@ -0,0 +1 @@
# pydantic models placeholder

View File

@ -0,0 +1,25 @@
import redis, uuid, json, time, os
REDIS_HOST = os.environ.get("REDIS_HOST", "redis")
r = redis.Redis(host=REDIS_HOST, port=6379, db=0)
QUEUE="tts_queue"
RESULT="tts_result"
def push_job(data: dict) -> str:
job_id = str(uuid.uuid4())
data["job_id"] = job_id
r.lpush(QUEUE, json.dumps(data))
return job_id
def await_result(job_id: str, timeout=30):
key = f"{RESULT}:{job_id}"
start=time.time()
while time.time()-start < timeout:
data=r.get(key)
if data:
r.delete(key)
obj=json.loads(data)
return bytes.fromhex(obj["audio"]), obj["mime"]
time.sleep(0.1)
raise TimeoutError("Worker antwortet nicht")

View File

@ -1 +1,42 @@
print('gateway start')
import socket, uvicorn, os
from fastapi import FastAPI
from api.openai_speech import router as speech_router
from api.voices import router as voice_router
from api.health import router as health_router
from pathlib import Path
app = FastAPI(title="XTTS2 Gateway")
app.include_router(speech_router, prefix="/v1/audio")
app.include_router(voice_router, prefix="/v1/voices")
app.include_router(health_router, prefix="/health")
PORT_FILE = Path("port.txt")
def find_free_port(start=8000, end=8100):
for port in range(start, end+1):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
try:
s.bind(("0.0.0.0", port))
return port
except:
pass
raise RuntimeError("No free port")
def start():
env_port = os.environ.get("GATEWAY_PORT")
port = int(env_port) if env_port else 8000
# check
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
try:
s.bind(("0.0.0.0", port))
except:
port = find_free_port()
PORT_FILE.write_text(str(port))
uvicorn.run(app, host="0.0.0.0", port=port)
if __name__ == "__main__":
start()

View File

@ -1 +1,5 @@
fastapi
uvicorn
redis
pydantic
requests

View File

@ -0,0 +1 @@
{}