Metadata-Version: 2.4
Name: shedcloud-partner-api
Version: 0.8.1
Summary: Official Python client for the ShedCloud Partner API
Project-URL: Homepage, https://github.com/Corland-Partners-LLC/shedcloud-pypi
Project-URL: Documentation, https://go.shedcloud.com/partner/reference
Project-URL: Repository, https://github.com/Corland-Partners-LLC/shedcloud-pypi
Project-URL: Issues, https://github.com/Corland-Partners-LLC/shedcloud-pypi/issues
Author: Corland Partners LLC
License-Expression: MIT
License-File: LICENSE
Keywords: inventory,leads,orders,partner-api,quotes,shedcloud
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
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: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# shedcloud-partner-api

Official Python client for the ShedCloud Partner API (`/partner/v1/*`).

Use this package from Python 3.10+ to call company-scoped Partner API endpoints with an API key (`sc_live_…`) or OAuth2 client credentials.

## Install

```bash
pip install shedcloud-partner-api
```

For local development:

```bash
pip install -e ".[dev]"
```

## Hosts

| Environment | Host |
|-------------|------|
| `production` (default) | `https://go.shedcloud.com` |
| `sandbox` | `https://api.shedcloudtest.com` |

Pass `environment="sandbox"` for test, or `base_url=` for a custom/local override.

## Quick start

### API key (production)

```python
from shedcloud_partner_api import ShedCloudPartnerClient

client = ShedCloudPartnerClient(
    auth={"type": "api_key", "api_key": "sc_live_..."},
)

stock = client.lot_stock.list({"limit": 50, "purchase_type": "Lot Stock"})
unit = stock["data"][0]
print(stock["total"], unit["title"])
# Typed public photo galleries (CDN URL arrays; empty when none):
# unit["heroImages"], unit["frontImages"], unit["backImages"],
# unit["leftImages"], unit["rightImages"], unit["exteriorImages"],
# unit["interiorImages"]
```

### Sandbox

```python
client = ShedCloudPartnerClient(
    environment="sandbox",
    auth={"type": "api_key", "api_key": "sc_live_..."},
)
```

### OAuth2 client credentials

```python
client = ShedCloudPartnerClient(
    auth={
        "type": "oauth",
        "client_id": "...",
        "client_secret": "...",
    },
)

orders = client.orders.list({"status": "Unprocessed", "limit": 25})
```

Create credentials in the ShedCloud portal under **Settings → Developer API**.

## Resources

Each attribute maps to a section of the [hosted reference](https://go.shedcloud.com/partner/reference).

| Client attribute | Endpoints |
|------------------|-----------|
| `client.lot_stock` | `GET /partner/v1/lot-stock` |
| `client.stock_templates` | `GET /partner/v1/stock-templates` |
| `client.leads` | leads CRUD + status |
| `client.quotes` | quotes CRUD, convert, line items |
| `client.orders` | orders CRUD, contract, payments, line items |
| `client.work_orders` | work orders CRUD + status |
| `client.locations` | locations CRUD |
| `client.customers` | customers CRUD + merge |
| `client.domains` | storefront domains (read-only) |
| `client.agreements` | B2B agreements + state legal (read-only) |
| `client.products` | catalog products + sizes |
| `client.users` | users CRUD + roles |
| `client.payments` | payments (read-only) |
| `client.documents` | documents + download links |
| `client.events` | event feed, iterator, redeliver, webhook deliveries |
| `client.site_events` | visitor behavioral tracking: batch ingest (snake_case body) + read-back iterator | [#site-events](https://go.shedcloud.com/partner/reference#site-events) |
| `client.configurator_sessions` | 3D configurator launch sessions |

### Idempotency and optimistic concurrency

```python
client.quotes.create(body, idempotency_key="uuid-here")
client.orders.update(order_id, body, if_match=record["version"])
```

### Event feed iterator

```python
for event in client.events.iterate({"types": ["order.created"]}):
    handle(event)
```

### Site events (visitor tracking)

Server-side batch ingest from a partner marketing site. The ingest body stays **snake_case** on the wire — do not camelCase it.

```python
from shedcloud_partner_api import PartnerScopes

client.site_events.track(
    {
        "session_id": "sess-abc",
        "visitor_id": "vis-xyz",
        "site_host": "www.example-sheds.com",
        "events": [
            {"event_type": "page.view", "page": "/buildings"},
            {"event_type": "cta.click", "product_id": "prod-1"},
        ],
    }
)

for event in client.site_events.iterate({"session_id": "sess-abc", "limit": 100}):
    print(event["eventType"], event.get("source"))
```

Scopes: `PartnerScopes.SITE_EVENTS_WRITE` (ingest), `PartnerScopes.SITE_EVENTS_READ` (read-back).

### Webhook verification

```python
from shedcloud_partner_api import verify_webhook_signature, WEBHOOK_SIGNATURE_HEADER

verify_webhook_signature(
    request.body,
    request.headers[WEBHOOK_SIGNATURE_HEADER],
    webhook_secret,
)
```

## Python field names

Request params and bodies use **snake_case** in Python (e.g. `location_id`, `default_for_store`). The client serializes them to camelCase JSON automatically.

## Scopes

See `shedcloud_partner_api.PartnerScopes` — kept in sync with the API's scope catalog.

## Related SDKs

- TypeScript/JavaScript: [`@shedcloud/partner-api`](https://www.npmjs.com/package/@shedcloud/partner-api)
- Go: [`shedcloud-gomod/partnerapi`](https://pkg.go.dev/github.com/Corland-Partners-LLC/shedcloud-gomod/partnerapi)
- PHP: [`shedcloud/partner-api`](https://github.com/Corland-Partners-LLC/shedcloud-php)
- Ruby: [`shedcloud-partner_api`](https://github.com/Corland-Partners-LLC/shedcloud-gem)

## Publishing (maintainers)

Automated via [`.github/workflows/publish.yml`](.github/workflows/publish.yml):

| Trigger | Index | Version | Install |
|---------|-------|---------|---------|
| Push to `main` | [TestPyPI](https://test.pypi.org) | `0.5.1.dev42` | `pip install --index-url https://test.pypi.org/simple/ --pre shedcloud-partner-api` |
| Tag `v0.5.1` or GitHub Release | [PyPI](https://pypi.org) | `0.5.1` | `pip install shedcloud-partner-api` |

Every `main` commit publishes a unique dev build to **TestPyPI only** — production PyPI stays clean for stable tags.

**One-time TestPyPI trusted publisher:** [test.pypi.org](https://test.pypi.org) → **Publishing** → pending publisher → Owner `Corland-Partners-LLC`, repo `shedcloud-pypi`, workflow `publish.yml`, environment **`testpypi`**. Create matching GitHub environment `testpypi`.

**Stable release:**

1. Bump `version` in `pyproject.toml` and `src/shedcloud_partner_api/__init__.py`
2. Update `CHANGELOG.md`, commit to `main` (TestPyPI dev build)
3. Tag: `git tag v0.5.1 && git push origin v0.5.1` (production PyPI)

## License

MIT
