# Python 示例

## 安装依赖

```bash
pip install requests httpx
```

## 配置

```python
import os
import time
import hmac
import hashlib
import requests
# 或使用 httpx（支持异步）
# import httpx

EASEBG_API_KEY = os.environ.get("EASEBG_API_KEY", "your_api_key_here")
EASEBG_API_BASE = os.environ.get("EASEBG_API_BASE", "https://api.easebg.com/api/v1")

headers = {
    "X-API-Key": EASEBG_API_KEY,
    "Content-Type": "application/json",
}
```

## 1. 创建抠图任务

```python
def create_task(image_url, model_version="easebg-2.0", callback_url=None, metadata=None):
    payload = {
        "imageUrl": image_url,
        "modelVersion": model_version,
    }
    if callback_url:
        payload["callbackUrl"] = callback_url
    if metadata:
        payload["metadata"] = metadata

    response = requests.post(
        f"{EASEBG_API_BASE}/open/developer/tasks",
        headers=headers,
        json=payload,
    )
    response.raise_for_status()
    return response.json()


# 使用示例
try:
    result = create_task(
        "https://example.com/photo.jpg",
        callback_url="https://your-app.com/webhooks/easebg",
    )
    print(f"Task created: {result['data']['id']}")
except requests.exceptions.HTTPError as e:
    error_body = e.response.json()
    print(f"API Error: {error_body.get('error', {}).get('message')}")
```

## 2. 查询任务状态

```python
def get_task(task_id):
    response = requests.get(
        f"{EASEBG_API_BASE}/open/developer/tasks/{task_id}",
        headers=headers,
    )
    response.raise_for_status()
    return response.json()


def wait_for_task(task_id, interval=2, max_attempts=60):
    """轮询等待任务完成"""
    for _ in range(max_attempts):
        result = get_task(task_id)
        data = result["data"]
        status = data["status"]

        if status == "succeeded":
            return data
        elif status == "failed":
            raise Exception(f"Task failed: {data.get('errorMessage')}")

        time.sleep(interval)

    raise TimeoutError("Task timed out")


# 使用示例
task = create_task("https://example.com/photo.jpg")
result = wait_for_task(task["data"]["id"])
print(f"Result URL: {result['resultUrl']}")
```

## 3. 获取任务结果

```python
def download_result(task_id, output_path):
    result = get_task(task_id)
    data = result["data"]

    if data["status"] != "succeeded" or not data.get("resultUrl"):
        raise Exception("Task not completed or no result available")

    # 下载结果图片
    image_response = requests.get(data["resultUrl"])
    image_response.raise_for_status()

    with open(output_path, "wb") as f:
        f.write(image_response.content)

    print(f"Result saved to {output_path}")
```

## 4. 取消任务

```python
def cancel_task(task_id):
    response = requests.delete(
        f"{EASEBG_API_BASE}/open/developer/tasks/{task_id}",
        headers=headers,
    )

    if response.status_code == 204:
        print("Task canceled successfully")
        return True
    elif response.status_code == 409:
        raise Exception("Task cannot be canceled in current state")

    response.raise_for_status()
```

## 5. 创建批量任务

```python
def create_batch_task(image_urls, model_version="easebg-2.0", callback_url=None):
    payload = {
        "imageUrls": image_urls,
        "modelVersion": model_version,
    }
    if callback_url:
        payload["callbackUrl"] = callback_url

    response = requests.post(
        f"{EASEBG_API_BASE}/open/developer/batch-tasks",
        headers=headers,
        json=payload,
    )
    response.raise_for_status()
    return response.json()


# 使用示例
batch = create_batch_task([
    "https://example.com/photo1.jpg",
    "https://example.com/photo2.jpg",
    "https://example.com/photo3.jpg",
], callback_url="https://your-app.com/webhooks/easebg")
```

## 6. Webhook 签名验证

```python
import hmac
import hashlib
from flask import Flask, request, jsonify

app = Flask(__name__)

def verify_webhook_signature(payload: bytes, signature: str, secret: str) -> bool:
    computed = hmac.new(
        secret.encode("utf-8"),
        payload,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(computed, signature)


@app.route("/webhooks/easebg", methods=["POST"])
def handle_webhook():
    signature = request.headers.get("X-EaseBG-Signature", "")
    secret = os.environ.get("EASEBG_WEBHOOK_SECRET", "")

    if not verify_webhook_signature(request.data, signature, secret):
        return jsonify({"error": "Invalid signature"}), 401

    event = request.json
    print(f"Received webhook: {event.get('event')} - {event.get('taskId')}")

    if event["event"] == "task.succeeded":
        print(f"Task succeeded: {event.get('resultUrl')}")
    elif event["event"] == "task.failed":
        print(f"Task failed: {event.get('errorMessage')}")

    return jsonify({"received": True}), 200
```

## 7. 错误处理

```python
class EaseBGApiError(Exception):
    def __init__(self, status_code, code, message, details=None):
        self.status_code = status_code
        self.code = code
        self.message = message
        self.details = details
        super().__init__(f"[{code}] {message}")


def api_request(method, path, **kwargs):
    response = requests.request(
        method,
        f"{EASEBG_API_BASE}{path}",
        headers=headers,
        **kwargs,
    )

    try:
        body = response.json()
    except ValueError:
        body = {}

    if not response.ok:
        error = body.get("error", {})
        raise EaseBGApiError(
            response.status_code,
            error.get("code", "UNKNOWN"),
            error.get("message", "Request failed"),
            error.get("details"),
        )

    return body


# 使用示例
try:
    result = api_request("POST", "/open/developer/tasks", json={
        "imageUrl": "https://example.com/photo.jpg",
    })
except EaseBGApiError as e:
    if e.code == "INSUFFICIENT_CREDITS":
        print("积分不足，请充值")
    elif e.code == "RATE_LIMIT_EXCEEDED":
        print("请求频率超限，请稍后重试")
    elif e.code == "INVALID_API_KEY":
        print("API Key 无效")
    else:
        print(f"API 错误: {e}")
except requests.exceptions.RequestException as e:
    print(f"网络错误: {e}")
```

## 8. 分页查询

```python
def list_tasks(page=1, page_size=20, status=None, start_date=None, end_date=None):
    params = {"page": page, "pageSize": page_size}
    if status:
        params["status"] = status
    if start_date:
        params["startDate"] = start_date
    if end_date:
        params["endDate"] = end_date

    response = requests.get(
        f"{EASEBG_API_BASE}/open/developer/tasks",
        headers=headers,
        params=params,
    )
    response.raise_for_status()
    return response.json()


def get_all_tasks(status=None):
    """自动翻页获取所有任务"""
    all_tasks = []
    page = 1
    total_pages = 1

    while page <= total_pages:
        result = list_tasks(page=page, status=status)
        all_tasks.extend(result["data"])
        total_pages = result["meta"]["totalPages"]
        page += 1

    return all_tasks
```

## 异步版本（使用 httpx）

```python
import httpx
import asyncio

async def async_create_task(image_url, callback_url=None):
    async with httpx.AsyncClient() as client:
        payload = {"imageUrl": image_url}
        if callback_url:
            payload["callbackUrl"] = callback_url

        response = await client.post(
            f"{EASEBG_API_BASE}/open/developer/tasks",
            headers=headers,
            json=payload,
        )
        response.raise_for_status()
        return response.json()


async def async_batch_create(image_urls):
    """并发创建多个任务"""
    tasks = [async_create_task(url) for url in image_urls]
    results = await asyncio.gather(*tasks, return_exceptions=True)
    return results
```
