Metadata-Version: 2.1
Name: channel3-sdk
Version: 4.1.0
Summary: 
Requires-Python: >=3.10,<4.0
Classifier: Intended Audience :: Developers
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: OS Independent
Classifier: Operating System :: POSIX
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Provides-Extra: aiohttp
Requires-Dist: aiohttp (>=3.14.1,<4) ; (python_version >= "3.10") and (extra == "aiohttp")
Requires-Dist: httpx (>=0.21.2,<1)
Requires-Dist: httpx-aiohttp (>=0.1.8,<0.2.0) ; (python_version >= "3.10") and (extra == "aiohttp")
Requires-Dist: pydantic (>=1.9.2)
Requires-Dist: pydantic-core (>=2.18.2,<3.0.0)
Requires-Dist: typing_extensions (>=4.0.0)
Project-URL: Repository, https://github.com/channel3-ai/channel3-python-sdk
Description-Content-Type: text/markdown

# Channel3 Python SDK

[![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-Built%20with%20Fern-brightgreen)](https://buildwithfern.com?utm_source=github&utm_medium=github&utm_campaign=readme&utm_source=https%3A%2F%2Fgithub.com%2Ffern-demo%2Fchannel3-python-sdk)
[![pypi](https://img.shields.io/pypi/v/channel3-sdk)](https://pypi.python.org/pypi/channel3-sdk)

The official Python SDK for the [Channel3 API](https://channel3.docs.buildwithfern.com) — a universal product database powering AI shopping apps and agents.

## Documentation

Full API documentation and guides are available at [channel3.docs.buildwithfern.com](https://channel3.docs.buildwithfern.com).

## Runtime Compatibilities

| Requirement | Version |
|-------------|---------|
| Python | `>= 3.10` |
| HTTP client | `httpx >= 0.21.2` |
| Async backend | `aiohttp >= 3.13.4` (optional extra) |
| Pydantic | `>= 1.9.2` (v1 and v2 supported) |
| OS | Linux, macOS, Windows |
| Typing | Fully typed — `py.typed` marker included |

## Installation

```sh
pip install channel3-sdk
# or
poetry add channel3-sdk
```

For async support with `aiohttp`:

```sh
pip install "channel3-sdk[aiohttp]"
```

## Authentication

The SDK authenticates via an `x-api-key` header. Pass your key when initializing the client:

```python
from channel3 import Channel3Client

client = Channel3Client(api_key="YOUR_API_KEY")
```

### Async client

```python
from channel3 import AsyncChannel3Client

client = AsyncChannel3Client(api_key="YOUR_API_KEY")
```

## Usage

### Search products

```python
response = client.products.search(query="organic cotton t-shirt", limit=10)

for product in response.products:
    print(product.title, product.offers[0].price if product.offers else None)
```

### Paginate through results

Search responses include a `next_page_token` for cursor-based pagination:

```python
page_token = None

while True:
    response = client.products.search(query="sneakers", page_token=page_token)
    for product in response.products:
        print(product.title)

    page_token = response.next_page_token
    if not page_token:
        break
```

### Visual search by image

```python
response = client.products.image_search(
    image_url="https://example.com/photo.jpg",
)
```

### Find similar products

```python
response = client.products.similar(product_id="prod-12345")
```

### Look up a product by URL

```python
product = client.products.lookup(url="https://example.com/product/abc")
```

### Browse brands and categories

Cursor-paginated listing:

```python
brands = client.brands.list(limit=50)
print(brands.items)         # list[Brand]
print(brands.next_cursor)   # pass as `cursor` for the next page

categories = client.categories.list(page_size=50)
```

### Track prices

```python
# Start tracking
client.price_tracking.start(canonical_product_id="prod-12345")

# Get price history
history = client.price_tracking.get_history("prod-12345")

# List active subscriptions
subs = client.price_tracking.list_subscriptions()

# Stop tracking
client.price_tracking.stop(canonical_product_id="prod-12345")
```

## Type Intellisense

All types are importable from the top-level `channel3` package:

```python
from channel3 import Channel3Client, SearchResponse, Product, Brand

# Full autocomplete in your IDE
response: SearchResponse = client.products.search(query="headphones")
product: Product = response.products[0]
```

Resource clients are accessible via dot notation — type `client.` in your editor to discover:

| Accessor | Methods |
|----------|---------|
| `client.products` | `search`, `image_search`, `similar`, `lookup`, `retrieve`, `enrich` |
| `client.brands` | `list`, `search`, `get` |
| `client.categories` | `list`, `search` |
| `client.price_tracking` | `start`, `stop`, `get_history`, `list_subscriptions` |
| `client.websites` | `list` |

## Error Handling

The SDK raises typed exceptions per HTTP status code:

```python
from channel3.errors import UnauthorizedError, PaymentRequiredError, BadRequestError

try:
    client.products.search(query="test")
except UnauthorizedError:
    print("Invalid API key")
except PaymentRequiredError:
    print("Upgrade your plan")
except BadRequestError as e:
    print(e.body)  # parsed error response
```

## Advanced

### Retries

Automatic exponential backoff on 5xx and network errors (default: 2 retries):

```python
response = client.products.search(
    query="shoes",
    request_options={"max_retries": 5},
)
```

### Timeouts

Default timeout is 60 seconds. Override per-client or per-request:

```python
client = Channel3Client(api_key="YOUR_API_KEY", timeout=30.0)

# Per-request
response = client.products.search(
    query="shoes",
    request_options={"timeout_in_seconds": 10},
)
```

### Raw Response Access

Access HTTP headers and status alongside parsed data:

```python
response = client.products.with_raw_response.search(query="shoes")
print(response.status_code)
print(response.headers)
print(response.data)  # parsed SearchResponse
```

### Custom HTTP Client

Pass your own `httpx` client for proxies, custom certs, or connection pooling:

```python
import httpx
from channel3 import Channel3Client

client = Channel3Client(
    api_key="YOUR_API_KEY",
    httpx_client=httpx.Client(proxy="http://proxy:8080"),
)
```

## Reference

See the full API reference in [reference.md](./reference.md).

## Contributing

See [CONTRIBUTING.md](./CONTRIBUTING.md) for development setup and guidelines.

