---
url: /zh/artifact/pypi.md
description: |
  介绍如何配置和使用 CNB PyPI 制品库， 用于存储和分发 Python 软件包， 包括凭证配置、包的上传和安装，以及在流水线中集成的方法。
---
PyPI 制品库用于存储和分发 Python 软件包，支持开发者上传、管理和安装各类 Python 第三方库和工具。

## 前置准备

1. [创建制品库](./intro.md#创建制品库)

2. [获取制品库的地址](./intro.md#获取制品库的地址)

3. [创建令牌](./intro.md#创建访问令牌)

## 本地开发

### 配置拉取凭据

* 方案 1：在 ~/.pip/pip.conf（MacOS/Linux）或者 %HOME%\pip\pip.ini（Windows）中添加 pip 源配置：

```INI
[global]
# YOUR_TOKEN: 访问令牌的 password; REPO_URL: 制品库地址
# 示例: index-url = https://cnb:<YOUR_TOKEN>@pypi.cnbprod.alpha.qq.com/cnb/pypi-repo/-/packages/simple
index-url = https://cnb:<YOUR_TOKEN>@<REPO_URL>
```

* 方案 2：也可以使用命令行设置：

```shell
# YOUR_TOKEN: 访问令牌的 password; REPO_URL: 制品库地址
# 示例: pip config set global.index-url
#   https://cnb:<YOUR_TOKEN>@pypi.cnbprod.alpha.qq.com/cnb/pypi-repo/-/packages/simple
pip config set global.index-url https://cnb:<YOUR_TOKEN>@<REPO_URL>
```

### 配置推送凭据

#### twine 配置

请在 ~/.pypirc 文件中添加以下配置

```INI
[distutils]
index-servers =
  cnb-pypi-repo
[cnb-pypi-repo]
# 制品库地址
repository: <REPO_URL>
username: cnb
# 访问令牌的 password
password: <YOUR_TOKEN>
```

示例：

```INI
[distutils]
index-servers =
  cnb-pypi-repo
[cnb-pypi-repo]
repository: https://pypi.cnbprod.alpha.qq.com/cnb/pypi-repo/-/packages/simple
username: cnb
password: "<YOUR_TOKEN>"
```

#### poetry 配置

运行以下命令

```shell
poetry config http-basic.cnb-pypi-repo cnb <YOUR_TOKEN> # 访问令牌的 password
poetry config repositories.cnb-pypi-repo <REPO_URL> # 制品库地址
```

示例：

```shell
poetry config http-basic.cnb-pypi-repo cnb <YOUR_TOKEN>
poetry config repositories.cnb-pypi-repo https://pypi.cnbprod.alpha.qq.com/cnb/pypi-repo/-/packages/simple
```

### 拉取制品

```shell
#示例1: pip install requests
#示例2: 拉取指定版本 pip install requests==2.30.1
pip install <PACKAGE_NAME>

# 示例, 临时源拉取
#   pip install -i https://cnb:<YOUR_TOKEN>@pypi.cnbprod.alpha.qq.com/cnb/pypi-repo/-/packages/simple requests
pip install -i https://cnb:<YOUR_TOKEN>@<REPO_URL> <PACKAGE_NAME>

```

### 编译及推送制品

#### twine

```shell
python -m build
twine upload -r cnb-pypi-repo dist/*
```

#### poetry

```shell
poetry build
poetry publish -r cnb-pypi-repo
```

## 云原生构建

云原生构建使用令牌有两种方式，参考 [云原生构建、云原生开发中使用令牌](./intro.md#在云原生构建，云原生开发中使用令牌)。

### 拉取制品

使用 `CNB_TOKEN` 配置 pip 源并安装包：

```yaml title=".cnb.yml"
main:
  push:
    - docker:
        image: docker.cnb.cool/examples/language/python-3:latest
      stages:
        - name: 拉取制品
          script:
            - pip config set global.index-url
              https://cnb:${CNB_TOKEN}@pypi.cnbprod.alpha.qq.com/cnb/pypi-repo/-/packages/simple
            - pip install requests
```

### 推送制品

核心配置：在 `tag_push` 事件中更新版本号并发布。

#### twine

```yaml title=".cnb.yml"
$:
  tag_push:
    - docker:
        image: docker.cnb.cool/examples/language/python-3:latest
      stages:
        - name: 打包 & 上传至仓库
          script:
            - export TWINE_USERNAME=${CNB_TOKEN_USER_NAME}
            - export TWINE_PASSWORD=${CNB_TOKEN}
            - export TWINE_REPOSITORY_URL=https://pypi.cnbprod.alpha.qq.com/cnb/pypi-repo/-/packages/simple
            - python -m build
            - twine upload dist/*
```

#### poetry

```yaml title=".cnb.yml"
$:
  tag_push:
    - docker:
        image: docker.cnb.cool/examples/language/python-3:latest
      stages:
        - name: 打包 & 上传至仓库
          script:
            - export POETRY_HTTP_BASIC_CNB_PYPI_REPO_USERNAME=${CNB_TOKEN_USER_NAME}
            - export POETRY_HTTP_BASIC_CNB_PYPI_REPO_PASSWORD=${CNB_TOKEN}
            - poetry config repositories.cnb-pypi-repo https://pypi.cnbprod.alpha.qq.com/cnb/pypi-repo/-/packages/simple
            - poetry build
            - poetry publish -r cnb-pypi-repo
```

如使用密钥仓库文件，将 `${CNB_TOKEN}` 等替换为 `${USER_NAME}`/`${PASS_WORD}`。

## 云原生开发

云原生开发使用令牌有两种方式，参考 [云原生构建、云原生开发中使用令牌](./intro.md#在云原生构建，云原生开发中使用令牌)。

### 前置准备

在 `.cnb.yml` 文件中添加以下配置：

```yaml title=".cnb.yml"
$:
  vscode:
    - docker:
        image: docker.cnb.cool/examples/language/python-3:latest
      services:
        - vscode
        - docker
```

### 配置拉取凭据

云原生开发终端中输入以下命令：

```shell
# 方式一：使用内置 CNB_TOKEN（推荐）
pip config set global.index-url https://cnb:${CNB_TOKEN}@pypi.cnbprod.alpha.qq.com/cnb/pypi-repo/-/packages/simple
# 方式二：使用密钥仓库文件
# pip config set global.index-url
#   https://${USER_NAME}:${PASS_WORD}@pypi.cnbprod.alpha.qq.com/cnb/pypi-repo/-/packages/simple
```

### 配置推送凭据

云原生开发终端中输入以下命令：

#### twine

```shell
# 方式一：使用内置 CNB_TOKEN（推荐）
export TWINE_USERNAME=${CNB_TOKEN_USER_NAME}
export TWINE_PASSWORD="${CNB_TOKEN}"
export TWINE_REPOSITORY_URL=https://pypi.cnbprod.alpha.qq.com/cnb/pypi-repo/-/packages/simple
# 方式二：使用密钥仓库文件
# export TWINE_USERNAME="${USER_NAME}"
# export TWINE_PASSWORD="${PASS_WORD}"
# export TWINE_REPOSITORY_URL=https://pypi.cnbprod.alpha.qq.com/cnb/pypi-repo/-/packages/simple
```

#### poetry

```shell
# 方式一：使用内置 CNB_TOKEN（推荐）
export POETRY_HTTP_BASIC_CNB_PYPI_REPO_USERNAME=${CNB_TOKEN_USER_NAME}
export POETRY_HTTP_BASIC_CNB_PYPI_REPO_PASSWORD="${CNB_TOKEN}"
poetry config repositories.cnb-pypi-repo https://pypi.cnbprod.alpha.qq.com/cnb/pypi-repo/-/packages/simple
# 方式二：使用密钥仓库文件
# export POETRY_HTTP_BASIC_CNB_PYPI_REPO_USERNAME="${USER_NAME}"
# export POETRY_HTTP_BASIC_CNB_PYPI_REPO_PASSWORD="${PASS_WORD}"
# poetry config repositories.cnb-pypi-repo https://pypi.cnbprod.alpha.qq.com/cnb/pypi-repo/-/packages/simple
```

### 拉取制品

```shell
# 示例1: pip install requests
# 示例2: pip install requests==2.30.1
# 示例3: 指定临时源拉取
pip install -i https://cnb:${CNB_TOKEN}@pypi.cnbprod.alpha.qq.com/cnb/pypi-repo/-/packages/simple requests
```

### 编译及推送制品

#### twine

```shell
python -m build
twine upload -r cnb-pypi-repo dist/*
```

#### poetry

```shell
poetry build
poetry publish -r cnb-pypi-repo
```

## FAQ

### Q: 为什么上传时会报 409 错误？

A: 制品包名称和版本已存在，请将制品仓库的「版本覆盖策略」设为「允许覆盖已有版本」，或更改包版本后重新上传。

### Q: 为什么上传时会报 400 错误？

A: 通常是制品文件名不符合 PyPI 规范，请检查并处理后重新上传。

### Q: CNB PyPI 制品库支持哪些制品格式？

A: 目前仅支持 wheel 和 sdist 两种格式，egg、exe 等旧格式会被拒绝上传。

## 更多用法

更多 PyPI 用法，请查阅 [PyPI 官方文档](https://pypi.org/)。
