Metadata-Version: 2.4
Name: tinet-data-foundry-cli
Version: 0.1.9
Summary: Tinet Data Foundry 取数 CLI（docs / catalog / query / schema）
Author: Tinet
License: MIT
Project-URL: Homepage, https://data-foundry.tinetcloud.com
Project-URL: Documentation, https://data-foundry.tinetcloud.com
Keywords: data-foundry,tinet,cli
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Environment :: Console
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# tinet-data-foundry-cli

Tinet Data Foundry 取数 CLI。包名 `tinet-data-foundry-cli`，命令 **`tdf`**（避开系统磁盘命令 `df`）。

鉴权只用环境变量，**不要**把 AccessKey / SecretKey 写入本地文件。需要 Python **≥ 3.10**。

macOS / Linux 用 Terminal（bash / zsh）。Windows 用 **cmd.exe** 跑下面示例（不要用 PowerShell 传 JSON：`export` 不可用，引号也会被剥掉）。

## macOS / Linux

```bash
pip install -U tinet-data-foundry-cli

export DF_ENDPOINT="https://data-foundry-data-api.tinetcloud.com"
export DF_AK="你的_AccessKey"
export DF_SK="你的_SecretKey"

tdf catalog
tdf schema --dataset "DATASET_ID"
tdf query \
  --dataset "DATASET_ID" \
  --fields "id" \
  --filter '{"op":"eq","field":"id","value":"sample"}' \
  --sort '[{"field":"id","direction":"DESC"}]' \
  --page-no 1 \
  --page-size 10 \
  --enterprise-range NORMAL \
  --visitor '{"dingtalkUserId":"钉钉用户ID"}'
```

`--enterprise-range` 可省略，服务端默认 `NORMAL`（不含注销用户和集团用户）。`ALL` 两者都包含。应用凭证必须传 `--visitor`，与数据集是否配置行级列无关；JSON 里 `username`、`dingtalkUserId`、`dingtalkUserMobile`、`dingtalkUserEmail` 至少填一个。无行级列时仍须传入，但不加企业过滤。个人凭证不要传。

字符串字段可做模糊匹配，`value` 为非空字符串，`%` 和 `_` 按字面匹配：

| op | 含义 | 示例 |
| --- | --- | --- |
| `starts_with` | 右模糊，匹配前缀 | `{"op":"starts_with","field":"name","value":"北京"}` |
| `ends_with` | 左模糊，匹配后缀 | `{"op":"ends_with","field":"name","value":"公司"}` |
| `contains` | 左右模糊 | `{"op":"contains","field":"name","value":"科技"}` |

仅按日分区表必须带分区条件。未传分区字段时，服务端按上海时区补当天闭区间，并在响应 `data.partitionWindow` 里返回实际 `field/from/to`。显式 `between` 不超过 30 天，否则 422 `PARTITION_RANGE_INVALID`。按月、按年分区字段不是必填条件。

ODS 可以查询和过滤 `_source_ds`，值是来源数据源编码。编码清单：

```bash
tdf datasource-codes
tdf datasource-codes --code nboss
```

只筛分区字段（如 `startTime`）时，服务端按同一范围另补 `_df_pt` 裁分区。其他时间字段不补。`_df_pt` 不能作为查询列。响应 `partitionWindow.prunedFrom` / `prunedTo` 是实际裁剪区间。

若 pip 提示 scripts 目录不在 PATH，把该目录加入 PATH，或用 `python3 -m tinet_data_foundry_cli`。

## Windows（cmd.exe）

```bat
pip install -U tinet-data-foundry-cli

set DF_ENDPOINT=https://data-foundry-data-api.tinetcloud.com
set DF_AK=你的_AccessKey
set DF_SK=你的_SecretKey

tdf catalog
tdf schema --dataset "DATASET_ID"
tdf query --dataset "DATASET_ID" --fields "id" --filter "{\"op\":\"eq\",\"field\":\"id\",\"value\":\"sample\"}" --sort "[{\"field\":\"id\",\"direction\":\"DESC\"}]" --page-no 1 --page-size 10 --enterprise-range NORMAL --visitor "{\"dingtalkUserId\":\"钉钉用户ID\"}"
```

环境变量只对当前 cmd 窗口有效。JSON 参数用 `\"` 转义，整条命令写在一行。

公司代理 / 自签证书导致 `CERTIFICATE_VERIFY_FAILED` 时：

```bash
tdf --insecure catalog
tdf catalog --insecure
```

| 命令 | 接口 |
| --- | --- |
| `tdf docs rev` | `GET /docs/credentials/{ak}?format=rev` |
| `tdf docs pull` | 按 `copy.catalog.policy` 只拉取变化的 `part=public` 或 `part=policy` |
| `tdf catalog` | `GET /data-api/v1/catalog` |
| `tdf datasource-codes` | `GET /data-api/v1/datasource-codes` |
| `tdf query` | `POST /data-api/v1/datasets/{id}/query` |
| `tdf schema` | `GET /data-api/v1/datasets/{id}/schema` |

文档站点默认 `https://data-foundry.tinetcloud.com`，可用 `DF_DOCS_BASE` 覆盖。`tdf docs` 只需要 `DF_AK`。缓存位于 `~/.cache/tinet-data-foundry/docs/<AK 哈希>/`，可用 `DF_DOCS_CACHE` 改根目录。stdout 非终端时 `tdf catalog` 改为 JSON。

### 业务 Skill 锁定数据集

`tdf docs pull` 把公共目录与授权策略缓存到本机。业务 Skill 自行检索和阅读字段，不要把 `public.json` 或 `policy.json` 读进上下文：

```bash
tdf docs pull
tdf docs search --query "<检索词>"
tdf docs describe --dataset "DATASET_ID"
```

`search` 默认只返回有表权限的数据集，表名或中文名精确匹配排在前面，最多 20 条。`describe` 只返回该表已授权字段、分区粒度和脱敏规则。需要与网关当前结构核对时再用 `tdf schema --dataset "DATASET_ID"`。不要用不带 `--keyword` 的 `tdf catalog` 拉取整份目录。

DataFoundry 查询 Skill 只执行已经写好的查询。查询体用文件传入，避免 shell 转义：

```bash
tdf query --dataset "DATASET_ID" --body-file query.json
```

签名：`canonical = METHOD + "\n" + PATH + "\n" + TIMESTAMP + "\n" + NONCE + "\n" + hex(SHA256(body))`，`X-DF-Signature = Base64(HMAC-SHA256(canonical, SK))`。GET 的 body 为空字节。PATH 不含域名、不含 query。

## 发布到 PyPI

版本号改 `pyproject.toml` 与 `src/tinet_data_foundry_cli/__init__.py`。

```bash
python -m pip install -U build twine
python -m build
python -m twine check dist/*
python -m twine upload --repository testpypi dist/*
python -m twine upload dist/*
```

已发布版本号不可覆盖。
