Installation
Copy
pip install chatads-sdk
Quick Start
Copy
from chatads_sdk import ChatAdsClient
# Use context manager for automatic cleanup
with ChatAdsClient(api_key="cak_your_api_key") as client:
response = client.analyze_message(
message="What are the best noise-cancelling headphones?",
country="US"
)
if response.error is None and response.data and response.data.returned > 0:
# Access first offer
offer = response.data.offers[0]
print(f"link_text: {offer.link_text}")
print(f"url: {offer.url}")
# Or iterate all offers
for i, offer in enumerate(response.data.offers):
print(f"Offer {i + 1}: {offer.link_text} - {offer.url}")
Configuration
Copy
from chatads_sdk import ChatAdsClient
# Basic usage with context manager (recommended)
with ChatAdsClient(
api_key="cak_your_api_key", # Required
base_url="https://...", # Optional: custom API URL
raise_on_failure=True, # Optional: raise exceptions on API errors
max_retries=2, # Optional: retry failed requests
retry_backoff_factor=0.75, # Optional: backoff multiplier between retries
debug=False, # Optional: enable debug logging
) as client:
# Use client here
pass
Methods
analyze_message
Analyze a message for affiliate opportunities.Copy
response = client.analyze_message(
message="Looking for a good yoga mat",
country="US",
quality="standard" # fast | standard | best
)
Response Structure
Copy
# response.data.status: str # "filled", "partial_fill", "no_offers_found", or "internal_error"
# response.data.offers: List[Offer] # Array of affiliate offers (only contains filled offers)
# response.data.requested: int # Number requested
# response.data.returned: int # Actual number returned
# response.error: ChatAdsError | None # Error details (None on success)
# response.meta.request_id: str
# response.meta.usage.monthly_requests: int
# response.meta.usage.daily_requests: int
# Each offer in response.data.offers has:
# offer.link_text: str # Text to use for affiliate link
# offer.url: str # Affiliate URL (always populated)
# offer.confidence_level: str # Confidence classification (low, medium, high)
# offer.product: Product # Product metadata (optional)
Error Handling
The SDK provides two exception types for different error scenarios:ChatAdsAPIError- Raised for API-level errors (HTTP 4xx/5xx responses)ChatAdsSDKError- Raised for SDK-level issues (validation, configuration, transport)
Copy
from chatads_sdk import ChatAdsClient, ChatAdsAPIError, ChatAdsSDKError
with ChatAdsClient(api_key="cak_your_api_key", raise_on_failure=True) as client:
try:
response = client.analyze_message(message="...")
if response.error is not None:
if response.error.code in ("DAILY_LIMIT_EXCEEDED", "MONTHLY_LIMIT_EXCEEDED"):
# Rate limit hit - wait for reset
pass
elif response.error.code == "UNAUTHORIZED":
# Check API key
pass
else:
print(f"Error: {response.error.message}")
except ChatAdsAPIError as e:
# API returned an error response (4xx/5xx)
print(f"API error: {e.status_code} - {e.payload}")
except ChatAdsSDKError as e:
# SDK-level error (validation, config, transport)
print(f"SDK error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
Framework Examples
FastAPI
Copy
from contextlib import asynccontextmanager
from fastapi import FastAPI
from chatads_sdk import AsyncChatAdsClient
import os
# Use lifespan for proper client lifecycle management
@asynccontextmanager
async def lifespan(app: FastAPI):
app.state.chatads = AsyncChatAdsClient(api_key=os.environ["CHATADS_API_KEY"])
yield
await app.state.chatads.close()
app = FastAPI(lifespan=lifespan)
@app.post("/analyze")
async def analyze(message: str):
response = await app.state.chatads.analyze_message(
message=message,
country="US"
)
return response.raw
Flask
Copy
from flask import Flask, request, jsonify, g
from chatads_sdk import ChatAdsClient
import os
app = Flask(__name__)
def get_chatads_client():
if 'chatads' not in g:
g.chatads = ChatAdsClient(api_key=os.environ["CHATADS_API_KEY"])
return g.chatads
@app.teardown_appcontext
def close_chatads(error):
client = g.pop('chatads', None)
if client is not None:
client.close()
@app.route("/analyze", methods=["POST"])
def analyze():
data = request.get_json()
client = get_chatads_client()
response = client.analyze_message(
message=data["message"]
)
return jsonify(response.raw)
Django
Copy
# views.py
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from chatads_sdk import ChatAdsClient
import json
import os
@require_POST
def analyze(request):
data = json.loads(request.body)
# Use context manager for automatic cleanup
with ChatAdsClient(api_key=os.environ["CHATADS_API_KEY"]) as client:
response = client.analyze_message(
message=data["message"]
)
return JsonResponse(response.raw)
Environment Variables
We recommend storing your API key in environment variables:Copy
import os
from chatads_sdk import ChatAdsClient
with ChatAdsClient(api_key=os.environ["CHATADS_API_KEY"]) as client:
response = client.analyze_message(message="...")
Copy
export CHATADS_API_KEY=cak_your_api_key
Using FunctionItemPayload
For more control over request parameters, useFunctionItemPayload:
Copy
from chatads_sdk import ChatAdsClient, FunctionItemPayload
with ChatAdsClient(api_key="cak_your_api_key") as client:
payload = FunctionItemPayload(
message="Looking for a CRM to close more deals",
ip="1.2.3.4",
country="US",
quality="standard" # fast | standard | best
)
result = client.analyze(payload)
if result.error is None and result.data.returned > 0:
print(result.data.offers[0])
else:
print("No offers found")
Async Client
For asynchronous workflows, useAsyncChatAdsClient:
Copy
import asyncio
from chatads_sdk import AsyncChatAdsClient, FunctionItemPayload
async def main():
async with AsyncChatAdsClient(
api_key="cak_your_api_key",
max_retries=3,
debug=True,
) as client:
# Using analyze_message shorthand
result = await client.analyze_message(
message="Need data warehousing ideas",
country="US",
ip="1.2.3.4",
)
print(result.raw)
# Or using FunctionItemPayload for full control
payload = FunctionItemPayload(
message="Best standing desk for home office",
country="US",
)
result = await client.analyze(payload)
if result.error is None and result.data.returned > 0:
print(f"Found: {result.data.offers[0].link_text}")
asyncio.run(main())
Concurrent Requests
Process multiple messages concurrently:Copy
import asyncio
from chatads_sdk import AsyncChatAdsClient
async def analyze_batch(messages: list[str]):
async with AsyncChatAdsClient(api_key="cak_your_api_key") as client:
tasks = [
client.analyze_message(message=msg, country="US")
for msg in messages
]
results = await asyncio.gather(*tasks)
return results
# Usage
messages = [
"Best noise-cancelling headphones",
"Top rated standing desks",
"Ergonomic office chairs",
]
results = asyncio.run(analyze_batch(messages))