solventum-image-metadata/backend/app/api/templates.py
SamoilenkoVadym 563d476a94 feat(backend): migrate from Flask to FastAPI with Redis sessions
- Create FastAPI application with async I/O
- Implement Redis session storage (fixes session loss on restart)
- Add JWT authentication with refresh tokens
- Add Microsoft SSO support via MSAL
- Copy all processors from src/ (100% reused, no changes)
- Create file upload/download endpoints
- Create metadata update endpoints
- Create template CRUD endpoints
- Add SQLAlchemy async database models
- Add Docker Compose configuration with Redis

Solves critical issues:
- Session management: Redis replaces in-memory dicts
- Scalability: Async FastAPI + microservices architecture
- File handling: Persistent storage with auto-cleanup

Key files:
- backend/app/main.py - FastAPI entry point
- backend/app/core/redis_client.py - Session store
- backend/app/core/auth.py - JWT authentication
- backend/app/api/* - All REST endpoints
- backend/app/processors/ - Reused from src/

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-09 13:14:37 +00:00

124 lines
3.7 KiB
Python

"""
Templates API Endpoints
Handles template CRUD operations and application.
"""
from fastapi import APIRouter, Depends, HTTPException, Request, status
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from app.core.auth import get_current_user_id
from app.core.database import get_db, AuditLogRepository
from app.services.metadata_service import get_metadata_service, MetadataService
from app.models.file import (
TemplateCreate,
TemplateResponse,
TemplateApply,
TemplatePreview
)
router = APIRouter()
@router.get("/", response_model=List[TemplateResponse])
async def list_templates(
metadata_service: MetadataService = Depends(get_metadata_service),
user_id: int = Depends(get_current_user_id)
):
"""List all available templates."""
templates = metadata_service.template_manager.list_templates()
return [TemplateResponse(**template) for template in templates]
@router.post("/", status_code=status.HTTP_201_CREATED)
async def create_template(
template_data: TemplateCreate,
db: AsyncSession = Depends(get_db),
metadata_service: MetadataService = Depends(get_metadata_service),
user_id: int = Depends(get_current_user_id)
):
"""Create a new template."""
template = {
"name": template_data.name,
"title": template_data.title,
"subject": template_data.subject,
"keywords": template_data.keywords,
"description": template_data.description
}
metadata_service.template_manager.save_template(template)
await AuditLogRepository.log_action(
db,
user_id=user_id,
action="template_create",
details=f"Created template: {template_data.name}"
)
return {"success": True, "message": "Template created", "template": template}
@router.get("/{template_name}", response_model=TemplateResponse)
async def get_template(
template_name: str,
metadata_service: MetadataService = Depends(get_metadata_service),
user_id: int = Depends(get_current_user_id)
):
"""Get template by name."""
template = metadata_service.template_manager.load_template(template_name)
if not template:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Template '{template_name}' not found"
)
return TemplateResponse(**template)
@router.delete("/{template_name}")
async def delete_template(
template_name: str,
db: AsyncSession = Depends(get_db),
metadata_service: MetadataService = Depends(get_metadata_service),
user_id: int = Depends(get_current_user_id)
):
"""Delete template."""
success = metadata_service.template_manager.delete_template(template_name)
if not success:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Template '{template_name}' not found"
)
await AuditLogRepository.log_action(
db,
user_id=user_id,
action="template_delete",
details=f"Deleted template: {template_name}"
)
return {"success": True, "message": "Template deleted"}
@router.post("/preview")
async def preview_template(
preview_data: TemplatePreview,
metadata_service: MetadataService = Depends(get_metadata_service),
user_id: int = Depends(get_current_user_id)
):
"""Preview template output."""
template = {
"title": preview_data.title,
"subject": preview_data.subject,
"keywords": preview_data.keywords
}
result = metadata_service.template_manager.apply_template(
template=template,
filename=preview_data.sample_filename,
user="user",
custom_vars=preview_data.custom_vars or {}
)
return {"preview": result}