PyODPS制作第三方包

PyODPS自V0.11.3版本开始提供了pyodps-pack命令行工具,用于制作符合PyODPS及DataWorks PyODPS节点标准的三方包,使用方法类似pip命令。您可以使用该工具将所有依赖项目制作成一个后缀为.tar.gz的压缩包,其中包含所有依照MaxCompute或DataWorks环境编译并打包的项目依赖。您也可以使用该工具打包您项目中自行创建的Python包。

环境准备

pyodps-pack命令需要在操作系统命令行(Windows CMD或者macOS/Linux Shell)中执行,DataWorks、odpscmd和Python命令行中不能调用。

Docker模式

您需要安装Docker以顺利使用Docker模式运行pyodps-packpyodps-pack会自动调用已安装的Docker并下载镜像,您无需手动执行下载Docker镜像和运行Docker命令的操作。

说明

仅支持在Docker模式下执行pyodps-pack命令,非Docker模式执行会报错。

说明

我们没有在包括minikube在内的其他Docker环境中测试pyodps-pack,不保证在这些环境中的可用性。

对于Windows用户,可能您的Docker服务需要依赖Windows系统的Server服务才能启动,而Server服务由于安全问题在很多企业被禁止启动。在遇到问题时,请改用Linux打包或者设法启用Server服务。Rancher Desktop在Windows 10下可能无法使用containerd作为容器引擎,可以尝试改用dockerd,配置详情请参考Container Engine

无Docker模式

说明

当您的环境支持Docker时,推荐采用Docker模式进行打包PyODPS所有依赖、代码以及Git Repo中的代码。若Docker不可用,才考虑使用非Docker模式。需要注意的是,非Docker模式生成的包可能不可用。

如果您安装Docker遇到困难,可以尝试使用非Docker模式。使用方式为新增一个--without-docker参数。该模式需要您的Python环境中已经安装pip。如果在该模式下执行pyodps-pack命令出现错误或者生成的包不可用,请改用Docker模式。Windows用户需要安装Git Bash以使用该模式,Git Bash包含在Git for Windows中。

打包操作

使用限制

  • MaxCompute建议除非不得已,新项目请尽量使用Python 3。我们不保证下面打包步骤对Python 2的可用性。

  • 旧项目请尽量迁移至Python 3以减少后续维护的难度。

  • 在Linux中使用下列命令时,请使用sudo调用pyodps-pack以保证Docker正常运行。

  • 在macOS中使用下列命令时,请不要使用sudo调用pyodps-pack以避免可能引发的权限错误。

打包所有依赖

说明

部分Python包可能存在一些可选依赖,例如pandas在使用to_excel方法时依赖openpyxl包,pyodps-pack无法自动包含这部分依赖,请根据三方包文档手动在打包命令中添加这些依赖。

安装完PyODPS后,您可以在本地命令行中使用以下命令为Python 3打包pandas以及pandas的依赖项。

  • 使用Docker模式打包:

    pyodps-pack pandas
  • 使用非Docker模式打包:

    pyodps-pack --without-docker pandas
  • 打包时指定所需版本:

    pyodps-pack pandas==1.2.5

经过一系列的打包步骤,工具会显示包中的所有依赖版本,具体如下。并在当前目录中生成一个packages.tar.gz文件,其中包括下面列出的所有依赖项目。

Package         Version
--------------- -------
numpy           1.21.6
pandas          1.2.5
python-dateutil 2.8.2
pytz            2022.6
six             1.16.0

如果您希望为Python 2.7打包,请确定包的后续使用环境为MaxCompute还是DataWorks,辨别方法请参考PyODPS DataFrame的代码运行环境

  • 在MaxCompute中使用Python 2.7包的打包命令:

    pyodps-pack --mcpy27 pandas
  • 在DataWorks中使用Python 2.7包的打包命令:

    pyodps-pack --dwpy27 pandas

打包自定义代码

pyodps-pack支持打包使用setup.pypyproject.toml组织的用户自定义Python Project。详情请参考Build System Interface

示例:以基于pyproject.toml组织的项目为例,为您介绍如何使用pyodps-pack打包。假定项目的目录结构如下:

test_package_root
├── test_package
│   ├── __init__.py
│   ├── mod1.py
│   └── subpackage
│       ├── __init__.py
│       └── mod2.py
└── pyproject.toml

其中pyproject.toml内容可能为:

[project]
name = "test_package"
description = "pyodps-pack example package"
version = "0.1.0"
dependencies = [
    "pandas>=1.0.5"
]

完成包的开发后,使用以下命令可以将此包和所有依赖打包进packages.tar.gz文件中(path_to_packagetest_package_root的上级路径):

pyodps-pack /<path_to_package>/test_package_root

打包Git Repo中的代码

pyodps-pack支持打包远程Git代码仓库(例如GitHub)中的代码。以PyODPS本身为例,可以使用以下命令执行打包:

pyodps-pack git+https://github.com/aliyun/aliyun-odps-python-sdk.git

如果想要打包某个分支或者Tag,可以使用:

pyodps-pack git+https://github.com/aliyun/aliyun-odps-python-sdk.git@v0.11.2.2

如果打包前需要安装一些打包依赖(例如cython),可以使用--install-requires参数增加安装时依赖。也可以编写一个格式与requirements.txt相同的install-requires.txt文件,并使用--install-requires-file选项指定。例如,如果需要先安装Cython再打包PyODPS,可以执行如下命令:

pyodps-pack \
    --install-requires cython \
    git+https://github.com/aliyun/aliyun-odps-python-sdk.git@v0.11.2.2

也可以创建一个install-requires.txt文件并依照requirements.txt格式编写如下:

cython>0.29

打包命令可以写成:

pyodps-pack \
    --install-requires-file install-requires.txt \
    git+https://github.com/aliyun/aliyun-odps-python-sdk.git@v0.11.2.2

更复杂的例子:二进制依赖

一部分包包含额外的二进制依赖,例如需要编译或安装的外部动态链接库。pyodps-pack提供了--run-before参数用以指定打包前需要执行的步骤,该步骤中可以安装所需的二进制依赖。下面以地理信息库GDAL为例为您介绍如何打包。

  1. 确定打包时需要安装的二进制依赖。

    根据GDAL 3.6.0在PyPI上的文档,我们需要安装3.6.0以上版本的libgdal。libgdal编译说明则指出,该包依赖6.0版本以上的PROJ包,这两个二进制包均使用CMake打包。据此,编写二进制包安装文件并保存为install-gdal.sh

    #!/bin/bash
    set -e
    
    cd /tmp
    curl -o proj-6.3.2.tar.gz https://download.osgeo.org/proj/proj-6.3.2.tar.gz
    tar xzf proj-6.3.2.tar.gz
    cd proj-6.3.2
    mkdir build && cd build
    cmake ..
    cmake --build .
    cmake --build . --target install
    
    cd /tmp
    curl -o gdal-3.6.0.tar.gz http://download.osgeo.org/gdal/3.6.0/gdal-3.6.0.tar.gz
    tar xzf gdal-3.6.0.tar.gz
    cd gdal-3.6.0
    mkdir build && cd build
    cmake ..
    cmake --build .
    cmake --build . --target install
  2. 使用pyodps-pack进行打包,命令如下:

    pyodps-pack --install-requires oldest-supported-numpy --run-before install-gdal.sh gdal==3.6.0

命令详情

下面列出pyodps-pack命令的可用参数,可用于控制打包过程:

参数名称

描述

-r--requirement <file>

根据给定的依赖文件打包。该选项可被指定多次。

-o--output <file>

指定打包生成目标文件名,默认为packages.tar.gz

--install-requires <item>

指定打包时所需的PyPI依赖,可指定多个,一般用于命令行中。这些依赖不一定会包含在最终的包中。

--install-requires-file <file>

指定打包时所需的PyPI依赖定义文件,可指定多个。这些依赖不一定会包含在最终的包中。

--run-before <script-file>

指定打包前需要执行的Bash脚本,通常可用于安装二进制依赖。

-x--exclude <dependency>

指定打包时需要从最终包删除的PyPI依赖。该选项可被指定多次。

--no-deps

指定打包时不包含指定项目的依赖项。

-i--index-url <index-url>

指定打包时所需的PyPI URL。如果缺省,会使用pip config list命令返回的global.index-url值,该值通常配置在pip.conf配置文件中。

--trusted-host <host>

指定打包时需要忽略证书问题的HTTPS域名。

-l--legacy-image

指定后,将使用CentOS 5镜像进行打包,这使得包可以被用在旧版专有云等环境中。

--mcpy27

指定后,将为MaxCompute内的Python 2.7制作三方包。如果启用,将默认--legacy-image选项开启。

--dwpy27

指定后将为DataWorks内的Python 2.7制作三方包。如果启用。将默认--legacy-image选项开启。

--prefer-binary

指定后,将倾向于选择PyPI中包含二进制编译的旧版,而不是仅有源码包的新版。

--docker-args <args>

指定在执行Docker命令时需要额外附加的参数。如有多个参数需用引号包裹,例如--docker-args "--ip 192.168.1.10"

--without-docker

使用无Docker模式运行pyodps-pack。当依赖中存在二进制依赖,可能报错或导致包不可用。

--without-merge

下载或生成Wheel包后不生成.tar.gz包,而是保留.whl文件。

--debug

指定后,将输出命令运行的详细信息,用于排查问题。

第三方包的使用方法请参见PyODPS使用第三方包