upload from file and url
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from fastapi import APIRouter, Depends, HTTPException, File, UploadFile
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List
|
||||
import uuid
|
||||
import shutil
|
||||
|
||||
from .. import crud, models, schemas
|
||||
from ..database import get_db
|
||||
@@ -13,7 +15,7 @@ router = APIRouter(
|
||||
|
||||
@router.post("/", response_model=schemas.Celebrity, status_code=201)
|
||||
def create_celebrity(celebrity: schemas.CelebrityCreate, db: Session = Depends(get_db)):
|
||||
# Qui potresti aggiungere un check per vedere se una celebrità con lo stesso nome esiste già
|
||||
# Qui potresti aggiungere un check per vedere se una celebrità con lo stesso nome esiste già
|
||||
return crud.create_celebrity(db=db, celebrity=celebrity)
|
||||
|
||||
@router.get("/", response_model=List[schemas.Celebrity])
|
||||
@@ -40,4 +42,80 @@ def delete_celebrity(celebrity_id: int, db: Session = Depends(get_db)):
|
||||
db_celebrity = crud.delete_celebrity(db, celebrity_id=celebrity_id)
|
||||
if db_celebrity is None:
|
||||
raise HTTPException(status_code=404, detail="Celebrity not found")
|
||||
return db_celebrity
|
||||
return db_celebrity
|
||||
|
||||
# --- NUOVI ENDPOINT PER LE IMMAGINI ---
|
||||
|
||||
@router.post("/{celebrity_id}/images", response_model=schemas.Image, status_code=201)
|
||||
def upload_celebrity_image(celebrity_id: int, file: UploadFile = File(...), db: Session = Depends(get_db)):
|
||||
db_celebrity = crud.get_celebrity(db, celebrity_id=celebrity_id)
|
||||
if db_celebrity is None:
|
||||
raise HTTPException(status_code=404, detail="Celebrity not found")
|
||||
|
||||
file_extension = file.filename.split('.')[-1]
|
||||
unique_filename = f"{uuid.uuid4()}.{file_extension}"
|
||||
file_location = f"uploads/{unique_filename}"
|
||||
|
||||
with open(file_location, "wb+") as file_object:
|
||||
shutil.copyfileobj(file.file, file_object)
|
||||
|
||||
return crud.create_celebrity_image(db=db, celebrity_id=celebrity_id, file_path=unique_filename)
|
||||
|
||||
@router.post("/{celebrity_id}/images/from-url", response_model=schemas.Image, status_code=201)
|
||||
async def add_image_from_url(celebrity_id: int, request: schemas.ImageUrlRequest, db: Session = Depends(get_db)):
|
||||
db_celebrity = crud.get_celebrity(db, celebrity_id=celebrity_id)
|
||||
if not db_celebrity:
|
||||
raise HTTPException(status_code=404, detail="Celebrity not found")
|
||||
|
||||
url = str(request.url)
|
||||
try:
|
||||
async with httpx.AsyncClient() as client:
|
||||
# Eseguiamo prima una richiesta HEAD per controllare il tipo e la dimensione
|
||||
head_response = await client.head(url, follow_redirects=True, timeout=10)
|
||||
head_response.raise_for_status()
|
||||
|
||||
content_type = head_response.headers.get('content-type')
|
||||
if not content_type or not content_type.startswith('image/'):
|
||||
raise HTTPException(status_code=400, detail="URL does not point to a valid image.")
|
||||
|
||||
# Limite di dimensione (es. 10MB)
|
||||
content_length = int(head_response.headers.get('content-length', 0))
|
||||
if content_length > 10 * 1024 * 1024:
|
||||
raise HTTPException(status_code=400, detail="Image size exceeds 10MB limit.")
|
||||
|
||||
# Scarica l'immagine
|
||||
get_response = await client.get(url, follow_redirects=True, timeout=30)
|
||||
get_response.raise_for_status()
|
||||
|
||||
# Determina l'estensione del file
|
||||
file_extension = content_type.split('/')[-1]
|
||||
if file_extension == 'jpeg': file_extension = 'jpg'
|
||||
|
||||
unique_filename = f"{uuid.uuid4()}.{file_extension}"
|
||||
file_location = f"uploads/{unique_filename}"
|
||||
|
||||
with open(file_location, "wb") as file_object:
|
||||
file_object.write(get_response.content)
|
||||
|
||||
return crud.create_celebrity_image(db=db, celebrity_id=celebrity_id, file_path=unique_filename)
|
||||
|
||||
except httpx.RequestError as exc:
|
||||
raise HTTPException(status_code=400, detail=f"Failed to fetch image from URL: {exc}")
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"An internal error occurred: {e}")
|
||||
|
||||
@router.put("/{celebrity_id}/profile-image", response_model=schemas.Celebrity)
|
||||
def set_celebrity_profile_image(celebrity_id: int, request: schemas.SetProfileImageRequest, db: Session = Depends(get_db)):
|
||||
updated_celebrity = crud.set_profile_image(db, celebrity_id=celebrity_id, image_id=request.image_id)
|
||||
if updated_celebrity is None:
|
||||
raise HTTPException(status_code=404, detail="Celebrity or Image not found, or image does not belong to celebrity.")
|
||||
return updated_celebrity
|
||||
|
||||
# NOTA: Un approccio pi├╣ RESTful sarebbe /api/images/{image_id} in un router dedicato.
|
||||
# Per semplicità, lo inseriamo qui.
|
||||
@router.delete("/images/{image_id}", response_model=schemas.Image)
|
||||
def delete_image(image_id: int, db: Session = Depends(get_db)):
|
||||
db_image = crud.delete_image(db, image_id=image_id)
|
||||
if db_image is None:
|
||||
raise HTTPException(status_code=404, detail="Image not found")
|
||||
return db_image
|
||||
Reference in New Issue
Block a user