File size: 2,825 Bytes
d7a7993
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
"""Upload Router - Image upload to Supabase Storage."""

import uuid
from datetime import datetime
from fastapi import APIRouter, UploadFile, File, HTTPException
from pydantic import BaseModel, Field

from app.shared.integrations.supabase_client import supabase
from app.core.config import settings


router = APIRouter(prefix="/upload", tags=["Upload"])

# Supabase Storage bucket name
BUCKET_NAME = "image"

# Allowed image types
ALLOWED_TYPES = {"image/jpeg", "image/png", "image/webp", "image/gif"}
MAX_SIZE_MB = 10


class UploadResponse(BaseModel):
    """Upload response model."""
    url: str = Field(..., description="Public URL of uploaded image")
    path: str = Field(..., description="Storage path")
    size: int = Field(..., description="File size in bytes")
    content_type: str = Field(..., description="MIME type")


@router.post(
    "/image",
    response_model=UploadResponse,
    summary="Upload image to storage",
    description="""
Upload an image file to Supabase Storage.

Returns a public URL that can be used with `/chat` endpoint's `image_url` parameter.

Supported formats: JPEG, PNG, WebP, GIF
Max size: 10MB
""",
)
async def upload_image(
    file: UploadFile = File(..., description="Image file to upload"),
    user_id: str = "anonymous",
) -> UploadResponse:
    """Upload image to Supabase Storage and return public URL."""
    
    # Validate content type
    if file.content_type not in ALLOWED_TYPES:
        raise HTTPException(
            status_code=400,
            detail=f"Invalid file type. Allowed: {', '.join(ALLOWED_TYPES)}"
        )
    
    # Read file content
    content = await file.read()
    
    # Validate size
    size = len(content)
    if size > MAX_SIZE_MB * 1024 * 1024:
        raise HTTPException(
            status_code=400,
            detail=f"File too large. Max size: {MAX_SIZE_MB}MB"
        )
    
    # Generate unique filename
    ext = file.filename.split(".")[-1] if file.filename and "." in file.filename else "jpg"
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    unique_id = str(uuid.uuid4())[:8]
    filename = f"{user_id}/{timestamp}_{unique_id}.{ext}"
    
    try:
        # Upload to Supabase Storage
        result = supabase.storage.from_(BUCKET_NAME).upload(
            path=filename,
            file=content,
            file_options={"content-type": file.content_type}
        )
        
        # Get public URL
        public_url = supabase.storage.from_(BUCKET_NAME).get_public_url(filename)
        
        return UploadResponse(
            url=public_url,
            path=filename,
            size=size,
            content_type=file.content_type,
        )
        
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Upload failed: {str(e)}"
        )