> ## Documentation Index
> Fetch the complete documentation index at: https://docs.siflow.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用 Python SDK 管理通用服务

> 使用人工智能平台 Python SDK 创建、查询、更新、启停、扩缩容、查看 Pod、查询日志和灰度发布通用服务。

Python SDK 可用于将通用服务接入自动化发布流程。使用本文示例前，请先完成 [Python SDK 快速开始](./python-sdk-quickstart)，并准备服务镜像、资源池、实例规格、端口、启动命令和访问方式等配置。

## 创建通用服务

以下示例创建一个单工作负载通用服务，并配置端口、网关、鉴权、自定义指标和 Volume 挂载。

```python theme={null}
from siflow import SiFlow
from siflow.types.generalsvc import (
    CreateGeneralsvcRequest,
    CustomMetricsConfig,
    HostItem,
    Image,
    Instance,
    Volume,
    Workload,
)

client = SiFlow(region="cn-beijing", cluster="auriga")

res = client.generalsvc.create(
    request=CreateGeneralsvcRequest(
        name="sdk-general-demo",
        ports=[8000],
        useBaseUrl=False,
        authEnabled=True,
        customMetrics=CustomMetricsConfig(
            enabled=True,
            path="/metrics",
            port=8000,
        ),
        hosts=[
            HostItem(
                host="<SERVICE_DOMAIN>",
                type="dedicated",
                paths={"8000": "/sdk-general-demo"},
            )
        ],
        workloads=[
            Workload(
                versionName="v1",
                version="v1",
                replicas=1,
                resourcePool="<RESOURCE_POOL>",
                instances=[
                    Instance(name="sci.c23-2", countPerPod=1),
                ],
                image=Image(
                    url="registry-cn-shanghai.siflow.cn/ai-infra/custom-app:v1.0.0-a1b2c3d",
                ),
                cmd="python app.py --port 8000",
                volumes=[
                    Volume(
                        volumeId=230,
                        mountDir="/volume/models",
                        subPath="models",
                        readOnly=True,
                    ),
                    Volume(
                        volumeId=231,
                        mountDir="/volume/data",
                    ),
                ],
                extraTerminationGraceSeconds=60,
            )
        ],
    ),
)

print(res)
```

创建参数如下：

| 参数              | 说明                                                      |
| --------------- | ------------------------------------------------------- |
| `name`          | 通用服务名称。                                                 |
| `ports`         | 对外暴露端口。                                                 |
| `useBaseUrl`    | 是否使用 base URL。开启后，平台按 base URL 组织访问路径；关闭时按网关配置访问。       |
| `authEnabled`   | 是否开启访问鉴权。                                               |
| `customMetrics` | 自定义指标采集配置。`path` 和 `port` 需要与服务实际暴露的 Prometheus 指标地址一致。 |
| `hosts`         | 网关访问配置。`type`、`host` 和 `paths` 需要按目标网关填写。               |
| `workloads`     | 工作负载配置。单服务可包含一个或多个工作负载版本。                               |

`Workload` 常用字段如下：

| 参数                                 | 说明                                                      |
| ---------------------------------- | ------------------------------------------------------- |
| `versionName` / `version`          | 工作负载版本名称和版本号。                                           |
| `replicas`                         | 副本数。                                                    |
| `resourcePool`                     | 工作负载使用的资源池。                                             |
| `instances`                        | 每个 Pod 使用的实例规格和数量。                                      |
| `image`                            | 工作负载镜像。使用 `url` 时，镜像名称、版本和类型不会用于定位镜像。                   |
| `volumes`                          | Volume 挂载配置。挂载目录级 Volume 时，需要配置 `subPath` 和 `readOnly`。 |
| `cmd`                              | 启动命令。                                                   |
| `env`                              | 环境变量。                                                   |
| `livenessProbe` / `readinessProbe` | 存活探针和就绪探针。                                              |
| `extraTerminationGraceSeconds`     | 优雅终止额外等待时间。省略或传 `0` 时使用默认终止等待时间。                        |

## 查询通用服务

查询列表：

```python theme={null}
page = client.generalsvc.list(
    page=1,
    page_size=10,
    name="sdk-general-demo",
    status=["Running"],
    resource_pool=["<RESOURCE_POOL>"],
    sort_by="createTime",
    sort_order="desc",
)

print(page.total)
for item in page.rows:
    print(item.uuid, item.name, item.status)
```

查询详情：

```python theme={null}
detail = client.generalsvc.get(id="<GENERAL_SERVICE_UUID>")
print(detail)
```

列表接口支持按 `name`、`status`、`resource_pool`、`generalsvc_uuid`、`sort_by`、`sort_order` 和 `show_all` 等参数过滤。

## 更新服务配置

更新服务配置时，建议只修改目标字段。涉及网关配置时，优先使用 `patch_hosts`，避免因全量更新遗漏已有网关配置。

```python theme={null}
from siflow.types.generalsvc import HostItem, PatchGeneralsvcHostsRequest, UpdateGeneralsvcRequest

client.generalsvc.update(
    id="<GENERAL_SERVICE_UUID>",
    request=UpdateGeneralsvcRequest(authEnabled=False),
)

client.generalsvc.patch_hosts(
    id="<GENERAL_SERVICE_UUID>",
    request=PatchGeneralsvcHostsRequest(
        hosts=[
            HostItem(
                host="<SERVICE_DOMAIN>",
                type="dedicated",
                paths={"8000": "/sdk-general-demo"},
            )
        ]
    ),
)
```

## 启停、重启和扩缩容

根据目标选择对应操作，不要在同一次变更中连续执行启停和重启：

```python theme={null}
client.generalsvc.offline(id="<GENERAL_SERVICE_UUID>")
```

```python theme={null}
client.generalsvc.online(id="<GENERAL_SERVICE_UUID>")
```

```python theme={null}
client.generalsvc.restart(id="<GENERAL_SERVICE_UUID>")
```

扩缩容时，按工作负载版本设置目标副本数：

```python theme={null}
client.generalsvc.scale(
    id="<GENERAL_SERVICE_UUID>",
    scale={"v1": 2},
)
```

下线会影响服务访问；扩缩容会改变资源占用。执行前请确认业务流量、资源配额和变更窗口。

## 公开和分享服务

```python theme={null}
client.generalsvc.set_visibility(
    id="<GENERAL_SERVICE_UUID>",
    is_public=False,
)

# 全量覆盖分享名单。
client.generalsvc.share(
    id="<GENERAL_SERVICE_UUID>",
    share_users=["alice", "bob"],
)
```

增量追加用户：

```python theme={null}
# 增量追加用户。
client.generalsvc.share_add_users(
    id="<GENERAL_SERVICE_UUID>",
    users_to_add=["carol"],
)
```

增量删除用户：

```python theme={null}
# 增量删除用户。
client.generalsvc.share_delete_users(
    id="<GENERAL_SERVICE_UUID>",
    users_to_remove=["bob"],
)
```

`share` 会把服务分享名单替换为传入列表；`share_add_users` 和 `share_delete_users` 用于在现有名单基础上追加或移除用户。

## 管理定时策略、Deployment 和 Pod

配置定时策略：

```python theme={null}
client.generalsvc.cronjob(
    id="<GENERAL_SERVICE_UUID>",
    job_type="restart",
    enable=True,
    action_time="0 */3 * * *",
)
```

查询和管理 Deployment：

```python theme={null}
deployments = client.generalsvc.list_deployments(
    general_svc_uuid="<GENERAL_SERVICE_UUID>",
)

for deployment in deployments:
    print(deployment)
```

需要重启指定 Deployment 时：

```python theme={null}
client.generalsvc.restart_deployment(
    workload_name="sdk-general-demo-v1",
    general_svc_uuid="<GENERAL_SERVICE_UUID>",
)
```

确认不再需要指定 Deployment 后再删除：

```python theme={null}
client.generalsvc.delete_deployment(
    workload_name="sdk-general-demo-v1",
    general_svc_uuid="<GENERAL_SERVICE_UUID>",
)
```

查询和管理 Pod：

```python theme={null}
pods = client.generalsvc.list_pods(
    id="<GENERAL_SERVICE_UUID>",
    page=1,
    page_size=10,
    status=["Running"],
    sort_by="podName",
    sort_order="asc",
)

for pod in pods.rows:
    print(pod)
```

需要重启指定 Pod 时：

```python theme={null}
client.generalsvc.restart_pod(
    id="<GENERAL_SERVICE_UUID>",
    pod_name="<POD_NAME>",
)

pod_statuses = client.generalsvc.list_pod_statuses(id="<GENERAL_SERVICE_UUID>")
service_statuses = client.generalsvc.list_statuses()
```

查询看板汇总：

```python theme={null}
dashboard = client.generalsvc.dashboard(
    details_limit=5,
    resource_pool="<RESOURCE_POOL>",
)

print(dashboard)
```

## 查询日志

通用服务继承 SDK 的日志能力，可按服务 ID 查询或下载日志。

```python theme={null}
logs = client.generalsvc.query_logs(
    "<GENERAL_SERVICE_UUID>",
    limit=100,
    sort_order="desc",
)

file_path = client.generalsvc.download_logs(
    "<GENERAL_SERVICE_UUID>",
    file_path="./generalsvc.log",
)
```

也可以直接查询单个 Pod 容器日志：

```python theme={null}
resp = client.generalsvc.get_pod_container_logs(
    pod_name="<POD_NAME>",
    general_svc_uuid="<GENERAL_SERVICE_UUID>",
    container_name="main",
    lines=200,
    previous=False,
)

print(resp)
```

更多日志分页、下载和系统日志示例，请参考 [使用 Python SDK 查询日志和指标](./query-logs-and-metrics-with-python-sdk)。

## 灰度发布和版本回滚

灰度发布适合在保留稳定版本的同时验证候选配置。以下示例按“发起灰度、查看状态、调整流量、查看差异、完成或回滚”的顺序组织。

### 发起灰度

```python theme={null}
client.generalsvc.canary_publish(
    id="<GENERAL_SERVICE_UUID>",
    request={
        "mode": "advanced",
        "workloads": [
            {
                "version": "v1",
                "replicas": 2,
                "image": {
                    "url": "registry-cn-shanghai.siflow.cn/ai-infra/custom-app:v1.0.1-b2c3d4e",
                },
                "cmd": "python app.py --port 8000",
            }
        ],
        "rollout": {
            "initialWeight": 0,
            "initialTotalReplicas": 2,
            "initialNewReplicas": 1,
            "surgeStrategy": "extra",
        },
    },
)
```

`workloads` 应只填写需要变更的候选配置；未变更字段按基线配置继承。

### 查询和调整灰度

```python theme={null}
rollout = client.generalsvc.get_rollout(id="<GENERAL_SERVICE_UUID>")
print(rollout)

client.generalsvc.patch_rollout(
    id="<GENERAL_SERVICE_UUID>",
    request={
        "weight": 50,
        "totalReplicas": 3,
        "newReplicas": 2,
        "surgeStrategy": "extra",
    },
)

diff = client.generalsvc.get_rollout_diff(id="<GENERAL_SERVICE_UUID>")
print(diff)
```

### 完成、放弃或回滚

```python theme={null}
# 灰度成功后完成发布。
client.generalsvc.complete_rollout(id="<GENERAL_SERVICE_UUID>")
```

`complete_rollout()` 提交全量发布后，需要等待灰度状态变为 `completed`，再执行收尾：

```python theme={null}
rollout = client.generalsvc.get_rollout(id="<GENERAL_SERVICE_UUID>")
print(rollout.state)

if rollout.state == "completed":
    client.generalsvc.finalize_rollout(id="<GENERAL_SERVICE_UUID>")
```

灰度异常时，放弃本次灰度并回到稳定版本：

```python theme={null}
client.generalsvc.rollback_rollout(id="<GENERAL_SERVICE_UUID>")
```

需要回滚到历史版本时，先查询版本，再选择目标版本：

```python theme={null}
versions = client.generalsvc.list_versions(
    id="<GENERAL_SERVICE_UUID>",
    page=1,
    page_size=10,
)

client.generalsvc.rollback_version(
    id="<GENERAL_SERVICE_UUID>",
    version="<VERSION_ID>",
)
```

灰度发布会同时影响服务流量和资源占用。执行前，请确认候选版本配置、资源配额和回滚路径。

## 删除通用服务

```python theme={null}
res = client.generalsvc.delete(id="<GENERAL_SERVICE_UUID>")
print(res)
```

删除会影响服务可用性。执行前，请确认该服务不再承载线上流量，并已保存需要保留的配置或数据。

## 相关文档

* [Python SDK 快速开始](./python-sdk-quickstart)
* [使用 Python SDK 查询日志和指标](./query-logs-and-metrics-with-python-sdk)
* [创建通用服务](../inference/create-general-inference-services)
* [管理通用服务](../inference/manage-general-inference-services)
