feat: polish generation demo workflow
This commit is contained in:
@@ -38,10 +38,22 @@ from app.services.story_status import StoryAssetStatus, sync_story_status
|
||||
logger = get_logger(__name__)
|
||||
router = APIRouter()
|
||||
|
||||
RATE_LIMIT_WINDOW = 60 # seconds
|
||||
RATE_LIMIT_WINDOW = 60 # seconds
|
||||
RATE_LIMIT_REQUESTS = 10
|
||||
|
||||
|
||||
def _legacy_generation_headers(successor: str) -> dict[str, str]:
|
||||
return {
|
||||
"Deprecation": "true",
|
||||
"Link": f"<{successor}>; rel=\"successor-version\"",
|
||||
"X-DreamWeaver-Successor-Endpoint": successor,
|
||||
}
|
||||
|
||||
|
||||
def _mark_legacy_generation_endpoint(response: Response, successor: str) -> None:
|
||||
response.headers.update(_legacy_generation_headers(successor))
|
||||
|
||||
|
||||
@router.post("/generations", response_model=GenerationResponse)
|
||||
async def create_generation(
|
||||
request: GenerationRequest,
|
||||
@@ -77,23 +89,27 @@ async def retry_generation_assets(
|
||||
@router.post("/stories/generate", response_model=StoryResponse)
|
||||
async def generate_story(
|
||||
request: GenerateRequest,
|
||||
response: Response,
|
||||
user: User = Depends(require_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""Generate or enhance a story."""
|
||||
await check_rate_limit(f"story:{user.id}", RATE_LIMIT_REQUESTS, RATE_LIMIT_WINDOW)
|
||||
return await story_service.generate_and_save_story(request, user.id, db)
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""Generate or enhance a story."""
|
||||
_mark_legacy_generation_endpoint(response, "/api/generations")
|
||||
await check_rate_limit(f"story:{user.id}", RATE_LIMIT_REQUESTS, RATE_LIMIT_WINDOW)
|
||||
return await story_service.generate_and_save_story(request, user.id, db)
|
||||
|
||||
|
||||
@router.post("/stories/generate/full", response_model=FullStoryResponse)
|
||||
async def generate_story_full(
|
||||
request: GenerateRequest,
|
||||
user: User = Depends(require_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""Generate complete story (story + parallel image/audio generation)."""
|
||||
await check_rate_limit(f"story:{user.id}", RATE_LIMIT_REQUESTS, RATE_LIMIT_WINDOW)
|
||||
return await story_service.generate_full_story_service(request, user.id, db)
|
||||
async def generate_story_full(
|
||||
request: GenerateRequest,
|
||||
response: Response,
|
||||
user: User = Depends(require_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""Generate complete story (story + parallel image/audio generation)."""
|
||||
_mark_legacy_generation_endpoint(response, "/api/generations")
|
||||
await check_rate_limit(f"story:{user.id}", RATE_LIMIT_REQUESTS, RATE_LIMIT_WINDOW)
|
||||
return await story_service.generate_full_story_service(request, user.id, db)
|
||||
|
||||
|
||||
@router.post("/stories/generate/stream")
|
||||
@@ -212,18 +228,23 @@ async def generate_story_stream(
|
||||
),
|
||||
}
|
||||
|
||||
return EventSourceResponse(event_generator())
|
||||
return EventSourceResponse(
|
||||
event_generator(),
|
||||
headers=_legacy_generation_headers("/api/generations"),
|
||||
)
|
||||
|
||||
|
||||
@router.post("/storybook/generate", response_model=StorybookResponse)
|
||||
async def generate_storybook_api(
|
||||
request: StorybookRequest,
|
||||
user: User = Depends(require_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""Generate storybook."""
|
||||
await check_rate_limit(f"story:{user.id}", RATE_LIMIT_REQUESTS, RATE_LIMIT_WINDOW)
|
||||
return await story_service.generate_storybook_service(request, user.id, db)
|
||||
async def generate_storybook_api(
|
||||
request: StorybookRequest,
|
||||
response: Response,
|
||||
user: User = Depends(require_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""Generate storybook."""
|
||||
_mark_legacy_generation_endpoint(response, "/api/generations")
|
||||
await check_rate_limit(f"story:{user.id}", RATE_LIMIT_REQUESTS, RATE_LIMIT_WINDOW)
|
||||
return await story_service.generate_storybook_service(request, user.id, db)
|
||||
|
||||
|
||||
# ==================== Missing Endpoints (Issue #5) ====================
|
||||
@@ -263,10 +284,15 @@ async def delete_story(
|
||||
@router.post("/image/generate/{story_id}", response_model=StoryImageResponse)
|
||||
async def generate_story_image(
|
||||
story_id: int,
|
||||
response: Response,
|
||||
user: User = Depends(require_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""Generate cover image for story."""
|
||||
_mark_legacy_generation_endpoint(
|
||||
response,
|
||||
f"/api/generations/{story_id}/retry-assets",
|
||||
)
|
||||
url = await story_service.generate_story_cover(story_id, user.id, db)
|
||||
story = await story_service.get_story_detail(story_id, user.id, db)
|
||||
return {
|
||||
@@ -282,10 +308,15 @@ async def generate_story_image(
|
||||
async def retry_story_assets(
|
||||
story_id: int,
|
||||
payload: StoryAssetRetryRequest,
|
||||
response: Response,
|
||||
user: User = Depends(require_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""Retry selected generated assets for a story."""
|
||||
_mark_legacy_generation_endpoint(
|
||||
response,
|
||||
f"/api/generations/{story_id}/retry-assets",
|
||||
)
|
||||
return await story_service.retry_story_assets(story_id, user.id, payload.assets, db)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user