# app/api/v1/vendor/marketplace.py """ Marketplace import endpoints for vendors. Vendor Context: Uses token_vendor_id from JWT token (authenticated vendor API pattern). The get_current_vendor_api dependency guarantees token_vendor_id is present. """ import logging from fastapi import APIRouter, BackgroundTasks, Depends, Query from sqlalchemy.orm import Session from app.api.deps import get_current_vendor_api from app.core.database import get_db from app.services.marketplace_import_job_service import marketplace_import_job_service from app.services.vendor_service import vendor_service from app.tasks.background_tasks import process_marketplace_import from middleware.decorators import rate_limit from models.database.user import User from models.schema.marketplace_import_job import ( MarketplaceImportJobRequest, MarketplaceImportJobResponse, ) router = APIRouter(prefix="/marketplace") logger = logging.getLogger(__name__) @router.post("/import", response_model=MarketplaceImportJobResponse) @rate_limit(max_requests=10, window_seconds=3600) async def import_products_from_marketplace( request: MarketplaceImportJobRequest, background_tasks: BackgroundTasks, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """Import products from marketplace CSV with background processing (Protected). The `language` parameter specifies the language code for product translations (e.g., 'en', 'fr', 'de'). Default is 'en'. For multi-language imports, call this endpoint multiple times with different language codes and CSV files containing translations. """ vendor = vendor_service.get_vendor_by_id(db, current_user.token_vendor_id) logger.info( f"Starting marketplace import: {request.marketplace} for vendor {vendor.vendor_code} " f"by user {current_user.username} (language={request.language})" ) # Create import job (vendor comes from token) import_job = marketplace_import_job_service.create_import_job( db, request, vendor, current_user ) db.commit() # Process in background with language parameter background_tasks.add_task( process_marketplace_import, import_job.id, request.source_url, request.marketplace, vendor.id, request.batch_size or 1000, request.language, # Pass language to background task ) return MarketplaceImportJobResponse( job_id=import_job.id, status="pending", marketplace=request.marketplace, vendor_id=import_job.vendor_id, vendor_code=vendor.vendor_code, vendor_name=vendor.name, source_url=request.source_url, language=request.language, message=f"Marketplace import started from {request.marketplace}. " f"Check status with /import-status/{import_job.id}", imported=0, updated=0, total_processed=0, error_count=0, created_at=import_job.created_at, ) @router.get("/imports/{job_id}", response_model=MarketplaceImportJobResponse) def get_marketplace_import_status( job_id: int, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """Get status of marketplace import job (Protected).""" # Service validates that job belongs to vendor and raises UnauthorizedVendorAccessException if not job = marketplace_import_job_service.get_import_job_for_vendor( db, job_id, current_user.token_vendor_id ) return marketplace_import_job_service.convert_to_response_model(job) @router.get("/imports", response_model=list[MarketplaceImportJobResponse]) def get_marketplace_import_jobs( marketplace: str | None = Query(None, description="Filter by marketplace"), skip: int = Query(0, ge=0), limit: int = Query(50, ge=1, le=100), current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """Get marketplace import jobs for current vendor (Protected).""" vendor = vendor_service.get_vendor_by_id(db, current_user.token_vendor_id) jobs = marketplace_import_job_service.get_import_jobs( db=db, vendor=vendor, user=current_user, marketplace=marketplace, skip=skip, limit=limit, ) return [ marketplace_import_job_service.convert_to_response_model(job) for job in jobs ]