from fastapi import FastAPI, UploadFile, File, Query
from fastapi.responses import HTMLResponse
from faster_whisper import WhisperModel
import uuid
import os
app = FastAPI()
AUDIO_DIR = "audio"
os.makedirs(AUDIO_DIR, exist_ok=True)
# =========================
# STORAGE
# =========================
TOKENS = {} # token -> nickname
LAST_TEXT = {} # token -> text
# =========================
# MODEL (быстро)
# =========================
model = WhisperModel(
"medium",
device="cpu",
compute_type="int8"
)
# =========================
# LOGIN
# =========================
@app.post("/login")
async def login(data: dict):
nickname = data.get("nickname")
if not nickname:
return {"error": "no nickname"}
# если уже есть токен — вернуть его
for token, name in TOKENS.items():
if name == nickname:
return {
"token": token,
"nickname": nickname
}
# иначе создать новый
token = str(uuid.uuid4())[:10]
TOKENS[token] = nickname
LAST_TEXT[token] = ""
return {
"token": token,
"nickname": nickname
}
# =========================
# HTML
# =========================
HTML = """
Voice Chat
VOICE CHAT
"""
# =========================
# HOME
# =========================
@app.get("/", response_class=HTMLResponse)
async def home():
return HTML
# =========================
# UPLOAD (защищённый)
# =========================
@app.post("/upload")
async def upload(file: UploadFile = File(...), token: str = Query(...)):
if token not in TOKENS:
return {"error": "invalid token"}
nickname = TOKENS[token]
path = f"{AUDIO_DIR}/{uuid.uuid4()}.webm"
with open(path, "wb") as f:
f.write(await file.read())
segments, _ = model.transcribe(
path,
beam_size=1,
temperature=0,
condition_on_previous_text=False
)
text = "".join([s.text for s in segments]).strip()
# 👇 ВОТ ЭТА СТРОКА ДОЛЖНА БЫТЬ ЗДЕСЬ
LAST_TEXT[token] = text
return {
"nickname": nickname,
"token": token,
"text": text
}
# =========================
# GET LAST MESSAGE
# =========================
@app.get("/last")
async def last(token: str):
if token not in LAST_TEXT:
return {"text": "", "nickname": ""}
return {
"text": f"{TOKENS.get(token, 'unknown')}: {LAST_TEXT[token]}"
}
# =========================================
# RUN
# =========================================
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=7860)