Skip to content

Products

Products are the core of your e-commerce store. The Konigle SDK provides comprehensive support for creating and managing products with or without variants, including rich content, SEO metadata, and inventory management.

Creating a Product Without Variants

For simple products that don't have variations like size or color, you can create a basic product:

from decimal import Decimal
from konigle import Client
from konigle.models.commerce.product import ProductCreate, ProductStatus
from konigle.models import SEOMeta

# Initialize the client
client = Client(api_key="your_api_key")

# Create a simple product
product_data = ProductCreate(
    title="Premium T-Shirt",
    handle="premium-t-shirt",
    status=ProductStatus.DRAFT,
    product_type="Clothing",
    vendor="Fashion Co",
    tags="cotton,comfortable,premium",
    price=Decimal("29.99"),
    currency="USD",
    content={
        "time": 1672531200000,
        "blocks": [
            {
                "type": "paragraph",
                "data": {"text": "Premium quality cotton t-shirt."},
            }
        ],
        "version": "2.28.0",
    },
    seo_meta=SEOMeta(
        description="Premium cotton t-shirt for everyday wear",
        keywords="t-shirt, cotton, premium, clothing",
        og_title="Premium T-Shirt",
        og_description="High-quality cotton t-shirt",
    ),
)

# Create the product
product = client.products.create(product_data)

print(f"Created product: {product.title}")
print(f"Product ID: {product.uid}")
print(f"Handle: {product.handle}")
print(f"Has variants: {product.has_variants}")

Creating a Product With Variants

When your product comes in multiple options (like size and color), you can create variants during product creation:

from decimal import Decimal
from konigle import Client
from konigle.models.commerce.product import ProductCreate, ProductOption, ProductStatus
from konigle.models.commerce.product_variant import ProductVariantCreate
from konigle.models import SEOMeta

# Initialize the client
client = Client(api_key="your_api_key")

# Define product options
options = [
    ProductOption(name="Size", values=["S", "M", "L", "XL"]),
    ProductOption(name="Color", values=["White", "Black", "Navy"]),
]

# Create variants that match the options
variants = [
    ProductVariantCreate(
        price=Decimal("29.99"),
        option1="M",
        option2="Red",
        sku="SHIRT-M-RED",
        inventory_quantity=50,
    ),
    ProductVariantCreate(
        price=Decimal("31.99"),
        option1="L",
        option2="Blue",
        sku="SHIRT-L-BLUE",
        inventory_quantity=30,
    ),
]

# Create product with variants
product_data = ProductCreate(
    title="Premium T-Shirt",
    handle="premium-t-shirt",
    status=ProductStatus.DRAFT,
    product_type="Clothing",
    vendor="Fashion Co",
    tags="cotton,comfortable,premium",
    currency="USD",
    content={
        "time": 1672531200000,
        "blocks": [
            {
                "type": "paragraph",
                "data": {"text": "Premium quality cotton t-shirt."},
            }
        ],
        "version": "2.28.0",
    },
    seo_meta=SEOMeta(
        description="Premium cotton t-shirt for everyday wear",
        keywords="t-shirt, cotton, premium, clothing",
        og_title="Premium T-Shirt",
        og_description="High-quality cotton t-shirt",
    ),
    options=options,
    variants=variants,
)

# Create the product
product = client.products.create(product_data)

print(f"Created product: {product.title}")
print(f"Product ID: {product.uid}")
print(f"Has variants: {product.has_variants}")
print(f"Number of options: {len(product.options)}")

# Variant titles are auto-generated from options
for variant in product_data.variants:
    print(f"Variant: {variant.title} - SKU: {variant.sku}")

Updating a Product

You can product attributes using partial updates:

from konigle import Client
from konigle.models.commerce.product import ProductUpdate, ProductStatus

# Initialize the client
client = Client(api_key="your_api_key")

# Update product fields
update_data = ProductUpdate(
    title="Updated Premium T-Shirt",
    status=ProductStatus.ACTIVE,
    tags="cotton,comfortable,premium,updated",
)

# Update the product
product_id = "c6ce805b-6dfb-4f66-91fb-797f9f5e60fa"
updated_product = client.products.update(product_id, update_data)

print(f"Updated product: {updated_product.title}")
print(f"Status: {updated_product.status}")
print(f"New price: {updated_product.price}")

Adding New Variants During Product Update

You can add new variants to an existing product by updating the product with new variant data:

from decimal import Decimal
from konigle import Client
from konigle.models.commerce.product import ProductUpdate
from konigle.models.commerce.product_variant import ProductVariantUpdate

# Initialize the client
client = Client(api_key="your_api_key")

# Create new variant updates
new_variants = [
    ProductVariantUpdate(
        price=Decimal("25.99"),
        sku="SHIRT-XS-YELLOW",
        inventory_quantity=25,
        option1="XS",
        option2="Yellow",
    ),
    ProductVariantUpdate(
        price=Decimal("35.99"),
        sku="SHIRT-XXL-GREEN",
        inventory_quantity=15,
        option1="XXL",
        option2="Green",
    ),
]

# Update product with new variants
update_data = ProductUpdate(
    title="Updated Premium T-Shirt",
    variants=new_variants,
)

# Update the product
product_id = "c6ce805b-6dfb-4f66-91fb-797f9f5e60fa"
updated_product = client.products.update(product_id, update_data)

print(f"Updated product: {updated_product.title}")
print(f"Has variants: {updated_product.has_variants}")

The new variants will be appended to the existing list of variants or replace them based on option matching.

Product Status Management

Products have different status levels for publication workflow:

from konigle.models.commerce.product import ProductStatus, ProductUpdate

# Available statuses
print(ProductStatus.DRAFT)      # "draft"
print(ProductStatus.ACTIVE)     # "active"
print(ProductStatus.ARCHIVED)   # "archived"

# Update product status
update_data = ProductUpdate(status=ProductStatus.ACTIVE)
updated_product = client.products.update(product_id, update_data)

print(f"Product status: {updated_product.status}")
print(f"Published at: {updated_product.published_at}")

Listing Products

Basic Product Listing

# List all products with pagination
products = client.products.list(page=1, page_size=20)

print(f"Total products: {products.count}")
print(f"Current page: {products.current_page}")
print(f"Total pages: {products.num_pages}")

for product in products.payload:
    print(f"- {product.title} ({product.status})")
    print(f"  Handle: {product.handle}")
    print(f"  Price: {product.price} {product.currency}")
    print(f"  Has variants: {product.has_variants}")

# Check if there are more pages
if products.has_next():
    next_page = client.products.list(page=2, page_size=20)

Filtering Products

from konigle.filters.commerce import ProductFilters

# Using filter object (type-safe)
product_filters = ProductFilters(
    q="t-shirt",  # Search in title, handle, and tags
    status="active",  # Only active products
    product_type="Clothing",
    vendor="Fashion Co",
    ordering="-created_at"  # Newest first
)

filtered_products = client.products.list(
    page=1,
    page_size=10,
    filters=product_filters
)

# Using filter kwargs (more concise)
active_products = client.products.list(
    status="active",
    q="premium",
    ordering="title"  # Sort by title
)

# Filter by product type
clothing_products = client.products.list(product_type="Clothing")

# Filter by vendor
vendor_products = client.products.list(vendor="Fashion Co")

# Search by text query
search_results = client.products.list(q="cotton t-shirt")

# Get draft products for review
draft_products = client.products.list(
    status="draft",
    ordering="-updated_at"
)

Getting a Specific Product

# Get product by ID
product = client.products.get("prod_123456789")
print(f"Product: {product.title}")
print(f"Status: {product.status}")
print(f"Price: {product.price} {product.currency}")
print(f"Vendor: {product.vendor}")
print(f"Product type: {product.product_type}")
print(f"Tags: {product.tags}")

# Check if product has variants
if product.has_variants:
    print(f"Number of options: {len(product.options)}")
    for option in product.options:
        print(f"  {option.name}: {', '.join(option.values)}")

# Access SEO metadata
if product.seo_meta:
    print(f"SEO Title: {product.seo_meta.title}")
    print(f"Description: {product.seo_meta.description}")

Iterating All Products

# Memory-efficient iteration over all products
for product in client.products.iter_all(page_size=50):
    print(f"Processing product: {product.title}")
    # Process each product...

# With filtering - get all active products
for product in client.products.iter_all(page_size=50, status="active"):
    print(f"Processing active product: {product.title}")

# Get products by vendor
for product in client.products.iter_all(vendor="Fashion Co"):
    print(f"Processing {product.vendor} product: {product.title}")

Working with Product Options

Product options define the dimensions for variants (size, color, etc.):

from konigle.models.commerce.product import ProductOption, ProductUpdate

# Define comprehensive options
options = [
    ProductOption(
        name="Size",
        values=["XS", "S", "M", "L", "XL", "XXL"]
    ),
    ProductOption(
        name="Color",
        values=["White", "Black", "Navy", "Red", "Green"]
    ),
    ProductOption(
        name="Material",
        values=["Cotton", "Polyester", "Blend"]
    ),
]

# Update product options
update_data = ProductUpdate(options=options)
updated_product = client.products.update(product_id, update_data)

print(f"Number of options: {len(updated_product.options)}")
for option in updated_product.options:
    print(f"{option.name}: {', '.join(option.values)}")

Deleting a Product

When you delete a product, all associated data is permanently removed. This includes:

  • Product variants: All variants of the product are deleted
  • Product images: All images associated with the product are deleted
  • Product metadata: SEO data, content, and other associated information

!!! warning "Cascading Delete" Deleting a product is irreversible and will permanently remove all variants, images, and associated data. Make sure you have backups if needed.

from konigle import Client

# Initialize the client
client = Client(api_key="your_api_key")

# Delete a product by ID
product_id = "c6ce805b-6dfb-4f66-91fb-797f9f5e60fa"

try:
    client.products.delete(product_id)
    print(f"Product {product_id} has been successfully deleted")
    print("All variants and images have been removed as well")
except Exception as e:
    print(f"Failed to delete product: {e}")

Soft Delete Alternative

Instead of permanently deleting a product, consider archiving it:

from konigle.models.commerce.product import ProductUpdate, ProductStatus

# Archive the product instead of deleting
update_data = ProductUpdate(status=ProductStatus.ARCHIVED)
archived_product = client.products.update(product_id, update_data)

print(f"Product archived: {archived_product.status}")
print("Product data is preserved and can be reactivated later")

Error Handling

The SDK includes validation for common mistakes:

from decimal import Decimal
from konigle.models.commerce.product import ProductCreate
from konigle.models.commerce.product_variant import ProductVariantCreate

# Price validation
try:
    # This will raise a ValueError
    invalid_product = ProductCreate(
        title="Test Product",
        price=Decimal("-10.00"),  # Negative price not allowed
    )
except ValueError as e:
    print(f"Price validation error: {e}")

try:
    # This will also raise a ValueError
    invalid_variant = ProductVariantCreate(
        price=Decimal("0.00"),  # Zero price not allowed
    )
except ValueError as e:
    print(f"Variant price validation error: {e}")

# Inventory validation
try:
    # This will raise a ValueError
    invalid_variant = ProductVariantCreate(
        price=Decimal("29.99"),
        inventory_quantity=-1,  # Negative inventory not allowed
    )
except ValueError as e:
    print(f"Inventory validation error: {e}")

Async Support

All product operations support async/await:

import asyncio
from konigle import AsyncClient
from konigle.models.commerce.product import ProductCreate

async def create_product_async():
    async_client = AsyncClient(api_key="your_api_key")

    product_data = ProductCreate(
        title="Async Product",
        handle="async-product",
    )

    product = await async_client.products.create(product_data)
    print(f"Created async product: {product.title}")

    await async_client.close()

# Run the async function
asyncio.run(create_product_async())