MaxCompute permite utilizar paquetes de terceros en una función definida por el usuario (UDF) de Python, como el paquete NumPy, paquetes que requieren compilación o aquellos que dependen de una biblioteca de vínculo dinámico. Este tema explica cómo utilizarlos.
Contexto
Es posible usar paquetes de terceros en una UDF de Python en los siguientes escenarios:
-
Use the NumPy package (Python 3 UDFs)
Debe cambiar la extensión del nombre de archivo del paquete NumPy, cargar el paquete mediante el cliente de MaxCompute y registrar la función para poder invocarla desde su UDF de Python 3.
-
Use a third-party package that requires compilation
En un entorno compatible con MaxCompute, debe compilar el script setup.py del paquete de terceros para generar un paquete wheel y cambiar la extensión del nombre de archivo del paquete. Posteriormente, utilice el cliente de MaxCompute para cargar el paquete y registrar la función, la cual podrá invocar desde su UDF de Python.
-
Use a third-party package that depends on a dynamic-link library
Debe compilar un archivo de biblioteca .so a partir del código fuente del paquete de terceros, generar un paquete wheel y cambiar la extensión del nombre de archivo del paquete. Luego, use el cliente de MaxCompute para cargar tanto el paquete como el archivo de biblioteca .so, y registre la función para poder invocarla desde su UDF de Python.
Requisitos previos
Antes de empezar, asegúrese de cumplir con los siguientes requisitos:
Python está instalado. Se recomienda Python 3.
El MaxCompute client está instalado y configurado. Para obtener más información, consulte Install and configure the MaxCompute client.
Para los paquetes que requieren compilación, asegúrese de que pip, setuptools y wheel estén instalados. Puede ejecutar el comando
pip install setuptoolspara instalar setuptools y el comandopip install wheelpara instalar wheel.Si utiliza GDAL 3.0 o posterior, asegúrese de que PROJ 6 esté instalado.
Si utiliza Docker para compilar un paquete de terceros, asegúrese de que Docker esté instalado. Para obtener más información, consulte la documentación de instalación de Docker.
Uso del paquete NumPy (UDF de Python 3)
El entorno de Python 2 de MaxCompute incluye NumPy de forma predeterminada. Para utilizar el paquete NumPy en una UDF de Python 3, debe cargar manualmente el paquete siguiendo estos pasos:
-
Tomando la versión 1.19.2 como ejemplo, vaya a la página de PyPI. En la sección Download files, descargue el paquete NumPy cuyo nombre de archivo termina con cp37-cp37m-manylinux1_x86_64.whl.
NotaLa carga puede fallar si utiliza un paquete con una extensión de nombre de archivo diferente. Si desea usar otra versión, vaya a la sección Navigation en la esquina superior izquierda de la página de PyPI y haga clic en Release history para consultar las versiones anteriores.
-
Cambie la extensión del nombre de archivo del paquete NumPy descargado a .zip.
Ejemplo: numpy-1.19.2-cp37-cp37m-manylinux1_x86_64.zip.
-
Utilice el MaxCompute client para cargar el paquete NumPy en un proyecto de MaxCompute. Para obtener más información sobre cómo cargar un recurso, consulte Resource operations.
Comando de ejemplo:
ADD ARCHIVE D:\Downloads\numpy-1.19.2-cp37-cp37m-manylinux1_x86_64.zip -f; -
Escriba un script de UDF de Python y guárdelo como un archivo .py.
A continuación se muestra un script de UDF de Python de ejemplo guardado como import_numpy.py:
from odps.udf import annotate @annotate("->string") class TryImport(object): # The class name is TryImport. def __init__(self): import sys sys.path.insert(0, 'work/numpy-1.19.2-cp37-cp37m-manylinux1_x86_64.zip') # The NumPy package. You only need to replace the package name that follows work/. def evaluate(self): import numpy return "import succeed" -
Utilice el MaxCompute client para cargar el script import_numpy.py como recurso en su proyecto de MaxCompute.
Comando de ejemplo:
ADD PY D:\Desktop\import_numpy.py -f; -
Utilice el script import_numpy.py y el paquete NumPy cargados para registrar una función definida por el usuario mediante el MaxCompute client. Para obtener más información sobre cómo registrar una función, consulte Function operations.
Suponga que la función definida por el usuario registrada se llama numpy y que el recurso de la función se encuentra en el proyecto test_project. Comando de ejemplo:
CREATE FUNCTION numpy AS 'import_numpy.TryImport' USING 'test_project/resources/import_numpy.py,numpy-1.19.2-cp37-cp37m-manylinux1_x86_64.zip';NotaAl registrar la función, debe agregar el paquete NumPy, como numpy-1.19.2-cp37-cp37m-manylinux1_x86_64.zip, a la lista de recursos.
Después de registrar la función, invoquela desde sus sentencias SQL. Asegúrese de habilitar Python 3 para la ejecución. Para obtener más información, consulte Python 3 UDF development specifications and workflow.
Uso de paquetes que requieren compilación
Si un paquete de terceros es un archivo TAR.GZ de PyPI o un paquete de código fuente de GitHub, el directorio raíz del paquete descomprimido puede contener un archivo setup.py. Antes de poder usar este tipo de paquete, debe compilar el archivo setup.py para generar un paquete wheel en un entorno compatible con MaxCompute. Posteriormente, cargue el recurso y registre la función. Entonces podrá invocar el paquete de terceros mediante una UDF de Python. Para obtener más información sobre cómo cargar un recurso y registrar una función, consulte Use the NumPy package (Python 3 UDFs).
Los paquetes de terceros se ejecutan en un entorno Linux en MaxCompute. Para evitar problemas de compatibilidad, compílelos en un entorno Linux en lugar de hacerlo en Windows.
Si utiliza un entorno Windows, se recomienda usar la versión correspondiente de Python (
/opt/python/cp27-cp27m/bin/pythono/opt/python/cp37-cp37m/bin/python3) para construir un paquete wheel en el contenedorquay.io/pypa/manylinux2010_x86_64de Docker.
Si utiliza un entorno Linux, verifique los siguientes puntos para garantizar la compatibilidad:
-
Debe usar una versión compatible de Python. En la interfaz de línea de comandos (CLI) de su sistema, ejecute el siguiente comando para comprobar la compatibilidad de su versión de Python:
python -c "import wheel.pep425tags; print(wheel.pep425tags.get_abi_tag())"Si se devuelve
cp27mocp37m, la versión de Python cumple con los requisitos de compatibilidad.Si se devuelve
cp27muocp37mu, la versión de Python no cumple con los requisitos de compatibilidad. Debe ejecutar el comando./configure --enable-unicode=ucs2en la CLI para establecer la codificación de Python a UCS-2.
-
Si existen dependencias de código C o C++, debe utilizar una versión compatible de GNU Compiler Collection (GCC).
NotaSe recomienda utilizar GCC 4.9.2 o anterior. Si usa una versión de GCC posterior a la 4.9.2, los archivos .so del paquete wheel generado podrían ser incompatibles con el entorno de MaxCompute.
Una vez que su entorno cumpla con los requisitos de compatibilidad, siga estos pasos para generar un paquete wheel a partir de un archivo setup.py:
-
Extraiga el paquete de terceros en un directorio local. En la CLI de su sistema, cambie a la carpeta donde se encuentra el archivo setup.py.
Por ejemplo, si descarga el paquete GDAL-3.2.0.zip y lo extrae, el archivo setup.py estará en el directorio D:\Downloads\GDAL-3.2.0. Comando de ejemplo:
cd D:\Downloads\GDAL-3.2.0 -
En la CLI, ejecute el siguiente comando para verificar si bdist_wheel aparece en la salida.
Comando de ejemplo:
python setup.py --help-command -
En la CLI, ejecute el siguiente comando para compilar y generar un paquete wheel.
python setup.py bdist_wheelNotaEl paquete wheel se encuentra en el directorio dist.
Uso de paquetes con bibliotecas de vínculo dinámico
Algunos paquetes de Python de terceros pueden depender de otras bibliotecas de vínculo dinámico además de las bibliotecas de Python. Esta sección toma GDAL 3.0.4 como ejemplo para describir cómo utilizar el contenedor Docker quay.io/pypa/manylinux2010_x86_64 para compilar los archivos de biblioteca .so correspondientes y generar un paquete wheel utilizable en MaxCompute. Posteriormente, utilizará estos archivos generados para cargarlos como recursos y registrar la función, lo que le permitirá invocar el paquete desde una UDF de Python. Para obtener más información sobre cómo cargar un recurso y registrar una función, consulte Use the NumPy package (Python 3 UDFs).
Asegúrese de que Docker esté instalado antes de continuar. Para obtener más información sobre las operaciones de Docker, consulte la documentación de Docker.
Para utilizar un paquete de terceros que depende de un archivo de biblioteca .so en una UDF de Python, siga estos pasos:
-
Consulte las dependencias. Puede verlas en la sección Dependencies de la página de PyPI.
Por ejemplo, las dependencias de GDAL 3.0.4 son las siguientes:
Dependencies - libgdal (3.0.4 or greater) and header files (gdal-devel) - numpy (1.0.0 or greater) and header files (numpy-devel) (not explicitly required, but many examples and utilities will not work without it)NotaComo se muestra arriba, las dependencias incluyen libgdal y numpy. libgdal se obtiene al compilar el código fuente de GDAL en un contenedor, y numpy se obtiene al descargar el paquete NumPy desde la página de PyPI o en un contenedor de Docker.
-
Descargue el paquete NumPy.
Puede descargar el paquete NumPy mediante uno de los siguientes métodos:
-
En la página de PyPI, vaya a la sección Download files y descargue el paquete NumPy cuyo nombre de archivo termina con cp37-cp37m-manylinux1_x86_64.whl.
NotaSi utiliza un entorno de Python 2, debe descargar un paquete NumPy compatible. En el área Navigation en el lado izquierdo de la página de PyPI, haga clic en Release history, seleccione la versión 1.16.6 o anterior, y descargue el paquete cuyo nombre de archivo termina con cp27-cp27m-manylinux1_x86_64.whl.
En el contenedor de Docker quay.io/pypa/manylinux2010_x86_64, ejecute el comando
/opt/python/cp37-cp37m/bin/pip download numpy -d ./para descargar el paquete NumPy en el directorio actual.
-
-
Compile el archivo de biblioteca .so.
Descargue el código fuente de GDAL 3.0.4 y extráigalo en un directorio local.
-
Utilice Docker para extraer la imagen del contenedor quay.io/pypa/manylinux2010_x86_64 y entrar en el modo de terminal interactiva.
Comandos de ejemplo:
docker pull quay.io/pypa/manylinux2010_x86_64 docker run -it quay.io/pypa/manylinux2010_x86_64 /bin/bash -
Copie el código fuente de GDAL 3.0.4 al contenedor.
Comando de ejemplo:
docker cp ./gdal-3.0.4 <CONTAINER ID>:/opt/source/Para obtener el CONTAINER ID, consulte docker ps.
-
Compile GDAL 3.0.4 en el contenedor. Para obtener más información, consulte BuildingOnUnix.
Comandos de ejemplo:
# You must specify the installation directory of PROJ 6 in the configure option. ./configure --prefix=/path/to/install/prefix --with-proj=/path/to/install/proj6/prefix make make install export PATH=/path/to/install/prefix/bin:$PATH export LD_LIBRARY_PATH=/path/to/install/prefix/lib:$LD_LIBRARY_PATH export GDAL_DATA=/path/to/install/prefix/share/gdal # Test gdalinfo --versionDurante la compilación pueden ocurrir los siguientes errores:
configure: error: PROJ 6 symbols not found: GDAL 3.0 y versiones posteriores dependen de PROJ 6. Debe descargar e instalar PROJ 6.fatal error: zlib.h: No such file or directory: Ejecute el comandoyum install zlib-devely compile nuevamente.
Utilice el comando docker cp para copiar los archivos libgdal.so y libproj.so del contenedor a su máquina local. Estos se encuentran en la carpeta lib de sus respectivos directorios de instalación. Asegúrese de copiar los archivos reales, no sus vínculos simbólicos.
-
Cree un paquete wheel de GDAL en el contenedor. Para obtener más información, consulte BuildingOnUnix.
Comandos de ejemplo:
# If NumPy is required, you must install NumPy first. /opt/python/cp37-cp37m/bin/pip install numpy # Switch to the directory of the GDAL source code. cd swig/python # A wheel package is generated in the dist directory. Example: GDAL-3.0.4-cp37-cp37m-linux_x86_64.whl /opt/python/cp37-cp37m/bin/python setup.py bdist_wheel -
Con base en los archivos de biblioteca .so, el paquete wheel o el paquete NumPy generados, cargue los recursos y registre la función para utilizar el paquete de terceros en una UDF de Python. Para obtener más información sobre cómo cargar recursos y registrar una función, consulte Use the NumPy package (Python 3 UDFs).
Tenga en cuenta los siguientes puntos:
Al cargar recursos, debe cargar libgdal.so y libproj.so como recursos FILE, y cargar numpy-1.19.2-cp37-cp37m-manylinux1_x86_64.zip y GDAL-3.0.4-cp37-cp37m-linux_x86_64.zip como recursos ARCHIVE.
Al registrar la función, debe agregar libgdal.so, libproj.so, numpy-1.19.2-cp37-cp37m-manylinux1_x86_64.zip y GDAL-3.0.4-cp37-cp37m-linux_x86_64.zip a la lista de recursos de la función.
A continuación se muestra un código de ejemplo para la UDF de Python:
NotaEste ejemplo utiliza código de Python 3 y debe ejecutarse en un entorno de Python 3. Si necesita ejecutarlo en un entorno de Python 2, preste atención al uso del parámetro
get_cache_file. Para obtener más información, consulte Reference resources.# coding: utf-8 from odps.udf import annotate from odps.distcache import get_cache_file def include_file(file_name): import os, sys so_file = get_cache_file(file_name, 'b') with open(so_file.name, 'rb') as fp: content=fp.read() so = open(file_name, "wb") so.write(content) so.flush() so.close() @annotate("->string") class TryImport(object): def __init__(self): import sys include_file('libgdal.so.26') include_file('libproj.so.15') sys.path.insert(0, 'work/GDAL-3.0.4-cp37-cp37m-linux_x86_64.zip') # The compiled GDAL package. You only need to replace the package name that follows work/. sys.path.insert(0, 'work/numpy-1.19.2-cp37-cp37m-manylinux1_x86_64.zip') # The NumPy package. You only need to replace the package name that follows work/. def evaluate(self): from osgeo import gdal from osgeo import ogr from osgeo import osr from osgeo import gdal_array from osgeo import gdalconst return "import succeed"NotaSi encuentra un error de ejecución que indica que no se puede encontrar libgdal.so.26 o libproj.so.15, cambie el nombre de los archivos cargados libgdal.so y libproj.so a libgdal.so.26 y libproj.so.15, respectivamente.