mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-09-16 13:20:39 -07:00
Update dependencies and enhance project structure. Upgraded Tailwind CSS to version 4.1.0, removed obsolete configuration files, and added a comprehensive CURRENT_STATE.md file detailing project features, architecture, and future plans. Improved history management in the backend with new response models and optimized API endpoints for better data handling.
This commit is contained in:
+31
-10
@@ -10,8 +10,8 @@ from pathlib import Path
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import or_
|
||||
|
||||
from .models import GenerationRequest, GenerationResponse, HistoryQuery
|
||||
from .database import Generation as DBGeneration
|
||||
from .models import GenerationRequest, GenerationResponse, HistoryQuery, HistoryResponse, HistoryListResponse
|
||||
from .database import Generation as DBGeneration, VoiceProfile as DBVoiceProfile
|
||||
|
||||
|
||||
# Generations storage directory
|
||||
@@ -85,7 +85,7 @@ async def get_generation(
|
||||
async def list_generations(
|
||||
query: HistoryQuery,
|
||||
db: Session,
|
||||
) -> Tuple[List[GenerationResponse], int]:
|
||||
) -> HistoryListResponse:
|
||||
"""
|
||||
List generations with optional filters.
|
||||
|
||||
@@ -94,10 +94,16 @@ async def list_generations(
|
||||
db: Database session
|
||||
|
||||
Returns:
|
||||
Tuple of (generations, total_count)
|
||||
HistoryListResponse with items and total count
|
||||
"""
|
||||
# Build base query
|
||||
q = db.query(DBGeneration)
|
||||
# Build base query with join to get profile name
|
||||
q = db.query(
|
||||
DBGeneration,
|
||||
DBVoiceProfile.name.label('profile_name')
|
||||
).join(
|
||||
DBVoiceProfile,
|
||||
DBGeneration.profile_id == DBVoiceProfile.id
|
||||
)
|
||||
|
||||
# Apply profile filter
|
||||
if query.profile_id:
|
||||
@@ -118,11 +124,26 @@ async def list_generations(
|
||||
q = q.offset(query.offset).limit(query.limit)
|
||||
|
||||
# Execute query
|
||||
generations = q.all()
|
||||
results = q.all()
|
||||
|
||||
return (
|
||||
[GenerationResponse.model_validate(g) for g in generations],
|
||||
total_count,
|
||||
# Convert to HistoryResponse with profile_name
|
||||
items = []
|
||||
for generation, profile_name in results:
|
||||
items.append(HistoryResponse(
|
||||
id=generation.id,
|
||||
profile_id=generation.profile_id,
|
||||
profile_name=profile_name,
|
||||
text=generation.text,
|
||||
language=generation.language,
|
||||
audio_path=generation.audio_path,
|
||||
duration=generation.duration,
|
||||
seed=generation.seed,
|
||||
created_at=generation.created_at,
|
||||
))
|
||||
|
||||
return HistoryListResponse(
|
||||
items=items,
|
||||
total=total_count,
|
||||
)
|
||||
|
||||
|
||||
|
||||
+29
-8
@@ -18,7 +18,7 @@ from pathlib import Path
|
||||
import uuid
|
||||
|
||||
from . import database, models, profiles, history, tts, transcribe
|
||||
from .database import get_db, init_db
|
||||
from .database import get_db, init_db, Generation as DBGeneration, VoiceProfile as DBVoiceProfile
|
||||
|
||||
# Initialize database
|
||||
init_db()
|
||||
@@ -240,7 +240,7 @@ async def generate_speech(
|
||||
# HISTORY ENDPOINTS
|
||||
# ============================================
|
||||
|
||||
@app.get("/history", response_model=List[models.GenerationResponse])
|
||||
@app.get("/history", response_model=models.HistoryListResponse)
|
||||
async def list_history(
|
||||
profile_id: Optional[str] = None,
|
||||
search: Optional[str] = None,
|
||||
@@ -255,20 +255,41 @@ async def list_history(
|
||||
limit=limit,
|
||||
offset=offset,
|
||||
)
|
||||
generations, total = await history.list_generations(query, db)
|
||||
return generations
|
||||
return await history.list_generations(query, db)
|
||||
|
||||
|
||||
@app.get("/history/{generation_id}", response_model=models.GenerationResponse)
|
||||
@app.get("/history/{generation_id}", response_model=models.HistoryResponse)
|
||||
async def get_generation(
|
||||
generation_id: str,
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""Get a generation by ID."""
|
||||
generation = await history.get_generation(generation_id, db)
|
||||
if not generation:
|
||||
# Get generation with profile name
|
||||
result = db.query(
|
||||
DBGeneration,
|
||||
DBVoiceProfile.name.label('profile_name')
|
||||
).join(
|
||||
DBVoiceProfile,
|
||||
DBGeneration.profile_id == DBVoiceProfile.id
|
||||
).filter(
|
||||
DBGeneration.id == generation_id
|
||||
).first()
|
||||
|
||||
if not result:
|
||||
raise HTTPException(status_code=404, detail="Generation not found")
|
||||
return generation
|
||||
|
||||
gen, profile_name = result
|
||||
return models.HistoryResponse(
|
||||
id=gen.id,
|
||||
profile_id=gen.profile_id,
|
||||
profile_name=profile_name,
|
||||
text=gen.text,
|
||||
language=gen.language,
|
||||
audio_path=gen.audio_path,
|
||||
duration=gen.duration,
|
||||
seed=gen.seed,
|
||||
created_at=gen.created_at,
|
||||
)
|
||||
|
||||
|
||||
@app.delete("/history/{generation_id}")
|
||||
|
||||
@@ -74,6 +74,28 @@ class HistoryQuery(BaseModel):
|
||||
offset: int = Field(default=0, ge=0)
|
||||
|
||||
|
||||
class HistoryResponse(BaseModel):
|
||||
"""Response model for history entry (includes profile name)."""
|
||||
id: str
|
||||
profile_id: str
|
||||
profile_name: str
|
||||
text: str
|
||||
language: str
|
||||
audio_path: str
|
||||
duration: float
|
||||
seed: Optional[int]
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class HistoryListResponse(BaseModel):
|
||||
"""Response model for history list."""
|
||||
items: List[HistoryResponse]
|
||||
total: int
|
||||
|
||||
|
||||
class TranscriptionRequest(BaseModel):
|
||||
"""Request model for audio transcription."""
|
||||
language: Optional[str] = Field(None, pattern="^(en|zh)$")
|
||||
|
||||
Reference in New Issue
Block a user