From 85ab62359ae622f02f117110a919c1a906dba229 Mon Sep 17 00:00:00 2001 From: Scarriffle Date: Wed, 29 Jul 2026 12:26:43 +0200 Subject: [PATCH] Backend: Bild beim Anlegen im Hintergrund holen (Anlegen viel schneller) create_product holte ein per URL vorgeschlagenes Bild synchron waehrend des Anlegens (httpx.get) - das blockierte die Antwort um mehrere Sekunden. Der Abruf laeuft jetzt als BackgroundTask mit eigener Session nach der Antwort; das Anlegen kehrt sofort zurueck, das Bild erscheint kurz danach. Co-Authored-By: Claude Opus 4.8 --- backend/app/routers/products.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/backend/app/routers/products.py b/backend/app/routers/products.py index 03bb188..bbcabfb 100644 --- a/backend/app/routers/products.py +++ b/backend/app/routers/products.py @@ -1,9 +1,9 @@ -from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status +from fastapi import APIRouter, BackgroundTasks, Depends, File, HTTPException, UploadFile, status from fastapi.responses import Response from sqlalchemy.orm import Session, joinedload, selectinload from ..crud import product_to_out, product_tracking, products_to_out_bulk -from ..database import get_db +from ..database import SessionLocal, get_db from ..deps import get_current_user, require_admin from ..models import ( Barcode, @@ -339,9 +339,23 @@ def delete_product_image( db.commit() +def _store_product_image_bg(product_id: int, url: str) -> None: + """Bild nach dem Anlegen im Hintergrund holen (eigene Session), damit das + Anlegen nicht auf den (langsamen) Netzwerk-Abruf wartet.""" + db = SessionLocal() + try: + product = db.get(Product, product_id) + if product is not None: + images.store(db, product, url) + db.commit() + finally: + db.close() + + @router.post("", response_model=ProductOut, status_code=status.HTTP_201_CREATED) def create_product( payload: ProductCreate, + background_tasks: BackgroundTasks, db: Session = Depends(get_db), _: User = Depends(require_admin), ) -> ProductOut: @@ -388,12 +402,13 @@ def create_product( apply_field_values(db, product, payload.field_values) except FieldError as exc: raise HTTPException(status.HTTP_400_BAD_REQUEST, str(exc)) from exc - if product.image_url: - # Gleich beim Anlegen holen. Schlaegt es fehl, entsteht kein Fehler: - # Ein fehlendes Bild darf das Anlegen eines Artikels nicht verhindern. - images.store(db, product, product.image_url) db.commit() db.refresh(product) + if product.image_url: + # Bild erst NACH dem Anlegen im Hintergrund holen – der Netzwerk-Abruf + # soll das Anlegen nicht mehrere Sekunden blockieren. Schlägt er fehl, + # bleibt der Artikel trotzdem angelegt (nur ohne Bild). + background_tasks.add_task(_store_product_image_bg, product.id, product.image_url) return product_to_out(db, product)