> **Источник:** https://python-all.ru/3.6/distutils/packageindex.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# 6. Python Package Index (PyPI)

[Python Package Index (PyPI)](https://python-all.ru/3.6/distutils/packageindex.html) хранит [метаданные](https://python-all.ru/3.6/distutils/setupscript.html#meta-data), описывающие дистрибутивы, собранные с помощью distutils, а также данные пакетов, такие как файлы дистрибутивов, если автор пакета пожелает.

Distutils предоставляет команды **register** и **upload** для отправки метаданных и файлов дистрибутивов в PyPI соответственно. См. [Distutils commands](https://python-all.ru/3.6/distutils/packageindex.html#package-commands) для получения информации об этих командах.

## 6.1. Обзор PyPI

PyPI позволяет отправлять в индекс любое количество версий вашего дистрибутива. Если вы измените метаданные для определённой версии, вы можете отправить их снова, и индекс будет обновлён.

PyPI хранит запись для каждой комбинации (имя, версия). Первый пользователь, отправивший информацию для данного имени, назначается владельцем этого имени. Изменения можно отправлять через команду **register** или через веб-интерфейс. Владельцы могут назначать других пользователей владельцами или сопровождающими. Сопровождающие могут редактировать информацию о пакете, но не могут назначать новых владельцев или сопровождающих.

По умолчанию PyPI отображает только самую новую версию данного пакета. Веб-интерфейс позволяет изменить это поведение по умолчанию и вручную выбрать, какие версии отображать, а какие скрывать.

Для каждой версии PyPI отображает домашнюю страницу. Домашняя страница создаётся из `long_description`, который можно отправить с помощью команды **register**. См. [PyPI package display](https://python-all.ru/3.6/distutils/packageindex.html#package-display) для получения дополнительной информации.

## 6.2. Команды Distutils

Distutils предоставляет две команды для отправки данных пакетов в PyPI: команда [register](https://python-all.ru/3.6/distutils/packageindex.html#package-register) для отправки метаданных в PyPI и команда [upload](https://python-all.ru/3.6/distutils/packageindex.html#package-upload) для отправки файлов дистрибутивов. Обе команды читают конфигурационные данные из специального файла, называемого [.pypirc-файл](https://python-all.ru/3.6/distutils/packageindex.html#pypirc).

### 6.2.1. Команда `register`

Команда distutils **register** используется для отправки метаданных вашего дистрибутива на сервер индекса. Она вызывается следующим образом:

```python
python setup.py register
```

Distutils ответит следующим приглашением:

```python
running register
We need to know who you are, so please choose either:
    1. use your existing login,
    2. register as a new user,
    3. have the server generate a new password for you (and email it to you), or
    4. quit
Your selection [default 1]:
```

Примечание: если ваше имя пользователя и пароль сохранены локально, вы не увидите это меню. Также обратитесь к [.pypirc-файл](https://python-all.ru/3.6/distutils/packageindex.html#pypirc), чтобы узнать, как хранить свои учётные данные в файле `.pypirc`.

Если вы ещё не зарегистрированы в PyPI, вам необходимо сделать это сейчас. Следует выбрать вариант 2 и ввести свои данные по запросу. Вскоре после отправки данных вы получите электронное письмо, которое будет использовано для подтверждения регистрации.

После регистрации вы можете выбрать вариант 1 из меню. Вас попросят ввести имя пользователя и пароль PyPI, а затем **register** отправит ваши метаданные в индекс.

См. [Дополнительные параметры команды](https://python-all.ru/3.6/distutils/packageindex.html#package-cmdoptions) для параметров команды **register**.

### 6.2.2. Команда `upload`

Команда distutils **upload** отправляет файлы дистрибутивов в PyPI.

Команда вызывается сразу после сборки одного или нескольких файлов дистрибутивов. Например, команда

```python
python setup.py sdist bdist_wininst upload
```

приведёт к загрузке исходного дистрибутива и установщика Windows в PyPI. Обратите внимание, что они будут загружены, даже если были собраны с помощью более раннего вызова `setup.py`, но будут загружены только те дистрибутивы, которые указаны в командной строке для вызова, включающего команду **upload**.

Если команда **register** была ранее вызвана в той же команде, и пароль был введён в приглашении, **upload** повторно использует введённый пароль. Это полезно, если вы не хотите хранить пароль в открытом виде в файле `.pypirc`.

Вы можете использовать параметр `--sign`, чтобы указать **upload** подписывать каждый загруженный файл с помощью GPG (GNU Privacy Guard). Программа **gpg** должна быть доступна для выполнения в системе `PATH`. Вы также можете указать, какой ключ использовать для подписи, с помощью параметра `--identity=name`.

См. [Дополнительные параметры команды](https://python-all.ru/3.6/distutils/packageindex.html#package-cmdoptions) для дополнительных параметров команды **upload**.

### 6.2.3. Дополнительные параметры команды

В этом разделе описаны параметры, общие для команд **register** и **upload**.

Параметр `--repository` или `-r` позволяет указать сервер PyPI, отличный от сервера по умолчанию. Например:

```python
python setup.py sdist bdist_wininst upload -r https://example.com/pypi
```

Для удобства вместо URL можно использовать имя, если файл `.pypirc` настроен соответствующим образом. Например:

```python
python setup.py register -r other
```

См. [.pypirc-файл](https://python-all.ru/3.6/distutils/packageindex.html#pypirc) для получения дополнительной информации об определении альтернативных серверов.

Параметр `--show-response` отображает полный текст ответа от сервера PyPI, что полезно при отладке проблем с регистрацией и загрузкой.

### 6.2.4. Файл `.pypirc`

Команды **register** и **upload** обе проверяют наличие файла `.pypirc` по пути `$HOME/.pypirc`. Если такой файл существует, команда использует имя пользователя, пароль и URL репозитория, указанные в нём. Формат файла `.pypirc` выглядит так:

```ini
[distutils]
index-servers =
    pypi

[pypi]
repository: <repository-url>
username: <username>
password: <password>
```

В разделе *distutils* определяется переменная *index-servers*, в которой перечисляются имена всех разделов, описывающих репозиторий.

Каждый раздел, описывающий репозиторий, задаёт три переменные:

- ***repository* – задаёт URL сервера PyPI. По умолчанию**

  `https://upload.pypi.org/legacy/`.
- *username* – зарегистрированное имя пользователя на сервере PyPI.
- ***password* – пароль для аутентификации. Если опущен, пользователю**

  будет предложено ввести его при необходимости.

Если требуется определить другой сервер, можно создать новый раздел и указать его в переменной *index-servers*:

```ini
[distutils]
index-servers =
    pypi
    other

[pypi]
repository: <repository-url>
username: <username>
password: <password>

[other]
repository: https://example.com/pypi
username: <username>
password: <password>
```

Это позволяет вызывать команды **register** и **upload** с параметром `--repository`, как описано в разделе [Дополнительные параметры команд](https://python-all.ru/3.6/distutils/packageindex.html#package-cmdoptions).

В частности, можно добавить [PyPI Test Repository](https://python-all.ru/3.6/distutils/packageindex.html) в ваш `.pypirc`, чтобы облегчить тестирование перед первой загрузкой на сам `PyPI`.

## 6.3. Отображение пакета на PyPI

Поле `long_description` играет особую роль на PyPI. Сервер использует его для отображения домашней страницы зарегистрированного пакета.

Если для этого поля используется синтаксис [reStructuredText](https://python-all.ru/3.6/distutils/packageindex.html), PyPI разберёт его и отобразит домашнюю страницу пакета в формате HTML.

Поле `long_description` может быть привязано к текстовому файлу, расположенному в пакете:

```python
from distutils.core import setup

with open('README.txt') as file:
    long_description = file.read()

setup(name='Distutils',
      long_description=long_description)
```

В этом случае `README.txt` – это обычный текстовый файл в формате reStructuredText, находящийся в корне пакета рядом с `setup.py`.

Чтобы избежать регистрации некорректного содержимого reStructuredText, можно воспользоваться программой **rst2html** из пакета `docutils` и проверить `long_description` из командной строки:

```console
$ python setup.py --long-description | rst2html.py > output.html
```

`docutils` выведет предупреждение, если с синтаксисом что-то не так. Поскольку PyPI выполняет дополнительные проверки (например, передавая `--no-raw` в `rst2html.py` в команде выше), успешный запуск команды без предупреждений не гарантирует, что PyPI преобразует содержимое без ошибок.
