5
votes

Est-il possible d'ajouter des chemins à la variable d'environnement PATH via serverless.yml?

Lorsque je crée une couche AWS Lambda, tous les contenus / modules de mon fichier zip vont dans / opt / lorsque AWS Lambda s'exécute. Cela devient facilement encombrant et frustrant car je dois utiliser des importations absolues sur tous mes lambdas. Exemple:

import json
import os
import importlib.util
spec = importlib.util.spec_from_file_location("dynamodb_layer.customer", "/opt/dynamodb_layer/customer.py")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)

def fetch(event, context):

    CustomerManager = module.CustomerManager
    customer_manager = CustomerManager()

    body = customer_manager.list_customers(event["queryStringParameters"]["acquirer"])

    response = {
        "statusCode": 200,
        "headers": {
            "Access-Control-Allow-Origin": "*"
        },
        "body": json.dumps(body)
    }

    return response

Alors je me demandais, est-il possible d'ajouter ces chemins / opt / à la variable d'environnement PATH au préalable via serverless.yml? De cette façon, je pourrais simplement depuis dynamodb_layer.customer importer CustomerManager , au lieu de cette laideur bizarre.


0 commentaires

4 Réponses :


0
votes

Avez-vous essayé de paramétrer votre PYTHONPATH env var? https://stackoverflow.com/a/5944201/6529424

Avez-vous essayé d'ajouter à sys.path? https://stackoverflow.com/a/12257807/6529424


1 commentaires

Ce ne sont pas des méthodes idiomatiques pour ajouter des modules et des packages importables à l'aide de couches Lambda. Voir ci-dessous.



1
votes

J'ai une couche Lambda pour l'exécution Python3.6. Ma structure my_package.zip est:

layers:
  my_package:
    path: build             
    compatibleRuntimes:     
      - python3.6

Toutes les dépendances sont dans le dossier build à la racine du projet: par exemple. build/python/lib/python3.6/site-packages/customer

Section pertinente de mon serverless.yml

my_package.zip
 - python
   - lib
     - python3.6
       - site-packages
         - customer

Dans mon Lambda, j'importe mon package comme je le ferais pour n'importe quel autre package: importer un client


2 commentaires

Savez-vous s'il existe un moyen de définir le chemin d'accès sans serveur? J'ai un tas de fichiers que je ne veux pas avoir à compresser dans une structure de répertoire spécifique, mais j'aimerais qu'ils se retrouvent dans /opt/python/lib/python3.6/site-packages / shared . Y a-t-il un moyen de faire cela sans les organiser dans la même structure de répertoires dans git?


@Craig Votre script de construction peut manipuler les répertoires comme bon lui semble, avant de les empaqueter dans un fichier zip. Ceci est généralement appelé «mise en scène». Dans ce cas, votre build créerait un répertoire appelé 'python' puis y copierait les fichiers requis et les packages, avant de créer le zip et de le télécharger en tant que couche. Voir ma réponse par exemple!




0
votes

Le paramétrage de la variable PYTHONPATH n'est pas obligatoire, tant que vous placez correctement les éléments dans le fichier zip.

Modules simples et répertoires de packages, ceux-ci doivent être placés dans un répertoire "python", puis tout le python / placé dans le fichier zip pour le téléchargement vers AWS en tant que couche. N'oubliez pas d'ajouter les paramètres "runtimes compatibles" (par exemple Python 3.6, 3.7, 3.8 ...) pour les couches.

Donc à titre d'exemple:

import json
import os

def lambda_handler(event, context):
    # TODO implement

    dir_list = os.listdir('/opt/python/')

    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!'),
        'event': json.dumps(event),
        '/opt/python/': dir_list
    }


0 commentaires