Skip to main content

Python Examples

Complete code examples for using the TakeTheme API with Python.

Setup

Using Requests

pip install requests
import os
import requests
from typing import Optional, Dict, Any, Iterator

API_KEY = os.environ.get('TAKETHEME_API_KEY')
BASE_URL = 'https://api.taketheme.com/api/v1'

class TakeThemeClient:
def __init__(self, api_key: str):
self.api_key = api_key
self.session = requests.Session()
self.session.headers.update({
'tt-api-key': f'{api_key}',
'Content-Type': 'application/json'
})

def request(self, method: str, endpoint: str, **kwargs) -> Dict[str, Any]:
response = self.session.request(
method,
f'{BASE_URL}{endpoint}',
**kwargs
)

if not response.ok:
error = response.json()['error']
raise TakeThemeError(error)

return response.json()

def get(self, endpoint: str, params: Optional[Dict] = None) -> Dict[str, Any]:
return self.request('GET', endpoint, params=params)

def post(self, endpoint: str, data: Dict) -> Dict[str, Any]:
return self.request('POST', endpoint, json=data)

def patch(self, endpoint: str, data: Dict) -> Dict[str, Any]:
return self.request('PATCH', endpoint, json=data)

def delete(self, endpoint: str) -> None:
self.request('DELETE', endpoint)


class TakeThemeError(Exception):
def __init__(self, error: Dict):
self.message = error.get('message', 'Unknown error')
self.code = error.get('code')
self.status = error.get('status')
self.details = error.get('details', [])
super().__init__(self.message)


# Initialize client
client = TakeThemeClient(API_KEY)

Products

List All Products

# Using requests
response = client.get('/products', params={'limit': 25})
products = response['data']
pagination = response['pagination']

print(f"Found {pagination['total_count']} products")
for product in products:
print(f"- {product['title']} (${product['price']})")

Get a Single Product

product = client.get('/products/prod_abc123')['data']
print(f"{product['title']}: {product['description']}")

Create a Product

new_product = client.post('/products', {
'title': 'Premium Hoodie',
'description': 'Warm and comfortable hoodie',
'price': 59.99,
'currency': 'USD',
'status': 'active',
'variants': [
{'title': 'Small', 'sku': 'HOODIE-S', 'price': 59.99, 'inventory_quantity': 50},
{'title': 'Medium', 'sku': 'HOODIE-M', 'price': 59.99, 'inventory_quantity': 75},
{'title': 'Large', 'sku': 'HOODIE-L', 'price': 59.99, 'inventory_quantity': 60},
],
'images': [
{'src': 'https://example.com/hoodie.jpg', 'alt': 'Premium Hoodie'}
]
})['data']

print(f"Created product: {new_product['id']}")

Update a Product

updated = client.patch('/products/prod_abc123', {
'price': 64.99,
'tags': ['featured', 'winter-collection']
})['data']

Delete a Product

client.delete('/products/prod_abc123')

Orders

List Orders

# Recent pending orders
orders = client.get('/orders', params={
'status': 'pending',
'limit': 50
})['data']

# Orders with date filtering
from datetime import datetime, timedelta

week_ago = (datetime.now() - timedelta(days=7)).isoformat()
recent_orders = client.get('/orders', params={
'created_at_min': week_ago
})['data']

Create an Order

order = client.post('/orders', {
'customer': {
'email': 'customer@example.com',
'first_name': 'John',
'last_name': 'Doe'
},
'line_items': [
{
'variant_id': 'var_abc123',
'quantity': 2,
'price': 29.99
}
],
'shipping_address': {
'first_name': 'John',
'last_name': 'Doe',
'address1': '123 Main Street',
'city': 'New York',
'province': 'NY',
'postal_code': '10001',
'country': 'US',
'phone': '+1-555-123-4567'
},
'shipping_line': {
'title': 'Standard Shipping',
'price': 5.99
}
})['data']

print(f"Order created: {order['order_number']}")

Fulfill an Order

fulfillment = client.post(f'/orders/{order_id}/fulfillments', {
'line_items': [
{'id': 'li_abc123', 'quantity': 2}
],
'tracking_number': '1Z999AA10123456784',
'tracking_company': 'UPS',
'notify_customer': True
})['data']

Cancel an Order

cancelled = client.post(f'/orders/{order_id}/cancel', {
'reason': 'customer_request',
'restock': True,
'notify_customer': True
})['data']

Customers

Search Customers

# Find by email
customers = client.get('/customers', params={
'email': 'john@example.com'
})['data']

# Find VIP customers
vip_customers = client.get('/customers', params={
'tags': 'vip',
'orders_count_min': 10
})['data']

Create a Customer

customer = client.post('/customers', {
'email': 'newcustomer@example.com',
'first_name': 'Jane',
'last_name': 'Smith',
'phone': '+1-555-987-6543',
'addresses': [
{
'address1': '456 Oak Avenue',
'city': 'Los Angeles',
'province': 'CA',
'postal_code': '90001',
'country': 'US',
'default': True
}
],
'tags': ['newsletter', 'loyalty-program'],
'accepts_marketing': True
})['data']

Inventory

Update Stock Levels

# Set absolute quantity
client.post('/inventory/var_abc123', {
'location_id': 'loc_main',
'available': 100
})

# Adjust by delta
client.post('/inventory/var_abc123/adjust', {
'location_id': 'loc_main',
'adjustment': -5,
'reason': 'Damaged stock'
})

Webhooks

Register a Webhook

webhook = client.post('/webhooks', {
'topic': 'orders/created',
'address': 'https://your-app.com/webhooks/orders',
'format': 'json'
})['data']

print(f"Webhook registered: {webhook['id']}")

Verify Webhook Signatures (Flask)

import hmac
import hashlib
from flask import Flask, request, abort

app = Flask(__name__)
WEBHOOK_SECRET = os.environ['TAKETHEME_WEBHOOK_SECRET']

def verify_webhook(payload: bytes, signature: str) -> bool:
expected = hmac.new(
WEBHOOK_SECRET.encode(),
payload,
hashlib.sha256
).digest()

return hmac.compare_digest(
expected,
base64.b64decode(signature)
)

@app.route('/webhooks/orders', methods=['POST'])
def handle_order_webhook():
signature = request.headers.get('X-TakeTheme-Signature')

if not signature or not verify_webhook(request.data, signature):
abort(401)

event = request.json
print(f"Order created: {event['data']['order_number']}")

return 'OK', 200

Pagination Helper

from typing import Iterator, Dict, Any

def paginate(endpoint: str, params: Optional[Dict] = None) -> Iterator[Dict[str, Any]]:
"""Generator that yields items from all pages."""
params = params or {}
params['limit'] = 100
cursor = None

while True:
if cursor:
params['cursor'] = cursor
params['direction'] = 'next'

response = client.get(endpoint, params=params)
data = response['data']
pagination = response['pagination']

for item in data:
yield item

if not pagination.get('has_more'):
break

cursor = pagination.get('next_cursor')


# Usage
for product in paginate('/products'):
print(product['title'])

# Collect all products
all_products = list(paginate('/products'))
print(f"Total: {len(all_products)} products")

Error Handling

from typing import List, Dict

class TakeThemeError(Exception):
def __init__(self, error: Dict):
self.message = error.get('message', 'Unknown error')
self.code = error.get('code')
self.status = error.get('status')
self.details: List[Dict] = error.get('details', [])
self.request_id = error.get('request_id')
super().__init__(self.message)


class ValidationError(TakeThemeError):
pass


class RateLimitError(TakeThemeError):
def __init__(self, error: Dict, retry_after: int):
super().__init__(error)
self.retry_after = retry_after


def handle_response(response: requests.Response) -> Dict:
if response.ok:
return response.json()

error_data = response.json()['error']

if response.status_code == 422:
raise ValidationError(error_data)
elif response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
raise RateLimitError(error_data, retry_after)
else:
raise TakeThemeError(error_data)


# Usage
try:
client.post('/products', {'title': ''}) # Invalid
except ValidationError as e:
for detail in e.details:
print(f"{detail['field']}: {detail['message']}")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after} seconds")
time.sleep(e.retry_after)
except TakeThemeError as e:
print(f"Error {e.code}: {e.message}")

Complete Example: Export Orders to CSV

import csv
import os
from datetime import datetime, timedelta
from typing import Iterator, Dict

API_KEY = os.environ['TAKETHEME_API_KEY']

def get_recent_orders(days: int = 30) -> Iterator[Dict]:
"""Fetch all orders from the last N days."""
since = (datetime.now() - timedelta(days=days)).isoformat()

for order in paginate('/orders', {'created_at_min': since}):
yield order


def export_orders_to_csv(filename: str, days: int = 30):
"""Export recent orders to a CSV file."""
fieldnames = [
'order_number',
'created_at',
'customer_email',
'total',
'status',
'fulfillment_status',
'items_count'
]

with open(filename, 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()

for order in get_recent_orders(days):
writer.writerow({
'order_number': order['order_number'],
'created_at': order['created_at'],
'customer_email': order.get('customer', {}).get('email', ''),
'total': order['total'],
'status': order['status'],
'fulfillment_status': order.get('fulfillment_status', 'unfulfilled'),
'items_count': len(order.get('line_items', []))
})

print(f"Exported orders to {filename}")


if __name__ == '__main__':
export_orders_to_csv('orders_export.csv', days=30)

Async Example (aiohttp)

import asyncio
import aiohttp
import os

API_KEY = os.environ['TAKETHEME_API_KEY']
BASE_URL = 'https://api.taketheme.com/api/v1'

async def fetch_products():
async with aiohttp.ClientSession() as session:
headers = {
'tt-api-key': f'{API_KEY}',
'Content-Type': 'application/json'
}

async with session.get(f'{BASE_URL}/products', headers=headers) as response:
data = await response.json()
return data['data']


async def fetch_multiple_products(product_ids: list):
async with aiohttp.ClientSession() as session:
headers = {
'tt-api-key': f'{API_KEY}',
'Content-Type': 'application/json'
}

tasks = [
session.get(f'{BASE_URL}/products/{pid}', headers=headers)
for pid in product_ids
]

responses = await asyncio.gather(*tasks)
products = []

for response in responses:
data = await response.json()
products.append(data['data'])

return products


# Usage
async def main():
products = await fetch_products()
print(f"Found {len(products)} products")

# Fetch multiple products concurrently
ids = [p['id'] for p in products[:5]]
details = await fetch_multiple_products(ids)
for p in details:
print(f"- {p['title']}")


asyncio.run(main())