TLDR :裤子从我在Mac上进行开发时获取OS X特定的轮子。如何避免这种情况,或者指定我将其部署到Ubuntu?

全文:

尝试使用Pants打包Python应用程序。到目前为止进展顺利,但遇到了一个问题,我已经坚持了一段时间。我在Macbook上进行开发,但正在部署到EC2 Ubuntu。

到目前为止,这是我所做的:

  • 创建virtualenv。
  • 向应用程序添加了BUILD文件,其中suggested 3rd party pattern用于第三方软件包。
  • 运行良好并生成./pants run.py backend:admin_server的然dist/admin_server.pex
  • 将.pex放到新的EC2 Ubuntu框中。

  • 但是,当我在那里运行应用程序时,我得到:
    Failed to execute PEX file, missing compatible dependencies for:
        mysql-python
        pycrypto
    

    问题似乎是,Pant需要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。

    最佳答案

    将项目作为PEX文件分发的好处之一是,您可以准备使其在多个平台上运行。例如,一个PEX可以在Linux和Mac平台上运行。对于许多项目,除了构建PEX外,没有其他特殊的事情要做。但是,当您的项目依赖于平台特定的二进制代码时,您将需要执行一些额外的步骤。

    包含平台特定代码的库的一个示例是psutil库。它包含在安装模块时编译为共享库的C代码。要创建包含此类依赖项的PEX文件,必须首先为除运行裤子的平台以外的所有平台提供该库的预构建版本。

    预先构建库的最简单方法是使用pip工具构建轮子。

    该配方假定以下条件:

  • 您想要构建一个多平台的pex以在Linux和Mac上运行
    您将在Linux环境中预先构建库,
    然后在Mac环境上构建PEX。
  • 您的项目目录位于〜/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)
    

    使用裤子,可以通过在BUILD文件中定义python_binary目标来定义可执行文件:
    # 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()
    

    在同一目录中,在requirements.txt文件中列出python库:
    # src/python/ps_example/requirements.txt
    psutil==3.1.1
    

    现在,要制作多平台的pex,您需要访问Linux框以创建psutil wheel的linux版本。将requirements.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/的目录中。

    完成此操作后,您现在可以使用
    mac $ ./pants binary src/python/py_example
    

    您可以通过解压缩pex来验证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
    ...
    

    关于pants - 裤子包括OS X专用的Python轮子,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34979100/

    10-13 08:59