pahvalentines/backend/app/models.py
michael 9c5b054dcc feat: Add Sonauto streaming audio on waiting page
Enable users to listen to their song while video generation continues
in the background. Backend proxies authenticated Sonauto stream API
since HTML audio elements cannot send auth headers.

- Add streaming_ready_at column to track when stream becomes available
- Enable streaming in Sonauto API request payload
- Handle GENERATING_STREAMING_READY webhook status
- Add /api/stream/{session_id} proxy endpoint using httpx
- Update StatusResponse with streaming_ready and task_id fields
- Add audio player UI with autoplay fallback for mobile
- Fade out audio gracefully before redirect to result page

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 08:23:14 -06:00

59 lines
1.7 KiB
Python

"""SQLAlchemy database models."""
from datetime import datetime
from sqlalchemy import Column, DateTime, Index, Integer, String, Text
from sqlalchemy.orm import declarative_base
Base = declarative_base()
class Submission(Base):
"""Submission model representing a user's pet song generation request."""
__tablename__ = "submissions"
# Primary key
session_id = Column(String(255), primary_key=True)
# Timestamps
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
# User identification (for rate limiting)
cookie_id = Column(String(255), index=True)
# Form data
owner_name = Column(String(100), nullable=False)
pet_name = Column(String(100), nullable=False)
pet_type = Column(String(50), nullable=False)
music_vibe = Column(String(50), nullable=False)
photo_path = Column(String(500), nullable=False)
# Processing state
retry_count = Column(Integer, default=0)
entry_status = Column(String(50), default="pending")
# Sonauto API interaction
sent_to_LLM = Column(DateTime)
LLM_task_id = Column(String(255))
received_from_LLM = Column(DateTime)
LLM_response = Column(Text)
LLM_full_response = Column(Text)
LLM_status = Column(String(50))
# Generated content
lyrics = Column(Text)
generated_song_path = Column(Text)
generated_video_path = Column(String(500))
# Streaming
streaming_ready_at = Column(DateTime)
# Video generation timestamps
video_creation_start = Column(DateTime)
video_creation_end = Column(DateTime)
__table_args__ = (Index("ix_submissions_llm_task_id", "LLM_task_id"),)
def __repr__(self) -> str:
return f"<Submission(session_id={self.session_id}, status={self.entry_status})>"