Les couches Lambda AWS sont une belle façon de pouvoir réutiliser le code avec vos différentes lambdas. J'ai vu de nombreux tutoriels sur la façon de créer des couches pour les packages PIP existants, mais pas autant d'expliquer comment le faire avec votre propre code et vous permettant de le déboguer avec votre lambda. Dans mon scénario, vous pouvez avoir votre couche et plusieurs lambdas en utilisant cette couche et déboguer le code des lambdas et la couche en simulant l'environnement AWS. Je suppose que vous avez déjà une fonction lambda créée avec son modèle.yml. Sinon, consultez l'article suivant sur la façon de créer un Lambda https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html. Après l'avoir créé, vous pouvez le télécharger sous forme de fichier zip et extraire le code et le modèle.yml à partir de là.
Tout d'abord, nous devons configurer la structure du dossier pour la couche. J'aime créer un dossier appelé couches, et pour chaque couche créez son propre dossier. AWS Lambda a besoin d'une structure de dossier spécifique pour les couches, où réside le code de chaque couche dans un dossier Python /. Voir le lien suivant pour plus d'informations à ce sujet. https://docs.aws.amazon.com/lambda/latest/dg/packaging-layers.html
Notre couche sera appelée couche_utils. Nous mettons ensuite un dossier Layer_UTILS à l'intérieur du dossier Python et à l'intérieur, nous créons les fichiers request_handler.py et processor.py avec le code. Nous avons également besoin d'un fichier vide init .py, qui est nécessaire pour que Python reconnaisse cela comme un package. C'est à quoi devrait ressembler la structure des arbres
layers/ └── layer_utils/ └── python/ ├── layer_utils/ │ ├── __init__.py │ └── request_handler.py │ └── processor.py
Le request_handler.py recevra une demande avec une URL, et appelle le processeur qui utilisera les demandes de bibliothèque pour obtenir les données et les renvoyer.
./ couches / couche_utils / python / couche_utils / processeur.py
import requests def process_data(url): """ Fetches data from a URL. Args: url (str): The URL to fetch data from. Returns: str: The fetched content or an error message. """ try: response = requests.get(url) response.raise_for_status() # Raise an error for bad status codes return response.text[:200] # Return the first 200 characters of the response except requests.RequestException as e: return f"Error fetching data: {str(e)}"
./ couches / couche_utils / python / couche_utils / request_handler.py
from layer_utils.processor import process_data def handle_request(request): """ Handles an incoming request and processes it. Args: request (dict): The input request data. Returns: dict: The processed result. """ # Example: Extract 'url' from the request and process it if "url" not in request: return {"error": "Missing 'data' in request"} data = request["url"] processed_result = process_data(data) return {"result": processed_result}
Ici, il est important de noter comment nous importons les fonctions du processeur, en appelant à partir de couche_utils.processor import process_data, au lieu de processeur import process_data uniquement. L'utilisation du chemin absolu permet d'éviter les erreurs d'importation plus tard.
Très bien, maintenant nous avons créé notre code de couche. Mais nous n'en avons pas encore fini avec. Nous devons maintenant créer un package modifiable avec PIP afin que cela puisse être utilisé par notre code Lambda. Nous suivrons le style PEP 660 pour le faire. Nous devons créer deux fichiers: exigences.txt et pyproject.toml. Le premier comprendra toutes les bibliothèques externes dont nous avons besoin pour cette couche, dans cette demande de cas. Le second est le fichier dont nous avons besoin pour créer un package modifiable à l'aide de PIP et garantir que toutes les dépendances sont installées. Cela permet de modifier le code de couche sans avoir besoin de le reconditionner constamment (que nous devons déboguer).
C'est à quoi devrait ressembler l'arbre
└── layer_utils └── python ├── layer_utils │ ├── __init__.py │ ├── processor.py │ └── request_handler.py ├── pyproject.toml └── requirements.txt
Le pyproject.toml sera utilisé par PIP pour créer le package avec notre couche.
./ couches / couche_utils / python / pyproject.toml
layers/ └── layer_utils/ └── python/ ├── layer_utils/ │ ├── __init__.py │ └── request_handler.py │ └── processor.py
Dans ce fichier, le package Setuptools est nécessaire pour créer le package et le package de roues est utilisé pour emballer le code dans un format distribuable.
Les exigences.txt indiquent tous les modules externes dont nos couches ont besoin. Dans notre cas, nous n'avons besoin que du module de demande, mais vous pouvez en ajouter autant que nécessaire.
./ couches / couche_utils / python / exigences.txt
import requests def process_data(url): """ Fetches data from a URL. Args: url (str): The URL to fetch data from. Returns: str: The fetched content or an error message. """ try: response = requests.get(url) response.raise_for_status() # Raise an error for bad status codes return response.text[:200] # Return the first 200 characters of the response except requests.RequestException as e: return f"Error fetching data: {str(e)}"
Je pense qu'il est important de suivre la version de votre package que vous utilisez, car vos packages externes seront importés en appelant votre ressource de couche Lambda AWS directement à partir d'AWS. Si vous déboguez directement sur votre système en exécutant votre Lambda directement à partir de votre environnement Python au lieu d'utiliser SAM Local Invoke ou SAM Local Start-API, vous devrez vous assurer que vos packages locaux installés avec PIP seront les mêmes que votre déployé packages dans votre couche. Je n'expliquerai pas comment créer les couches externes car il existe de nombreux bons tutoriels pour cela (par exemple, ce https://www.keyq.cloud/en/blog/creating-an-aws-lambda-layer-for- python-requests-module
).
Créons maintenant un environnement virtuel. Ce n'est pas nécessaire, mais il est recommandé, car il isole les dépendances et garantit que l'environnement Python est cohérent avec celui que Lambda utilisera. Pour ce faire, dans la console de votre projet DIR, entrée
from layer_utils.processor import process_data def handle_request(request): """ Handles an incoming request and processes it. Args: request (dict): The input request data. Returns: dict: The processed result. """ # Example: Extract 'url' from the request and process it if "url" not in request: return {"error": "Missing 'data' in request"} data = request["url"] processed_result = process_data(data) return {"result": processed_result}
Le premier fait que Python exécute le module VENV avec -m VENV et créent un environnement virtuel appelé VENV.
Le second active l'environnement virtuel en appelant la source de commande intégrée qui exécute le script d'activation de l'environnement virtuel. Si vous utilisez Visual Studio Code, cela pourrait vous inciter à passer à l'environnement virtuel. Dites oui.
Après cela, vous devriez voir dans votre coquille quelque chose comme ça.
└── layer_utils └── python ├── layer_utils │ ├── __init__.py │ ├── processor.py │ └── request_handler.py ├── pyproject.toml └── requirements.txt
Le (VENV) au début indique que vous êtes sur l'environnement virtuel.
Parfois, j'aime déboguer en exécutant le fichier Python directement plutôt qu'avec les outils SAM (car c'est plus rapide). Pour ce faire, je vais installer tous les packages externes sur mon environnement virtuel afin que je puisse les utiliser localement pour le développement et le débogage.
[project] name = "layer_utils" version = "0.1.0" [build-system] requires = ["setuptools", "wheel"] build-backend = "setuptools.build_meta"
Ceci est nécessaire pour déboguer localement et directement sans les outils SAM, vous pouvez donc ignorer cette étape si vous ne prévoyez pas de le faire.
Nous devons maintenant emballer le calque, afin que notre Lambda puisse trouver le calque comme un package Python.
requests==2.32.2
Le drapeau -e indique qu'il s'agit d'un package modifiable. Le chemin pointe vers où le fichier pyproject.toml est. En fonctionnement, cela créera un nouveau dossier Layer_UTILS.Egg-Info. Rien à faire là-bas, laissez-le.
Ok, voyons maintenant comment nous y déboguerions. Ceci est ma structure de dossiers avec les couches et les lambdas.
layers/ └── layer_utils/ └── python/ ├── layer_utils/ │ ├── __init__.py │ └── request_handler.py │ └── processor.py
Ceci est le code de mon lambda
import requests def process_data(url): """ Fetches data from a URL. Args: url (str): The URL to fetch data from. Returns: str: The fetched content or an error message. """ try: response = requests.get(url) response.raise_for_status() # Raise an error for bad status codes return response.text[:200] # Return the first 200 characters of the response except requests.RequestException as e: return f"Error fetching data: {str(e)}"
Vous pouvez exécuter le fichier et vous devez obtenir un résultat valide sans erreurs.
Si vous utilisez le code Visual Studio avec Pylance, vous pouvez voir que l'importation de la couche ne se résout pas même si le code a fonctionné.
Pour résoudre ce problème, vous pouvez modifier les paramètres.json de votre espace de travail. Faire le décalage de contrôle / commande p, entrez les préférences: ouvrez les paramètres de l'espace de travail (JSON) et ajoutez ce qui suit à l'intérieur des supports (si vous avez plus d'extrapathes, ajoutez simplement le chemin)
from layer_utils.processor import process_data def handle_request(request): """ Handles an incoming request and processes it. Args: request (dict): The input request data. Returns: dict: The processed result. """ # Example: Extract 'url' from the request and process it if "url" not in request: return {"error": "Missing 'data' in request"} data = request["url"] processed_result = process_data(data) return {"result": processed_result}
Maintenant, le pylance devrait résoudre cette amende.
Nous devons maintenant configurer le calque sur votre modèle Lambdas.yml. Nous devons ajouter ce qui suit dans la section Ressources: (adaptez le contenu selon votre projet)
./ lambdas / mylambda / template.yml
└── layer_utils └── python ├── layer_utils │ ├── __init__.py │ ├── processor.py │ └── request_handler.py ├── pyproject.toml └── requirements.txt
Dans le contenuturi, vous pouvez voir comment il se réfère au chemin relatif où se trouve le code de couche. Voyez comment il ne pointe pas vers le dossier Python, car le système AWS SAM recherchera le dossier Python là-bas. Assurez-vous que le runtime correspond à celui que vous utilisez dans votre environnement virtuel et votre Lamnbda.
En outre, vous devez référencer la couche sur la section Lambda du fichier
[project] name = "layer_utils" version = "0.1.0" [build-system] requires = ["setuptools", "wheel"] build-backend = "setuptools.build_meta"
Notez que dans la section Calques du fichier de modèle, nous avons également la couche de demandes qui est déjà sur notre AWS. Cela créera la couche localement, donc Sam saura qu'il doit le lire. Il déploiera également cette couche sur AWS chaque fois que vous appelez AWS Deploy.
Testons cela. Construisons-le en premier. J'ai eu des problèmes avec la construction du modèle à partir d'un chemin différent de l'endroit où il est parce que dans le modèle, il y a des indications sur l'endroit où se trouve le code source. Pour éviter cela, je recommande de le construire directement à partir du chemin du fichier de modèle.
requests==2.32.2
Cela créera toutes les dépendances nécessaires.
Maintenant, nous pouvons l'invoquer. J'ai créé un fichier d'événements pour tester le lambda
./ lambdas / mylambda / événements / événement.json
python3.12 -m venv venv source venv/bin/activate
Maintenant, nous pouvons invoquer le dossier pour le débogage. N'oubliez pas que vous avez besoin de Docker installé et fonctionne pour cela. Encore une fois, n'oubliez pas d'invoquer cela de l'endroit où se trouve le fichier de modèle.
(venv) usar@MacBookPro my-lambda-project
Cela invoquera la fonction sur le modèle.yml. L'indicateur -D indique que le port de débogage est 5678. L'indicateur -e indique où se trouve le fichier d'événements qui sera soumis à la Lambda.
Finalisons maintenant cela en déployant le code à AWS.
layers/ └── layer_utils/ └── python/ ├── layer_utils/ │ ├── __init__.py │ └── request_handler.py │ └── processor.py
Le drapeau - guidé peut être utilisé la première fois si vous n'avez pas encore déployé votre lambda, car cela vous aidera dans le processus. Après cela, vous pouvez aller à la console AWS et trouver votre couche. Vous pouvez maintenant utiliser la couche avec d'autres lambdas en utilisant l'ARN de la couche.
Si vous souhaitez utiliser VScode pour déboguer, définir des points d'arrêt, etc., nous devons faire des étapes supplémentaires.
Nous devons ajouter une configuration de débogage. Pour ce faire, effectuez un décalage de contrôle / commandes P et Type Debug: Ajouter une configuration .... Cela ouvrira le fichier lancé.json. Vous devez y ajouter la configuration.
./. Vscode / launch.json
import requests def process_data(url): """ Fetches data from a URL. Args: url (str): The URL to fetch data from. Returns: str: The fetched content or an error message. """ try: response = requests.get(url) response.raise_for_status() # Raise an error for bad status codes return response.text[:200] # Return the first 200 characters of the response except requests.RequestException as e: return f"Error fetching data: {str(e)}"
Nous utilisons Debugpy qui s'attachera à l'invocation locale de SAM, et ici nous configurons le port 5678 que nous avons vu lors de l'invocation avec l'indicateur -D. Assurez-vous que le LocalRoot pointe vers le répertoire où se trouve votre code lambda. Si vous avez plus de configurations, ajoutez la pièce dans la configuration à la liste.
Nous aurons besoin de la bibliothèque Debugpy pour déboguer. Ajoutons d'abord aux exigences.txt de votre lambda
./ lambdas / mylambda / exigences.txt
from layer_utils.processor import process_data def handle_request(request): """ Handles an incoming request and processes it. Args: request (dict): The input request data. Returns: dict: The processed result. """ # Example: Extract 'url' from the request and process it if "url" not in request: return {"error": "Missing 'data' in request"} data = request["url"] processed_result = process_data(data) return {"result": processed_result}
maintenant l'installons avec pip
└── layer_utils └── python ├── layer_utils │ ├── __init__.py │ ├── processor.py │ └── request_handler.py ├── pyproject.toml └── requirements.txt
ou vous pouvez également l'installer via le fichier exigence.txt
[project] name = "layer_utils" version = "0.1.0" [build-system] requires = ["setuptools", "wheel"] build-backend = "setuptools.build_meta"
Nous devons créer un fichier d'environnement où nous pouvons définir une variable d'environnement AWS_SAM_LOCAL qui indiquera à notre calque qu'elle s'exécute localement. Nous créons un fichier .env sur notre dossier d'espace de travail.
./. Env
requests==2.32.2
Ici, nous définissons le AWS_SAM_LOCAL, donc le Lambda saura qu'il s'exécute localement via AWS SAM.
Nous devons également dire à notre environnement Python qu'il doit utiliser les variables d'environnement du fichier environnement. C'est à quoi ça devrait ressembler
./. Vscode / settings.json
python3.12 -m venv venv source venv/bin/activate
Et enfin, nous devons modifier notre code lambda afin qu'il sache qu'il doit se connecter au débogueur lors de son exécution localement. Au tout début de notre fichier, nous ajouterons le morceau de code suivant
./ lambdas / mylambda / src / lambda_function.py
(venv) usar@MacBookPro my-lambda-project
Maintenant, nous invoquons la fonction (encore une fois, du chemin où se trouve la fonction):
pip3 install -r ./layers/layer_utils/python/requirements.txt
Lorsque la console affiche en attente de débogueur pour attacher ..., appuyez sur F5 ou sélectionnez le débogueur Python: débogage à l'aide de lancers.json
Et maintenant vous êtes prêt à déboguer vos couches locales et vos lambdas!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!