web-dev-qa-db-fra.com

AWS Lambda en Python: Importer le package parent / répertoire dans le gestionnaire de fonctions Lambda

J'ai une structure de répertoire comme ci-après dans mon application sans serveur (application la plus simple pour éviter l'encombrement) que j'ai créée à l'aide de AWS Sam avec Python 3,8 en tant qu'instrument:

├── common
│   └── a.py
├── hello_world
│   ├── __init__.py
│   ├── app.py
│   └── requirements.txt
└── template.yaml

Je voudrais importer common/a.py Module à l'intérieur du gestionnaire Lambda - hello_world/app.py. Maintenant, je sais que je peux importez-le normalement en python en ajoutant le chemin d'accès à PYTHONPATH ou sys.path, mais cela ne fonctionne pas lorsque le code est exécuté à Lambda à l'intérieur d'un conteneur Docker. Lorsqu'il est invoqué, la fonction de gestionnaire Lambda est exécutée à l'intérieur /var/task Répertoire et la structure de dossiers n'est pas considérée.

J'ai essayé d'insérer /var/task/common, /var/common, /var et même /common à sys.path comme ceci de manière programmatique:

import sys
sys.path.insert(0, '/var/task/common')
from common.a import Alpha

mais j'ai toujours l'erreur:

ModuleNotFoundError: No module named 'common'

Je suis au courant de couches Lambda Mais étant donné mon scénario, je voudrais faire référence directement au code commun dans plusieurs fonctions Lambda sans la nécessité de télécharger sur une couche. Je veux avoir quelque chose comme le serverless-python-requirements plugin dans le cadre sans serveur mais dans AWS Sam.

Donc, ma question est, comment devrais-je ajouter ce chemin à common à PYTHONPATH ou sys.path? Ou existe-t-il une solution de contournement alternative pour cela comme [serverless-python-requirements][3] Pour importer directement un module dans un dossier parent sans utiliser de couches Lambda?

9
Syed Waqas

Je n'ai pas trouvé ce que je cherchais mais j'ai fini par une solution pour créer une seule fonction Lambda dans la racine qui gère tous les appels d'API différents dans la fonction. Oui, ma fonction Lambda est intégrée à l'API Gateway et je peux obtenir la méthode API et le chemin de l'API en utilisant event["httpMethod"] et event ["httpPath"] respectivement. Je peux ensuite mettre tous les paquets sous la racine et les importer entre eux.

Par exemple, disons que j'ai 2 chemins d'API /items et /employees Cela doit être manipulé et les deux doivent gérer à la fois d'obtenir et POST méthodes, le code suivant suffit:

if event["path"] == '/items':
   if event["httpMethod"] == 'GET':
      ...
   Elif event["httpMethod"] == 'POST':
      ...
Elif event["path"] == '/employees':
   if event["httpMethod"] == 'GET':
      ...
   if event["httpMethod"] == 'POST':
      ...

Alors maintenant, je peux avoir autant de paquets sous cette fonction Lambda. Par exemple, ce qui suit est la façon dont le référentiel ressemble maintenant à:

├── application
│   └── *.py
├── persistence
│   └── *.py
├── models
│   └── *.py
└── rootLambdaFunction.py
└── requirements.txt

De cette façon, je peux importer des packages à volonté partout où je veux dans la structure donnée.

0
Syed Waqas