feat: initial Flask REST API implementation for TTS + Voice Conversion

This commit is contained in:
root
2026-04-08 01:35:34 +02:00
commit 879f770927
17 changed files with 837 additions and 0 deletions

4
app/models/__init__.py Normal file
View File

@@ -0,0 +1,4 @@
"""Models package."""
from app.models.voice import Voice
__all__ = ['Voice']

73
app/models/voice.py Normal file
View File

@@ -0,0 +1,73 @@
"""Voice model for reference voice metadata."""
import os
import json
from datetime import datetime
from typing import List, Optional, Dict, Any
class Voice:
"""Represents a reference voice."""
def __init__(self, voice_id: str, name: str, filename: str, created_at: str = None):
self.id = voice_id
self.name = name
self.filename = filename
self.created_at = created_at or datetime.now().isoformat()
def to_dict(self) -> Dict[str, Any]:
"""Convert to dictionary."""
return {
'id': self.id,
'name': self.name,
'filename': self.filename,
'created_at': self.created_at
}
@classmethod
def from_file(cls, voice_id: str, voices_dir: str) -> Optional['Voice']:
"""Load voice metadata from JSON file."""
meta_path = os.path.join(voices_dir, f"{voice_id}.json")
if not os.path.exists(meta_path):
return None
with open(meta_path, 'r') as f:
data = json.load(f)
return cls(
voice_id=data['id'],
name=data['name'],
filename=data['filename'],
created_at=data.get('created_at')
)
def save(self, voices_dir: str):
"""Save voice metadata to JSON file."""
meta_path = os.path.join(voices_dir, f"{self.id}.json")
with open(meta_path, 'w') as f:
json.dump(self.to_dict(), f, indent=2)
def get_audio_path(self, voices_dir: str) -> str:
"""Get full path to audio file."""
return os.path.join(voices_dir, self.filename)
def exists(self, voices_dir: str) -> bool:
"""Check if voice files exist."""
audio_path = self.get_audio_path(voices_dir)
meta_path = os.path.join(voices_dir, f"{self.id}.json")
return os.path.exists(audio_path) and os.path.exists(meta_path)
@classmethod
def list_all(cls, voices_dir: str) -> List['Voice']:
"""List all voices in directory."""
voices = []
if not os.path.exists(voices_dir):
return voices
for filename in os.listdir(voices_dir):
if filename.endswith('.json'):
voice_id = filename[:-5] # Remove .json
voice = cls.from_file(voice_id, voices_dir)
if voice and voice.exists(voices_dir):
voices.append(voice)
return sorted(voices, key=lambda v: v.created_at, reverse=True)