Штаны включают в себя OS X специальные колеса Python

TLDR: Pants получает специально для OS X диски, которые я разрабатываю на Mac. Как я могу избежать этого или указать, что я буду развертывать в Ubuntu?

Полная история:

Попытка упаковать приложение Python с помощью Pants. Пока все шло отлично, но я столкнулся с проблемой, над которой я застрял некоторое время. Я работаю на MacBook, но развертываю в EC2 Ubuntu.

Вот что я сделал до сих пор:

  1. Создано virtualenv.
  2. Добавлены файлы BUILD в приложения с предложенным сторонним шаблоном для сторонних пакетов.
  3. Ран ./pants run.py backend:admin_server который работает нормально и генерируется dist/admin_server.pex
  4. Подберите этот.pex на свежую коробку EC2 Ubuntu.

Однако когда я запускаю приложение там, я получаю:

Failed to execute PEX file, missing compatible dependencies for:
    mysql-python
    pycrypto

Кажется, проблема в том, что Pants использует специальные диски OS X для этих 2:

pex: - MySQL_python-1.2.5-cp27-none-macosx_10_11_intel.whl pex: - pycrypto-2.6.1-cp27-none-macosx_10_11_intel.whl

Как я могу избежать этого или указать, на какой ОС они должны работать?

Вот полный вывод:

ubuntu@ip-***:~$ export PEX_VERBOSE=1
ubuntu@ip-***:~$ python admin_server.pex
pex: Found site-library: /usr/local/lib/python2.7/dist-packages
pex: Found site-library: /usr/lib/python2.7/dist-packages
pex: Tainted path element: /usr/local/lib/python2.7/dist-packages
pex: Tainted path element: /usr/lib/python2.7/dist-packages
pex: Scrubbing from site-packages: /usr/local/lib/python2.7/dist-packages
pex: Scrubbing from site-packages: /usr/lib/python2.7/dist-packages
pex: Scrubbing from user site: /home/ubuntu/.local/lib/python2.7/site-packages
pex: Failed to resolve a requirement: MySQL-python==1.2.5
pex: Failed to resolve a requirement: pycrypto==2.6.1
pex: Unresolved requirements:
pex:   - mysql-python
pex:   - pycrypto
pex: Distributions contained within this pex:
pex:   - six-1.10.0-py2.py3-none-any.whl
pex:   - protobuf-2.6.1-py2.7.egg
pex:   - setuptools-19.5-py2.py3-none-any.whl
pex:   - MySQL_python-1.2.5-cp27-none-macosx_10_11_intel.whl
pex:   - pycrypto-2.6.1-cp27-none-macosx_10_11_intel.whl
pex:   - futures-3.0.4-py2-none-any.whl
pex:   - webapp2-2.5.2-py2-none-any.whl
pex:   - requests-2.9.0-py2.py3-none-any.whl
pex:   - jmespath-0.9.0-py2.py3-none-any.whl
pex:   - beautifulsoup4-4.4.1-py2-none-any.whl
pex:   - python_dateutil-2.4.2-py2.py3-none-any.whl
pex:   - boto3-1.2.3-py2.py3-none-any.whl
pex:   - WebOb-1.5.1-py2.py3-none-any.whl
pex:   - cssutils-1.0.1-py2-none-any.whl
pex:   - webapp2_static-0.1-py2-none-any.whl
pex:   - Paste-2.0.2-py2-none-any.whl
pex:   - docutils-0.12-py2-none-any.whl
pex:   - botocore-1.3.22-py2.py3-none-any.whl
pex:   - protobuf_to_dict-0.1.0-py2-none-any.whl
Failed to execute PEX file, missing compatible dependencies for:
mysql-python
pycrypto

PS: чтобы убедиться, что я не включил свои версии библиотек python, я удалил pip и PyCrypto, и MySQL-Python.

1 ответ

Решение

Одна из приятных сторон распространения проекта в виде PEX-файла заключается в том, что вы можете подготовить его для работы на нескольких платформах. Например, один PEX может работать на платформах Linux и Mac. Для многих проектов нет ничего особенного, кроме как построить PEX. Но когда ваш проект зависит от бинарного кода конкретной платформы, вам нужно будет выполнить несколько дополнительных шагов.

Одним из примеров библиотеки, содержащей код для конкретной платформы, является psutil библиотека. Он содержит код C, который был скомпилирован в общую библиотеку при установке модуля. Чтобы создать PEX-файл, содержащий такие зависимости, вы должны сначала предоставить предварительно собранную версию этой библиотеки для всех платформ, кроме той, на которой вы работаете.

Самый простой способ предварительно собрать библиотеки - использовать инструмент pip для сборки колес.

Этот рецепт предполагает следующее:

  • Вы хотите создать мультиплатформенный pex для работы как на Linux, так и на Mac. Вы собираетесь предварительно собрать библиотеки в среде Linux, а затем собрать PEX в среде Mac.
  • Каталог вашего проекта находится в ~/src/cookbook

Давайте возьмем простую программу, которая ссылается на библиотеку и создадим из нее pex.

#  src/python/ps_example/main.py
import psutil

for proc in psutil.process_iter():
    try:
        pinfo = proc.as_dict(attrs=['pid', 'name'])
    except psutil.NoSuchProcess:
        pass
    else:
        print(pinfo)

С помощью Pants вы можете определить исполняемый файл, определив цель python_binary в файле BUILD:

# src/python/ps_example/BUILD
python_binary(name='ps_example',
  source = 'main.py',
  dependencies = [
    ':psutil',  # defined in requirements.txt
  ],
)

# Defines targets from specifications in requirements.txt
python_requirements()

В этом же каталоге перечислите библиотеки python в файле require.txt:

# src/python/ps_example/requirements.txt 
psutil==3.1.1

Теперь, чтобы сделать мультиплатформенный pex, вам понадобится доступ к Linux-боксу для создания Linux-версии psutil wheel. Скопируйте файл needs.txt на машину linux, затем запустите инструмент pip:

linux $ mkdir ~/src/cookbook/wheelhouse
linux $ pip wheel -r src/python/multi-platform/requirements.txt  \
    --wheel-dir=~/src/cookbook/wheelhouse

Это создаст файл колеса для конкретной платформы.

linux $ ls ~/src/cookbook/wheelhouse/
psutil-3.1.1-cp27-none-linux_x86_64.whl

Теперь вам нужно скопировать колесо для конкретной платформы на компьютер, на котором вы хотите собрать свой мультиплатформенный pex (в данном случае, ваш ноутбук Mac). Если вы используете этот рецепт на регулярной основе, вы, вероятно, захотите настроить репозиторий Python для хранения ваших предварительно собранных библиотек.

Мы будем использовать ту же настройку файла BUILD, что и выше, но изменим python_binary, чтобы указать platforms= параметр.

# src/python/ps_example/BUILD
python_binary(name='ps_example',
  source = 'main.py',
  dependencies = [
    ':psutil',  # defined in requirements.txt
  ],
  platforms=[
    'linux-x86_64',
    'macosx-10.7-x86_64',
  ],
)

# Defines targets from specifications in requirements.txt
python_requirements()

Вам также нужно будет сообщить брюкам, где найти готовые пакеты Python. редактировать pants.ini и добавить:

[python-repos]
repos: [
    "%(buildroot)s/wheelhouse/"
  ]

Теперь скопируйте файл psutil-3.1.1-cp27-none-linux_x86_64.whl на рабочую станцию ​​Mac и поместите его в каталог с именем wheelhouse/ под корень вашего репо.

Как только это будет сделано, теперь вы можете построить мультиплатформенный Pex с

mac $ ./pants binary src/python/py_example

Вы можете проверить, что библиотеки для Mac и Linux включены в pex, разархивировав его:

mac $ unzip -l dist/ps_example.pex | grep psutil
    17290  12-21-15 22:09   .deps/psutil-3.1.1-cp27-none-linux_x86_64.whl/psutil-3.1.1.dist-info/DESCRIPTION.rst
    19671  12-21-15 22:09   .deps/psutil-3.1.1-cp27-none-linux_x86_64.whl/psutil-3.1.1.dist-info/METADATA
     1340  12-21-15 22:09   .deps/psutil-3.1.1-cp27-none-linux_x86_64.whl/psutil-3.1.1.dist-info/RECORD
      103  12-21-15 22:09  
...   .deps/psutil-3.1.1-cp27-none-macosx_10_11_intel.whl/psutil-3.1.1.dist-info/DESCRIPTION.rst
    19671  12-21-15 22:09   .deps/psutil-3.1.1-cp27-none-macosx_10_11_intel.whl/psutil-3.1.1.dist-info/METADATA
     1338  12-21-15 22:09   .deps/psutil-3.1.1-cp27-none-macosx_10_11_intel.whl/psutil-3.1.1.dist-info/RECORD
      109  12-21-15 22:09   
...
Другие вопросы по тегам