Вместо предисловия
Каждый день миллионы разработчиков набирают:
pip install <название пакета>
Через несколько секунд пакет установлен. Это настолько привычно, что воспринимается как свойство языка. Но за этой командой стоит инфраструктура, у которой есть большая история. И конкретные люди, которые её построили.
pip install состоит из двух частей. pip — это инструмент-установщик, он появился в 2008 году. Но куда он обращается? К реестру пакетов Python Package Index или сокращённо PyPI. Без PyPI команда pip install была бы как поисковик без интернета: инструмент есть, искать негде.
PyPI — централизованный каталог Python-пакетов. Любой разработчик может опубликовать там свою библиотеку, и она станет доступна всем остальным одной командой. Сегодня в PyPI более 865 тысяч проектов общим весом 36 терабайт. Он работает круглосуточно, обслуживает миллиарды запросов, и, возможно, большинство людей, которые им пользуются, никогда не задумывались о том, кто и когда его создал.
Его создал Ричард Джонс (Richard Jones). В октябре 2002-го, в электричке, по дороге на работу в Мельбурн.
Хранилище Парнаса
До PyPI главным ориентиром для Python-разработчика служил Vaults of Parnassus ("Хранилище Парнаса", в честь обители муз в греческой мифологии) — сайт, который вручную поддерживал список ссылок на пакеты. Никакой автоматизации: автор находил пакет, добавлял ссылку и описание. К середине 2000-х там накопилось более двух тысяч записей, и у сайта была своя лояльная аудитория, люди ценили его за удобный интерфейс и полноту.
Пакеты при этом никуда не переезжали: они по-прежнему жили на личных страницах авторов, FTP-серверах и в архивах рассылок. Хранилище Парнаса служило навигатором. Хочешь поставить библиотеку? Найди в каталоге, перейди на сайт автора, скачай, разберись сам с установкой.
В августе 2005 года "Хранилище" перестало обновляться. В декабре того же года на форуме появился встревоженный пост: "Что случилось с Vaults? Это был мой любимый ресурс!". Ответ был лаконичным: "Все теперь пользуются cheeseshop (неофициальное название PyPI)". Но не все были рады. Тот же пользователь возражал: в индексе PyPI тогда было всего 673 пакета против двух тысяч у Парнаса, интерфейс хуже, поиска не видно. Эта дискуссия состоялась спустя почти 3 года после запуска PyPI. Как видно, переход был небыстрым и для некоторых достаточно болезненным.
Но вернемся в 2002-й...
Предпосылки создания PyPI
Набор модулей Distutils, появившийся в Python 1.6, уже умел собирать метаданные о пакете: имя, версию, автора, лицензию. Но дальше этого дело не шло: метаданные упаковывались вместе с дистрибутивом и никуда не отправлялись. Инструмент для сбора информации был. Стандартного способа передать её в каталог не существовало.
Мотивы создания PyPI его автор, австралийский разработчик Ричард Джонс, описал в PEP 301 так:
Программистам на Python давно нужен простой способ обнаруживать существующие модули. Можно утверждать, что наличие подобных каталогов в других языках стало значительным вкладом в их популярность.
Говоря о других языках, Джонс имел в виду прежде всего Perl. С 1995 года у этого языка был CPAN — Comprehensive Perl Archive Network, централизованный репозиторий модулей для языка программирования. Тысячи пакетов, единый инструмент установки, стандартизированные метаданные. Сообщество Perl росло в том числе потому, что найти и поставить чужой модуль было просто.
Python к 2002 году был не менее мощным языком, но инфраструктуры такого уровня не имел. Джонс решил это исправить.
Электричка в Мельбурн
22 октября 2002 года Джонс ехал в электричке на работу в Мельбурн и писал код. В этой поездке он создал прототип PyPI: база данных на SQLite, HTTP-интерфейс для приёма метаданных, реализация команды setup.py register для отправки информации о пакете в индекс. В тот же день прототип появился онлайн.
Идея в том, чтобы сразу после
setup.py sdistлюди запускалиsetup.py register— и метаданные дистрибутива регистрировались на поисковом сервере. Работы ещё немного осталось, но основа есть. Я поставлю веб-интерфейс на mechanicalcat как тестовый запуск. Жду обратной связи. Это моя попытка просто взять и сделать — чтобы сдвинуть с места репозиторий Python-модулей. Не думаю сейчас о следующем шаге — загрузке самих дистрибутивов. Не думаю. Надо просто выпустить хоть что-то...
"mechanicalcat", упомянутый в цитате, — это личный сайт Джонса.
Выход PEP 301 и помощь Эндрю Кучлинга
Свою идею Джонс оформил в виде PEP (Python Enhancement Proposal), официального документа с описанием предлагаемых изменений в язык или экосистему. Это стандартный путь для любого значимого нововведения в Python: сначала PEP, потом обсуждение сообществом, потом реализация. PEP описывал архитектуру индекса, схему базы данных, формат метаданных и принципы работы команды register.
1 ноября 2002 года PEP ушёл редакторам. В тот же день Джонс завёл проект на SourceForge, крупнейшей на тот момент платформе для хостинга открытого кода, и там же придумал название: "Python Packages Index, aka pypi".
На следующий день прототип PyPI переехал с личного сервера Джонса на машину того самого Эндрю Кучлинга, которому была посвящена предыдущая статья цикла. Такое вот питонячье братство.
8 ноября PEP, написанный Джонсом, получил номер 301 (PEP 301 "Package Index and Metadata for Distutils"). В конце документа Джонс не забыл поблагодарить товарища:
A.M. Kuchling за поддержку, включая хостинг второго прототипа.
17 января 2003 года Джонс написал:
Будущее PyPI...
Что ж, люди начали активно замечать мои усилия с PyPI. И комментировать — в целом позитивно. Критических багов пока нет. Некоторые... начали говорить о возможности создать Python-аналог CPAN. Просто хочу дать понять, как я сам смотрю на этот вопрос. Моей целью с первой версией PyPI было просто сдвинуть дело с места. Как упомянуто в PEP, я намеренно ограничил объём работы тем, что мог разумно реализовать в доступное время и что сообщество готово было принять. Когда выйдет Python 2.3 и мир начнёт пользоваться репозиторием на python.org, я надеюсь, что другие интегрируют PyPI в свои pypan или похожие проекты. Ещё надеюсь, что найдутся добровольцы, которые напишут, например, интерфейс обзора по Trove-классификаторам — чтобы люди могли углубляться в категории и находить то, что им интересно... Код проекта на SourceForge, участникам рад!
Обратите внимание на призыв о помощи с навигацией по Trove-классификатором. Кто же откликнулся на этот призыв? Да, это снова был Эндрю Кучлинг.
Trove-классификаторы — это система тегов для пакетов, позволяющая указать тематику, лицензию, версию Python, операционную систему и другие характеристики. Например: Programming Language :: Python :: 3, License :: OSI Approved :: MIT License. Они появились в PEP 301 и живы до сих пор. Любой, кто публиковал пакет на PyPI, заполнял поле classifiers в setup.py или pyproject.toml. Кучлинг добавил интерфейс навигации по каталогу через эти классификаторы, от общего к частному: выбрать тематику, потом лицензию, потом версию Python и получить отфильтрованный список пакетов.
23 января 2003 года PyPI заработал на сервере python.org. Джонс не торопился объявлять URL, хотел синхронизировать запуск с выходом Python 2.3 alpha 2.
19 февраля 2003 года Python 2.3 alpha 2 вышел. Джонс написал в блоге: "PyPI lives!".
От первого коммита в электричке до официального запуска прошло 4 месяца.
Пай-пай против пай-пай
Март 2005 года, Вашингтон, PyCon. Джонс наконец добрался до конференции и первый раз очно встретился с людьми, с которыми годами общался по почте и в рассылках. Среди них и Эндрю Кучлинг.
Возникла неожиданная проблема. На спринтах в одной комнате сидели две команды: разработчики PyPI, индекса пакетов, и разработчики... PyPy, альтернативного интерпретатора Python. И те, и другие постоянно упоминали свой проект вслух. "Пай-пай" — это про интерпретатор или про индекс?
Джонс добавил в программу специальное пятиминутное выступление с единственной целью: прояснить произношение. Джонс настаивал на произношении "пи-пи" с коротким "и" (it was always intended to be pronounced "pipi" with the short "ih" sound).
30 марта, вернувшись домой в Мельбурн, Джонс написал в блоге: "PyPI нужно новое имя?" И предложил сообществу придумать что-нибудь в духе Монти Пайтона, не аббревиатура. В списке вариантов: "shrub", "shrubbery", "lumberjack", "wafer", "creosote", "grail", "holy grail", "brian"...
Но уже 7 апреля он передумал.
"Я поспрашивал людей, посмотрел на варианты, н�� один не цепляет. PyPI достаточно точно отражает природу того, что мы создали. Не слишком глупо. Коротко. Уже прижилось. Пожалуй, решено: сойдёт. Возможно, потенциал для путаницы был преувеличен из-за близости с PyPy-людьми на спринтах. Произношение на самом деле не проблема... Путаница возникает только когда вы в одной комнате с PyPy-людьми. Даже тогда из контекста обычно понятно, о чём речь, например, 'Твой пакет есть в PyPI?' или 'Возьми XYZ из PyPI'.
И вообще: PyPI появился раньше :)"
Но чтобы точно не было путаницы в произношении на сайте PyPI есть отдельный раздел в FAQ "Как мне произносить PyPI?". И в нем третий вариант произношения. Запомните: "пай-пи-ай" :)
Кстати, на той же конференции Джонс решил давнюю проблему: мигрировал PyPI с SQLite на PostgreSQL. Блокировки базы, которые мучили его несколько лет, остались в прошлом.
Сырная лавка
1 августа 2005 года Джонс написал в блоге: "Now open... The Python Cheese Shop!".
Это было неофициальное название PyPI, которое появилось после PyCon 2005. Официально индекс по-прежнему назывался (и называется!) Python Package Index. Но новый сервер получил адрес cheeseshop.python.org и именно здесь впервые появился полноценный файловый хостинг — то, что было намеренно исключено из PEP 301 три года назад. Джонс снова поблагодарил Кучлинга: тот помог довести всё до ума.
Название "Сырная лавка" отсылает к скетчу Монти Пайтон 1972 года. Покупатель приходит в сырный магазин и один за другим называет сорта сыра. У хозяина нет ни одного. Ирония в том, что PyPI в первые месяцы после запуска тоже был почти пустым каталогом.
Название прижилось мгновенно. В декабре того же года на форуме уже писали просто: "Все теперь пользуются cheeseshop.".
Кстати, редирект с http://cheeseshop.python.org/pypi/ на официальный https://pypi.org/ работает до сих пор.
PEP 439: pip должен идти вместе с Python
К 2013 году прошло пять лет с момента, когда Иан Бикинг создал pip. Установщик пакетов стал стандартом де-факто: любой Python-разработчик знал о нём и пользовался им. Но была одна проблема: pip надо было ставить отдельно. Python установлен, а pip — нет. Для опытного разработчика это мелочь. Для новичка же это становилось первым барьером, который иногда оказывался последним.
Джонс сформулировал это в PEP 439 так:
Крупные Python-проекты, которые делают акцент на низком пороге входа, избегали зависимости от сторонних пакетов именно из-за этого препятствия для новых пользователей. С включением установщика пакетов в стандартную поставку Python барьер для установки дополнительного программного обеспечения значительно снижается. Есть надежда, что это увеличит вероятность того, что Python-проекты будут активнее переиспользовать сторонние библиотеки.
Идея пришла Джонсу на PyCon 2013 в разговоре с разработчиком Джеймсом Беннеттом. Там же, на конференции, он и описал предложение включить в стандартную установку Python небольшой бутстрап-скрипт. При первом вызове pip3 install <пакет> скрипт проверял наличие pip, и если его не было, то молча скачивал и устанавливал. После этого команда выполнялась как обычно. Пользователь мог даже не знать, что произошло какое-то дополнительное действие.
Ключевой принцип PEP 439 был сформулирован одной фразой:
Пользовательский опыт работы с pip не должен требовать от пользователя его установки.
PEP 439 отклонили. Но не потому что идея оказалась плохой, а потому что сообщество приняло более явный механизм, описанный в PEP 453 в том же 2013.
PEP 439, предшественник настоящего PEP, предлагал собственное решение: поставлять вместе с Python фиктивную команду
pip, которая при первом вызове неявно загружала и устанавливала н��стоящий pip, если его ещё не было. Это решение было отклонено как слишком "магическое".
Именно PEP 453 дал нам pip, встроенный в Python начиная с версии 3.4.
Не только PyPI
PyPI — главная, но не единственная заслуга Джонса перед Python-сообществом.
Параллельно с разработкой индекса он руководил разработкой баг-трекера Roundup, который 17 лет был официальным трекером задач Python вплоть до переезда на Гитхаб. В 2005 году основал PyWeek, двухнедельный конкурс по написанию игр на Python, который проводится до сих пор. Участвовал в создании pyglet, кроссплатформенной библиотеки для разработки игр и мультимедийных приложений. Долгие годы организовывал PyCon в Австралии.
В 2018 году PyPI переехал на новый адрес pypi.org и получил современный движок Warehouse. От кода, написанного Джонсом в электричке в 2002 году, там, вероятно, ничего не осталось. Но осталось главное: идея, что у Python должен быть свой каталог. Простой, доступный, с одной командой для регистрации.
