153 lines
3.6 KiB
Python
153 lines
3.6 KiB
Python
"""
|
|
Base class for POD provider integrations.
|
|
"""
|
|
|
|
from abc import ABC, abstractmethod
|
|
from pathlib import Path
|
|
from typing import Optional, Any
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass
|
|
class ProductResult:
|
|
"""Result of a product creation/update operation."""
|
|
success: bool
|
|
product_id: Optional[str] = None
|
|
error: Optional[str] = None
|
|
data: Optional[dict] = None
|
|
|
|
|
|
@dataclass
|
|
class MockupResult:
|
|
"""Result of a mockup generation operation."""
|
|
success: bool
|
|
image_url: Optional[str] = None
|
|
local_path: Optional[Path] = None
|
|
error: Optional[str] = None
|
|
|
|
|
|
class PODProvider(ABC):
|
|
"""Abstract base class for print-on-demand providers."""
|
|
|
|
name: str = "base"
|
|
|
|
def __init__(self, api_key: str, sandbox: bool = False) -> None:
|
|
self.api_key = api_key
|
|
self.sandbox = sandbox
|
|
self._validate_credentials()
|
|
|
|
@abstractmethod
|
|
def _validate_credentials(self) -> None:
|
|
"""Validate API credentials."""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def create_product(
|
|
self,
|
|
design_path: Path,
|
|
metadata: dict,
|
|
product_config: dict,
|
|
) -> ProductResult:
|
|
"""
|
|
Create a new product on the POD service.
|
|
|
|
Args:
|
|
design_path: Path to the design file (PNG)
|
|
metadata: Design metadata from metadata.yaml
|
|
product_config: Product configuration from products.yaml
|
|
|
|
Returns:
|
|
ProductResult with product_id if successful
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def update_product(
|
|
self,
|
|
product_id: str,
|
|
design_path: Path,
|
|
metadata: dict,
|
|
) -> ProductResult:
|
|
"""
|
|
Update an existing product.
|
|
|
|
Args:
|
|
product_id: Provider's product ID
|
|
design_path: Path to updated design file
|
|
metadata: Updated metadata
|
|
|
|
Returns:
|
|
ProductResult indicating success/failure
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def generate_mockup(
|
|
self,
|
|
product_id: str,
|
|
variant: Optional[str] = None,
|
|
) -> MockupResult:
|
|
"""
|
|
Generate a product mockup.
|
|
|
|
Args:
|
|
product_id: Provider's product ID
|
|
variant: Optional variant (color, size) for mockup
|
|
|
|
Returns:
|
|
MockupResult with image URL or local path
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def get_product(self, product_id: str) -> Optional[dict]:
|
|
"""
|
|
Get product details from the provider.
|
|
|
|
Args:
|
|
product_id: Provider's product ID
|
|
|
|
Returns:
|
|
Product data dict or None if not found
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def list_products(self, limit: int = 100) -> list[dict]:
|
|
"""
|
|
List products from the provider.
|
|
|
|
Args:
|
|
limit: Maximum number of products to return
|
|
|
|
Returns:
|
|
List of product data dicts
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def get_catalog(self, product_type: Optional[str] = None) -> list[dict]:
|
|
"""
|
|
Get available products from provider catalog.
|
|
|
|
Args:
|
|
product_type: Optional filter by type (sticker, tshirt, etc)
|
|
|
|
Returns:
|
|
List of catalog items
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def upload_file(self, file_path: Path) -> Optional[str]:
|
|
"""
|
|
Upload a file to the provider.
|
|
|
|
Args:
|
|
file_path: Local path to file
|
|
|
|
Returns:
|
|
File URL or ID from provider, or None on failure
|
|
"""
|
|
pass
|