9.0 KiB
9.0 KiB
Asset Tracking Implementation Guide
Overview
This document describes the production-ready implementation of asset tracking across all ALwrity modules. The unified Content Asset Library automatically tracks all AI-generated content (images, videos, audio, text) for easy management and organization.
Architecture
Core Components
-
Database Models (
backend/models/content_asset_models.py)ContentAsset: Main model for tracking assetsAssetCollection: Collections/albums for organizing assetsAssetType: Enum (text, image, video, audio)AssetSource: Enum (all ALwrity modules)
-
Service Layer (
backend/services/content_asset_service.py)- CRUD operations for assets
- Search, filter, pagination
- Usage tracking
-
Utility Functions
backend/utils/asset_tracker.py:save_asset_to_library()helperbackend/utils/file_storage.py: Robust file saving utilities
Implementation Status
✅ Completed Integrations
1. Story Writer (backend/api/story_writer/router.py)
- Images: Tracks all scene images with metadata
- Audio: Tracks all scene audio files with narration details
- Videos: Tracks individual scene videos and complete story videos
- Location: After generation in
/generate-images,/generate-audio,/generate-video,/generate-complete-video - Metadata: Includes prompts, scene numbers, providers, models, costs, status
2. Image Studio (backend/api/images.py)
- Image Generation: Tracks all generated images
- Image Editing: Tracks all edited images
- Location: After generation in
/api/images/generateand/api/images/edit - Features:
- Robust file saving with validation
- Atomic file writes
- Proper error handling (non-blocking)
- File serving endpoint at
/api/images/image-studio/images/{filename}
📝 Notes on Other Modules
Main Generation Services
- Text Generation (
main_text_generation.py): Returns strings, not files. If text content needs tracking, save to.txtor.mdfiles first. - Video Generation (
main_video_generation.py): Already integrated via Story Writer - Audio Generation (
main_audio_generation.py): Already integrated via Story Writer
Social Writers
- LinkedIn Writer: Generates text content (posts, articles). No file generation currently.
- Facebook Writer: Generates text content (posts, stories, reels). No file generation currently.
- Blog Writer: Generates blog content. May generate images in future.
Note: If these modules generate files in the future, follow the integration pattern below.
Integration Pattern
For Image Generation
from utils.asset_tracker import save_asset_to_library
from utils.file_storage import save_file_safely, generate_unique_filename
from sqlalchemy.orm import Session
from pathlib import Path
# After successful image generation
try:
base_dir = Path(__file__).parent.parent
output_dir = base_dir / "module_images"
image_filename = generate_unique_filename(
prefix="img_prompt",
extension=".png",
include_uuid=True
)
# Save file safely
image_path, save_error = save_file_safely(
content=result.image_bytes,
directory=output_dir,
filename=image_filename,
max_file_size=50 * 1024 * 1024 # 50MB
)
if image_path and not save_error:
image_url = f"/api/module/images/{image_path.name}"
# Track in asset library (non-blocking)
try:
asset_id = save_asset_to_library(
db=db,
user_id=user_id,
asset_type="image",
source_module="module_name",
filename=image_path.name,
file_url=image_url,
file_path=str(image_path),
file_size=len(result.image_bytes),
mime_type="image/png",
title="Image Title",
description="Image description",
prompt=prompt,
tags=["tag1", "tag2"],
provider=result.provider,
model=result.model,
metadata={"status": "completed"}
)
logger.info(f"✅ Asset saved: ID={asset_id}")
except Exception as e:
logger.error(f"Asset tracking failed: {e}", exc_info=True)
# Don't fail the request
except Exception as e:
logger.error(f"File save failed: {e}", exc_info=True)
# Continue - base64 is still available
For Video Generation
# After successful video generation
try:
asset_id = save_asset_to_library(
db=db,
user_id=user_id,
asset_type="video",
source_module="module_name",
filename=video_filename,
file_url=video_url,
file_path=str(video_path),
file_size=file_size,
mime_type="video/mp4",
title="Video Title",
description="Video description",
prompt=prompt,
tags=["video", "tag"],
provider=provider,
model=model,
cost=cost,
metadata={"duration": duration, "status": "completed"}
)
except Exception as e:
logger.error(f"Asset tracking failed: {e}", exc_info=True)
For Audio Generation
# After successful audio generation
try:
asset_id = save_asset_to_library(
db=db,
user_id=user_id,
asset_type="audio",
source_module="module_name",
filename=audio_filename,
file_url=audio_url,
file_path=str(audio_path),
file_size=file_size,
mime_type="audio/mpeg",
title="Audio Title",
description="Audio description",
prompt=text,
tags=["audio", "tag"],
provider=provider,
model=model,
cost=cost,
metadata={"status": "completed"}
)
except Exception as e:
logger.error(f"Asset tracking failed: {e}", exc_info=True)
Best Practices
1. Error Handling
- Always non-blocking: Asset tracking failures should never break the main request
- Log errors: Use
logger.error()withexc_info=Truefor debugging - Graceful degradation: Continue with base64/file response even if tracking fails
2. File Management
- Use
save_file_safely(): Handles validation, atomic writes, directory creation - Sanitize filenames: Use
sanitize_filename()to prevent path traversal - Unique filenames: Use
generate_unique_filename()with UUIDs - File size limits: Enforce reasonable limits (50MB for images, 100MB for videos)
3. Database Sessions
- Pass session explicitly: Use
db: Session = Depends(get_db)in endpoints - Handle session lifecycle: Let FastAPI manage session cleanup
- Background tasks: Get new session in background tasks
4. Metadata
- Rich metadata: Include provider, model, dimensions, cost, status
- Searchable tags: Use consistent tag naming (e.g., "image_studio", "generated")
- Status tracking: Always include
"status": "completed"in metadata
5. File URLs
- Consistent patterns: Use
/api/{module}/images/{filename}format - Serving endpoints: Create corresponding GET endpoints to serve files
- Authentication: Protect file serving endpoints with
get_current_user
File Storage Utilities
save_file_safely()
- Validates file size
- Creates directories automatically
- Atomic writes (temp file + rename)
- Returns
(file_path, error_message)tuple
sanitize_filename()
- Removes dangerous characters
- Prevents path traversal
- Limits filename length
- Handles empty filenames
generate_unique_filename()
- Creates unique filenames with UUIDs
- Sanitizes prefix
- Handles extensions properly
Testing Checklist
- Images are saved to disk correctly
- Files are accessible via serving endpoints
- Asset tracking works (check database)
- Errors don't break main requests
- File size limits are enforced
- Filenames are sanitized properly
- Metadata is complete and accurate
- Asset Library UI displays assets correctly
Future Enhancements
- Text Content Tracking: Save text content as files when needed
- Batch Operations: Track multiple assets in single transaction
- File Cleanup: Automatic cleanup of orphaned files
- Storage Backends: Support S3, GCS for production
- Thumbnail Generation: Auto-generate thumbnails for videos/images
- Compression: Compress large files before storage
Troubleshooting
Assets not appearing in library
- Check database:
SELECT * FROM content_assets WHERE user_id = '...' - Check logs for asset tracking errors
- Verify
save_asset_to_library()returns asset ID - Check file URLs are correct
File serving fails
- Verify file exists on disk
- Check serving endpoint is registered
- Verify authentication is working
- Check file permissions
Performance issues
- Use background tasks for heavy operations
- Batch database operations
- Consider async file I/O for large files
- Monitor database query performance