Назад | Перейти на главную страницу

Как управлять Python в ограниченной среде?

Потребность:

Окружающая среда:

Спросите:

Def ценит решения, основанные на аналогичном реальном опыте.

Предположения:

Разъяснения:

Предисловие

В настоящее время существует множество жизнеспособных вариантов, если вы хотите разместить собственный репозиторий PyPI. Доступно множество пакетов, реализующих сервер репозитория PyPI, наиболее примечательными из которых являются:

Есть и другие, более или менее экзотические пакеты вроде PyPICloud который загружает файлы пакетов непосредственно в экземпляр Amazon S3. JFrog's Artifactory также поддерживает обслуживание пакетов Python, хотя и не в бесплатной версии afaik, поэтому это имеет смысл только в том случае, если вы уже платите за лицензию. Вы даже можете создать локальное репозиторий PyPI, не используя ничего, кроме stdlib Python, см. мой ответ на ТАК.

Кроме того, эта тема несколько раз обсуждалась на SO, наиболее популярные вопросы: Как накатить собственный pypi? и как создать локальный собственный индекс репозитория pypi без зеркала? Помните, что первый вопрос довольно старый и содержит в основном устаревшие ответы, а второй - более актуальный.

devpi

В своей работе мы оценивали доступные решения два года назад и придерживаемся devpi поскольку. Разработан теми же людьми, которые стоят за популярным фреймворком для тестирования. pytest и инструмент автоматизации задач CI tox, devpi это универсальный инструмент, который:

  • может размещать несколько репозиториев (называемых индексами), что позволяет группировать доступ к пакетам;
  • по умолчанию действует как зеркало PyPI, его можно отключить по запросу;
  • обеспечивает управление доступом на основе ролей для загрузки пакетов;
  • предлагает дополнительный веб-интерфейс, который можно настроить с помощью шаблонов страниц;
  • предлагает репликацию главного сервера - все реплики автоматически синхронизируют базу пакетов с мастером при изменении;
  • может размещать документацию по пакету (Sphinx);
  • может запускать тестовый запуск при загрузке пакета и отображать результаты тестового запуска, если он подключен к серверу CI, например Jenkins;
  • имеет плагин API для расширения на стороне сервера и клиента CLI (на основе pluggy библиотека; тот же, что использовался для расширения tox или pytest если вы с ними знакомы); вы можете настроить множество вещей, написав свои собственные плагины, от аутентификации до бэкэндов хранилища. Есть также несколько собственных плагинов, доступных на Страница Github.

Самая мощная особенность IMO - это индексы. Индекс определяет набор пакетов, которые могут быть установлены из URL-адреса индекса. Например, представьте себе один devpi экземпляр с двумя настроенными индексами: index foo предлагает пакет A и индекс bar предложения B. Теперь у вас есть два URL-адреса репозитория:

$ pip install A --index-url=https://my.pypi.org/foo

получится, но

$ pip install A --index-url=https://my.PyPI.org/bar

не удастся. Индексы могут наследовать друг друга в смысле расширения собственной базы пакетов, поэтому, если bar наследует foo, вы сможете установить оба A и B из bar индекс.

Это позволяет нам легко настроить политику ограничения пакетов: скажем, у нас есть две основные группы пользователей (разработчики и QA), каждая группа имеет свой собственный набор необходимых пакетов, также мы разрабатываем пакеты, предлагаемые клиентам, и инструменты для внутреннего использования. Без проблем сгруппировать их по индексам:

root/pypi
├── company/base    <- contains common packages like pip or setuptools
│   └── company/internal    <- in-house tools
│       ├── company/dev    <- packages necessary for development
│       │   ├── developer/sandbox    <- private index for single developer
│       │   └── developer2/sandbox
│       └── company/qa    <- packages for QA (test automation etc)
└── customer/release    <- customer packages

Теперь, например, разработчик устанавливает URL-адрес индекса https://my.pypi.org/developer/sandbox один раз и имеет доступ ко всем новым пакетам, загруженным, например, company/base, в то время как заказчик устанавливает индексный URL https://my.pypi.org/customer/release, не имея доступа к пакетам из company/internal.

В root/pypi это специальный метаиндекс: он всегда присутствует; если индекс наследует его, все запросы на установку пакетов, не содержащихся в индексе, передаются на pypi.org. Чтобы отключить зеркалирование pypi.org, просто не наследуйте от root/pypi.

Политику ограничения загрузки также легко настроить для каждого индекса: все разработчики могут загружать в свои собственные частные песочницы и company/dev; все QA могут загружать в company/qa; только администратор может загружать в company/base, загружает в company/internal а индексы клиентов создаются с сервера CI при успешных ночных сборках.

Ссылаться на devpi документы для всего процесса установки и настройки; документация довольно обширна и охватывает большинство вопросов, которые могут возникнуть.

Пользовательские колеса со скомпилированными расширениями C

Это совсем не тривиально, и при неправильном выполнении может возникнуть много головной боли. Я никогда не видел полностью или хотя бы частично автоматизированного решения для сборки колес из исходных дисков из-за разного набора зависимостей, которые имеет каждый пакет. Сложность настройки среды здания также зависит от платформы - настройка docker на машине Linux / MacOS и запустить более или менее предопределенный скрипт намного проще, чем настроить компилятор Visual C ++ и инструменты сборки в Windows.

Хотя мы поддерживаем Windows, нам нужно гораздо меньше предварительно скомпилированных пакетов для Windows, чем для Linux; большинство предварительно скомпилированных колес затем устанавливается в jessie-slim контейнеры, в которых просто нет gcc и прочее в наличии. Таким образом, мы не раздуваем контейнеры (главная причина всей этой неразберихи!). Все строительство ведется вручную по существующим образцам. При успешной сборке разработчику рекомендуется скопировать журнал терминала в сущность, улучшив коллекцию примеров.

manylinux1_x86_64/manylinux1_i686

Мы ведем список рецептов для статически связанных колес, которые кто-то успешно построил; основной подход всегда один и тот же:

  1. Беги чисто quay.io/pypa/manylinux1_x86_64 контейнер
  2. Клонировать исходный код
  3. Установите необходимые зависимости
  4. Бегать bdist_wheel
  5. Ремонт колес с auditwheel
  6. Установите колесо
  7. Запустите тесты; выходной контейнер
  8. Если сборка и тесты успешны, запустите devpi upload на отремонтированных колесах

Пример рецепта mysqlclient, строит колеса для python 3.5 и python 3.6:

$ mkdir io
$ docker pull quay.io/pypa/manylinux1_x86_64
$ docker run --rm -w /root -v $(pwd)/io:/io -it quay.io/pypa/manylinux1_x86_64 /bin/bash
# yum install -y mysql-devel  # mysqlclient needs mysql-devel libs
# git clone https://github.com/PyMySQL/mysqlclient-python.git
# cd mysqlclient-python
# /opt/python/cp35-cp35m/bin/python setup.py bdist_wheel
# /opt/python/cp36-cp36m/bin/python setup.py bdist_wheel
# find dist/ -type f -name "*.whl" | xargs -I {} auditwheel repair {} -w /io
# # start the server for tests
# yum install mysql-server
# chkconfig mysqld on
# service mysqld start
# mysql for CentOS 5 is too old, use utf8 instead of utf8mb4 and hope for the best
# mysql -e 'create database mysqldb_test charset utf8;'
# sed -i '' 's/utf8mb4/utf8/' tests/travis.cnf
# # run the tests with built wheels
# find /io -name "*cp35*" | xargs -I {} /opt/python/cp35-cp35m/bin/python -m pip install {} pytest mock
# TESTDB=travis.cnf /opt/python/cp35-cp35m/bin/python -m pytest
# # same for py3.6
# find /io -name "*cp36*" | xargs -I {} /opt/python/cp36-cp36m/bin/python -m pip install {} pytest mock
# TESTDB=travis.cnf /opt/python/cp36-cp36m/bin/python -m pytest
# exit
$ # check the terminal log for any errors!
$ devpi login admin
$ devpi use https://my.pypi.org/company/base
$ devpi upload --from-dir=io/

Windows

Мы настроили виртуальную машину Windows, настроенную для сборки колес, с инструментами сборки Visual C ++ и т. Д. Как и в случае с Linux, у нас есть примеры сущностей, которые шаг за шагом описывают, что необходимо сделать для сборки. Однако он редко используется для сборки колес и в основном служит рабом Дженкинса.