Metadata-Version: 2.4
Name: dataxapi
Version: 0.3.0
Summary: DataXAPI Python SDK: exact public social data endpoints with one CNY balance
Author-email: "DataXAPI (Aurevant LLC)" <support@dataxapi.com>
License-Expression: MIT
Project-URL: Homepage, https://dataxapi.com
Project-URL: Documentation, https://dataxapi.com/en/docs/
Project-URL: API catalog, https://dataxapi.com/en/apis/
Project-URL: Changelog, https://dataxapi.com/en/docs/sdks/#upgrade
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Operating System :: OS Independent
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown

# DataXAPI Python SDK

Typed client for [DataXAPI](https://dataxapi.com): fixed, per-call-priced public social data APIs (X, Reddit, Xiaohongshu, Douyin, TikTok, Instagram, YouTube, Bilibili, Weibo, Kuaishou, Zhihu) paid from one CNY balance.

The input, output and error `TypedDict`s are generated from the current API catalog / [OpenAPI document](https://dataxapi.com/openapi.json). The runtime only handles authentication, timeouts, safe retries with one idempotency key, pagination and Usage lookups. It has no third-party dependencies.

## Install

```sh
pip install dataxapi
```

Python 3.11 or later.

## Authenticate

Create an API key in the [Console](https://dataxapi.com/en/console/) and keep it in an environment variable:

```sh
export DATAXAPI_API_KEY="sk_live_..."
```

For development and tests, use a test key (`sk_test_...`, created with the Console's "Test key" switch) with the same client: calls are validated like live calls but return each API's documented example with `meta["mode"] == "test"` and are never charged. See [Test keys](https://dataxapi.com/en/docs/authentication/#test-keys).

## Call an API

```python
import os
import uuid

from dataxapi import DataXClient

client = DataXClient("https://api.dataxapi.com", os.environ["DATAXAPI_API_KEY"])

# Every API is available by its operationId (the OpenAPI operationId).
result = client.call(
    "x_posts_search_v1",
    {"query": "OpenAI min_faves:100"},
    # Optional. Store the key with your job and reuse it when you retry the same
    # logical call: the retry returns the original result and is not charged again.
    idempotency_key=str(uuid.uuid4()),
)

print(len(result["data"]["items"]), result["meta"]["charged_amount"], result["meta"]["balance_after"])
```

When you do not pass `idempotency_key`, the SDK generates one per call and reuses it for its own automatic retries. Unknown operation ids raise a `ValueError` that names the id.

## Errors and retries

- `DataXError`: the API answered with a non-2xx problem. Attributes: `status`, `code`, `detail`, `request_id`, `charge_status`, `charged_amount`, `retry_after_ms`, `retry_after`, `idempotency_key`.
- `DataXConnectionError`: the outcome is unknown (network error or timeout). Retry later with `error.idempotency_key` so the call cannot run or charge twice.

Built-in behavior (defaults: `timeout=60` seconds per attempt, `max_retries=2`):

- `429 rate_limited` and retryable `5xx` errors are retried with the same key after the server's `retry_after_ms` / `Retry-After`.
- `409 request_in_progress` means the original call with that key is still running (`charge_status` is `unknown` until it settles). The SDK waits `retry_after_ms` and polls with the same key for up to about 90 seconds; this does not use up `max_retries`. Set `max_retries=0` to disable all automatic retries.
- Network errors are retried with exponential backoff and jitter, with the same key.
- Codes that repeat deterministically are never retried: `upstream_failed`, `upstream_schema_changed`, `settlement_failed`, `previous_execution_failed`, `no_results`, `not_found`, `route_not_found`, `method_not_allowed`, `listing_paused`, `account_suspended`, and other 4xx errors. (`no_results` is no longer returned since 2026-10-08: an empty result is a charged 200 with `meta.result_status` `"empty"`.)

```python
from dataxapi import DataXConnectionError, DataXError

try:
    client.call("x_posts_search_v1", {"query": "OpenAI"})
except DataXError as error:
    print(error.status, error.code, error.request_id, error.charge_status)
except DataXConnectionError as error:
    print("retry later with", error.idempotency_key)
```

`DataXPaginationError` is raised when a page iterator sees a repeated cursor. `ExactApiClient`, `ExactApiError`, `ExactApiConnectionError` and `ExactApiPaginationError` remain as deprecated aliases of these classes.

## Upgrading from 0.2.x

0.3.0 renames the classes (old names still work), raises the default timeout from 10 to 60 seconds, polls `request_in_progress` with the same key, and stops retrying errors that a retry would only repeat. See `CHANGELOG.md` in the source distribution and the [upgrade notes](https://dataxapi.com/en/docs/sdks/#upgrade).

## Links

- Docs: <https://dataxapi.com/en/docs/> (中文：<https://dataxapi.com/zh/docs/>)
- SDK guide: <https://dataxapi.com/en/docs/sdks/>
- Upgrade notes: <https://dataxapi.com/en/docs/sdks/#upgrade>
- Errors: <https://dataxapi.com/en/docs/errors/>
- API catalog and prices: <https://dataxapi.com/en/apis/>
- OpenAPI: <https://dataxapi.com/openapi.json>
- MCP server for AI agents: <https://dataxapi.com/en/docs/mcp/>

## 中文说明

`dataxapi` 是 DataXAPI 的 Python SDK：用一个 API Key、一个人民币余额按次调用各平台的公开数据接口。

- 安装：`pip install dataxapi`（Python 3.11+，无第三方依赖）。
- 用法：`DataXClient("https://api.dataxapi.com", api_key)`，再用 `client.call("<operationId>", 参数, idempotency_key=...)` 调用任意接口。
- 重试：同一个逻辑调用复用同一个 `idempotency_key`，重试不会重复执行或扣费；SDK 自动重试 429 和可重试的 5xx，遇到 `request_in_progress` 会用同一个 Key 等待最多约 90 秒；`upstream_failed`、`no_results`、`not_found` 等确定性错误不自动重试。
- 默认每次尝试超时 60 秒，`max_retries` 默认 2。
- 文档：<https://dataxapi.com/zh/docs/>，SDK 说明：<https://dataxapi.com/zh/docs/sdks/>。
- 从 0.2.x 升级：旧名称仍可用，默认超时由 10 秒改为 60 秒，重试规则有调整，见源码包中的 `CHANGELOG.md` 和 <https://dataxapi.com/zh/docs/sdks/#upgrade>。

## License

MIT
