Python Examples
Authentication
Using Personal Access Token (Recommended for Development)
import os
from trading_card_api import Client
# Initialize with Personal Access Token
client = Client(
personal_access_token=os.getenv('TRADING_CARD_API_PAT'),
base_url='https://api.tradingcardapi.com'
)
# No additional authentication steps required!
# The token is automatically included in all requests
Using OAuth 2.0 Client Credentials (Recommended for Production)
import os
from trading_card_api import Client
# Initialize with OAuth credentials
client = Client(
client_id=os.getenv('TRADING_CARD_API_CLIENT_ID'),
client_secret=os.getenv('TRADING_CARD_API_CLIENT_SECRET'),
base_url='https://api.tradingcardapi.com'
)
# Client handles OAuth token flow automatically
Basic Usage
from trading_card_api import Client
client = Client(
client_id='your_client_id',
client_secret='your_client_secret',
base_url='https://api.tradingcardapi.com'
)
# Get cards
cards = client.cards.list(
page={'limit': 25},
filter={'year': 2023}
)
for card in cards['data']:
print(card['attributes']['name'])
Advanced Filtering
# Search with multiple filters
results = client.cards.list(
filter={'year': 1989, 'name': '*Griffey*'},
include='set,oncard',
sort='name',
page={'limit': 50}
)
Cards
Fetch Card with Image Reference
# Get a card and check for image_uuid
card_id = '550e8400-e29b-41d4-a716-446655440000'
try:
response = client.cards.get(card_id)
card = response['data']
print(f"Card: {card['attributes']['name']}")
print(f"Number: {card['attributes']['number']}")
# Check if card has an image reference (v0.6.0+)
if card['attributes'].get('image_uuid'):
print(f"Image UUID: {card['attributes']['image_uuid']}")
else:
print("No image uploaded yet")
except Exception as e:
print(f"Error: {str(e)}")
Include Card Images in Response
# Fetch card with related images included (v0.7.0+)
card_id = '550e8400-e29b-41d4-a716-446655440000'
try:
response = client.cards.get(card_id, include='images')
card = response['data']
print(f"Card: {card['attributes']['name']}")
# Access included images
if 'included' in response:
for included in response['included']:
if included['type'] == 'card_images':
print(f"Image: {included['attributes']['side']}")
print(f"URL: {included['attributes']['image_url']}")
except Exception as e:
print(f"Error: {str(e)}")
List Cards with Images
# List cards and include their images
results = client.cards.list(
filter={'set_id': '550e8400-e29b-41d4-a716-446655440000'},
include='images,set',
page={'limit': 25}
)
for card in results['data']:
has_image = ' [Has Image]' if card['attributes'].get('image_uuid') else ''
print(f"{card['attributes']['number']} - {card['attributes']['name']}{has_image}")
# Process included images
if 'included' in results:
images = [item for item in results['included'] if item['type'] == 'card_images']
print(f"\nTotal images included: {len(images)}")
File Uploads
Upload Card Image
import os
import json
# Upload a card image with validation
image_path = '/path/to/card-front.jpg'
# Validate file exists
if not os.path.exists(image_path):
raise FileNotFoundError(f"Image file not found: {image_path}")
# Check file size
file_size = os.path.getsize(image_path)
max_size = 10 * 1024 * 1024 # 10MB
if file_size > max_size:
raise ValueError("Image too large. Maximum size: 10MB")
# Validate image type
allowed_extensions = {'.jpg', '.jpeg', '.png'}
file_ext = os.path.splitext(image_path)[1].lower()
if file_ext not in allowed_extensions:
raise ValueError(f"Invalid image type. Allowed: {', '.join(allowed_extensions)}")
try:
with open(image_path, 'rb') as image_file:
files = {
'file': ('card-front.jpg', image_file, 'image/jpeg')
}
data = {
'data': json.dumps({
'type': 'card_images',
'attributes': {
'card_id': '550e8400-e29b-41d4-a716-446655440000',
'image_type': 'front'
}
})
}
response = client.card_images.create(files=files, data=data)
print("Image uploaded successfully!")
print(f"Image ID: {response['data']['id']}")
print(f"Small URL: {response['data']['attributes']['variants']['small']['url']}")
print(f"Medium URL: {response['data']['attributes']['variants']['medium']['url']}")
print(f"Large URL: {response['data']['attributes']['variants']['large']['url']}")
image_id = response['data']['id']
except Exception as e:
print(f"Upload failed: {str(e)}")
raise
Upload with Progress Tracking
import requests
from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor
import json
def upload_with_progress(client, image_path, card_id):
def progress_callback(monitor):
progress = (monitor.bytes_read / monitor.len) * 100
print(f"Upload progress: {progress:.1f}%")
with open(image_path, 'rb') as f:
encoder = MultipartEncoder({
'file': ('card.jpg', f, 'image/jpeg'),
'data': json.dumps({
'type': 'card_images',
'attributes': {
'card_id': card_id,
'image_type': 'front'
}
})
})
monitor = MultipartEncoderMonitor(encoder, progress_callback)
headers = {
'Authorization': f'Bearer {client.access_token}',
'Content-Type': monitor.content_type
}
response = requests.post(
'https://api.tradingcardapi.com/v1/card-images',
data=monitor,
headers=headers
)
return response.json()
# Usage
result = upload_with_progress(client, '/path/to/card.jpg', '550e8400-e29b-41d4-a716-446655440000')
print(f"Upload complete: {result['data']['id']}")
List Card Images
# List all images for a specific card
card_id = '550e8400-e29b-41d4-a716-446655440000'
images = client.card_images.list(filter={'card_id': card_id})
for image in images['data']:
print(f"Image ID: {image['id']}")
print(f"Type: {image['attributes']['image_type']}")
print(f"Small URL: {image['attributes']['variants']['small']['url']}")
print("---")
Download Card Image
import requests
# Download specific size variant
image_id = '01234567-89ab-cdef-0123-456789abcdef'
image_url = f"https://api.tradingcardapi.com/v1/card-images/{image_id}/download?size=medium"
try:
headers = {
'Authorization': f'Bearer {client.access_token}'
}
response = requests.get(image_url, headers=headers, allow_redirects=True)
if response.status_code == 200:
with open('card-image.jpg', 'wb') as f:
f.write(response.content)
print("Image downloaded successfully")
else:
print(f"Download failed with status: {response.status_code}")
except Exception as e:
print(f"Download error: {str(e)}")
Update Image Metadata
# Update image metadata (e.g., change from front to back)
image_id = '01234567-89ab-cdef-0123-456789abcdef'
try:
response = client.card_images.update(image_id, {
'type': 'card_images',
'id': image_id,
'attributes': {
'image_type': 'back'
}
})
print("Image metadata updated successfully")
print(f"New type: {response['data']['attributes']['image_type']}")
except Exception as e:
print(f"Update failed: {str(e)}")
Delete Card Image
# Delete a card image
image_id = '01234567-89ab-cdef-0123-456789abcdef'
try:
client.card_images.delete(image_id)
print("Image deleted successfully")
except Exception as e:
print(f"Deletion failed: {str(e)}")
Responsive Images with Versioned CDN URLs
# Fetch image with versioned CDN URLs
image_response = client.card_images.get(image_id)
attrs = image_response['data']['attributes']
# All URLs include version parameter (?v=timestamp) for automatic cache invalidation
small_url = attrs['variants']['small']['url']
medium_url = attrs['variants']['medium']['url']
large_url = attrs['variants']['large']['url']
# Generate responsive image HTML
img_html = f'''
<img
src="{small_url}"
srcset="
{small_url} 150w,
{medium_url} 300w,
{large_url} 600w
"
sizes="(max-width: 640px) 150px, 300px"
alt="Card image"
loading="lazy"
/>
'''
# Or use in Flask/Django template
def render_card_image(client, image_id):
image = client.card_images.get(image_id)
attrs = image['data']['attributes']
return {
'small': attrs['variants']['small']['url'],
'medium': attrs['variants']['medium']['url'],
'large': attrs['variants']['large']['url'],
'original': attrs['download_url']
}
# In template:
# <img src="{{ image.small }}" srcset="{{ image.small }} 150w, {{ image.medium }} 300w" ... />
Set Sources
Create Set Source
# Add a checklist source to a set
set_id = '550e8400-e29b-41d4-a716-446655440000'
try:
response = client.set_sources.create({
'type': 'set_sources',
'attributes': {
'set_id': set_id,
'source_type': 'checklist',
'source_name': 'Beckett Online Price Guide',
'source_url': 'https://www.beckett.com/price-guides'
}
})
print("Source created successfully!")
print(f"Source ID: {response['data']['id']}")
print(f"Type: {response['data']['attributes']['source_type']}")
print(f"Name: {response['data']['attributes']['source_name']}")
except Exception as e:
print(f"Failed to create source: {str(e)}")
List Sources for a Set
# Get all sources for a specific set
set_id = '550e8400-e29b-41d4-a716-446655440000'
sources = client.set_sources.list(filter={'set_id': set_id})
print(f"Found {len(sources['data'])} sources\n")
for source in sources['data']:
print(f"Source Type: {source['attributes']['source_type']}")
print(f"Name: {source['attributes']['source_name']}")
print(f"URL: {source['attributes']['source_url']}")
if 'verified_at' in source['attributes'] and source['attributes']['verified_at']:
print(f"Verified: {source['attributes']['verified_at']}")
print("---")
Get Set with Sources Included
# Fetch a set with all its sources using include parameter
set_id = '550e8400-e29b-41d4-a716-446655440000'
response = client.sets.get(set_id, include='sources')
set_data = response['data']
print(f"Set: {set_data['attributes']['name']}")
print(f"Year: {set_data['attributes']['year']}")
print()
# Sources are in the included array
if 'included' in response:
print("Data Sources:")
for item in response['included']:
if item['type'] == 'set_sources':
source_type = item['attributes']['source_type']
source_name = item['attributes']['source_name']
print(f"- {source_type}: {source_name}")
Update Source Verification
from datetime import datetime
# Update a source to mark it as verified
source_id = '01234567-89ab-cdef-0123-456789abcdef'
try:
response = client.set_sources.update(source_id, {
'type': 'set_sources',
'id': source_id,
'attributes': {
'verified_at': datetime.utcnow().isoformat() + 'Z'
}
})
print(f"Source verified at: {response['data']['attributes']['verified_at']}")
except Exception as e:
print(f"Verification failed: {str(e)}")
Delete Set Source
# Remove a source from a set
source_id = '01234567-89ab-cdef-0123-456789abcdef'
try:
client.set_sources.delete(source_id)
print("Source deleted successfully")
except Exception as e:
print(f"Deletion failed: {str(e)}")
Track Multiple Source Types
# Add multiple sources for different data types
set_id = '550e8400-e29b-41d4-a716-446655440000'
source_types = [
{
'type': 'checklist',
'name': 'COMC Database',
'url': 'https://www.comc.com'
},
{
'type': 'metadata',
'name': 'CardboardConnection',
'url': 'https://www.cardboardconnection.com'
},
{
'type': 'images',
'name': 'Trading Card Database',
'url': 'https://www.tradingcarddb.com'
}
]
for source_info in source_types:
try:
response = client.set_sources.create({
'type': 'set_sources',
'attributes': {
'set_id': set_id,
'source_type': source_info['type'],
'source_name': source_info['name'],
'source_url': source_info['url']
}
})
print(f"Added {source_info['type']} source: {source_info['name']}")
except Exception as e:
print(f"Failed to add {source_info['type']} source: {str(e)}")
v2 Endpoints
Get Set Checklist (v2)
# v2 endpoint returns cards as primary data (correct JSON:API semantics)
set_id = '550e8400-e29b-41d4-a716-446655440000'
try:
response = client.get(f"/v2/sets/{set_id}/checklist")
cards = response['data']
set_data = response.get('included', [{}])[0]
for card in cards:
print(f"Card #{card['attributes']['number']}: {card['attributes']['name']}")
except Exception as e:
print(f"Error: {str(e)}")
Compact Format for Large Sets
# Use compact format to reduce response size by ~75%
set_id = '550e8400-e29b-41d4-a716-446655440000'
try:
response = client.get(f"/v2/sets/{set_id}/checklist", params={
'format': 'compact'
})
for card in response['data']:
attrs = card['attributes']
print(f"#{attrs['number']:<4} {attrs['name']}")
except Exception as e:
print(f"Error: {str(e)}")