Utilizzo delle librerie Python con AWS Glue - AWS Glue

Utilizzo delle librerie Python con AWS Glue

Puoi installare moduli e librerie Python aggiuntivi da utilizzare con AWS Glue ETL. Per AWS Glue 2.0 e versioni successive, AWS Glue utilizza Python Package Installer (pip3) per installare moduli aggiuntivi utilizzati da AWS Glue ETL. AWS Glue offre diverse opzioni per portare i moduli Python aggiuntivi nell'ambiente di lavoro AWS Glue. È possibile usare il parametro "—additional-python-modules" per inserire moduli usando i file wheel Python, il file dei requisiti (requirement.txt, AWS Glue 5.0 e versioni successive) o un elenco di moduli Python separati da virgole.

Secondo il modello di responsabilità condivisa AWS, l'utente è responsabile della gestione di moduli Python aggiuntivi, delle librerie e delle dipendenze utilizzati con i processi AWS Glue ETL. Ciò include l'applicazione di aggiornamenti e patch di sicurezza.

AWS Glue non supporta la compilazione di codice nativo nell'ambiente del processo. I processi di AWS Glue, tuttavia, possono essere eseguiti in un ambiente Linux gestito da Amazon. È possibile fornire le dipendenze native in un formato compilato tramite un file wheel Python. Fare riferimento alla tabella precedente per i dettagli sulla compatibilità della versione di AWS Glue.

Se le dipendenze di Python si basano in modo transitivo sul codice nativo compilato, si potrebbe riscontrare la seguente limitazione: AWS Glue non supporta la compilazione di codice nativo nell'ambiente di processo. I processi di AWS Glue, tuttavia, possono essere eseguiti in un ambiente Linux gestito da Amazon. È possibile fornire le dipendenze native in un formato compilato tramite una distribuzione wheel. Fare riferimento alla tabella precedente per i dettagli sulla compatibilità della versione di AWS Glue.

Importante

L'utilizzo di dipendenze incompatibili può causare problemi di runtime, in particolare per le librerie con estensioni native che devono corrispondere all'architettura e alle librerie di sistema dell'ambiente di destinazione. Ogni versione di AWS Glue funziona su una versione di Python specifica con librerie e configurazioni di sistema preinstallate.

Installazione di moduli Python aggiuntivi con pip in AWS Glue 2.0 e versioni successive

AWS Glue utilizza Python Package Installer (pip3) per installare moduli aggiuntivi che AWS Glue ETL utilizza. Puoi utilizzare il parametro --additional-python-modules con un elenco di moduli Python separati da virgole per aggiungere un nuovo modulo o modificare la versione di un modulo esistente. Puoi installare distribuzioni personalizzate di una libreria caricando la distribuzione in Amazon S3 e successivamente includendo il percorso dell'oggetto Amazon S3 nell'elenco dei moduli.

Puoi passare opzioni aggiuntive a pip3 tramite il parametro --python-modules-installer-option. Ad esempio, è possibile passare "--upgrade" per aggiornare i pacchetti specificati da "--additional-python-modules". Per ulteriori esempi, consulta la sezione Creazione di moduli Python da un file wheel per carichi di lavoro ETL Spark usando AWS Glue 2.0.

AWS Glue supporta l'installazione di pacchetti Python personalizzati utilizzando file wheel (.whl) archiviati in Amazon S3. Per includere i file wheel nei lavori AWS Glue, fornire un elenco separato da virgole dei file wheel memorizzati in S3 al parametro del processo --additional-python-modules. Ad esempio:

--additional-python-modules s3://amzn-s3-demo-bucket/path/to/package-1.0.0-py3-none-any.whl,s3://your-bucket/path/to/another-package-2.1.0-cp311-cp311-linux_x86_64.whl

Questo approccio supporta anche le casistiche in cui sono necessarie distribuzioni personalizzate o pacchetti con dipendenze native precompilati per il sistema operativo corretto. Per ulteriori esempi, consultare la sezione Creazione di moduli Python da un file wheel per carichi di lavoro ETL Spark usando AWS Glue 2.0.

È possibile specificare --additional-python-modules nel campo Parametri del processo della console AWS Glue o puoi modificare gli argomenti del processo nell'SDK AWS. Per ulteriori informazioni sulla configurazione dei parametri di processo, consultare Utilizzo dei parametri di processo nei processi AWS Glue.

In AWS Glue 5.0, è possibile fornire lo standard di fatto requirements.txt per gestire le dipendenze della libreria Python. A tale scopo, fornire i seguenti due parametri di lavoro:

  • Chiave: --python-modules-installer-option

    Valore: -r

  • Chiave: --additional-python-modules

    Valore: s3://path_to_requirements.txt

I nodi AWS Glue 5.0 caricano inizialmente le librerie python specificate in requirements.txt.

Segue un file di esempio requirements.txt:

awswrangler==3.9.1 elasticsearch==8.15.1 PyAthena==3.9.0 PyMySQL==1.1.1 PyYAML==6.0.2 pyodbc==5.2.0 pyorc==0.9.0 redshift-connector==2.1.3 scipy==1.14.1 scikit-learn==1.5.2 SQLAlchemy==2.0.36
Importante

Evita le versioni della libreria non bloccate nel tuo requirements.txt per assicurarti di avere un ambiente AWS Glue affidabile e deterministico per i tuoi lavori.

Quando si usa wheel per le dipendenze dirette, è possibile inserire versioni incompatibili delle dipendenze transitive, se non sono bloccate correttamente. Come best practice, tutte le versioni della libreria devono essere bloccate per garantire la coerenza nei processi AWS Glue. AWS Glue consiglia di impacchettare l'ambiente Python in un file wheel per garantire coerenza e affidabilità per il carico di lavoro di produzione.

Per aggiornare o aggiungere un nuovo modulo Python, AWS Glue consente di passare i parametri --additional-python-modules con un elenco di moduli Python separati da virgole come valori. Ad esempio, per aggiornare o aggiungere un modulo scikit-learn, usa la seguente coppia chiave-valore: "--additional-python-modules", "scikit-learn==0.21.3". Sono disponibili due opzioni per configurare direttamente i moduli Python.

  • Modulo Python bloccato (consigliato)

    "--additional-python-modules", "scikit-learn==0.21.3,ephem==4.1.6"

  • Modulo Python non bloccato: (non consigliato per carichi di lavoro di produzione)

    "--additional-python-modules", "scikit-learn>==0.20.0,ephem>=4.0.0"

    O

    "--additional-python-modules", "scikit-learn,ephem"

Importante

Quando si configurano i moduli Python direttamente in --additional-python-modules, AWS Glue consiglia di utilizzare versioni della libreria bloccate per garantire la coerenza nell'ambiente di lavoro AWS Glue. Utilizzando versioni della libreria non bloccate, infatti, estrae l'ultima versione dei moduli Python, anche se questo può introdurre modifiche sostanziali o portare a un modulo Python incompatibile che porta al fallimento del processo a causa dell'errore di installazione di Python nell'ambiente di lavoro AWS Glue. Consigliamo ai clienti di non utilizzare versioni della libreria non bloccate per il carico di lavoro di produzione. Come best practice, AWS Glue consiglia di impacchettare l'ambiente Python in un file wheel per garantire coerenza e affidabilità per il carico di lavoro di produzione.

Best practice per l'installazione di librerie Python aggiuntive in AWS Glue

(Consigliato) Imballaggio dell'ambiente Python in un unico file wheel

Per un ambiente sicuro e coerente, AWS Glue consiglia di creare uno snapshor e di impacchettare l'ambiente Python in un file wheel. Il vantaggio di questo procedimento è che l'ambiente Python per i moduli Python di riferimento e le sue dipendenze transitive saranno bloccati. In questo modo, il processo AWS Glue non viene intaccato quando un repository upstream come PyPI o le dipendenze introducono aggiornamenti incompatibili.

Questo file può quindi essere utilizzato nel processo AWS Glue utilizzando il flag --additional-python-modules.

Importante

È necessario eseguire lo script seguente in un ambiente simile alla versione di AWS Glue in esecuzione. Fare riferimento alla tabella dei dettagli dell'ambiente Glue e assicurarsi di utilizzare la stessa immagine del sistema operativo di base e la stessa versione di Python.

#!/bin/bash set -e REQUIREMENTS_FILE="requirements.txt" FINAL_WHEEL_OUTPUT_DIRECTORY="." PACKAGE_NAME=$(basename "$(pwd)") PACKAGE_VERSION="0.1.0" # Help message show_help() { echo "Usage: $0 [options]" echo "" echo "Options:" echo " -r, --requirements FILE Path to requirements.txt file (default: requirements.txt)" echo " -o, --wheel-output DIR Output directory for final wheel (default: current directory)" echo " -n, --name NAME Package name (default: current directory name)" echo " -v, --version VERSION Package version (default: 0.1.0)" echo " -h, --help Show this help message" echo " -g, --glue-version Glue version (required)" echo "" echo "Example:" echo " $0 -r custom-requirements.txt -o dist -n my_package -v 1.2.3 -g 4.0" } # Parse command line arguments while [[ $# -gt 0 ]]; do key="$1" case $key in -r | --requirements) REQUIREMENTS_FILE="$2" shift 2 ;; -o | --wheel-output) FINAL_WHEEL_OUTPUT_DIRECTORY="$2" shift 2 ;; -n | --name) PACKAGE_NAME="$2" shift 2 ;; -v | --version) PACKAGE_VERSION="$2" shift 2 ;; -g | --glue-version) GLUE_VERSION="$2" shift 2 ;; -h | --help) show_help exit 0 ;; *) echo "Unknown option: $1" show_help exit 1 ;; esac done # If package name has dashes, convert to underscores and notify user. We need to check this since we cant import a package with dashes. if [[ "$PACKAGE_NAME" =~ "-" ]]; then echo "Warning: Package name '$PACKAGE_NAME' contains dashes. Converting to underscores." PACKAGE_NAME=$(echo "$PACKAGE_NAME" | tr '-' '_') fi UBER_WHEEL_NAME="${PACKAGE_NAME}-${PACKAGE_VERSION}-py3-none-any.whl" # Check if glue version is provided if [ -z "$GLUE_VERSION" ]; then echo "Error: Glue version is required." exit 1 fi # Validate version format (basic check) if [[ ! "$PACKAGE_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && [[ ! "$PACKAGE_VERSION" =~ ^[0-9]+\.[0-9]+$ ]]; then echo "Warning: Version '$PACKAGE_VERSION' doesn't follow semantic versioning (x.y.z or x.y)" fi # Check if requirements file exists if [ ! -f "$REQUIREMENTS_FILE" ]; then echo "Error: Requirements file '$REQUIREMENTS_FILE' not found." exit 1 fi # Get relevant platform tags/python versions based on glue version if [[ "$GLUE_VERSION" == "5.0" ]]; then PYTHON_VERSION="3.11" GLIBC_VERSION="2.34" elif [[ "$GLUE_VERSION" == "4.0" ]]; then PYTHON_VERSION="3.10" GLIBC_VERSION="2.26" elif [[ "$GLUE_VERSION" == "3.0" ]]; then PYTHON_VERSION="3.7" GLIBC_VERSION="2.26" elif [[ "$GLUE_VERSION" == "2.0" ]]; then PYTHON_VERSION="3.7" GLIBC_VERSION="2.17" elif [[ "$GLUE_VERSION" == "1.0" ]]; then PYTHON_VERSION="3.6" GLIBC_VERSION="2.17" elif [[ "$GLUE_VERSION" == "0.9" ]]; then PYTHON_VERSION="2.7" GLIBC_VERSION="2.17" else echo "Error: Unsupported glue version '$GLUE_VERSION'." exit 1 fi echo "Using Glue version $GLUE_VERSION" echo "Using Glue python version $PYTHON_VERSION" echo "Using Glue glibc version $GLIBC_VERSION" PIP_PLATFORM_FLAG="" is_glibc_compatible() { # assumes glibc version in the form of major.minor (ex: 2.17) # glue glibc must be >= platform glibc local glue_glibc_version="$GLIBC_VERSION" local platform_glibc_version="$1" # 2.27 (platform) can run on 2.27 (glue) if [[ "$platform_glibc_version" == "$glue_glibc_version" ]]; then return 0 fi local glue_glibc_major="${glue_glibc_version%%.*}" local glue_glibc_minor="${glue_glibc_version#*.}" local platform_glibc_major="${platform_glibc_version%%.*}" local platform_glibc_minor="${platform_glibc_version#*.}" # 3.27 (platform) cannot run on 2.27 (glue) if [[ "$platform_glibc_major" -gt "$glue_glibc_major" ]]; then return 1 fi # 2.34 (platform) cannot run on 2.27 (glue) if [[ "$platform_glibc_major" -eq "$glue_glibc_major" ]] && [[ "$platform_glibc_minor" -gt "$glue_glibc_minor" ]]; then return 1 fi # 2.17 (platform) can run on 2.27 (glue) return 0 } PIP_PLATFORM_FLAG="" if is_glibc_compatible "2.17"; then PIP_PLATFORM_FLAG="${PIP_PLATFORM_FLAG} --platform manylinux2014_x86_64" fi if is_glibc_compatible "2.28"; then PIP_PLATFORM_FLAG="${PIP_PLATFORM_FLAG} --platform manylinux_2_28_x86_64" fi if is_glibc_compatible "2.34"; then PIP_PLATFORM_FLAG="${PIP_PLATFORM_FLAG} --platform manylinux_2_34_x86_64" fi if is_glibc_compatible "2.39"; then PIP_PLATFORM_FLAG="${PIP_PLATFORM_FLAG} --platform manylinux_2_39_x86_64" fi echo "Using pip platform flags: $PIP_PLATFORM_FLAG" # Convert to absolute paths REQUIREMENTS_FILE=$(realpath "$REQUIREMENTS_FILE") FINAL_WHEEL_OUTPUT_DIRECTORY=$(realpath "$FINAL_WHEEL_OUTPUT_DIRECTORY") TEMP_WORKING_DIR=$(mktemp -d) VENV_DIR="${TEMP_WORKING_DIR}/.build_venv" WHEEL_OUTPUT_DIRECTORY="${TEMP_WORKING_DIR}/wheelhouse" # Cleanup function cleanup() { echo "Cleaning up temporary files..." rm -rf "$TEMP_WORKING_DIR" } trap cleanup EXIT echo "=========================================" echo "Building wheel for $PACKAGE_NAME with all dependencies from $REQUIREMENTS_FILE" echo "=========================================" # Determine Python executable to use consistently PYTHON_EXEC=$(which python3 2>/dev/null || which python 2>/dev/null) if [ -z "$PYTHON_EXEC" ]; then echo "Error: No Python executable found" exit 1 fi echo "Using Python: $PYTHON_EXEC" echo "" # Install build requirements echo "Step 1/5: Installing build tools..." echo "----------------------------------------" "$PYTHON_EXEC" -m pip install --upgrade pip build wheel setuptools echo "✓ Build tools installed successfully" echo "" # Create a virtual environment for building echo "Step 2/5: Creating build environment..." echo "----------------------------------------" "$PYTHON_EXEC" -m venv "$VENV_DIR" # Check if virtual environment was created successfully if [ ! -f "$VENV_DIR/bin/activate" ]; then echo "Error: Failed to create virtual environment" exit 1 fi source "$VENV_DIR/bin/activate" # Install pip-tools for dependency resolution "$VENV_DIR/bin/pip" install pip-tools echo "✓ Build environment created successfully" echo "" # Compile requirements to get all transitive dependencies GLUE_PIP_ARGS="$PIP_PLATFORM_FLAG --python-version $PYTHON_VERSION --only-binary=:all:" echo "Step 3/5: Resolving all dependencies..." echo "----------------------------------------" if ! "$VENV_DIR/bin/pip-compile" --pip-args "$GLUE_PIP_ARGS" --no-emit-index-url --output-file "$TEMP_WORKING_DIR/.compiled_requirements.txt" "$REQUIREMENTS_FILE"; then echo "Error: Failed to resolve dependencies. Check for conflicts in $REQUIREMENTS_FILE" exit 1 fi echo "✓ Dependencies resolved successfully" echo "" # Download all wheels for dependencies echo "Step 4/5: Downloading all dependency wheels..." echo "----------------------------------------" "$VENV_DIR/bin/pip" download -r "$TEMP_WORKING_DIR/.compiled_requirements.txt" -d "$WHEEL_OUTPUT_DIRECTORY" $GLUE_PIP_ARGS # Check if any wheels were downloaded if [ ! "$(ls -A "$WHEEL_OUTPUT_DIRECTORY")" ]; then echo "Error: No wheels were downloaded. Check your requirements file." exit 1 fi # Count downloaded wheels (using find instead of ls for better handling) WHEEL_COUNT=$(find "$WHEEL_OUTPUT_DIRECTORY" -name "*.whl" -type f | wc -l | tr -d ' ') echo "✓ Downloaded $WHEEL_COUNT dependency wheels successfully" echo "" # Create a single uber wheel with all dependencies echo "Step 5/5: Creating uber wheel with all dependencies included..." echo "----------------------------------------" # Create a temporary directory for the uber wheel UBER_WHEEL_DIR="$TEMP_WORKING_DIR/uber" mkdir -p "$UBER_WHEEL_DIR" # Create the setup.py file with custom install command cat >"$UBER_WHEEL_DIR/setup.py" <<EOF from setuptools import setup, find_packages import setuptools.command.install import os import glob import subprocess import sys setup( name='${PACKAGE_NAME}', version='${PACKAGE_VERSION}', description='Bundle containing dependencies for ${PACKAGE_NAME}', author='Package Builder', author_email='builder@example.com', packages=['${PACKAGE_NAME}'], # Include the package directory to hold wheels include_package_data=True, package_data={ '${PACKAGE_NAME}': ['wheels/*.whl'], # Include wheels in the package directory } ) EOF # Create a MANIFEST.in file to include all wheels cat >"$UBER_WHEEL_DIR/MANIFEST.in" <<EOF recursive-include ${PACKAGE_NAME}/wheels *.whl EOF # Create an __init__.py file that imports all the bundled wheel files (no auto-install logic) mkdir -p "$UBER_WHEEL_DIR/${PACKAGE_NAME}" cat >"$UBER_WHEEL_DIR/${PACKAGE_NAME}/__init__.py" <<EOF """ ${PACKAGE_NAME} - dependencies can be installed at runtime using the $(load_wheels) function """ from pathlib import Path import logging import subprocess import sys __version__ = "${PACKAGE_VERSION}" def load_wheels(log_level=logging.INFO): logger = logging.getLogger(__name__) handler = logging.StreamHandler(sys.stdout) formatter = logging.Formatter("[Glue Python Wheel Installer] %(asctime)s - %(name)s - %(levelname)s - %(message)s") handler.setFormatter(formatter) logger.addHandler(handler) logger.setLevel(log_level) logger.info("Starting wheel installation process") package_dir = Path(__file__).parent.absolute() wheels_dir = package_dir / "wheels" logger.debug(f"Package directory: {package_dir}") logger.debug(f"Looking for wheels in: {wheels_dir}") if not wheels_dir.exists(): logger.error(f"Wheels directory not found: {wheels_dir}") return False wheel_files = list(wheels_dir.glob("*.whl")) if not wheel_files: logger.warning(f"No wheels found in: {wheels_dir}") return False logger.info(f"Found {len(wheel_files)} wheels") wheel_file_paths = [str(wheel_file) for wheel_file in wheel_files] logger.info(f"Installing {wheel_file_paths}...") try: result = subprocess.run( [sys.executable, "-m", "pip", "install", *wheel_file_paths], check=True, capture_output=True, text=True ) logger.info(f"✓ Successfully installed wheel files") logger.debug(f"pip output: {result.stdout}") except subprocess.CalledProcessError as e: error_msg = f"Failed to install wheel files" logger.error(f"✗ {error_msg}: {e}") if e.stderr: logger.error(f"Error details: {e.stderr}") return False logger.info("All wheels installed successfully") return True EOF cat >"$UBER_WHEEL_DIR/${PACKAGE_NAME}/auto.py" <<EOF """ ${PACKAGE_NAME} - utility module that allows users to automatically install modules by adding $(import ${PACKAGE_NAME}.auto) to the top of their script """ from ${PACKAGE_NAME} import load_wheels load_wheels() EOF # Copy all wheels to the uber wheel directory mkdir -p "$UBER_WHEEL_DIR/${PACKAGE_NAME}/wheels" cp "$WHEEL_OUTPUT_DIRECTORY"/*.whl "$UBER_WHEEL_DIR/${PACKAGE_NAME}/wheels/" # Build the uber wheel echo "Building uber wheel package..." # Install build tools in the current environment "$VENV_DIR/bin/pip" install build if ! (cd "$UBER_WHEEL_DIR" && "$VENV_DIR/bin/python" -m build --skip-dependency-check --wheel --outdir .); then echo "Error: Failed to build uber wheel" exit 1 fi # Ensure output directory exists mkdir -p "$FINAL_WHEEL_OUTPUT_DIRECTORY" # Copy the uber wheel to the output directory FINAL_WHEEL_OUTPUT_PATH="$FINAL_WHEEL_OUTPUT_DIRECTORY/$UBER_WHEEL_NAME" # Find the generated wheel (should be only one in the root directory) GENERATED_WHEEL=$(find "$UBER_WHEEL_DIR" -maxdepth 1 -name "*.whl" -type f | head -1) if [ -z "$GENERATED_WHEEL" ]; then echo "Error: No uber wheel was generated" exit 1 fi cp "$GENERATED_WHEEL" "$FINAL_WHEEL_OUTPUT_PATH" # Get final wheel size for user feedback WHEEL_SIZE=$(du -h "$FINAL_WHEEL_OUTPUT_PATH" | cut -f1) echo "✓ Uber wheel created successfully!" echo "" echo "=========================================" echo "BUILD COMPLETED SUCCESSFULLY!" echo "=========================================" echo "Final wheel: $FINAL_WHEEL_OUTPUT_PATH" echo "Wheel size: $WHEEL_SIZE" echo "Dependencies included: $WHEEL_COUNT packages" echo "" echo "To install the bundle, run:" echo " pip install $FINAL_WHEEL_OUTPUT_PATH" echo "" echo "After installation, you can verify that the bundle works by running:" echo " python -c \"import ${PACKAGE_NAME}; ${PACKAGE_NAME}.load_wheels()\"" echo " or " echo " python -c \"import ${PACKAGE_NAME}.auto\"" echo "========================================="

./wheel_packager.sh -r <path to requirements.txt> -g <glue version> -o <wheel output directory> -n <package name> -v <wheel version>

--additional-python-modules s3://your-bucket/path/to/package_with_dependencies-1.0.0-py3-none-any.whl

# Option 1: automatic installation via import import package_with_dependencies.auto # Option 2: manual installation from package_with_dependencies import load_wheels load_wheels()

Integrazione di file Python con funzionalità native di PySpark

AWS Glue utilizza PySpark per includere i file Python nei processi ETL di AWS Glue. Quando possibile, ti consigliamo di usare --additional-python-modules per gestire le dipendenze. Puoi utilizzare il parametro del processo --extra-py-files per includere i file Python. Le dipendenze devono essere ospitate in Amazon S3 e il valore dell'argomento deve essere un elenco delimitato da virgole di percorsi Amazon S3 senza spazi. Questa funzionalità si comporta come la gestione delle dipendenze Python che useresti con Spark. Per ulteriori informazioni sulla gestione delle dipendenze Python in Spark, consulta la pagina Utilizzo delle funzionalità native di PySpark nella documentazione di Apache Spark. --extra-py-files è utile nei casi in cui il codice aggiuntivo non è contenuto in un pacchetto o quando si esegue la migrazione di un programma Spark con una toolchain esistente per la gestione delle dipendenze. Affinché gli strumenti di dipendenza siano gestibili, sarà necessario raggruppare le dipendenze prima di inviarle.

Script di programmazione che utilizzano trasformazioni visive

Quando si crea un processo AWS Glue utilizzando l'interfaccia visiva di AWS Glue Studio, è possibile trasformare i dati con nodi di trasformazione dati gestiti e trasformazioni visive personalizzate. Per ulteriori informazioni sui nodi di trasformazione dei dati, consultare Trasformare i dati con AWS Glue trasformazioni gestite. Per ulteriori informazioni sulle trasformazioni visive, consultare Trasforma i dati con le trasformazioni visive personalizzate . Gli script che utilizzano le trasformazioni visive possono essere generati solo quando il linguaggio del processo è impostato per utilizzare Python.

Quando si genera un lavoro AWS Glue utilizzando le trasformazioni visive, AWS Glue Studio include queste trasformazioni nell'ambiente di runtime utilizzando il parametro --extra-py-files nella configurazione del lavoro. Per ulteriori informazioni sui parametri di processo, consulta Utilizzo dei parametri del processo nei processi AWS Glue. Quando a si apportano modifiche a uno script o a un ambiente di runtime generato, è necessario mantenere questa configurazione del lavoro affinché lo script venga eseguito correttamente.

Compressione delle librerie per l'inclusione

A meno che una libreria non sia contenuta in un singolo file .py, deve essere compressa in un archivio .zip. La directory del pacchetto deve trovarsi al livello radice dell'archivio e deve contenere un file __init__.py per il pacchetto. Python sarà in grado di importare il pacchetto nel modo normale.

Se la tua libreria è composta da un singolo modulo Python in un file .py, non è necessario trasferirla in un file .zip.

Caricamento di librerie Python nei notebook AWS Glue Studio

Per specificare le librerie Python nei notebook AWS Glue Studio, consultare Installazione di moduli Python aggiuntivi.

Caricamento di librerie Python in un endpoint di sviluppo in AWS Glue 0.9/1.0

Se utilizzi diversi set di librerie per diversi script ETL, puoi impostare un endpoint di sviluppo separato per ciascun set oppure sovrascrivere i file .zip della libreria che l'endpoint di sviluppo carica ogni volta che si cambia script.

Puoi utilizzare la console per specificare uno o più file .zip di libreria per un endpoint di sviluppo al momento della creazione. Dopo l'assegnazione di un nome e un ruolo IAM, scegli Script Libraries and job parameters (optional) (Librerie di Script e parametri di processo -opzionale) e immetti il percorso Amazon S3 completo per i tuoi file .zip della libreria nella casella Python library path (Percorso libreria Python). Ad esempio:

s3://bucket/prefix/site-packages.zip

Se lo desideri, puoi specificare più percorsi completi per i file, separandoli con virgole ma non spazi, in questo modo:

s3://bucket/prefix/lib_A.zip,s3://bucket_B/prefix/lib_X.zip

Se aggiorni questi file .zip in un secondo momento, puoi utilizzare la console per importarli nuovamente nell'endpoint di sviluppo. Individua l'endpoint dello sviluppatore in questione, verifica la casella a esso corrispondente e scegli Update ETL libraries (Aggiorna librerie ETL) dal menu Action (Operazione).

Analogamente, puoi specificare i file della libreria usando le API AWS Glue. Quando crei un endpoint di sviluppo chiamando Operazione CreateDevEndpoint (Python: create_dev_endpoint), puoi specificare uno o più percorsi completi per le librerie nel parametro ExtraPythonLibsS3Path in una chiamata come la seguente:

dep = glue.create_dev_endpoint( EndpointName="testDevEndpoint", RoleArn="arn:aws:iam::123456789012", SecurityGroupIds="sg-7f5ad1ff", SubnetId="subnet-c12fdba4", PublicKey="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCtp04H/y...", NumberOfNodes=3, ExtraPythonLibsS3Path="s3://bucket/prefix/lib_A.zip,s3://bucket_B/prefix/lib_X.zip")

Quando aggiorni un endpoint di sviluppo, puoi anche aggiornare le librerie caricate utilizzando un oggetto DevEndpointCustomLibraries e impostare il parametro UpdateEtlLibraries su True durante la chiamata UpdateDevEndpoint (update_dev_endpoint).

Utilizzo di librerie Python in un processo o JobRun

Quando si crea un nuovo processo nella console, è possibile specificare uno o più file ZIP di libreria scegliendo Script Libraries and job parameters (optional) (Librerie di script e parametri di processo - opzionale) e immettendo percorsi di librerie Amazon S3 completi, analogamente a come si farebbe quando si crea un endpoint di sviluppo:

s3://bucket/prefix/lib_A.zip,s3://bucket_B/prefix/lib_X.zip

Se si sta chiamando CreateJob (create_job), è possibile specificare uno o più percorsi completi alle librerie predefinite utilizzando il parametro predefinito --extra-py-files, come segue:

job = glue.create_job(Name='sampleJob', Role='Glue_DefaultRole', Command={'Name': 'glueetl', 'ScriptLocation': 's3://my_script_bucket/scripts/my_etl_script.py'}, DefaultArguments={'--extra-py-files': 's3://bucket/prefix/lib_A.zip,s3://bucket_B/prefix/lib_X.zip'})

Quindi, quando si avvia un JobRun, è possibile sovrascrivere l'impostazione della libreria predefinita con una diversa:

runId = glue.start_job_run(JobName='sampleJob', Arguments={'--extra-py-files': 's3://bucket/prefix/lib_B.zip'})

Analizza in modo proattivo le dipendenze di Python

Per identificare in modo proattivo potenziali problemi di dipendenza prima della distribuzione su AWS Glue, puoi utilizzare lo strumento di analisi delle dipendenze per convalidare i tuoi pacchetti Python rispetto all'ambiente AWS Glue di destinazione.

AWS fornisce uno strumento di analisi delle dipendenze Python open source progettato specificamente per gli ambienti AWS Glue. Questo strumento è disponibile nel repository degli esempi AWS Glue e può essere utilizzato localmente per convalidare le dipendenze prima dell'implementazione.

Questa analisi aiuta a garantire che le dipendenze seguano la pratica consigliata del pinning di tutte le versioni della libreria per implementazioni di produzione coerenti. Per maggiori dettagli, consultare la sezione README dello strumento.

AWS Glue Python Dependency Analyzer aiuta a identificare le dipendenze non bloccate e i conflitti di versione simulando l'installazione pip con vincoli specifici della piattaforma che corrispondono all'ambiente AWS Glue di destinazione.

# Analyze a single Glue job python glue_dependency_analyzer.py -j my-glue-job # Analyze multiple jobs with specific AWS configuration python glue_dependency_analyzer.py -j job1 -j job2 --aws-profile production --aws-region us-west-2

Lo strumento contrassegnerà:

  • Dipendenze non bloccate che potrebbero installare versioni diverse tra le esecuzioni dei processi

  • Conflitti delle versioni tra pacchetti

  • Dipendenze non disponibili per l'ambiente AWS Glue di destinazione

Amazon Q Developer è un assistente conversazionale basato sull'intelligenza artificiale (IA) generativa che permette di comprendere, creare, estendere e utilizzare al meglio le applicazioni AWS. È possibile scaricarlo seguendo le istruzioni nella Guida alle nozioni di base per Amazon Q.

Amazon Q Developer può essere usato per analizzare e correggere gli errori nei processi dovuti alle dipendenze Python. Suggeriamo di utilizzare il seguente prompt sostituendo il placeholder <Job-Name> con il nome del processo Glue.

I have an AWS Glue job named <Job-Name> that has failed due to Python module installation conflicts. Please assist in diagnosing and resolving this issue using the following systematic approach. Proceed once sufficient information is available. Objective: Implement a fix that addresses the root cause module while minimizing disruption to the existing working environment. Step 1: Root Cause Analysis • Retrieve the most recent failed job run ID for the specified Glue job • Extract error logs from CloudWatch Logs using the job run ID as a log stream prefix • Analyze the logs to identify: • The recently added or modified Python module that triggered the dependency conflict • The specific dependency chain causing the installation failure • Version compatibility conflicts between required and existing modules Step 2: Baseline Configuration Identification • Locate the last successful job run ID prior to the dependency failure • Document the Python module versions that were functioning correctly in that baseline run • Establish the compatible version constraints for conflicting dependencies Step 3: Targeted Resolution Implementation • Apply pinning by updating the job's additional_python_modules parameter • Pin only the root cause module and its directly conflicting dependencies to compatible versions, and do not remove python modules unless necessary • Preserve flexibility for non-conflicting modules by avoiding unnecessary version constraints • Deploy the configuration changes with minimal changes to the existing configuration and execute a validation test run. Do not change the Glue versions. Implementation Example: Scenario: Recently added pandas==2.0.0 to additional_python_modules Error: numpy version conflict (pandas 2.0.0 requires numpy>=1.21, but existing job code requires numpy<1.20) Resolution: Update additional_python_modules to "pandas==1.5.3,numpy==1.19.5" Rationale: Use pandas 1.5.3 (compatible with numpy 1.19.5) and pin numpy to last known working version Expected Outcome: Restore job functionality with minimal configuration changes while maintaining system stability.

Il prompt indica a Q di:

  1. Recuperare l'ultimo ID di esecuzione dei processi non riuscito

  2. Trovare i log associati e i dettagli

  3. Trovare le esecuzioni dei processi riuscite per rilevare eventuali pacchetti Python modificati

  4. Apportare eventuali correzioni alla configurazione e avviare un'altra esecuzione di test

Moduli Python già forniti in AWS Glue

È possibile modificare la versione dei moduli disponibili con il parametro di processo --additional-python-modules.

AWS Glue version 5.0

AWS Glue versione 5.0 supporta i seguenti moduli Python per impostazione predefinita:

  • aiobotocore==2.13.1

  • aiohappyeyeballs==2.3.5

  • aiohttp==3.10.1

  • aioitertools==0.11.0

  • aiosignal==1.3.1

  • appdirs==1.4.4

  • attrs==24.2.0

  • boto3==1.34.131

  • botocore==1.34.131

  • certifi==2024.7.4

  • charset-normalizer==3.3.2

  • contourpy==1.2.1

  • cycler==0.12.1

  • fonttools==4.53.1

  • frozenlist==1.4.1

  • fsspec==2024.6.1

  • idna==2.10

  • jmespath==0.10.0

  • kaleido==0.2.1

  • kiwisolver==1.4.5

  • matplotlib==3.9.0

  • multidict==6.0.5

  • numpy==1.26.4

  • packaging==24.1

  • pandas==2.2.2

  • pillow==10.4.0

  • pip==23.0.1

  • plotly==5.23.0

  • pyarrow==17.0.0

  • pyparsing==3.1.2

  • python-dateutil==2.9.0.post0

  • pytz==2024.1

  • requests==2.32.2

  • s3fs==2024.6.1

  • s3transfer==0.10.2

  • seaborn==0.13.2

  • setuptools==59.6.0

  • six==1.16.0

  • tenacity==9.0.0

  • tzdata==2024.1

  • urllib3==1.25.10

  • virtualenv==20.4.0

  • wrapt==1.16.0

  • yarl==1.9.4

AWS Glue version 4.0

AWS Glue versione 4.0 supporta i seguenti moduli Python per impostazione predefinita:

  • aiobotocore==2.4.1

  • aiohttp==3.8.3

  • aioitertools==0.11.0

  • aiosignal==1.3.1

  • async-timeout==4.0.2

  • asynctest==0.13.0

  • attrs==22.2.0

  • avro-python3==1.10.2

  • boto3==1.24.70

  • botocore==1.27.59

  • certifi==2021.5.30

  • chardet==3.0.4

  • charset-normalizer==2.1.1

  • click==8.1.3

  • cycler==0.10.0

  • Cython==0.29.32

  • fsspec==2021.8.1

  • idna==2.10

  • importlib-metadata==5.0.0

  • jmespath==0.10.0

  • joblib==1.0.1

  • kaleido==0.2.1

  • kiwisolver==1.4.4

  • matplotlib==3.4.3

  • mpmath==1.2.1

  • multidict==6.0.4

  • nltk==3.7

  • numpy==1.23.5

  • packaging==23.0

  • pandas == 1.5.1

  • patsy==0.5.1

  • Pillow==9.4.0

  • pip==23.0.1

  • plotly==5.16.0

  • pmdarima==2.0.1

  • ptvsd==4.3.2

  • pyarrow==10.0.0

  • pydevd==2.5.0

  • pyhocon==0.3.58

  • PyMySQL==1.0.2

  • pyparsing==2.4.7

  • python-dateutil==2.8.2

  • pytz==2021.1

  • PyYAML==6.0.1

  • regex==2022.10.31

  • requests==2.23.0

  • s3fs==2022.11.0

  • s3transfer==0.6.0

  • scikit-learn==1.1.3

  • scipy==1.9.3

  • setuptools==49.1.3

  • six==1.16.0

  • statsmodels==0.13.5

  • subprocess32==3.5.4

  • sympy==1.8

  • tbats==1.1.0

  • threadpoolctl==3.1.0

  • tqdm==4.64.1

  • typing_extensions==4.4.0

  • urllib3==1.25.11

  • wheel==0.37.0

  • wrapt==1.14.1

  • yarl==1.8.2

  • zipp==3.10.0

AWS Glue version 3.0

AWS Glue versione 3.0 supporta i seguenti moduli Python per impostazione predefinita:

  • aiobotocore==1.4.2

  • aiohttp==3.8.3

  • aioitertools==0.11.0

  • aiosignal==1.3.1

  • async-timeout==4.0.2

  • asynctest==0.13.0

  • attrs==22.2.0

  • avro-python3==1.10.2

  • boto3==1.18.50

  • botocore==1.21.50

  • certifi==2021.5.30

  • chardet==3.0.4

  • charset-normalizer==2.1.1

  • click==8.1.3

  • cycler==0.10.0

  • Cython==0.29.4

  • docutils==0.17.1

  • enum34==1.1.10

  • frozenlist==1.3.3

  • fsspec==2021.8.1

  • idna==2.10

  • importlib-metadata==6.0.0

  • jmespath==0.10.0

  • joblib==1.0.1

  • kiwisolver==1.3.2

  • matplotlib==3.4.3

  • mpmath==1.2.1

  • multidict==6.0.4

  • nltk==3.6.3

  • numpy==1.19.5

  • packaging==23.0

  • pandas==1.3.2

  • patsy==0.5.1

  • Pillow==9.4.0

  • pip==23.0

  • pmdarima==1.8.2

  • ptvsd==4.3.2

  • pyarrow==5.0.0

  • pydevd==2.5.0

  • pyhocon==0.3.58

  • PyMySQL==1.0.2

  • pyparsing==2.4.7

  • python-dateutil==2.8.2

  • pytz==2021.1

  • PyYAML==5.4.1

  • regex==2022.10.31

  • requests==2.23.0

  • s3fs==2021.8.1

  • s3transfer==0.5.0

  • scikit-learn==0.24.2

  • scipy==1.7.1

  • six==1.16.0

  • Spark==1.0

  • statsmodels==0.12.2

  • subprocess32==3.5.4

  • sympy==1.8

  • tbats==1.1.0

  • threadpoolctl==3.1.0

  • tqdm==4.64.1

  • typing_extensions==4.4.0

  • urllib3==1.25.11

  • wheel==0.37.0

  • wrapt==1.14.1

  • yarl==1.8.2

  • zipp==3.12.0

AWS Glue version 2.0

AWS Glue versione 2.0 supporta i seguenti moduli Python per impostazione predefinita:

  • avro-python3==1.10.0

  • awscli==1.27.60

  • boto3==1.12.4

  • botocore==1.15.4

  • certifi==2019.11.28

  • chardet==3.0.4

  • click==8.1.3

  • colorama==0.4.4

  • cycler==0.10.0

  • Cython==0.29.15

  • docutils==0.15.2

  • enum34==1.1.9

  • fsspec==0.6.2

  • idna==2.9

  • importlib-metadata==6.0.0

  • jmespath==0.9.4

  • joblib==0.14.1

  • kiwisolver==1.1.0

  • matplotlib==3.1.3

  • mpmath==1.1.0

  • nltk==3.5

  • numpy==1.18.1

  • pandas==1.0.1

  • patsy==0.5.1

  • pmdarima==1.5.3

  • ptvsd==4.3.2

  • pyarrow==0.16.0

  • pyasn1==0.4.8

  • pydevd==1.9.0

  • pyhocon==0.3.54

  • PyMySQL==0.9.3

  • pyparsing==2.4.6

  • python-dateutil==2.8.1

  • pytz==2019.3

  • PyYAML==5.3.1

  • regex==2022.10.31

  • requests==2.23.0

  • rsa==4.7.2

  • s3fs==0.4.0

  • s3transfer==0.3.3

  • scikit-learn==0.22.1

  • scipy==1.4.1

  • setuptools==45.2.0

  • six==1.14.0

  • Spark==1.0

  • statsmodels==0.11.1

  • subprocess32==3.5.4

  • sympy==1.5.1

  • tbats==1.0.9

  • tqdm==4.64.1

  • typing-extensions==4.4.0

  • urllib3==1.25.8

  • wheel==0.35.1

  • zipp==3.12.0