matsuap's picture
Upload folder using huggingface_hub
ed7ee89 verified
from fastapi import APIRouter, Depends, HTTPException, status, Response, BackgroundTasks
from sqlalchemy.orm import Session
from typing import List, Optional
import logging
from datetime import datetime
from core.database import get_db, SessionLocal
from models import db_models
from models.schemas import CanvasCreateRequest, CanvasEditRequest, CanvasResponse
from services.canvas_service import canvas_service
from api.auth import get_current_user
from api.websocket_routes import manager
router = APIRouter(prefix="/api/canvas", tags=["Canvas - Collaborative Editing"])
logger = logging.getLogger(__name__)
async def run_canvas_generation(canvas_id: int, request: CanvasCreateRequest, user_id: int):
"""Background task for canvas summary generation"""
db = SessionLocal()
connection_id = f"user_{user_id}"
try:
db_canvas = db.query(db_models.Canvas).filter(db_models.Canvas.id == canvas_id).first()
if not db_canvas: return
# Call AI service
content = await canvas_service.generate_canvas_summary(
file_key=request.file_key,
text_input=request.text_input
)
if not content:
raise Exception("AI failed to generate canvas content")
db_canvas.text = content
db_canvas.status = "completed"
db.commit()
# Notify via WebSocket
await manager.send_result(connection_id, {
"type": "canvas",
"id": db_canvas.id,
"status": "completed",
"title": db_canvas.title
})
except Exception as e:
logger.error(f"Background canvas generation failed: {e}")
db_canvas = db.query(db_models.Canvas).filter(db_models.Canvas.id == canvas_id).first()
if db_canvas:
db_canvas.status = "failed"
db_canvas.error_message = str(e)
db.commit()
await manager.send_error(connection_id, f"Canvas generation failed: {str(e)}")
finally:
db.close()
@router.post("/create", response_model=CanvasResponse)
async def create_canvas(
request: CanvasCreateRequest,
background_tasks: BackgroundTasks,
current_user: db_models.User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""
Initiates Canvas creation in the background.
"""
source_id = None
if request.file_key:
source = db.query(db_models.Source).filter(
db_models.Source.s3_key == request.file_key,
db_models.Source.user_id == current_user.id
).first()
if not source:
raise HTTPException(status_code=403, detail="Not authorized to access this file")
source_id = source.id
# Create initial record
file_base = request.file_key.split('/')[-1].rsplit('.', 1)[0] if request.file_key else None
# Priority: 1. File-based name, 2. User Title (if not default 'string'), 3. Default timestamp
if file_base:
title = f"Canvas-{file_base}"
elif request.title and request.title != "string":
title = request.title
else:
title = f"Canvas {datetime.now().strftime('%Y-%m-%d %H:%M')}"
db_canvas = db_models.Canvas(
title=title,
user_id=current_user.id,
source_id=source_id,
status="processing"
)
db.add(db_canvas)
db.commit()
db.refresh(db_canvas)
# Offload to background task
background_tasks.add_task(run_canvas_generation, db_canvas.id, request, current_user.id)
return db_canvas
@router.get("/", response_model=List[CanvasResponse])
async def list_canvases(
current_user: db_models.User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""List all canvases for the current user."""
return db.query(db_models.Canvas).filter(db_models.Canvas.user_id == current_user.id).all()
@router.get("/{canvas_id}", response_model=CanvasResponse)
async def get_canvas(
canvas_id: int,
current_user: db_models.User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""Get a specific canvas by ID."""
canvas = db.query(db_models.Canvas).filter(
db_models.Canvas.id == canvas_id,
db_models.Canvas.user_id == current_user.id
).first()
if not canvas:
raise HTTPException(status_code=404, detail="Canvas not found")
return canvas
@router.put("/{canvas_id}", response_model=CanvasResponse)
async def update_canvas_text(
canvas_id: int,
request: CanvasEditRequest,
current_user: db_models.User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""
Manually update the text of an existing canvas.
"""
db_canvas = db.query(db_models.Canvas).filter(
db_models.Canvas.id == canvas_id,
db_models.Canvas.user_id == current_user.id
).first()
if not db_canvas:
raise HTTPException(status_code=404, detail="Canvas not found")
try:
db_canvas.text = request.text
db_canvas.status = "completed"
db.commit()
db.refresh(db_canvas)
return db_canvas
except Exception as e:
logger.error(f"Error updating canvas: {e}")
raise HTTPException(status_code=500, detail=str(e))
@router.delete("/{canvas_id}")
async def delete_canvas(
canvas_id: int,
current_user: db_models.User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""Delete a canvas."""
db_canvas = db.query(db_models.Canvas).filter(
db_models.Canvas.id == canvas_id,
db_models.Canvas.user_id == current_user.id
).first()
if not db_canvas:
raise HTTPException(status_code=404, detail="Canvas not found")
db.delete(db_canvas)
db.commit()
return {"message": "Canvas deleted successfully"}